mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-11 14:36:25 +00:00
feat(schema): Add looseValue
and looseObject
helpers (#20576)
This commit is contained in:
parent
340a913a48
commit
edef60045c
3 changed files with 84 additions and 20 deletions
|
@ -1,6 +1,7 @@
|
|||
import is from '@sindresorhus/is';
|
||||
import { z } from 'zod';
|
||||
import { logger } from '../../../logger';
|
||||
import { looseObject, looseValue } from '../../../util/schema';
|
||||
import type { Release, ReleaseResult } from '../types';
|
||||
|
||||
export const MinifiedArray = z.array(z.record(z.unknown())).transform((xs) => {
|
||||
|
@ -44,32 +45,20 @@ export const ComposerRelease = z
|
|||
version: z.string(),
|
||||
})
|
||||
.merge(
|
||||
z
|
||||
.object({
|
||||
homepage: z.string().nullable().catch(null),
|
||||
source: z
|
||||
.object({
|
||||
url: z.string(),
|
||||
})
|
||||
.nullable()
|
||||
.catch(null),
|
||||
time: z.string().nullable().catch(null),
|
||||
require: z
|
||||
.object({
|
||||
php: z.string(),
|
||||
})
|
||||
.nullable()
|
||||
.catch(null),
|
||||
})
|
||||
.partial()
|
||||
looseObject({
|
||||
homepage: z.string(),
|
||||
source: z.object({ url: z.string() }),
|
||||
time: z.string(),
|
||||
require: z.object({ php: z.string() }),
|
||||
})
|
||||
);
|
||||
export type ComposerRelease = z.infer<typeof ComposerRelease>;
|
||||
|
||||
export const ComposerReleases = z
|
||||
.union([
|
||||
z.array(ComposerRelease.nullable().catch(null)),
|
||||
z.array(looseValue(ComposerRelease)),
|
||||
z
|
||||
.record(ComposerRelease.nullable().catch(null))
|
||||
.record(looseValue(ComposerRelease))
|
||||
.transform((map) => Object.values(map)),
|
||||
])
|
||||
.catch([])
|
||||
|
|
|
@ -151,4 +151,50 @@ describe('util/schema', () => {
|
|||
expect(called).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('looseValue', () => {
|
||||
it('parses value', () => {
|
||||
const s = schema.looseValue(z.string());
|
||||
expect(s.parse('foobar')).toBe('foobar');
|
||||
});
|
||||
|
||||
it('falls back to null wrong value', () => {
|
||||
const s = schema.looseValue(z.string());
|
||||
expect(s.parse(123)).toBeNull();
|
||||
});
|
||||
|
||||
it('runs callback for wrong elements', () => {
|
||||
let called = false;
|
||||
const s = schema.looseValue(z.string(), () => {
|
||||
called = true;
|
||||
});
|
||||
expect(s.parse(123)).toBeNull();
|
||||
expect(called).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('looseObject', () => {
|
||||
it('parses object', () => {
|
||||
const s = schema.looseObject({
|
||||
foo: z.string(),
|
||||
bar: z.number(),
|
||||
});
|
||||
expect(s.parse({ foo: 'foo', bar: 123 })).toEqual({
|
||||
foo: 'foo',
|
||||
bar: 123,
|
||||
});
|
||||
});
|
||||
|
||||
it('drops wrong items', () => {
|
||||
const s = schema.looseObject({
|
||||
foo: z.string(),
|
||||
bar: z.number(),
|
||||
baz: z.string(),
|
||||
});
|
||||
expect(s.parse({ foo: 'foo', bar: 'bar' })).toEqual({
|
||||
foo: 'foo',
|
||||
bar: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -143,3 +143,32 @@ export function looseRecord<T extends z.ZodTypeAny>(
|
|||
|
||||
return filteredRecord;
|
||||
}
|
||||
|
||||
export function looseValue<T, U extends z.ZodTypeDef, V>(
|
||||
schema: z.ZodType<T, U, V>,
|
||||
catchCallback?: () => void
|
||||
): z.ZodCatch<z.ZodNullable<z.ZodType<T, U, V>>> {
|
||||
const nullableSchema = schema.nullable();
|
||||
const schemaWithFallback = catchCallback
|
||||
? nullableSchema.catch(() => {
|
||||
catchCallback();
|
||||
return null;
|
||||
})
|
||||
: nullableSchema.catch(null);
|
||||
return schemaWithFallback;
|
||||
}
|
||||
|
||||
export function looseObject<T extends z.ZodRawShape>(
|
||||
shape: T
|
||||
): z.ZodObject<{
|
||||
[k in keyof T]: z.ZodOptional<z.ZodCatch<z.ZodNullable<T[k]>>>;
|
||||
}> {
|
||||
const newShape: Record<keyof T, z.ZodTypeAny> = { ...shape };
|
||||
const keys: (keyof T)[] = Object.keys(shape);
|
||||
for (const k of keys) {
|
||||
const v = looseValue(shape[k]);
|
||||
newShape[k] = v;
|
||||
}
|
||||
|
||||
return z.object(newShape).partial() as never;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue