Skip to content

Sanitizing misidentifies diamond-shaped references as cycles #367

@SkelatorIndy

Description

@SkelatorIndy

This is a very similar issue to #348, but occurs when the same record is referenced from two different paths in a create call.

For example, this code results in the same type of validation error as #348:

import { Collection } from '@msw/data';
import * as v from 'valibot';

const profileSchema = v.object({
  id: v.string(),
  bio: v.string(),
});

const userSchema = v.object({
  id: v.string(),
  name: v.string(),
  get profile() { return profileSchema; },
});

const postSchema = v.object({
  id: v.string(),
  title: v.string(),
  get author() { return userSchema; },
  get editor() { return userSchema; },
});

const profiles = new Collection({ schema: profileSchema });
const users = new Collection({ schema: userSchema });
const posts = new Collection({ schema: postSchema });

users.defineRelations({ one }) => ({ profile: one(profiles) }));
posts.defineRelations({ one }) => ({
  author: one(users),
  editor: one(users),
}));

const profile = await profiles.create({ id: 'p1', bio: 'hi' });
const user = await users.create({ id: 'u1', name: 'Alice', profile });

// Diamond: same user referenced from two sibling fields
await posts.create({
  id: 'post1',
  title: 'Hello',
  author: user,
  editor: user,
});

In this setup, either author.profile or editor.profile will be undefined after sanitization.

From my testing, I've been able to fix the error by adding the following to the inner sanitize method within the #sanitizeInitialValues method:

const result = Object.fromEntries(...);

if (record && !isRevisit) {
  visited.delete(record[kPrimaryKey]);
}

return result;

I'd be happy to open up a PR with the change if that would be helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions