Skip to content
Draft
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .github/workflows/nuke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ on:
description: "Eas"
type: boolean
default: false
clerk:
description: "Clerk"
type: boolean
default: false

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
typesense: ${{ steps.force.outputs.all || steps.changes.outputs.typesense }}
workos: ${{ steps.force.outputs.all || steps.changes.outputs.workos }}
expo-eas: ${{ steps.force.outputs.all || steps.changes.outputs.expo-eas }}
clerk: ${{ steps.force.outputs.all || steps.changes.outputs.clerk }}
steps:
- id: force
if: contains(github.event.pull_request.labels.*.name, 'force-ci')
Expand Down Expand Up @@ -110,6 +111,9 @@ jobs:
expo-eas:
- 'packages/expo-eas/**'
- 'packages/core/**'
clerk:
- 'packages/clerk/**'
- 'packages/core/**'

ci-core:
needs: detect-changes
Expand Down Expand Up @@ -494,3 +498,18 @@ jobs:
working-directory: packages/expo-eas
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}

ci-clerk:
needs: detect-changes
if: needs.detect-changes.outputs.clerk == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- run: bun install
- run: bun run build
working-directory: packages/core
- run: bun run check
working-directory: packages/clerk
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,6 @@
shallow = true
ignore = dirty
fetchRecurseSubmodules = false
[submodule "packages/clerk/specs/distilled-spec-clerk"]
path = packages/clerk/specs/distilled-spec-clerk
url = https://github.com/alchemy-run/distilled-spec-clerk.git
59 changes: 39 additions & 20 deletions bun.lock

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

99 changes: 99 additions & 0 deletions packages/clerk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# @distilled.cloud/clerk

Effect-native Clerk SDK generated from the official Clerk OpenAPI specifications. Covers both APIs Clerk publishes:

- **Platform API** — workspace / application management (private beta).
- **Backend API** — per-instance resources: users, sessions, organizations, JWTs, OAuth, etc.

Spec source: <https://github.com/clerk/openapi-specs>.

## Installation

```bash
npm install @distilled.cloud/clerk effect
```

## Quick Start

The Backend API covers the operations most server-side integrations need. Authenticate with your instance secret key (`sk_test_...` / `sk_live_...`):

```typescript
import { Effect, Layer } from "effect";
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
import { Backend } from "@distilled.cloud/clerk/Operations";
import { BackendCredentialsFromEnv } from "@distilled.cloud/clerk";

const program = Effect.gen(function* () {
const instance = yield* Backend.GetInstance({});
return instance;
});

const ClerkLive = Layer.mergeAll(
FetchHttpClient.layer,
BackendCredentialsFromEnv,
);

program.pipe(Effect.provide(ClerkLive), Effect.runPromise);
```

Platform API operations are namespaced under `Platform` and require the platform access token credential:

```typescript
import { Platform } from "@distilled.cloud/clerk/Operations";
import { PlatformCredentialsFromEnv } from "@distilled.cloud/clerk";

const apps = Platform.PlatformListApplications({});
// provide PlatformCredentialsFromEnv (and FetchHttpClient.layer)
```

## Configuration

Set whichever environment variable matches the API(s) you call:

```bash
# Backend API (per-instance secret key)
CLERK_SECRET_KEY=sk_test_...

# Platform API (workspace access token, private beta)
CLERK_PLATFORM_API_TOKEN=...
```

`CredentialsFromEnv` provides both layers at once if you use both APIs in the same program.

## Error Handling

All Clerk error responses share the same envelope (`{ errors: [{ message, long_message, code, meta }], clerk_trace_id }`). The SDK maps HTTP status codes to the standard typed errors from `@distilled.cloud/core` and falls back to `UnknownClerkError` for anything unrecognised:

```typescript
import { Effect } from "effect";
import { Backend } from "@distilled.cloud/clerk/Operations";
import { NotFound, UnknownClerkError } from "@distilled.cloud/clerk";

Backend.GetUser({ user_id: "user_missing" }).pipe(
Effect.catchTags({
NotFound: () => Effect.succeed(null),
UnknownClerkError: (e: UnknownClerkError) =>
Effect.fail(new Error(`Clerk error: ${e.message ?? "unknown"}`)),
}),
);
```

## Services

The Backend API surface is large; here are the main groupings:

- **Users** — list, create, get, update, delete; ban/unban; lock/unlock; email/phone management
- **Sessions / Clients / Sign-in / Sign-up** — session lifecycle, JWT templates, sign-in tokens, OAuth access tokens
- **Organizations** — organizations, memberships, invitations, domains, roles, permissions
- **Allow-list / Block-list / Waitlist** — identifier-based access controls
- **OAuth applications & Enterprise connections** — SSO and OAuth app management
- **Billing & Commerce** — plans, prices, subscription items, statements, credit balances
- **API keys / M2M tokens** — service account credentials

Platform API operations are prefixed with `Platform*` and cover applications, application instances, domains, deployments, and application transfers.

Browse the full list of operations in `src/operations/{platform,backend}/`.

## License

MIT
Loading
Loading