Skip to content

chore(deps): update zod to v4#105

Draft
renovate[bot] wants to merge 7 commits intomainfrom
renovate/zod-4.x
Draft

chore(deps): update zod to v4#105
renovate[bot] wants to merge 7 commits intomainfrom
renovate/zod-4.x

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Nov 3, 2025

Note: This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
zod (source) 3.25.764.3.5 age confidence

Release Notes

colinhacks/zod (zod)

v4.3.5

Compare Source

Commits:

v4.3.4

Compare Source

Commits:

v4.3.3

Compare Source

v4.3.2

Compare Source

v4.3.1

Compare Source

Commits:

  • 0fe8840 allow non-overwriting extends with refinements. 4.3.1

v4.3.0

Compare Source

This is Zod's biggest release since 4.0. It addresses several of Zod's longest-standing feature requests.

z.fromJSONSchema()

Convert JSON Schema to Zod (#​5534, #​5586)

You can now convert JSON Schema definitions directly into Zod schemas. This function supports JSON Schema "draft-2020-12", "draft-7", "draft-4", and OpenAPI 3.0.

import * as z from "zod";

const schema = z.fromJSONSchema({
  type: "object",
  properties: {
    name: { type: "string", minLength: 1 },
    age: { type: "integer", minimum: 0 },
  },
  required: ["name"],
});

schema.parse({ name: "Alice", age: 30 }); // ✅

The API should be considered experimental. There are no guarantees of 1:1 "round-trip soundness": MySchema > z.toJSONSchema() > z.fromJSONSchema(). There are several features of Zod that don't exist in JSON Schema and vice versa, which makes this virtually impossible.

Features supported:

  • All primitive types (string, number, integer, boolean, null, object, array)
  • String formats (email, uri, uuid, date-time, date, time, ipv4, ipv6, and more)
  • Composition (anyOf, oneOf, allOf)
  • Object constraints (additionalProperties, patternProperties, propertyNames)
  • Array constraints (prefixItems, items, minItems, maxItems)
  • $ref for local references and circular schemas
  • Custom metadata is preserved

z.xor() — exclusive union (#​5534)

A new exclusive union type that requires exactly one option to match. Unlike z.union() which passes if any option matches, z.xor() fails if zero or more than one option matches.

const schema = z.xor([z.string(), z.number()]);

schema.parse("hello"); // ✅
schema.parse(42);      // ✅
schema.parse(true);    // ❌ zero matches

When converted to JSON Schema, z.xor() produces oneOf instead of anyOf.

z.looseRecord() — partial record validation (#​5534)

A new record variant that only validates keys matching the key schema, passing through non-matching keys unchanged. This is used to represent patternProperties in JSON Schema.

const schema = z.looseRecord(z.string().regex(/^S_/), z.string());

schema.parse({ S_name: "John", other: 123 });
// ✅ { S_name: "John", other: 123 }
// only S_name is validated, "other" passes through

.exactOptional() — strict optional properties (#​5589)

A new wrapper that makes a property key-optional (can be omitted) but does not accept undefined as an explicit value.

const schema = z.object({
  a: z.string().optional(),      // accepts `undefined`
  b: z.string().exactOptional(), // does not accept `undefined`
});

schema.parse({});                  // ✅
schema.parse({ a: undefined });    // ✅
schema.parse({ b: undefined });    // ❌

This makes it possible to accurately represent the full spectrum of optionality expressible using exactOptionalPropertyTypes.

.apply()

A utility method for applying arbitrary transformations to a schema, enabling cleaner schema composition. (#​5463)

const setCommonChecks = <T extends z.ZodNumber>(schema: T) => {
  return schema.min(0).max(100);
};

const schema = z.number().apply(setCommonChecks).nullable();

.brand() cardinality

The .brand() method now accepts a second argument to control whether the brand applies to input, output, or both. Closes #​4764, #​4836.

// output only (default)
z.string().brand<"UserId">();           // output is branded (default)
z.string().brand<"UserId", "out">();    // output is branded
z.string().brand<"UserId", "in">();     // input is branded
z.string().brand<"UserId", "inout">();  // both are branded

Type predicates on .refine() (#​5575)

The .refine() method now supports type predicates to narrow the output type:

const schema = z.string().refine((s): s is "a" => s === "a");

type Input = z.input<typeof schema>;   // string
type Output = z.output<typeof schema>; // "a"

ZodMap methods: min, max, nonempty, size (#​5316)

ZodMap now has parity with ZodSet and ZodArray:

const schema = z.map(z.string(), z.number())
  .min(1)
  .max(10)
  .nonempty();

schema.size; // access the size constraint

.with() alias for .check() (359c0db)

A new .with() method has been added as a more readable alias for .check(). Over time, more APIs have been added that don't qualify as "checks". The new method provides a readable alternative that doesn't muddy semantics.

z.string().with(
  z.minLength(5),
  z.toLowerCase()
);

// equivalent to:
z.string().check(
  z.minLength(5),
  z.trim(),
  z.toLowerCase()
);
z.slugify() transform

Transform strings into URL-friendly slugs. Works great with .with():

// Zod
z.string().slugify().parse("Hello World");           // "hello-world"

// Zod Mini
// using .with() for explicit check composition
z.string().with(z.slugify()).parse("Hello World");   // "hello-world"

z.meta() and z.describe() in Zod Mini (947b4eb)

Zod Mini now exports z.meta() and z.describe() as top-level functions for adding metadata to schemas:

import * as z from "zod/mini";

// add description
const schema = z.string().with(
  z.describe("A user's name"),
);

// add arbitrary metadata
const schema2 = z.number().with(
  z.meta({ deprecated: true })
);

New locales

import * as z from "zod";
import { uz } from "zod/locales";

z.config(uz());






Bug fixes

All of these changes fix soundness issues in Zod. As with any bug fix there's some chance of breakage if you were intentionally or unintentionally relying on this unsound behavior.

⚠️ .pick() and .omit() disallowed on object schemas containing refinements (#​5317)

Using .pick() or .omit() on object schemas with refinements now throws an error. Previously, this would silently drop the refinements, leading to unexpected behavior.

const schema = z.object({
  password: z.string(),
  confirmPassword: z.string(),
}).refine(data => data.password === data.confirmPassword);

schema.pick({ password: true });
// 4.2: refinement silently dropped ⚠️
// 4.3: throws error ❌

Migration: The easiest way to migrate is to create a new schema using the shape of the old one.

const newSchema = z.object(schema.shape).pick({ ... })
⚠️ .extend() disallowed on refined schemas (#​5317)

Similarly, .extend() now throws on schemas with refinements. Use .safeExtend() if you need to extend refined schemas.

const schema = z.object({ a: z.string() }).refine(/* ... */);

// 4.2: refinement silently dropped ⚠️
// 4.3: throws error ✅
schema.extend({ b: z.number() });
// error: object schemas containing refinements cannot be extended. use `.safeExtend()` instead.
⚠️ Stricter object masking methods (#​5581)

Object masking methods (.pick(), .omit()) now validate that the keys provided actually exist in the schema:

const schema = z.object({ a: z.string() });

// 4.3: throws error for unrecognized keys
schema.pick({ nonexistent: true });
// error: unrecognized key: "nonexistent"

Additional changes

  • Fixed JSON Schema generation for z.iso.time with minute precision (#​5557)
  • Fixed error details for tuples with extraneous elements (#​5555)
  • Fixed includes method params typing to accept string | $ZodCheckIncludesParams (#​5556)
  • Fixed numeric formats error messages to be inclusive (#​5485)
  • Fixed implementAsync inferred type to always be a promise (#​5476)
  • Tightened E.164 regex to require a non-zero leading digit and 7–15 digits total (#​5524)
  • Fixed Dutch (nl) error strings (#​5529)
  • Convert Date instances to numbers in minimum/maximum checks (#​5351)
  • Improved numeric keys handling in z.record() (#​5585)
  • Lazy initialization of ~standard schema property (#​5363)
  • Functions marked as @__NO_SIDE_EFFECTS__ for better tree-shaking (#​5475)
  • Improved metadata tracking across child-parent relationships (#​5578)
  • Improved locale translation approach (#​5584)
  • Dropped id uniqueness enforcement at registry level (#​5574)

v4.2.1

Compare Source

v4.2.0

Compare Source

Features

Implement Standard JSON Schema

standard-schema/standard-schema#134

Implement z.fromJSONSchema()
const jsonSchema = {
  type: "object",
  properties: {
    name: { type: "string" },
    age: { type: "number" }
  },
  required: ["name"]
};

const schema = z.fromJSONSchema(jsonSchema);
Implement z.xor()
const schema = z.xor(
  z.object({ type: "user", name: z.string() }),
  z.object({ type: "admin", role: z.string() })
);
// Exactly one of the schemas must match
Implement z.looseRecord()
const schema = z.looseRecord(z.string(), z.number());
// Allows additional properties beyond those defined

Commits:

v4.1.13

Compare Source

v4.1.12

Compare Source

Commits:

v4.1.11

Compare Source

Commits:

v4.1.10

Compare Source

Commits:

v4.1.9

Compare Source

Commits:

v4.1.8

Compare Source

Commits:

v4.1.7

Compare Source

Commits:

v4.1.6

Compare Source

v4.1.5

Compare Source

Commits:

v4.1.4

Compare Source

Commits:

  • 3291c61 fix(v4): toJSONSchema - wrong tuple with null output when targeting openapi-3.0 (#​5156)
  • 23f41c7 test(v4): toJSONSchema - use validateOpenAPI30Schema in all relevant scenarios (#​5163)
  • 0a09fd2 Update installation instructions
  • 4ea5fec 4.1.4

v4.1.3

Compare Source

Commits:

  • 98ff675 Drop stringToBoolean
  • a410616 Fix typo
  • 0cf4589 fix(v4): toJSONSchema - add missing oneOf inside items in tuple conversion (#​5146)
  • 8bf0c16 fix(v4): toJSONSchema tuple path handling for draft-7 with metadata IDs (#​5152)
  • 5c5fa90 fix(v4): toJSONSchema - wrong record output when targeting openapi-3.0 (#​5141)
  • 87b97cc docs(codecs): update example to use payloadSchema (#​5150)
  • 309f358 fix(v4): toJSONSchema - output numbers with exclusive range correctly when targeting openapi-3.0 (#​5139)
  • 1e71ca9 docs: fix refine fn to encode works properly (#​5148)
  • a85ec3c fix(docs): correct example to use LooseDog instead of Dog (#​5136)
  • 3e98274 4.1.3

v4.1.2

Compare Source

Commits:

v4.1.1

Compare Source

Commits:

v4.1.0

Compare Source

The first minor version since the introduction of Zod 4 back in May. This version contains a number of features that barely missed the cut for the 4.0 release. With Zod 4 stable and widely adopted, there's more time to resume feature development.

Codecs

This is the flagship feature of this release. Codecs are a new API & schema type that encapsulates a bi-directional transformation. It's a huge missing piece in Zod that's finally filled, and it unlocks some totally new ways to use Zod.

const stringToDate = z.codec(
  z.iso.datetime(),  // input schema: ISO date string
  z.date(),          // output schema: Date object
  {
    decode: (isoString) => new Date(isoString), 
    encode: (date) => date.toISOString(),
  }
);

New top-level functions are added for processing inputs in the forward direction ("decoding") and backward direction ("encoding").

stringToDate.decode("2025-08-21T20:59:45.500Z")
// => Date

stringToDate.encode(new Date())
// => "2025-08-21T20:59:45.500Z"

Note — For bundle size reasons, these new methods have not added to Zod Mini schemas. Instead, this functionality is available via equivalent top-level functions.

// equivalent at runtime
z.decode(stringToDate, "2024-01-15T10:30:00.000Z");
z.encode(stringToDate, new Date());
.parse() vs .decode()

Both .parse() and decode() process data in the "forward" direction. They behave identically at runtime.

stringToDate.parse("2025-08-21T20:59:45.500Z");
stringToDate.decode("2025-08-21T20:59:45.500Z");

There is an important difference however. While .parse() accepts any input, .decode() expects a strongly typed input. That is, it expects an input of type string, whereas .parse() accepts unknown.

stringToDate.parse(Symbol('not-a-string'));
// => fails at runtime, but no TypeScript error

stringToDate.decode(Symbol("not-a-string"));
//                     ^ ❌ Argument of type 'symbol' is not assignable to parameter of type 'Date'. ts(2345)

This is a highly requested feature unto itself:

Encoding

You can use any Zod schema with .encode(). The vast majority of Zod schemas are non-transforming (the input and output types are identical) so .decode() and .encode() behave identically. Only certain schema types change their behavior:

  • Codecs — runs from B->A and executes the encode transform during encoding
  • Pipes — these execute B->A instead of A->B
  • Defaults and prefaults — Only applied in the forward direction
  • Catch — Only applied in the forward direction

Note — To avoid increasing bundle size unnecessarily, these new methods are not available on Zod Mini schemas. For those schemas, equivalent top-level functions are provided.

The usual async and safe variants exist as well:

// decode methods
stringToDate.decode("2024-01-15T10:30:00.000Z")
await stringToDate.decodeAsync("2024-01-15T10:30:00.000Z")
stringToDate.safeDecode("2024-01-15T10:30:00.000Z")
await stringToDate.safeDecodeAsync("2024-01-15T10:30:00.000Z")

// encode methods
stringToDate.encode(new Date())
await stringToDate.encodeAsync(new Date())
stringToDate.safeEncode(new Date())
await stringToDate.safeEncodeAsync(new Date())
Example codecs

Below are some "worked examples" for some commonly-needed codecs. These examples are all tested internally for correctness. Just copy/paste them into your project as needed. There is a more comprehensive set available at zod.dev/codecs.

stringToBigInt

Converts bigint into a serializable form.

const stringToBigInt = z.codec(z.string(), z.bigint(), {
  decode: (str) => BigInt(str),
  encode: (bigint) => bigint.toString(),
});

stringToBigInt.decode("12345");  // => 12345n
stringToBigInt.encode(12345n);   // => "12345"
json

Parses/stringifies JSON data.

const jsonCodec = z.codec(z.string(), z.json(), {
  decode: (jsonString, ctx) => {
    try {
      return JSON.parse(jsonString);
    } catch (err: any) {
      ctx.issues.push({
        code: "invalid_format",
        format: "json_string",
        input: jsonString,
        message: err.message,
      });
      return z.NEVER;
    }
  },
  encode: (value) => JSON.stringify(value),
});

To further validate the data, .pipe() the result of this codec into another schema.

const Params = z.object({ name: z.string(), age: z.number() });
const JsonToParams = jsonCodec.pipe(Params);

JsonToParams.decode('{"name":"Alice","age":30}');  // => { name: "Alice", age: 30 }
JsonToParams.encode({ name: "Bob", age: 25 });     // => '{"name":"Bob","age":25}'
Further reading

For more examples and a technical breakdown of how encoding works, reads theannouncement blog post and new Codecs docs page. The docs page contains implementations for several other commonly-needed codecs:

.safeExtend()

The existing way to add additional fields to an object is to use .extend().

const A = z.object({ a: z.string() })
const B = A.extend({ b: z.string() })

Unfortunately this is a bit of a misnomer, as it allows you to overwrite existing fields. This means the result of .extend() may not literally extend the original type (in the TypeScript sense).

const A = z.object({ a: z.string() }) // { a: string }
const B = A.extend({ a: z.number() }) // { a: number }

To enforce true extends logic, Zod 4.1 introduces a new .safeExtend() method. This statically enforces that the newly added properties conform to the existing ones.

z.object({ a: z.string() }).safeExtend({ a: z.number().min(5) }); // ✅
z.object({ a: z.string() }).safeExtend({ a: z.any() }); // ✅
z.object({ a: z.string() }).safeExtend({ a: z.number() });
//                                       ^  ❌ ZodNumber is not assignable 

Importantly, this new API allows you to safely extend objects containing refinements.

const AB = z.object({ a: z.string(), b: z.string() }).refine(val => val.a === val.b);
const ABC = AB.safeExtend({ c: z.string() });
// ABC includes the refinements defined on AB

Previously (in Zod 4.x) any refinements attached to the base schema were dropped in the extended result. This was too unexpected. It now throws an error. (Zod 3 did not support extension of refined objects either.)

z.hash()

A new top-level string format for validating hashes produced using various common algorithms & encodings.

const md5Schema = z.hash("md5");          
// => ZodCustomStringFormat<"md5_hex">

const sha256Base64 = z.hash("sha256", { enc: "base64" }); 
// => ZodCustomStringFormat<"sha256_base64">

The following hash algorithms and encodings are supported. Each cell provides information about the expected number of characters/padding.

Algorithm / Encoding "hex" "base64" "base64url"
"md5" 32 24 (22 + "==") 22
"sha1" 40 28 (27 + "=") 27
"sha256" 64 44 (43 + "=") 43
"sha384" 96 64 (no padding) 64
"sha512" 128 88 (86 + "==") 86

z.hex()

To validate hexadecimal strings of any length.

const hexSchema = z.hex();

hexSchema.parse("123abc");    // ✅ "123abc"
hexSchema.parse("DEADBEEF");  // ✅ "DEADBEEF" 
hexSchema.parse("xyz");       // ❌ ZodError

Additional changes

  1. z.uuid() now supports the "Max UUID" (FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF) per the RFC
  2. $ZodFunction is now a subtype of $ZodType

Commits

v4.0.17

Compare Source

Commits:

v4.0.16

Compare Source

Commits:

v4.0.15

Compare Source

Commits:

v4.0.14

Compare Source

Commits:

v4.0.13

Compare Source

Commits:

v4.0.12

Compare Source

Commits:

v4.0.11

Compare Source

Commits:

v4.0.10

Compare Source

Commits:

v4.0.9

Compare Source

Commits:

v4.0.8

Compare Source

Commits:

v4.0.7

Compare Source

Commits:

v4.0.6

Compare Source

Commits:

v4.0.5

Compare Source

Commits:

v4.0.4

Compare Source

Commits:

  • 9335f05 Adds ZodFirstPartyTypeKind stub to fix module resolution failure inside zod-to-json-schema

v4.0.3

[Compare Source](https://redirect.github.com/colinhacks/zod/compare/44a936cb77961e57a0988d8a3c63d9c71fce69ac...v4


Configuration

📅 Schedule: Branch creation - "before 9am on Monday" in timezone UTC, Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of explicit nulls and defaults for input variables across blocks.
  • Refactor

    • Updated validation dependency to a newer major release.
    • Tightened schema shapes and map typings for more consistent validation and public schema shapes.
  • Tests

    • Added coverage to ensure unknown-integration metadata is propagated into environment variables.
  • Chores

    • Added "prefault" to project dictionary.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

📝 Walkthrough

Walkthrough

Zod upgraded from 3.25.76 to 4.3.5 in packages/blocks, packages/database-integrations, and packages/reactivity (import path updated). deepnote-file-schema.ts tightens map types to string-keyed records, replaces many .default({}) with .prefault({}), and switches various input block defaults to nullish-aware schemas with transform/removeNullDeepnoteVariableDefaultValue pipelines. environmentSchema.packages and executionSchema.inputs now use string-keyed records. A test was added to propagate unknown integration metadata into generated env vars. cspell.json added "prefault" to the word list.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title directly and clearly summarizes the main change: updating the zod dependency from v3 to v4 across multiple packages.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9f5bdee and b90d059.

📒 Files selected for processing (1)
  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Place test files next to source files with .test.ts or .test.tsx extension
Use strict type checking in TypeScript files
Prefer type safety over convenience in TypeScript
Use const for immutable values
Avoid any types - use proper type definitions
Follow Biome's rules (configured in biome.json)
Use literal keys instead of bracket notation when possible
Prefer single quotes for strings (except when avoiding escapes)
Keep code clean and readable following Biome standards

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
packages/blocks/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/blocks/src/**/*.{ts,tsx}: Use escapePythonString() for safely embedding strings in Python code in the blocks package
Use ts-dedent for clean multiline template strings in code generation
Always include DataFrame config when generating code for code/SQL blocks

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
🔇 Additional comments (2)
packages/blocks/src/deserialize-file/deepnote-file-schema.ts (2)

451-465: environmentSchema.packages: v4 record typing looks correct; verify callers don’t pass non-string values.
This will now reject values that aren’t strings (which is probably desired).


489-499: executionSchema.inputs: string-keyed record is good; consider whether values should be unknown vs a narrower schema.
As-is, this is an explicit “bag of inputs” and matches JSON realities.


Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Nov 3, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.49%. Comparing base (a117b0f) to head (b90d059).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #105      +/-   ##
==========================================
- Coverage   91.52%   91.49%   -0.03%     
==========================================
  Files          40       40              
  Lines        2029     2022       -7     
  Branches      623      638      +15     
==========================================
- Hits         1857     1850       -7     
  Misses        172      172              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@renovate renovate bot force-pushed the renovate/zod-4.x branch 7 times, most recently from fe55215 to 731f4d7 Compare November 4, 2025 13:03
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b3c030b and 731f4d7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • packages/blocks/package.json (1 hunks)
  • packages/database-integrations/package.json (1 hunks)
🔇 Additional comments (1)
packages/database-integrations/package.json (1)

35-35: No issues found — zod v4 is compatible with this package.

The main user-facing breaking change is default handling with .default().optional(), which this codebase doesn't use. Deprecated methods like .strict() remain available for backwards compatibility. The database-integrations package only contains schema definitions using z.object(), z.string(), .optional(), .extend(), z.record(), and type inference—all fully supported in v4.

@renovate renovate bot force-pushed the renovate/zod-4.x branch 2 times, most recently from 1817727 to 2d62ae2 Compare November 4, 2025 17:10
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 731f4d7 and 2d62ae2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • packages/blocks/package.json (1 hunks)
  • packages/database-integrations/package.json (1 hunks)
🔇 Additional comments (1)
packages/database-integrations/package.json (1)

35-35: Zod v4 appears compatible; confirm tests pass before merging.

The package uses only stable zod APIs (z.object, z.string, z.literal, z.optional, z.discriminatedUnion, z.infer, z.ZodSchema) with no deprecated error patterns or .nonstrict() calls. However, run npm test in packages/database-integrations/ to verify the 100+ .safeParse() calls in the test suite work with v4.1.12.

@renovate renovate bot force-pushed the renovate/zod-4.x branch from 2d62ae2 to fad71f5 Compare November 4, 2025 18:43
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2d62ae2 and fad71f5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • packages/blocks/package.json (1 hunks)
  • packages/database-integrations/package.json (1 hunks)
🔇 Additional comments (1)
packages/database-integrations/package.json (1)

35-35: No schema changes needed for zod v4 upgrade.

Verification found no z.record() calls in database-integrations. Schemas use z.object() and z.discriminatedUnion() exclusively, which have no breaking changes in zod v4. Safe to proceed.

@renovate renovate bot force-pushed the renovate/zod-4.x branch 6 times, most recently from 546f302 to 41c52d2 Compare November 10, 2025 07:52
@renovate renovate bot force-pushed the renovate/zod-4.x branch 3 times, most recently from b5da804 to 879e0e7 Compare November 11, 2025 14:35
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Fix all issues with AI Agents 🤖
In @packages/database-integrations/package.json:
- Line 35: Update the import in database-integration-config.ts to use Zod's
named export: replace the default import `import z from 'zod'` with `import { z
} from 'zod'` so Zod v4's named export is used; then rebuild/verify any usages
of `z` (e.g., schema declarations) still reference the same identifier and run
tests/typecheck to confirm compatibility.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6e782c4 and c2f4f3a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/blocks/package.json
  • packages/database-integrations/package.json
  • packages/reactivity/package.json
🔇 Additional comments (2)
packages/reactivity/package.json (1)

36-36: No action needed. Verified that ast-analyzer.ts uses the correct named import pattern (import { z } from 'zod') compatible with zod v4.3.5.

packages/blocks/package.json (1)

37-37: No changes needed; z.record() usage is valid in Zod v4.

The code's single-arg z.record() calls (lines 14, 27, 65 in deepnote-file-schema.ts) are fully compatible with Zod v4. Both single-arg form z.record(schema) and two-arg form z.record(keySchema, valueSchema) are supported; the former defaults the key schema to z.string(). No breaking API changes are present.

Version 4.3.5 in package.json is correct.

Likely an incorrect or invalid review comment.

@renovate renovate bot force-pushed the renovate/zod-4.x branch 2 times, most recently from 9490a33 to 9a4a026 Compare January 5, 2026 15:54
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Fix all issues with AI Agents 🤖
In @packages/blocks/package.json:
- Line 37: Replace the single-argument z.record(...) calls with the Zod v4
two-argument form by explicitly passing a key schema of z.string() and the
appropriate value schema: change the first occurrence to z.record(z.string(),
z.any()), the second to z.record(z.string(), z.string()), and the third to
z.record(z.string(), z.unknown()); ensure the file imports z from "zod" and
update each schema usage accordingly.

In @packages/database-integrations/package.json:
- Line 35: The import in database-integration-config.ts is using a default
import from Zod which no longer exists in v4; update the top-level import
statement from a default import to a named import so it reads with the named
symbol z (i.e., replace the current import of z with an import that uses { z }
from 'zod') to match Zod v4's exports and prevent runtime/compile errors.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9490a33 and 9a4a026.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/blocks/package.json
  • packages/database-integrations/package.json
  • packages/reactivity/package.json
🔇 Additional comments (1)
packages/reactivity/package.json (1)

36-36: Zod v4.3.5 compatibility confirmed.

Named imports are correctly used (import { z } from 'zod'), no invalid default imports present, and all z.record() calls have proper argument counts. No compatibility issues detected.

@renovate renovate bot force-pushed the renovate/zod-4.x branch from 9a4a026 to 607236c Compare January 6, 2026 14:27
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI Agents
In @packages/blocks/package.json:
- Line 37: The z.record() calls use the old single-argument v3 API and must be
updated for zod v4: replace the three occurrences accordingly—change the call
that uses z.record(z.any()) to z.record(z.string(), z.any()), change the call
using z.record(z.string()) to z.record(z.string(), z.string()), and change the
call using z.record(z.unknown()) to z.record(z.string(), z.unknown()); update
the specific functions/variables where these records are declared so the key
type (z.string()) is the first argument and the value schema is the second.

In @packages/database-integrations/package.json:
- Line 35: Change the invalid default import in database-integration-config.ts
to the named import required by zod v4: replace any occurrence of "import z from
'zod'" with the named import form "import { z } from 'zod'"; ensure this matches
usage in database-integration-metadata-schemas.ts and update any references in
functions or types that expect the named z symbol (e.g., where z.object,
z.string, etc. are used).
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9a4a026 and 607236c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/blocks/package.json
  • packages/database-integrations/package.json
  • packages/reactivity/package.json
🔇 Additional comments (1)
packages/reactivity/package.json (1)

36-36: Version correct—Zod v4 API verified.

Bump to 4.3.5 confirmed compatible. Named imports and 2-arg z.record() usage verified in all source files.

@renovate renovate bot force-pushed the renovate/zod-4.x branch from 607236c to 4b263fb Compare January 7, 2026 17:51
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @packages/database-integrations/package.json:
- Line 35: database-integration-config.ts currently uses a default import
"import z from 'zod'", which is invalid for Zod v4; change the import to the
named export form "import { z } from 'zod'" (keep all existing uses of the z
identifier unchanged) so that the module loads correctly with the declared Zod
version.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 607236c and 4b263fb.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/blocks/package.json
  • packages/database-integrations/package.json
  • packages/reactivity/package.json
🔇 Additional comments (2)
packages/reactivity/package.json (1)

36-36: Version correct—matches PR objectives (4.3.5).

packages/blocks/package.json (1)

37-37: Verify z.record() calls are v4-compatible.

Zod v4.3.5 requires z.record(keySchema, valueSchema) with two arguments. If deepnote-file-schema.ts still uses single-arg z.record() calls from v3, they will fail at runtime.

@renovate renovate bot force-pushed the renovate/zod-4.x branch 2 times, most recently from 0e8393c to 5f4851a Compare January 8, 2026 13:34
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @packages/blocks/package.json:
- Line 37: Zod v4 changed z.record() to require a key schema and a value schema;
update each z.record(...) call in the deepnote file schema so keys are explicit
strings: replace z.record(z.any()) with z.record(z.string(), z.any()),
z.record(z.string()) with z.record(z.string(), z.string()), and
z.record(z.unknown()) with z.record(z.string(), z.unknown()). Locate and update
the eight occurrences of z.record in deepnote-file-schema (the ones using
z.any(), z.string() single-arg, or z.unknown()) so the first argument is
z.string() and the second is the existing value schema.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4b263fb and 5f4851a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/blocks/package.json
  • packages/database-integrations/package.json
  • packages/reactivity/package.json
🔇 Additional comments (2)
packages/reactivity/package.json (1)

36-36: Fix inconsistent Zod imports—mixing v3 compatibility layer with v4 native API.

types.ts imports zod/v3 (compatibility layer), while ast-analyzer.ts uses native zod. Schemas are simple and won't hit the breaking changes mentioned, but imports should be consistent. Migrate all files to either the native v4 API or keep the v3 compatibility layer throughout.

Likely an incorrect or invalid review comment.

packages/database-integrations/package.json (1)

35-35: No Zod v4 breaking changes detected in this package.

The codebase only uses .extend() for discriminated union schemas, which is compatible with Zod v4. No unsafe patterns (.refine(), .transform(), .pick(), .omit(), .record(), or .default()) were found.

@renovate renovate bot force-pushed the renovate/zod-4.x branch from 5f4851a to 47e3b2d Compare January 8, 2026 14:22
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @packages/reactivity/package.json:
- Line 36: The project mixes Zod import paths: one file imports from "zod/v3"
and another from "zod", causing inconsistency; update the import in types.ts
(the import that currently uses "zod/v3") to use the top-level "zod" export to
match ast-analyzer.ts (or vice versa if you prefer v3 for all files), and ensure
all Zod usages (e.g., ZodSchema, z.object, z.string, z.array, z.optional,
z.infer) across files are imported from the same module path (types.ts and
ast-analyzer.ts) so the codebase uses a single standardized Zod import path.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5f4851a and 47e3b2d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/blocks/package.json
  • packages/database-integrations/package.json
  • packages/reactivity/package.json
🔇 Additional comments (2)
packages/blocks/package.json (1)

37-37: Verify Zod v4 compatibility.

Breaking changes require validation: object masking methods stricter, record schemas need both arguments, number/UUID validation tighter.

packages/database-integrations/package.json (1)

35-35: No Zod v4 compatibility issues found.

The codebase uses only patterns compatible with Zod v4.3.5: .extend() for schema composition, .enum() with array literals, and standard modifiers like .nullable() and .optional(). No breaking patterns detected.

@renovate renovate bot force-pushed the renovate/zod-4.x branch from 47e3b2d to ab7fd50 Compare January 8, 2026 14:27
@tkislan tkislan self-assigned this Jan 8, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @packages/blocks/src/deserialize-file/deepnote-file-schema.test.ts:
- Around line 22-28: The test uses expect(oldResult.data).toBe(expected) which
fails for arrays because toBe uses Object.is; replace that assertion with
expect(oldResult.data).toStrictEqual(expected) and keep the subsequent
comparisons between oldResult and newResult as-is (they already use
toStrictEqual) so arrays are compared deeply; update the assertion in the test
block that references oldResult.data.

In @packages/blocks/src/deserialize-file/deepnote-file-schema.ts:
- Line 262: The pipeline is failing because the new Zod v4 method name
'prefault' is not in the code spellchecker dictionary; open the cspell.json (or
your project's spellchecker config) and add the token "prefault" to the words
array (ensure exact casing 'prefault'), then commit the updated cspell.json so
references like .prefault({}) in deepnote-file-schema.ts are accepted.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 47e3b2d and 62cff17.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • packages/blocks/package.json
  • packages/blocks/src/deserialize-file/deepnote-file-schema.test.ts
  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
  • packages/database-integrations/package.json
  • packages/database-integrations/src/database-integration-env-vars.test.ts
  • packages/reactivity/package.json
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Place test files next to source files with .test.ts or .test.tsx extension
Use strict type checking in TypeScript files
Prefer type safety over convenience in TypeScript
Use const for immutable values
Avoid any types - use proper type definitions
Follow Biome's rules (configured in biome.json)
Use literal keys instead of bracket notation when possible
Prefer single quotes for strings (except when avoiding escapes)
Keep code clean and readable following Biome standards

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.test.ts
  • packages/database-integrations/src/database-integration-env-vars.test.ts
  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Use Vitest as the testing framework
Follow existing test patterns in the codebase (see packages/blocks/src/blocks/*.test.ts)
Test edge cases, error handling, and special characters

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.test.ts
  • packages/database-integrations/src/database-integration-env-vars.test.ts
packages/blocks/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

For functions that generate code, test the exact output format

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.test.ts
packages/blocks/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/blocks/src/**/*.{ts,tsx}: Use escapePythonString() for safely embedding strings in Python code in the blocks package
Use ts-dedent for clean multiline template strings in code generation
Always include DataFrame config when generating code for code/SQL blocks

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.test.ts
  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
🪛 GitHub Actions: CI
packages/blocks/src/deserialize-file/deepnote-file-schema.test.ts

[error] 26-26: AssertionError: expected [ 'abc', 'def' ] to be [ 'abc', 'def' ] // Object.is equality. Use toStrictEqual for deep equality in tests.

packages/blocks/src/deserialize-file/deepnote-file-schema.ts

[error] 262-262: CSpell: Unknown word 'prefault' detected.


[error] 279-279: CSpell: Unknown word 'prefault' detected.


[error] 292-292: CSpell: Unknown word 'prefault' detected.


[error] 306-306: CSpell: Unknown word 'prefault' detected.


[error] 325-325: CSpell: Unknown word 'prefault' detected.

🔇 Additional comments (7)
packages/database-integrations/package.json (1)

35-35: LGTM.

Consistent zod v4 upgrade across packages.

packages/database-integrations/src/database-integration-env-vars.test.ts (1)

2953-2973: LGTM.

Good edge-case coverage for unknown integration metadata propagation.

packages/blocks/package.json (1)

37-37: LGTM.

Consistent zod v4 upgrade.

packages/blocks/src/deserialize-file/deepnote-file-schema.ts (3)

14-28: LGTM.

Clean helper for null removal from deepnote_variable_default_value. Type inference is correct.


54-57: Record type tightening.

Good alignment with Zod v4's requirement for explicit key schemas in z.record().


276-279: Clarify intent: .prefault({}) bypasses the transform.

When metadata is undefined, .prefault({}) provides a default that skips the removeNullDeepnoteVariableDefaultValue transform. When metadata is provided with deepnote_variable_default_value: null, the transform runs and removes the key. Confirm this inconsistency is intentional or consider restructuring to ensure consistent behavior.

packages/reactivity/package.json (1)

36-36: Zod v4 upgrade is safe for this package.

The specified breaking change patterns (.pick(), .omit(), .extend() on refinements; z.record()) are not used. Schemas rely only on z.object(), z.string(), z.array(), z.optional(), and z.union(), which are stable across v3 and v4. The zod/v3 import path in types.ts is a supported compatibility mechanism in Zod v4—no changes required.

@renovate
Copy link
Contributor Author

renovate bot commented Jan 8, 2026

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

@tkislan
Copy link
Contributor

tkislan commented Jan 8, 2026

@coderabbitai resolve

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 8, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

✅ Actions performed

Comments resolved and changes approved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @packages/blocks/src/deserialize-file/deepnote-file-schema.ts:
- Around line 14-28: The return type of removeNullDeepnoteVariableDefaultValue
is incorrect because when deepnote_variable_default_value is null the function
deletes that key at runtime but the signature still claims the key exists (with
null excluded); change the return type to reflect either the original T or T
with the key removed (e.g., T | Omit<T, 'deepnote_variable_default_value'> or a
conditional mapped type that yields Omit<T,'deepnote_variable_default_value'>
when the value is null), update the two return casts to use that
union/conditional type, and keep the runtime logic (destructuring removal) in
the function body.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7948cd2 and 9f5bdee.

📒 Files selected for processing (1)
  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Place test files next to source files with .test.ts or .test.tsx extension
Use strict type checking in TypeScript files
Prefer type safety over convenience in TypeScript
Use const for immutable values
Avoid any types - use proper type definitions
Follow Biome's rules (configured in biome.json)
Use literal keys instead of bracket notation when possible
Prefer single quotes for strings (except when avoiding escapes)
Keep code clean and readable following Biome standards

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
packages/blocks/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/blocks/src/**/*.{ts,tsx}: Use escapePythonString() for safely embedding strings in Python code in the blocks package
Use ts-dedent for clean multiline template strings in code generation
Always include DataFrame config when generating code for code/SQL blocks

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
🔇 Additional comments (3)
packages/blocks/src/deserialize-file/deepnote-file-schema.ts (3)

54-54: LGTM: Record types correctly updated for v4.

Explicit string keys align with Zod v4 requirements and improve type safety.

Also applies to: 57-57, 212-213, 225-225, 228-228, 478-478, 516-516


276-279: Nullish + transform pattern is consistent.

Normalizing null defaults across input blocks is sensible for v4 migration, assuming prefault is valid.

Also applies to: 289-292, 302-306, 316-325, 335-341, 351-356, 366-369


262-262: .prefault() is a valid Zod v4 method. It sets a pre-parse default (applied before validation), which appropriately handles null/invalid inputs before the schema validates. No issues here.

Comment on lines 14 to 28
function removeNullDeepnoteVariableDefaultValue<TValue, T extends { deepnote_variable_default_value?: TValue }>(
value: T
): {
[K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
} {
if (value.deepnote_variable_default_value === null) {
const { deepnote_variable_default_value: _, ...rest } = value
return rest as {
[K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
}
}
return value as {
[K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Return type doesn't reflect that the key is removed.

When deepnote_variable_default_value is null, the key is deleted (line 20), but the return type claims Exclude<T[K], null> for that key—implying it's still present. Runtime and type shape diverge.

♻️ Align the type with runtime behavior
-function removeNullDeepnoteVariableDefaultValue<TValue, T extends { deepnote_variable_default_value?: TValue }>(
-  value: T
-): {
-  [K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
-} {
+function removeNullDeepnoteVariableDefaultValue<TValue, T extends { deepnote_variable_default_value?: TValue }>(
+  value: T
+): Omit<T, 'deepnote_variable_default_value'> & {
+  deepnote_variable_default_value?: Exclude<TValue, null>
+} {
   if (value.deepnote_variable_default_value === null) {
     const { deepnote_variable_default_value: _, ...rest } = value
-    return rest as {
-      [K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
-    }
+    return rest as any
   }
-  return value as {
-    [K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
-  }
+  return value as any
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function removeNullDeepnoteVariableDefaultValue<TValue, T extends { deepnote_variable_default_value?: TValue }>(
value: T
): {
[K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
} {
if (value.deepnote_variable_default_value === null) {
const { deepnote_variable_default_value: _, ...rest } = value
return rest as {
[K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
}
}
return value as {
[K in keyof T]: K extends 'deepnote_variable_default_value' ? Exclude<T[K], null> : T[K]
}
}
function removeNullDeepnoteVariableDefaultValue<TValue, T extends { deepnote_variable_default_value?: TValue }>(
value: T
): Omit<T, 'deepnote_variable_default_value'> & {
deepnote_variable_default_value?: Exclude<TValue, null>
} {
if (value.deepnote_variable_default_value === null) {
const { deepnote_variable_default_value: _, ...rest } = value
return rest as Omit<T, 'deepnote_variable_default_value'> & {
deepnote_variable_default_value?: Exclude<TValue, null>
}
}
return value as Omit<T, 'deepnote_variable_default_value'> & {
deepnote_variable_default_value?: Exclude<TValue, null>
}
}
🤖 Prompt for AI Agents
In @packages/blocks/src/deserialize-file/deepnote-file-schema.ts around lines 14
- 28, The return type of removeNullDeepnoteVariableDefaultValue is incorrect
because when deepnote_variable_default_value is null the function deletes that
key at runtime but the signature still claims the key exists (with null
excluded); change the return type to reflect either the original T or T with the
key removed (e.g., T | Omit<T, 'deepnote_variable_default_value'> or a
conditional mapped type that yields Omit<T,'deepnote_variable_default_value'>
when the value is null), update the two return casts to use that
union/conditional type, and keep the runtime logic (destructuring removal) in
the function body.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (11)
packages/blocks/src/deserialize-file/deepnote-file-schema.ts (11)

26-43: Good Zod v4 record migration; consider z.unknown() over z.any() and sanity-check .extend() behavior.
The z.record(z.string(), …) changes look right for v4. If these payloads are truly opaque, z.unknown() is usually safer than z.any() (type-level). Also, please verify Zod v4 doesn’t object to .extend() on your .passthrough() objects in this file at runtime (some v4 changes tightened object operations).

Proposed tweak (type-safety only)
-    deepnote_table_state: z.record(z.string(), z.any()).optional(),
+    deepnote_table_state: z.record(z.string(), z.unknown()).optional(),
 ...
-    function_notebook_export_states: z.record(z.string(), z.any()).optional(),
+    function_notebook_export_states: z.record(z.string(), z.unknown()).optional(),

189-200: String-keyed records are correct here; same any vs unknown note.
Looks consistent with Zod v4 record typing. Consider z.unknown() unless you truly want any inference.

Proposed tweak (type-safety only)
-      function_notebook_inputs: z.record(z.string(), z.any()).optional(),
-      function_notebook_export_mappings: z.record(z.string(), z.any()).optional(),
+      function_notebook_inputs: z.record(z.string(), z.unknown()).optional(),
+      function_notebook_export_mappings: z.record(z.string(), z.unknown()).optional(),

202-215: Same: Zod v4 record keys look right; consider unknown.
No functional concerns beyond the any typing choice.

Proposed tweak (type-safety only)
-      deepnote_visualization_spec: z.record(z.string(), z.any()).optional(),
+      deepnote_visualization_spec: z.record(z.string(), z.unknown()).optional(),
 ...
-      deepnote_chart_filter: z.record(z.string(), z.any()).optional(),
+      deepnote_chart_filter: z.record(z.string(), z.unknown()).optional(),

231-247: .prefault({}) likely fixes v4 default short-circuiting; avoid shared-object defaults.
If any consumer mutates metadata, prefer a factory to avoid sharing the same {} across parses.

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),

253-276: Input text metadata: .prefault makes sense; confirm downstream accepts null default values.
.nullish() means deepnote_variable_default_value can now be null (not just absent). That’s fine if intentional (commit msg hints it is), but downstream should treat null consistently. Also: consider a factory for .prefault.

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),

277-289: Input checkbox: same nullish + prefault semantics; double-check consumer expectations for null.

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),

290-307: Input select: nullish defaults can be null (and array/string); verify downstream normalization.
If consumers previously relied on “missing/undefined only”, they now need to handle null (and possibly null vs [] semantics). Also: consider .prefault(() => ({})).

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),

308-322: Input slider: same prefault + nullish notes.

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),

323-336: Input date: same prefault + nullish notes.

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),

337-348: Input date-range: nullish allows null for both string/tuple variants; verify downstream handling.

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),

349-359: Input file: if .prefault({}) stays, prefer a factory to avoid shared objects.

Proposed tweak (avoid shared references)
-    .prefault({}),
+    .prefault(() => ({})),
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9f5bdee and b90d059.

📒 Files selected for processing (1)
  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Place test files next to source files with .test.ts or .test.tsx extension
Use strict type checking in TypeScript files
Prefer type safety over convenience in TypeScript
Use const for immutable values
Avoid any types - use proper type definitions
Follow Biome's rules (configured in biome.json)
Use literal keys instead of bracket notation when possible
Prefer single quotes for strings (except when avoiding escapes)
Keep code clean and readable following Biome standards

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
packages/blocks/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/blocks/src/**/*.{ts,tsx}: Use escapePythonString() for safely embedding strings in Python code in the blocks package
Use ts-dedent for clean multiline template strings in code generation
Always include DataFrame config when generating code for code/SQL blocks

Files:

  • packages/blocks/src/deserialize-file/deepnote-file-schema.ts
🔇 Additional comments (2)
packages/blocks/src/deserialize-file/deepnote-file-schema.ts (2)

451-465: environmentSchema.packages: v4 record typing looks correct; verify callers don’t pass non-string values.
This will now reject values that aren’t strings (which is probably desired).


489-499: executionSchema.inputs: string-keyed record is good; consider whether values should be unknown vs a narrower schema.
As-is, this is an explicit “bag of inputs” and matches JSON realities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant