From a00c498db16ca713c8b093c4f66792c460ef951f Mon Sep 17 00:00:00 2001 From: Austin Turner Date: Sat, 9 Aug 2025 09:53:07 -0700 Subject: [PATCH] chore: upgrade to zod 4 --- .vscode/extensions.json | 5 +- .../src/app/controllers/auth.controller.ts | 12 +-- .../app/controllers/data-sync.controller.ts | 7 +- .../app/controllers/desktop-app.controller.ts | 2 +- .../jetstream-organizations.controller.ts | 4 +- .../src/app/controllers/oauth.controller.ts | 2 +- .../src/app/controllers/orgs.controller.ts | 2 +- .../controllers/web-extension.controller.ts | 2 +- .../profile/ProfileUserPassword.tsx | 5 +- .../src/config/environment.ts | 6 +- .../jetstream-orgs.desktop.controller.ts | 8 +- .../controllers/orgs.desktop.controller.ts | 2 +- .../profile/ProfileUserPassword.tsx | 5 +- .../landing/components/auth/LoginOrSignUp.tsx | 9 ++- .../components/auth/PasswordResetInit.tsx | 2 +- .../components/auth/PasswordResetVerify.tsx | 5 +- apps/landing/utils/types.ts | 6 +- libs/api-config/src/lib/env-config.ts | 8 +- libs/api-types/src/lib/api-metadata.types.ts | 4 +- libs/api-types/src/lib/api-misc.types.ts | 2 +- libs/api-types/src/lib/api-shared.types.ts | 2 +- libs/auth/types/src/lib/auth-types.ts | 8 +- .../src/lib/desktop-app.types.ts | 3 +- libs/types/src/lib/sync/sync.types.ts | 4 +- package.json | 2 +- run-zod-codemod.sh | 79 +++++++++++++++++++ yarn.lock | 8 +- 27 files changed, 142 insertions(+), 62 deletions(-) create mode 100755 run-zod-codemod.sh diff --git a/.vscode/extensions.json b/.vscode/extensions.json index fb9a22956..3a5df552a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,12 +4,9 @@ "esbenp.prettier-vscode", "mikestead.dotenv", "prisma.prisma", - "vscode-icons-team.vscode-icons", "streetsidesoftware.code-spell-checker", "eamodio.gitlens", "ms-playwright.playwright", - "wayou.vscode-todo-highlight", - "orta.vscode-jest", - "firsttris.vscode-jest-runner" + "wayou.vscode-todo-highlight" ] } diff --git a/apps/api/src/app/controllers/auth.controller.ts b/apps/api/src/app/controllers/auth.controller.ts index 35f4d8b1c..75e4e2feb 100644 --- a/apps/api/src/app/controllers/auth.controller.ts +++ b/apps/api/src/app/controllers/auth.controller.ts @@ -71,7 +71,7 @@ export const routeDefinition = { getCsrfToken: { controllerFn: () => getCsrfToken, validators: { - query: z.record(z.any()), + query: z.record(z.string(), z.any()), hasSourceOrg: false, }, }, @@ -86,14 +86,14 @@ export const routeDefinition = { validators: { params: z.object({ provider: OauthProviderTypeSchema }), query: z.object({ returnUrl: z.string().nullish(), isAccountLink: z.literal('true').nullish() }), - body: z.object({ csrfToken: z.string(), callbackUrl: z.string().url() }), + body: z.object({ csrfToken: z.string(), callbackUrl: z.url() }), hasSourceOrg: false, }, }, callback: { controllerFn: () => callback, validators: { - query: z.record(z.any()), + query: z.record(z.string(), z.any()), params: z.object({ provider: ProviderKeysSchema }), body: z.union([ z.discriminatedUnion('action', [ @@ -101,14 +101,14 @@ export const routeDefinition = { action: z.literal('login'), csrfToken: z.string(), captchaToken: z.string().nullish(), - email: z.string().email().min(5).max(255).toLowerCase(), + email: z.email().min(5).max(255).toLowerCase(), password: z.string().min(8).max(255), }), z.object({ action: z.literal('register'), csrfToken: z.string(), captchaToken: z.string().nullish(), - email: z.string().email().min(5).max(255).toLowerCase(), + email: z.email().min(5).max(255).toLowerCase(), name: z.string().min(1).max(255).trim(), password: z.string().min(8).max(255), }), @@ -162,7 +162,7 @@ export const routeDefinition = { controllerFn: () => validatePasswordReset, validators: { body: z.object({ - email: z.string().email().toLowerCase(), + email: z.email().toLowerCase(), token: z.string(), password: z.string(), csrfToken: z.string(), diff --git a/apps/api/src/app/controllers/data-sync.controller.ts b/apps/api/src/app/controllers/data-sync.controller.ts index bb5a500b4..758d48f7f 100644 --- a/apps/api/src/app/controllers/data-sync.controller.ts +++ b/apps/api/src/app/controllers/data-sync.controller.ts @@ -10,12 +10,11 @@ import { createRoute } from '../utils/route.utils'; // FIXME: TEMPORARY UNTIL ALL CLIENTS HAVE BEEN BACKFILLED export const SyncRecordOperationSchemaFillHashedKey = z - .object({ + .looseObject({ key: z.string(), hashedKey: z.string().optional(), - data: z.record(z.unknown()), + data: z.record(z.string(), z.unknown()), }) - .passthrough() .array() .transform((records) => { return SyncRecordOperationSchema.array() @@ -61,7 +60,7 @@ export const routeDefinition = { controllerFn: () => push, validators: { query: z.object({ - clientId: z.string().uuid(), + clientId: z.uuid(), updatedAt: z .string() .regex(REGEX.ISO_DATE) diff --git a/apps/api/src/app/controllers/desktop-app.controller.ts b/apps/api/src/app/controllers/desktop-app.controller.ts index 5b66de87a..0adcef1d7 100644 --- a/apps/api/src/app/controllers/desktop-app.controller.ts +++ b/apps/api/src/app/controllers/desktop-app.controller.ts @@ -35,7 +35,7 @@ export const routeDefinition = { controllerFn: () => initSession, validators: { query: z.object({ - deviceId: z.string().uuid(), + deviceId: z.uuid(), }), hasSourceOrg: false, }, diff --git a/apps/api/src/app/controllers/jetstream-organizations.controller.ts b/apps/api/src/app/controllers/jetstream-organizations.controller.ts index 8525832e5..34cf7e2a6 100644 --- a/apps/api/src/app/controllers/jetstream-organizations.controller.ts +++ b/apps/api/src/app/controllers/jetstream-organizations.controller.ts @@ -25,7 +25,7 @@ export const routeDefinition = { controllerFn: () => updateOrganization, validators: { params: z.object({ - id: z.string().uuid(), + id: z.uuid(), }), body: z.object({ name: z.string(), @@ -38,7 +38,7 @@ export const routeDefinition = { controllerFn: () => deleteOrganization, validators: { params: z.object({ - id: z.string().uuid(), + id: z.uuid(), }), hasSourceOrg: false, }, diff --git a/apps/api/src/app/controllers/oauth.controller.ts b/apps/api/src/app/controllers/oauth.controller.ts index c8aac0eeb..dd7744851 100644 --- a/apps/api/src/app/controllers/oauth.controller.ts +++ b/apps/api/src/app/controllers/oauth.controller.ts @@ -36,7 +36,7 @@ export const routeDefinition = { salesforceOauthCallback: { controllerFn: () => salesforceOauthCallback, validators: { - query: z.record(z.any()), + query: z.record(z.string(), z.any()), hasSourceOrg: false, }, }, diff --git a/apps/api/src/app/controllers/orgs.controller.ts b/apps/api/src/app/controllers/orgs.controller.ts index 6429b5086..908721cbb 100644 --- a/apps/api/src/app/controllers/orgs.controller.ts +++ b/apps/api/src/app/controllers/orgs.controller.ts @@ -46,7 +46,7 @@ export const routeDefinition = { uniqueId: z.string().min(1), }), body: z.object({ - jetstreamOrganizationId: z.string().uuid().nullish(), + jetstreamOrganizationId: z.uuid().nullish(), }), hasSourceOrg: false, }, diff --git a/apps/api/src/app/controllers/web-extension.controller.ts b/apps/api/src/app/controllers/web-extension.controller.ts index a7666446a..7523a7f7a 100644 --- a/apps/api/src/app/controllers/web-extension.controller.ts +++ b/apps/api/src/app/controllers/web-extension.controller.ts @@ -31,7 +31,7 @@ export const routeDefinition = { controllerFn: () => initSession, validators: { query: z.object({ - deviceId: z.string().uuid(), + deviceId: z.uuid(), }), hasSourceOrg: false, }, diff --git a/apps/jetstream-desktop-client/src/app/components/profile/ProfileUserPassword.tsx b/apps/jetstream-desktop-client/src/app/components/profile/ProfileUserPassword.tsx index 312ac7d32..06fb76787 100644 --- a/apps/jetstream-desktop-client/src/app/components/profile/ProfileUserPassword.tsx +++ b/apps/jetstream-desktop-client/src/app/components/profile/ProfileUserPassword.tsx @@ -13,10 +13,11 @@ const FormSchema = z }) .superRefine((data, ctx) => { if (data.password !== data.confirmPassword) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, + ctx.issues.push({ + code: 'custom', message: 'Passwords do not match', path: ['confirmPassword'], + input: '', }); } }); diff --git a/apps/jetstream-desktop/src/config/environment.ts b/apps/jetstream-desktop/src/config/environment.ts index c81d91cd8..675a8d35c 100644 --- a/apps/jetstream-desktop/src/config/environment.ts +++ b/apps/jetstream-desktop/src/config/environment.ts @@ -59,11 +59,11 @@ const envSchema = z.object({ .optional() .transform((value) => value ?? 'production'), CLIENT_URL: z.string(), - SERVER_URL: z.string().url(), + SERVER_URL: z.url(), // TODO: allow updating this in the app SFDC_API_VERSION: z.string().regex(/^[0-9]{2,4}\.[0-9]$/), DESKTOP_SFDC_CLIENT_ID: z.string().min(1), - DESKTOP_SFDC_CALLBACK_URL: z.string().url(), + DESKTOP_SFDC_CALLBACK_URL: z.url(), }); const parseResults = envSchema.safeParse({ @@ -73,7 +73,7 @@ const parseResults = envSchema.safeParse({ if (!parseResults.success) { console.error(`❌ ${chalk.red('Error parsing environment variables:')} -${chalk.yellow(JSON.stringify(parseResults.error.flatten().fieldErrors, null, 2))} +${chalk.yellow(JSON.stringify(z.treeifyError(parseResults.error), null, 2))} `); process.exit(1); } diff --git a/apps/jetstream-desktop/src/controllers/jetstream-orgs.desktop.controller.ts b/apps/jetstream-desktop/src/controllers/jetstream-orgs.desktop.controller.ts index 9d5101005..8b087d443 100644 --- a/apps/jetstream-desktop/src/controllers/jetstream-orgs.desktop.controller.ts +++ b/apps/jetstream-desktop/src/controllers/jetstream-orgs.desktop.controller.ts @@ -14,7 +14,7 @@ export const routeDefinition = { validators: { body: z.object({ name: z.string(), - description: z.string().optional().nullable().default(null), + description: z.string().optional().nullable().prefault(null), }), hasSourceOrg: false, }, @@ -23,11 +23,11 @@ export const routeDefinition = { controllerFn: () => updateOrganization, validators: { params: z.object({ - id: z.string().uuid(), + id: z.uuid(), }), body: z.object({ name: z.string(), - description: z.string().optional().nullable().default(null), + description: z.string().optional().nullable().prefault(null), }), hasSourceOrg: false, }, @@ -36,7 +36,7 @@ export const routeDefinition = { controllerFn: () => deleteOrganization, validators: { params: z.object({ - id: z.string().uuid(), + id: z.uuid(), }), hasSourceOrg: false, }, diff --git a/apps/jetstream-desktop/src/controllers/orgs.desktop.controller.ts b/apps/jetstream-desktop/src/controllers/orgs.desktop.controller.ts index 11fb673e6..b87b46787 100644 --- a/apps/jetstream-desktop/src/controllers/orgs.desktop.controller.ts +++ b/apps/jetstream-desktop/src/controllers/orgs.desktop.controller.ts @@ -43,7 +43,7 @@ export const routeDefinition = { uniqueId: z.string().min(1), }), body: z.object({ - jetstreamOrganizationId: z.string().uuid().nullish().default(null), + jetstreamOrganizationId: z.uuid().nullish().default(null), }), hasSourceOrg: false, }, diff --git a/apps/jetstream/src/app/components/profile/ProfileUserPassword.tsx b/apps/jetstream/src/app/components/profile/ProfileUserPassword.tsx index 5cd7baf65..3c6a5c653 100644 --- a/apps/jetstream/src/app/components/profile/ProfileUserPassword.tsx +++ b/apps/jetstream/src/app/components/profile/ProfileUserPassword.tsx @@ -13,10 +13,11 @@ const FormSchema = z }) .superRefine((data, ctx) => { if (data.password !== data.confirmPassword) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, + ctx.issues.push({ + code: 'custom', message: 'Passwords do not match', path: ['confirmPassword'], + input: '', }); } }); diff --git a/apps/landing/components/auth/LoginOrSignUp.tsx b/apps/landing/components/auth/LoginOrSignUp.tsx index 15425804b..5ab375aa6 100644 --- a/apps/landing/components/auth/LoginOrSignUp.tsx +++ b/apps/landing/components/auth/LoginOrSignUp.tsx @@ -19,23 +19,24 @@ const LoginSchema = z.object({ action: z.literal('login'), csrfToken: z.string(), captchaToken: z.string(), - email: z.string().email({ message: 'A valid email address is required' }).min(5).max(255).trim(), + email: z.email().min(5).max(255).trim(), password: PasswordSchema, }); const RegisterSchema = LoginSchema.omit({ action: true }).extend({ action: z.literal('register'), - name: z.string().min(1, { message: 'Name is required' }).max(255, { message: 'Name must be at most 255 characters' }), + name: z.string().min(1, { error: 'Name is required' }).max(255, { error: 'Name must be at most 255 characters' }), confirmPassword: PasswordSchema, }); const FormSchema = z.discriminatedUnion('action', [LoginSchema, RegisterSchema]).superRefine((data, ctx) => { if (data.action === 'register') { if (data.password !== data.confirmPassword) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, + ctx.issues.push({ + code: 'custom', message: 'Passwords do not match', path: ['confirmPassword'], + input: '', }); } } diff --git a/apps/landing/components/auth/PasswordResetInit.tsx b/apps/landing/components/auth/PasswordResetInit.tsx index 5dd8d601b..776a705dc 100644 --- a/apps/landing/components/auth/PasswordResetInit.tsx +++ b/apps/landing/components/auth/PasswordResetInit.tsx @@ -14,7 +14,7 @@ import { Captcha } from './Captcha'; const FormSchema = z.object({ csrfToken: z.string(), captchaToken: z.string(), - email: z.string().email({ message: 'A valid email address is required' }).min(5).max(255).trim(), + email: z.email({ error: 'A valid email address is required' }).min(5).max(255).trim(), }); type Form = z.infer; diff --git a/apps/landing/components/auth/PasswordResetVerify.tsx b/apps/landing/components/auth/PasswordResetVerify.tsx index 7f0e1ba7f..35b304316 100644 --- a/apps/landing/components/auth/PasswordResetVerify.tsx +++ b/apps/landing/components/auth/PasswordResetVerify.tsx @@ -21,10 +21,11 @@ const FormSchema = z }) .superRefine((data, ctx) => { if (data.password !== data.confirmPassword) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, + ctx.issues.push({ + code: 'custom', message: 'Passwords do not match', path: ['confirmPassword'], + input: '', }); } }); diff --git a/apps/landing/utils/types.ts b/apps/landing/utils/types.ts index a7ec91128..ca9309d21 100644 --- a/apps/landing/utils/types.ts +++ b/apps/landing/utils/types.ts @@ -4,9 +4,9 @@ import { z } from 'zod'; export const PasswordSchema = z .string() - .min(1, { message: 'Password is required' }) - .min(8, { message: 'Password must be at least 8 characters' }) - .max(255, { message: 'Password must be at most 255 characters' }); + .min(1, { error: 'Password is required' }) + .min(8, { error: 'Password must be at least 8 characters' }) + .max(255, { error: 'Password must be at most 255 characters' }); export interface AnalyticSummaryItem { type: 'LOAD_SUMMARY' | 'QUERY_SUMMARY'; diff --git a/libs/api-config/src/lib/env-config.ts b/libs/api-config/src/lib/env-config.ts index c869519d4..bcd19944e 100644 --- a/libs/api-config/src/lib/env-config.ts +++ b/libs/api-config/src/lib/env-config.ts @@ -95,7 +95,7 @@ const envSchema = z.object({ }) .nullish(), EXAMPLE_USER_PASSWORD: z.string().nullish(), - EXAMPLE_USER_FULL_PROFILE: z.record(z.any()).nullish(), + EXAMPLE_USER_FULL_PROFILE: z.record(z.string(), z.any()).nullish(), IS_LOCAL_DOCKER: booleanSchema, // SYSTEM NODE_ENV: z @@ -134,7 +134,7 @@ const envSchema = z.object({ .transform((val) => val || null), JETSTREAM_POSTGRES_DBURI: z.string(), JETSTREAM_SERVER_DOMAIN: z.string(), - JETSTREAM_SERVER_URL: z.string().url(), + JETSTREAM_SERVER_URL: z.url(), JETSTREAM_CLIENT_URL: z.string(), PRISMA_DEBUG: booleanSchema, COMETD_DEBUG: z.enum(['error', 'warn', 'info', 'debug']).optional(), @@ -191,7 +191,7 @@ const envSchema = z.object({ SFDC_API_VERSION: z.string().regex(/^[0-9]{2,4}\.[0-9]$/), SFDC_CONSUMER_SECRET: z.string().min(1), SFDC_CONSUMER_KEY: z.string().min(1), - SFDC_CALLBACK_URL: z.string().url(), + SFDC_CALLBACK_URL: z.url(), /** * Google OAuth2 * Allows google drive configuration @@ -239,7 +239,7 @@ const parseResults = envSchema.safeParse({ if (!parseResults.success) { console.error(`❌ ${chalk.red('Error parsing environment variables:')} -${chalk.yellow(JSON.stringify(parseResults.error.flatten().fieldErrors, null, 2))} +${chalk.yellow(JSON.stringify(z.treeifyError(parseResults.error), null, 2))} `); process.exit(1); } diff --git a/libs/api-types/src/lib/api-metadata.types.ts b/libs/api-types/src/lib/api-metadata.types.ts index 6f2e22459..909af6e30 100644 --- a/libs/api-types/src/lib/api-metadata.types.ts +++ b/libs/api-types/src/lib/api-metadata.types.ts @@ -30,6 +30,7 @@ export const DeployMetadataRequestSchema = z.object({ export type DeployMetadataRequest = z.infer; export const RetrievePackageFromLisMetadataResultsRequestSchema = z.record( + z.string(), z .object({ fullName: z.string(), @@ -63,6 +64,7 @@ export type CheckRetrieveStatusAndRedeployRequest = z.infer; diff --git a/libs/api-types/src/lib/api-misc.types.ts b/libs/api-types/src/lib/api-misc.types.ts index f63abd432..a9cca335d 100644 --- a/libs/api-types/src/lib/api-misc.types.ts +++ b/libs/api-types/src/lib/api-misc.types.ts @@ -5,7 +5,7 @@ export const SalesforceApiRequestSchema = z.object({ method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']), isTooling: z.boolean().nullish(), body: z.any().nullish(), - headers: z.record(z.string()).nullish(), + headers: z.record(z.string(), z.string()).nullish(), options: z .object({ responseType: z.enum(['json', 'text']).nullish().default('json'), diff --git a/libs/api-types/src/lib/api-shared.types.ts b/libs/api-types/src/lib/api-shared.types.ts index 2290bbd77..ca597d1f9 100644 --- a/libs/api-types/src/lib/api-shared.types.ts +++ b/libs/api-types/src/lib/api-shared.types.ts @@ -26,7 +26,7 @@ export const DeployOptionsSchema = z } return record; }, - { message: 'RunSpecifiedTests requires specified tests to be provided' } + { error: 'RunSpecifiedTests requires specified tests to be provided' } ) .transform((record) => { if (record.testLevel !== 'RunSpecifiedTests' && record.runTests) { diff --git a/libs/auth/types/src/lib/auth-types.ts b/libs/auth/types/src/lib/auth-types.ts index fbee4fc02..bb7b0c0ea 100644 --- a/libs/auth/types/src/lib/auth-types.ts +++ b/libs/auth/types/src/lib/auth-types.ts @@ -290,7 +290,7 @@ export const MfaMethodSchema = z.enum(['otp', 'email']); export type MfaMethod = z.infer; export const LoginConfigurationSchema = z.object({ - id: z.string().uuid(), + id: z.uuid(), allowedMfaMethods: z.array(MfaMethodSchema).transform( (value) => new Set( @@ -327,9 +327,9 @@ export type LoginConfigurationUI = { // TODO: could do discriminated union? export const ProviderBaseSchema = z.object({ label: z.string(), - icon: z.string().url(), - signinUrl: z.string().url(), - callbackUrl: z.string().url(), + icon: z.url(), + signinUrl: z.url(), + callbackUrl: z.url(), }); export const OauthProviderSchema = ProviderBaseSchema.extend({ diff --git a/libs/desktop-types/src/lib/desktop-app.types.ts b/libs/desktop-types/src/lib/desktop-app.types.ts index ca78ec170..294da9189 100644 --- a/libs/desktop-types/src/lib/desktop-app.types.ts +++ b/libs/desktop-types/src/lib/desktop-app.types.ts @@ -81,12 +81,11 @@ export const AppDataSchema = z.object({ .default(() => crypto.randomUUID()), accessToken: z.string().nullish(), userProfile: z - .object({ + .looseObject({ id: z.string(), name: z.string(), email: z.string(), }) - .passthrough() .nullish(), expiresAt: z.number().nullish(), lastChecked: z.number().nullish(), diff --git a/libs/types/src/lib/sync/sync.types.ts b/libs/types/src/lib/sync/sync.types.ts index 9e9340b4f..e3885247b 100644 --- a/libs/types/src/lib/sync/sync.types.ts +++ b/libs/types/src/lib/sync/sync.types.ts @@ -21,7 +21,7 @@ export const SyncRecordOperationBaseSchema = z.object({ key: z.string(), hashedKey: z.string(), entity: SyncTypeSchema, - data: z.record(z.unknown()), + data: z.record(z.string(), z.unknown()), }); export const SyncRecordOperationCreateUpdateSchema = SyncRecordOperationBaseSchema.extend({ @@ -53,7 +53,7 @@ export const SyncRecordSchema = z.object({ // since browser extensions can become out-dated, we need to account for that entity: z.union([SyncTypeSchema, z.string()]), orgId: z.string().nullish(), - data: z.record(z.unknown()), + data: z.record(z.string(), z.unknown()), createdAt: DateTimeSchema, updatedAt: DateTimeSchema, deletedAt: DateTimeSchema.nullish(), diff --git a/package.json b/package.json index 72d7675e5..fa39b4937 100644 --- a/package.json +++ b/package.json @@ -407,6 +407,6 @@ "write-file-atomic": "^6.0.0", "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", "xmlbuilder2": "^3.1.1", - "zod": "^3.23.4" + "zod": "^4.0.16" } } diff --git a/run-zod-codemod.sh b/run-zod-codemod.sh new file mode 100755 index 000000000..19c806f17 --- /dev/null +++ b/run-zod-codemod.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# Script to run zod v3 to v4 codemod on all tsconfig files in apps and libs that use zod + +echo "Running zod v3 to v4 codemod on all relevant tsconfig files..." +echo + +# Counter for processed files +count=0 + +# Apps that use zod +apps=( + "api" + "geo-ip-api" + "jetstream" + "jetstream-desktop" + "jetstream-desktop-client" + "jetstream-e2e" + "jetstream-web-extension" + "jetstream-web-extension-e2e" + "landing" +) + +# Libs that use zod +libs=( + "api-config" + "api-types" + "auth/types" + "desktop-types" + "features/platform-event-monitor" + "types" +) + +# Function to run codemod if file exists +run_codemod() { + local file=$1 + if [ -f "$file" ]; then + echo "Processing: $file" + npx zod-v3-to-v4 "$file" + ((count++)) + echo + fi +} + +# Process apps +echo "=== Processing Apps ===" +for app in "${apps[@]}"; do + echo "Checking app: $app" + + # Check for tsconfig.app.json + run_codemod "apps/$app/tsconfig.app.json" + + # Check for tsconfig.spec.json + run_codemod "apps/$app/tsconfig.spec.json" + + # Some apps might have tsconfig.json as the main config + run_codemod "apps/$app/tsconfig.json" +done + +echo +echo "=== Processing Libraries ===" +# Process libs +for lib in "${libs[@]}"; do + echo "Checking lib: $lib" + + # Check for tsconfig.lib.json + run_codemod "libs/$lib/tsconfig.lib.json" + + # Check for tsconfig.spec.json + run_codemod "libs/$lib/tsconfig.spec.json" + + # Some libs might have tsconfig.json as the main config + run_codemod "libs/$lib/tsconfig.json" +done + +echo +echo "=== Summary ===" +echo "Total tsconfig files processed: $count" +echo "Codemod complete!" \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 879002cdf..0b89583cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29906,10 +29906,10 @@ zip-stream@^6.0.1: compress-commons "^6.0.2" readable-stream "^4.0.0" -zod@^3.23.4: - version "3.23.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.4.tgz#c63805b2f39e10d4ab3d55eb3c8cdb472c79dfb1" - integrity sha512-/AtWOKbBgjzEYYQRNfoGKHObgfAZag6qUJX1VbHo2PRBgS+wfWagEY2mizjfyAPcGesrJOcx/wcl0L9WnVrHFw== +zod@^4.0.16: + version "4.0.16" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.0.16.tgz#bf785eb8dda343c2746ecbd7a6bb47f20ed588c3" + integrity sha512-Djo/cM339grjI7/HmN+ixYO2FzEMcWr/On50UlQ/RjrWK1I/hPpWhpC76heCptnRFpH0LMwrEbUY50HDc0V8wg== zx@^7.2.3: version "7.2.3"