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
2 changes: 2 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use flake
layout node
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ dist-ssr
*.sw?

.direnv/
.envrc
pg_data/
result

Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
let
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
};
node = pkgs.nodejs_20;
in
{
devShells.default = pkgs.mkShell {
buildInputs = [ node pkgs.postgresql pkgs.jq ];
buildInputs = [ node pkgs.postgresql pkgs.jq pkgs.claude-code pkgs.nixfmt];
};
formatter = pkgs.nixpkgs-fmt;
packages.default =
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"vitest": "^2.0.2",
"zx": "^8.5.3"
},
"description": "PostgreSQL, expressed in Typescript",
"description": "PostgreSQL, expressed in TypeScript",
"main": "index.js",
"types": "dist/index.d.ts",
"files": [
Expand Down
2 changes: 2 additions & 0 deletions site/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
public/api
.next
53 changes: 53 additions & 0 deletions site/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Typegres Documentation Site

This is the documentation and playground site for Typegres, built with Vite + Vike.

## Features

- **Landing Page**: High-energy, animated landing page showcasing Typegres features
- **Documentation**: Overview and quickstart guide
- **API Reference**: Auto-generated from TypeScript comments using TypeDoc
- **SQL Playground**: Interactive TypeScript editor with live PostgreSQL (via PGlite WASM)

## Development

```bash
# Install dependencies
npm install

# Run development server
npm run dev

# Open http://localhost:5173
```

## Building

```bash
# Build the static site
npm run build

# The output will be in the 'dist' directory

# Preview the production build
npm run preview
```

## Structure

- `/` - Landing page with animations and feature highlights
- `/docs` - Documentation overview
- `/docs/quickstart` - Quick start guide
- `/playground` - Interactive TypeScript playground with Monaco editor
- `/api` - Auto-generated API reference (after running build:docs)

## Technologies

- Vite + Vike (SSG framework)
- React 19
- TypeScript
- Tailwind CSS
- Framer Motion (animations)
- Monaco Editor (code editor)
- PGlite (WASM PostgreSQL)
- TypeDoc (API documentation)
43 changes: 43 additions & 0 deletions site/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--foreground-rgb: 17, 24, 39;
--background-rgb: 255, 255, 255;
--typegres-blue: 59, 130, 246;
--typegres-dark: 17, 24, 39;
}

@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-rgb: 17, 24, 39;
}
}

body {
color: rgb(var(--foreground-rgb));
background: rgb(var(--background-rgb));
}

@layer utilities {
.text-balance {
text-wrap: balance;
}

.bg-dot-pattern {
background-image: radial-gradient(circle, rgba(59, 130, 246, 0.1) 1px, transparent 1px);
background-size: 20px 20px;
}

.gradient-text {
@apply bg-gradient-to-r from-typegres-dark to-typegres-blue bg-clip-text text-transparent;
}

@media (prefers-color-scheme: dark) {
.gradient-text {
@apply bg-gradient-to-r from-gray-100 via-gray-200 to-typegres-blue;
}
}
}
13 changes: 13 additions & 0 deletions site/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/typegres_favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Typegres - PostgreSQL, expressed in TypeScript</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
142 changes: 142 additions & 0 deletions site/lib/monaco-typegres-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import * as monaco from 'monaco-editor'

// Create a virtual file system with key typegres types
export function setupMonacoTypescript(monaco: typeof import('monaco-editor')) {
// Configure TypeScript compiler options
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.ES2020,
module: monaco.languages.typescript.ModuleKind.ESNext,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
allowNonTsExtensions: true,
allowJs: false,
typeRoots: ['node_modules/@types'],
lib: ['es2020', 'dom', 'esnext.asynciterable'],
strict: true,
esModuleInterop: true,
allowSyntheticDefaultImports: true,
noEmit: true,
skipLibCheck: true,
forceConsistentCasingInFileNames: true,
jsx: monaco.languages.typescript.JsxEmit.None,
paths: {
'typegres': ['node_modules/typegres/index.d.ts'],
'kysely': ['node_modules/kysely/index.d.ts']
}
})

// Set diagnostic options
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
noSemanticValidation: false,
noSyntaxValidation: false,
noSuggestionDiagnostics: false
})

// Add typegres main export that combines everything
monaco.languages.typescript.typescriptDefaults.addExtraLib(`
declare module 'typegres' {
// Re-export from kysely
export { Kysely, sql } from 'kysely';

// Database types for the playground
export interface Database {
users: {
id: number;
name: string;
email: string;
active: boolean;
created_at: Date;
};
posts: {
id: number;
user_id: number;
title: string;
content: string | null;
published: boolean;
created_at: Date;
};
}

// Main database instance
export const db: Kysely<Database>;
}
`, 'file:///node_modules/typegres/index.d.ts');

// Add Kysely types (simplified but functional)
monaco.languages.typescript.typescriptDefaults.addExtraLib(`
declare module 'kysely' {
export interface Kysely<DB> {
selectFrom<T extends keyof DB & string>(table: T): SelectQueryBuilder<DB, T>;
insertInto<T extends keyof DB & string>(table: T): InsertQueryBuilder<DB, T>;
updateTable<T extends keyof DB & string>(table: T): UpdateQueryBuilder<DB, T>;
deleteFrom<T extends keyof DB & string>(table: T): DeleteQueryBuilder<DB, T>;
with<N extends string, E>(name: N, expr: (qb: any) => E): WithQueryBuilder<DB, N>;
transaction(): TransactionBuilder<DB>;
}

export interface SelectQueryBuilder<DB, TB extends keyof DB> {
select<S extends SelectExpression<DB, TB>>(selection: S[]): SelectQueryBuilder<DB, TB>;
selectAll(): SelectQueryBuilder<DB, TB>;
where<F extends keyof DB[TB]>(field: F, op: ComparisonOperator, value: DB[TB][F]): SelectQueryBuilder<DB, TB>;
leftJoin<T extends keyof DB & string>(table: T, leftRef: string, rightRef: string): SelectQueryBuilder<DB, TB | T>;
innerJoin<T extends keyof DB & string>(table: T, leftRef: string, rightRef: string): SelectQueryBuilder<DB, TB | T>;
groupBy(fields: string[]): SelectQueryBuilder<DB, TB>;
having(expr: Expression<any>, op: ComparisonOperator, value: any): SelectQueryBuilder<DB, TB>;
orderBy(field: string, direction?: 'asc' | 'desc'): SelectQueryBuilder<DB, TB>;
limit(limit: number): SelectQueryBuilder<DB, TB>;
execute(): Promise<any[]>;
executeTakeFirst(): Promise<any | undefined>;
executeTakeFirstOrThrow(): Promise<any>;
}

export interface InsertQueryBuilder<DB, TB extends keyof DB> {
values(values: Partial<DB[TB]> | Partial<DB[TB]>[]): InsertQueryBuilder<DB, TB>;
returning<S extends keyof DB[TB]>(fields: S[]): InsertQueryBuilder<DB, TB>;
execute(): Promise<any[]>;
executeTakeFirst(): Promise<any | undefined>;
executeTakeFirstOrThrow(): Promise<any>;
}

export interface UpdateQueryBuilder<DB, TB extends keyof DB> {
set(values: Partial<DB[TB]>): UpdateQueryBuilder<DB, TB>;
where<F extends keyof DB[TB]>(field: F, op: ComparisonOperator, value: DB[TB][F]): UpdateQueryBuilder<DB, TB>;
returning<S extends keyof DB[TB]>(fields: S[]): UpdateQueryBuilder<DB, TB>;
execute(): Promise<any[]>;
}

export interface DeleteQueryBuilder<DB, TB extends keyof DB> {
where<F extends keyof DB[TB]>(field: F, op: ComparisonOperator, value: DB[TB][F]): DeleteQueryBuilder<DB, TB>;
execute(): Promise<any[]>;
}

export interface WithQueryBuilder<DB, N extends string> {
selectFrom<T extends keyof DB & string | N>(table: T): SelectQueryBuilder<DB, T>;
}

export interface TransactionBuilder<DB> {
execute<T>(fn: (trx: Kysely<DB>) => Promise<T>): Promise<T>;
}

export interface Expression<T> {
as(alias: string): AliasedExpression<T>;
}

export interface AliasedExpression<T> {}

export type SelectExpression<DB, TB extends keyof DB> = keyof DB[TB] | string | Expression<any> | AliasedExpression<any>;
export type ComparisonOperator = '=' | '!=' | '<' | '>' | '<=' | '>=' | 'in' | 'not in' | 'like' | 'not like';

export interface Sql {
<T = unknown>(strings: TemplateStringsArray, ...values: any[]): Expression<T>;
raw<T = unknown>(sql: string): Expression<T>;
ref<T = unknown>(ref: string): Expression<T>;
val<T>(value: T): Expression<T>;
join<T>(values: Expression<T>[], separator?: string): Expression<T>;
}

export const sql: Sql;
}
`, 'file:///node_modules/kysely/index.d.ts');

// Enable type acquisition
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
}
Loading