kanel
Source of truth: PostgreSQL
Turn your Postgres schema into Typescript types that look like this:
// @generated
// This file is automatically generated by Kanel. Do not modify manually.
import { countryId } from './Country';
import type { CountryId } from './Country';
import { z } from 'zod';
/** Identifier type for city */
export type CityId = number & { __flavor?: 'CityId' };
/** Represents the table public.city */
export default interface City {
/** Database type: pg_catalog.int4 */
city_id: CityId;
/** Database type: pg_catalog.varchar */
city: string;
/** Database type: pg_catalog.int2 */
country_id: CountryId;
/** Database type: pg_catalog.timestamp */
last_update: Date;
}
/** Represents the initializer for the table public.city */
export interface CityInitializer {
/**
* Database type: pg_catalog.int4
* Default value: nextval('city_city_id_seq'::regclass)
*/
city_id?: CityId;
/** Database type: pg_catalog.varchar */
city: string;
/** Database type: pg_catalog.int2 */
country_id: CountryId;
/**
* Database type: pg_catalog.timestamp
* Default value: now()
*/
last_update?: Date;
}
/** Represents the mutator for the table public.city */
export interface CityMutator {
/** Database type: pg_catalog.int4 */
city_id?: CityId;
/** Database type: pg_catalog.varchar */
city?: string;
/** Database type: pg_catalog.int2 */
country_id?: CountryId;
/** Database type: pg_catalog.timestamp */
last_update?: Date;
}
export const cityId: z.Schema<CityId> = z.number() as any;
export const city: z.Schema<City> = z.object({
city_id: cityId,
city: z.string(),
country_id: countryId,
last_update: z.date(),
}) as any;
export const cityInitializer: z.Schema<CityInitializer> = z.object({
city_id: cityId.optional(),
city: z.string(),
country_id: countryId,
last_update: z.date().optional(),
}) as any;
export const cityMutator: z.Schema<CityMutator> = z.object({
city_id: cityId.optional(),
city: z.string().optional(),
country_id: countryId.optional(),
last_update: z.date().optional(),
}) as any;
It does this by inspecting a live PostgreSQL database, sort of like a reverse object/relations mapper.
You check the generated code into your repository and work with it using Knex.js or similar.
The idea is introduced in this blog post.
Copyright © 2018 Kristian Dupont, licensed under the MIT License