@kdtlabs/utils 0.0.9 → 0.0.11

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.
@@ -0,0 +1,4 @@
1
+ import{isDirectory,isFile,isHexString,isNumberString,isReadable,isStrictHexString,isTrueLike,isValidDate,isWritable,isWritableDirectory}from"../chunk-rn7vfxhm.js";import{z}from"zod";var PROTOCOL_PATTERNS={file:/^file$/u,ftp:/^ftps?$/u,http:/^https?$/u,ssh:/^ssh$/u,ws:/^wss?$/u};function url(...protocols){let patterns=protocols.flat().map((p)=>PROTOCOL_PATTERNS[p]),combined=new RegExp(`^(?:${patterns.map((r)=>r.source.slice(1,-1)).join("|")})$`);return z.url({protocol:combined})}var hexString=(length)=>z.string().refine((val)=>isHexString(val,length),{error:length?`Invalid hex string (expected ${length} bytes)`:"Invalid hex string"}),strictHexString=(length)=>z.string().refine((val)=>isStrictHexString(val,length),{error:length?`Invalid strict hex string (expected 0x prefix, ${length} bytes)`:"Invalid strict hex string (expected 0x prefix)"}),numberString=()=>z.string().refine((val)=>isNumberString(val),{error:"Invalid number string"}),validDate=()=>z.custom((val)=>isValidDate(val),{error:"Invalid date"}),trueLike=(options)=>z.unknown().transform((val)=>isTrueLike(val,options)),filePath=()=>z.string().refine((val)=>isFile(val),{error:"Path is not a file"}),directoryPath=()=>z.string().refine((val)=>isDirectory(val),{error:"Path is not a directory"}),readable=()=>z.string().refine((val)=>isReadable(val),{error:"Path is not readable"}),writable=()=>z.string().refine((val)=>isWritable(val),{error:"Path is not writable"}),writableDirectory=()=>z.string().refine((val)=>isWritableDirectory(val),{error:"Path is not a writable directory"});export{writableDirectory,writable,validDate,url,trueLike,strictHexString,readable,numberString,hexString,filePath,directoryPath,PROTOCOL_PATTERNS};
2
+
3
+ //# debugId=CA2A82F81B89B66B64756E2164756E21
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/zod/schemas.ts"],
4
+ "sourcesContent": [
5
+ "import type { IsTrueLikeOptions } from '../core'\nimport { z } from 'zod'\nimport { isTrueLike } from '../core'\nimport { isNumberString } from '../numbers'\nimport { isHexString, isStrictHexString } from '../strings'\nimport { isDirectory, isFile, isReadable, isWritable, isWritableDirectory } from '../system'\nimport { isValidDate } from '../times'\n\nexport const PROTOCOL_PATTERNS = <const>{\n file: /^file$/u,\n ftp: /^ftps?$/u,\n http: /^https?$/u,\n ssh: /^ssh$/u,\n ws: /^wss?$/u,\n}\n\nexport type Protocol = keyof typeof PROTOCOL_PATTERNS\n\nexport function url(...protocols: Array<Protocol | Protocol[]>) {\n const flat = protocols.flat()\n const patterns = flat.map((p) => PROTOCOL_PATTERNS[p])\n const combined = new RegExp(`^(?:${patterns.map((r) => r.source.slice(1, -1)).join('|')})$`)\n\n return z.url({ protocol: combined })\n}\n\nexport const hexString = (length?: number) => (\n z.string().refine((val) => isHexString(val, length), {\n error: length ? `Invalid hex string (expected ${length} bytes)` : 'Invalid hex string',\n })\n)\n\nexport const strictHexString = (length?: number) => (\n z.string().refine((val) => isStrictHexString(val, length), {\n error: length ? `Invalid strict hex string (expected 0x prefix, ${length} bytes)` : 'Invalid strict hex string (expected 0x prefix)',\n })\n)\n\nexport const numberString = () => (\n z.string().refine((val) => isNumberString(val), {\n error: 'Invalid number string',\n })\n)\n\nexport const validDate = () => (\n z.custom<Date>((val) => isValidDate(val), { error: 'Invalid date' })\n)\n\nexport const trueLike = (options?: IsTrueLikeOptions) => z.unknown().transform((val) => isTrueLike(val, options))\n\nexport const filePath = () => z.string().refine((val) => isFile(val), {\n error: 'Path is not a file',\n})\n\nexport const directoryPath = () => (\n z.string().refine((val) => isDirectory(val), {\n error: 'Path is not a directory',\n })\n)\n\nexport const readable = () => (\n z.string().refine((val) => isReadable(val), {\n error: 'Path is not readable',\n })\n)\n\nexport const writable = () => (\n z.string().refine((val) => isWritable(val), {\n error: 'Path is not writable',\n })\n)\n\nexport const writableDirectory = () => (\n z.string().refine((val) => isWritableDirectory(val), {\n error: 'Path is not a writable directory',\n })\n)\n"
6
+ ],
7
+ "mappings": "mKACA,mBAOO,IAAM,kBAA2B,CACpC,KAAM,UACN,IAAK,WACL,KAAM,YACN,IAAK,SACL,GAAI,SACR,EAIO,SAAS,GAAG,IAAI,UAAyC,CAE5D,IAAM,SADO,UAAU,KAAK,EACN,IAAI,CAAC,IAAM,kBAAkB,EAAE,EAC/C,SAAW,IAAI,OAAO,OAAO,SAAS,IAAI,CAAC,IAAM,EAAE,OAAO,MAAM,EAAG,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,EAE3F,OAAO,EAAE,IAAI,CAAE,SAAU,QAAS,CAAC,EAGhC,IAAM,UAAY,CAAC,SACtB,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,YAAY,IAAK,MAAM,EAAG,CACjD,MAAO,OAAS,gCAAgC,gBAAkB,oBACtE,CAAC,EAGQ,gBAAkB,CAAC,SAC5B,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,kBAAkB,IAAK,MAAM,EAAG,CACvD,MAAO,OAAS,kDAAkD,gBAAkB,gDACxF,CAAC,EAGQ,aAAe,IACxB,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,eAAe,GAAG,EAAG,CAC5C,MAAO,uBACX,CAAC,EAGQ,UAAY,IACrB,EAAE,OAAa,CAAC,MAAQ,YAAY,GAAG,EAAG,CAAE,MAAO,cAAe,CAAC,EAG1D,SAAW,CAAC,UAAgC,EAAE,QAAQ,EAAE,UAAU,CAAC,MAAQ,WAAW,IAAK,OAAO,CAAC,EAEnG,SAAW,IAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,OAAO,GAAG,EAAG,CAClE,MAAO,oBACX,CAAC,EAEY,cAAgB,IACzB,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,YAAY,GAAG,EAAG,CACzC,MAAO,yBACX,CAAC,EAGQ,SAAW,IACpB,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,WAAW,GAAG,EAAG,CACxC,MAAO,sBACX,CAAC,EAGQ,SAAW,IACpB,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,WAAW,GAAG,EAAG,CACxC,MAAO,sBACX,CAAC,EAGQ,kBAAoB,IAC7B,EAAE,OAAO,EAAE,OAAO,CAAC,MAAQ,oBAAoB,GAAG,EAAG,CACjD,MAAO,kCACX,CAAC",
8
+ "debugId": "CA2A82F81B89B66B64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,22 @@
1
+ import type { IsTrueLikeOptions } from '../core';
2
+ import { z } from 'zod';
3
+ export declare const PROTOCOL_PATTERNS: {
4
+ readonly file: RegExp;
5
+ readonly ftp: RegExp;
6
+ readonly http: RegExp;
7
+ readonly ssh: RegExp;
8
+ readonly ws: RegExp;
9
+ };
10
+ export type Protocol = keyof typeof PROTOCOL_PATTERNS;
11
+ export declare function url(...protocols: Array<Protocol | Protocol[]>): z.ZodURL;
12
+ export declare const hexString: (length?: number) => z.ZodString;
13
+ export declare const strictHexString: (length?: number) => z.ZodString & z.ZodType<`0x${string}`, string, z.core.$ZodTypeInternals<`0x${string}`, string>>;
14
+ export declare const numberString: () => z.ZodString & z.ZodType<import("..").NumberString<true>, string, z.core.$ZodTypeInternals<import("..").NumberString<true>, string>>;
15
+ export declare const validDate: () => z.ZodCustom<Date, Date>;
16
+ export declare const trueLike: (options?: IsTrueLikeOptions) => z.ZodPipe<z.ZodUnknown, z.ZodTransform<boolean, unknown>>;
17
+ export declare const filePath: () => z.ZodString;
18
+ export declare const directoryPath: () => z.ZodString;
19
+ export declare const readable: () => z.ZodString;
20
+ export declare const writable: () => z.ZodString;
21
+ export declare const writableDirectory: () => z.ZodString;
22
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/zod/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,eAAO,MAAM,iBAAiB;;;;;;CAM7B,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAErD,wBAAgB,GAAG,CAAC,GAAG,SAAS,EAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC,YAM7D;AAED,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,gBAIxC,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,oGAI9C,CAAA;AAED,eAAO,MAAM,YAAY,2IAIxB,CAAA;AAED,eAAO,MAAM,SAAS,+BAErB,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,UAAU,iBAAiB,8DAA6D,CAAA;AAEjH,eAAO,MAAM,QAAQ,mBAEnB,CAAA;AAEF,eAAO,MAAM,aAAa,mBAIzB,CAAA;AAED,eAAO,MAAM,QAAQ,mBAIpB,CAAA;AAED,eAAO,MAAM,QAAQ,mBAIpB,CAAA;AAED,eAAO,MAAM,iBAAiB,mBAI7B,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kdtlabs/utils",
3
3
  "type": "module",
4
- "version": "0.0.9",
4
+ "version": "0.0.11",
5
5
  "description": "A comprehensive TypeScript utility library",
6
6
  "author": "Diep Dang <kdt310722@gmail.com>",
7
7
  "license": "MIT",
@@ -16,6 +16,10 @@
16
16
  ".": {
17
17
  "types": "./dist/index.d.ts",
18
18
  "default": "./dist/index.js"
19
+ },
20
+ "./zod": {
21
+ "types": "./dist/zod/index.d.ts",
22
+ "default": "./dist/zod/index.js"
19
23
  }
20
24
  },
21
25
  "main": "dist/index.js",
@@ -38,6 +42,14 @@
38
42
  "up": "taze -I --group --force --peer",
39
43
  "preinstall": "only-allow bun && ([ -d .git ] && simple-git-hooks || true)"
40
44
  },
45
+ "peerDependencies": {
46
+ "zod": "^4.0.0"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "zod": {
50
+ "optional": true
51
+ }
52
+ },
41
53
  "devDependencies": {
42
54
  "@commitlint/cli": "^20.5.0",
43
55
  "@commitlint/config-conventional": "^20.5.0",
@@ -52,7 +64,8 @@
52
64
  "rimraf": "^6.1.3",
53
65
  "simple-git-hooks": "^2.13.1",
54
66
  "taze": "^19.10.0",
55
- "typescript": "^6.0.2"
67
+ "typescript": "^6.0.2",
68
+ "zod": "^4.3.6"
56
69
  },
57
70
  "simple-git-hooks": {
58
71
  "commit-msg": "bunx --no -- commitlint --edit ${1}",
@@ -1,3 +1,5 @@
1
+ import { notUndefined } from '../core'
2
+
1
3
  export type BaseErrorCode = number | string
2
4
 
3
5
  export interface BaseErrorOptions extends ErrorOptions {
@@ -41,7 +43,9 @@ export class BaseError extends Error {
41
43
  }
42
44
 
43
45
  protected defineValue(key: string, value: unknown) {
44
- Object.defineProperty(this, key, { configurable: false, enumerable: true, value, writable: false })
46
+ if (notUndefined(value)) {
47
+ Object.defineProperty(this, key, { configurable: false, enumerable: true, value, writable: false })
48
+ }
45
49
 
46
50
  return this
47
51
  }
@@ -9,6 +9,8 @@ export const isBaseError = (value: unknown): value is BaseError => value instanc
9
9
 
10
10
  export const isAbortError = (error: unknown): error is DOMException => error instanceof DOMException && error.name === 'AbortError'
11
11
 
12
+ export const isTimeoutError = (error: unknown): error is DOMException => error instanceof DOMException && error.name === 'TimeoutError'
13
+
12
14
  export const isErrorLike = (value: unknown): value is ErrorLike => isObject(value) && isKeysOf(value, 'name') && isString(value.name)
13
15
 
14
16
  export const isErrnoException = (value: unknown): value is NodeJS.ErrnoException => (
@@ -55,7 +55,13 @@ export class Emitter<TEventMap = EventMap, TStrict extends boolean = false> {
55
55
  const fromRegular = this.#emitSnapshot(regularSnapshot, args)
56
56
  const fromOnce = this.#emitSnapshot(onceSnapshot, args)
57
57
 
58
- return fromRegular || fromOnce
58
+ if (eventName === '*') {
59
+ return fromRegular || fromOnce
60
+ }
61
+
62
+ const fromWildcard = this.#emitWildcard(eventName, args)
63
+
64
+ return fromRegular || fromOnce || fromWildcard
59
65
  }
60
66
 
61
67
  public removeAllListeners<TEventName extends EventNames<TEventMap, TStrict>>(eventName?: TEventName): this {
@@ -114,4 +120,17 @@ export class Emitter<TEventMap = EventMap, TStrict extends boolean = false> {
114
120
 
115
121
  return true
116
122
  }
123
+
124
+ #emitWildcard(eventName: PropertyKey, args: any[]) {
125
+ const regularSnapshot = this.#takeSnapshot(this.eventListeners.get('*'))
126
+ const onceSnapshot = this.#takeSnapshot(this.onceListeners.get('*'))
127
+
128
+ this.onceListeners.delete('*')
129
+
130
+ const wildcardArgs = [eventName, ...args]
131
+ const fromRegular = this.#emitSnapshot(regularSnapshot, wildcardArgs)
132
+ const fromOnce = this.#emitSnapshot(onceSnapshot, wildcardArgs)
133
+
134
+ return fromRegular || fromOnce
135
+ }
117
136
  }
@@ -1,10 +1,12 @@
1
1
  export type EventMap = Record<PropertyKey, any[]>
2
2
 
3
- export type EventNames<TEventMap, TStrict extends boolean> = TStrict extends true ? keyof TEventMap : keyof TEventMap | string
3
+ export type EventNames<TEventMap, TStrict extends boolean> = TStrict extends true ? keyof TEventMap | '*' : keyof TEventMap | string
4
4
 
5
5
  export type ResolveEventArgs<TEventMap, TEventName> = TEventName extends keyof TEventMap ? TEventMap[TEventName] extends any[] ? TEventMap[TEventName] : any[] : any[]
6
6
 
7
- export type EventArgs<TEventMap, TEventName, TStrict extends boolean> = TStrict extends true ? TEventName extends keyof TEventMap ? ResolveEventArgs<TEventMap, TEventName> : never : ResolveEventArgs<TEventMap, TEventName>
7
+ export type WildcardArgs<TEventMap, TStrict extends boolean> = [eventName: EventNames<TEventMap, TStrict>, ...args: any[]]
8
+
9
+ export type EventArgs<TEventMap, TEventName, TStrict extends boolean> = TEventName extends '*' ? WildcardArgs<TEventMap, TStrict> : TStrict extends true ? TEventName extends keyof TEventMap ? ResolveEventArgs<TEventMap, TEventName> : never : ResolveEventArgs<TEventMap, TEventName>
8
10
 
9
11
  export type EventListener<TArgs = any[]> = (...args: TArgs extends any[] ? TArgs : any[]) => void
10
12
 
@@ -8,7 +8,7 @@ export function tap<T>(value: T, callback: (value: T) => void) {
8
8
 
9
9
  export const transform = <T, R>(value: T, callback: (value: T) => R) => callback(value)
10
10
 
11
- export function tryCatch<T>(fn: () => T, fallback: T | ((error: unknown) => T)) {
11
+ export function tryCatch<T, R>(fn: () => T, fallback: R | ((error: unknown) => R)) {
12
12
  try {
13
13
  return fn()
14
14
  } catch (error) {
@@ -9,7 +9,7 @@ pTap.catch = (fn: (error: unknown) => Awaitable<unknown>) => async (error: unkno
9
9
  throw error
10
10
  }
11
11
 
12
- export async function tryCatchAsync<T>(fn: () => Awaitable<T>, fallback: (error: unknown) => Awaitable<T>) {
12
+ export async function tryCatchAsync<T, R>(fn: () => Awaitable<T>, fallback: (error: unknown) => Awaitable<R>) {
13
13
  try {
14
14
  return await fn()
15
15
  } catch (error) {
@@ -0,0 +1 @@
1
+ export * from './schemas'
@@ -0,0 +1,77 @@
1
+ import type { IsTrueLikeOptions } from '../core'
2
+ import { z } from 'zod'
3
+ import { isTrueLike } from '../core'
4
+ import { isNumberString } from '../numbers'
5
+ import { isHexString, isStrictHexString } from '../strings'
6
+ import { isDirectory, isFile, isReadable, isWritable, isWritableDirectory } from '../system'
7
+ import { isValidDate } from '../times'
8
+
9
+ export const PROTOCOL_PATTERNS = <const>{
10
+ file: /^file$/u,
11
+ ftp: /^ftps?$/u,
12
+ http: /^https?$/u,
13
+ ssh: /^ssh$/u,
14
+ ws: /^wss?$/u,
15
+ }
16
+
17
+ export type Protocol = keyof typeof PROTOCOL_PATTERNS
18
+
19
+ export function url(...protocols: Array<Protocol | Protocol[]>) {
20
+ const flat = protocols.flat()
21
+ const patterns = flat.map((p) => PROTOCOL_PATTERNS[p])
22
+ const combined = new RegExp(`^(?:${patterns.map((r) => r.source.slice(1, -1)).join('|')})$`)
23
+
24
+ return z.url({ protocol: combined })
25
+ }
26
+
27
+ export const hexString = (length?: number) => (
28
+ z.string().refine((val) => isHexString(val, length), {
29
+ error: length ? `Invalid hex string (expected ${length} bytes)` : 'Invalid hex string',
30
+ })
31
+ )
32
+
33
+ export const strictHexString = (length?: number) => (
34
+ z.string().refine((val) => isStrictHexString(val, length), {
35
+ error: length ? `Invalid strict hex string (expected 0x prefix, ${length} bytes)` : 'Invalid strict hex string (expected 0x prefix)',
36
+ })
37
+ )
38
+
39
+ export const numberString = () => (
40
+ z.string().refine((val) => isNumberString(val), {
41
+ error: 'Invalid number string',
42
+ })
43
+ )
44
+
45
+ export const validDate = () => (
46
+ z.custom<Date>((val) => isValidDate(val), { error: 'Invalid date' })
47
+ )
48
+
49
+ export const trueLike = (options?: IsTrueLikeOptions) => z.unknown().transform((val) => isTrueLike(val, options))
50
+
51
+ export const filePath = () => z.string().refine((val) => isFile(val), {
52
+ error: 'Path is not a file',
53
+ })
54
+
55
+ export const directoryPath = () => (
56
+ z.string().refine((val) => isDirectory(val), {
57
+ error: 'Path is not a directory',
58
+ })
59
+ )
60
+
61
+ export const readable = () => (
62
+ z.string().refine((val) => isReadable(val), {
63
+ error: 'Path is not readable',
64
+ })
65
+ )
66
+
67
+ export const writable = () => (
68
+ z.string().refine((val) => isWritable(val), {
69
+ error: 'Path is not writable',
70
+ })
71
+ )
72
+
73
+ export const writableDirectory = () => (
74
+ z.string().refine((val) => isWritableDirectory(val), {
75
+ error: 'Path is not a writable directory',
76
+ })
77
+ )