|
| 1 | +/** |
| 2 | + * ESM stub for lodash — used in Jest ESM test environment. |
| 3 | + * The real lodash is CJS and may not resolve correctly through Jest's ESM resolver. |
| 4 | + */ |
| 5 | + |
| 6 | +const noop = () => {}; |
| 7 | + |
| 8 | +const _ = { |
| 9 | + isArray: Array.isArray, |
| 10 | + isString: (v) => typeof v === "string", |
| 11 | + isObject: (v) => v !== null && typeof v === "object", |
| 12 | + isFunction: (v) => typeof v === "function", |
| 13 | + isNumber: (v) => typeof v === "number", |
| 14 | + isUndefined:(v) => v === undefined, |
| 15 | + isNull: (v) => v === null, |
| 16 | + isNil: (v) => v == null, |
| 17 | + isEmpty: (v) => !v || (Array.isArray(v) ? v.length === 0 : typeof v === "object" ? Object.keys(v).length === 0 : false), |
| 18 | + merge: (target, ...sources) => Object.assign(target ?? {}, ...sources), |
| 19 | + omit: (obj, keys) => { |
| 20 | + const result = { ...obj }; |
| 21 | + const ks = Array.isArray(keys) ? keys : [keys]; |
| 22 | + for (const k of ks) delete result[k]; |
| 23 | + return result; |
| 24 | + }, |
| 25 | + pick: (obj, keys) => { |
| 26 | + const result = {}; |
| 27 | + const ks = Array.isArray(keys) ? keys : [keys]; |
| 28 | + for (const k of ks) if (k in obj) result[k] = obj[k]; |
| 29 | + return result; |
| 30 | + }, |
| 31 | + clone: (v) => Array.isArray(v) ? [...v] : typeof v === "object" && v ? { ...v } : v, |
| 32 | + cloneDeep: (v) => JSON.parse(JSON.stringify(v)), |
| 33 | + assign: Object.assign, |
| 34 | + forEach: (collection, fn) => { |
| 35 | + if (Array.isArray(collection)) { collection.forEach(fn); } |
| 36 | + else if (collection && typeof collection === "object") { Object.entries(collection).forEach(([k, v]) => fn(v, k)); } |
| 37 | + }, |
| 38 | + map: (collection, fn) => { |
| 39 | + if (Array.isArray(collection)) return collection.map(fn); |
| 40 | + if (collection && typeof collection === "object") return Object.entries(collection).map(([k, v]) => fn(v, k)); |
| 41 | + return []; |
| 42 | + }, |
| 43 | + filter: (arr, fn) => Array.isArray(arr) ? arr.filter(fn) : [], |
| 44 | + find: (arr, fn) => Array.isArray(arr) ? arr.find(fn) : undefined, |
| 45 | + reduce: (arr, fn, init) => Array.isArray(arr) ? arr.reduce(fn, init) : init, |
| 46 | + some: (arr, fn) => Array.isArray(arr) ? arr.some(fn) : false, |
| 47 | + every: (arr, fn) => Array.isArray(arr) ? arr.every(fn) : true, |
| 48 | + keys: Object.keys, |
| 49 | + values: Object.values, |
| 50 | + entries: Object.entries, |
| 51 | + get: (obj, path, def) => { |
| 52 | + if (!obj) return def; |
| 53 | + const parts = typeof path === "string" ? path.split(".") : path; |
| 54 | + let cur = obj; |
| 55 | + for (const p of parts) { if (cur == null) return def; cur = cur[p]; } |
| 56 | + return cur === undefined ? def : cur; |
| 57 | + }, |
| 58 | + set: (obj, path, val) => { |
| 59 | + const parts = typeof path === "string" ? path.split(".") : path; |
| 60 | + let cur = obj; |
| 61 | + for (let i = 0; i < parts.length - 1; i++) { if (!cur[parts[i]]) cur[parts[i]] = {}; cur = cur[parts[i]]; } |
| 62 | + cur[parts[parts.length - 1]] = val; |
| 63 | + return obj; |
| 64 | + }, |
| 65 | + has: (obj, key) => Object.prototype.hasOwnProperty.call(obj ?? {}, key), |
| 66 | + defaults: (obj, ...sources) => { for (const src of sources) for (const [k, v] of Object.entries(src)) if (obj[k] === undefined) obj[k] = v; return obj; }, |
| 67 | + flatten: (arr) => arr.flat(), |
| 68 | + flatMap: (arr, fn) => arr.flatMap(fn), |
| 69 | + uniq: (arr) => [...new Set(arr)], |
| 70 | + sortBy: (arr, fn) => [...arr].sort((a, b) => { const va = typeof fn === "function" ? fn(a) : a[fn]; const vb = typeof fn === "function" ? fn(b) : b[fn]; return va < vb ? -1 : va > vb ? 1 : 0; }), |
| 71 | + noop, |
| 72 | +}; |
| 73 | + |
| 74 | +export default _; |
0 commit comments