zudoku 0.21.14 → 0.22.0
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/loader.js +3 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/lib/components/Markdown.js +1 -1
- package/dist/lib/components/Markdown.js.map +1 -1
- package/dist/lib/components/ReactMarkdown.d.ts +29 -0
- package/dist/lib/components/ReactMarkdown.js +182 -0
- package/dist/lib/components/ReactMarkdown.js.map +1 -0
- package/dist/lib/plugins/search-inkeep/index.d.ts +22 -3
- package/dist/lib/plugins/search-inkeep/index.js +27 -5
- package/dist/lib/plugins/search-inkeep/index.js.map +1 -1
- package/dist/lib/plugins/search-inkeep/inkeep.d.ts +3 -4
- package/dist/lib/plugins/search-inkeep/inkeep.js.map +1 -1
- package/lib/{Markdown-CdkU5HcM.js → Markdown-CRsmPPfY.js} +13083 -13095
- package/lib/Markdown-CRsmPPfY.js.map +1 -0
- package/lib/{MdxPage-ChziqNPp.js → MdxPage-Wp8QU0-q.js} +2 -2
- package/lib/{MdxPage-ChziqNPp.js.map → MdxPage-Wp8QU0-q.js.map} +1 -1
- package/lib/{OperationList-CQKkyrZH.js → OperationList-u8xHU9-b.js} +3 -3
- package/lib/{OperationList-CQKkyrZH.js.map → OperationList-u8xHU9-b.js.map} +1 -1
- package/lib/{SlotletProvider-D77pO-fA.js → SlotletProvider-BgvYIPQe.js} +2 -2
- package/lib/{SlotletProvider-D77pO-fA.js.map → SlotletProvider-BgvYIPQe.js.map} +1 -1
- package/lib/{index-DjB6H4GT.js → index-CmdLGbbk.js} +2 -2
- package/lib/{index-DjB6H4GT.js.map → index-CmdLGbbk.js.map} +1 -1
- package/lib/zudoku.components.js +2 -2
- package/lib/zudoku.plugin-api-catalog.js +1 -1
- package/lib/zudoku.plugin-api-keys.js +1 -1
- package/lib/zudoku.plugin-custom-pages.js +1 -1
- package/lib/zudoku.plugin-markdown.js +1 -1
- package/lib/zudoku.plugin-openapi.js +1 -1
- package/lib/zudoku.plugin-search-inkeep.js +44 -23
- package/lib/zudoku.plugin-search-inkeep.js.map +1 -1
- package/package.json +9 -3
- package/src/lib/components/Markdown.tsx +1 -1
- package/src/lib/components/ReactMarkdown.license.txt +21 -0
- package/src/lib/components/ReactMarkdown.tsx +264 -0
- package/src/lib/plugins/search-inkeep/index.tsx +59 -23
- package/src/lib/plugins/search-inkeep/inkeep.ts +3 -9
- package/dist/lib/plugins/search-inkeep/InkeepCustomTrigger.d.ts +0 -2
- package/dist/lib/plugins/search-inkeep/InkeepCustomTrigger.js +0 -3
- package/dist/lib/plugins/search-inkeep/InkeepCustomTrigger.js.map +0 -1
- package/lib/InkeepCustomTrigger-CE5-K5ex.js +0 -6
- package/lib/InkeepCustomTrigger-CE5-K5ex.js.map +0 -1
- package/lib/Markdown-CdkU5HcM.js.map +0 -1
- package/src/lib/plugins/search-inkeep/InkeepCustomTrigger.tsx +0 -3
package/lib/zudoku.components.js
CHANGED
|
@@ -16,7 +16,7 @@ var J = (e, t, r, s) => ({
|
|
|
16
16
|
import { a as He, H as me } from "./index.esm-Bm8pj-bc.js";
|
|
17
17
|
import { d as jt, R as wt, N as ae, u as St, L as ge } from "./index-Yn8c3UWE.js";
|
|
18
18
|
import { u as Nt } from "./state-tsXBLONe.js";
|
|
19
|
-
import { E as Ue, S as O, a as Et, R as Ct } from "./SlotletProvider-
|
|
19
|
+
import { E as Ue, S as O, a as Et, R as Ct } from "./SlotletProvider-BgvYIPQe.js";
|
|
20
20
|
import { j as a } from "./jsx-runtime-B6kdoens.js";
|
|
21
21
|
import { Button as Pt } from "./ui/Button.js";
|
|
22
22
|
import { Callout as kt } from "./ui/Callout.js";
|
|
@@ -32,7 +32,7 @@ import { C as je } from "./ClientOnly-E7hGysn1.js";
|
|
|
32
32
|
import { ChevronRightIcon as Xt, ExternalLinkIcon as Jt, CircleXIcon as Gt, SearchIcon as er, MoonStarIcon as tr, SunIcon as rr, MenuIcon as ar, PanelLeftIcon as sr } from "lucide-react";
|
|
33
33
|
import { Drawer as et, DrawerTrigger as tt, DrawerContent as rt, DrawerTitle as at } from "./ui/Drawer.js";
|
|
34
34
|
import { c as R } from "./cn-BmFQLtkS.js";
|
|
35
|
-
import { u as we, a as nr, V as ir } from "./Markdown-
|
|
35
|
+
import { u as we, a as nr, V as ir } from "./Markdown-CRsmPPfY.js";
|
|
36
36
|
import { c as or, a as lr } from "./index-BuAyrJe3.js";
|
|
37
37
|
import { A as cr, M as ur, u as dr } from "./AnchorLink-BR0MvI7n.js";
|
|
38
38
|
import * as oe from "@radix-ui/react-collapsible";
|
|
@@ -2,7 +2,7 @@ import { j as e } from "./jsx-runtime-B6kdoens.js";
|
|
|
2
2
|
import { s as n } from "./index-LNp6rxyU.js";
|
|
3
3
|
import { Fragment as x } from "react";
|
|
4
4
|
import { Head as f, Link as h } from "./zudoku.components.js";
|
|
5
|
-
import { M as u } from "./Markdown-
|
|
5
|
+
import { M as u } from "./Markdown-CRsmPPfY.js";
|
|
6
6
|
import { u as j } from "./useExposedProps-CTPtylCV.js";
|
|
7
7
|
const b = ({
|
|
8
8
|
items: l,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as e } from "./jsx-runtime-B6kdoens.js";
|
|
2
2
|
import { RotateCwIcon as g, TrashIcon as f, EyeOffIcon as j, EyeIcon as v, CheckIcon as w, CopyIcon as b, FileKey2Icon as K } from "lucide-react";
|
|
3
|
-
import { D as k, S as m, R as N } from "./SlotletProvider-
|
|
3
|
+
import { D as k, S as m, R as N } from "./SlotletProvider-BgvYIPQe.js";
|
|
4
4
|
import { i as c } from "./invariant-Caa8-XvF.js";
|
|
5
5
|
import { u as d, S as I, a as S, b as A, c as C, d as E, e as x } from "./Select-O9ZM3ZgX.js";
|
|
6
6
|
import { a as P } from "./index.esm-C5mr_sKO.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { j as o } from "./jsx-runtime-B6kdoens.js";
|
|
2
2
|
import a from "react";
|
|
3
|
-
import { P as n } from "./Markdown-
|
|
3
|
+
import { P as n } from "./Markdown-CRsmPPfY.js";
|
|
4
4
|
import { c } from "./cn-BmFQLtkS.js";
|
|
5
5
|
import { u as p } from "./useExposedProps-CTPtylCV.js";
|
|
6
6
|
const u = ({
|
|
@@ -74,7 +74,7 @@ const C = (n) => ({
|
|
|
74
74
|
const h = {
|
|
75
75
|
path: r,
|
|
76
76
|
lazy: async () => {
|
|
77
|
-
const { MdxPage: l } = await import("./MdxPage-
|
|
77
|
+
const { MdxPage: l } = await import("./MdxPage-Wp8QU0-q.js"), { default: p, ...g } = await a();
|
|
78
78
|
return {
|
|
79
79
|
element: /* @__PURE__ */ P.jsx(
|
|
80
80
|
l,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { j as n } from "./jsx-runtime-B6kdoens.js";
|
|
2
|
-
import {
|
|
3
|
-
import { C as
|
|
4
|
-
const
|
|
2
|
+
import { useRef as a, useMemo as p, useEffect as c } from "react";
|
|
3
|
+
import { C as u } from "./ClientOnly-E7hGysn1.js";
|
|
4
|
+
const d = {
|
|
5
5
|
theme: {
|
|
6
6
|
components: {
|
|
7
7
|
AIChatPageWrapper: {
|
|
@@ -19,29 +19,50 @@ const o = {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
},
|
|
23
|
-
prefilledQuery:
|
|
24
|
-
isOpen:
|
|
25
|
-
onClose:
|
|
26
|
-
settings:
|
|
27
|
-
}) =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
}, m = {}, g = ({
|
|
23
|
+
prefilledQuery: t,
|
|
24
|
+
isOpen: e,
|
|
25
|
+
onClose: r,
|
|
26
|
+
settings: i
|
|
27
|
+
}) => {
|
|
28
|
+
const s = a(null), o = p(
|
|
29
|
+
() => ({
|
|
30
|
+
componentType: "CustomTrigger",
|
|
31
|
+
targetElement: s.current,
|
|
32
|
+
properties: {
|
|
33
|
+
isOpen: e,
|
|
34
|
+
onClose: r,
|
|
35
|
+
onOpen: void 0,
|
|
36
|
+
baseSettings: { ...d, ...i },
|
|
37
|
+
searchSettings: {
|
|
38
|
+
prefilledQuery: t || void 0
|
|
39
|
+
},
|
|
40
|
+
aiChatSettings: m
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
[e, r, t, i, s]
|
|
44
|
+
);
|
|
45
|
+
return c(() => {
|
|
46
|
+
Inkeep().embed(o).render({
|
|
47
|
+
...o,
|
|
48
|
+
isOpen: e
|
|
49
|
+
});
|
|
50
|
+
}), /* @__PURE__ */ n.jsx("div", { ref: s });
|
|
51
|
+
}, j = (t) => ({
|
|
52
|
+
getHead: () => /* @__PURE__ */ n.jsx(
|
|
53
|
+
"script",
|
|
54
|
+
{
|
|
55
|
+
type: "module",
|
|
56
|
+
src: "https://unpkg.com/@inkeep/uikit-js@0.3.19/dist/embed.js",
|
|
57
|
+
defer: !0
|
|
36
58
|
}
|
|
37
|
-
|
|
38
|
-
), d = (e) => ({
|
|
59
|
+
),
|
|
39
60
|
renderSearch: ({
|
|
40
|
-
isOpen:
|
|
41
|
-
onClose:
|
|
42
|
-
}) => /* @__PURE__ */ n.jsx(
|
|
61
|
+
isOpen: e,
|
|
62
|
+
onClose: r
|
|
63
|
+
}) => /* @__PURE__ */ n.jsx(u, { children: /* @__PURE__ */ n.jsx(g, { isOpen: e, onClose: r, settings: t }) })
|
|
43
64
|
});
|
|
44
65
|
export {
|
|
45
|
-
|
|
66
|
+
j as inkeepSearchPlugin
|
|
46
67
|
};
|
|
47
68
|
//# sourceMappingURL=zudoku.plugin-search-inkeep.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugin-search-inkeep.js","sources":["../src/lib/plugins/search-inkeep/inkeep.ts","../src/lib/plugins/search-inkeep/index.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"zudoku.plugin-search-inkeep.js","sources":["../src/lib/plugins/search-inkeep/inkeep.ts","../src/lib/plugins/search-inkeep/index.tsx"],"sourcesContent":["const baseSettings = {\n theme: {\n components: {\n AIChatPageWrapper: {\n defaultProps: {\n size: \"shrink-vertically\",\n variant: \"no-shadow\",\n },\n },\n SearchBarTrigger: {\n defaultProps: {\n size: \"expand\",\n variant: \"subtle\", // Choose from 'emphasized' or 'subtle'\n },\n },\n },\n },\n} as const;\n\nconst modalSettings = {};\n\nconst searchSettings = {};\n\nconst aiChatSettings = {};\n\nexport { aiChatSettings, baseSettings, modalSettings, searchSettings };\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { ClientOnly } from \"../../components/ClientOnly.js\";\nimport type { ZudokuPlugin } from \"../../core/plugins.js\";\nimport { aiChatSettings, baseSettings } from \"./inkeep.js\";\n\ninterface PluginInkeepBaseSettings {\n apiKey?: string;\n integrationId: string;\n organizationId: string;\n organizationDisplayName?: string;\n primaryBrandColor: string;\n}\n\ninterface InkeepEmbedConfig {\n componentType: string;\n targetElement: HTMLElement;\n properties: unknown;\n}\n\ninterface InkeepWidget {\n render: (config: InkeepEmbedConfig & { isOpen: boolean }) => void;\n}\n\ndeclare global {\n let Inkeep: () => {\n embed: (config: InkeepEmbedConfig) => InkeepWidget;\n };\n}\n\nconst InkeepSearch = ({\n prefilledQuery,\n isOpen,\n onClose,\n settings,\n}: {\n isOpen: boolean;\n onClose: () => void;\n prefilledQuery?: string | null;\n settings: PluginInkeepBaseSettings;\n}) => {\n const ref = useRef<HTMLDivElement>(null);\n\n const config: InkeepEmbedConfig = useMemo(\n () => ({\n componentType: \"CustomTrigger\",\n targetElement: ref.current!,\n properties: {\n isOpen,\n onClose,\n onOpen: undefined,\n baseSettings: { ...baseSettings, ...settings },\n searchSettings: {\n prefilledQuery: prefilledQuery || undefined,\n },\n aiChatSettings,\n },\n }),\n [isOpen, onClose, prefilledQuery, settings, ref],\n );\n\n useEffect(() => {\n const inkeepWidget = Inkeep().embed(config);\n inkeepWidget.render({\n ...config,\n isOpen,\n });\n });\n\n return <div ref={ref} />;\n};\n\nexport const inkeepSearchPlugin = (\n settings: PluginInkeepBaseSettings,\n): ZudokuPlugin => {\n return {\n getHead: () => {\n return (\n <script\n type=\"module\"\n src=\"https://unpkg.com/@inkeep/uikit-js@0.3.19/dist/embed.js\"\n defer\n ></script>\n );\n },\n renderSearch: ({\n isOpen,\n onClose,\n }: {\n isOpen: boolean;\n onClose: () => void;\n }) => {\n return (\n <ClientOnly>\n <InkeepSearch isOpen={isOpen} onClose={onClose} settings={settings} />\n </ClientOnly>\n );\n },\n };\n};\n"],"names":["baseSettings","aiChatSettings","InkeepSearch","prefilledQuery","isOpen","onClose","settings","ref","useRef","config","useMemo","useEffect","jsx","inkeepSearchPlugin","ClientOnly"],"mappings":";;;AAAA,MAAMA,IAAe;AAAA,EACnB,OAAO;AAAA,IACL,YAAY;AAAA,MACV,mBAAmB;AAAA,QACjB,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA,kBAAkB;AAAA,QAChB,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,SAAS;AAAA;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,GAMMC,IAAiB,CAAC,GCMlBC,IAAe,CAAC;AAAA,EACpB,gBAAAC;AAAA,EACA,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AACF,MAKM;AACE,QAAAC,IAAMC,EAAuB,IAAI,GAEjCC,IAA4BC;AAAA,IAChC,OAAO;AAAA,MACL,eAAe;AAAA,MACf,eAAeH,EAAI;AAAA,MACnB,YAAY;AAAA,QACV,QAAAH;AAAA,QACA,SAAAC;AAAA,QACA,QAAQ;AAAA,QACR,cAAc,EAAE,GAAGL,GAAc,GAAGM,EAAS;AAAA,QAC7C,gBAAgB;AAAA,UACd,gBAAgBH,KAAkB;AAAA,QACpC;AAAA,QACA,gBAAAF;AAAA,MACF;AAAA,IAAA;AAAA,IAEF,CAACG,GAAQC,GAASF,GAAgBG,GAAUC,CAAG;AAAA,EAAA;AAGjD,SAAAI,EAAU,MAAM;AAEd,IADqB,OAAA,EAAS,MAAMF,CAAM,EAC7B,OAAO;AAAA,MAClB,GAAGA;AAAA,MACH,QAAAL;AAAA,IAAA,CACD;AAAA,EAAA,CACF,GAEMQ,gBAAAA,MAAC,SAAI,KAAAL,EAAU,CAAA;AACxB,GAEaM,IAAqB,CAChCP,OAEO;AAAA,EACL,SAAS,MAELM,gBAAAA,EAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,KAAI;AAAA,MACJ,OAAK;AAAA,IAAA;AAAA,EAAA;AAAA,EAIX,cAAc,CAAC;AAAA,IACb,QAAAR;AAAA,IACA,SAAAC;AAAA,EAAA,4BAMGS,GACC,EAAA,UAAAF,gBAAAA,EAAAA,IAACV,KAAa,QAAAE,GAAgB,SAAAC,GAAkB,UAAAC,EAAoB,CAAA,EACtE,CAAA;AAEJ;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zudoku",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"homepage": "https://zudoku.dev",
|
|
6
6
|
"repository": {
|
|
@@ -160,6 +160,7 @@
|
|
|
160
160
|
"class-variance-authority": "0.7.0",
|
|
161
161
|
"clsx": "2.1.1",
|
|
162
162
|
"cmdk": "1.0.4",
|
|
163
|
+
"devlop": "^1.1.0",
|
|
163
164
|
"embla-carousel-react": "8.3.1",
|
|
164
165
|
"estree-util-value-to-estree": "3.2.1",
|
|
165
166
|
"express": "4.21.1",
|
|
@@ -168,7 +169,9 @@
|
|
|
168
169
|
"graphql-type-json": "0.3.2",
|
|
169
170
|
"graphql-yoga": "5.7.0",
|
|
170
171
|
"gray-matter": "4.0.3",
|
|
172
|
+
"hast-util-to-jsx-runtime": "^2.3.2",
|
|
171
173
|
"hast-util-to-string": "3.0.1",
|
|
174
|
+
"html-url-attributes": "^3.0.1",
|
|
172
175
|
"http-terminator": "3.2.0",
|
|
173
176
|
"loglevel": "1.9.2",
|
|
174
177
|
"lru-cache": "11.0.1",
|
|
@@ -185,7 +188,6 @@
|
|
|
185
188
|
"react-error-boundary": "4.1.2",
|
|
186
189
|
"react-hook-form": "7.53.0",
|
|
187
190
|
"react-is": "18.3.1",
|
|
188
|
-
"react-markdown": "9.0.1",
|
|
189
191
|
"react-router-dom": "6.27.0",
|
|
190
192
|
"rehype-raw": "7.0.0",
|
|
191
193
|
"rehype-slug": "6.0.0",
|
|
@@ -195,6 +197,8 @@
|
|
|
195
197
|
"remark-frontmatter": "5.0.0",
|
|
196
198
|
"remark-gfm": "4.0.0",
|
|
197
199
|
"remark-mdx-frontmatter": "5.0.0",
|
|
200
|
+
"remark-parse": "^11.0.0",
|
|
201
|
+
"remark-rehype": "^11.1.1",
|
|
198
202
|
"rollup": "4.24.0",
|
|
199
203
|
"semver": "7.6.3",
|
|
200
204
|
"sitemap": "8.0.0",
|
|
@@ -204,6 +208,7 @@
|
|
|
204
208
|
"tailwindcss": "3.4.13",
|
|
205
209
|
"tsx": "^4.19.2",
|
|
206
210
|
"ulidx": "2.4.1",
|
|
211
|
+
"unified": "^11.0.5",
|
|
207
212
|
"unist-util-visit": "5.0.0",
|
|
208
213
|
"urql": "4.1.0",
|
|
209
214
|
"vaul": "1.1.1",
|
|
@@ -221,6 +226,7 @@
|
|
|
221
226
|
"@types/estree": "1.0.6",
|
|
222
227
|
"@types/express": "5.0.0",
|
|
223
228
|
"@types/har-format": "1.2.15",
|
|
229
|
+
"@types/hast": "^3.0.4",
|
|
224
230
|
"@types/json-schema": "7.0.15",
|
|
225
231
|
"@types/mdast": "4.0.4",
|
|
226
232
|
"@types/mdx": "2.0.13",
|
|
@@ -228,6 +234,7 @@
|
|
|
228
234
|
"@types/object-hash": "3.0.6",
|
|
229
235
|
"@types/react-is": "18.3.0",
|
|
230
236
|
"@types/semver": "7.5.8",
|
|
237
|
+
"@types/unist": "^3.0.3",
|
|
231
238
|
"@types/yargs": "17.0.33",
|
|
232
239
|
"@vitest/coverage-v8": "2.1.8",
|
|
233
240
|
"mdast-util-mdx": "3.0.0",
|
|
@@ -243,7 +250,6 @@
|
|
|
243
250
|
},
|
|
244
251
|
"optionalDependencies": {
|
|
245
252
|
"@clerk/clerk-js": "5.11.0",
|
|
246
|
-
"@inkeep/widgets": "^0.2.289",
|
|
247
253
|
"@sentry/react": "^8.45.1"
|
|
248
254
|
},
|
|
249
255
|
"scripts": {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import ReactMarkdown from "react-markdown";
|
|
2
1
|
import rehypeRaw from "rehype-raw";
|
|
3
2
|
import remarkGfm from "remark-gfm";
|
|
4
3
|
import { visit } from "unist-util-visit";
|
|
5
4
|
import { MdxComponents } from "../util/MdxComponents.js";
|
|
5
|
+
import { ReactMarkdown } from "./ReactMarkdown.js";
|
|
6
6
|
|
|
7
7
|
// same as in packages/dev-portal/framework/vite.ts
|
|
8
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) Espen Hovlandsdal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This is a fork of `react-markdown` converted to typescript.
|
|
6
|
+
* The reason we fork it is because react-markdown is comptaible with
|
|
7
|
+
* unified 11, but references the unified 10 and related packages causing
|
|
8
|
+
* type errors and a bunch of extra imports
|
|
9
|
+
*
|
|
10
|
+
* Source: https://github.com/remarkjs/react-markdown/blob/main/index.js
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { unreachable } from "devlop";
|
|
14
|
+
import type { Element, ElementContent, Nodes, Parents } from "hast";
|
|
15
|
+
import {
|
|
16
|
+
Components as JsxRuntimeComponents,
|
|
17
|
+
toJsxRuntime,
|
|
18
|
+
} from "hast-util-to-jsx-runtime";
|
|
19
|
+
import { urlAttributes } from "html-url-attributes";
|
|
20
|
+
import { ReactElement } from "react";
|
|
21
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
22
|
+
import remarkParse from "remark-parse";
|
|
23
|
+
import remarkRehype, { Options as RemarkRehypeOptions } from "remark-rehype";
|
|
24
|
+
import { PluggableList, unified } from "unified";
|
|
25
|
+
import { visit } from "unist-util-visit";
|
|
26
|
+
import { VFile } from "vfile";
|
|
27
|
+
|
|
28
|
+
const changelog =
|
|
29
|
+
"https://github.com/remarkjs/react-markdown/blob/main/changelog.md";
|
|
30
|
+
|
|
31
|
+
const emptyPlugins: PluggableList = [];
|
|
32
|
+
const emptyRemarkRehypeOptions: Readonly<RemarkRehypeOptions> = {
|
|
33
|
+
allowDangerousHtml: true,
|
|
34
|
+
};
|
|
35
|
+
const safeProtocol = /^(https?|ircs?|mailto|xmpp)$/i;
|
|
36
|
+
|
|
37
|
+
interface Deprecation {
|
|
38
|
+
from: string;
|
|
39
|
+
id: string;
|
|
40
|
+
to?: keyof Options;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface AllowElement {
|
|
44
|
+
(
|
|
45
|
+
element: Readonly<Element>,
|
|
46
|
+
index: number,
|
|
47
|
+
parent: Readonly<Parents> | undefined,
|
|
48
|
+
): boolean | null | undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface UrlTransform {
|
|
52
|
+
(
|
|
53
|
+
url: string,
|
|
54
|
+
key: string,
|
|
55
|
+
node: Readonly<Element>,
|
|
56
|
+
): string | null | undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
60
|
+
interface Components extends Partial<JsxRuntimeComponents> {}
|
|
61
|
+
|
|
62
|
+
interface Options {
|
|
63
|
+
allowElement?: AllowElement | null;
|
|
64
|
+
allowedElements?: ReadonlyArray<string> | null;
|
|
65
|
+
children?: string | null;
|
|
66
|
+
className?: string | null;
|
|
67
|
+
components?: Components | null;
|
|
68
|
+
disallowedElements?: ReadonlyArray<string> | null;
|
|
69
|
+
rehypePlugins?: PluggableList | null;
|
|
70
|
+
remarkPlugins?: PluggableList | null;
|
|
71
|
+
remarkRehypeOptions?: Readonly<RemarkRehypeOptions> | null;
|
|
72
|
+
skipHtml?: boolean | null;
|
|
73
|
+
unwrapDisallowed?: boolean | null;
|
|
74
|
+
urlTransform?: UrlTransform | null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const deprecations: ReadonlyArray<Readonly<Deprecation>> = [
|
|
78
|
+
{ from: "astPlugins", id: "remove-buggy-html-in-markdown-parser" },
|
|
79
|
+
{ from: "allowDangerousHtml", id: "remove-buggy-html-in-markdown-parser" },
|
|
80
|
+
{
|
|
81
|
+
from: "allowNode",
|
|
82
|
+
id: "replace-allownode-allowedtypes-and-disallowedtypes",
|
|
83
|
+
to: "allowElement",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
from: "allowedTypes",
|
|
87
|
+
id: "replace-allownode-allowedtypes-and-disallowedtypes",
|
|
88
|
+
to: "allowedElements",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
from: "disallowedTypes",
|
|
92
|
+
id: "replace-allownode-allowedtypes-and-disallowedtypes",
|
|
93
|
+
to: "disallowedElements",
|
|
94
|
+
},
|
|
95
|
+
{ from: "escapeHtml", id: "remove-buggy-html-in-markdown-parser" },
|
|
96
|
+
{ from: "includeElementIndex", id: "#remove-includeelementindex" },
|
|
97
|
+
{
|
|
98
|
+
from: "includeNodeIndex",
|
|
99
|
+
id: "change-includenodeindex-to-includeelementindex",
|
|
100
|
+
},
|
|
101
|
+
{ from: "linkTarget", id: "remove-linktarget" },
|
|
102
|
+
{
|
|
103
|
+
from: "plugins",
|
|
104
|
+
id: "change-plugins-to-remarkplugins",
|
|
105
|
+
to: "remarkPlugins",
|
|
106
|
+
},
|
|
107
|
+
{ from: "rawSourcePos", id: "#remove-rawsourcepos" },
|
|
108
|
+
{ from: "renderers", id: "change-renderers-to-components", to: "components" },
|
|
109
|
+
{ from: "source", id: "change-source-to-children", to: "children" },
|
|
110
|
+
{ from: "sourcePos", id: "#remove-sourcepos" },
|
|
111
|
+
{ from: "transformImageUri", id: "#add-urltransform", to: "urlTransform" },
|
|
112
|
+
{ from: "transformLinkUri", id: "#add-urltransform", to: "urlTransform" },
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
export function ReactMarkdown(options: Readonly<Options>): ReactElement {
|
|
116
|
+
const allowedElements = options.allowedElements;
|
|
117
|
+
const allowElement = options.allowElement;
|
|
118
|
+
const children = options.children || "";
|
|
119
|
+
const className = options.className;
|
|
120
|
+
const components = options.components;
|
|
121
|
+
const disallowedElements = options.disallowedElements;
|
|
122
|
+
const rehypePlugins = options.rehypePlugins || emptyPlugins;
|
|
123
|
+
const remarkPlugins = options.remarkPlugins || emptyPlugins;
|
|
124
|
+
const remarkRehypeOptions = options.remarkRehypeOptions
|
|
125
|
+
? { ...options.remarkRehypeOptions, ...emptyRemarkRehypeOptions }
|
|
126
|
+
: emptyRemarkRehypeOptions;
|
|
127
|
+
const skipHtml = options.skipHtml;
|
|
128
|
+
const unwrapDisallowed = options.unwrapDisallowed;
|
|
129
|
+
const urlTransform = options.urlTransform || defaultUrlTransform;
|
|
130
|
+
|
|
131
|
+
const processor = unified()
|
|
132
|
+
.use(remarkParse)
|
|
133
|
+
.use(remarkPlugins)
|
|
134
|
+
.use(remarkRehype, remarkRehypeOptions)
|
|
135
|
+
.use(rehypePlugins);
|
|
136
|
+
|
|
137
|
+
const file = new VFile();
|
|
138
|
+
|
|
139
|
+
if (typeof children === "string") {
|
|
140
|
+
file.value = children;
|
|
141
|
+
} else {
|
|
142
|
+
unreachable(
|
|
143
|
+
`Unexpected value '${children}' for 'children' prop, expected 'string'`,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (allowedElements && disallowedElements) {
|
|
148
|
+
unreachable(
|
|
149
|
+
"Unexpected combined `allowedElements` and `disallowedElements`, expected one or the other",
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
for (const deprecation of deprecations) {
|
|
154
|
+
if (Object.prototype.hasOwnProperty.call(options, deprecation.from)) {
|
|
155
|
+
unreachable(
|
|
156
|
+
`Unexpected '${deprecation.from}' prop, ` +
|
|
157
|
+
(deprecation.to ? `use '${deprecation.to}' instead` : "remove it") +
|
|
158
|
+
` (see <${changelog}#${deprecation.id}> for more info)`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const mdastTree = processor.parse(file);
|
|
164
|
+
let hastTree: Nodes = processor.runSync(mdastTree, file);
|
|
165
|
+
|
|
166
|
+
if (className) {
|
|
167
|
+
hastTree = {
|
|
168
|
+
type: "element",
|
|
169
|
+
tagName: "div",
|
|
170
|
+
properties: { className },
|
|
171
|
+
children:
|
|
172
|
+
hastTree.type === "root"
|
|
173
|
+
? (hastTree.children as ElementContent[])
|
|
174
|
+
: [hastTree],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Nodes type is slightly off, different versions of `hast` have different types
|
|
179
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
180
|
+
// @ts-ignore
|
|
181
|
+
visit(hastTree, transform);
|
|
182
|
+
|
|
183
|
+
return toJsxRuntime(hastTree, {
|
|
184
|
+
Fragment,
|
|
185
|
+
components,
|
|
186
|
+
ignoreInvalidStyle: true,
|
|
187
|
+
jsx,
|
|
188
|
+
jsxs,
|
|
189
|
+
passKeys: true,
|
|
190
|
+
passNode: true,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
function transform(
|
|
194
|
+
node: Nodes,
|
|
195
|
+
index: number | null,
|
|
196
|
+
parent: Parents | undefined,
|
|
197
|
+
): number | void {
|
|
198
|
+
if (node.type === "raw" && parent && typeof index === "number") {
|
|
199
|
+
if (skipHtml) {
|
|
200
|
+
parent.children.splice(index, 1);
|
|
201
|
+
} else {
|
|
202
|
+
parent.children[index] = { type: "text", value: node.value };
|
|
203
|
+
}
|
|
204
|
+
return index;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (node.type === "element") {
|
|
208
|
+
for (const key in urlAttributes) {
|
|
209
|
+
if (
|
|
210
|
+
Object.prototype.hasOwnProperty.call(urlAttributes, key) &&
|
|
211
|
+
Object.prototype.hasOwnProperty.call(node.properties, key)
|
|
212
|
+
) {
|
|
213
|
+
const value = node.properties[key];
|
|
214
|
+
const test = urlAttributes[key];
|
|
215
|
+
if (
|
|
216
|
+
test === null ||
|
|
217
|
+
test === undefined ||
|
|
218
|
+
test.includes(node.tagName)
|
|
219
|
+
) {
|
|
220
|
+
node.properties[key] = urlTransform(String(value || ""), key, node);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
let remove = allowedElements
|
|
226
|
+
? !allowedElements.includes(node.tagName)
|
|
227
|
+
: disallowedElements
|
|
228
|
+
? disallowedElements.includes(node.tagName)
|
|
229
|
+
: false;
|
|
230
|
+
|
|
231
|
+
if (!remove && allowElement && typeof index === "number") {
|
|
232
|
+
remove = !allowElement(node, index, parent);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (remove && parent && typeof index === "number") {
|
|
236
|
+
if (unwrapDisallowed && node.children) {
|
|
237
|
+
parent.children.splice(index, 1, ...node.children);
|
|
238
|
+
} else {
|
|
239
|
+
parent.children.splice(index, 1);
|
|
240
|
+
}
|
|
241
|
+
return index;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function defaultUrlTransform(value: string): string {
|
|
248
|
+
const colon = value.indexOf(":");
|
|
249
|
+
const questionMark = value.indexOf("?");
|
|
250
|
+
const numberSign = value.indexOf("#");
|
|
251
|
+
const slash = value.indexOf("/");
|
|
252
|
+
|
|
253
|
+
if (
|
|
254
|
+
colon < 0 ||
|
|
255
|
+
(slash > -1 && colon > slash) ||
|
|
256
|
+
(questionMark > -1 && colon > questionMark) ||
|
|
257
|
+
(numberSign > -1 && colon > numberSign) ||
|
|
258
|
+
safeProtocol.test(value.slice(0, colon))
|
|
259
|
+
) {
|
|
260
|
+
return value;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return "";
|
|
264
|
+
}
|
|
@@ -1,22 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { lazy } from "react";
|
|
1
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
3
2
|
import { ClientOnly } from "../../components/ClientOnly.js";
|
|
4
3
|
import type { ZudokuPlugin } from "../../core/plugins.js";
|
|
5
4
|
import { aiChatSettings, baseSettings } from "./inkeep.js";
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
interface PluginInkeepBaseSettings {
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
integrationId: string;
|
|
9
|
+
organizationId: string;
|
|
10
|
+
organizationDisplayName?: string;
|
|
11
|
+
primaryBrandColor: string;
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
interface InkeepEmbedConfig {
|
|
15
|
+
componentType: string;
|
|
16
|
+
targetElement: HTMLElement;
|
|
17
|
+
properties: unknown;
|
|
18
|
+
}
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
interface InkeepWidget {
|
|
21
|
+
render: (config: InkeepEmbedConfig & { isOpen: boolean }) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
declare global {
|
|
25
|
+
let Inkeep: () => {
|
|
26
|
+
embed: (config: InkeepEmbedConfig) => InkeepWidget;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
20
29
|
|
|
21
30
|
const InkeepSearch = ({
|
|
22
31
|
prefilledQuery,
|
|
@@ -29,23 +38,50 @@ const InkeepSearch = ({
|
|
|
29
38
|
prefilledQuery?: string | null;
|
|
30
39
|
settings: PluginInkeepBaseSettings;
|
|
31
40
|
}) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
42
|
+
|
|
43
|
+
const config: InkeepEmbedConfig = useMemo(
|
|
44
|
+
() => ({
|
|
45
|
+
componentType: "CustomTrigger",
|
|
46
|
+
targetElement: ref.current!,
|
|
47
|
+
properties: {
|
|
48
|
+
isOpen,
|
|
49
|
+
onClose,
|
|
50
|
+
onOpen: undefined,
|
|
51
|
+
baseSettings: { ...baseSettings, ...settings },
|
|
52
|
+
searchSettings: {
|
|
53
|
+
prefilledQuery: prefilledQuery || undefined,
|
|
54
|
+
},
|
|
55
|
+
aiChatSettings,
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
[isOpen, onClose, prefilledQuery, settings, ref],
|
|
42
59
|
);
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
const inkeepWidget = Inkeep().embed(config);
|
|
63
|
+
inkeepWidget.render({
|
|
64
|
+
...config,
|
|
65
|
+
isOpen,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return <div ref={ref} />;
|
|
43
70
|
};
|
|
44
71
|
|
|
45
72
|
export const inkeepSearchPlugin = (
|
|
46
73
|
settings: PluginInkeepBaseSettings,
|
|
47
74
|
): ZudokuPlugin => {
|
|
48
75
|
return {
|
|
76
|
+
getHead: () => {
|
|
77
|
+
return (
|
|
78
|
+
<script
|
|
79
|
+
type="module"
|
|
80
|
+
src="https://unpkg.com/@inkeep/uikit-js@0.3.19/dist/embed.js"
|
|
81
|
+
defer
|
|
82
|
+
></script>
|
|
83
|
+
);
|
|
84
|
+
},
|
|
49
85
|
renderSearch: ({
|
|
50
86
|
isOpen,
|
|
51
87
|
onClose,
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
InkeepAIChatSettings,
|
|
3
|
-
InkeepModalSettings,
|
|
4
|
-
InkeepSearchSettings,
|
|
5
|
-
} from "@inkeep/widgets";
|
|
6
|
-
|
|
7
1
|
const baseSettings = {
|
|
8
2
|
theme: {
|
|
9
3
|
components: {
|
|
@@ -23,10 +17,10 @@ const baseSettings = {
|
|
|
23
17
|
},
|
|
24
18
|
} as const;
|
|
25
19
|
|
|
26
|
-
const modalSettings
|
|
20
|
+
const modalSettings = {};
|
|
27
21
|
|
|
28
|
-
const searchSettings
|
|
22
|
+
const searchSettings = {};
|
|
29
23
|
|
|
30
|
-
const aiChatSettings
|
|
24
|
+
const aiChatSettings = {};
|
|
31
25
|
|
|
32
26
|
export { aiChatSettings, baseSettings, modalSettings, searchSettings };
|