Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript support - Doesn't catch type issues like vanilla valtio proxy #4

Closed
rothnic opened this issue Sep 20, 2024 · 5 comments
Closed
Assignees

Comments

@rothnic
Copy link

rothnic commented Sep 20, 2024

Maybe I'm missing something, but it seems like this doesn't support typescript at the moment? I've used valtio before and was looking for something to help with data validation, but I feel like this now misses out on catching incompatible types. It seems I can't type the proxy like with valtio.

./types with original typescript type and zod schema/inferred type

import { z } from "zod";

export type ImageMetadataType = {
  base64: string;
  filename: string;
  tags: string[];
  title: string;
  contentType: string;
  width: number;
  height: number;
};

export type SelectFieldOption = { label: string; value: string };

// Base64 validation regex
const base64Regex =
  /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;

// Content type validation regex (matches any MIME type starting with 'image/')
const contentTypeRegex = /^image\/[a-zA-Z0-9+\.-]+$/;

// Filename validation regex (simple validation to exclude invalid filename characters)
const filenameRegex = /^[^<>:"/\\|?*\x00-\x1F]+$/;

// Define the ImageMetadata schema
export const ImageMetadataSchema = z.object({
  base64: z.string().regex(base64Regex, { message: "Invalid image data" }),
  filename: z
    .string({ required_error: "Filename cannot be empty" })
    .regex(filenameRegex, { message: "Filename contains invalid characters" }),
  tags: z.array(z.string({ required_error: "Tags cannot be empty strings" })),
  title: z.string({ required_error: "Title cannot be empty" }),
  contentType: z.string().regex(contentTypeRegex, {
    message:
      'Content type must start with "image/" and contain valid characters',
  }),
  width: z
    .number()
    .int({ message: "Width must be an integer" })
    .positive({ message: "Width must be a positive number" }),
  height: z
    .number()
    .int({ message: "Height must be an integer" })
    .positive({ message: "Height must be a positive number" }),
});

// Export the TypeScript type inferred from the schema
export type ImageMetadata = z.infer<typeof ImageMetadataSchema>;

Example valtio-zod vs valtio store setup with initial data (invalid base64 value)

image

If trying to use the same typing of proxy, it isn't supported like with valtio.

image
@rothnic
Copy link
Author

rothnic commented Sep 20, 2024

I did find i could separate the initial data and type it separately or specify the initial data inline {...} as ImageMetadata to catch the issue. Just thought it would be nice if it worked the same as valtio.

image

@overthemike overthemike self-assigned this Sep 25, 2024
@overthemike
Copy link
Collaborator

overthemike commented Sep 25, 2024

Sorry for the delay - I published a patch to hopefully fix this (0.7.5).

Just FYI: This package is still pretty new and in development and it doesn't have many tests in place to verify everything working correctly. Feel free to play around with it and report anything you find (much appreciated!), however it might be a bit early to use in any important projects.

@rothnic
Copy link
Author

rothnic commented Sep 26, 2024

Thanks! I'll take a look at it. Yeah, this was for a small CMS plugin to do some basic cropping and metadata collection for images and thought it would be interesting to try separating the state and data validation from the UI component, so no worries.

@overthemike
Copy link
Collaborator

Hope it works! Let me know if you run into issues.

@overthemike
Copy link
Collaborator

overthemike commented Oct 8, 2024

Just getting back to thinking about this lib again - and something occurred to me about this issue...there's no reason we can't use z.infer to grab the type defs directly from zod object passed into schema. Basically do what you're doing in your type definitions file. There's no reason to make the lib user do this and make them pass a type. I'll make an issue for this.

#5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants