@bikdotai/bik-component-library 0.0.839-beta.2 → 0.0.839-beta.4

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.
Files changed (80) hide show
  1. package/dist/cjs/components/BikGiftedChat/GiftedChat/GiftedChat.js +1 -1
  2. package/dist/cjs/components/BikGiftedChat/GiftedChat/GiftedChat.js.map +1 -1
  3. package/dist/cjs/components/WhatsAppTextEditor/WhatsAppTextEditor.js +23 -23
  4. package/dist/cjs/components/WhatsAppTextEditor/WhatsAppTextEditor.js.map +1 -1
  5. package/dist/cjs/components/agent-builder/components/AiTextArea.js +1 -1
  6. package/dist/cjs/components/agent-builder/components/AiTextArea.js.map +1 -1
  7. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js +2 -2
  8. package/dist/cjs/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  9. package/dist/cjs/components/bik-chatbot/components/ChatWindow.js +20 -20
  10. package/dist/cjs/components/bik-chatbot/components/ChatWindow.js.map +1 -1
  11. package/dist/cjs/components/button/themes.js +11 -11
  12. package/dist/cjs/components/button/themes.js.map +1 -1
  13. package/dist/cjs/components/input/ChipInput.js +1 -1
  14. package/dist/cjs/components/input/ChipInput.js.map +1 -1
  15. package/dist/cjs/components/input/Input-helper.js +1 -1
  16. package/dist/cjs/components/input/Input-helper.js.map +1 -1
  17. package/dist/cjs/components/input/Input.js +1 -1
  18. package/dist/cjs/components/input/Input.js.map +1 -1
  19. package/dist/cjs/components/plans/SubscriptionPlanSelector.js +5 -5
  20. package/dist/cjs/components/plans/SubscriptionPlanSelector.js.map +1 -1
  21. package/dist/cjs/editor/BikEditor.js +1 -1
  22. package/dist/cjs/editor/BikEditor.js.map +1 -1
  23. package/dist/cjs/editor/BikEditor.utils.js +3 -3
  24. package/dist/cjs/editor/BikEditor.utils.js.map +1 -1
  25. package/dist/cjs/editor/extensions/buildExtensions.js +2 -2
  26. package/dist/cjs/editor/extensions/buildExtensions.js.map +1 -1
  27. package/dist/cjs/icons/Media/Visual/FormkitNeutral.js +2 -0
  28. package/dist/cjs/icons/Media/Visual/FormkitNeutral.js.map +1 -0
  29. package/dist/cjs/icons/index.js +1 -1
  30. package/dist/cjs/index.js +1 -1
  31. package/dist/esm/components/BikGiftedChat/GiftedChat/GiftedChat.js +66 -61
  32. package/dist/esm/components/BikGiftedChat/GiftedChat/GiftedChat.js.map +1 -1
  33. package/dist/esm/components/WhatsAppTextEditor/WhatsAppTextEditor.js +143 -144
  34. package/dist/esm/components/WhatsAppTextEditor/WhatsAppTextEditor.js.map +1 -1
  35. package/dist/esm/components/agent-builder/components/AiTextArea.js +23 -24
  36. package/dist/esm/components/agent-builder/components/AiTextArea.js.map +1 -1
  37. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js +30 -31
  38. package/dist/esm/components/agent-builder/components/ToolInstructionsField.js.map +1 -1
  39. package/dist/esm/components/bik-chatbot/components/ChatWindow.js +53 -54
  40. package/dist/esm/components/bik-chatbot/components/ChatWindow.js.map +1 -1
  41. package/dist/esm/components/button/themes.d.ts +1 -0
  42. package/dist/esm/components/button/themes.js +61 -51
  43. package/dist/esm/components/button/themes.js.map +1 -1
  44. package/dist/esm/components/input/ChipInput.js +40 -41
  45. package/dist/esm/components/input/ChipInput.js.map +1 -1
  46. package/dist/esm/components/input/Input-helper.d.ts +0 -7
  47. package/dist/esm/components/input/Input-helper.js +25 -16
  48. package/dist/esm/components/input/Input-helper.js.map +1 -1
  49. package/dist/esm/components/input/Input.js +58 -60
  50. package/dist/esm/components/input/Input.js.map +1 -1
  51. package/dist/esm/components/input/Input.model.d.ts +0 -1
  52. package/dist/esm/components/plans/SubscriptionPlanSelector.js +40 -42
  53. package/dist/esm/components/plans/SubscriptionPlanSelector.js.map +1 -1
  54. package/dist/esm/editor/BikEditor.js +118 -122
  55. package/dist/esm/editor/BikEditor.js.map +1 -1
  56. package/dist/esm/editor/BikEditor.utils.d.ts +1 -1
  57. package/dist/esm/editor/BikEditor.utils.js +140 -141
  58. package/dist/esm/editor/BikEditor.utils.js.map +1 -1
  59. package/dist/esm/editor/extensions/buildExtensions.js +39 -49
  60. package/dist/esm/editor/extensions/buildExtensions.js.map +1 -1
  61. package/dist/esm/helpers/index.d.ts +0 -1
  62. package/dist/esm/icons/Media/Visual/FormkitNeutral.js +58 -0
  63. package/dist/esm/icons/Media/Visual/FormkitNeutral.js.map +1 -0
  64. package/dist/esm/icons/Media/Visual/index.d.ts +1 -0
  65. package/dist/esm/icons/index.d.ts +1 -1
  66. package/dist/esm/icons/index.js +404 -402
  67. package/dist/esm/icons/index.js.map +1 -1
  68. package/dist/esm/index.js +114 -124
  69. package/dist/esm/index.js.map +1 -1
  70. package/package.json +1 -2
  71. package/dist/cjs/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js +0 -2
  72. package/dist/cjs/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js.map +0 -1
  73. package/dist/cjs/helpers/sanitize.js +0 -2
  74. package/dist/cjs/helpers/sanitize.js.map +0 -1
  75. package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.d.ts +0 -13
  76. package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js +0 -64
  77. package/dist/esm/editor/extensions/htmlTagStrip/HtmlTagStripExtension.js.map +0 -1
  78. package/dist/esm/helpers/sanitize.d.ts +0 -32
  79. package/dist/esm/helpers/sanitize.js +0 -204
  80. package/dist/esm/helpers/sanitize.js.map +0 -1
@@ -1,13 +0,0 @@
1
- import { Extension } from '@tiptap/core';
2
- /**
3
- * Strips HTML tags from typed text in real time.
4
- *
5
- * Two modes controlled by `stripAll`:
6
- * - `true` (non-email): strip ALL complete tags — `<h1>Hello</h1>` → `Hello`
7
- * - `false` (email): strip only DANGEROUS tags — `<script>`, `<iframe>`,
8
- * `<form>`, etc. — while preserving legitimate email tags like `<h1>`, `<table>`
9
- *
10
- * Incomplete tags like `<h` are preserved (the regex requires a closing `>`).
11
- * Non-tag angle brackets like `2 < 3` are also preserved.
12
- */
13
- export declare const HtmlTagStripExtension: Extension<any, any>;
@@ -1,64 +0,0 @@
1
- import { Extension as u } from "../../../node_modules/@tiptap/core/dist/index.js";
2
- import { Plugin as d } from "@tiptap/pm/state";
3
- const n = /<\/?[a-zA-Z][a-zA-Z0-9]*(?:\s[^>]*)?\/?>/g, f = /* @__PURE__ */ new Set([
4
- "script",
5
- "iframe",
6
- "object",
7
- "embed",
8
- "applet",
9
- "form",
10
- "input",
11
- "button",
12
- "select",
13
- "option",
14
- "textarea",
15
- "style",
16
- "link",
17
- "meta",
18
- "base",
19
- "svg",
20
- "math",
21
- "noscript",
22
- "template"
23
- ]), g = /<\/?([a-zA-Z][a-zA-Z0-9]*)/;
24
- function x(a) {
25
- const r = a.match(g);
26
- return r ? f.has(r[1].toLowerCase()) : !1;
27
- }
28
- const E = u.create({
29
- name: "htmlTagStrip",
30
- addOptions() {
31
- return { stripAll: !0 };
32
- },
33
- addProseMirrorPlugins() {
34
- const { stripAll: a } = this.options, r = a ? () => !0 : (s) => x(s);
35
- return [
36
- new d({
37
- appendTransaction(s, A, i) {
38
- if (!s.some((t) => t.docChanged)) return null;
39
- const { tr: e } = i;
40
- let l = !1;
41
- return i.doc.descendants((t, o) => {
42
- if (!t.isText || !t.text || (n.lastIndex = 0, !n.test(t.text))) return;
43
- n.lastIndex = 0;
44
- const p = t.text.replace(
45
- n,
46
- (c) => r(c) ? "" : c
47
- );
48
- if (p === t.text) return;
49
- const m = o + t.nodeSize;
50
- p ? e.replaceWith(
51
- e.mapping.map(o),
52
- e.mapping.map(m),
53
- i.schema.text(p, t.marks)
54
- ) : e.delete(e.mapping.map(o), e.mapping.map(m)), l = !0;
55
- }), l ? (e.setMeta("addToHistory", !1), e) : null;
56
- }
57
- })
58
- ];
59
- }
60
- });
61
- export {
62
- E as HtmlTagStripExtension
63
- };
64
- //# sourceMappingURL=HtmlTagStripExtension.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HtmlTagStripExtension.js","sources":["../../../../../src/editor/extensions/htmlTagStrip/HtmlTagStripExtension.ts"],"sourcesContent":["import { Extension } from '@tiptap/core';\nimport { Plugin } from '@tiptap/pm/state';\n\nconst COMPLETE_TAG = /<\\/?[a-zA-Z][a-zA-Z0-9]*(?:\\s[^>]*)?\\/?>/g;\n\n// Tags that have no business in an email — stripped even in rich-paste mode.\nconst DANGEROUS_TAG_NAMES = new Set([\n\t'script',\n\t'iframe',\n\t'object',\n\t'embed',\n\t'applet',\n\t'form',\n\t'input',\n\t'button',\n\t'select',\n\t'option',\n\t'textarea',\n\t'style',\n\t'link',\n\t'meta',\n\t'base',\n\t'svg',\n\t'math',\n\t'noscript',\n\t'template',\n]);\n\nconst TAG_NAME_RE = /<\\/?([a-zA-Z][a-zA-Z0-9]*)/;\n\nfunction isDangerousTag(tag: string): boolean {\n\tconst m = tag.match(TAG_NAME_RE);\n\treturn m ? DANGEROUS_TAG_NAMES.has(m[1].toLowerCase()) : false;\n}\n\n/**\n * Strips HTML tags from typed text in real time.\n *\n * Two modes controlled by `stripAll`:\n * - `true` (non-email): strip ALL complete tags — `<h1>Hello</h1>` → `Hello`\n * - `false` (email): strip only DANGEROUS tags — `<script>`, `<iframe>`,\n * `<form>`, etc. — while preserving legitimate email tags like `<h1>`, `<table>`\n *\n * Incomplete tags like `<h` are preserved (the regex requires a closing `>`).\n * Non-tag angle brackets like `2 < 3` are also preserved.\n */\nexport const HtmlTagStripExtension = Extension.create({\n\tname: 'htmlTagStrip',\n\taddOptions() {\n\t\treturn { stripAll: true };\n\t},\n\taddProseMirrorPlugins() {\n\t\tconst { stripAll } = this.options;\n\t\tconst shouldStrip = stripAll\n\t\t\t? () => true\n\t\t\t: (tag: string) => isDangerousTag(tag);\n\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tappendTransaction(transactions, _oldState, newState) {\n\t\t\t\t\tif (!transactions.some((t) => t.docChanged)) return null;\n\n\t\t\t\t\tconst { tr } = newState;\n\t\t\t\t\tlet changed = false;\n\n\t\t\t\t\tnewState.doc.descendants((node, pos) => {\n\t\t\t\t\t\tif (!node.isText || !node.text) return;\n\t\t\t\t\t\tCOMPLETE_TAG.lastIndex = 0;\n\t\t\t\t\t\tif (!COMPLETE_TAG.test(node.text)) return;\n\n\t\t\t\t\t\tCOMPLETE_TAG.lastIndex = 0;\n\t\t\t\t\t\tconst stripped = node.text.replace(COMPLETE_TAG, (match) =>\n\t\t\t\t\t\t\tshouldStrip(match) ? '' : match,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (stripped === node.text) return;\n\n\t\t\t\t\t\tconst end = pos + node.nodeSize;\n\t\t\t\t\t\tif (stripped) {\n\t\t\t\t\t\t\ttr.replaceWith(\n\t\t\t\t\t\t\t\ttr.mapping.map(pos),\n\t\t\t\t\t\t\t\ttr.mapping.map(end),\n\t\t\t\t\t\t\t\tnewState.schema.text(stripped, node.marks),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttr.delete(tr.mapping.map(pos), tr.mapping.map(end));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!changed) return null;\n\t\t\t\t\ttr.setMeta('addToHistory', false);\n\t\t\t\t\treturn tr;\n\t\t\t\t},\n\t\t\t}),\n\t\t];\n\t},\n});\n"],"names":["COMPLETE_TAG","DANGEROUS_TAG_NAMES","TAG_NAME_RE","isDangerousTag","tag","m","HtmlTagStripExtension","Extension","stripAll","shouldStrip","Plugin","transactions","_oldState","newState","tr","changed","node","pos","stripped","match","end"],"mappings":";;AAGA,MAAMA,IAAe,6CAGfC,wBAA0B,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC,GAEKC,IAAc;AAEpB,SAASC,EAAeC,GAAsB;AAC7C,QAAMC,IAAID,EAAI,MAAMF,CAAW;AAC/B,SAAOG,IAAIJ,EAAoB,IAAII,EAAE,CAAC,EAAE,YAAA,CAAa,IAAI;AAC1D;AAaO,MAAMC,IAAwBC,EAAU,OAAO;AAAA,EACrD,MAAM;AAAA,EACN,aAAa;AACZ,WAAO,EAAE,UAAU,GAAA;AAAA,EACpB;AAAA,EACA,wBAAwB;AACvB,UAAM,EAAE,UAAAC,MAAa,KAAK,SACpBC,IAAcD,IACjB,MAAM,KACN,CAACJ,MAAgBD,EAAeC,CAAG;AAEtC,WAAO;AAAA,MACN,IAAIM,EAAO;AAAA,QACV,kBAAkBC,GAAcC,GAAWC,GAAU;AACpD,cAAI,CAACF,EAAa,KAAK,CAAC,MAAM,EAAE,UAAU,EAAG,QAAO;AAEpD,gBAAM,EAAE,IAAAG,MAAOD;AACf,cAAIE,IAAU;AA0Bd,iBAxBAF,EAAS,IAAI,YAAY,CAACG,GAAMC,MAAQ;AAGvC,gBAFI,CAACD,EAAK,UAAU,CAACA,EAAK,SAC1BhB,EAAa,YAAY,GACrB,CAACA,EAAa,KAAKgB,EAAK,IAAI,GAAG;AAEnC,YAAAhB,EAAa,YAAY;AACzB,kBAAMkB,IAAWF,EAAK,KAAK;AAAA,cAAQhB;AAAA,cAAc,CAACmB,MACjDV,EAAYU,CAAK,IAAI,KAAKA;AAAA,YAAA;AAE3B,gBAAID,MAAaF,EAAK,KAAM;AAE5B,kBAAMI,IAAMH,IAAMD,EAAK;AACvB,YAAIE,IACHJ,EAAG;AAAA,cACFA,EAAG,QAAQ,IAAIG,CAAG;AAAA,cAClBH,EAAG,QAAQ,IAAIM,CAAG;AAAA,cAClBP,EAAS,OAAO,KAAKK,GAAUF,EAAK,KAAK;AAAA,YAAA,IAG1CF,EAAG,OAAOA,EAAG,QAAQ,IAAIG,CAAG,GAAGH,EAAG,QAAQ,IAAIM,CAAG,CAAC,GAEnDL,IAAU;AAAA,UACX,CAAC,GAEIA,KACLD,EAAG,QAAQ,gBAAgB,EAAK,GACzBA,KAFc;AAAA,QAGtB;AAAA,MAAA,CACA;AAAA,IAAA;AAAA,EAEH;AACD,CAAC;"}
@@ -1,32 +0,0 @@
1
- export declare const isAllowedUrl: (url: string | null | undefined, allowed: Set<string>) => string | null;
2
- export declare const isAllowedLinkUrl: (url?: string | null) => boolean;
3
- export declare const isAllowedImageUrl: (url?: string | null) => boolean;
4
- export declare const stripHtmlTags: (input: string | null | undefined) => string;
5
- /**
6
- * Escape CSV/Excel formula injection. Prefixes values starting with a
7
- * formula-triggering character (=, +, -, @, tab, CR) with a single quote
8
- * so spreadsheet software treats them as literal text.
9
- */
10
- export declare const escapeFormulaInjection: (input: string | null | undefined) => string;
11
- /**
12
- * Render-safe plain text. Strips every tag and returns safe HTML (with
13
- * entities). Use at render sinks that must show plain text via innerHTML.
14
- * For input onChange, use stripHtmlTags instead.
15
- */
16
- export declare const sanitizePlainText: (input: string | null | undefined) => string;
17
- /**
18
- * Basic rich text. A small formatting allowlist; no style tag/attr, links
19
- * restricted to safe protocols.
20
- */
21
- export declare const sanitizeBasicHtml: (input: string | null | undefined) => string;
22
- /**
23
- * Filter an inline style string to only safe CSS properties with safe values.
24
- * Returns the cleaned style string (empty string if nothing survives).
25
- */
26
- export declare const sanitizeCssProperties: (style: string) => string;
27
- /**
28
- * Full rich text / inbound email HTML. Allowlist of tags and attributes an
29
- * email needs to render; everything else is stripped. Inline style attributes
30
- * are filtered to a safe CSS property allowlist.
31
- */
32
- export declare const sanitizeEmailHtml: (input: string | null | undefined) => string;
@@ -1,204 +0,0 @@
1
- import i from "dompurify";
2
- const n = () => typeof window < "u", l = /<\/?[^>]+(>|$)/g, d = /* @__PURE__ */ new Set(["https:", "mailto:", "tel:"]), p = /* @__PURE__ */ new Set(["https:", "data:"]), c = (t, e) => {
3
- if (!t) return null;
4
- try {
5
- const r = new URL(t, "https://bik.local");
6
- return e.has(r.protocol) ? t : null;
7
- } catch {
8
- return null;
9
- }
10
- }, A = (t) => c(t, d) !== null, L = (t) => c(t, p) !== null, f = /<\/?[a-zA-Z][a-zA-Z0-9]*(?:\s[^>]*)?\/?>/g, O = (t) => t ? t.replace(f, "") : "", g = /^[=+\-@\t\r]/, w = (t) => t ? g.test(t) ? `'${t}` : t : "", _ = (t) => t ? n() ? i.sanitize(t, {
11
- ALLOWED_TAGS: [],
12
- ALLOWED_ATTR: [],
13
- KEEP_CONTENT: !0
14
- }) : t.replace(l, "") : "", E = (t) => t ? n() ? i.sanitize(t, {
15
- ALLOWED_TAGS: [
16
- "p",
17
- "br",
18
- "b",
19
- "strong",
20
- "i",
21
- "em",
22
- "u",
23
- "s",
24
- "span",
25
- "a",
26
- "ul",
27
- "ol",
28
- "li",
29
- "blockquote"
30
- ],
31
- ALLOWED_ATTR: ["href", "target", "rel", "class"],
32
- FORBID_TAGS: ["style"],
33
- FORBID_ATTR: ["style"],
34
- ALLOWED_URI_REGEXP: /^(?:https|mailto|tel):/i
35
- }) : t.replace(l, "") : "", h = /* @__PURE__ */ new Set([
36
- "color",
37
- "background-color",
38
- "background",
39
- "font-family",
40
- "font-size",
41
- "font-weight",
42
- "font-style",
43
- "font-variant",
44
- "font",
45
- "line-height",
46
- "letter-spacing",
47
- "word-spacing",
48
- "text-align",
49
- "text-decoration",
50
- "text-transform",
51
- "text-indent",
52
- "vertical-align",
53
- "white-space",
54
- "word-wrap",
55
- "word-break",
56
- "overflow-wrap",
57
- "direction",
58
- "margin",
59
- "margin-top",
60
- "margin-right",
61
- "margin-bottom",
62
- "margin-left",
63
- "padding",
64
- "padding-top",
65
- "padding-right",
66
- "padding-bottom",
67
- "padding-left",
68
- "border",
69
- "border-top",
70
- "border-right",
71
- "border-bottom",
72
- "border-left",
73
- "border-width",
74
- "border-style",
75
- "border-color",
76
- "border-collapse",
77
- "border-spacing",
78
- "border-radius",
79
- "width",
80
- "min-width",
81
- "max-width",
82
- "height",
83
- "min-height",
84
- "max-height",
85
- "display",
86
- "visibility",
87
- "opacity",
88
- "float",
89
- "clear",
90
- "overflow",
91
- "overflow-x",
92
- "overflow-y",
93
- "table-layout",
94
- "list-style",
95
- "list-style-type",
96
- "list-style-position",
97
- "box-sizing"
98
- ]), u = /url\s*\(|expression\s*\(|-moz-binding|behavior\s*:|@import|javascript:|data:/i, b = (t) => t.split(";").map((e) => e.trim()).filter((e) => {
99
- if (!e) return !1;
100
- const r = e.indexOf(":");
101
- if (r < 0) return !1;
102
- const s = e.slice(0, r).trim().toLowerCase(), o = e.slice(r + 1).trim();
103
- return h.has(s) && !u.test(o);
104
- }).join("; "), T = (t) => {
105
- if (!t) return "";
106
- if (!n()) return t.replace(l, "");
107
- const e = (s, o) => {
108
- if (o.attrName !== "style") return;
109
- const a = b(o.attrValue);
110
- a ? o.attrValue = a : o.keepAttr = !1;
111
- };
112
- i.addHook("uponSanitizeAttribute", e);
113
- const r = i.sanitize(t, {
114
- ALLOWED_TAGS: [
115
- "p",
116
- "br",
117
- "div",
118
- "span",
119
- "strong",
120
- "b",
121
- "em",
122
- "i",
123
- "u",
124
- "s",
125
- "ul",
126
- "ol",
127
- "li",
128
- "blockquote",
129
- "h1",
130
- "h2",
131
- "h3",
132
- "h4",
133
- "h5",
134
- "h6",
135
- "a",
136
- "img",
137
- "table",
138
- "thead",
139
- "tbody",
140
- "tfoot",
141
- "tr",
142
- "th",
143
- "td",
144
- "caption",
145
- "colgroup",
146
- "col",
147
- "center",
148
- "font",
149
- "hr",
150
- "pre",
151
- "code",
152
- "sub",
153
- "sup",
154
- "small",
155
- "big",
156
- "figure",
157
- "figcaption",
158
- "section",
159
- "article",
160
- "header",
161
- "footer",
162
- "abbr",
163
- "cite",
164
- "mark",
165
- "del",
166
- "ins"
167
- ],
168
- ALLOWED_ATTR: [
169
- "href",
170
- "target",
171
- "rel",
172
- "src",
173
- "alt",
174
- "title",
175
- "width",
176
- "height",
177
- "style",
178
- "class",
179
- "align",
180
- "valign",
181
- "colspan",
182
- "rowspan",
183
- "cellpadding",
184
- "cellspacing",
185
- "border",
186
- "color",
187
- "bgcolor"
188
- ],
189
- ALLOW_UNKNOWN_PROTOCOLS: !1
190
- });
191
- return i.removeHook("uponSanitizeAttribute"), r;
192
- };
193
- export {
194
- w as escapeFormulaInjection,
195
- L as isAllowedImageUrl,
196
- A as isAllowedLinkUrl,
197
- c as isAllowedUrl,
198
- E as sanitizeBasicHtml,
199
- b as sanitizeCssProperties,
200
- T as sanitizeEmailHtml,
201
- _ as sanitizePlainText,
202
- O as stripHtmlTags
203
- };
204
- //# sourceMappingURL=sanitize.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sanitize.js","sources":["../../../src/helpers/sanitize.ts"],"sourcesContent":["import DOMPurify from 'dompurify';\n\n/**\n * Central HTML/CSS-injection sanitisation for the component library.\n *\n * Two categories:\n *\n * INPUT layer (onChange) — strips tags, keeps plain text:\n * - stripHtmlTags: remove every HTML tag, return raw text\n * - escapeFormulaInjection: prefix CSV-dangerous leading chars with '\n *\n * RENDER layer (dangerouslySetInnerHTML / innerHTML) — DOMPurify-based:\n * - sanitizePlainText: ALLOWED_TAGS: [] (for sinks that must show plain text)\n * - sanitizeBasicHtml: formatting allowlist (chat bubbles, rich previews)\n * - sanitizeEmailHtml: full email allowlist (tables, images, inline style)\n */\n\nconst hasDOM = (): boolean => typeof window !== 'undefined';\n\nconst REGEX_TAG_STRIP = /<\\/?[^>]+(>|$)/g;\n\nconst ALLOWED_LINK_PROTOCOLS = new Set(['https:', 'mailto:', 'tel:']);\nconst ALLOWED_IMG_PROTOCOLS = new Set(['https:', 'data:']);\n\nexport const isAllowedUrl = (\n\turl: string | null | undefined,\n\tallowed: Set<string>,\n): string | null => {\n\tif (!url) return null;\n\ttry {\n\t\tconst parsed = new URL(url, 'https://bik.local');\n\t\treturn allowed.has(parsed.protocol) ? url : null;\n\t} catch {\n\t\treturn null;\n\t}\n};\n\nexport const isAllowedLinkUrl = (url?: string | null): boolean =>\n\tisAllowedUrl(url, ALLOWED_LINK_PROTOCOLS) !== null;\n\nexport const isAllowedImageUrl = (url?: string | null): boolean =>\n\tisAllowedUrl(url, ALLOWED_IMG_PROTOCOLS) !== null;\n\n// ---------------------------------------------------------------------------\n// INPUT layer — for onChange handlers on plain-text inputs\n// ---------------------------------------------------------------------------\n\n/**\n * Strip complete HTML tags from the input, return the raw text content.\n * Uses a regex that only matches tags with both < and >, so partial input\n * like \"<h\" while typing is preserved (no closing >, not a tag yet).\n *\n * \"<h1>Hello</h1>\" → \"Hello\"\n * \"<h\" → \"<h\" (incomplete, kept)\n * \"2 < 3\" → \"2 < 3\"\n * \"<script>x</script>\" → \"x\"\n */\nconst COMPLETE_TAG = /<\\/?[a-zA-Z][a-zA-Z0-9]*(?:\\s[^>]*)?\\/?>/g;\n\nexport const stripHtmlTags = (input: string | null | undefined): string => {\n\tif (!input) return '';\n\treturn input.replace(COMPLETE_TAG, '');\n};\n\nconst CSV_FORMULA_PREFIX = /^[=+\\-@\\t\\r]/;\n\n/**\n * Escape CSV/Excel formula injection. Prefixes values starting with a\n * formula-triggering character (=, +, -, @, tab, CR) with a single quote\n * so spreadsheet software treats them as literal text.\n */\nexport const escapeFormulaInjection = (\n\tinput: string | null | undefined,\n): string => {\n\tif (!input) return '';\n\treturn CSV_FORMULA_PREFIX.test(input) ? `'${input}` : input;\n};\n\n// ---------------------------------------------------------------------------\n// RENDER layer — for dangerouslySetInnerHTML / innerHTML sinks\n// ---------------------------------------------------------------------------\n\n/**\n * Render-safe plain text. Strips every tag and returns safe HTML (with\n * entities). Use at render sinks that must show plain text via innerHTML.\n * For input onChange, use stripHtmlTags instead.\n */\nexport const sanitizePlainText = (input: string | null | undefined): string => {\n\tif (!input) return '';\n\tif (!hasDOM()) return input.replace(REGEX_TAG_STRIP, '');\n\treturn DOMPurify.sanitize(input, {\n\t\tALLOWED_TAGS: [],\n\t\tALLOWED_ATTR: [],\n\t\tKEEP_CONTENT: true,\n\t});\n};\n\n/**\n * Basic rich text. A small formatting allowlist; no style tag/attr, links\n * restricted to safe protocols.\n */\nexport const sanitizeBasicHtml = (input: string | null | undefined): string => {\n\tif (!input) return '';\n\tif (!hasDOM()) return input.replace(REGEX_TAG_STRIP, '');\n\treturn DOMPurify.sanitize(input, {\n\t\tALLOWED_TAGS: [\n\t\t\t'p',\n\t\t\t'br',\n\t\t\t'b',\n\t\t\t'strong',\n\t\t\t'i',\n\t\t\t'em',\n\t\t\t'u',\n\t\t\t's',\n\t\t\t'span',\n\t\t\t'a',\n\t\t\t'ul',\n\t\t\t'ol',\n\t\t\t'li',\n\t\t\t'blockquote',\n\t\t],\n\t\tALLOWED_ATTR: ['href', 'target', 'rel', 'class'],\n\t\tFORBID_TAGS: ['style'],\n\t\tFORBID_ATTR: ['style'],\n\t\tALLOWED_URI_REGEXP: /^(?:https|mailto|tel):/i,\n\t});\n};\n\n// CSS properties safe for email rendering. Everything else is stripped from\n// inline style attributes to block position-overlay, url()-exfiltration,\n// expression(), and -moz-binding attacks.\nconst SAFE_CSS_PROPERTIES = new Set([\n\t'color',\n\t'background-color',\n\t'background',\n\t'font-family',\n\t'font-size',\n\t'font-weight',\n\t'font-style',\n\t'font-variant',\n\t'font',\n\t'line-height',\n\t'letter-spacing',\n\t'word-spacing',\n\t'text-align',\n\t'text-decoration',\n\t'text-transform',\n\t'text-indent',\n\t'vertical-align',\n\t'white-space',\n\t'word-wrap',\n\t'word-break',\n\t'overflow-wrap',\n\t'direction',\n\t'margin',\n\t'margin-top',\n\t'margin-right',\n\t'margin-bottom',\n\t'margin-left',\n\t'padding',\n\t'padding-top',\n\t'padding-right',\n\t'padding-bottom',\n\t'padding-left',\n\t'border',\n\t'border-top',\n\t'border-right',\n\t'border-bottom',\n\t'border-left',\n\t'border-width',\n\t'border-style',\n\t'border-color',\n\t'border-collapse',\n\t'border-spacing',\n\t'border-radius',\n\t'width',\n\t'min-width',\n\t'max-width',\n\t'height',\n\t'min-height',\n\t'max-height',\n\t'display',\n\t'visibility',\n\t'opacity',\n\t'float',\n\t'clear',\n\t'overflow',\n\t'overflow-x',\n\t'overflow-y',\n\t'table-layout',\n\t'list-style',\n\t'list-style-type',\n\t'list-style-position',\n\t'box-sizing',\n]);\n\n// Values that indicate CSS injection attempts regardless of property.\nconst DANGEROUS_CSS_VALUE =\n\t/url\\s*\\(|expression\\s*\\(|-moz-binding|behavior\\s*:|@import|javascript:|data:/i;\n\n/**\n * Filter an inline style string to only safe CSS properties with safe values.\n * Returns the cleaned style string (empty string if nothing survives).\n */\nexport const sanitizeCssProperties = (style: string): string => {\n\treturn style\n\t\t.split(';')\n\t\t.map((decl) => decl.trim())\n\t\t.filter((decl) => {\n\t\t\tif (!decl) return false;\n\t\t\tconst colonIdx = decl.indexOf(':');\n\t\t\tif (colonIdx < 0) return false;\n\t\t\tconst prop = decl.slice(0, colonIdx).trim().toLowerCase();\n\t\t\tconst value = decl.slice(colonIdx + 1).trim();\n\t\t\treturn SAFE_CSS_PROPERTIES.has(prop) && !DANGEROUS_CSS_VALUE.test(value);\n\t\t})\n\t\t.join('; ');\n};\n\n/**\n * Full rich text / inbound email HTML. Allowlist of tags and attributes an\n * email needs to render; everything else is stripped. Inline style attributes\n * are filtered to a safe CSS property allowlist.\n */\nexport const sanitizeEmailHtml = (input: string | null | undefined): string => {\n\tif (!input) return '';\n\tif (!hasDOM()) return input.replace(REGEX_TAG_STRIP, '');\n\n\tconst hook = (\n\t\t_node: Element,\n\t\tdata: { attrName: string; attrValue: string; keepAttr: boolean },\n\t) => {\n\t\tif (data.attrName !== 'style') return;\n\t\tconst clean = sanitizeCssProperties(data.attrValue);\n\t\tif (clean) {\n\t\t\tdata.attrValue = clean;\n\t\t} else {\n\t\t\tdata.keepAttr = false;\n\t\t}\n\t};\n\tDOMPurify.addHook('uponSanitizeAttribute', hook);\n\n\tconst result = DOMPurify.sanitize(input, {\n\t\tALLOWED_TAGS: [\n\t\t\t'p',\n\t\t\t'br',\n\t\t\t'div',\n\t\t\t'span',\n\t\t\t'strong',\n\t\t\t'b',\n\t\t\t'em',\n\t\t\t'i',\n\t\t\t'u',\n\t\t\t's',\n\t\t\t'ul',\n\t\t\t'ol',\n\t\t\t'li',\n\t\t\t'blockquote',\n\t\t\t'h1',\n\t\t\t'h2',\n\t\t\t'h3',\n\t\t\t'h4',\n\t\t\t'h5',\n\t\t\t'h6',\n\t\t\t'a',\n\t\t\t'img',\n\t\t\t'table',\n\t\t\t'thead',\n\t\t\t'tbody',\n\t\t\t'tfoot',\n\t\t\t'tr',\n\t\t\t'th',\n\t\t\t'td',\n\t\t\t'caption',\n\t\t\t'colgroup',\n\t\t\t'col',\n\t\t\t'center',\n\t\t\t'font',\n\t\t\t'hr',\n\t\t\t'pre',\n\t\t\t'code',\n\t\t\t'sub',\n\t\t\t'sup',\n\t\t\t'small',\n\t\t\t'big',\n\t\t\t'figure',\n\t\t\t'figcaption',\n\t\t\t'section',\n\t\t\t'article',\n\t\t\t'header',\n\t\t\t'footer',\n\t\t\t'abbr',\n\t\t\t'cite',\n\t\t\t'mark',\n\t\t\t'del',\n\t\t\t'ins',\n\t\t],\n\t\tALLOWED_ATTR: [\n\t\t\t'href',\n\t\t\t'target',\n\t\t\t'rel',\n\t\t\t'src',\n\t\t\t'alt',\n\t\t\t'title',\n\t\t\t'width',\n\t\t\t'height',\n\t\t\t'style',\n\t\t\t'class',\n\t\t\t'align',\n\t\t\t'valign',\n\t\t\t'colspan',\n\t\t\t'rowspan',\n\t\t\t'cellpadding',\n\t\t\t'cellspacing',\n\t\t\t'border',\n\t\t\t'color',\n\t\t\t'bgcolor',\n\t\t],\n\t\tALLOW_UNKNOWN_PROTOCOLS: false,\n\t});\n\n\tDOMPurify.removeHook('uponSanitizeAttribute');\n\treturn result;\n};\n"],"names":["hasDOM","REGEX_TAG_STRIP","ALLOWED_LINK_PROTOCOLS","ALLOWED_IMG_PROTOCOLS","isAllowedUrl","url","allowed","parsed","isAllowedLinkUrl","isAllowedImageUrl","COMPLETE_TAG","stripHtmlTags","input","CSV_FORMULA_PREFIX","escapeFormulaInjection","sanitizePlainText","DOMPurify","sanitizeBasicHtml","SAFE_CSS_PROPERTIES","DANGEROUS_CSS_VALUE","sanitizeCssProperties","style","decl","colonIdx","prop","value","sanitizeEmailHtml","hook","_node","data","clean","result"],"mappings":"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"}