Skip to content

Ranges

Creating a Postgres Range Type in your schema will add this data type to your ranges directory.

-- Built-in.
CREATE TABLE ... (
a_tstzrange TSTZRANGE NOT NULL,
-- ...
);
-- Custom.
CREATE TYPE float_range AS RANGE (
subtype = float8,
subtype_diff = float8mi
);
  • Directoryno-orm
    • Directorypublic
      • Directoryranges
        • schemas.ts
        • types.ts

This generates a Zod schema which can parse the enum from your database:

export const floatRange = z.string().brand<"public.ranges.float_range">();

Note that ranges are scoped on a per-schema level (e.g public).

no-orm has support for Postgres built-in ranges. This uses the postgres-range package.

import { Range } from "postgres-range";
const tstzRange = new Range<Date>(
new Date("2025-01-01 00:00:00+10"),
new Date("2025-01-02 00:00:00+10"),
4,
);

You can then pass tstzRange into a no-orm create or update method and know that your database will accept and store it correctly.

Likewise when reading a range, it will come back in the Range type:

const tstzRange = row.a_tstz_range; // Range<Date>

You can see these ranges defined in the postgres directory of no-orm:

  • Directoryno-orm
    • Directorypostgres
      • schemas.ts
      • types.ts

For custom defined ranges, no-orm will basically treat these like a string with some extra branding.

Similar to domains, any custom range defined in your schema must be manually validated.

In its simplest form, this can be done with zod parsing:

import * as Ranges from "./expected/public/ranges";
const floatRange = Ranges.Schemas.floatRange.parse("[1.0,5.0)")