Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
431 changes: 425 additions & 6 deletions examples/basic/package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions examples/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"typegres": "file:../.."
},
"devDependencies": {
"@swc/core": "^1.15.43",
"@types/pg": "^8.20.0",
"unplugin-swc": "^1.5.9",
"vitest": "^4.1.5"
}
}
11 changes: 6 additions & 5 deletions examples/basic/src/tables/collars.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Int8, Text } from "typegres/postgres";
import { db } from "../db";
import { expose } from "typegres";
import { Int8, Text } from "typegres/postgres";
import { Dogs } from "./dogs";

export class Collars extends db.Table("collars") {
// @generated-start
id = (Int8<1>).column({ nonNull: true, generated: true });
color = (Text<1>).column({ nonNull: true });
dog_id = (Int8<1>).column({ nonNull: true });
@expose() id = (Int8<1>).column({ nonNull: true, generated: true });
@expose() color = (Text<1>).column({ nonNull: true });
@expose() dog_id = (Int8<1>).column({ nonNull: true });
// relations
dog() { return Dogs.from().where(({ dogs }) => dogs.id["="](this.dog_id)).cardinality("one"); }
@expose() dog() { return Dogs.scope(Collars.contextOf(this)).where(({ dogs }) => dogs.id.eq(this.dog_id)).cardinality("one"); }
// @generated-end
}
29 changes: 15 additions & 14 deletions examples/basic/src/tables/dogs.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { sql } from "typegres";
import { Int8, Text, Timestamptz } from "typegres/postgres";
import { db } from "../db";
import { expose, sql } from "typegres";
import { Int8, Text, Timestamptz } from "typegres/postgres";
import { Teams } from "./teams";
import { Collars } from "./collars";
import { Microchips } from "./microchips";
import { Toys } from "./toys";

export class Dogs extends db.Table("dogs") {
// @generated-start
id = (Int8<1>).column({ nonNull: true, generated: true });
name = (Text<1>).column({ nonNull: true });
breed = (Text<0 | 1>).column();
created_at = (Timestamptz<1>).column({ nonNull: true, default: sql`now()` });
team_id = (Int8<1>).column({ nonNull: true });
rival_id = (Int8<0 | 1>).column();
@expose() id = (Int8<1>).column({ nonNull: true, generated: true });
@expose() name = (Text<1>).column({ nonNull: true });
@expose() breed = (Text<0 | 1>).column();
@expose() created_at = (Timestamptz<1>).column({ nonNull: true, default: sql`now()` });
@expose() team_id = (Int8<1>).column({ nonNull: true });
@expose() rival_id = (Int8<0 | 1>).column();
// relations
rival() { return Dogs.from().where(({ dogs }) => dogs.id["="](this.rival_id)).cardinality("maybe"); }
team() { return Teams.from().where(({ teams }) => teams.id["="](this.team_id)).cardinality("one"); }
collars() { return Collars.from().where(({ collars }) => collars.dog_id["="](this.id)).cardinality("one"); }
dogs() { return Dogs.from().where(({ dogs }) => dogs.rival_id["="](this.id)).cardinality("many"); }
microchips() { return Microchips.from().where(({ microchips }) => microchips.dog_id["="](this.id)).cardinality("maybe"); }
toys() { return Toys.from().where(({ toys }) => toys.dog_id["="](this.id)).cardinality("many"); }
@expose() rival() { return Dogs.scope(Dogs.contextOf(this)).where(({ dogs }) => dogs.id.eq(this.rival_id)).cardinality("maybe"); }
@expose() team() { return Teams.scope(Dogs.contextOf(this)).where(({ teams }) => teams.id.eq(this.team_id)).cardinality("one"); }
@expose() collars() { return Collars.scope(Dogs.contextOf(this)).where(({ collars }) => collars.dog_id.eq(this.id)).cardinality("one"); }
@expose() dogs() { return Dogs.scope(Dogs.contextOf(this)).where(({ dogs }) => dogs.rival_id.eq(this.id)).cardinality("many"); }
@expose() microchips() { return Microchips.scope(Dogs.contextOf(this)).where(({ microchips }) => microchips.dog_id.eq(this.id)).cardinality("maybe"); }
@expose() toys() { return Toys.scope(Dogs.contextOf(this)).where(({ toys }) => toys.dog_id.eq(this.id)).cardinality("many"); }
// @generated-end
}
11 changes: 6 additions & 5 deletions examples/basic/src/tables/microchips.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Int8, Text } from "typegres/postgres";
import { db } from "../db";
import { expose } from "typegres";
import { Int8, Text } from "typegres/postgres";
import { Dogs } from "./dogs";

export class Microchips extends db.Table("microchips") {
// @generated-start
id = (Int8<1>).column({ nonNull: true, generated: true });
serial = (Text<1>).column({ nonNull: true });
dog_id = (Int8<0 | 1>).column();
@expose() id = (Int8<1>).column({ nonNull: true, generated: true });
@expose() serial = (Text<1>).column({ nonNull: true });
@expose() dog_id = (Int8<0 | 1>).column();
// relations
dog() { return Dogs.from().where(({ dogs }) => dogs.id["="](this.dog_id)).cardinality("maybe"); }
@expose() dog() { return Dogs.scope(Microchips.contextOf(this)).where(({ dogs }) => dogs.id.eq(this.dog_id)).cardinality("maybe"); }
// @generated-end
}
9 changes: 5 additions & 4 deletions examples/basic/src/tables/teams.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Int8, Text } from "typegres/postgres";
import { db } from "../db";
import { expose } from "typegres";
import { Int8, Text } from "typegres/postgres";
import { Dogs } from "./dogs";

export class Teams extends db.Table("teams") {
// @generated-start
id = (Int8<1>).column({ nonNull: true, generated: true });
name = (Text<1>).column({ nonNull: true });
@expose() id = (Int8<1>).column({ nonNull: true, generated: true });
@expose() name = (Text<1>).column({ nonNull: true });
// relations
dogs() { return Dogs.from().where(({ dogs }) => dogs.team_id["="](this.id)).cardinality("many"); }
@expose() dogs() { return Dogs.scope(Teams.contextOf(this)).where(({ dogs }) => dogs.team_id.eq(this.id)).cardinality("many"); }
// @generated-end
}
11 changes: 6 additions & 5 deletions examples/basic/src/tables/toys.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Int8, Text } from "typegres/postgres";
import { db } from "../db";
import { expose } from "typegres";
import { Int8, Text } from "typegres/postgres";
import { Dogs } from "./dogs";

export class Toys extends db.Table("toys") {
// @generated-start
id = (Int8<1>).column({ nonNull: true, generated: true });
name = (Text<1>).column({ nonNull: true });
dog_id = (Int8<1>).column({ nonNull: true });
@expose() id = (Int8<1>).column({ nonNull: true, generated: true });
@expose() name = (Text<1>).column({ nonNull: true });
@expose() dog_id = (Int8<1>).column({ nonNull: true });
// relations
dog() { return Dogs.from().where(({ dogs }) => dogs.id["="](this.dog_id)).cardinality("one"); }
@expose() dog() { return Dogs.scope(Toys.contextOf(this)).where(({ dogs }) => dogs.id.eq(this.dog_id)).cardinality("one"); }
// @generated-end
}
1 change: 1 addition & 0 deletions examples/basic/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"skipLibCheck": true,
"noEmit": true
},
"include": ["src", "*.ts"]
Expand Down
1 change: 1 addition & 0 deletions examples/basic/typegres.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Config } from "typegres";

export default {
dialect: "postgres",
db: process.env["DATABASE_URL"] ?? "postgres://localhost/postgres",
tables: "src/tables",
dbImport: "../db",
Expand Down
17 changes: 16 additions & 1 deletion examples/basic/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
import { defineConfig } from "vitest/config";
import swc from "unplugin-swc";

export default defineConfig({});
// SWC handles the TC39 stage-3 decorators (`@expose()`) that `tg
// generate` emits on columns and relations. Vite's default transform
// leaves them as-is, which trips the Node runtime with a SyntaxError.
export default defineConfig({
oxc: false,
plugins: [
swc.vite({
jsc: {
target: "es2022",
parser: { syntax: "typescript", decorators: true },
transform: { decoratorVersion: "2022-03" },
},
}),
],
});
4 changes: 4 additions & 0 deletions examples/sqlite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dev.db
dev.db-journal
dev.db-wal
dev.db-shm
26 changes: 26 additions & 0 deletions examples/sqlite/migrate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Drops + recreates the SQLite schema at ./dev.db by running every
// migration file under ./migrations/*.sql. `tg generate` reads
// ./dev.db to introspect the resulting schema.

import Database from "better-sqlite3";
import * as fs from "node:fs";
import * as path from "node:path";

// Fresh file each run so DROP TABLE isn't needed inside the SQL.
const dbPath = "./dev.db";
if (fs.existsSync(dbPath)) { fs.unlinkSync(dbPath); }

const db = new Database(dbPath);
db.pragma("foreign_keys = ON");

const migrationsDir = path.resolve(import.meta.dirname, "migrations");
const files = fs.readdirSync(migrationsDir).filter((f) => f.endsWith(".sql")).sort();

for (const file of files) {
const sqlText = fs.readFileSync(path.join(migrationsDir, file), "utf-8");
console.log(`Running ${file}...`);
db.exec(sqlText);
}

db.close();
console.log(`Migrated ${dbPath}`);
15 changes: 15 additions & 0 deletions examples/sqlite/migrations/001_schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- SQLite schema. Read by `migrate.ts` (runs against ./dev.db so
-- `tg generate` has something to introspect) and by `dogs.test.ts`
-- (runs against :memory: so each test run is hermetic).

CREATE TABLE teams (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);

CREATE TABLE dogs (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
breed TEXT,
team_id INTEGER NOT NULL REFERENCES teams(id)
);
Loading
Loading