instantdb-react-ui
Version:
Customizable react components for InstantDB (forms/lists/etc.)
59 lines (58 loc) • 2.39 kB
JavaScript
import { z } from 'zod';
export const addZod = (input, zodSchema) => {
return {
...input,
zodSchema: zodSchema,
};
};
/** Zod schema for any Instant entity - requires an id field but allows any other properties */
export const generateZodEntitySchema = (message = 'This relation is required') => z.object({
id: z.string(),
}, { message }).passthrough();
/** Make an IDB link required with zod in the schema */
export const makeLinkRequired = (input, message) => {
const zodMessage = message || 'This relation is required';
if (input.cardinality === 'one') {
input.zodSchema = generateZodEntitySchema(zodMessage);
}
else {
input.zodSchema = z.array(generateZodEntitySchema(zodMessage)).min(1, { message: zodMessage });
}
};
/** Get all entity names from the schema */
export const getEntityNames = (schema) => Object.keys(schema.entities).reduce((acc, key) => ({ ...acc, [key]: key }), {});
/** Get all fields for a specific entity */
export const getEntityFields = (schema, entityName) => {
return Object.keys(schema.entities[entityName].attrs).reduce((acc, key) => ({ ...acc, [key]: key }), {});
};
// Example usage - const itemFields = getEntityFields(schema, 'items');
/** Get readable error message for field. Returns null if the field hasn't been touched */
export const getErrorMessageForField = (field) => {
if (!field.state.meta.isDirty)
return null;
return field.state.meta.errors.map(error => error.message).join(', ');
};
// Old example code of getting full details of an entity
// type EntityFields<Schema extends { entities: any }, T extends keyof Schema['entities']> =
// Record<
// keyof (typeof _schema['entities'][T]['attrs'] &
// typeof _schema['entities'][T]['links']),
// string
// >;
// function getEntities<Schema extends { entities: any }>(schema: Schema) {
// return Object.fromEntries(
// Object.keys(schema.entities).map(entityName => [
// entityName,
// Object.fromEntries(
// [...Object.keys(schema.entities[entityName].attrs),
// ...Object.keys(schema.entities[entityName].links)]
// .map(key => [key, key]),
// ),
// ]),
// ) as {
// [K in keyof Schema['entities']]: EntityFields<Schema, K>
// };
// }
// Example usage:
// export const AllEntities = getEntities(_schema);
// type Test2 = EntityFields<AppSchema, 'items'>;