kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: add pruneEmptyDeep; improve omit types
rodzic
7922da9c60
commit
e3b317ecdd
|
@ -6,6 +6,8 @@ import { mockKyInstance } from './_utils'
|
||||||
import {
|
import {
|
||||||
omit,
|
omit,
|
||||||
pick,
|
pick,
|
||||||
|
pruneEmpty,
|
||||||
|
pruneEmptyDeep,
|
||||||
sanitizeSearchParams,
|
sanitizeSearchParams,
|
||||||
stringifyForModel,
|
stringifyForModel,
|
||||||
throttleKy
|
throttleKy
|
||||||
|
@ -20,9 +22,11 @@ test('pick', () => {
|
||||||
|
|
||||||
test('omit', () => {
|
test('omit', () => {
|
||||||
expect(omit({ a: 1, b: 2, c: 3 }, 'a', 'c')).toEqual({ b: 2 })
|
expect(omit({ a: 1, b: 2, c: 3 }, 'a', 'c')).toEqual({ b: 2 })
|
||||||
expect(
|
expect(omit({ a: { b: 'foo' }, d: -1, foo: null }, 'b', 'foo')).toEqual({
|
||||||
omit({ a: { b: 'foo' }, d: -1, foo: null } as any, 'b', 'foo')
|
a: { b: 'foo' },
|
||||||
).toEqual({ a: { b: 'foo' }, d: -1 })
|
d: -1
|
||||||
|
})
|
||||||
|
expect(omit({ a: 1, b: 2, c: 3 }, 'foo', 'bar', 'c')).toEqual({ a: 1, b: 2 })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('sanitizeSearchParams', () => {
|
test('sanitizeSearchParams', () => {
|
||||||
|
@ -71,6 +75,69 @@ describe('stringifyForModel', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('pruneEmpty', () => {
|
||||||
|
expect(
|
||||||
|
pruneEmpty({
|
||||||
|
a: 1,
|
||||||
|
b: { foo: true },
|
||||||
|
c: [true],
|
||||||
|
d: 'foo',
|
||||||
|
e: null,
|
||||||
|
f: undefined
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
a: 1,
|
||||||
|
b: { foo: true },
|
||||||
|
c: [true],
|
||||||
|
d: 'foo'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(pruneEmpty({ a: 0, b: {}, c: [], d: '' })).toEqual({
|
||||||
|
a: 0
|
||||||
|
})
|
||||||
|
expect(pruneEmpty({ b: {}, c: [], d: '' })).toEqual({})
|
||||||
|
|
||||||
|
expect(
|
||||||
|
pruneEmpty({
|
||||||
|
a: null,
|
||||||
|
b: { foo: [{}], bar: [null, undefined, ''] },
|
||||||
|
c: ['', '', ''],
|
||||||
|
d: '',
|
||||||
|
e: undefined,
|
||||||
|
f: [],
|
||||||
|
g: {}
|
||||||
|
})
|
||||||
|
).toEqual({
|
||||||
|
b: { foo: [{}], bar: [null, undefined, ''] },
|
||||||
|
c: ['', '', '']
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('pruneEmptyDeep', () => {
|
||||||
|
expect(
|
||||||
|
pruneEmptyDeep({ a: 1, b: { foo: true }, c: [true], d: 'foo' })
|
||||||
|
).toEqual({
|
||||||
|
a: 1,
|
||||||
|
b: { foo: true },
|
||||||
|
c: [true],
|
||||||
|
d: 'foo'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(pruneEmptyDeep({ a: 0, b: {}, c: [], d: '' })).toEqual({
|
||||||
|
a: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(
|
||||||
|
pruneEmptyDeep({
|
||||||
|
a: null,
|
||||||
|
b: { foo: [{}], bar: [null, undefined, ''] },
|
||||||
|
c: ['', '', ''],
|
||||||
|
d: '',
|
||||||
|
e: undefined
|
||||||
|
})
|
||||||
|
).toEqual(undefined)
|
||||||
|
})
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'throttleKy should rate-limit requests to ky properly',
|
'throttleKy should rate-limit requests to ky properly',
|
||||||
async () => {
|
async () => {
|
||||||
|
|
|
@ -15,8 +15,8 @@ export { default as delay } from 'delay'
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export const omit = <
|
export const omit = <
|
||||||
T extends Record<any, unknown> | object,
|
T extends Record<string, unknown> | object,
|
||||||
K extends keyof T = keyof T
|
K extends keyof any
|
||||||
>(
|
>(
|
||||||
inputObj: T,
|
inputObj: T,
|
||||||
...keys: K[]
|
...keys: K[]
|
||||||
|
@ -36,8 +36,8 @@ export const omit = <
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export const pick = <
|
export const pick = <
|
||||||
T extends Record<any, unknown> | object,
|
T extends Record<string, unknown> | object,
|
||||||
K extends keyof T = keyof T
|
K extends keyof T
|
||||||
>(
|
>(
|
||||||
inputObj: T,
|
inputObj: T,
|
||||||
...keys: K[]
|
...keys: K[]
|
||||||
|
@ -110,6 +110,50 @@ export function pruneEmpty<T extends Record<string, any>>(
|
||||||
) as NonNullable<T>
|
) as NonNullable<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pruneEmptyDeep<T>(
|
||||||
|
value?: T
|
||||||
|
):
|
||||||
|
| undefined
|
||||||
|
| (T extends Record<string, any>
|
||||||
|
? { [K in keyof T]: Exclude<T[K], undefined | null> }
|
||||||
|
: T extends Array<infer U>
|
||||||
|
? Array<Exclude<U, undefined | null>>
|
||||||
|
: Exclude<T, null>) {
|
||||||
|
if (value === undefined || value === null) return undefined
|
||||||
|
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
if (!value) return undefined
|
||||||
|
|
||||||
|
return value as any
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (!value.length) return undefined
|
||||||
|
|
||||||
|
value = value
|
||||||
|
.map((v) => pruneEmptyDeep(v))
|
||||||
|
.filter((v) => v !== undefined) as any
|
||||||
|
|
||||||
|
if (!value || !Array.isArray(value) || !value.length) return undefined
|
||||||
|
return value as any
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
if (!Object.keys(value).length) return undefined
|
||||||
|
|
||||||
|
value = Object.fromEntries(
|
||||||
|
Object.entries(value)
|
||||||
|
.map(([k, v]) => [k, pruneEmptyDeep(v)])
|
||||||
|
.filter(([, v]) => v !== undefined)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!value || !Object.keys(value).length) return undefined
|
||||||
|
return value as any
|
||||||
|
}
|
||||||
|
|
||||||
|
return value as any
|
||||||
|
}
|
||||||
|
|
||||||
export function getEnv(name: string): string | undefined {
|
export function getEnv(name: string): string | undefined {
|
||||||
try {
|
try {
|
||||||
return typeof process !== 'undefined'
|
return typeof process !== 'undefined'
|
||||||
|
|
|
@ -22,10 +22,6 @@
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"verbatimModuleSyntax": true
|
"verbatimModuleSyntax": true
|
||||||
|
|
||||||
// NOTE: these are deprecated
|
|
||||||
// "experimentalDecorators": true,
|
|
||||||
// "emitDecoratorMetadata": true,
|
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue