@jchat/addon-sdk 1.0.0-alpha.30 → 1.0.0-alpha.31
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 +25 -0
- package/README.md +7 -8
- package/dist/i18n-validator.d.mts +9 -3
- package/dist/i18n-validator.mjs +9 -5
- package/dist/index.d.mts +846 -17
- package/dist/index.mjs +2 -2
- package/dist/src.mjs +27 -2
- package/dist/testing.d.mts +1 -1
- package/dist/ui.d.mts +7 -1
- package/dist/ui.mjs +8 -2
- package/dist/vite.mjs +1 -2
- package/package.json +7 -24
- package/skills/jchat-addon-development/SKILL.md +5 -5
- package/src/tailwind.css +1 -0
- package/dist/icon.d.mts +0 -4
- package/dist/icon.mjs +0 -4
- package/dist/index2.d.mts +0 -831
- package/dist/types.d.mts +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @jchat/addon-sdk
|
|
2
2
|
|
|
3
|
+
## 1.0.0-alpha.31
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add receiverId to message mutable data and findUserByName to AddonServerContext
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Clarify mandatory English base localization policy and fix dependency catalog configuration
|
|
12
|
+
|
|
13
|
+
- Add useAddonSettings hook and AddonSettingsLoading component
|
|
14
|
+
|
|
15
|
+
- Allow optional host language translation files with automatic English fallback
|
|
16
|
+
|
|
17
|
+
- Add generic return type to AddonServerContext getConfig
|
|
18
|
+
|
|
19
|
+
- Add findUserByName mock to testing context
|
|
20
|
+
|
|
21
|
+
- Upgrade package type-checking to native bun check for faster validation
|
|
22
|
+
|
|
23
|
+
- Consolidate icons and Tailwind styles into @jchat/addon-sdk/ui
|
|
24
|
+
|
|
25
|
+
- Bumped `@jchat/*` dependencies:
|
|
26
|
+
- [`ui@1.0.0-alpha.28`](https://github.com/jchatcloud/jchat/releases/tag/ui@v1.0.0-alpha.28)
|
|
27
|
+
|
|
3
28
|
## 1.0.0-alpha.30
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -14,10 +14,10 @@ Provides typed interfaces, manifest contracts, Vite bundler plugins, and CLI dev
|
|
|
14
14
|
JChat addons are **sandboxed, modular extensions** designed to enhance real-time chats without modifying core database schemas or server code.
|
|
15
15
|
|
|
16
16
|
- **Ultra-Lightweight Server Bundles**: Elysia and TypeBox are externalized and provided directly by the host server runtime via `ctx.t` and `app`. Server bundles (`build/api.js`) compile down to just **2–7 KB**.
|
|
17
|
-
- **Zero Frontend Bundle Bloat**: Host externals (`react`, `react-dom`, `@jchat/ui`, `@
|
|
17
|
+
- **Zero Frontend Bundle Bloat**: Host externals (`react`, `react-dom`, `@jchat/ui`, `@tanstack/react-query`, `jotai`) are injected at runtime by the JChat host application.
|
|
18
18
|
- **Isolated Database Schema**: Addon tables reside exclusively in the isolated `addons` PostgreSQL schema (e.g. `addons.GlimpseStories`), preventing collisions with core chat tables.
|
|
19
19
|
- **Scoped Cache & Real-Time Events**: Addons receive namespaced Redis cache (`addon:<id>:<key>`) and real-time WebSocket event broadcasting scoped to sites, rooms, or users.
|
|
20
|
-
- **
|
|
20
|
+
- **First-Class i18n & RTL Support**: English (`en.json`) is mandatory as the base localization; the other 19 host languages are optional with automatic runtime fallback to English and full RTL direction support.
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
@@ -121,7 +121,7 @@ Addon UI components receive typed `AddonProps` and access host services via the
|
|
|
121
121
|
|
|
122
122
|
```tsx
|
|
123
123
|
import { useAddonSDK, useAddonQuery, useTranslation, type AddonProps } from "@jchat/addon-sdk"
|
|
124
|
-
import Icons from "@jchat/addon-sdk/
|
|
124
|
+
import { Icons } from "@jchat/addon-sdk/ui"
|
|
125
125
|
import locales from "./locales"
|
|
126
126
|
|
|
127
127
|
export default function MyAddon({ mountPoint, roomId }: AddonProps) {
|
|
@@ -308,8 +308,7 @@ export const activeTabAtom = atom<"trending" | "search">("trending")
|
|
|
308
308
|
|
|
309
309
|
### 4. Localization: `useTranslation()` & `useLocale()`
|
|
310
310
|
|
|
311
|
-
|
|
312
|
-
`ar`, `bg`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hr`, `kn`, `ml`, `nl`, `pt`, `ro`, `ru`, `ta`, `te`, `tr`, `ur`.
|
|
311
|
+
English (`en.json`) is strictly mandatory as the base localization. The other 19 host languages (`ar`, `bg`, `de`, `el`, `es`, `fr`, `he`, `hi`, `hr`, `kn`, `ml`, `nl`, `pt`, `ro`, `ru`, `ta`, `te`, `tr`, `ur`) are optional and automatically fall back to English at runtime.
|
|
313
312
|
|
|
314
313
|
```tsx
|
|
315
314
|
import { useTranslation, useLocale } from "@jchat/addon-sdk"
|
|
@@ -325,12 +324,12 @@ For backend server routes (`src/api.ts`), use `createTranslator(locales, default
|
|
|
325
324
|
|
|
326
325
|
---
|
|
327
326
|
|
|
328
|
-
### 5. Icons: `@jchat/addon-sdk/
|
|
327
|
+
### 5. Icons: `@jchat/addon-sdk/ui`
|
|
329
328
|
|
|
330
|
-
Imports the site's active icon pack directly
|
|
329
|
+
Imports the site's active icon pack directly from `@jchat/addon-sdk/ui`, ensuring visual consistency with the host theme:
|
|
331
330
|
|
|
332
331
|
```tsx
|
|
333
|
-
import Icons from "@jchat/addon-sdk/
|
|
332
|
+
import { Icons } from "@jchat/addon-sdk/ui"
|
|
334
333
|
|
|
335
334
|
;<Icons.Heart className="size-4 text-red-500" />
|
|
336
335
|
```
|
|
@@ -6,12 +6,18 @@ export interface AddonLocaleValidationResult {
|
|
|
6
6
|
missingKeys: Record<string, string[]>;
|
|
7
7
|
extraKeys: Record<string, string[]>;
|
|
8
8
|
}
|
|
9
|
+
export interface ValidateAddonLocalesOptions {
|
|
10
|
+
strict?: boolean;
|
|
11
|
+
}
|
|
9
12
|
/**
|
|
10
|
-
* Validates that an addon's `locales/` directory contains valid
|
|
11
|
-
*
|
|
13
|
+
* Validates that an addon's `locales/` directory contains a valid `en.json` base file, and that any
|
|
14
|
+
* provided host language files contain valid JSON and matching keys. Missing translations
|
|
15
|
+
* automatically fall back to English at runtime.
|
|
12
16
|
*
|
|
13
17
|
* @param dirPath - Path to the addon's locales directory.
|
|
14
18
|
* @param domainName - Optional label for error messages (defaults to "Addon").
|
|
19
|
+
* @param options - Optional configuration (e.g. `{ strict: true }` to enforce 100% presence of all
|
|
20
|
+
* 20 language files).
|
|
15
21
|
*/
|
|
16
|
-
export declare function validateAddonLocales(dirPath: string, domainName?: string): AddonLocaleValidationResult;
|
|
22
|
+
export declare function validateAddonLocales(dirPath: string, domainName?: string, options?: ValidateAddonLocalesOptions): AddonLocaleValidationResult;
|
|
17
23
|
//#endregion
|
package/dist/i18n-validator.mjs
CHANGED
|
@@ -14,13 +14,17 @@ function extractNestedKeys(obj, prefix = "") {
|
|
|
14
14
|
return keys;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* Validates that an addon's `locales/` directory contains valid
|
|
18
|
-
*
|
|
17
|
+
* Validates that an addon's `locales/` directory contains a valid `en.json` base file, and that any
|
|
18
|
+
* provided host language files contain valid JSON and matching keys. Missing translations
|
|
19
|
+
* automatically fall back to English at runtime.
|
|
19
20
|
*
|
|
20
21
|
* @param dirPath - Path to the addon's locales directory.
|
|
21
22
|
* @param domainName - Optional label for error messages (defaults to "Addon").
|
|
23
|
+
* @param options - Optional configuration (e.g. `{ strict: true }` to enforce 100% presence of all
|
|
24
|
+
* 20 language files).
|
|
22
25
|
*/
|
|
23
|
-
function validateAddonLocales(dirPath, domainName = "Addon") {
|
|
26
|
+
function validateAddonLocales(dirPath, domainName = "Addon", options) {
|
|
27
|
+
const isStrict = Boolean(options?.strict);
|
|
24
28
|
const errors = [];
|
|
25
29
|
const missingFiles = [];
|
|
26
30
|
const missingKeys = {};
|
|
@@ -58,17 +62,17 @@ function validateAddonLocales(dirPath, domainName = "Addon") {
|
|
|
58
62
|
const langFileName = `${lang}.json`;
|
|
59
63
|
const langPath = path$1.join(dirPath, langFileName);
|
|
60
64
|
if (!fs$1.existsSync(langPath)) {
|
|
61
|
-
errors.push(`[${domainName}] Missing locale file: ${langFileName}`);
|
|
62
65
|
missingFiles.push(langFileName);
|
|
66
|
+
if (isStrict) errors.push(`[${domainName}] Missing locale file: ${langFileName}`);
|
|
63
67
|
continue;
|
|
64
68
|
}
|
|
65
69
|
try {
|
|
66
70
|
const langContent = JSON.parse(fs$1.readFileSync(langPath, "utf-8"));
|
|
67
71
|
const langKeys = new Set(extractNestedKeys(langContent));
|
|
68
72
|
for (const key of enKeys) if (!langKeys.has(key)) {
|
|
69
|
-
errors.push(`[${domainName}] Missing key in ${langFileName}: "${key}"`);
|
|
70
73
|
if (!missingKeys[lang]) missingKeys[lang] = [];
|
|
71
74
|
missingKeys[lang].push(key);
|
|
75
|
+
if (isStrict) errors.push(`[${domainName}] Missing key in ${langFileName}: "${key}"`);
|
|
72
76
|
}
|
|
73
77
|
for (const key of langKeys) if (!enKeys.has(key)) {
|
|
74
78
|
errors.push(`[${domainName}] Extra key in ${langFileName} (not in en.json): "${key}"`);
|