From 6c8c469ca03ef9a9d393b3c20d4e2aaa09201472 Mon Sep 17 00:00:00 2001 From: Sergei Zharinov <zharinov@users.noreply.github.com> Date: Mon, 21 Aug 2023 18:29:41 +0300 Subject: [PATCH] refactor(schema): Use `Json` helper schema instead of `JSON.parse` (#23997) --- lib/config/decrypt.ts | 4 +-- lib/config/schema.ts | 13 +++++---- lib/modules/manager/pipenv/artifacts.ts | 8 ++---- lib/modules/manager/pipenv/schema.ts | 32 ++++++++++++---------- lib/modules/platform/azure/azure-helper.ts | 4 +-- lib/modules/platform/azure/schema.ts | 28 ++++++++++--------- lib/util/cache/repository/impl/base.ts | 9 +++--- lib/util/cache/repository/schema.ts | 21 ++++++++------ lib/util/emoji.ts | 10 +++---- 9 files changed, 65 insertions(+), 64 deletions(-) diff --git a/lib/config/decrypt.ts b/lib/config/decrypt.ts index 80fb62b524..533d255802 100644 --- a/lib/config/decrypt.ts +++ b/lib/config/decrypt.ts @@ -94,9 +94,7 @@ export async function tryDecrypt( const decryptedObjStr = await tryDecryptPgp(privateKey, encryptedStr); if (decryptedObjStr) { try { - const decryptedObj = DecryptedObject.safeParse( - JSON.parse(decryptedObjStr) - ); + const decryptedObj = DecryptedObject.safeParse(decryptedObjStr); // istanbul ignore if if (!decryptedObj.success) { const error = new Error('config-validation'); diff --git a/lib/config/schema.ts b/lib/config/schema.ts index 7a2661c369..3541b34c95 100644 --- a/lib/config/schema.ts +++ b/lib/config/schema.ts @@ -1,7 +1,10 @@ import { z } from 'zod'; +import { Json } from '../util/schema-utils'; -export const DecryptedObject = z.object({ - o: z.string().optional(), - r: z.string().optional(), - v: z.string().optional(), -}); +export const DecryptedObject = Json.pipe( + z.object({ + o: z.string().optional(), + r: z.string().optional(), + v: z.string().optional(), + }) +); diff --git a/lib/modules/manager/pipenv/artifacts.ts b/lib/modules/manager/pipenv/artifacts.ts index d2f3ea3363..db98b3df96 100644 --- a/lib/modules/manager/pipenv/artifacts.ts +++ b/lib/modules/manager/pipenv/artifacts.ts @@ -28,9 +28,7 @@ export function getPythonConstraint( return python; } try { - const result = PipfileLockSchema.safeParse( - JSON.parse(existingLockFileContent) - ); + const result = PipfileLockSchema.safeParse(existingLockFileContent); // istanbul ignore if: not easily testable if (!result.success) { logger.warn({ error: result.error }, 'Invalid Pipfile.lock'); @@ -62,9 +60,7 @@ export function getPipenvConstraint( return pipenv; } try { - const result = PipfileLockSchema.safeParse( - JSON.parse(existingLockFileContent) - ); + const result = PipfileLockSchema.safeParse(existingLockFileContent); // istanbul ignore if: not easily testable if (!result.success) { logger.warn({ error: result.error }, 'Invalid Pipfile.lock'); diff --git a/lib/modules/manager/pipenv/schema.ts b/lib/modules/manager/pipenv/schema.ts index a57cac2148..e39a9b112c 100644 --- a/lib/modules/manager/pipenv/schema.ts +++ b/lib/modules/manager/pipenv/schema.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { Json } from '../../../util/schema-utils'; const PipfileLockEntrySchema = z .record( @@ -8,17 +9,20 @@ const PipfileLockEntrySchema = z }) ) .optional(); -export const PipfileLockSchema = z.object({ - _meta: z - .object({ - requires: z - .object({ - python_version: z.string().optional(), - python_full_version: z.string().optional(), - }) - .optional(), - }) - .optional(), - default: PipfileLockEntrySchema, - develop: PipfileLockEntrySchema, -}); + +export const PipfileLockSchema = Json.pipe( + z.object({ + _meta: z + .object({ + requires: z + .object({ + python_version: z.string().optional(), + python_full_version: z.string().optional(), + }) + .optional(), + }) + .optional(), + default: PipfileLockEntrySchema, + develop: PipfileLockEntrySchema, + }) +); diff --git a/lib/modules/platform/azure/azure-helper.ts b/lib/modules/platform/azure/azure-helper.ts index 55233bc61d..8273d9e04d 100644 --- a/lib/modules/platform/azure/azure-helper.ts +++ b/lib/modules/platform/azure/azure-helper.ts @@ -83,9 +83,7 @@ export async function getFile( if (item?.readable) { const fileContent = await streamToString(item); try { - const result = await WrappedExceptionSchema.safeParseAsync( - JSON.parse(fileContent) - ); + const result = WrappedExceptionSchema.safeParse(fileContent); if (result.success) { if (result.data.typeKey === 'GitItemNotFoundException') { logger.warn(`Unable to find file ${filePath}`); diff --git a/lib/modules/platform/azure/schema.ts b/lib/modules/platform/azure/schema.ts index f305ee2ee7..57406229d1 100644 --- a/lib/modules/platform/azure/schema.ts +++ b/lib/modules/platform/azure/schema.ts @@ -1,17 +1,19 @@ import type { WrappedException } from 'azure-devops-node-api/interfaces/common/VSSInterfaces'; import { z } from 'zod'; +import { Json } from '../../../util/schema-utils'; -export const WrappedExceptionSchema: z.ZodSchema<WrappedException> = z.lazy( - () => - z.object({ - customProperties: z.record(z.any()).optional(), - errorCode: z.number().optional(), - eventId: z.number().optional(), - helpLink: z.string().optional(), - innerException: WrappedExceptionSchema.optional(), - message: z.string().optional(), - stackTrace: z.string().optional(), - typeKey: z.string().optional(), - typeName: z.string().optional(), - }) +const WrappedException: z.ZodSchema<WrappedException> = z.lazy(() => + z.object({ + customProperties: z.record(z.any()).optional(), + errorCode: z.number().optional(), + eventId: z.number().optional(), + helpLink: z.string().optional(), + innerException: WrappedException.optional(), + message: z.string().optional(), + stackTrace: z.string().optional(), + typeKey: z.string().optional(), + typeName: z.string().optional(), + }) ); + +export const WrappedExceptionSchema = Json.pipe(WrappedException); diff --git a/lib/util/cache/repository/impl/base.ts b/lib/util/cache/repository/impl/base.ts index 878fcad50b..3025e3ee9b 100644 --- a/lib/util/cache/repository/impl/base.ts +++ b/lib/util/cache/repository/impl/base.ts @@ -48,14 +48,13 @@ export abstract class RepoCacheBase implements RepoCache { async load(): Promise<void> { try { - const rawOldCache = await this.read(); - if (!is.string(rawOldCache)) { + const oldCache = await this.read(); + if (!is.string(oldCache)) { logger.debug( - `RepoCacheBase.load() - expecting data of type 'string' received '${typeof rawOldCache}' instead - skipping` + `RepoCacheBase.load() - expecting data of type 'string' received '${typeof oldCache}' instead - skipping` ); return; } - const oldCache = JSON.parse(rawOldCache) as unknown; const cacheV13 = RepoCacheV13.safeParse(oldCache); if (cacheV13.success) { @@ -65,7 +64,7 @@ export abstract class RepoCacheBase implements RepoCache { } logger.debug('Repository cache is invalid'); - } catch (err) { + } catch (err) /* istanbul ignore next: not easily testable */ { logger.debug({ err }, 'Error reading repository cache'); } } diff --git a/lib/util/cache/repository/schema.ts b/lib/util/cache/repository/schema.ts index 61af6926e0..5a337b0c6b 100644 --- a/lib/util/cache/repository/schema.ts +++ b/lib/util/cache/repository/schema.ts @@ -1,13 +1,16 @@ import { z } from 'zod'; +import { Json } from '../../schema-utils'; -export const RepoCacheV13 = z - .object({ - repository: z.string().min(1), - revision: z.number().refine((v) => v === 13), - payload: z.string().min(1), - hash: z.string().min(1), - fingerprint: z.string().min(1), - }) - .strict(); +export const RepoCacheV13 = Json.pipe( + z + .object({ + repository: z.string().min(1), + revision: z.number().refine((v) => v === 13), + payload: z.string().min(1), + hash: z.string().min(1), + fingerprint: z.string().min(1), + }) + .strict() +); export type RepoCacheRecord = z.infer<typeof RepoCacheV13>; diff --git a/lib/util/emoji.ts b/lib/util/emoji.ts index 9fe537dc05..0e8dff8788 100644 --- a/lib/util/emoji.ts +++ b/lib/util/emoji.ts @@ -12,6 +12,7 @@ import type { RenovateConfig } from '../config/types'; import dataFiles from '../data-files.generated'; import { logger } from '../logger'; import { regEx } from './regex'; +import { Json } from './schema-utils'; let unicodeEmoji = true; @@ -19,17 +20,14 @@ let mappingsInitialized = false; const shortCodesByHex = new Map<string, string>(); const hexCodesByShort = new Map<string, string>(); -const EmojiShortcodesSchema = z.record( - z.string(), - z.union([z.string(), z.array(z.string())]) +const EmojiShortcodesSchema = Json.pipe( + z.record(z.string(), z.union([z.string(), z.array(z.string())])) ); function lazyInitMappings(): void { if (!mappingsInitialized) { const result = EmojiShortcodesSchema.safeParse( - JSON.parse( - dataFiles.get('node_modules/emojibase-data/en/shortcodes/github.json')! - ) + dataFiles.get('node_modules/emojibase-data/en/shortcodes/github.json')! ); // istanbul ignore if: not easily testable if (!result.success) { -- GitLab