@letsrunit/utils 0.1.0 → 0.2.6
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/dist/index.d.ts +11 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/package.json +18 -8
- package/src/index.ts +2 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
declare function diffArray<T>(ref: T[], cmp: T[]): T[];
|
|
2
|
+
declare function uniqueItem<T>(m: T, i: T, self: T[]): boolean;
|
|
3
|
+
|
|
1
4
|
type UUID = `${string}-${string}-${string}-${string}-${string}`;
|
|
2
5
|
type RequireOnly<T, K extends keyof T> = Required<Pick<T, K>> & Partial<Omit<T, K>>;
|
|
3
6
|
type RequiredAndOptional<T, KR extends keyof T, KO extends keyof T> = Required<Pick<T, KR>> & Partial<Pick<T, KO>>;
|
|
@@ -42,6 +45,13 @@ declare function textToHtml(text: string): string;
|
|
|
42
45
|
declare function join(glue: string, ...items: Array<string | undefined | false | Array<string | undefined | false>>): string;
|
|
43
46
|
declare function cn(...names: Array<string | undefined | false | Array<string | undefined | false>>): string;
|
|
44
47
|
|
|
48
|
+
interface MemoOptions {
|
|
49
|
+
ttl?: number;
|
|
50
|
+
max?: number;
|
|
51
|
+
cacheKey?: (args: any[]) => string;
|
|
52
|
+
}
|
|
53
|
+
declare function memoize<F extends (...args: any[]) => any>(fn: F, opts?: MemoOptions): F;
|
|
54
|
+
|
|
45
55
|
/**
|
|
46
56
|
* Shallowly cleans values:
|
|
47
57
|
* - Plain objects: remove top-level properties that are null or undefined (no recursion).
|
|
@@ -109,4 +119,4 @@ declare function randomUUID(): UUID;
|
|
|
109
119
|
declare function fixedUUID(index: string | number, group?: string): UUID;
|
|
110
120
|
declare function uuidToTag(id: string, length?: number): string;
|
|
111
121
|
|
|
112
|
-
export { type AtLeastOne, type Cartesian, type Clean, type Predicate, type Range, type RequireOnly, type RequiredAndOptional, type Scalar, type UUID, asFilename, cartesian, chain, clean, cn, eventually, fixedUUID, getWeekNumber, hash, hashKey, isArray, isBinary, isDate, isDateArray, isDateRange, isEntity, isRange, isRecord, isUUID, join, omit, parseDateString, pathRegexp, pick, randomUUID, sleep, splitUrl, statusSymbol, textToHtml, uuidToTag };
|
|
122
|
+
export { type AtLeastOne, type Cartesian, type Clean, type Predicate, type Range, type RequireOnly, type RequiredAndOptional, type Scalar, type UUID, asFilename, cartesian, chain, clean, cn, diffArray, eventually, fixedUUID, getWeekNumber, hash, hashKey, isArray, isBinary, isDate, isDateArray, isDateRange, isEntity, isRange, isRecord, isUUID, join, memoize, omit, parseDateString, pathRegexp, pick, randomUUID, sleep, splitUrl, statusSymbol, textToHtml, uniqueItem, uuidToTag };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import stringify from 'fast-json-stable-stringify';
|
|
2
|
+
import { LRUCache } from 'lru-cache';
|
|
2
3
|
import { validate, v4, v5, NIL } from 'uuid';
|
|
3
4
|
|
|
5
|
+
// src/array.ts
|
|
6
|
+
function diffArray(ref, cmp) {
|
|
7
|
+
const selectedSet = new Set(ref);
|
|
8
|
+
return [...new Set(cmp)].filter((v) => !selectedSet.has(v));
|
|
9
|
+
}
|
|
10
|
+
function uniqueItem(m, i, self) {
|
|
11
|
+
return self.indexOf(m) === i;
|
|
12
|
+
}
|
|
13
|
+
|
|
4
14
|
// src/cartesian.ts
|
|
5
15
|
function cartesian(...arrays) {
|
|
6
16
|
let acc = [[]];
|
|
@@ -159,6 +169,23 @@ function join(glue, ...items) {
|
|
|
159
169
|
function cn(...names) {
|
|
160
170
|
return join(" ", ...names);
|
|
161
171
|
}
|
|
172
|
+
function memoize(fn, opts = {}) {
|
|
173
|
+
const { ttl, max = 1e3, cacheKey = stringify } = opts;
|
|
174
|
+
const cache = new LRUCache({ ttl, max });
|
|
175
|
+
const wrapped = (...args) => {
|
|
176
|
+
const key = cacheKey(args);
|
|
177
|
+
if (cache.has(key)) {
|
|
178
|
+
return cache.get(key);
|
|
179
|
+
}
|
|
180
|
+
const result = fn(...args);
|
|
181
|
+
cache.set(key, result);
|
|
182
|
+
if (result instanceof Promise) {
|
|
183
|
+
result.catch(() => cache.delete(key));
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
};
|
|
187
|
+
return wrapped;
|
|
188
|
+
}
|
|
162
189
|
|
|
163
190
|
// src/object.ts
|
|
164
191
|
function clean(input) {
|
|
@@ -291,6 +318,6 @@ function uuidToTag(id, length = 10) {
|
|
|
291
318
|
return s.slice(-length);
|
|
292
319
|
}
|
|
293
320
|
|
|
294
|
-
export { asFilename, cartesian, chain, clean, cn, eventually, fixedUUID, getWeekNumber, hash, hashKey, isArray, isBinary, isDate, isDateArray, isDateRange, isEntity, isRange, isRecord, isUUID, join, omit, parseDateString, pathRegexp, pick, randomUUID, sleep, splitUrl, statusSymbol, textToHtml, uuidToTag };
|
|
321
|
+
export { asFilename, cartesian, chain, clean, cn, diffArray, eventually, fixedUUID, getWeekNumber, hash, hashKey, isArray, isBinary, isDate, isDateArray, isDateRange, isEntity, isRange, isRecord, isUUID, join, memoize, omit, parseDateString, pathRegexp, pick, randomUUID, sleep, splitUrl, statusSymbol, textToHtml, uniqueItem, uuidToTag };
|
|
295
322
|
//# sourceMappingURL=index.js.map
|
|
296
323
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cartesian.ts","../src/chain.ts","../src/date.ts","../src/type-check.ts","../src/hash.ts","../src/html.ts","../src/join.ts","../src/object.ts","../src/sleep.ts","../src/path.ts","../src/status-symbol.ts","../src/uuid.ts"],"names":["date","uuidv4","uuidv5"],"mappings":"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","file":"index.js","sourcesContent":["import type { Cartesian } from './types';\n\nexport function cartesian<const T extends readonly (readonly unknown[])[]>(...arrays: T): Cartesian<T> {\n let acc: unknown[][] = [[]];\n\n for (const arr of arrays) {\n acc = acc.flatMap((prev) => arr.map((v) => [...prev, v]));\n }\n\n return acc as Cartesian<T>;\n}\n","/**\n * Chain of responsibility.\n * Each function returns true if handled or false if not\n */\nexport function chain<A extends readonly unknown[]>(...steps: ReadonlyArray<(...args: A) => boolean | Promise<boolean>>) {\n return async (...args: A): Promise<boolean> => {\n for (const step of steps) {\n if (await step(...args)) return true;\n }\n return false;\n };\n}\n","export function getWeekNumber(date: Date): number {\n const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n const dayNum = d.getUTCDay() || 7;\n d.setUTCDate(d.getUTCDate() + 4 - dayNum);\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n}\n\nexport function parseDateString(str: string): Date {\n const dateRegex =\n /^((?:today|tomorrow|yesterday|(\\d+) (\\w+) (?:ago|from now))(?: (?:at )?(\\d\\d?:\\d\\d(?::\\d\\d)?))?|\"(.*)\")$/;\n const match = str.match(dateRegex);\n\n if (!match) {\n throw new Error(`Invalid date string: ${str}`);\n }\n\n const quoted = match[5];\n if (quoted !== undefined) {\n const date = new Date(quoted.replace(/\\\\\"/g, '\"'));\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date string: ${str}`);\n }\n return date;\n }\n\n const date = new Date();\n\n const relative = match[1];\n if (relative.startsWith('tomorrow')) {\n date.setDate(date.getDate() + 1);\n } else if (relative.startsWith('yesterday')) {\n date.setDate(date.getDate() - 1);\n } else if (match[2] && match[3]) {\n const amount = parseInt(match[2], 10);\n const unit = match[3].toLowerCase();\n const multiplier = relative.endsWith('ago') ? -1 : 1;\n\n switch (unit) {\n case 'year':\n case 'years':\n date.setFullYear(date.getFullYear() + amount * multiplier);\n break;\n case 'month':\n case 'months':\n date.setMonth(date.getMonth() + amount * multiplier);\n break;\n case 'week':\n case 'weeks':\n date.setDate(date.getDate() + amount * 7 * multiplier);\n break;\n case 'day':\n case 'days':\n date.setDate(date.getDate() + amount * multiplier);\n break;\n case 'hour':\n case 'hours':\n date.setHours(date.getHours() + amount * multiplier);\n break;\n case 'minute':\n case 'minutes':\n date.setMinutes(date.getMinutes() + amount * multiplier);\n break;\n case 'second':\n case 'seconds':\n date.setSeconds(date.getSeconds() + amount * multiplier);\n break;\n default:\n throw new Error(`Invalid date string: ${str}`);\n }\n }\n\n const time = match[4];\n if (time) {\n const [hours, minutes, seconds] = time.split(':').map((s) => parseInt(s, 10));\n date.setHours(hours, minutes, seconds ?? 0, 0);\n }\n\n return date;\n}\n","import type { Predicate, Range, Scalar } from './types';\n\nexport function isBinary(input: unknown): input is Uint8Array {\n return input instanceof Uint8Array;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') return false;\n if (Array.isArray(value)) return false;\n // Preserve well-known special objects\n if (value instanceof Date) return false;\n if (value instanceof RegExp) return false;\n if (value instanceof Uint8Array) return false;\n return Object.getPrototypeOf(value) === Object.prototype;\n}\n\nexport function isEntity<T extends { id: any }>(value: unknown): value is T {\n return typeof value === 'object' && value !== null && 'id' in value;\n}\n\nexport function isRange(value: unknown): value is Range;\nexport function isRange<T extends Scalar>(value: unknown, isT: Predicate<T>): value is Range<T>;\nexport function isRange<T extends Scalar>(value: unknown, isT?: Predicate<T>): value is Range<T> {\n if (!isRecord(value) || !('from' in value) || !('to' in value)) return false;\n return !isT || (isT(value.from) && isT(value.to));\n}\n\nexport function isArray<T>(value: unknown): value is unknown[];\nexport function isArray<T>(value: unknown, isT: Predicate<T>): value is T[];\nexport function isArray<T>(value: unknown, isT?: Predicate<T>): value is T[] {\n if (!Array.isArray(value)) return false;\n return isT ? value.every(isT) : true;\n}\n\nexport const isDate: Predicate<Date> = (v): v is Date => v instanceof Date;\n\n/** @deprecated */\nexport function isDateRange(value: unknown): value is Range<Date> {\n return isRange(value, isDate);\n}\n\n/** @deprecated */\nexport function isDateArray(value: unknown): value is Date[] {\n return isArray(value, isDate);\n}\n","import stringify from 'fast-json-stable-stringify';\nimport { isBinary } from './type-check';\n\nfunction toHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction toArrayBuffer(u8: Uint8Array): ArrayBuffer {\n return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength) as ArrayBuffer;\n}\n\nexport async function hash(input: unknown): Promise<string> {\n const payload = isBinary(input) || typeof input === 'string' ? input : stringify(input);\n\n const bytes = typeof payload === 'string' ? new TextEncoder().encode(payload) : payload;\n\n const digest = await crypto.subtle.digest('SHA-256', toArrayBuffer(bytes));\n return toHex(new Uint8Array(digest));\n}\n\nexport async function hashKey(template: string, input: unknown): Promise<string> {\n const hashVal = await hash(input);\n return template.replace('{hash}', hashVal);\n}\n","export function textToHtml(text: string): string {\n // Basic HTML escaping to prevent injection\n const escaped = text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n\n // Linkify http/https URLs\n const urlRegex = /(https?:\\/\\/[^\\s<>\"]+)/g;\n const linkified = escaped.replace(urlRegex, (href) => {\n return `<a href=\"${href}\" rel=\"noopener noreferrer\">${href}</a>`;\n });\n\n // Wrap in a div with white-space: pre so text preserves whitespace/newlines\n return `<div style=\"white-space: pre\">${linkified}</div>`;\n}\n","export function join(glue: string, ...items: Array<string | undefined | false | Array<string | undefined | false>>) {\n return items.flat().filter(Boolean).join(glue);\n}\n\nexport function cn(...names: Array<string | undefined | false | Array<string | undefined | false>>) {\n return join(' ', ...names);\n}\n","import { isRecord } from './type-check';\nimport type { Clean } from './types';\n\n/**\n * Shallowly cleans values:\n * - Plain objects: remove top-level properties that are null or undefined (no recursion).\n * - Arrays: filter out elements that are null or undefined (no recursion into items).\n * - Non-plain objects and primitives are returned as-is.\n */\nexport function clean<T>(input: T): Clean<T> {\n // Primitives and special instances are returned as-is\n if (\n input === null ||\n input === undefined ||\n typeof input !== 'object' ||\n input instanceof Date ||\n input instanceof RegExp ||\n input instanceof Uint8Array\n ) {\n return input as unknown as Clean<T>;\n }\n\n if (Array.isArray(input)) {\n const filtered = (input as unknown[]).filter((v) => v !== null && v !== undefined);\n return filtered as unknown as Clean<T>;\n }\n\n if (isRecord(input)) {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(input as Record<string, unknown>)) {\n if (value === null || value === undefined) continue;\n result[key] = value as unknown;\n }\n return result as unknown as Clean<T>;\n }\n\n return input as unknown as Clean<T>;\n}\n\n/**\n * Picks a subset of properties from an object by key list.\n * Returns a new object containing only the specified keys (if the key exists on the object).\n */\nexport function pick<T extends object, K extends readonly (keyof T)[]>(obj: T, keys: K): Pick<T, K[number]> {\n const out: Partial<Pick<T, K[number]>> = {};\n for (const key of keys) {\n if (key in obj) {\n out[key] = obj[key];\n }\n }\n return out as Pick<T, K[number]>;\n}\n\n/**\n * Omits a subset of properties from an object by key list.\n * Returns a new object does not contain the specified keys.\n */\nexport function omit<T extends object, K extends readonly (keyof T)[]>(obj: T, keys: K): Omit<T, K[number]> {\n return Object.fromEntries(\n Object.entries(obj).filter(([k]) => !keys.includes(k as keyof T)),\n ) as Omit<T, K[number]>;\n}\n","type SleepOptions = {\n signal?: AbortSignal;\n}\n\ntype RetryOptions = SleepOptions & {\n timeout?: number; // total time to keep trying\n interval?: number; // delay between attempts\n};\n\n/**\n * Sleep for a specified time.\n * Supports abort signal.\n */\nexport function sleep(time: number, { signal }: SleepOptions = {}): Promise<void> {\n if (time <= 0) return Promise.resolve();\n\n if (signal?.aborted) {\n return Promise.reject(signal.reason);\n }\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, time);\n\n const onAbort = () => {\n cleanup();\n reject(signal?.reason);\n };\n\n const cleanup = () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n };\n\n if (signal) {\n signal.addEventListener('abort', onAbort, { once: true } as AddEventListenerOptions);\n }\n });\n}\n\n/**\n * Retry the function if it throws an error, within the given time.\n */\nexport async function eventually<T>(\n fn: () => T | Promise<T>,\n { timeout = 5000, interval = 200, signal: signal2 }: RetryOptions = {},\n): Promise<T> {\n let lastErr: unknown;\n const signal1 = AbortSignal.timeout(timeout);\n const signal = signal2 ? AbortSignal.any([signal1, signal2]) : signal1;\n\n while (!signal.aborted) {\n try {\n const res = await fn();\n if (!signal.aborted) return res;\n } catch (e) {\n lastErr = e;\n try {\n await sleep(interval, { signal });\n } catch (sleepErr) {\n if (!signal1.aborted) throw sleepErr;\n }\n }\n }\n\n throw lastErr;\n}\n","export function splitUrl(url: string): { base: string; path: string } {\n const parsed = new URL(url);\n const base = `${parsed.protocol}//${parsed.host}`;\n const path = parsed.pathname + parsed.search + parsed.hash;\n return { base, path };\n}\n\nexport function asFilename(name: string, ext?: string): string {\n const filename = name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-') // collapse to dashes\n .replace(/^-+|-+$/g, ''); // trim dashes\n\n return filename + (ext ? `.${ext}` : '');\n}\n\n// Build a regex from the pattern (eg `/books/:id`) to extract params\nexport function pathRegexp(path: string): { regexp: RegExp, names: string[] } {\n const names: string[] = [];\n\n const escape = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = path\n .split('/')\n .map((seg) => {\n if (seg.startsWith(':')) {\n names.push(seg.slice(1));\n return '([^/]+)';\n }\n return escape(seg);\n })\n .join('/');\n\n const regexp = new RegExp(`^${pattern}$`);\n\n return { regexp, names };\n}\n","export function statusSymbol(status: string | undefined = undefined) {\n switch (status) {\n case 'success': return '✓';\n case 'failure': return '✘';\n default: return '○';\n }\n}\n","import { NIL, v4 as uuidv4, v5 as uuidv5, validate } from 'uuid';\nimport type { UUID } from './types';\n\nexport function isUUID(value: string): value is UUID {\n return validate(value);\n}\n\nexport function randomUUID(): UUID {\n return uuidv4() as UUID;\n}\n\nexport function fixedUUID(index: string | number, group = ''): UUID {\n const ns = uuidv5(group, NIL);\n return uuidv5(String(index), ns) as UUID;\n}\n\nexport function uuidToTag(id: string, length = 10): string {\n const hex = id.replace(/-/g, '');\n const n = BigInt('0x' + hex);\n const s = n.toString(36);\n return s.slice(-length);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/array.ts","../src/cartesian.ts","../src/chain.ts","../src/date.ts","../src/type-check.ts","../src/hash.ts","../src/html.ts","../src/join.ts","../src/memoize.ts","../src/object.ts","../src/sleep.ts","../src/path.ts","../src/status-symbol.ts","../src/uuid.ts"],"names":["date","stringify","uuidv4","uuidv5"],"mappings":";;;;;AAAO,SAAS,SAAA,CAAa,KAAU,GAAA,EAAU;AAC/C,EAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,GAAG,CAAA;AAC/B,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,GAAG,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAC,CAAA;AAC5D;AAEO,SAAS,UAAA,CAAc,CAAA,EAAM,CAAA,EAAM,IAAA,EAAoB;AAC5D,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA;AAC7B;;;ACLO,SAAS,aAA8D,MAAA,EAAyB;AACrG,EAAA,IAAI,GAAA,GAAmB,CAAC,EAAE,CAAA;AAE1B,EAAA,KAAA,MAAW,OAAO,MAAA,EAAQ;AACxB,IAAA,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,CAAC,IAAA,KAAS,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,GAAG,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAAA,EAC1D;AAEA,EAAA,OAAO,GAAA;AACT;;;ACNO,SAAS,SAAuC,KAAA,EAAkE;AACvH,EAAA,OAAO,UAAU,IAAA,KAA8B;AAC7C,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,IAAI,MAAM,IAAA,CAAK,GAAG,IAAI,GAAG,OAAO,IAAA;AAAA,IAClC;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAA;AACF;;;ACXO,SAAS,cAAc,IAAA,EAAoB;AAChD,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,IAAA,CAAK,IAAI,IAAA,CAAK,WAAA,EAAY,EAAG,IAAA,CAAK,QAAA,EAAS,EAAG,IAAA,CAAK,OAAA,EAAS,CAAC,CAAA;AAChF,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,SAAA,EAAU,IAAK,CAAA;AAChC,EAAA,CAAA,CAAE,UAAA,CAAW,CAAA,CAAE,UAAA,EAAW,GAAI,IAAI,MAAM,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY,IAAI,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,EAAE,cAAA,EAAe,EAAG,CAAA,EAAG,CAAC,CAAC,CAAA;AAC7D,EAAA,OAAO,IAAA,CAAK,IAAA,CAAA,CAAA,CAAO,CAAA,CAAE,OAAA,EAAQ,GAAI,UAAU,OAAA,EAAQ,IAAK,KAAA,GAAW,CAAA,IAAK,CAAC,CAAA;AAC3E;AAEO,SAAS,gBAAgB,GAAA,EAAmB;AACjD,EAAA,MAAM,SAAA,GACJ,0GAAA;AACF,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,SAAS,CAAA;AAEjC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,GAAG,CAAA,CAAE,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,CAAC,CAAA;AACtB,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,MAAMA,QAAO,IAAI,IAAA,CAAK,OAAO,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAC,CAAA;AACjD,IAAA,IAAI,KAAA,CAAMA,KAAAA,CAAK,OAAA,EAAS,CAAA,EAAG;AACzB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,GAAG,CAAA,CAAE,CAAA;AAAA,IAC/C;AACA,IAAA,OAAOA,KAAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,uBAAW,IAAA,EAAK;AAEtB,EAAA,MAAM,QAAA,GAAW,MAAM,CAAC,CAAA;AACxB,EAAA,IAAI,QAAA,CAAS,UAAA,CAAW,UAAU,CAAA,EAAG;AACnC,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAQ,GAAI,CAAC,CAAA;AAAA,EACjC,CAAA,MAAA,IAAW,QAAA,CAAS,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3C,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAQ,GAAI,CAAC,CAAA;AAAA,EACjC,WAAW,KAAA,CAAM,CAAC,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA,EAAG;AAC/B,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,CAAC,GAAG,EAAE,CAAA;AACpC,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,CAAE,WAAA,EAAY;AAClC,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,QAAA,CAAS,KAAK,IAAI,EAAA,GAAK,CAAA;AAEnD,IAAA,QAAQ,IAAA;AAAM,MACZ,KAAK,MAAA;AAAA,MACL,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,WAAA,EAAY,GAAI,SAAS,UAAU,CAAA;AACzD,QAAA;AAAA,MACF,KAAK,OAAA;AAAA,MACL,KAAK,QAAA;AACH,QAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,QAAA,EAAS,GAAI,SAAS,UAAU,CAAA;AACnD,QAAA;AAAA,MACF,KAAK,MAAA;AAAA,MACL,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,OAAA,EAAQ,GAAI,MAAA,GAAS,IAAI,UAAU,CAAA;AACrD,QAAA;AAAA,MACF,KAAK,KAAA;AAAA,MACL,KAAK,MAAA;AACH,QAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAQ,GAAI,SAAS,UAAU,CAAA;AACjD,QAAA;AAAA,MACF,KAAK,MAAA;AAAA,MACL,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,QAAA,EAAS,GAAI,SAAS,UAAU,CAAA;AACnD,QAAA;AAAA,MACF,KAAK,QAAA;AAAA,MACL,KAAK,SAAA;AACH,QAAA,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,UAAA,EAAW,GAAI,SAAS,UAAU,CAAA;AACvD,QAAA;AAAA,MACF,KAAK,QAAA;AAAA,MACL,KAAK,SAAA;AACH,QAAA,IAAA,CAAK,UAAA,CAAW,IAAA,CAAK,UAAA,EAAW,GAAI,SAAS,UAAU,CAAA;AACvD,QAAA;AAAA,MACF;AACE,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,GAAG,CAAA,CAAE,CAAA;AAAA;AACjD,EACF;AAEA,EAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,MAAM,CAAC,KAAA,EAAO,OAAA,EAAS,OAAO,IAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,IAAI,CAAC,CAAA,KAAM,QAAA,CAAS,CAAA,EAAG,EAAE,CAAC,CAAA;AAC5E,IAAA,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO,OAAA,EAAS,OAAA,IAAW,GAAG,CAAC,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO,IAAA;AACT;;;AC7EO,SAAS,SAAS,KAAA,EAAqC;AAC5D,EAAA,OAAO,KAAA,YAAiB,UAAA;AAC1B;AAEO,SAAS,SAAS,KAAA,EAAkD;AACzE,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AACxD,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,KAAA;AAEjC,EAAA,IAAI,KAAA,YAAiB,MAAM,OAAO,KAAA;AAClC,EAAA,IAAI,KAAA,YAAiB,QAAQ,OAAO,KAAA;AACpC,EAAA,IAAI,KAAA,YAAiB,YAAY,OAAO,KAAA;AACxC,EAAA,OAAO,MAAA,CAAO,cAAA,CAAe,KAAK,CAAA,KAAM,MAAA,CAAO,SAAA;AACjD;AAEO,SAAS,SAAgC,KAAA,EAA4B;AAC1E,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,IAAA,IAAQ,KAAA;AAChE;AAIO,SAAS,OAAA,CAA0B,OAAgB,GAAA,EAAuC;AAC/F,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,IAAK,EAAE,UAAU,KAAA,CAAA,IAAU,EAAE,IAAA,IAAQ,KAAA,CAAA,EAAQ,OAAO,KAAA;AACvE,EAAA,OAAO,CAAC,OAAQ,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,IAAK,GAAA,CAAI,MAAM,EAAE,CAAA;AACjD;AAIO,SAAS,OAAA,CAAW,OAAgB,GAAA,EAAkC;AAC3E,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA;AAClC,EAAA,OAAO,GAAA,GAAM,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,GAAI,IAAA;AAClC;AAEO,IAAM,MAAA,GAA0B,CAAC,CAAA,KAAiB,CAAA,YAAa;AAG/D,SAAS,YAAY,KAAA,EAAsC;AAChE,EAAA,OAAO,OAAA,CAAQ,OAAO,MAAM,CAAA;AAC9B;AAGO,SAAS,YAAY,KAAA,EAAiC;AAC3D,EAAA,OAAO,OAAA,CAAQ,OAAO,MAAM,CAAA;AAC9B;;;ACzCA,SAAS,MAAM,KAAA,EAA2B;AACxC,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,KAAA,EAAO,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA;AAC1E;AAEA,SAAS,cAAc,EAAA,EAA6B;AAClD,EAAA,OAAO,EAAA,CAAG,OAAO,KAAA,CAAM,EAAA,CAAG,YAAY,EAAA,CAAG,UAAA,GAAa,GAAG,UAAU,CAAA;AACrE;AAEA,eAAsB,KAAK,KAAA,EAAiC;AAC1D,EAAA,MAAM,OAAA,GAAU,SAAS,KAAK,CAAA,IAAK,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,SAAA,CAAU,KAAK,CAAA;AAEtF,EAAA,MAAM,KAAA,GAAQ,OAAO,OAAA,KAAY,QAAA,GAAW,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,OAAO,CAAA,GAAI,OAAA;AAEhF,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,MAAA,CAAO,OAAO,SAAA,EAAW,aAAA,CAAc,KAAK,CAAC,CAAA;AACzE,EAAA,OAAO,KAAA,CAAM,IAAI,UAAA,CAAW,MAAM,CAAC,CAAA;AACrC;AAEA,eAAsB,OAAA,CAAQ,UAAkB,KAAA,EAAiC;AAC/E,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,KAAK,CAAA;AAChC,EAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,QAAA,EAAU,OAAO,CAAA;AAC3C;;;ACvBO,SAAS,WAAW,IAAA,EAAsB;AAE/C,EAAA,MAAM,OAAA,GAAU,KACb,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CACrB,OAAA,CAAQ,MAAM,MAAM,CAAA,CACpB,QAAQ,IAAA,EAAM,MAAM,EACpB,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA,CACtB,OAAA,CAAQ,MAAM,OAAO,CAAA;AAGxB,EAAA,MAAM,QAAA,GAAW,yBAAA;AACjB,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,QAAA,EAAU,CAAC,IAAA,KAAS;AACpD,IAAA,OAAO,CAAA,SAAA,EAAY,IAAI,CAAA,4BAAA,EAA+B,IAAI,CAAA,IAAA,CAAA;AAAA,EAC5D,CAAC,CAAA;AAGD,EAAA,OAAO,iCAAiC,SAAS,CAAA,MAAA,CAAA;AACnD;;;ACjBO,SAAS,IAAA,CAAK,SAAiB,KAAA,EAA8E;AAClH,EAAA,OAAO,MAAM,IAAA,EAAK,CAAE,OAAO,OAAO,CAAA,CAAE,KAAK,IAAI,CAAA;AAC/C;AAEO,SAAS,MAAM,KAAA,EAA8E;AAClG,EAAA,OAAO,IAAA,CAAK,GAAA,EAAK,GAAG,KAAK,CAAA;AAC3B;ACGO,SAAS,OAAA,CAA2C,EAAA,EAAO,IAAA,GAAoB,EAAC,EAAM;AAC3F,EAAA,MAAM,EAAE,GAAA,EAAK,GAAA,GAAM,GAAA,EAAM,QAAA,GAAWC,WAAU,GAAI,IAAA;AAElD,EAAA,MAAM,QAAQ,IAAI,QAAA,CAAsB,EAAE,GAAA,EAAK,KAAK,CAAA;AAEpD,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,KAAuC;AACzD,IAAA,MAAM,GAAA,GAAM,SAAS,IAAI,CAAA;AAEzB,IAAA,IAAI,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,EAAG;AAClB,MAAA,OAAO,KAAA,CAAM,IAAI,GAAG,CAAA;AAAA,IACtB;AAEA,IAAA,MAAM,MAAA,GAAS,EAAA,CAAG,GAAG,IAAI,CAAA;AACzB,IAAA,KAAA,CAAM,GAAA,CAAI,KAAK,MAAM,CAAA;AAErB,IAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,MAAA,MAAA,CAAO,KAAA,CAAM,MAAM,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,IACtC;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,OAAO,OAAA;AACT;;;ACvBO,SAAS,MAAS,KAAA,EAAoB;AAE3C,EAAA,IACE,KAAA,KAAU,IAAA,IACV,KAAA,KAAU,MAAA,IACV,OAAO,KAAA,KAAU,QAAA,IACjB,KAAA,YAAiB,IAAA,IACjB,KAAA,YAAiB,MAAA,IACjB,KAAA,YAAiB,UAAA,EACjB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,MAAM,QAAA,GAAY,MAAoB,MAAA,CAAO,CAAC,MAAM,CAAA,KAAM,IAAA,IAAQ,MAAM,MAAS,CAAA;AACjF,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,IAAI,QAAA,CAAS,KAAK,CAAA,EAAG;AACnB,IAAA,MAAM,SAAkC,EAAC;AACzC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AAC3E,MAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AAC3C,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AAAA,IAChB;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO,KAAA;AACT;AAMO,SAAS,IAAA,CAAuD,KAAQ,IAAA,EAA6B;AAC1G,EAAA,MAAM,MAAmC,EAAC;AAC1C,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA,CAAI,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAMO,SAAS,IAAA,CAAuD,KAAQ,IAAA,EAA6B;AAC1G,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAAE,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA,KAAM,CAAC,IAAA,CAAK,QAAA,CAAS,CAAY,CAAC;AAAA,GAClE;AACF;;;AChDO,SAAS,MAAM,IAAA,EAAc,EAAE,MAAA,EAAO,GAAkB,EAAC,EAAkB;AAChF,EAAA,IAAI,IAAA,IAAQ,CAAA,EAAG,OAAO,OAAA,CAAQ,OAAA,EAAQ;AAEtC,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,MAAA,OAAA,EAAQ;AACR,MAAA,OAAA,EAAQ;AAAA,IACV,GAAG,IAAI,CAAA;AAEP,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,OAAA,EAAQ;AACR,MAAA,MAAA,CAAO,QAAQ,MAAM,CAAA;AAAA,IACvB,CAAA;AAEA,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,YAAA,CAAa,KAAK,CAAA;AAClB,MAAA,MAAA,EAAQ,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAAA,IAC9C,CAAA;AAEA,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,IAAA,EAAM,MAAiC,CAAA;AAAA,IACrF;AAAA,EACF,CAAC,CAAA;AACH;AAKA,eAAsB,UAAA,CACpB,EAAA,EACA,EAAE,OAAA,GAAU,GAAA,EAAM,QAAA,GAAW,GAAA,EAAK,MAAA,EAAQ,OAAA,EAAQ,GAAkB,EAAC,EACzD;AACZ,EAAA,IAAI,OAAA;AACJ,EAAA,MAAM,OAAA,GAAU,WAAA,CAAY,OAAA,CAAQ,OAAO,CAAA;AAC3C,EAAA,MAAM,MAAA,GAAS,UAAU,WAAA,CAAY,GAAA,CAAI,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA,GAAI,OAAA;AAE/D,EAAA,OAAO,CAAC,OAAO,OAAA,EAAS;AACtB,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,EAAA,EAAG;AACrB,MAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,GAAA;AAAA,IAC9B,SAAS,CAAA,EAAG;AACV,MAAA,OAAA,GAAU,CAAA;AACV,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,CAAM,QAAA,EAAU,EAAE,MAAA,EAAQ,CAAA;AAAA,MAClC,SAAS,QAAA,EAAU;AACjB,QAAA,IAAI,CAAC,OAAA,CAAQ,OAAA,EAAS,MAAM,QAAA;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA;AACR;;;ACpEO,SAAS,SAAS,GAAA,EAA6C;AACpE,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,EAAA,MAAM,OAAO,CAAA,EAAG,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK,OAAO,IAAI,CAAA,CAAA;AAC/C,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,QAAA,GAAW,MAAA,CAAO,SAAS,MAAA,CAAO,IAAA;AACtD,EAAA,OAAO,EAAE,MAAM,IAAA,EAAK;AACtB;AAEO,SAAS,UAAA,CAAW,MAAc,GAAA,EAAsB;AAC7D,EAAA,MAAM,QAAA,GAAW,IAAA,CACd,WAAA,EAAY,CACZ,IAAA,EAAK,CACL,OAAA,CAAQ,aAAA,EAAe,GAAG,CAAA,CAC1B,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAEzB,EAAA,OAAO,QAAA,IAAY,GAAA,GAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,EAAA,CAAA;AACvC;AAGO,SAAS,WAAW,IAAA,EAAmD;AAC5E,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,MAAM,SAAS,CAAC,CAAA,KAAc,CAAA,CAAE,OAAA,CAAQ,uBAAuB,MAAM,CAAA;AACrE,EAAA,MAAM,UAAU,IAAA,CACb,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,GAAA,KAAQ;AACZ,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AACvB,MAAA,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AACvB,MAAA,OAAO,SAAA;AAAA,IACT;AACA,IAAA,OAAO,OAAO,GAAG,CAAA;AAAA,EACnB,CAAC,CAAA,CACA,IAAA,CAAK,GAAG,CAAA;AAEX,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,CAAG,CAAA;AAExC,EAAA,OAAO,EAAE,QAAQ,KAAA,EAAM;AACzB;;;ACpCO,SAAS,YAAA,CAAa,SAA6B,MAAA,EAAW;AACnE,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,SAAA;AAAW,MAAA,OAAO,QAAA;AAAA,IACvB,KAAK,SAAA;AAAW,MAAA,OAAO,QAAA;AAAA,IACvB;AAAS,MAAA,OAAO,QAAA;AAAA;AAEpB;ACHO,SAAS,OAAO,KAAA,EAA8B;AACnD,EAAA,OAAO,SAAS,KAAK,CAAA;AACvB;AAEO,SAAS,UAAA,GAAmB;AACjC,EAAA,OAAOC,EAAA,EAAO;AAChB;AAEO,SAAS,SAAA,CAAU,KAAA,EAAwB,KAAA,GAAQ,EAAA,EAAU;AAClE,EAAA,MAAM,EAAA,GAAKC,EAAA,CAAO,KAAA,EAAO,GAAG,CAAA;AAC5B,EAAA,OAAOA,EAAA,CAAO,MAAA,CAAO,KAAK,CAAA,EAAG,EAAE,CAAA;AACjC;AAEO,SAAS,SAAA,CAAU,EAAA,EAAY,MAAA,GAAS,EAAA,EAAY;AACzD,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,OAAA,CAAQ,IAAA,EAAM,EAAE,CAAA;AAC/B,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,IAAA,GAAO,GAAG,CAAA;AAC3B,EAAA,MAAM,CAAA,GAAI,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA;AACvB,EAAA,OAAO,CAAA,CAAE,KAAA,CAAM,CAAC,MAAM,CAAA;AACxB","file":"index.js","sourcesContent":["export function diffArray<T>(ref: T[], cmp: T[]) {\n const selectedSet = new Set(ref);\n return [...new Set(cmp)].filter((v) => !selectedSet.has(v));\n}\n\nexport function uniqueItem<T>(m: T, i: T, self: T[]): boolean {\n return self.indexOf(m) === i;\n}\n","import type { Cartesian } from './types';\n\nexport function cartesian<const T extends readonly (readonly unknown[])[]>(...arrays: T): Cartesian<T> {\n let acc: unknown[][] = [[]];\n\n for (const arr of arrays) {\n acc = acc.flatMap((prev) => arr.map((v) => [...prev, v]));\n }\n\n return acc as Cartesian<T>;\n}\n","/**\n * Chain of responsibility.\n * Each function returns true if handled or false if not\n */\nexport function chain<A extends readonly unknown[]>(...steps: ReadonlyArray<(...args: A) => boolean | Promise<boolean>>) {\n return async (...args: A): Promise<boolean> => {\n for (const step of steps) {\n if (await step(...args)) return true;\n }\n return false;\n };\n}\n","export function getWeekNumber(date: Date): number {\n const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));\n const dayNum = d.getUTCDay() || 7;\n d.setUTCDate(d.getUTCDate() + 4 - dayNum);\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n}\n\nexport function parseDateString(str: string): Date {\n const dateRegex =\n /^((?:today|tomorrow|yesterday|(\\d+) (\\w+) (?:ago|from now))(?: (?:at )?(\\d\\d?:\\d\\d(?::\\d\\d)?))?|\"(.*)\")$/;\n const match = str.match(dateRegex);\n\n if (!match) {\n throw new Error(`Invalid date string: ${str}`);\n }\n\n const quoted = match[5];\n if (quoted !== undefined) {\n const date = new Date(quoted.replace(/\\\\\"/g, '\"'));\n if (isNaN(date.getTime())) {\n throw new Error(`Invalid date string: ${str}`);\n }\n return date;\n }\n\n const date = new Date();\n\n const relative = match[1];\n if (relative.startsWith('tomorrow')) {\n date.setDate(date.getDate() + 1);\n } else if (relative.startsWith('yesterday')) {\n date.setDate(date.getDate() - 1);\n } else if (match[2] && match[3]) {\n const amount = parseInt(match[2], 10);\n const unit = match[3].toLowerCase();\n const multiplier = relative.endsWith('ago') ? -1 : 1;\n\n switch (unit) {\n case 'year':\n case 'years':\n date.setFullYear(date.getFullYear() + amount * multiplier);\n break;\n case 'month':\n case 'months':\n date.setMonth(date.getMonth() + amount * multiplier);\n break;\n case 'week':\n case 'weeks':\n date.setDate(date.getDate() + amount * 7 * multiplier);\n break;\n case 'day':\n case 'days':\n date.setDate(date.getDate() + amount * multiplier);\n break;\n case 'hour':\n case 'hours':\n date.setHours(date.getHours() + amount * multiplier);\n break;\n case 'minute':\n case 'minutes':\n date.setMinutes(date.getMinutes() + amount * multiplier);\n break;\n case 'second':\n case 'seconds':\n date.setSeconds(date.getSeconds() + amount * multiplier);\n break;\n default:\n throw new Error(`Invalid date string: ${str}`);\n }\n }\n\n const time = match[4];\n if (time) {\n const [hours, minutes, seconds] = time.split(':').map((s) => parseInt(s, 10));\n date.setHours(hours, minutes, seconds ?? 0, 0);\n }\n\n return date;\n}\n","import type { Predicate, Range, Scalar } from './types';\n\nexport function isBinary(input: unknown): input is Uint8Array {\n return input instanceof Uint8Array;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') return false;\n if (Array.isArray(value)) return false;\n // Preserve well-known special objects\n if (value instanceof Date) return false;\n if (value instanceof RegExp) return false;\n if (value instanceof Uint8Array) return false;\n return Object.getPrototypeOf(value) === Object.prototype;\n}\n\nexport function isEntity<T extends { id: any }>(value: unknown): value is T {\n return typeof value === 'object' && value !== null && 'id' in value;\n}\n\nexport function isRange(value: unknown): value is Range;\nexport function isRange<T extends Scalar>(value: unknown, isT: Predicate<T>): value is Range<T>;\nexport function isRange<T extends Scalar>(value: unknown, isT?: Predicate<T>): value is Range<T> {\n if (!isRecord(value) || !('from' in value) || !('to' in value)) return false;\n return !isT || (isT(value.from) && isT(value.to));\n}\n\nexport function isArray<T>(value: unknown): value is unknown[];\nexport function isArray<T>(value: unknown, isT: Predicate<T>): value is T[];\nexport function isArray<T>(value: unknown, isT?: Predicate<T>): value is T[] {\n if (!Array.isArray(value)) return false;\n return isT ? value.every(isT) : true;\n}\n\nexport const isDate: Predicate<Date> = (v): v is Date => v instanceof Date;\n\n/** @deprecated */\nexport function isDateRange(value: unknown): value is Range<Date> {\n return isRange(value, isDate);\n}\n\n/** @deprecated */\nexport function isDateArray(value: unknown): value is Date[] {\n return isArray(value, isDate);\n}\n","import stringify from 'fast-json-stable-stringify';\nimport { isBinary } from './type-check';\n\nfunction toHex(bytes: Uint8Array): string {\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n\nfunction toArrayBuffer(u8: Uint8Array): ArrayBuffer {\n return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength) as ArrayBuffer;\n}\n\nexport async function hash(input: unknown): Promise<string> {\n const payload = isBinary(input) || typeof input === 'string' ? input : stringify(input);\n\n const bytes = typeof payload === 'string' ? new TextEncoder().encode(payload) : payload;\n\n const digest = await crypto.subtle.digest('SHA-256', toArrayBuffer(bytes));\n return toHex(new Uint8Array(digest));\n}\n\nexport async function hashKey(template: string, input: unknown): Promise<string> {\n const hashVal = await hash(input);\n return template.replace('{hash}', hashVal);\n}\n","export function textToHtml(text: string): string {\n // Basic HTML escaping to prevent injection\n const escaped = text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n\n // Linkify http/https URLs\n const urlRegex = /(https?:\\/\\/[^\\s<>\"]+)/g;\n const linkified = escaped.replace(urlRegex, (href) => {\n return `<a href=\"${href}\" rel=\"noopener noreferrer\">${href}</a>`;\n });\n\n // Wrap in a div with white-space: pre so text preserves whitespace/newlines\n return `<div style=\"white-space: pre\">${linkified}</div>`;\n}\n","export function join(glue: string, ...items: Array<string | undefined | false | Array<string | undefined | false>>) {\n return items.flat().filter(Boolean).join(glue);\n}\n\nexport function cn(...names: Array<string | undefined | false | Array<string | undefined | false>>) {\n return join(' ', ...names);\n}\n","import stringify from 'fast-json-stable-stringify';\nimport { LRUCache } from 'lru-cache';\n\ninterface MemoOptions {\n ttl?: number;\n max?: number;\n cacheKey?: (args: any[]) => string;\n}\n\nexport function memoize<F extends (...args: any[]) => any>(fn: F, opts: MemoOptions = {}): F {\n const { ttl, max = 1000, cacheKey = stringify } = opts;\n\n const cache = new LRUCache<string, any>({ ttl, max });\n\n const wrapped = (...args: Parameters<F>): ReturnType<F> => {\n const key = cacheKey(args);\n\n if (cache.has(key)) {\n return cache.get(key) as ReturnType<F>;\n }\n\n const result = fn(...args);\n cache.set(key, result);\n\n if (result instanceof Promise) {\n result.catch(() => cache.delete(key));\n }\n\n return result as ReturnType<F>;\n };\n\n return wrapped as F;\n}\n","import { isRecord } from './type-check';\nimport type { Clean } from './types';\n\n/**\n * Shallowly cleans values:\n * - Plain objects: remove top-level properties that are null or undefined (no recursion).\n * - Arrays: filter out elements that are null or undefined (no recursion into items).\n * - Non-plain objects and primitives are returned as-is.\n */\nexport function clean<T>(input: T): Clean<T> {\n // Primitives and special instances are returned as-is\n if (\n input === null ||\n input === undefined ||\n typeof input !== 'object' ||\n input instanceof Date ||\n input instanceof RegExp ||\n input instanceof Uint8Array\n ) {\n return input as unknown as Clean<T>;\n }\n\n if (Array.isArray(input)) {\n const filtered = (input as unknown[]).filter((v) => v !== null && v !== undefined);\n return filtered as unknown as Clean<T>;\n }\n\n if (isRecord(input)) {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(input as Record<string, unknown>)) {\n if (value === null || value === undefined) continue;\n result[key] = value as unknown;\n }\n return result as unknown as Clean<T>;\n }\n\n return input as unknown as Clean<T>;\n}\n\n/**\n * Picks a subset of properties from an object by key list.\n * Returns a new object containing only the specified keys (if the key exists on the object).\n */\nexport function pick<T extends object, K extends readonly (keyof T)[]>(obj: T, keys: K): Pick<T, K[number]> {\n const out: Partial<Pick<T, K[number]>> = {};\n for (const key of keys) {\n if (key in obj) {\n out[key] = obj[key];\n }\n }\n return out as Pick<T, K[number]>;\n}\n\n/**\n * Omits a subset of properties from an object by key list.\n * Returns a new object does not contain the specified keys.\n */\nexport function omit<T extends object, K extends readonly (keyof T)[]>(obj: T, keys: K): Omit<T, K[number]> {\n return Object.fromEntries(\n Object.entries(obj).filter(([k]) => !keys.includes(k as keyof T)),\n ) as Omit<T, K[number]>;\n}\n","type SleepOptions = {\n signal?: AbortSignal;\n}\n\ntype RetryOptions = SleepOptions & {\n timeout?: number; // total time to keep trying\n interval?: number; // delay between attempts\n};\n\n/**\n * Sleep for a specified time.\n * Supports abort signal.\n */\nexport function sleep(time: number, { signal }: SleepOptions = {}): Promise<void> {\n if (time <= 0) return Promise.resolve();\n\n if (signal?.aborted) {\n return Promise.reject(signal.reason);\n }\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n cleanup();\n resolve();\n }, time);\n\n const onAbort = () => {\n cleanup();\n reject(signal?.reason);\n };\n\n const cleanup = () => {\n clearTimeout(timer);\n signal?.removeEventListener('abort', onAbort);\n };\n\n if (signal) {\n signal.addEventListener('abort', onAbort, { once: true } as AddEventListenerOptions);\n }\n });\n}\n\n/**\n * Retry the function if it throws an error, within the given time.\n */\nexport async function eventually<T>(\n fn: () => T | Promise<T>,\n { timeout = 5000, interval = 200, signal: signal2 }: RetryOptions = {},\n): Promise<T> {\n let lastErr: unknown;\n const signal1 = AbortSignal.timeout(timeout);\n const signal = signal2 ? AbortSignal.any([signal1, signal2]) : signal1;\n\n while (!signal.aborted) {\n try {\n const res = await fn();\n if (!signal.aborted) return res;\n } catch (e) {\n lastErr = e;\n try {\n await sleep(interval, { signal });\n } catch (sleepErr) {\n if (!signal1.aborted) throw sleepErr;\n }\n }\n }\n\n throw lastErr;\n}\n","export function splitUrl(url: string): { base: string; path: string } {\n const parsed = new URL(url);\n const base = `${parsed.protocol}//${parsed.host}`;\n const path = parsed.pathname + parsed.search + parsed.hash;\n return { base, path };\n}\n\nexport function asFilename(name: string, ext?: string): string {\n const filename = name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-') // collapse to dashes\n .replace(/^-+|-+$/g, ''); // trim dashes\n\n return filename + (ext ? `.${ext}` : '');\n}\n\n// Build a regex from the pattern (eg `/books/:id`) to extract params\nexport function pathRegexp(path: string): { regexp: RegExp, names: string[] } {\n const names: string[] = [];\n\n const escape = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = path\n .split('/')\n .map((seg) => {\n if (seg.startsWith(':')) {\n names.push(seg.slice(1));\n return '([^/]+)';\n }\n return escape(seg);\n })\n .join('/');\n\n const regexp = new RegExp(`^${pattern}$`);\n\n return { regexp, names };\n}\n","export function statusSymbol(status: string | undefined = undefined) {\n switch (status) {\n case 'success': return '✓';\n case 'failure': return '✘';\n default: return '○';\n }\n}\n","import { NIL, v4 as uuidv4, v5 as uuidv5, validate } from 'uuid';\nimport type { UUID } from './types';\n\nexport function isUUID(value: string): value is UUID {\n return validate(value);\n}\n\nexport function randomUUID(): UUID {\n return uuidv4() as UUID;\n}\n\nexport function fixedUUID(index: string | number, group = ''): UUID {\n const ns = uuidv5(group, NIL);\n return uuidv5(String(index), ns) as UUID;\n}\n\nexport function uuidToTag(id: string, length = 10): string {\n const hex = id.replace(/-/g, '');\n const n = BigInt('0x' + hex);\n const s = n.toString(36);\n return s.slice(-length);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letsrunit/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Utility functions for letsrunit",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"testing",
|
|
@@ -10,12 +10,11 @@
|
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/letsrunit/letsrunit.git",
|
|
13
|
+
"url": "https://github.com/letsrunit-hq/letsrunit.git",
|
|
14
14
|
"directory": "packages/utils"
|
|
15
15
|
},
|
|
16
|
-
"bugs": "https://github.com/letsrunit/letsrunit/issues",
|
|
17
|
-
"homepage": "https://github.com/letsrunit/letsrunit#readme",
|
|
18
|
-
"private": false,
|
|
16
|
+
"bugs": "https://github.com/letsrunit-hq/letsrunit/issues",
|
|
17
|
+
"homepage": "https://github.com/letsrunit-hq/letsrunit#readme",
|
|
19
18
|
"type": "module",
|
|
20
19
|
"main": "./dist/index.js",
|
|
21
20
|
"module": "./dist/index.js",
|
|
@@ -23,11 +22,22 @@
|
|
|
23
22
|
"exports": {
|
|
24
23
|
".": {
|
|
25
24
|
"types": "./dist/index.d.ts",
|
|
26
|
-
"import": "./dist/index.js"
|
|
25
|
+
"import": "./dist/index.js",
|
|
26
|
+
"default": "./dist/index.js"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
"publishConfig": {
|
|
30
|
-
"access": "public"
|
|
30
|
+
"access": "public",
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"module": "./dist/index.js",
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
31
41
|
},
|
|
32
42
|
"files": [
|
|
33
43
|
"dist",
|
|
@@ -49,4 +59,4 @@
|
|
|
49
59
|
"devDependencies": {
|
|
50
60
|
"vitest": "^4.0.17"
|
|
51
61
|
}
|
|
52
|
-
}
|
|
62
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
export * from './array';
|
|
1
2
|
export * from './cartesian';
|
|
2
3
|
export * from './chain';
|
|
3
4
|
export * from './date';
|
|
4
5
|
export * from './hash';
|
|
5
6
|
export * from './html';
|
|
6
7
|
export * from './join';
|
|
8
|
+
export * from './memoize';
|
|
7
9
|
export * from './object';
|
|
8
10
|
export * from './sleep';
|
|
9
11
|
export * from './path';
|