Skip to content

Commit e467bc5

Browse files
committed
docs(site): Nextra documentation site + GitHub Pages deploy
Full docs site under docs/ (Nextra 4, App Router, static export): - Content: intro, getting-started, client, events, sending-messages, interactive, rich-responses, commands, automation (broadcast/schedule), storage, runtimes. - Builds to static out/ with basePath /zaileys + 404.html + .nojekyll; verified 12 HTML pages render. - GitHub Actions workflow (.github/workflows/docs.yml) builds + deploys to Pages on push to main (docs/**) or manual dispatch. Stack note: pinned nextra/nextra-theme-docs 4.2.17 + Next 15.5 — nextra 4.6.x has a static-export regression that crashes the /_not-found page prerender; 4.2.17 is the last version that exports cleanly with the root-layout theme. Also: removed TypeDoc (typedoc.json + docs script + dep) now that TSDoc is gone, and moved the Convex helper template docs/convex -> examples/convex (README/DEPENDENCIES links updated).
1 parent fc2653b commit e467bc5

30 files changed

Lines changed: 7453 additions & 13 deletions

.github/workflows/docs.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Deploy Docs
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'docs/**'
8+
- '.github/workflows/docs.yml'
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: read
13+
pages: write
14+
id-token: write
15+
16+
# Allow one concurrent deployment; let an in-progress run finish.
17+
concurrency:
18+
group: pages
19+
cancel-in-progress: false
20+
21+
jobs:
22+
build:
23+
runs-on: ubuntu-latest
24+
defaults:
25+
run:
26+
working-directory: docs
27+
steps:
28+
- uses: actions/checkout@v4
29+
- uses: actions/setup-node@v4
30+
with:
31+
node-version: 20
32+
- name: Install
33+
run: npm install
34+
- name: Build static site
35+
run: npm run build
36+
- name: Upload Pages artifact
37+
uses: actions/upload-pages-artifact@v3
38+
with:
39+
path: docs/out
40+
41+
deploy:
42+
needs: build
43+
runs-on: ubuntu-latest
44+
environment:
45+
name: github-pages
46+
url: ${{ steps.deployment.outputs.page_url }}
47+
steps:
48+
- name: Deploy to GitHub Pages
49+
id: deployment
50+
uses: actions/deploy-pages@v4

DEPENDENCIES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ only the backend they use; a missing peer throws `STORE_NOT_AVAILABLE` instead o
6767
| `better-sqlite3` | `^11.0.0` | `SqliteAuthStore` / `SqliteMessageStore` | `pnpm add better-sqlite3` |
6868
| `redis` | `^4.7.0` | `RedisAuthStore` / `RedisMessageStore` | `pnpm add redis` |
6969
| `pg` | `^8.11.0` | `PostgresAuthStore` / `PostgresMessageStore` | `pnpm add pg` |
70-
| `convex` | `^1.0.0` | `ConvexAuthStore` / `ConvexMessageStore` (requires deploying `docs/convex/`) | `pnpm add convex` |
70+
| `convex` | `^1.0.0` | `ConvexAuthStore` / `ConvexMessageStore` (requires deploying `examples/convex/`) | `pnpm add convex` |
7171

7272
## Optional accelerator (not declared)
7373

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ const client = new Client({
201201
| `postgres` | `PostgresAuthStore` | `PostgresMessageStore` | `pg` |
202202
| `convex` | `ConvexAuthStore` | `ConvexMessageStore` | `convex` |
203203

204-
> ⭐ default. Convex requires deploying the helper functions in [`docs/convex/`](./docs/convex) — see that folder's README.
204+
> ⭐ default. Convex requires deploying the helper functions in [`examples/convex/`](./examples/convex) — see that folder's README.
205205
206206
## Runtime support
207207

docs/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules/
2+
.next/
3+
out/
4+
next-env.d.ts
5+
.DS_Store

docs/app/[[...mdxPath]]/page.jsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { generateStaticParamsFor, importPage } from 'nextra/pages'
2+
import { useMDXComponents as getMDXComponents } from '../../mdx-components'
3+
4+
export const generateStaticParams = generateStaticParamsFor('mdxPath')
5+
6+
export async function generateMetadata(props) {
7+
const params = await props.params
8+
const { metadata } = await importPage(params.mdxPath)
9+
return metadata
10+
}
11+
12+
const Wrapper = getMDXComponents().wrapper
13+
14+
export default async function Page(props) {
15+
const params = await props.params
16+
const result = await importPage(params.mdxPath)
17+
const { default: MDXContent, toc, metadata, sourceCode } = result
18+
return (
19+
<Wrapper toc={toc} metadata={metadata} sourceCode={sourceCode}>
20+
<MDXContent {...props} params={params} />
21+
</Wrapper>
22+
)
23+
}

docs/app/layout.jsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Footer, Layout, Navbar } from 'nextra-theme-docs'
2+
import { Head } from 'nextra/components'
3+
import { getPageMap } from 'nextra/page-map'
4+
import 'nextra-theme-docs/style.css'
5+
6+
export const metadata = {
7+
title: {
8+
default: 'Zaileys — Simplified WhatsApp API',
9+
template: '%s — Zaileys',
10+
},
11+
description: 'Type-safe, batteries-included WhatsApp bot framework for Node.js / TypeScript built on Baileys.',
12+
}
13+
14+
const navbar = (
15+
<Navbar logo={<b>Zaileys</b>} projectLink="https://github.com/zeative/zaileys" chatLink="https://discord.gg/KBHhTTVUc5" />
16+
)
17+
const footer = <Footer>MIT {new Date().getFullYear()} © Zaileys.</Footer>
18+
19+
export default async function RootLayout({ children }) {
20+
return (
21+
<html lang="en" dir="ltr" suppressHydrationWarning>
22+
<Head />
23+
<body>
24+
<Layout
25+
navbar={navbar}
26+
footer={footer}
27+
pageMap={await getPageMap()}
28+
docsRepositoryBase="https://github.com/zeative/zaileys/tree/main/docs"
29+
sidebar={{ defaultMenuCollapseLevel: 1 }}
30+
>
31+
{children}
32+
</Layout>
33+
</body>
34+
</html>
35+
)
36+
}

docs/app/not-found.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { NotFoundPage } from 'nextra-theme-docs'
2+
3+
export default function NotFound() {
4+
return (
5+
<NotFoundPage content="Report a broken link" labels="broken-link">
6+
<h1>404 — Page not found</h1>
7+
</NotFoundPage>
8+
)
9+
}

docs/content/_meta.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default {
2+
index: 'Introduction',
3+
'getting-started': 'Getting Started',
4+
client: 'Client & Lifecycle',
5+
events: 'Events',
6+
'sending-messages': 'Sending Messages',
7+
interactive: 'Interactive Messages',
8+
'rich-responses': 'Rich Responses (AIRich)',
9+
commands: 'Commands',
10+
automation: 'Broadcast & Schedule',
11+
storage: 'Storage Adapters',
12+
runtimes: 'Runtime Support',
13+
}

docs/content/automation.mdx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Broadcast & Schedule
2+
3+
## Broadcast
4+
5+
Send the same message to many recipients with built-in rate limiting. The builder callback runs
6+
once per recipient.
7+
8+
```typescript
9+
const result = await client.broadcast(
10+
['6281111111111@s.whatsapp.net', '6282222222222@s.whatsapp.net'],
11+
(b) => b.text('Announcement to everyone'),
12+
{ rateLimitPerSec: 5 },
13+
)
14+
```
15+
16+
The rate limiter uses a token bucket (global + per-recipient), so you stay under WhatsApp's
17+
limits without manual `sleep()` calls. Per-recipient failures are isolated — one bad JID does not
18+
abort the run, and the original error is preserved per recipient.
19+
20+
## Schedule
21+
22+
Queue a send for a future time. When the configured [message store](/storage) implements the
23+
scheduled-job methods, jobs **survive restarts**.
24+
25+
```typescript
26+
const job = await client.scheduleAt(
27+
new Date(Date.now() + 60_000),
28+
(b) => b.text('This sends one minute from now'),
29+
)
30+
```
31+
32+
The builder callback is evaluated **once at schedule time** into a serializable snapshot
33+
(`{ recipient, content }`) — it is never stored as a live closure, which is what makes
34+
restart-recovery possible.
35+
36+
37+
> Restart-survival requires a store with `saveScheduledJob` / `listScheduledJobs` /
38+
> `deleteScheduledJob` (SQLite, Postgres, Redis, and Convex adapters implement these). With the
39+
> in-memory default, scheduled jobs are lost on restart.

docs/content/client.mdx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Client & Lifecycle
2+
3+
The `Client` is the entry point. Constructing it **connects automatically** and emits lifecycle
4+
events; there is no separate `connect()` call.
5+
6+
```typescript
7+
import { Client } from 'zaileys'
8+
9+
const client = new Client({ sessionId: 'default' })
10+
```
11+
12+
## Connection events
13+
14+
```typescript
15+
client.on('qr', ({ qrString }) => {}) // QR string to render
16+
client.on('connect', ({ me }) => {}) // authenticated; `me` is your JID
17+
client.on('disconnect', ({ reason }) => {}) // dropped (auto-reconnect runs with backoff)
18+
```
19+
20+
Zaileys reconnects automatically with exponential backoff, and detects an invalid/corrupted
21+
session so you know when to delete the auth folder and re-scan.
22+
23+
## Sending & mutating
24+
25+
`client.send(jid)` opens a [builder](/sending-messages). Awaiting any send resolves to the new
26+
`WAMessageKey`, which the mutation helpers consume:
27+
28+
```typescript
29+
const key = await client.send(jid).text('Original')
30+
await client.edit(key).text('Edited')
31+
await client.react(key, '👍') // empty string removes the reaction
32+
await client.delete(key, { forEveryone: true })
33+
await client.forward(key, otherJid)
34+
```
35+
36+
## Domain namespaces
37+
38+
Higher-level operations are grouped under namespaces (each throws `NOT_CONNECTED` until the client
39+
is connected):
40+
41+
| Namespace | Purpose |
42+
| --------- | ------- |
43+
| `client.group.*` | metadata, participants, invite, subject/description |
44+
| `client.presence.*` | `typing()` / `recording()` / `online()` / `offline()` |
45+
| `client.privacy.*` | privacy settings |
46+
| `client.newsletter.*` | channel/newsletter operations |
47+
| `client.community.*` | community operations |
48+
49+
```typescript
50+
await client.presence.typing(jid) // show the "typing…" indicator
51+
const meta = await client.group.metadata(groupJid)
52+
```
53+
54+
## Options
55+
56+
| Option | Type | Default | Notes |
57+
| ------ | ---- | ------- | ----- |
58+
| `sessionId` | `string` | `'default'` | auth folder / namespace |
59+
| `authType` | `'qr' \| 'pairing'` | `'qr'` | login method |
60+
| `phoneNumber` | `string` || required for `pairing` |
61+
| `commandPrefix` | `string \| string[]` || enables the [command framework](/commands) |
62+
| `ignoreMe` | `boolean` | `true` | drop messages from the bot's own account |
63+
| `auth` | `AuthStoreBundle` | `FileAuthStore` | see [Storage](/storage) |
64+
| `store` | `MessageStore` | in-memory | see [Storage](/storage) |
65+
| `logger` | Pino-compatible | silent-ish | structural logger |

0 commit comments

Comments
 (0)