@jchat/addon-sdk 1.0.0-alpha.2 → 1.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +132 -0
- package/LICENSE +18 -196
- package/README.md +385 -20
- package/dist/cli.d.mts +35 -0
- package/dist/cli.mjs +136 -0
- package/dist/contracts.d.mts +43 -31
- package/dist/contracts.mjs +40 -0
- package/dist/diagnostics.d.mts +55 -9
- package/dist/diagnostics.mjs +66 -1
- package/dist/i18n-validator.d.mts +17 -0
- package/dist/i18n-validator.mjs +90 -0
- package/dist/i18n.mjs +191 -0
- package/dist/icon.d.mts +4 -0
- package/dist/icon.mjs +4 -0
- package/dist/index.d.mts +16 -253
- package/dist/index.mjs +131 -43
- package/dist/index2.d.mts +601 -0
- package/dist/state.d.mts +1 -0
- package/dist/state.mjs +2 -0
- package/dist/types.d.mts +12 -0
- package/dist/ui.d.mts +1 -0
- package/dist/ui.mjs +2 -0
- package/dist/vite.d.mts +64 -10
- package/dist/vite.mjs +227 -34
- package/package.json +119 -17
- package/skills/create-jchat-addon/SKILL.md +140 -0
- package/skills/jchat-addon-development/SKILL.md +260 -0
- package/tsconfig.addon.json +20 -0
- package/src/contracts.d.ts +0 -127
- package/src/contracts.ts +0 -132
- package/src/diagnostics.d.ts +0 -19
- package/src/diagnostics.test.ts +0 -106
- package/src/diagnostics.ts +0 -182
- package/src/index.d.ts +0 -249
- package/src/index.test.ts +0 -35
- package/src/index.ts +0 -299
- package/src/vite.test.ts +0 -62
- package/src/vite.ts +0 -289
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-jchat-addon
|
|
3
|
+
description: Scaffold and initialize new JChat addons using @jchat/create-addon with correct templates, mount points, manifest configuration, and devkit sandbox setup.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Create JChat Addon Skill
|
|
7
|
+
|
|
8
|
+
Use this skill whenever you need to create, scaffold, or initialize a new JChat addon, whether inside the JChat monorepo or as a standalone third-party project for external developers.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Quick Start Commands
|
|
13
|
+
|
|
14
|
+
### Inside the JChat Monorepo
|
|
15
|
+
|
|
16
|
+
When working inside the JChat monorepo root:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Interactive scaffolding
|
|
20
|
+
bunx @jchat/create-addon <addon-id> --workspace
|
|
21
|
+
|
|
22
|
+
# Non-interactive UI addon
|
|
23
|
+
bunx @jchat/create-addon <addon-id> --workspace --template=ui --mount-points=chat-toolbar --name="My Addon"
|
|
24
|
+
|
|
25
|
+
# Non-interactive fullstack addon (frontend UI + Elysia backend + isolated DB schema)
|
|
26
|
+
bunx @jchat/create-addon <addon-id> --workspace --template=fullstack --mount-points=chat-toolbar,room-settings --name="My Fullstack Addon"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Monorepo addons are generated directly into the `addons/<addon-id>/` workspace directory and automatically wired into Bun workspaces.
|
|
30
|
+
|
|
31
|
+
### Standalone (Third-Party Addon Developers)
|
|
32
|
+
|
|
33
|
+
For third-party developers building standalone addons outside the JChat monorepo:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Recommended command
|
|
37
|
+
bun create @jchat/addon <addon-id>
|
|
38
|
+
|
|
39
|
+
# Or with npx/bunx directly
|
|
40
|
+
bunx @jchat/create-addon <addon-id>
|
|
41
|
+
|
|
42
|
+
# With explicit flags
|
|
43
|
+
bunx @jchat/create-addon <addon-id> --template=fullstack --mount-points=chat-toolbar,user-profile
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Standalone projects generate a complete DevKit environment containing:
|
|
47
|
+
|
|
48
|
+
- `addon/` — The addon source package.
|
|
49
|
+
- `docker-compose.yml` — Disposable JChat development sandbox container with pre-configured PostgreSQL and Redis.
|
|
50
|
+
- `scripts/devkit.ts` — Lifecycle management scripts (`bun run devkit:start`, `bun run devkit:stop`).
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 2. CLI Options & Parameters
|
|
55
|
+
|
|
56
|
+
| Option | Description | Values / Examples | Default |
|
|
57
|
+
| ---------------- | ----------------------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------ |
|
|
58
|
+
| `<addon-id>` | Unique identifier in kebab-case (letters, numbers, hyphens) | `gifyard`, `poll-wise`, `weather-now` | _Required_ |
|
|
59
|
+
| `--template` | Architecture template | `ui` or `fullstack` | `ui` |
|
|
60
|
+
| `--mount-points` | Comma-separated UI mount locations | `chat-toolbar,room-settings,chat-message-action` | `chat-toolbar` |
|
|
61
|
+
| `--name` | Human-readable display name | `--name="Weather Widget"` | Capitalized `addon-id` |
|
|
62
|
+
| `--target` | Destination directory | `--target=addons/my-addon` | `<addon-id>` (or `addons/<addon-id>` if `--workspace`) |
|
|
63
|
+
| `--workspace` | Target JChat monorepo workspace dependencies | Flag | `false` |
|
|
64
|
+
| `--image` | Custom JChat sandbox container image | `--image=jchat/devkit:local` | Default published sandbox image |
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 3. Choosing a Template
|
|
69
|
+
|
|
70
|
+
### `ui` Template (Frontend Only)
|
|
71
|
+
|
|
72
|
+
Select when the addon only displays UI elements, embeds content, interacts with external third-party APIs via client fetch, or executes client-side actions (e.g. inserting text or media into the message editor).
|
|
73
|
+
|
|
74
|
+
- **Files generated**: `src/manifest.ts`, `src/ui.tsx`, `src/locales/*.json`, `vite.config.ts`, `package.json`.
|
|
75
|
+
- **Backend required**: None.
|
|
76
|
+
|
|
77
|
+
### `fullstack` Template (UI + Elysia Backend + Isolated DB)
|
|
78
|
+
|
|
79
|
+
Select when the addon needs:
|
|
80
|
+
|
|
81
|
+
- Custom REST endpoints or server-side webhook processing.
|
|
82
|
+
- Persistent database storage (tables in PostgreSQL `addons.*` schema).
|
|
83
|
+
- Real-time Redis / WebSocket event broadcasting.
|
|
84
|
+
- Enforcing server-side authorization or managing secrets.
|
|
85
|
+
- **Files generated**: Everything in `ui`, plus `src/server.ts`, database migrations, and backend configuration.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 4. UI Mount Points
|
|
90
|
+
|
|
91
|
+
Available mount points supported by the JChat host:
|
|
92
|
+
|
|
93
|
+
- `chat-toolbar`: Action button or picker in the chat composer toolbar.
|
|
94
|
+
- `chat-message-action`: Context menu action on existing chat messages.
|
|
95
|
+
- `room-settings`: Custom tab or section inside Room Settings.
|
|
96
|
+
- `site-settings`: Admin configuration panel for site administrators.
|
|
97
|
+
- `user-profile`: Extended tab or badge inside user profile cards.
|
|
98
|
+
- `sidebar-left` / `sidebar-right`: Persistent panels in chat sidebars.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 5. Generated Workspace Structure
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
my-addon/
|
|
106
|
+
├── .agents/
|
|
107
|
+
│ └── skills/
|
|
108
|
+
│ └── jchat-addon-development/
|
|
109
|
+
│ └── SKILL.md # In-workspace agent development guide
|
|
110
|
+
├── src/
|
|
111
|
+
│ ├── manifest.ts # Addon definition, permissions, mount points
|
|
112
|
+
│ ├── ui.tsx # Main React UI entry point
|
|
113
|
+
│ ├── server.ts # ElysiaJS server entry point (fullstack only)
|
|
114
|
+
│ └── locales/ # 20 host language JSON dictionaries
|
|
115
|
+
│ ├── en.json
|
|
116
|
+
│ ├── ar.json
|
|
117
|
+
│ ├── es.json
|
|
118
|
+
│ └── ...
|
|
119
|
+
├── package.json
|
|
120
|
+
├── tsconfig.json
|
|
121
|
+
└── vite.config.ts
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 6. Verification and Validation Checklist
|
|
127
|
+
|
|
128
|
+
Immediately after scaffolding an addon:
|
|
129
|
+
|
|
130
|
+
1. **Check Manifest**: Verify `src/manifest.ts` contains the correct `id`, `name`, `mountPoints`, and `permissions`.
|
|
131
|
+
2. **Verify Localization**: Ensure all 20 required language dictionaries exist in `src/locales/` (`bun check:translations` if in monorepo).
|
|
132
|
+
3. **Run Typecheck & Build**:
|
|
133
|
+
```bash
|
|
134
|
+
bun run typecheck
|
|
135
|
+
bun run build
|
|
136
|
+
```
|
|
137
|
+
4. **DevKit Sandbox (Standalone)**:
|
|
138
|
+
```bash
|
|
139
|
+
bun run devkit:start
|
|
140
|
+
```
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jchat-addon-development
|
|
3
|
+
description: Comprehensive guide for developing JChat addons using @jchat/addon-sdk, including manifests, UI widgets, direct icon imports, Elysia backend, isolated DB schemas, and i18n.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# JChat Addon Development Skill
|
|
7
|
+
|
|
8
|
+
Use this skill when developing, updating, or debugging JChat addons using `@jchat/addon-sdk`.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Architectural Guardrails (Non-Negotiable)
|
|
13
|
+
|
|
14
|
+
1. **Import Boundaries**:
|
|
15
|
+
- Addons MUST ONLY import `@jchat/addon-sdk` and `@jchat/addon-sdk/icon`.
|
|
16
|
+
- NEVER import private internal monorepo packages (`@jchat/icon`, `@jchat/ui`, `@jchat/db`, `@jchat/shared`, etc.).
|
|
17
|
+
- Host externals (`react`, `react-dom`, `@tanstack/react-query`) are provided at runtime by the JChat host.
|
|
18
|
+
2. **Icons**:
|
|
19
|
+
- Use direct imports: `import Icons from "@jchat/addon-sdk/icon"`.
|
|
20
|
+
- Never call `useIcons()` or install `lucide-react` / `react-icons` directly in the addon.
|
|
21
|
+
3. **Database Isolation**:
|
|
22
|
+
- All addon tables MUST reside in the isolated `addons` PostgreSQL schema (e.g. `addons.GlimpseStories`).
|
|
23
|
+
- Never write to or alter core tables (`Users`, `Rooms`, `Messages`, `Sites`).
|
|
24
|
+
4. **Real-Time Event Namespacing**:
|
|
25
|
+
- All WebSocket/Redis events MUST follow the canonical format: `addon:<addonId>:<eventName>` (e.g. `addon:pollwise:voted`).
|
|
26
|
+
5. **Localization (i18n)**:
|
|
27
|
+
- All addons must support all 20 host languages:
|
|
28
|
+
`ar`, `bg`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hr`, `kn`, `ml`, `nl`, `pt`, `ro`, `ru`, `ta`, `te`, `tr`, `ur`.
|
|
29
|
+
- All locale dictionaries in `src/locales/*.json` must maintain 100% key parity.
|
|
30
|
+
6. **Directional Styling (RTL/LTR)**:
|
|
31
|
+
- Use Tailwind CSS logical properties (`ps-*`, `pe-*`, `ms-*`, `me-*`, `text-start`, `text-end`, `start-*`, `end-*`, `rounded-s-*`, `rounded-e-*`).
|
|
32
|
+
- Never use physical `pl-*`, `pr-*`, `ml-*`, `mr-*`, `text-left`, or `text-right`.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2. Manifest Contract (`src/manifest.ts`)
|
|
37
|
+
|
|
38
|
+
Define addon metadata and capabilities with `defineAddonManifest`:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { defineAddonManifest } from "@jchat/addon-sdk"
|
|
42
|
+
|
|
43
|
+
export default defineAddonManifest({
|
|
44
|
+
id: "pollwise",
|
|
45
|
+
name: "Pollwise Polls",
|
|
46
|
+
version: "1.0.0",
|
|
47
|
+
description: "Create and vote on live interactive polls in chat rooms.",
|
|
48
|
+
author: "JChat Ecosystem Team",
|
|
49
|
+
compatibility: {
|
|
50
|
+
jchat: ">=1.0.0-alpha.0 <2.0.0",
|
|
51
|
+
addonSdk: ">=1.0.0-alpha.0 <2.0.0"
|
|
52
|
+
},
|
|
53
|
+
locales: [
|
|
54
|
+
"ar",
|
|
55
|
+
"bg",
|
|
56
|
+
"de",
|
|
57
|
+
"el",
|
|
58
|
+
"en",
|
|
59
|
+
"es",
|
|
60
|
+
"fr",
|
|
61
|
+
"he",
|
|
62
|
+
"hi",
|
|
63
|
+
"hr",
|
|
64
|
+
"kn",
|
|
65
|
+
"ml",
|
|
66
|
+
"nl",
|
|
67
|
+
"pt",
|
|
68
|
+
"ro",
|
|
69
|
+
"ru",
|
|
70
|
+
"ta",
|
|
71
|
+
"te",
|
|
72
|
+
"tr",
|
|
73
|
+
"ur"
|
|
74
|
+
],
|
|
75
|
+
defaultLocale: "en",
|
|
76
|
+
frontend: {
|
|
77
|
+
bundle: "./ui.js",
|
|
78
|
+
mountPoints: ["chat-toolbar", "room-settings"]
|
|
79
|
+
},
|
|
80
|
+
backend: {
|
|
81
|
+
bundle: "./server.js"
|
|
82
|
+
},
|
|
83
|
+
permissions: ["network", "storage"]
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 3. Frontend UI Development (`src/ui.tsx`)
|
|
90
|
+
|
|
91
|
+
Addon UI components receive `AddonProps` and use hooks from `@jchat/addon-sdk`:
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import {
|
|
95
|
+
type AddonProps,
|
|
96
|
+
useAddonSDK,
|
|
97
|
+
useAddonQuery,
|
|
98
|
+
useAddonMutation,
|
|
99
|
+
useAddonTranslation
|
|
100
|
+
} from "@jchat/addon-sdk"
|
|
101
|
+
import Icons from "@jchat/addon-sdk/icon"
|
|
102
|
+
|
|
103
|
+
export default function PollwiseAddon({ mountPoint, roomId }: AddonProps) {
|
|
104
|
+
const sdk = useAddonSDK()
|
|
105
|
+
const { t } = useAddonTranslation()
|
|
106
|
+
|
|
107
|
+
// 1. Data fetching via TanStack Query bridge
|
|
108
|
+
const { data: poll, isLoading } = useAddonQuery({
|
|
109
|
+
queryKey: ["poll", roomId],
|
|
110
|
+
queryFn: () => sdk.api.get<{ id: string; question: string }>(`/rooms/${roomId}/poll`)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
// 2. Mutations
|
|
114
|
+
const voteMutation = useAddonMutation({
|
|
115
|
+
mutationFn: (optionId: string) => sdk.api.post(`/rooms/${roomId}/vote`, { optionId }),
|
|
116
|
+
onSuccess: () => {
|
|
117
|
+
sdk.ui.toast({
|
|
118
|
+
title: t("vote_success_title"),
|
|
119
|
+
description: t("vote_success_desc"),
|
|
120
|
+
variant: "success"
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// 3. Real-time event listener
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
const unsubscribe = sdk.events.on("addon:pollwise:updated", (updatedPoll) => {
|
|
128
|
+
// Handle incoming real-time payload
|
|
129
|
+
})
|
|
130
|
+
return () => unsubscribe()
|
|
131
|
+
}, [sdk])
|
|
132
|
+
|
|
133
|
+
if (isLoading) return <div>{t("loading")}</div>
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<div className="p-4 rounded-xl bg-card border border-border">
|
|
137
|
+
<div className="flex items-center gap-2 mb-3">
|
|
138
|
+
<Icons.BarChart3 className="size-5 text-primary" />
|
|
139
|
+
<h3 className="font-semibold text-foreground">{poll?.question}</h3>
|
|
140
|
+
</div>
|
|
141
|
+
<button
|
|
142
|
+
onClick={() => voteMutation.mutate("option-1")}
|
|
143
|
+
className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors"
|
|
144
|
+
>
|
|
145
|
+
{t("vote_button")}
|
|
146
|
+
</button>
|
|
147
|
+
</div>
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Direct Icon Usage
|
|
153
|
+
|
|
154
|
+
Icons are rendered directly:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import Icons, { resolveIcon } from "@jchat/addon-sdk/icon"
|
|
158
|
+
|
|
159
|
+
// Direct JSX:
|
|
160
|
+
<Icons.Sparkles className="size-4 text-primary" />
|
|
161
|
+
<Icons.Send className="size-5" />
|
|
162
|
+
|
|
163
|
+
// Dynamic resolution:
|
|
164
|
+
const DynamicIcon = resolveIcon("Smile", Icons.HelpCircle)
|
|
165
|
+
<DynamicIcon className="size-4" />
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 4. Backend Server Development (`src/server.ts`)
|
|
171
|
+
|
|
172
|
+
Fullstack addons expose ElysiaJS routes running within the JChat server runtime:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { createAddonServer } from "@jchat/addon-sdk/server"
|
|
176
|
+
import { t } from "elysia"
|
|
177
|
+
|
|
178
|
+
export default createAddonServer("pollwise", ({ app, db, events }) => {
|
|
179
|
+
return app
|
|
180
|
+
.get("/rooms/:roomId/poll", async ({ params: { roomId } }) => {
|
|
181
|
+
// Query isolated addons schema using Kysely
|
|
182
|
+
const poll = await db
|
|
183
|
+
.selectFrom("addons.Polls")
|
|
184
|
+
.selectAll()
|
|
185
|
+
.where("roomId", "=", roomId)
|
|
186
|
+
.executeTakeFirst()
|
|
187
|
+
|
|
188
|
+
return poll ?? { message: "No active poll" }
|
|
189
|
+
})
|
|
190
|
+
.post(
|
|
191
|
+
"/rooms/:roomId/vote",
|
|
192
|
+
async ({ params: { roomId }, body, user }) => {
|
|
193
|
+
// Record vote in DB
|
|
194
|
+
await db
|
|
195
|
+
.insertInto("addons.PollVotes")
|
|
196
|
+
.values({
|
|
197
|
+
pollId: body.pollId,
|
|
198
|
+
userId: user.id,
|
|
199
|
+
optionId: body.optionId
|
|
200
|
+
})
|
|
201
|
+
.execute()
|
|
202
|
+
|
|
203
|
+
// Broadcast real-time event to room subscribers
|
|
204
|
+
await events.publish(`addon:pollwise:updated`, {
|
|
205
|
+
roomId,
|
|
206
|
+
pollId: body.pollId
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
return { success: true }
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
body: t.Object({
|
|
213
|
+
pollId: t.String(),
|
|
214
|
+
optionId: t.String()
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
})
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 5. Addon Localization (`src/locales/`)
|
|
224
|
+
|
|
225
|
+
Every translatable string in the UI must use `t("key")`.
|
|
226
|
+
Translations reside in `src/locales/<lang>.json` for all 20 supported languages:
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
// src/locales/en.json
|
|
230
|
+
{
|
|
231
|
+
"welcome": "Welcome to Pollwise",
|
|
232
|
+
"vote_button": "Submit Vote",
|
|
233
|
+
"vote_success_title": "Vote Recorded",
|
|
234
|
+
"vote_success_desc": "Thank you for participating."
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Validate key parity across all 20 languages:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
bun check:translations
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 6. Build and Verification Workflow
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# 1. Typecheck the addon
|
|
250
|
+
bun run typecheck
|
|
251
|
+
|
|
252
|
+
# 2. Bundle the addon artifacts (frontend bundle into ui.js, backend into server.js)
|
|
253
|
+
bun run build
|
|
254
|
+
|
|
255
|
+
# 3. In the standalone devkit: start the disposable sandbox environment
|
|
256
|
+
bun run devkit:start
|
|
257
|
+
|
|
258
|
+
# 4. View sandbox logs
|
|
259
|
+
bun run devkit:logs
|
|
260
|
+
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"display": "JChat Addon Base",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
9
|
+
"jsx": "react-jsx",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"verbatimModuleSyntax": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"skipLibCheck": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"types": ["bun", "vite/client"]
|
|
18
|
+
},
|
|
19
|
+
"exclude": ["build", "dist", "node_modules"]
|
|
20
|
+
}
|
package/src/contracts.d.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
export type AddonPermission = string;
|
|
2
|
-
/**
|
|
3
|
-
* Defines a single configuration field for an addon's settings panel. These are shown to site
|
|
4
|
-
* admins in the Jchat dashboard.
|
|
5
|
-
*/
|
|
6
|
-
export interface ConfigSchemaField {
|
|
7
|
-
/** Unique key used to store and retrieve the value in `getConfig` */
|
|
8
|
-
key: string;
|
|
9
|
-
/** Data type for validation and UI rendering */
|
|
10
|
-
type: "string" | "number" | "boolean";
|
|
11
|
-
/** Human-readable label shown in the settings UI */
|
|
12
|
-
label: string;
|
|
13
|
-
/** If true, the admin must provide a value before saving */
|
|
14
|
-
required?: boolean;
|
|
15
|
-
/** Whether the value is sensitive (encrypted at rest and masked in the UI) */
|
|
16
|
-
secret?: boolean;
|
|
17
|
-
/** Default value pre-filled in the settings form for new installations */
|
|
18
|
-
default?: string | number | boolean;
|
|
19
|
-
}
|
|
20
|
-
/** Definition of a custom permission introduced by an addon. */
|
|
21
|
-
export interface AddonPermissionDefinition {
|
|
22
|
-
/** Permission identifier (recommended: `addon.<id>.<action>`) */
|
|
23
|
-
name: string;
|
|
24
|
-
/** Short, human-readable name for the permission */
|
|
25
|
-
label: string;
|
|
26
|
-
/** Detailed description of what the permission grants (shown in Rank editor) */
|
|
27
|
-
description: string;
|
|
28
|
-
}
|
|
29
|
-
/** Valid locations where an addon can be rendered within the Jchat layout. */
|
|
30
|
-
export declare const MOUNT_POINTS: {
|
|
31
|
-
/** Top of the main chat column */
|
|
32
|
-
readonly CHAT_HEADER: "chat-header";
|
|
33
|
-
/** Below the main chat header, above messages */
|
|
34
|
-
readonly CHAT_TOOLBAR: "chat-toolbar";
|
|
35
|
-
/** The persistent right-side sidebar */
|
|
36
|
-
readonly CHAT_SIDEBAR: "chat-sidebar";
|
|
37
|
-
/** Top of the left sidebar (room list) */
|
|
38
|
-
readonly SIDEBAR_TOP: "sidebar-top";
|
|
39
|
-
/** Bottom of the left sidebar */
|
|
40
|
-
readonly SIDEBAR_BOTTOM: "sidebar-bottom";
|
|
41
|
-
/** Action list shown when clicking a user's avatar */
|
|
42
|
-
readonly USER_POPOVER_ACTIONS: "user-popover-actions";
|
|
43
|
-
/** Menu shown when right-clicking a message */
|
|
44
|
-
readonly MESSAGE_CONTEXT_MENU: "message-context-menu";
|
|
45
|
-
/** Floating overlay rendered on top of the message stream */
|
|
46
|
-
readonly MESSAGE_FEED_OVERLAY: "message-feed-overlay";
|
|
47
|
-
/** Main admin dashboard area */
|
|
48
|
-
readonly ADMIN_PANEL: "admin-panel";
|
|
49
|
-
/** User or site settings dashboard area */
|
|
50
|
-
readonly SETTINGS_PANEL: "settings-panel";
|
|
51
|
-
/** The 'plus' (+) menu in the message composer */
|
|
52
|
-
readonly CHAT_PLUS_MENU: "chat-plus-menu";
|
|
53
|
-
/** Custom tab in the emoji/gif selection panel */
|
|
54
|
-
readonly EMOJI_PICKER_GIF_TAB: "emoji-picker-gif-tab";
|
|
55
|
-
/** Full-screen or modal dialog specifically for TubeScan */
|
|
56
|
-
readonly TUBESCAN_DIALOG: "tubescan-dialog";
|
|
57
|
-
};
|
|
58
|
-
/** Union type of all valid addon mount points. */
|
|
59
|
-
export type MountPoint = (typeof MOUNT_POINTS)[keyof typeof MOUNT_POINTS];
|
|
60
|
-
/**
|
|
61
|
-
* The `manifest.json` schema required for every Jchat addon. This file describes how the addon is
|
|
62
|
-
* identified and mounted.
|
|
63
|
-
*/
|
|
64
|
-
export interface AddonManifest {
|
|
65
|
-
/** Unique kebab-case addon identifier (must match the folder name) */
|
|
66
|
-
id: string;
|
|
67
|
-
/** Human-readable addon name */
|
|
68
|
-
name: string;
|
|
69
|
-
/** Semver version string (e.g. `1.2.0`) */
|
|
70
|
-
version: string;
|
|
71
|
-
/** Brief summary of what the addon does */
|
|
72
|
-
description?: string;
|
|
73
|
-
/** Author name, organization, or GitHub handle */
|
|
74
|
-
author?: string;
|
|
75
|
-
/** Support or documentation URL */
|
|
76
|
-
homepage?: string;
|
|
77
|
-
/** SPDX license identifier (e.g. `MIT`) */
|
|
78
|
-
license?: string;
|
|
79
|
-
/** Host and SDK versions this directly executed plugin was built and tested against */
|
|
80
|
-
compatibility: {
|
|
81
|
-
/** Supported JChat versions as a semantic-version range, for example `^1.0.0` */
|
|
82
|
-
jchat: string;
|
|
83
|
-
/** Supported `@jchat/addon-sdk` versions as a semantic-version range */
|
|
84
|
-
addonSdk: string;
|
|
85
|
-
};
|
|
86
|
-
/** Identity of the trusted publisher that signed this package. Required when migrations exist */
|
|
87
|
-
publisher?: {
|
|
88
|
-
id: string;
|
|
89
|
-
};
|
|
90
|
-
/** Signature over the canonical archive digest. Required when migrations exist */
|
|
91
|
-
signature?: {
|
|
92
|
-
algorithm: "rsa-sha256";
|
|
93
|
-
digest: string;
|
|
94
|
-
value: string;
|
|
95
|
-
};
|
|
96
|
-
/** Configuration for the React-based frontend bundle */
|
|
97
|
-
frontend?: {
|
|
98
|
-
/** Relative path to the pre-compiled ESM bundle (created by Vite) */
|
|
99
|
-
bundle: string;
|
|
100
|
-
/** List of UI locations where this addon should be active */
|
|
101
|
-
mountPoints: MountPoint[];
|
|
102
|
-
/** Optional path to a specific UI for the settings panel */
|
|
103
|
-
settings?: string;
|
|
104
|
-
/** Additional shared packages this addon imports from the host */
|
|
105
|
-
externals?: string[];
|
|
106
|
-
};
|
|
107
|
-
/** Configuration for the server-side API bundle */
|
|
108
|
-
server?: {
|
|
109
|
-
/** Relative path to the pre-compiled server bundle */
|
|
110
|
-
bundle?: string;
|
|
111
|
-
/** List of SQL files to run (in order) to set up the addon's database tables */
|
|
112
|
-
migrations?: string[];
|
|
113
|
-
/** List of declarative JSON master-data files to apply once, in order */
|
|
114
|
-
seeds?: string[];
|
|
115
|
-
};
|
|
116
|
-
/**
|
|
117
|
-
* The minimum permission required to see or use this addon. If provided, the host gates
|
|
118
|
-
* visibility in the UI and access to all server routes.
|
|
119
|
-
*/
|
|
120
|
-
accessPermission?: AddonPermission;
|
|
121
|
-
/** Full list of all permissions used by this addon for informational purposes */
|
|
122
|
-
permissions?: AddonPermission[];
|
|
123
|
-
/** Custom permissions that should be registered with the host application on installation */
|
|
124
|
-
permissionDefinitions?: AddonPermissionDefinition[];
|
|
125
|
-
/** Settings form structure shown to site admins. Values are stored encrypted per site */
|
|
126
|
-
configSchema?: ConfigSchemaField[];
|
|
127
|
-
}
|
package/src/contracts.ts
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
export type AddonPermission = string
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Defines a single configuration field for an addon's settings panel. These are shown to site
|
|
5
|
-
* admins in the Jchat dashboard.
|
|
6
|
-
*/
|
|
7
|
-
export interface ConfigSchemaField {
|
|
8
|
-
/** Unique key used to store and retrieve the value in `getConfig` */
|
|
9
|
-
key: string
|
|
10
|
-
/** Data type for validation and UI rendering */
|
|
11
|
-
type: "string" | "number" | "boolean"
|
|
12
|
-
/** Human-readable label shown in the settings UI */
|
|
13
|
-
label: string
|
|
14
|
-
/** If true, the admin must provide a value before saving */
|
|
15
|
-
required?: boolean
|
|
16
|
-
/** Whether the value is sensitive (encrypted at rest and masked in the UI) */
|
|
17
|
-
secret?: boolean
|
|
18
|
-
/** Default value pre-filled in the settings form for new installations */
|
|
19
|
-
default?: string | number | boolean
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Definition of a custom permission introduced by an addon. */
|
|
23
|
-
export interface AddonPermissionDefinition {
|
|
24
|
-
/** Permission identifier (recommended: `addon.<id>.<action>`) */
|
|
25
|
-
name: string
|
|
26
|
-
/** Short, human-readable name for the permission */
|
|
27
|
-
label: string
|
|
28
|
-
/** Detailed description of what the permission grants (shown in Rank editor) */
|
|
29
|
-
description: string
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** Valid locations where an addon can be rendered within the Jchat layout. */
|
|
33
|
-
export const MOUNT_POINTS = {
|
|
34
|
-
/** Top of the main chat column */
|
|
35
|
-
CHAT_HEADER: "chat-header",
|
|
36
|
-
/** Below the main chat header, above messages */
|
|
37
|
-
CHAT_TOOLBAR: "chat-toolbar",
|
|
38
|
-
/** The persistent right-side sidebar */
|
|
39
|
-
CHAT_SIDEBAR: "chat-sidebar",
|
|
40
|
-
/** Top of the left sidebar (room list) */
|
|
41
|
-
SIDEBAR_TOP: "sidebar-top",
|
|
42
|
-
/** Bottom of the left sidebar */
|
|
43
|
-
SIDEBAR_BOTTOM: "sidebar-bottom",
|
|
44
|
-
/** Action list shown when clicking a user's avatar */
|
|
45
|
-
USER_POPOVER_ACTIONS: "user-popover-actions",
|
|
46
|
-
/** Menu shown when right-clicking a message */
|
|
47
|
-
MESSAGE_CONTEXT_MENU: "message-context-menu",
|
|
48
|
-
/** Floating overlay rendered on top of the message stream */
|
|
49
|
-
MESSAGE_FEED_OVERLAY: "message-feed-overlay",
|
|
50
|
-
/** Main admin dashboard area */
|
|
51
|
-
ADMIN_PANEL: "admin-panel",
|
|
52
|
-
/** User or site settings dashboard area */
|
|
53
|
-
SETTINGS_PANEL: "settings-panel",
|
|
54
|
-
/** The 'plus' (+) menu in the message composer */
|
|
55
|
-
CHAT_PLUS_MENU: "chat-plus-menu",
|
|
56
|
-
/** Custom tab in the emoji/gif selection panel */
|
|
57
|
-
EMOJI_PICKER_GIF_TAB: "emoji-picker-gif-tab",
|
|
58
|
-
/** Full-screen or modal dialog specifically for TubeScan */
|
|
59
|
-
TUBESCAN_DIALOG: "tubescan-dialog"
|
|
60
|
-
} as const
|
|
61
|
-
|
|
62
|
-
/** Union type of all valid addon mount points. */
|
|
63
|
-
export type MountPoint = (typeof MOUNT_POINTS)[keyof typeof MOUNT_POINTS]
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* The `manifest.json` schema required for every Jchat addon. This file describes how the addon is
|
|
67
|
-
* identified and mounted.
|
|
68
|
-
*/
|
|
69
|
-
export interface AddonManifest {
|
|
70
|
-
/** Unique kebab-case addon identifier (must match the folder name) */
|
|
71
|
-
id: string
|
|
72
|
-
/** Human-readable addon name */
|
|
73
|
-
name: string
|
|
74
|
-
/** Semver version string (e.g. `1.2.0`) */
|
|
75
|
-
version: string
|
|
76
|
-
/** Brief summary of what the addon does */
|
|
77
|
-
description?: string
|
|
78
|
-
/** Author name, organization, or GitHub handle */
|
|
79
|
-
author?: string
|
|
80
|
-
/** Support or documentation URL */
|
|
81
|
-
homepage?: string
|
|
82
|
-
/** SPDX license identifier (e.g. `MIT`) */
|
|
83
|
-
license?: string
|
|
84
|
-
/** Host and SDK versions this directly executed plugin was built and tested against */
|
|
85
|
-
compatibility: {
|
|
86
|
-
/** Supported JChat versions as a semantic-version range, for example `^1.0.0` */
|
|
87
|
-
jchat: string
|
|
88
|
-
/** Supported `@jchat/addon-sdk` versions as a semantic-version range */
|
|
89
|
-
addonSdk: string
|
|
90
|
-
}
|
|
91
|
-
/** Identity of the trusted publisher that signed this package. Required when migrations exist */
|
|
92
|
-
publisher?: {
|
|
93
|
-
id: string
|
|
94
|
-
}
|
|
95
|
-
/** Signature over the canonical archive digest. Required when migrations exist */
|
|
96
|
-
signature?: {
|
|
97
|
-
algorithm: "rsa-sha256"
|
|
98
|
-
digest: string
|
|
99
|
-
value: string
|
|
100
|
-
}
|
|
101
|
-
/** Configuration for the React-based frontend bundle */
|
|
102
|
-
frontend?: {
|
|
103
|
-
/** Relative path to the pre-compiled ESM bundle (created by Vite) */
|
|
104
|
-
bundle: string
|
|
105
|
-
/** List of UI locations where this addon should be active */
|
|
106
|
-
mountPoints: MountPoint[]
|
|
107
|
-
/** Optional path to a specific UI for the settings panel */
|
|
108
|
-
settings?: string
|
|
109
|
-
/** Additional shared packages this addon imports from the host */
|
|
110
|
-
externals?: string[]
|
|
111
|
-
}
|
|
112
|
-
/** Configuration for the server-side API bundle */
|
|
113
|
-
server?: {
|
|
114
|
-
/** Relative path to the pre-compiled server bundle */
|
|
115
|
-
bundle?: string
|
|
116
|
-
/** List of SQL files to run (in order) to set up the addon's database tables */
|
|
117
|
-
migrations?: string[]
|
|
118
|
-
/** List of declarative JSON master-data files to apply once, in order */
|
|
119
|
-
seeds?: string[]
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* The minimum permission required to see or use this addon. If provided, the host gates
|
|
123
|
-
* visibility in the UI and access to all server routes.
|
|
124
|
-
*/
|
|
125
|
-
accessPermission?: AddonPermission
|
|
126
|
-
/** Full list of all permissions used by this addon for informational purposes */
|
|
127
|
-
permissions?: AddonPermission[]
|
|
128
|
-
/** Custom permissions that should be registered with the host application on installation */
|
|
129
|
-
permissionDefinitions?: AddonPermissionDefinition[]
|
|
130
|
-
/** Settings form structure shown to site admins. Values are stored encrypted per site */
|
|
131
|
-
configSchema?: ConfigSchemaField[]
|
|
132
|
-
}
|