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
111 changes: 111 additions & 0 deletions .claude/rules/bun.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
description: Use Bun instead of Node.js, npm, pnpm, or vite.
globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
alwaysApply: false
---

Default to using Bun instead of Node.js.

- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
- Use `bun test` instead of `jest` or `vitest`
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
- Bun automatically loads .env, so don't use dotenv.

## APIs

- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
- `Bun.redis` for Redis. Don't use `ioredis`.
- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
- `WebSocket` is built-in. Don't use `ws`.
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
- Bun.$`ls` instead of execa.

## Testing

Use `bun test` to run tests.

```ts#index.test.ts
import { test, expect } from "bun:test";

test("hello world", () => {
expect(1).toBe(1);
});
```

## Frontend

Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.

Server:

```ts#index.ts
import index from "./index.html"

Bun.serve({
routes: {
"/": index,
"/api/users/:id": {
GET: (req) => {
return new Response(JSON.stringify({ id: req.params.id }));
},
},
},
// optional websocket support
websocket: {
open: (ws) => {
ws.send("Hello, world!");
},
message: (ws, message) => {
ws.send(message);
},
close: (ws) => {
// handle close
}
},
development: {
hmr: true,
console: true,
}
})
```

HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.

```html#index.html
<html>
<body>
<h1>Hello, world!</h1>
<script type="module" src="./frontend.tsx"></script>
</body>
</html>
```

With the following `frontend.tsx`:

```tsx#frontend.tsx
import React from "react";

// import .css files directly and it works
import './index.css';

import { createRoot } from "react-dom/client";

const root = createRoot(document.body);

export default function Frontend() {
return <h1>Hello, world!</h1>;
}

root.render(<Frontend />);
```

Then, run index.ts

```sh
bun --hot ./index.ts
```

For more information, read the Bun API docs in `node_modules/bun-types/docs/**.md`.
30 changes: 30 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Lint

on:
pull_request:
branches: [dev, main]
push:
branches: [dev, main]

jobs:
lint:
name: Lint & Type Check
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Run type checking
run: bun run typecheck

- name: Check formatting
run: bun run format:check
70 changes: 70 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Tests

on:
pull_request:
branches: [dev, main]
push:
branches: [dev, main]

jobs:
# Unit tests - fast feedback
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Build SDK
run: bun run build

- name: Run unit tests
run: bun run test:unit

# Integration tests - with real SSO server
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: unit-tests

steps:
- name: Checkout SDK code
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Install dependencies
run: make install

- name: Build SDK
run: make build

- name: Start SSO Server
run: make test-up

- name: Run integration tests
run: make test-integration
env:
SSO_BASE_URL: http://localhost:8080
TEST_CLIENT_ID: test-client-id
TEST_ISSUER: sso-service

- name: Show SSO Server logs on failure
if: failure()
run: make test-logs

- name: Stop Docker services
if: always()
run: make test-down
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# dependencies (bun install)
node_modules

# output
out
dist
*.tgz

# code coverage
coverage
*.lcov

# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# caches
.eslintcache
.cache
*.tsbuildinfo

# IntelliJ based IDEs
.idea

# Finder (MacOS) folder config
.DS_Store
17 changes: 17 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100,
"plugins": ["@trivago/prettier-plugin-sort-imports"],
"importOrder": [
"^node:",
"<THIRD_PARTY_MODULES>",
"^../types/(.*)$",
"^./(.*)$",
"^[./]"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true
}
84 changes: 84 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
.PHONY: help test test-unit test-integration test-up test-down test-logs test-logs-follow install build typecheck format

# Default target - show help
help:
@echo "SSO TypeScript SDK - Available Commands"
@echo ""
@echo "Testing:"
@echo " make test - Run all tests (starts server, runs tests, stops server)"
@echo " make test-unit - Run unit tests only (fast, no server needed)"
@echo " make test-integration - Run integration tests (server must be running)"
@echo ""
@echo "Test Server:"
@echo " make test-up - Start SSO server"
@echo " make test-down - Stop SSO server"
@echo " make test-logs - View server logs (last 100 lines)"
@echo " make test-logs-follow - Follow server logs (interactive)"
@echo ""
@echo "Development:"
@echo " make install - Install dependencies"
@echo " make build - Build the SDK"
@echo " make typecheck - Run type checking"
@echo " make format - Format code"

# Run all tests (starts server, runs tests, stops server)
test:
@echo "▶ Starting SSO server..."
@docker compose -f docker-compose.test.yml up -d
@echo "⏳ Waiting for services (30s)..."
@sleep 30
@echo "▶ Running unit tests..."
@bun run test:unit || (docker compose -f docker-compose.test.yml down && exit 1)
@echo "▶ Running integration tests..."
@bun run test:integration || (docker compose -f docker-compose.test.yml down && exit 1)
@echo "▶ Stopping server..."
@docker compose -f docker-compose.test.yml down
@echo "✅ All tests passed!"

# Run unit tests only
test-unit:
@echo "▶ Running unit tests..."
@bun run test:unit

# Run integration tests (requires running server)
test-integration:
@echo "▶ Running integration tests..."
@bun run test:integration

# Start SSO server and dependencies
test-up:
@echo "▶ Starting SSO server..."
@docker compose -f docker-compose.test.yml up -d
@echo "⏳ Waiting 30s for services to be ready..."
@sleep 30
@echo "✅ Server ready! Use 'make test-integration' to run tests"

# Stop SSO server
test-down:
@echo "▶ Stopping SSO server..."
@docker compose -f docker-compose.test.yml down -v
@echo "✅ Server stopped"

# View SSO server logs (use test-logs-follow for interactive mode)
test-logs:
@docker compose -f docker-compose.test.yml logs --tail=100 sso

# Follow SSO server logs (interactive)
test-logs-follow:
@docker compose -f docker-compose.test.yml logs -f sso

# Install dependencies
install:
@bun install

# Build the SDK
build:
@bun run build

# Run TypeScript type checking
typecheck:
@bun run typecheck

# Format code
format:
@bun run format
Loading