Last active
November 11, 2025 19:07
-
-
Save severi/5d181a3e779f41a5e5fce1b7dcd17a89 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { z } from 'zod'; | |
| const VehicleSchema = z.object({ | |
| id: z.string(), | |
| itemType: z.literal('VEHICLE'), | |
| licencePlateNumber: z.string(), | |
| }); | |
| const HouseSchema = z.object({ | |
| id: z.string(), | |
| itemType: z.literal('HOUSE'), | |
| address: z.string(), | |
| city: z.string(), | |
| country: z.string(), | |
| }); | |
| const ItemModelZod = z.discriminatedUnion('itemType', [VehicleSchema, HouseSchema]); | |
| const ItemEntity = new Entity({ | |
| model: { | |
| entity: 'item', | |
| service: 'auth', | |
| version: '01', | |
| }, | |
| attributes: { | |
| id: { | |
| type: 'string', | |
| }, | |
| itemType: { | |
| type: 'string' | |
| }, | |
| /* | |
| also allow any other attributes to be inserted besides these two i.e. in this case | |
| - licencePlateNumber | |
| - address | |
| - city | |
| - country | |
| without having to explicitly define them here | |
| With for example large/complex discriminated unions keeping this up-to-date could be quite cumbersome | |
| and force us to basically list all the possible attributes that an item in the union might have | |
| One interesting option could of course be if these could be automatically created from the zod schema... | |
| */ | |
| }, | |
| indexes: { | |
| byItemType: { | |
| pk: { | |
| field: 'pk', | |
| composite: ['itemType'] | |
| }, | |
| sk: { | |
| field: 'sk', | |
| composite: ['id'] | |
| } | |
| } | |
| } | |
| }, { table, client }); | |
| const item = ItemModelZod.parse({ | |
| id: '123456', | |
| itemType: 'VEHICLE', | |
| licencePlateNumber: 'abcde', | |
| }); | |
| await ItemEntity.put(item).go(); |
+1
+1 anyone have a solution yet? Just starting to explore
Author
+1 anyone have a solution yet? Just starting to explore
Unfortunately not, see my answer here tywalch/electrodb#216 (reply in thread)
I just did something similar this week. I was googling to see if anyone had a better solution. Here’s what I came up with:
// Define Zod schema first
export const videoSchema = z.object({
slug: z.string().min(2).max(100),
bucket: z.string().min(2).max(100),
objectKey: z.string().min(2).max(100),
createdAt: z.string(),
title: z.string().min(5).max(100),
description: z.string().max(500),
tags: z.array(z.string()),
duration: z.number().gt(0),
thumbnail: z.string(),
videoUrl: z.string()
});
type ElectroDBAttribute = Attribute;
// Helper function to convert Zod schema to ElectroDB attributes
function zodToElectroDB(schema: z.ZodObject<z.ZodRawShape>) {
const attributes: Record<string, ElectroDBAttribute> = {};
Object.entries(schema.shape).forEach(([key, value]) => {
if (value instanceof z.ZodString) {
attributes[key] = { type: "string" };
} else if (value instanceof z.ZodNumber) {
attributes[key] = { type: "number" };
} else if (value instanceof z.ZodArray) {
attributes[key] = {
type: "list",
items: { type: "string" } // array of strings
};
}
// Add more type conversions as needed
});
return attributes;
}
// Create ElectroDB entity using the converted schema
export const Video = new Entity(
{
model: {
entity: "Video",
version: "1",
service: "videos",
},
attributes: zodToElectroDB(videoSchema),
indexes: {
byS3Key: {
pk: { field: "pk", composite: ["bucket"] },
sk: { field: "sk", composite: ["objectKey"] },
},
bySlug: {
index: "gsi1pk-gsi1sk-index",
pk: { field: "gsi1pk", composite: ["slug"] },
sk: { field: "gsi1sk", composite: ["slug"] },
},
},
},
{ client, table }
);I tried something similar awhile ago, but they main issue I have is that you'll loose Entity type-safety when using the get/update/set... methods. I started to work on a type helper to infer the type Entity attribute types from a Zod schema, but got nowhere.
In it case helps anyone, here is link to discussion with type inference / assertion solution that has been working quite well tywalch/electrodb#216 (comment)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm looking for exact the same thing: deriving the Electro schema from a Zod schema. Did you find a solution?