Skip to content

Commit

Permalink
feat: dot notation for object unpacking
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Sep 8, 2022
1 parent 2977c5e commit 2f50f21
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 7 deletions.
33 changes: 26 additions & 7 deletions src/pack/object.ts
Expand Up @@ -14,19 +14,38 @@ export function packObject<T extends Record<string, any>>(input: T, options?: Pa
options.value = options.value || v
options.resolveKey = options.resolveKey || (k => k as string)

const resolveOption = (index: keyof PackOptions<T>) => {
const resolveKey = (index: keyof PackOptions<T>) => {
const arr = (asArray(options?.[index]))
return arr.find(k => k && keys.includes(k))
return arr.find((k) => {
if (typeof k === 'string' && k.includes('.')) {
// use dot notation to get the value
return k
}
return k && keys.includes(k)
})
}

k = resolveOption('key') || k
v = resolveOption('value') || v
const resolveValue = (k: string, input: any) => {
if (k.includes('.')) {
// use dot notation to get the value
const paths = k.split('.')
let val: any = input
for (const path of paths)
val = val[path]
return val
}
return input[k]
}

k = resolveKey('key') || k
v = resolveKey('value') || v

const keyPrefix = input.key ? `${InternalKeySymbol}${input.key}-` : '' || ''
const dedupeKeyPrefix = input.key ? `${InternalKeySymbol}${input.key}-` : '' || ''

const key = options.resolveKey(input[k])
let keyValue = resolveValue(k as string, input)
keyValue = options.resolveKey(keyValue)

return {
[`${keyPrefix}${key}`]: input?.[v],
[`${dedupeKeyPrefix}${keyValue}`]: resolveValue(v as string, input),
} as Partial<T>
}
25 changes: 25 additions & 0 deletions test/pack-object.test.ts
@@ -0,0 +1,25 @@
import { describe, it } from 'vitest'
import { packObject } from '../src'

describe('pack array', () => {
it('basic', () => {
const packed = packObject({
image: {
src: {
'1x': 'https://example.com/image.png',
'2x': 'https://example.com/image@2x.png',
},
alt: 'Example Image',
},
}, {
key: 'image.src.1x',
value: 'image.alt',
})

expect(packed).toMatchInlineSnapshot(`
{
"https://example.com/image.png": "Example Image",
}
`)
})
})

0 comments on commit 2f50f21

Please sign in to comment.