sindresorhus / electron-store

Simple data persistence for your Electron app or module - Save and load user preferences, app state, cache, etc
MIT License
4.57k stars 148 forks source link

feature: compatibility with zod or similar #253

Open ArthurLobopro opened 1 year ago

ArthurLobopro commented 1 year ago

Hello, I recently discovered zod lib and used it in some projects. It's very easy create validation schemas and, in my opinion, more human friendly to use.

I've migrating some sistems for typescript and reciving a lot of errors related of schemas, it would be interesting if you could add some kind of compatibility with zod or similar more or less like this:

import Store from "electron-store"
import {z} from "zod"

const schema = {
    foo: z.number().min(1).max(100).default(50),
    bar: z.string().url()
}

const store = new Store({schema})
sindresorhus commented 1 year ago

You could use https://github.com/StefanTerdell/zod-to-json-schema for this.

ArthurLobopro commented 1 year ago

Apparently it not works correctly, see this case:

//Original Schema
type StoreOptions = {
    darkMode: boolean
    frameStyle: "windows" | "macos"
    frameTheme: "light" | "dark" | "auto"
}

export const optionsSchema: ElectronStore.Schema<StoreOptions> = {
    darkMode: {
        type: "boolean",
        default: true
    },
    frameStyle: {
        type: "string",
        enum: ["windows", "macos"],
        default: "windows"
    },
    frameTheme: {
        type: "string",
        enum: ["light", "dark", "auto"],
        default: "auto"
    }
}

It Works Correctly, now see it:

// Conversion to zod schema
const zodOptionsSchema = z.object({
    darkMode: z.boolean().default(true),
    frameStyle: z.enum(["windows", "macos"]).default("windows"),
    frameTheme: z.enum(["light", "dark", "auto"]).default("auto")
})

export const optionsSchema = zodToJsonSchema(zodOptionsSchema)

It's a correct conversion right? But it causes some type errors like "The types are incompatible"

Apparently zod-to-json-schema return types that not accepted by ElectronStore

jakst commented 1 year ago

Does it work if you define your optionsSchema like this?

// Conversion to zod schema
const zodOptionsSchema = z.object({
    darkMode: z.boolean().default(true),
    frameStyle: z.enum(["windows", "macos"]).default("windows"),
    frameTheme: z.enum(["light", "dark", "auto"]).default("auto")
})

type Options = z.infer<typeof zodOptionsSchema>

export const optionsSchema: ElectronStore.Schema<Options> = zodToJsonSchema(zodOptionsSchema)
ArthurLobopro commented 1 year ago

I get this error:

Type 'JsonSchema7Type & { $schema?: string | undefined; definitions?: { [key: string]: JsonSchema7Type; } | undefined; }' is not assignable to type 'Schema<{ darkMode: boolean; frameStyle: "windows" | "macos"; frameTheme: "light" | "dark" | "auto"; }>'.
  Type 'JsonSchema7Meta & { $schema?: string | undefined; definitions?: { [key: string]: JsonSchema7Type; } | undefined; }' is missing the following properties from type 'Schema<{ darkMode: boolean; frameStyle: "windows" | "macos"; frameTheme: "light" | "dark" | "auto"; }>': darkMode, frameStyle, frameTheme

On this line:

export const optionsSchema: ElectronStore.Schema<Options> = zodToJsonSchema(zodOptionsSchema)
anserwaseem commented 5 months ago

Did anyone find a good solution for it?

ArthurLobopro commented 5 months ago

Did anyone find a good solution for it?

I made a package called zod-electron-store, you can find on npm.