better code

Massimo Melina committed Jan 5, 2022 at 16:22 UTC f5aef8cc2954e2c71b63bd2dd1055a6d22e6f276
2 files changed +5 -104
src/misc.ts
+5 -2
@@ -1,5 +1,4 @@
1 import fs from 'fs/promises'
2 -import { objSameKeys } from './obj'
2
3 export function enforceFinal(sub:string, s:string) {
4 return s.endsWith(sub) ? s : s+sub
@@ -23,10 +22,14 @@ export function prefix(pre:string, v:string|number, post:string='') {
22 return v ? pre+v+post : ''
23 }
24
26 -export function setHidden(dest: object, src:Record<string,any>) {
25 +export function setHidden(dest: object, src:object) {
26 Object.defineProperties(dest, objSameKeys(src, value => ({ enumerable:false, value })))
27 }
28
29 +export function objSameKeys(src: object, newValue:(value:any,key:string)=>any) {
30 + return Object.fromEntries(Object.entries(src).map(([k,v]) => [k, newValue(v,k)]))
31 +}
32 +
33 export function wait(ms: number) {
34 return new Promise(res=> setTimeout(res,ms))
35 }
src/obj.ts deleted
-102
@@ -1,102 +0,0 @@
1 -/** creates an object iterating an array or an object.
2 - * The callback(val,key/index) should return [val,key] to set both, or just [val] and they key is kept, or just the key (no array) and val will be kept,
3 - * or an object to merge with the result, or undefined to skip.
4 - */
5 -type Key = string | number
6 -type Mapper = (v?: any, k?: Key, src?:any, dst?:object) => any
7 -
8 -export function obj(src:any, cb: string | Mapper, skipUndefined:boolean=true, dst:any={}) {
9 - const short = (typeof cb==='string')
10 - let i = 0
11 - if (Array.isArray(src))
12 - for (const e of src)
13 - work(e, i++)
14 - else
15 - for (const k in src)
16 - work(src[k], k)
17 - return dst
18 -
19 - function work(entry:any, k: Key) {
20 - const r = short ? entry[cb] : cb(entry,k,src,dst)
21 - if (short)
22 - add(k, r)
23 - else if (Array.isArray(r))
24 - if (r.length===1)
25 - add(k, r[0])
26 - else
27 - add(r[1], r[0])
28 - else if (r instanceof Object)
29 - Object.assign(dst, r)
30 - else
31 - add(r, entry)
32 - }
33 -
34 - function add(k: Key | string[], v: any) {
35 - if (k === undefined || (skipUndefined && v === undefined))
36 - return
37 - let o = dst
38 - if (Array.isArray(k))
39 - if (k.length === 1)
40 - k = k[0]
41 - else {
42 - const a = k
43 - k = a.pop() as Key
44 - for (const k1 of a) // @ts-ignore
45 - o = o[k1] instanceof Object ? o[k1] : (o[k1] = {})
46 - }
47 - o[k] = v
48 - }
49 -}
50 -
51 -export function objFilter(src:any, cb:Mapper) {
52 - return obj(src, function(v,k){ // @ts-ignore
53 - return cb.apply(this,arguments) ? k : undefined
54 - })
55 -}
56 -
57 -export function objSameKeys(src:any, cb:Mapper | string) {
58 - return obj(src, typeof cb === 'string' ? cb : (...args)=> [cb(...args)])
59 -}
60 -
61 -export function objFromKeys(keys: string[], returnValueFromKey:(k:string)=>any, skipUndefined=true) {
62 - return obj(keys, k => [returnValueFromKey(k), k], skipUndefined)
63 -}
64 -
65 -// useful only in the extent of making clear your intentions
66 -export const objSameValues = obj
67 -
68 -//** replace object's (or array's) values with those returned by callback
69 -export function remap(obj:any, map:Mapper, skipUndefined=true) {
70 - if (!obj) return
71 - if (Array.isArray(obj)) {
72 - let k = obj.length
73 - while (k--) {
74 - const v = map(obj[k], k)
75 - if (v !== undefined || !skipUndefined)
76 - obj[k] = v
77 - else
78 - obj.splice(k, 1) // will this cause problems if we remove in the middle?
79 - }
80 - return
81 - }
82 - for (const k in obj) {
83 - const v = map(obj[k], k)
84 - if (v !== undefined || !skipUndefined)
85 - obj[k] = v
86 - else
87 - delete obj[k]
88 - }
89 -}
90 -
91 -// replace object's keys using map object. If undefined the key will be removed.
92 -export function remapKeys(obj:any, map:Record<string,string>) {
93 - if (obj)
94 - for (const k in obj)
95 - if (obj.hasOwnProperty(k) && map.hasOwnProperty(k)) {
96 - const newK = map[k]
97 - if (newK !== undefined)
98 - obj[newK] = obj[k]
99 - delete obj[k]
100 - }
101 - return obj
102 -}