@djangocfg/ext-knowbase 1.0.22 → 1.0.23

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/dist/config.cjs CHANGED
@@ -27,7 +27,7 @@ var import_ext_base = require("@djangocfg/ext-base");
27
27
  // package.json
28
28
  var package_default = {
29
29
  name: "@djangocfg/ext-knowbase",
30
- version: "1.0.22",
30
+ version: "1.0.23",
31
31
  description: "Knowledge base and chat extension for DjangoCFG",
32
32
  keywords: [
33
33
  "django",
@@ -98,14 +98,15 @@ var package_default = {
98
98
  "@djangocfg/ui-nextjs": "workspace:*",
99
99
  consola: "^3.4.2",
100
100
  "lucide-react": "^0.545.0",
101
+ moment: "^2.30.1",
101
102
  next: "^16",
103
+ "next-intl": "^4",
102
104
  "p-retry": "^7.0.0",
103
105
  react: "^19",
104
106
  "react-dom": "^19",
105
107
  "react-markdown": "^9.0.0 || ^10.0.0",
106
108
  swr: "^2.3.7",
107
- zod: "^4.3.4",
108
- moment: "^2.30.1"
109
+ zod: "^4.3.4"
109
110
  },
110
111
  devDependencies: {
111
112
  "@djangocfg/api": "workspace:*",
@@ -116,6 +117,7 @@ var package_default = {
116
117
  "@types/node": "^24.7.2",
117
118
  "@types/react": "^19.0.0",
118
119
  consola: "^3.4.2",
120
+ "next-intl": "^4.1.0",
119
121
  "p-retry": "^7.0.0",
120
122
  swr: "^2.3.7",
121
123
  tsup: "^8.5.0",
package/dist/config.js CHANGED
@@ -4,7 +4,7 @@ import { createExtensionConfig } from "@djangocfg/ext-base";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "@djangocfg/ext-knowbase",
7
- version: "1.0.22",
7
+ version: "1.0.23",
8
8
  description: "Knowledge base and chat extension for DjangoCFG",
9
9
  keywords: [
10
10
  "django",
@@ -75,14 +75,15 @@ var package_default = {
75
75
  "@djangocfg/ui-nextjs": "workspace:*",
76
76
  consola: "^3.4.2",
77
77
  "lucide-react": "^0.545.0",
78
+ moment: "^2.30.1",
78
79
  next: "^16",
80
+ "next-intl": "^4",
79
81
  "p-retry": "^7.0.0",
80
82
  react: "^19",
81
83
  "react-dom": "^19",
82
84
  "react-markdown": "^9.0.0 || ^10.0.0",
83
85
  swr: "^2.3.7",
84
- zod: "^4.3.4",
85
- moment: "^2.30.1"
86
+ zod: "^4.3.4"
86
87
  },
87
88
  devDependencies: {
88
89
  "@djangocfg/api": "workspace:*",
@@ -93,6 +94,7 @@ var package_default = {
93
94
  "@types/node": "^24.7.2",
94
95
  "@types/react": "^19.0.0",
95
96
  consola: "^3.4.2",
97
+ "next-intl": "^4.1.0",
96
98
  "p-retry": "^7.0.0",
97
99
  swr: "^2.3.7",
98
100
  tsup: "^8.5.0",
package/dist/hooks.cjs CHANGED
@@ -12,8 +12,7 @@ var jsxRuntime = require('react/jsx-runtime');
12
12
  var lucideReact = require('lucide-react');
13
13
  var navigation = require('next/navigation');
14
14
  var reactDom = require('react-dom');
15
- var i18n = require('@djangocfg/ext-base/i18n');
16
- var i18n$1 = require('@djangocfg/i18n');
15
+ var nextIntl = require('next-intl');
17
16
  var uiNextjs = require('@djangocfg/ui-nextjs');
18
17
  var hooks = require('@djangocfg/ui-core/hooks');
19
18
  var moment = require('moment');
@@ -4799,7 +4798,7 @@ var apiKnowbase = api.createExtensionAPI(API);
4799
4798
  // package.json
4800
4799
  var package_default = {
4801
4800
  name: "@djangocfg/ext-knowbase",
4802
- version: "1.0.22",
4801
+ version: "1.0.23",
4803
4802
  description: "Knowledge base and chat extension for DjangoCFG",
4804
4803
  keywords: [
4805
4804
  "django",
@@ -4870,14 +4869,15 @@ var package_default = {
4870
4869
  "@djangocfg/ui-nextjs": "workspace:*",
4871
4870
  consola: "^3.4.2",
4872
4871
  "lucide-react": "^0.545.0",
4872
+ moment: "^2.30.1",
4873
4873
  next: "^16",
4874
+ "next-intl": "^4",
4874
4875
  "p-retry": "^7.0.0",
4875
4876
  react: "^19",
4876
4877
  "react-dom": "^19",
4877
4878
  "react-markdown": "^9.0.0 || ^10.0.0",
4878
4879
  swr: "^2.3.7",
4879
- zod: "^4.3.4",
4880
- moment: "^2.30.1"
4880
+ zod: "^4.3.4"
4881
4881
  },
4882
4882
  devDependencies: {
4883
4883
  "@djangocfg/api": "workspace:*",
@@ -4888,6 +4888,7 @@ var package_default = {
4888
4888
  "@types/node": "^24.7.2",
4889
4889
  "@types/react": "^19.0.0",
4890
4890
  consola: "^3.4.2",
4891
+ "next-intl": "^4.1.0",
4891
4892
  "p-retry": "^7.0.0",
4892
4893
  swr: "^2.3.7",
4893
4894
  tsup: "^8.5.0",
@@ -5357,14 +5358,28 @@ var ko = {
5357
5358
  }
5358
5359
  };
5359
5360
 
5360
- // src/i18n/index.ts
5361
- var KNOWBASE_NAMESPACE = "knowbase";
5362
- var knowbaseI18n = i18n.createExtensionI18n({
5363
- namespace: KNOWBASE_NAMESPACE,
5364
- defaultLocale: "en",
5365
- locales: { en, ru, ko }
5366
- });
5367
- knowbaseI18n.getAllTranslations();
5361
+ // src/i18n/useKnowbaseT.ts
5362
+ var translations = { en, ru, ko };
5363
+ function getNestedValue(obj, path) {
5364
+ const keys = path.split(".");
5365
+ let result = obj;
5366
+ for (const key of keys) {
5367
+ if (result && typeof result === "object" && key in result) {
5368
+ result = result[key];
5369
+ } else {
5370
+ return path;
5371
+ }
5372
+ }
5373
+ return typeof result === "string" ? result : path;
5374
+ }
5375
+ function useKnowbaseT() {
5376
+ const locale = nextIntl.useLocale();
5377
+ const t = react.useMemo(() => translations[locale] || translations.en, [locale]);
5378
+ return react.useCallback(
5379
+ (key) => getNestedValue(t, key),
5380
+ [t]
5381
+ );
5382
+ }
5368
5383
  var isDevelopment = process.env.NODE_ENV === "development";
5369
5384
  var logger = consola.createConsola({
5370
5385
  level: isDevelopment ? 4 : 1
@@ -5381,8 +5396,7 @@ var MessageList = ({
5381
5396
  autoScroll = true,
5382
5397
  className = ""
5383
5398
  }) => {
5384
- const baseT = i18n$1.useT();
5385
- const kt = i18n.createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5399
+ const kt = useKnowbaseT();
5386
5400
  const scrollRef = react.useRef(null);
5387
5401
  const { user } = auth.useAuth();
5388
5402
  const labels = react.useMemo(() => ({
@@ -5472,8 +5486,7 @@ var MessageInput = ({
5472
5486
  placeholder,
5473
5487
  className = ""
5474
5488
  }) => {
5475
- const baseT = i18n$1.useT();
5476
- const kt = i18n.createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5489
+ const kt = useKnowbaseT();
5477
5490
  const [message, setMessage] = react.useState("");
5478
5491
  const [rows, setRows] = react.useState(1);
5479
5492
  const textareaRef = react.useRef(null);
@@ -5610,8 +5623,7 @@ var SessionList = ({
5610
5623
  onSelectSession,
5611
5624
  className = ""
5612
5625
  }) => {
5613
- const baseT = i18n$1.useT();
5614
- const kt = i18n.createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5626
+ const kt = useKnowbaseT();
5615
5627
  const { deleteSession, archiveSession } = useKnowbaseSessionsContext();
5616
5628
  const {
5617
5629
  sessions,
@@ -5734,8 +5746,7 @@ var ChatWidget = ({
5734
5746
  onToggle,
5735
5747
  onMessage
5736
5748
  }) => {
5737
- const baseT = i18n$1.useT();
5738
- const kt = i18n.createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5749
+ const kt = useKnowbaseT();
5739
5750
  const { sendQuery, getChatHistory } = useKnowbaseChatContext();
5740
5751
  const { createSession, getSession } = useKnowbaseSessionsContext();
5741
5752
  const {
package/dist/hooks.js CHANGED
@@ -10,8 +10,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
10
  import { Bot, ExternalLink, User, Loader2, Send, MessageSquare, Clock, Archive, Trash2, List, Plus, X, Minimize2, Maximize2 } from 'lucide-react';
11
11
  import { usePathname } from 'next/navigation';
12
12
  import { createPortal } from 'react-dom';
13
- import { createExtensionI18n, createTypedExtensionT } from '@djangocfg/ext-base/i18n';
14
- import { useT } from '@djangocfg/i18n';
13
+ import { useLocale } from 'next-intl';
15
14
  import { ScrollArea, Avatar, Card, CardContent, Badge, AvatarImage, AvatarFallback, Textarea, Button, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, CardHeader } from '@djangocfg/ui-nextjs';
16
15
  import { useIsMobile, useLocalStorage } from '@djangocfg/ui-core/hooks';
17
16
  import moment from 'moment';
@@ -4790,7 +4789,7 @@ var apiKnowbase = createExtensionAPI(API);
4790
4789
  // package.json
4791
4790
  var package_default = {
4792
4791
  name: "@djangocfg/ext-knowbase",
4793
- version: "1.0.22",
4792
+ version: "1.0.23",
4794
4793
  description: "Knowledge base and chat extension for DjangoCFG",
4795
4794
  keywords: [
4796
4795
  "django",
@@ -4861,14 +4860,15 @@ var package_default = {
4861
4860
  "@djangocfg/ui-nextjs": "workspace:*",
4862
4861
  consola: "^3.4.2",
4863
4862
  "lucide-react": "^0.545.0",
4863
+ moment: "^2.30.1",
4864
4864
  next: "^16",
4865
+ "next-intl": "^4",
4865
4866
  "p-retry": "^7.0.0",
4866
4867
  react: "^19",
4867
4868
  "react-dom": "^19",
4868
4869
  "react-markdown": "^9.0.0 || ^10.0.0",
4869
4870
  swr: "^2.3.7",
4870
- zod: "^4.3.4",
4871
- moment: "^2.30.1"
4871
+ zod: "^4.3.4"
4872
4872
  },
4873
4873
  devDependencies: {
4874
4874
  "@djangocfg/api": "workspace:*",
@@ -4879,6 +4879,7 @@ var package_default = {
4879
4879
  "@types/node": "^24.7.2",
4880
4880
  "@types/react": "^19.0.0",
4881
4881
  consola: "^3.4.2",
4882
+ "next-intl": "^4.1.0",
4882
4883
  "p-retry": "^7.0.0",
4883
4884
  swr: "^2.3.7",
4884
4885
  tsup: "^8.5.0",
@@ -5348,14 +5349,28 @@ var ko = {
5348
5349
  }
5349
5350
  };
5350
5351
 
5351
- // src/i18n/index.ts
5352
- var KNOWBASE_NAMESPACE = "knowbase";
5353
- var knowbaseI18n = createExtensionI18n({
5354
- namespace: KNOWBASE_NAMESPACE,
5355
- defaultLocale: "en",
5356
- locales: { en, ru, ko }
5357
- });
5358
- knowbaseI18n.getAllTranslations();
5352
+ // src/i18n/useKnowbaseT.ts
5353
+ var translations = { en, ru, ko };
5354
+ function getNestedValue(obj, path) {
5355
+ const keys = path.split(".");
5356
+ let result = obj;
5357
+ for (const key of keys) {
5358
+ if (result && typeof result === "object" && key in result) {
5359
+ result = result[key];
5360
+ } else {
5361
+ return path;
5362
+ }
5363
+ }
5364
+ return typeof result === "string" ? result : path;
5365
+ }
5366
+ function useKnowbaseT() {
5367
+ const locale = useLocale();
5368
+ const t = useMemo(() => translations[locale] || translations.en, [locale]);
5369
+ return useCallback(
5370
+ (key) => getNestedValue(t, key),
5371
+ [t]
5372
+ );
5373
+ }
5359
5374
  var isDevelopment = process.env.NODE_ENV === "development";
5360
5375
  var logger = createConsola({
5361
5376
  level: isDevelopment ? 4 : 1
@@ -5372,8 +5387,7 @@ var MessageList = ({
5372
5387
  autoScroll = true,
5373
5388
  className = ""
5374
5389
  }) => {
5375
- const baseT = useT();
5376
- const kt = createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5390
+ const kt = useKnowbaseT();
5377
5391
  const scrollRef = useRef(null);
5378
5392
  const { user } = useAuth();
5379
5393
  const labels = useMemo(() => ({
@@ -5463,8 +5477,7 @@ var MessageInput = ({
5463
5477
  placeholder,
5464
5478
  className = ""
5465
5479
  }) => {
5466
- const baseT = useT();
5467
- const kt = createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5480
+ const kt = useKnowbaseT();
5468
5481
  const [message, setMessage] = useState("");
5469
5482
  const [rows, setRows] = useState(1);
5470
5483
  const textareaRef = useRef(null);
@@ -5601,8 +5614,7 @@ var SessionList = ({
5601
5614
  onSelectSession,
5602
5615
  className = ""
5603
5616
  }) => {
5604
- const baseT = useT();
5605
- const kt = createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5617
+ const kt = useKnowbaseT();
5606
5618
  const { deleteSession, archiveSession } = useKnowbaseSessionsContext();
5607
5619
  const {
5608
5620
  sessions,
@@ -5725,8 +5737,7 @@ var ChatWidget = ({
5725
5737
  onToggle,
5726
5738
  onMessage
5727
5739
  }) => {
5728
- const baseT = useT();
5729
- const kt = createTypedExtensionT(baseT, KNOWBASE_NAMESPACE);
5740
+ const kt = useKnowbaseT();
5730
5741
  const { sendQuery, getChatHistory } = useKnowbaseChatContext();
5731
5742
  const { createSession, getSession } = useKnowbaseSessionsContext();
5732
5743
  const {
package/dist/i18n.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -19,12 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
20
  // src/i18n/index.ts
20
21
  var i18n_exports = {};
21
22
  __export(i18n_exports, {
22
- KNOWBASE_NAMESPACE: () => KNOWBASE_NAMESPACE,
23
- knowbaseI18n: () => knowbaseI18n,
24
- knowbaseTranslations: () => knowbaseTranslations
23
+ en: () => en,
24
+ ko: () => ko,
25
+ ru: () => ru,
26
+ useKnowbaseT: () => useKnowbaseT
25
27
  });
26
28
  module.exports = __toCommonJS(i18n_exports);
27
- var import_i18n = require("@djangocfg/ext-base/i18n");
29
+
30
+ // src/i18n/useKnowbaseT.ts
31
+ var import_next_intl = require("next-intl");
32
+ var import_react = require("react");
28
33
 
29
34
  // src/i18n/locales/en.ts
30
35
  var en = {
@@ -128,17 +133,32 @@ var ko = {
128
133
  }
129
134
  };
130
135
 
131
- // src/i18n/index.ts
132
- var KNOWBASE_NAMESPACE = "knowbase";
133
- var knowbaseI18n = (0, import_i18n.createExtensionI18n)({
134
- namespace: KNOWBASE_NAMESPACE,
135
- defaultLocale: "en",
136
- locales: { en, ru, ko }
137
- });
138
- var knowbaseTranslations = knowbaseI18n.getAllTranslations();
136
+ // src/i18n/useKnowbaseT.ts
137
+ var translations = { en, ru, ko };
138
+ function getNestedValue(obj, path) {
139
+ const keys = path.split(".");
140
+ let result = obj;
141
+ for (const key of keys) {
142
+ if (result && typeof result === "object" && key in result) {
143
+ result = result[key];
144
+ } else {
145
+ return path;
146
+ }
147
+ }
148
+ return typeof result === "string" ? result : path;
149
+ }
150
+ function useKnowbaseT() {
151
+ const locale = (0, import_next_intl.useLocale)();
152
+ const t = (0, import_react.useMemo)(() => translations[locale] || translations.en, [locale]);
153
+ return (0, import_react.useCallback)(
154
+ (key) => getNestedValue(t, key),
155
+ [t]
156
+ );
157
+ }
139
158
  // Annotate the CommonJS export names for ESM import in node:
140
159
  0 && (module.exports = {
141
- KNOWBASE_NAMESPACE,
142
- knowbaseI18n,
143
- knowbaseTranslations
160
+ en,
161
+ ko,
162
+ ru,
163
+ useKnowbaseT
144
164
  });
package/dist/i18n.d.cts CHANGED
@@ -1,16 +1,14 @@
1
- import * as _djangocfg_ext_base_i18n from '@djangocfg/ext-base/i18n';
2
- import { ExtensionKeys, PathKeys } from '@djangocfg/ext-base/i18n';
3
-
4
1
  /**
5
2
  * Knowbase Extension I18n Types
6
3
  */
7
-
8
4
  /**
9
- * All valid keys for knowbase translations (with namespace)
5
+ * Helper type to get dot-notation paths from nested object
10
6
  */
11
- type KnowbaseKeys = ExtensionKeys<'knowbase', KnowbaseTranslations>;
7
+ type PathKeys<T, Prefix extends string = ''> = T extends object ? {
8
+ [K in keyof T]: K extends string ? T[K] extends object ? PathKeys<T[K], `${Prefix}${K}.`> : `${Prefix}${K}` : never;
9
+ }[keyof T] : never;
12
10
  /**
13
- * Keys without namespace prefix (for createTypedExtensionT)
11
+ * Keys for knowbase translations
14
12
  */
15
13
  type KnowbaseLocalKeys = PathKeys<KnowbaseTranslations>;
16
14
  interface KnowbaseTranslations {
@@ -49,11 +47,26 @@ interface KnowbaseTranslations {
49
47
  };
50
48
  }
51
49
 
52
- /** Knowbase extension namespace */
53
- declare const KNOWBASE_NAMESPACE: "knowbase";
54
- declare const knowbaseI18n: _djangocfg_ext_base_i18n.ExtensionI18n<KnowbaseTranslations>;
55
- declare const knowbaseTranslations: Record<string, {
56
- [namespace: string]: KnowbaseTranslations;
57
- }>;
50
+ /**
51
+ * Self-contained translation hook for knowbase extension
52
+ *
53
+ * Uses built-in translations based on current locale from next-intl.
54
+ * No need to add translations to app's i18n config.
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * function ChatWidget() {
59
+ * const t = useKnowbaseT();
60
+ * return <h1>{t('chat.title')}</h1>;
61
+ * }
62
+ * ```
63
+ */
64
+ declare function useKnowbaseT(): (key: KnowbaseLocalKeys) => string;
65
+
66
+ declare const en: KnowbaseTranslations;
67
+
68
+ declare const ru: KnowbaseTranslations;
69
+
70
+ declare const ko: KnowbaseTranslations;
58
71
 
59
- export { KNOWBASE_NAMESPACE, type KnowbaseKeys, type KnowbaseLocalKeys, type KnowbaseTranslations, knowbaseI18n, knowbaseTranslations };
72
+ export { type KnowbaseLocalKeys, type KnowbaseTranslations, en, ko, ru, useKnowbaseT };
package/dist/i18n.d.ts CHANGED
@@ -1,16 +1,14 @@
1
- import * as _djangocfg_ext_base_i18n from '@djangocfg/ext-base/i18n';
2
- import { ExtensionKeys, PathKeys } from '@djangocfg/ext-base/i18n';
3
-
4
1
  /**
5
2
  * Knowbase Extension I18n Types
6
3
  */
7
-
8
4
  /**
9
- * All valid keys for knowbase translations (with namespace)
5
+ * Helper type to get dot-notation paths from nested object
10
6
  */
11
- type KnowbaseKeys = ExtensionKeys<'knowbase', KnowbaseTranslations>;
7
+ type PathKeys<T, Prefix extends string = ''> = T extends object ? {
8
+ [K in keyof T]: K extends string ? T[K] extends object ? PathKeys<T[K], `${Prefix}${K}.`> : `${Prefix}${K}` : never;
9
+ }[keyof T] : never;
12
10
  /**
13
- * Keys without namespace prefix (for createTypedExtensionT)
11
+ * Keys for knowbase translations
14
12
  */
15
13
  type KnowbaseLocalKeys = PathKeys<KnowbaseTranslations>;
16
14
  interface KnowbaseTranslations {
@@ -49,11 +47,26 @@ interface KnowbaseTranslations {
49
47
  };
50
48
  }
51
49
 
52
- /** Knowbase extension namespace */
53
- declare const KNOWBASE_NAMESPACE: "knowbase";
54
- declare const knowbaseI18n: _djangocfg_ext_base_i18n.ExtensionI18n<KnowbaseTranslations>;
55
- declare const knowbaseTranslations: Record<string, {
56
- [namespace: string]: KnowbaseTranslations;
57
- }>;
50
+ /**
51
+ * Self-contained translation hook for knowbase extension
52
+ *
53
+ * Uses built-in translations based on current locale from next-intl.
54
+ * No need to add translations to app's i18n config.
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * function ChatWidget() {
59
+ * const t = useKnowbaseT();
60
+ * return <h1>{t('chat.title')}</h1>;
61
+ * }
62
+ * ```
63
+ */
64
+ declare function useKnowbaseT(): (key: KnowbaseLocalKeys) => string;
65
+
66
+ declare const en: KnowbaseTranslations;
67
+
68
+ declare const ru: KnowbaseTranslations;
69
+
70
+ declare const ko: KnowbaseTranslations;
58
71
 
59
- export { KNOWBASE_NAMESPACE, type KnowbaseKeys, type KnowbaseLocalKeys, type KnowbaseTranslations, knowbaseI18n, knowbaseTranslations };
72
+ export { type KnowbaseLocalKeys, type KnowbaseTranslations, en, ko, ru, useKnowbaseT };
package/dist/i18n.js CHANGED
@@ -1,5 +1,8 @@
1
- // src/i18n/index.ts
2
- import { createExtensionI18n } from "@djangocfg/ext-base/i18n";
1
+ "use client";
2
+
3
+ // src/i18n/useKnowbaseT.ts
4
+ import { useLocale } from "next-intl";
5
+ import { useMemo, useCallback } from "react";
3
6
 
4
7
  // src/i18n/locales/en.ts
5
8
  var en = {
@@ -103,16 +106,31 @@ var ko = {
103
106
  }
104
107
  };
105
108
 
106
- // src/i18n/index.ts
107
- var KNOWBASE_NAMESPACE = "knowbase";
108
- var knowbaseI18n = createExtensionI18n({
109
- namespace: KNOWBASE_NAMESPACE,
110
- defaultLocale: "en",
111
- locales: { en, ru, ko }
112
- });
113
- var knowbaseTranslations = knowbaseI18n.getAllTranslations();
109
+ // src/i18n/useKnowbaseT.ts
110
+ var translations = { en, ru, ko };
111
+ function getNestedValue(obj, path) {
112
+ const keys = path.split(".");
113
+ let result = obj;
114
+ for (const key of keys) {
115
+ if (result && typeof result === "object" && key in result) {
116
+ result = result[key];
117
+ } else {
118
+ return path;
119
+ }
120
+ }
121
+ return typeof result === "string" ? result : path;
122
+ }
123
+ function useKnowbaseT() {
124
+ const locale = useLocale();
125
+ const t = useMemo(() => translations[locale] || translations.en, [locale]);
126
+ return useCallback(
127
+ (key) => getNestedValue(t, key),
128
+ [t]
129
+ );
130
+ }
114
131
  export {
115
- KNOWBASE_NAMESPACE,
116
- knowbaseI18n,
117
- knowbaseTranslations
132
+ en,
133
+ ko,
134
+ ru,
135
+ useKnowbaseT
118
136
  };
package/dist/index.cjs CHANGED
@@ -4369,7 +4369,7 @@ var apiKnowbase = api.createExtensionAPI(API);
4369
4369
  // package.json
4370
4370
  var package_default = {
4371
4371
  name: "@djangocfg/ext-knowbase",
4372
- version: "1.0.22",
4372
+ version: "1.0.23",
4373
4373
  description: "Knowledge base and chat extension for DjangoCFG",
4374
4374
  keywords: [
4375
4375
  "django",
@@ -4440,14 +4440,15 @@ var package_default = {
4440
4440
  "@djangocfg/ui-nextjs": "workspace:*",
4441
4441
  consola: "^3.4.2",
4442
4442
  "lucide-react": "^0.545.0",
4443
+ moment: "^2.30.1",
4443
4444
  next: "^16",
4445
+ "next-intl": "^4",
4444
4446
  "p-retry": "^7.0.0",
4445
4447
  react: "^19",
4446
4448
  "react-dom": "^19",
4447
4449
  "react-markdown": "^9.0.0 || ^10.0.0",
4448
4450
  swr: "^2.3.7",
4449
- zod: "^4.3.4",
4450
- moment: "^2.30.1"
4451
+ zod: "^4.3.4"
4451
4452
  },
4452
4453
  devDependencies: {
4453
4454
  "@djangocfg/api": "workspace:*",
@@ -4458,6 +4459,7 @@ var package_default = {
4458
4459
  "@types/node": "^24.7.2",
4459
4460
  "@types/react": "^19.0.0",
4460
4461
  consola: "^3.4.2",
4462
+ "next-intl": "^4.1.0",
4461
4463
  "p-retry": "^7.0.0",
4462
4464
  swr: "^2.3.7",
4463
4465
  tsup: "^8.5.0",
package/dist/index.js CHANGED
@@ -4363,7 +4363,7 @@ var apiKnowbase = createExtensionAPI(API);
4363
4363
  // package.json
4364
4364
  var package_default = {
4365
4365
  name: "@djangocfg/ext-knowbase",
4366
- version: "1.0.22",
4366
+ version: "1.0.23",
4367
4367
  description: "Knowledge base and chat extension for DjangoCFG",
4368
4368
  keywords: [
4369
4369
  "django",
@@ -4434,14 +4434,15 @@ var package_default = {
4434
4434
  "@djangocfg/ui-nextjs": "workspace:*",
4435
4435
  consola: "^3.4.2",
4436
4436
  "lucide-react": "^0.545.0",
4437
+ moment: "^2.30.1",
4437
4438
  next: "^16",
4439
+ "next-intl": "^4",
4438
4440
  "p-retry": "^7.0.0",
4439
4441
  react: "^19",
4440
4442
  "react-dom": "^19",
4441
4443
  "react-markdown": "^9.0.0 || ^10.0.0",
4442
4444
  swr: "^2.3.7",
4443
- zod: "^4.3.4",
4444
- moment: "^2.30.1"
4445
+ zod: "^4.3.4"
4445
4446
  },
4446
4447
  devDependencies: {
4447
4448
  "@djangocfg/api": "workspace:*",
@@ -4452,6 +4453,7 @@ var package_default = {
4452
4453
  "@types/node": "^24.7.2",
4453
4454
  "@types/react": "^19.0.0",
4454
4455
  consola: "^3.4.2",
4456
+ "next-intl": "^4.1.0",
4455
4457
  "p-retry": "^7.0.0",
4456
4458
  swr: "^2.3.7",
4457
4459
  tsup: "^8.5.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ext-knowbase",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "description": "Knowledge base and chat extension for DjangoCFG",
5
5
  "keywords": [
6
6
  "django",
@@ -64,31 +64,33 @@
64
64
  "check": "tsc --noEmit"
65
65
  },
66
66
  "peerDependencies": {
67
- "@djangocfg/api": "^2.1.111",
68
- "@djangocfg/ext-base": "^1.0.17",
69
- "@djangocfg/i18n": "^2.1.111",
70
- "@djangocfg/ui-core": "^2.1.111",
71
- "@djangocfg/ui-nextjs": "^2.1.111",
67
+ "@djangocfg/api": "^2.1.124",
68
+ "@djangocfg/ext-base": "^1.0.18",
69
+ "@djangocfg/i18n": "^2.1.124",
70
+ "@djangocfg/ui-core": "^2.1.124",
71
+ "@djangocfg/ui-nextjs": "^2.1.124",
72
72
  "consola": "^3.4.2",
73
73
  "lucide-react": "^0.545.0",
74
+ "moment": "^2.30.1",
74
75
  "next": "^16",
76
+ "next-intl": "^4",
75
77
  "p-retry": "^7.0.0",
76
78
  "react": "^19",
77
79
  "react-dom": "^19",
78
80
  "react-markdown": "^9.0.0 || ^10.0.0",
79
81
  "swr": "^2.3.7",
80
- "zod": "^4.3.4",
81
- "moment": "^2.30.1"
82
+ "zod": "^4.3.4"
82
83
  },
83
84
  "devDependencies": {
84
- "@djangocfg/api": "^2.1.111",
85
- "@djangocfg/ext-base": "^1.0.17",
86
- "@djangocfg/i18n": "^2.1.111",
87
- "@djangocfg/ui-core": "^2.1.111",
88
- "@djangocfg/typescript-config": "^2.1.111",
85
+ "@djangocfg/api": "^2.1.124",
86
+ "@djangocfg/ext-base": "^1.0.18",
87
+ "@djangocfg/i18n": "^2.1.124",
88
+ "@djangocfg/ui-core": "^2.1.124",
89
+ "@djangocfg/typescript-config": "^2.1.124",
89
90
  "@types/node": "^24.7.2",
90
91
  "@types/react": "^19.0.0",
91
92
  "consola": "^3.4.2",
93
+ "next-intl": "^4.1.0",
92
94
  "p-retry": "^7.0.0",
93
95
  "swr": "^2.3.7",
94
96
  "tsup": "^8.5.0",
@@ -10,9 +10,7 @@ import { usePathname } from 'next/navigation';
10
10
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
11
11
  import { createPortal } from 'react-dom';
12
12
 
13
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
14
- import { useT } from '@djangocfg/i18n';
15
- import { KNOWBASE_NAMESPACE, type KnowbaseTranslations } from '../../i18n';
13
+ import { useKnowbaseT } from '../../i18n';
16
14
  import {
17
15
  Button, Card, CardContent, CardHeader,
18
16
  } from '@djangocfg/ui-nextjs';
@@ -40,8 +38,7 @@ export const ChatWidget: React.FC<ChatWidgetProps> = ({
40
38
  onToggle,
41
39
  onMessage,
42
40
  }) => {
43
- const baseT = useT();
44
- const kt = createTypedExtensionT<typeof KNOWBASE_NAMESPACE, KnowbaseTranslations>(baseT, KNOWBASE_NAMESPACE);
41
+ const kt = useKnowbaseT();
45
42
  const { sendQuery, getChatHistory } = useKnowbaseChatContext();
46
43
  const { createSession, getSession } = useKnowbaseSessionsContext();
47
44
  const {
@@ -8,9 +8,7 @@
8
8
  import { Loader2, Send } from 'lucide-react';
9
9
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
10
10
 
11
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
12
- import { useT } from '@djangocfg/i18n';
13
- import { KNOWBASE_NAMESPACE, type KnowbaseTranslations } from '../../../i18n';
11
+ import { useKnowbaseT } from '../../../i18n';
14
12
  import { Button, Textarea } from '@djangocfg/ui-nextjs';
15
13
 
16
14
  import { chatLogger } from '../../../utils/logger';
@@ -28,8 +26,7 @@ export const MessageInput: React.FC<MessageInputProps> = ({
28
26
  placeholder,
29
27
  className = '',
30
28
  }) => {
31
- const baseT = useT();
32
- const kt = createTypedExtensionT<typeof KNOWBASE_NAMESPACE, KnowbaseTranslations>(baseT, KNOWBASE_NAMESPACE);
29
+ const kt = useKnowbaseT();
33
30
  const [message, setMessage] = useState('');
34
31
  const [rows, setRows] = useState(1);
35
32
  const textareaRef = useRef<HTMLTextAreaElement>(null);
@@ -10,9 +10,7 @@ import moment from 'moment';
10
10
  import React, { useEffect, useMemo, useRef } from 'react';
11
11
 
12
12
  import { useAuth } from '@djangocfg/api/auth';
13
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
14
- import { useT } from '@djangocfg/i18n';
15
- import { KNOWBASE_NAMESPACE, type KnowbaseTranslations } from '../../../i18n';
13
+ import { useKnowbaseT } from '../../../i18n';
16
14
  import {
17
15
  Avatar, AvatarFallback, AvatarImage, Badge, Card, CardContent, ScrollArea
18
16
  } from '@djangocfg/ui-nextjs';
@@ -32,8 +30,7 @@ export const MessageList: React.FC<MessageListProps> = ({
32
30
  autoScroll = true,
33
31
  className = '',
34
32
  }) => {
35
- const baseT = useT();
36
- const kt = createTypedExtensionT<typeof KNOWBASE_NAMESPACE, KnowbaseTranslations>(baseT, KNOWBASE_NAMESPACE);
33
+ const kt = useKnowbaseT();
37
34
  const scrollRef = useRef<HTMLDivElement>(null);
38
35
  const { user } = useAuth();
39
36
 
@@ -9,9 +9,7 @@ import { Archive, Clock, Loader2, MessageSquare, Trash2 } from 'lucide-react';
9
9
  import moment from 'moment';
10
10
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
11
11
 
12
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
13
- import { useT } from '@djangocfg/i18n';
14
- import { KNOWBASE_NAMESPACE, type KnowbaseTranslations } from '../../../i18n';
12
+ import { useKnowbaseT } from '../../../i18n';
15
13
  import {
16
14
  Badge, Button, ScrollArea, Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle
17
15
  } from '@djangocfg/ui-nextjs';
@@ -31,8 +29,7 @@ export const SessionList: React.FC<SessionListProps> = ({
31
29
  onSelectSession,
32
30
  className = '',
33
31
  }) => {
34
- const baseT = useT();
35
- const kt = createTypedExtensionT<typeof KNOWBASE_NAMESPACE, KnowbaseTranslations>(baseT, KNOWBASE_NAMESPACE);
32
+ const kt = useKnowbaseT();
36
33
  const { deleteSession, archiveSession } = useKnowbaseSessionsContext();
37
34
  const {
38
35
  sessions,
package/src/i18n/index.ts CHANGED
@@ -1,23 +1,26 @@
1
1
  /**
2
2
  * Knowbase Extension I18n
3
+ *
4
+ * Self-contained translations - no app configuration needed.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { useKnowbaseT } from '@djangocfg/ext-knowbase/i18n';
9
+ *
10
+ * function MyComponent() {
11
+ * const t = useKnowbaseT();
12
+ * return <span>{t('chat.title')}</span>;
13
+ * }
14
+ * ```
3
15
  */
4
16
 
5
- import { createExtensionI18n } from '@djangocfg/ext-base/i18n';
6
- import type { KnowbaseTranslations } from './types';
7
- import { en } from './locales/en';
8
- import { ru } from './locales/ru';
9
- import { ko } from './locales/ko';
10
-
11
- /** Knowbase extension namespace */
12
- export const KNOWBASE_NAMESPACE = 'knowbase' as const;
13
-
14
- export const knowbaseI18n = createExtensionI18n<KnowbaseTranslations>({
15
- namespace: KNOWBASE_NAMESPACE,
16
- defaultLocale: 'en',
17
- locales: { en, ru, ko },
18
- });
19
-
20
- export const knowbaseTranslations = knowbaseI18n.getAllTranslations();
17
+ // Self-contained hook (recommended)
18
+ export { useKnowbaseT } from './useKnowbaseT';
21
19
 
22
20
  // Types
23
- export type { KnowbaseTranslations, KnowbaseKeys, KnowbaseLocalKeys } from './types';
21
+ export type { KnowbaseTranslations, KnowbaseLocalKeys } from './types';
22
+
23
+ // Locales (for direct access if needed)
24
+ export { en } from './locales/en';
25
+ export { ru } from './locales/ru';
26
+ export { ko } from './locales/ko';
package/src/i18n/types.ts CHANGED
@@ -2,15 +2,21 @@
2
2
  * Knowbase Extension I18n Types
3
3
  */
4
4
 
5
- import type { ExtensionKeys, PathKeys } from '@djangocfg/ext-base/i18n';
6
-
7
5
  /**
8
- * All valid keys for knowbase translations (with namespace)
6
+ * Helper type to get dot-notation paths from nested object
9
7
  */
10
- export type KnowbaseKeys = ExtensionKeys<'knowbase', KnowbaseTranslations>;
8
+ type PathKeys<T, Prefix extends string = ''> = T extends object
9
+ ? {
10
+ [K in keyof T]: K extends string
11
+ ? T[K] extends object
12
+ ? PathKeys<T[K], `${Prefix}${K}.`>
13
+ : `${Prefix}${K}`
14
+ : never;
15
+ }[keyof T]
16
+ : never;
11
17
 
12
18
  /**
13
- * Keys without namespace prefix (for createTypedExtensionT)
19
+ * Keys for knowbase translations
14
20
  */
15
21
  export type KnowbaseLocalKeys = PathKeys<KnowbaseTranslations>;
16
22
 
@@ -0,0 +1,60 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Self-contained translation hook for ext-knowbase
5
+ *
6
+ * Uses built-in translations, no app configuration needed.
7
+ */
8
+
9
+ import { useLocale } from 'next-intl';
10
+ import { useMemo, useCallback } from 'react';
11
+
12
+ import type { KnowbaseTranslations, KnowbaseLocalKeys } from './types';
13
+ import { en } from './locales/en';
14
+ import { ru } from './locales/ru';
15
+ import { ko } from './locales/ko';
16
+
17
+ const translations: Record<string, KnowbaseTranslations> = { en, ru, ko };
18
+
19
+ /**
20
+ * Get nested value from object by dot-notation path
21
+ */
22
+ function getNestedValue(obj: Record<string, unknown>, path: string): string {
23
+ const keys = path.split('.');
24
+ let result: unknown = obj;
25
+
26
+ for (const key of keys) {
27
+ if (result && typeof result === 'object' && key in result) {
28
+ result = (result as Record<string, unknown>)[key];
29
+ } else {
30
+ return path; // Return key if not found
31
+ }
32
+ }
33
+
34
+ return typeof result === 'string' ? result : path;
35
+ }
36
+
37
+ /**
38
+ * Self-contained translation hook for knowbase extension
39
+ *
40
+ * Uses built-in translations based on current locale from next-intl.
41
+ * No need to add translations to app's i18n config.
42
+ *
43
+ * @example
44
+ * ```tsx
45
+ * function ChatWidget() {
46
+ * const t = useKnowbaseT();
47
+ * return <h1>{t('chat.title')}</h1>;
48
+ * }
49
+ * ```
50
+ */
51
+ export function useKnowbaseT(): (key: KnowbaseLocalKeys) => string {
52
+ const locale = useLocale();
53
+
54
+ const t = useMemo(() => translations[locale] || translations.en, [locale]);
55
+
56
+ return useCallback(
57
+ (key: KnowbaseLocalKeys): string => getNestedValue(t as unknown as Record<string, unknown>, key),
58
+ [t]
59
+ );
60
+ }