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
93 changes: 93 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,96 @@ find the full documentation for it [in our repository](https://github.com/change

We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

## Creating a Changeset

When you make changes that should be included in a release, create a changeset to document them:

### From the root directory:

```bash
pnpm changeset
```

This will:

1. Prompt you to select which packages have changed
2. Ask you to choose the type of change (major, minor, patch)
3. Request a summary of the changes

### Changeset Types

- **major** - Breaking changes (e.g., API changes, removed features)
- **minor** - New features (e.g., new functionality, new APIs)
- **patch** - Bug fixes and small improvements

### Example Workflow

```bash
# 1. Make your changes to the codebase
# 2. Create a changeset
pnpm changeset

# 3. Select packages (use space to select, enter to confirm):
# - @ts-contract/core (if you changed core)
# - @ts-contract/plugins (if you changed plugins)

# 4. Choose version bump type:
# - patch (0.0.x) for bug fixes
# - minor (0.x.0) for new features
# - major (x.0.0) for breaking changes

# 5. Write a summary describing your changes

# 6. Commit the changeset file along with your changes
git add .changeset/your-changeset-name.md
git commit -m "feat: add new feature"
```

### Manual Changeset Creation

You can also create changeset files manually in `.changeset/`:

```markdown
---
'@ts-contract/core': minor
'@ts-contract/plugins': minor
---

Add WebSocket contract support with bidirectional message schemas
```

### Release Process (Automated)

Releases are **fully automated** via GitHub Actions:

1. **Merge PR to main** - When your PR with a changeset is merged to `main`
2. **Changesets bot creates a "Version Packages" PR** - This PR updates package versions and CHANGELOGs
3. **Merge the "Version Packages" PR** - This triggers:
- Automatic publishing to npm
- GitHub releases creation
- Documentation deployment to Cloudflare Pages

**You don't need to run any manual commands!** The CI pipeline handles everything.

### Manual Release (If Needed)

Only use these commands if you need to release locally (rare):

```bash
# Update package versions based on changesets
pnpm changeset version

# Build packages
pnpm -r build

# Publish to npm (requires npm authentication)
pnpm changeset publish
```

### Best Practices

1. **Create changesets with your PR** - Don't wait until release time
2. **Be descriptive** - Write clear summaries that will appear in CHANGELOGs
3. **One changeset per logical change** - Multiple changesets are fine for complex PRs
4. **Include all affected packages** - If a change affects multiple packages, select them all
11 changes: 10 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,14 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@ts-contract/docs"]
"ignore": [
"@ts-contract/docs",
"@ts-contract-recipes/client",
"@ts-contract-recipes/server",
"@ts-contract-recipes/shared",
"@ts-contract-recipes/fastify-react-query",
"@ts-contract-recipes/hono-custom-fetch",
"@ts-contract-recipes/custom-plugins",
"@ts-contract-recipes/express"
]
}
10 changes: 9 additions & 1 deletion .changeset/pre.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
"initialVersions": {
"@ts-contract/docs": "0.0.0",
"@ts-contract/core": "0.0.1",
"@ts-contract/plugins": "0.0.1"
"@ts-contract/plugins": "0.0.1",
"@ts-contract-recipes/custom-plugins": "1.0.0",
"@ts-contract-recipes/express": "1.0.0",
"@ts-contract-recipes/fastify-react-query": "1.0.0",
"@ts-contract-recipes/client": "1.0.0",
"@ts-contract-recipes/server": "1.0.0",
"@ts-contract-recipes/shared": "1.0.0",
"@ts-contract-recipes/hono-custom-fetch": "1.0.0"
},
"changesets": [
"sparkly-pianos-brake",
"upset-eyes-brush"
]
}
6 changes: 6 additions & 0 deletions .changeset/sparkly-pianos-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@ts-contract/plugins': minor
'@ts-contract/core': minor
---

Add experimental websocket contract
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: mbrimmer83
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,61 @@ const user = api.getUser.validateResponse(200, data);
// => { id: string, name: string, email: string }
```

### WebSocket Example

```ts
import { createContract, initContract } from '@ts-contract/core';
import {
websocketPathPlugin,
websocketValidatePlugin,
} from '@ts-contract/plugins';
import { z } from 'zod';

const contract = createContract({
chat: {
type: 'websocket',
path: '/ws/chat/:roomId',
pathParams: z.object({ roomId: z.string() }),
query: z.object({ token: z.string() }),
clientMessages: {
new_msg: z.object({
type: z.literal('new_msg'),
body: z.string(),
}),
},
serverMessages: {
new_msg: z.object({
type: z.literal('new_msg'),
id: z.string(),
body: z.string(),
userId: z.string(),
}),
},
},
});

const api = initContract(contract)
.useWebSocket(websocketPathPlugin)
.useWebSocket(websocketValidatePlugin)
.build();

// Build WebSocket URL
const url = api.chat.buildPath({ roomId: '123' }, { token: 'abc' });
// => "/ws/chat/123?token=abc"

// Validate outgoing message
const msg = api.chat.validateClientMessage('new_msg', {
type: 'new_msg',
body: 'Hello!',
});

// Validate incoming message (e.g., with Phoenix.js)
channel.on('new_msg', (data) => {
const validated = api.chat.validateServerMessage('new_msg', data);
console.log(validated.body);
});
```

## Packages

| Package | Description |
Expand Down
3 changes: 2 additions & 1 deletion apps/docs/components/construction-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export function ConstructionBanner() {
🚧
</span>
<p className="font-medium">
Under Construction - This documentation is actively being developed
Alpha Release - This project is in early development and APIs may
change
</p>
</div>
</div>
Expand Down
Loading