kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: add pruneEmptyDeep; improve omit types
rodzic
08012e28a9
commit
84544c774c
|
@ -6,6 +6,8 @@ import { mockKyInstance } from './_utils'
|
|||
import {
|
||||
omit,
|
||||
pick,
|
||||
pruneEmpty,
|
||||
pruneEmptyDeep,
|
||||
sanitizeSearchParams,
|
||||
stringifyForModel,
|
||||
throttleKy
|
||||
|
@ -20,9 +22,11 @@ test('pick', () => {
|
|||
|
||||
test('omit', () => {
|
||||
expect(omit({ a: 1, b: 2, c: 3 }, 'a', 'c')).toEqual({ b: 2 })
|
||||
expect(
|
||||
omit({ a: { b: 'foo' }, d: -1, foo: null } as any, 'b', 'foo')
|
||||
).toEqual({ a: { b: 'foo' }, d: -1 })
|
||||
expect(omit({ a: { b: 'foo' }, d: -1, foo: null }, 'b', 'foo')).toEqual({
|
||||
a: { b: 'foo' },
|
||||
d: -1
|
||||
})
|
||||
expect(omit({ a: 1, b: 2, c: 3 }, 'foo', 'bar', 'c')).toEqual({ a: 1, b: 2 })
|
||||
})
|
||||
|
||||
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(
|
||||
'throttleKy should rate-limit requests to ky properly',
|
||||
async () => {
|
||||
|
|
52
src/utils.ts
52
src/utils.ts
|
@ -15,8 +15,8 @@ export { default as delay } from 'delay'
|
|||
* ```
|
||||
*/
|
||||
export const omit = <
|
||||
T extends Record<any, unknown> | object,
|
||||
K extends keyof T = keyof T
|
||||
T extends Record<string, unknown> | object,
|
||||
K extends keyof any
|
||||
>(
|
||||
inputObj: T,
|
||||
...keys: K[]
|
||||
|
@ -36,8 +36,8 @@ export const omit = <
|
|||
* ```
|
||||
*/
|
||||
export const pick = <
|
||||
T extends Record<any, unknown> | object,
|
||||
K extends keyof T = keyof T
|
||||
T extends Record<string, unknown> | object,
|
||||
K extends keyof T
|
||||
>(
|
||||
inputObj: T,
|
||||
...keys: K[]
|
||||
|
@ -110,6 +110,50 @@ export function pruneEmpty<T extends Record<string, any>>(
|
|||
) 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 {
|
||||
try {
|
||||
return typeof process !== 'undefined'
|
||||
|
|
|
@ -22,10 +22,6 @@
|
|||
"strict": true,
|
||||
"useDefineForClassFields": true,
|
||||
"verbatimModuleSyntax": true
|
||||
|
||||
// NOTE: these are deprecated
|
||||
// "experimentalDecorators": true,
|
||||
// "emitDecoratorMetadata": true,
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue