@flamingo-stack/openframe-frontend-core 0.0.508 → 0.0.509
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/chat-protocol/decode.d.ts +58 -0
- package/dist/chat-protocol/decode.d.ts.map +1 -0
- package/dist/chat-protocol/encode.d.ts +44 -0
- package/dist/chat-protocol/encode.d.ts.map +1 -0
- package/dist/chat-protocol/env-flag.d.ts +35 -0
- package/dist/chat-protocol/env-flag.d.ts.map +1 -0
- package/dist/chat-protocol/events.d.ts +216 -0
- package/dist/chat-protocol/events.d.ts.map +1 -0
- package/dist/chat-protocol/frames.d.ts +213 -0
- package/dist/chat-protocol/frames.d.ts.map +1 -0
- package/dist/chat-protocol/index.cjs +506 -0
- package/dist/chat-protocol/index.cjs.map +1 -0
- package/dist/chat-protocol/index.d.ts +18 -0
- package/dist/chat-protocol/index.d.ts.map +1 -0
- package/dist/chat-protocol/index.js +490 -0
- package/dist/chat-protocol/index.js.map +1 -0
- package/dist/chat-protocol/ip-normalize.d.ts +44 -0
- package/dist/chat-protocol/ip-normalize.d.ts.map +1 -0
- package/dist/chat-protocol/nats-decoder.d.ts +26 -0
- package/dist/chat-protocol/nats-decoder.d.ts.map +1 -0
- package/dist/{chunk-3SQ5KXHQ.cjs → chunk-2T4GTV25.cjs} +9 -9
- package/dist/{chunk-3SQ5KXHQ.cjs.map → chunk-2T4GTV25.cjs.map} +1 -1
- package/dist/{chunk-CWAOV2FK.cjs → chunk-3CGZPAGR.cjs} +3 -3
- package/dist/{chunk-CWAOV2FK.cjs.map → chunk-3CGZPAGR.cjs.map} +1 -1
- package/dist/{chunk-TLMJHMXJ.js → chunk-3QSR22IC.js} +12 -12
- package/dist/chunk-3QSR22IC.js.map +1 -0
- package/dist/{chunk-TWYNR4TZ.cjs → chunk-4G5TLHJD.cjs} +7141 -4799
- package/dist/chunk-4G5TLHJD.cjs.map +1 -0
- package/dist/{chunk-ADPMHWOE.js → chunk-72XAID7Y.js} +4 -4
- package/dist/{chunk-PAGKRNWK.js → chunk-7WZHBQ4J.js} +2 -2
- package/dist/{chunk-OCEKO5CW.js → chunk-AEELJC4N.js} +12106 -9764
- package/dist/chunk-AEELJC4N.js.map +1 -0
- package/dist/{chunk-Z42BGM6Q.cjs → chunk-BT2WWDFP.cjs} +5 -5
- package/dist/{chunk-Z42BGM6Q.cjs.map → chunk-BT2WWDFP.cjs.map} +1 -1
- package/dist/{chunk-7LEL3RIX.cjs → chunk-C7OY3PQP.cjs} +11 -11
- package/dist/{chunk-7LEL3RIX.cjs.map → chunk-C7OY3PQP.cjs.map} +1 -1
- package/dist/{chunk-RHGGEKPQ.cjs → chunk-CIOLOQKQ.cjs} +4 -4
- package/dist/{chunk-RHGGEKPQ.cjs.map → chunk-CIOLOQKQ.cjs.map} +1 -1
- package/dist/{chunk-TSZHM74B.js → chunk-DC2TKS7C.js} +2 -2
- package/dist/{chunk-M2GOR3XQ.cjs → chunk-DYPYR7FR.cjs} +87 -87
- package/dist/{chunk-M2GOR3XQ.cjs.map → chunk-DYPYR7FR.cjs.map} +1 -1
- package/dist/{chunk-I64ABCDX.js → chunk-I2B6X77L.js} +2 -2
- package/dist/{chunk-NIZDKTGL.cjs → chunk-K5MSCMDK.cjs} +37 -37
- package/dist/{chunk-NIZDKTGL.cjs.map → chunk-K5MSCMDK.cjs.map} +1 -1
- package/dist/{chunk-DTYRYB2N.js → chunk-K6QTZ7CZ.js} +2 -2
- package/dist/{chunk-4LTMXDUS.js → chunk-KBN7PMFT.js} +2 -2
- package/dist/{chunk-TBMV7I5N.js → chunk-KXZO2WZX.js} +2 -2
- package/dist/{chunk-QTYZMP6D.cjs → chunk-LBAKLT6T.cjs} +62 -62
- package/dist/chunk-LBAKLT6T.cjs.map +1 -0
- package/dist/{chunk-KEBYLU3U.js → chunk-LFUPI7VX.js} +2 -2
- package/dist/{chunk-LDTR4IVZ.cjs → chunk-M37PBG4N.cjs} +31 -31
- package/dist/{chunk-LDTR4IVZ.cjs.map → chunk-M37PBG4N.cjs.map} +1 -1
- package/dist/{chunk-WA7RR64F.js → chunk-PO5O654H.js} +6 -5
- package/dist/chunk-PO5O654H.js.map +1 -0
- package/dist/{chunk-WK4N5VBX.cjs → chunk-QJJISLPA.cjs} +28 -27
- package/dist/chunk-QJJISLPA.cjs.map +1 -0
- package/dist/{chunk-2F44PLTV.cjs → chunk-T7MCSA55.cjs} +26 -26
- package/dist/{chunk-2F44PLTV.cjs.map → chunk-T7MCSA55.cjs.map} +1 -1
- package/dist/{chunk-WJQHJD7J.js → chunk-TWSKTJHW.js} +2 -2
- package/dist/{chunk-ZSQHZYCO.cjs → chunk-UQDMJ6DH.cjs} +13 -13
- package/dist/{chunk-ZSQHZYCO.cjs.map → chunk-UQDMJ6DH.cjs.map} +1 -1
- package/dist/{chunk-TZRUCD56.js → chunk-V3ZAAFE3.js} +5 -5
- package/dist/{chunk-LRGHJPET.js → chunk-XGIFOHKE.js} +2 -2
- package/dist/{chunk-POOMO3PA.cjs → chunk-YQEPRYT5.cjs} +7 -7
- package/dist/{chunk-POOMO3PA.cjs.map → chunk-YQEPRYT5.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/chat-message-enhanced.d.ts.map +1 -1
- package/dist/components/chat/chat-message-list.d.ts.map +1 -1
- package/dist/components/chat/hooks/index.d.ts +0 -1
- package/dist/components/chat/hooks/index.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-chat.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-chunk-catchup.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts +15 -48
- package/dist/components/chat/hooks/use-nats-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts +10 -57
- package/dist/components/chat/hooks/use-sse-chat-adapter.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +10 -2
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.d.ts +1 -0
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +21 -13
- package/dist/components/chat/stream/chat-dialog-store.d.ts +184 -0
- package/dist/components/chat/stream/chat-dialog-store.d.ts.map +1 -0
- package/dist/components/chat/stream/chat-stream-reducer.d.ts +380 -0
- package/dist/components/chat/stream/chat-stream-reducer.d.ts.map +1 -0
- package/dist/components/chat/stream/delta-batcher.d.ts +51 -0
- package/dist/components/chat/stream/delta-batcher.d.ts.map +1 -0
- package/dist/components/chat/stream/index.d.ts +17 -0
- package/dist/components/chat/stream/index.d.ts.map +1 -0
- package/dist/components/chat/stream/message-mutations.d.ts +77 -0
- package/dist/components/chat/stream/message-mutations.d.ts.map +1 -0
- package/dist/components/chat/stream/use-chat-stream-reducer.d.ts +22 -0
- package/dist/components/chat/stream/use-chat-stream-reducer.d.ts.map +1 -0
- package/dist/components/chat/types/api.types.d.ts +1 -81
- package/dist/components/chat/types/api.types.d.ts.map +1 -1
- package/dist/components/chat/types/processing.types.d.ts +2 -93
- package/dist/components/chat/types/processing.types.d.ts.map +1 -1
- package/dist/components/chat/types/unified-chat-state.types.d.ts +15 -0
- package/dist/components/chat/types/unified-chat-state.types.d.ts.map +1 -1
- package/dist/components/chat/utils/extract-incomplete-message-state.d.ts +34 -6
- package/dist/components/chat/utils/extract-incomplete-message-state.d.ts.map +1 -1
- package/dist/components/chat/utils/history-merge.d.ts.map +1 -1
- package/dist/components/chat/utils/index.d.ts +2 -3
- package/dist/components/chat/utils/index.d.ts.map +1 -1
- package/dist/components/chat/utils/process-historical-messages.d.ts +59 -11
- package/dist/components/chat/utils/process-historical-messages.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +174 -132
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +65 -23
- package/dist/components/index.js.map +1 -1
- package/dist/components/meeting-scheduler/index.cjs +34 -34
- package/dist/components/meeting-scheduler/index.js +3 -3
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/index.cjs +44 -2
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.d.ts +1 -2
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +55 -13
- package/dist/components/ui/markdown/base-components.d.ts +51 -0
- package/dist/components/ui/markdown/base-components.d.ts.map +1 -0
- package/dist/components/ui/markdown/engine.d.ts +99 -0
- package/dist/components/ui/markdown/engine.d.ts.map +1 -0
- package/dist/components/ui/markdown/heading-ids.d.ts +65 -0
- package/dist/components/ui/markdown/heading-ids.d.ts.map +1 -0
- package/dist/components/ui/markdown/index.d.ts +18 -0
- package/dist/components/ui/markdown/index.d.ts.map +1 -0
- package/dist/components/ui/markdown/mermaid-diagram.d.ts +79 -0
- package/dist/components/ui/markdown/mermaid-diagram.d.ts.map +1 -0
- package/dist/components/ui/markdown/rich/embed-overrides.d.ts +14 -0
- package/dist/components/ui/markdown/rich/embed-overrides.d.ts.map +1 -0
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts +40 -0
- package/dist/components/ui/markdown/rich/rich-markdown-renderer.d.ts.map +1 -0
- package/dist/components/ui/markdown/rich/shortcodes.d.ts +8 -0
- package/dist/components/ui/markdown/rich/shortcodes.d.ts.map +1 -0
- package/dist/components/ui/markdown/sanitize.d.ts +153 -0
- package/dist/components/ui/markdown/sanitize.d.ts.map +1 -0
- package/dist/components/ui/markdown/simple-markdown-renderer.d.ts +23 -0
- package/dist/components/ui/markdown/simple-markdown-renderer.d.ts.map +1 -0
- package/dist/components/ui/markdown/streaming.d.ts +78 -0
- package/dist/components/ui/markdown/streaming.d.ts.map +1 -0
- package/dist/components/ui/markdown/text-size.d.ts +34 -0
- package/dist/components/ui/markdown/text-size.d.ts.map +1 -0
- package/dist/index.cjs +60 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +71 -13
- package/dist/utils/index.cjs +169 -40
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +162 -41
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/markdown-fences.d.ts +42 -0
- package/dist/utils/markdown-fences.d.ts.map +1 -0
- package/dist/utils/markdown-heading-id.d.ts +85 -0
- package/dist/utils/markdown-heading-id.d.ts.map +1 -0
- package/dist/utils/markdown-section-extractor.d.ts.map +1 -1
- package/package.json +7 -1
- package/src/chat-protocol/__tests__/__snapshots__/nats-decoder-golden.test.ts.snap +319 -0
- package/src/chat-protocol/__tests__/chat-protocol.test.ts +516 -0
- package/src/chat-protocol/__tests__/env-flag.test.ts +52 -0
- package/src/chat-protocol/__tests__/ip-normalize.test.ts +136 -0
- package/src/chat-protocol/__tests__/nats-decoder-golden.test.ts +237 -0
- package/src/chat-protocol/decode.ts +278 -0
- package/src/chat-protocol/encode.ts +71 -0
- package/src/chat-protocol/env-flag.ts +39 -0
- package/src/chat-protocol/events.ts +254 -0
- package/src/chat-protocol/frames.ts +245 -0
- package/src/chat-protocol/index.ts +21 -0
- package/src/chat-protocol/ip-normalize.ts +146 -0
- package/src/chat-protocol/nats-decoder.ts +264 -0
- package/src/components/chat/.chat-message-list.md +10 -6
- package/src/components/chat/__tests__/chat-message-list.test.tsx +450 -9
- package/src/components/chat/__tests__/chat-message-streaming-memo.test.tsx +207 -0
- package/src/components/chat/__tests__/chat-pending-turn.test.tsx +250 -0
- package/src/components/chat/chat-message-enhanced.tsx +122 -20
- package/src/components/chat/chat-message-list.tsx +515 -133
- package/src/components/chat/embeddable-chat.tsx +6 -0
- package/src/components/chat/hooks/.index.md +30 -33
- package/src/components/chat/hooks/.use-nats-chat-adapter.md +36 -55
- package/src/components/chat/hooks/__tests__/__snapshots__/conversation-id-persistence-golden.test.ts.snap +37 -0
- package/src/components/chat/hooks/__tests__/__snapshots__/sse-stream-golden.test.ts.snap +0 -0
- package/src/components/chat/hooks/__tests__/chunk-catchup-dialog-staleness.test.ts +92 -0
- package/src/components/chat/hooks/__tests__/conversation-id-persistence-golden.test.ts +438 -0
- package/src/components/chat/hooks/__tests__/sse-stream-golden.test.ts +318 -0
- package/src/components/chat/hooks/index.ts +0 -1
- package/src/components/chat/hooks/use-chat.ts +8 -0
- package/src/components/chat/hooks/use-chunk-catchup.ts +26 -1
- package/src/components/chat/hooks/use-nats-chat-adapter.ts +254 -825
- package/src/components/chat/hooks/use-sse-chat-adapter.ts +380 -684
- package/src/components/chat/index.ts +5 -0
- package/src/components/chat/stream/__tests__/__snapshots__/chat-stream-reducer-golden.test.ts.snap +944 -0
- package/src/components/chat/stream/__tests__/chat-dialog-store.test.ts +806 -0
- package/src/components/chat/stream/__tests__/chat-stream-reducer-golden.test.ts +467 -0
- package/src/components/chat/stream/__tests__/chat-stream-reducer.test.ts +1330 -0
- package/src/components/chat/stream/__tests__/delta-batcher.test.ts +255 -0
- package/src/components/chat/stream/__tests__/use-chat-stream-reducer.test.ts +105 -0
- package/src/components/chat/stream/chat-dialog-store.ts +536 -0
- package/src/components/chat/stream/chat-stream-reducer.ts +1928 -0
- package/src/components/chat/stream/delta-batcher.ts +168 -0
- package/src/components/chat/stream/index.ts +55 -0
- package/src/components/chat/stream/message-mutations.ts +340 -0
- package/src/components/chat/stream/use-chat-stream-reducer.ts +126 -0
- package/src/components/chat/thinking-display.tsx +1 -1
- package/src/components/chat/types/.api.types.md +39 -49
- package/src/components/chat/types/.processing.types.md +29 -58
- package/src/components/chat/types/.unified-chat-state.types.md +2 -2
- package/src/components/chat/types/api.types.ts +6 -73
- package/src/components/chat/types/processing.types.ts +11 -53
- package/src/components/chat/types/unified-chat-state.types.ts +16 -0
- package/src/components/chat/utils/.extract-incomplete-message-state.md +21 -3
- package/src/components/chat/utils/.history-merge.md +44 -3
- package/src/components/chat/utils/.index.md +31 -40
- package/src/components/chat/utils/__tests__/__snapshots__/process-historical-messages-golden.test.ts.snap +420 -0
- package/src/components/chat/utils/__tests__/__snapshots__/segment-accumulator-golden.test.ts.snap +605 -0
- package/src/components/chat/utils/__tests__/extract-incomplete-message-state.test.ts +106 -0
- package/src/components/chat/utils/__tests__/history-merge.test.ts +160 -0
- package/src/components/chat/utils/__tests__/process-historical-messages-approvals.test.ts +61 -0
- package/src/components/chat/utils/__tests__/process-historical-messages-golden.test.ts +394 -0
- package/src/components/chat/utils/__tests__/segment-accumulator-golden.test.ts +270 -0
- package/src/components/chat/utils/extract-incomplete-message-state.ts +93 -6
- package/src/components/chat/utils/history-merge.ts +85 -5
- package/src/components/chat/utils/index.ts +5 -8
- package/src/components/chat/utils/process-historical-messages.ts +361 -385
- package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +22 -4
- package/src/components/shared/legal-document/legal-document-page.tsx +1 -1
- package/src/components/shared/product-release/release-detail-page.tsx +19 -4
- package/src/components/ui/__tests__/__snapshots__/markdown-parity.test.tsx.snap +2420 -0
- package/src/components/ui/__tests__/markdown-parity.test.tsx +2540 -0
- package/src/components/ui/index.ts +1 -2
- package/src/components/ui/markdown/__tests__/mermaid-security.test.ts +176 -0
- package/src/components/ui/markdown/__tests__/mermaid-stale-render.test.tsx +151 -0
- package/src/components/ui/markdown/__tests__/sanitize-invariant.test.ts +354 -0
- package/src/components/ui/markdown/__tests__/sanitize-render.test.tsx +118 -0
- package/src/components/ui/markdown/__tests__/streaming.test.tsx +436 -0
- package/src/components/ui/markdown/base-components.tsx +360 -0
- package/src/components/ui/markdown/engine.tsx +315 -0
- package/src/components/ui/markdown/heading-ids.ts +239 -0
- package/src/components/ui/markdown/index.ts +49 -0
- package/src/components/ui/markdown/mermaid-diagram.tsx +323 -0
- package/src/components/ui/markdown/rich/embed-overrides.tsx +199 -0
- package/src/components/ui/markdown/rich/rich-markdown-renderer.tsx +184 -0
- package/src/components/ui/markdown/rich/shortcodes.ts +170 -0
- package/src/components/ui/markdown/sanitize.ts +3584 -0
- package/src/components/ui/markdown/simple-markdown-renderer.tsx +28 -0
- package/src/components/ui/markdown/streaming.ts +390 -0
- package/src/components/ui/markdown/text-size.ts +106 -0
- package/src/components/ui/release-changelog-section.tsx +1 -1
- package/src/components/ui/ticket-info-section.tsx +1 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/markdown-fences.ts +127 -0
- package/src/utils/markdown-heading-id.ts +348 -0
- package/src/utils/markdown-section-extractor.ts +41 -56
- package/dist/chunk-OCEKO5CW.js.map +0 -1
- package/dist/chunk-QTYZMP6D.cjs.map +0 -1
- package/dist/chunk-TLMJHMXJ.js.map +0 -1
- package/dist/chunk-TWYNR4TZ.cjs.map +0 -1
- package/dist/chunk-WA7RR64F.js.map +0 -1
- package/dist/chunk-WK4N5VBX.cjs.map +0 -1
- package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts +0 -6
- package/dist/components/chat/hooks/use-realtime-chunk-processor.d.ts.map +0 -1
- package/dist/components/chat/utils/chunk-parser.d.ts +0 -25
- package/dist/components/chat/utils/chunk-parser.d.ts.map +0 -1
- package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
- package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
- package/dist/components/ui/simple-markdown-renderer.d.ts +0 -73
- package/dist/components/ui/simple-markdown-renderer.d.ts.map +0 -1
- package/src/components/chat/hooks/.use-realtime-chunk-processor.md +0 -77
- package/src/components/chat/hooks/use-realtime-chunk-processor.ts +0 -489
- package/src/components/chat/utils/.chunk-parser.md +0 -62
- package/src/components/chat/utils/chunk-parser.ts +0 -262
- package/src/components/ui/.simple-markdown-renderer.md +0 -52
- package/src/components/ui/rich-markdown-renderer.tsx +0 -1223
- package/src/components/ui/simple-markdown-renderer.tsx +0 -964
- /package/dist/{chunk-ADPMHWOE.js.map → chunk-72XAID7Y.js.map} +0 -0
- /package/dist/{chunk-PAGKRNWK.js.map → chunk-7WZHBQ4J.js.map} +0 -0
- /package/dist/{chunk-TSZHM74B.js.map → chunk-DC2TKS7C.js.map} +0 -0
- /package/dist/{chunk-I64ABCDX.js.map → chunk-I2B6X77L.js.map} +0 -0
- /package/dist/{chunk-DTYRYB2N.js.map → chunk-K6QTZ7CZ.js.map} +0 -0
- /package/dist/{chunk-4LTMXDUS.js.map → chunk-KBN7PMFT.js.map} +0 -0
- /package/dist/{chunk-TBMV7I5N.js.map → chunk-KXZO2WZX.js.map} +0 -0
- /package/dist/{chunk-KEBYLU3U.js.map → chunk-LFUPI7VX.js.map} +0 -0
- /package/dist/{chunk-WJQHJD7J.js.map → chunk-TWSKTJHW.js.map} +0 -0
- /package/dist/{chunk-TZRUCD56.js.map → chunk-V3ZAAFE3.js.map} +0 -0
- /package/dist/{chunk-LRGHJPET.js.map → chunk-XGIFOHKE.js.map} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Components } from 'react-markdown';
|
|
2
|
+
import type { ResolveLinkResult } from '../../../types/doc-source';
|
|
3
|
+
import type { TextSizeElement } from './text-size';
|
|
4
|
+
export declare function hasRenderableSrc(src: unknown): src is string;
|
|
5
|
+
export interface BuildBaseComponentsOptions {
|
|
6
|
+
textSizes: Record<TextSizeElement, string>;
|
|
7
|
+
demoteMarkdownH1ToH2: boolean;
|
|
8
|
+
brokenLinks: readonly string[];
|
|
9
|
+
currentPath?: string;
|
|
10
|
+
onInternalLinkClick?: (path: string, options?: {
|
|
11
|
+
expandFolder?: boolean;
|
|
12
|
+
fromInternalLink?: boolean;
|
|
13
|
+
}) => void;
|
|
14
|
+
onResolveLink?: (href: string, currentPath: string) => Promise<ResolveLinkResult>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The standard leaf renderers (`code` block + inline, `blockquote`, `div`
|
|
18
|
+
* pass-through) as standalone functions.
|
|
19
|
+
*
|
|
20
|
+
* SSOT for compositions that must OVERRIDE these renderers for a narrow
|
|
21
|
+
* special case and then fall through: the rich composition intercepts embed
|
|
22
|
+
* fence languages, shortcode-expanded `div`s and Reddit's `reddit-embed-bq`
|
|
23
|
+
* blockquote, and delegates everything else here. Previously it reproduced
|
|
24
|
+
* these renderers byte-for-byte, so any class change here silently drifted
|
|
25
|
+
* on content surfaces.
|
|
26
|
+
*
|
|
27
|
+
* THESE MUST STAY HOOK-FREE: the rich composition calls them as plain
|
|
28
|
+
* functions from inside its own renderers (`standard.code(props)`), which is
|
|
29
|
+
* not a React render of a component and would break the rules of hooks.
|
|
30
|
+
* Hook-using renderers (the headings, which read the heading-line offset
|
|
31
|
+
* from context) live in `buildBaseComponents` below and are never delegated
|
|
32
|
+
* to this way.
|
|
33
|
+
*
|
|
34
|
+
* ODS-TOKENS FLAG (ODS_TOKEN_RULES §Typography / §General): inline code keeps
|
|
35
|
+
* an inline `text-[0.9em]`, carried over verbatim from the pre-unification
|
|
36
|
+
* renderers — ODS has no relative-to-parent code size, so mapping it onto an
|
|
37
|
+
* existing token would visibly change every inline code span. Same shape as
|
|
38
|
+
* the flag in ./text-size.ts — flagged for addition to ODS, not copied
|
|
39
|
+
* anywhere else.
|
|
40
|
+
*
|
|
41
|
+
* The code BLOCK's font is NOT flagged: the raw "JetBrains Mono", "SF Mono",
|
|
42
|
+
* Consolas stack the old renderer inlined is gone, replaced by Tailwind's
|
|
43
|
+
* `font-mono` (→ `var(--font-family-heading)`, the Azeret Mono ODS stack) —
|
|
44
|
+
* the same class the inline-code branch below already used, so the two code
|
|
45
|
+
* surfaces no longer disagree about their family.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildStandardLeafRenderers({ textSizes, }: {
|
|
48
|
+
textSizes: Record<TextSizeElement, string>;
|
|
49
|
+
}): Pick<Components, 'code' | 'blockquote' | 'div'>;
|
|
50
|
+
export declare function buildBaseComponents({ textSizes, demoteMarkdownH1ToH2, brokenLinks, currentPath: propCurrentPath, onInternalLinkClick, onResolveLink, }: BuildBaseComponentsOptions): Components;
|
|
51
|
+
//# sourceMappingURL=base-components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-components.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/base-components.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA4CnD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAE5D;AAED,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC3C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/G,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACnF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,SAAS,GACV,EAAE;IACD,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;CAC5C,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,KAAK,CAAC,CA4DlD;AAED,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,oBAAoB,EACpB,WAAW,EACX,WAAW,EAAE,eAAe,EAC5B,mBAAmB,EACnB,aAAa,GACd,EAAE,0BAA0B,GAAG,UAAU,CAwLzC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MarkdownEngine — THE one react-markdown pipeline for every surface
|
|
3
|
+
* (chat messages, blog, docs, KB articles, legal, releases, admin previews).
|
|
4
|
+
*
|
|
5
|
+
* `SimpleMarkdownRenderer` and `RichMarkdownRenderer` are thin compositions
|
|
6
|
+
* over this engine (see ./simple-markdown-renderer.tsx and ./rich/) — there
|
|
7
|
+
* is exactly ONE parse path, ONE sanitizer stack, ONE mermaid, ONE
|
|
8
|
+
* heading-id algorithm, ONE link-click model. Do not fork this pipeline;
|
|
9
|
+
* extend via `componentOverrides` / `additionalRemarkPlugins` /
|
|
10
|
+
* `preprocessContent` / `extraAllowedHtmlTags`.
|
|
11
|
+
*
|
|
12
|
+
* Pipeline order (each stage documented in ./sanitize.ts):
|
|
13
|
+
* preprocessContent (composition hook, e.g. shortcodes)
|
|
14
|
+
* → completeStreamingTail (streaming only — MUST precede the escape pass)
|
|
15
|
+
* → escapeUnknownHtmlTags (text pre-pass, React 19 crash guard)
|
|
16
|
+
* → remark: remarkGfm, remarkBreaks, ...additionalRemarkPlugins
|
|
17
|
+
* → rehype: rehypeRaw → rehypeSanitize(schema) → rehypeStripUnsafe
|
|
18
|
+
* → rehypeHighlight
|
|
19
|
+
* → urlTransform: cardAwareUrlTransform
|
|
20
|
+
* → components: buildBaseComponents(...) spread-last componentOverrides
|
|
21
|
+
*/
|
|
22
|
+
import React from 'react';
|
|
23
|
+
import { type Components } from 'react-markdown';
|
|
24
|
+
import type { PluggableList } from 'unified';
|
|
25
|
+
import type { ResolveLinkResult } from '../../../types/doc-source';
|
|
26
|
+
import { type TextSizeConfig } from './text-size';
|
|
27
|
+
import { type HeadingSection } from './heading-ids';
|
|
28
|
+
export type { ResolveLinkResult };
|
|
29
|
+
/**
|
|
30
|
+
* Module-scope empty default for `brokenLinks`.
|
|
31
|
+
*
|
|
32
|
+
* A `brokenLinks = []` DEFAULT PARAMETER allocates a fresh array on every
|
|
33
|
+
* render, so the `components` useMemo (which lists it as a dep) recomputed
|
|
34
|
+
* every render, which changed `StreamingBlockRenderer`'s `components` prop
|
|
35
|
+
* identity, which made its `memo` bail EVERY time — every completed block
|
|
36
|
+
* re-parsed on every streamed token, defeating the entire atomic-block
|
|
37
|
+
* optimization. Any new default that is an object/array/function MUST be
|
|
38
|
+
* hoisted here for the same reason.
|
|
39
|
+
*
|
|
40
|
+
* Exported so the compositions that apply the SAME default before handing
|
|
41
|
+
* props down (rich) share this ONE identity instead of declaring a second
|
|
42
|
+
* module-scope empty array with a copy of this rationale. Deliberately NOT
|
|
43
|
+
* re-exported from ./index — it is an internal identity contract between the
|
|
44
|
+
* engine and its compositions, not public API.
|
|
45
|
+
*/
|
|
46
|
+
export declare const NO_BROKEN_LINKS: readonly string[];
|
|
47
|
+
export interface MarkdownEngineProps {
|
|
48
|
+
content: string;
|
|
49
|
+
className?: string;
|
|
50
|
+
/** Backend-provided heading IDs for deep-link anchors */
|
|
51
|
+
sectionIds?: HeadingSection[];
|
|
52
|
+
/** When the page already has an H1, render markdown `#` as `<h2>` */
|
|
53
|
+
demoteMarkdownH1ToH2?: boolean;
|
|
54
|
+
/** List of broken link hrefs detected server-side (shown with [BROKEN] badge) */
|
|
55
|
+
brokenLinks?: readonly string[];
|
|
56
|
+
/** Callback for internal (non-http, non-anchor) link clicks */
|
|
57
|
+
onInternalLinkClick?: (path: string, options?: {
|
|
58
|
+
expandFolder?: boolean;
|
|
59
|
+
fromInternalLink?: boolean;
|
|
60
|
+
}) => void;
|
|
61
|
+
/** Current documentation path — enables internal-link mode when set */
|
|
62
|
+
currentPath?: string;
|
|
63
|
+
/** Resolve an internal link href to a navigation path. */
|
|
64
|
+
onResolveLink?: (href: string, currentPath: string) => Promise<ResolveLinkResult>;
|
|
65
|
+
/** Pre-process the raw markdown string before rendering (e.g. shortcode expansion) */
|
|
66
|
+
preprocessContent?: (content: string) => string;
|
|
67
|
+
/** Merge additional or override react-markdown component renderers (spread LAST — caller wins) */
|
|
68
|
+
componentOverrides?: Partial<Components>;
|
|
69
|
+
/** Extra remark plugins appended after the built-in remarkGfm + remarkBreaks */
|
|
70
|
+
additionalRemarkPlugins?: PluggableList;
|
|
71
|
+
/** Text sizing preset / per-element overrides */
|
|
72
|
+
textSize?: TextSizeConfig;
|
|
73
|
+
/**
|
|
74
|
+
* Extra raw-HTML tags this composition admits. Unioned into BOTH the
|
|
75
|
+
* text pre-pass allowlist AND the sanitize schema together (the
|
|
76
|
+
* coupled-allowlist invariant — see ./sanitize.ts).
|
|
77
|
+
*/
|
|
78
|
+
extraAllowedHtmlTags?: string[];
|
|
79
|
+
/**
|
|
80
|
+
* Set true for the actively streaming message ONLY. Enables atomic-block
|
|
81
|
+
* memoization + fence tail-completion + an aria-live wrapper. The caller
|
|
82
|
+
* MUST flip back to false on completion — that final render is one
|
|
83
|
+
* authoritative whole-document parse (block cache discarded), so
|
|
84
|
+
* streaming can never permanently diverge from the settled output.
|
|
85
|
+
*/
|
|
86
|
+
streaming?: boolean;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Memoized so a parent re-render with UNCHANGED props (same `content`
|
|
90
|
+
* string, same memoized `componentOverrides`/plugins) does NOT re-parse the
|
|
91
|
+
* markdown. Re-parsing rebuilds the entire react-markdown subtree, which
|
|
92
|
+
* RE-MOUNTS any embedded inline entity cards — closing their open menus and
|
|
93
|
+
* re-triggering their fetch on every chat re-render (streaming chunk AND
|
|
94
|
+
* scroll). With stable props the renderer bails, so completed messages'
|
|
95
|
+
* cards stay mounted. The streaming path additionally memoizes completed
|
|
96
|
+
* atomic blocks so the in-flight message re-parses only its live tail.
|
|
97
|
+
*/
|
|
98
|
+
export declare const MarkdownEngine: React.NamedExoticComponent<MarkdownEngineProps>;
|
|
99
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/engine.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAwB,MAAM,OAAO,CAAC;AAC7C,OAAsB,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAQnE,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAIvB,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAAO,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,qEAAqE;IACrE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iFAAiF;IACjF,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC/G,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClF,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,kGAAkG;IAClG,kBAAkB,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACzC,gFAAgF;IAChF,uBAAuB,CAAC,EAAE,aAAa,CAAC;IACxC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAqMD;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,iDAA2B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export interface HeadingSection {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
level: number;
|
|
5
|
+
}
|
|
6
|
+
/** `line (1-based, document-wide) → heading id`. */
|
|
7
|
+
export type HeadingIdMap = ReadonlyMap<number, string>;
|
|
8
|
+
/**
|
|
9
|
+
* Line offset added to unit-relative hast positions. Non-zero only on the
|
|
10
|
+
* streaming path, where each atomic unit is parsed by its own
|
|
11
|
+
* `ReactMarkdown` (see `StreamingBlock.startLine`).
|
|
12
|
+
*/
|
|
13
|
+
export declare const HeadingLineOffsetContext: import("react").Context<number>;
|
|
14
|
+
/**
|
|
15
|
+
* The document's heading-id map, delivered by CONTEXT rather than baked into
|
|
16
|
+
* the react-markdown `components` map on purpose: the map is rebuilt on every
|
|
17
|
+
* streamed token (its input is the growing `processedContent`), so listing it
|
|
18
|
+
* as a `components` memo dep would change that map's identity each token and
|
|
19
|
+
* make every completed streaming block's `memo` bail — the exact regression
|
|
20
|
+
* `NO_BROKEN_LINKS` was introduced to fix. Through context only the heading
|
|
21
|
+
* renderers re-render.
|
|
22
|
+
*/
|
|
23
|
+
export declare const HeadingIdMapContext: import("react").Context<HeadingIdMap>;
|
|
24
|
+
/** Look up the pre-computed id for a heading hast node. Pure. */
|
|
25
|
+
export declare function useHeadingId(node: any): string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Build the document's `line → id` map. Pure: same content + same
|
|
28
|
+
* `sectionIds` always yields the same map.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildHeadingIdMap(content: string, sectionIds?: HeadingSection[]): HeadingIdMap;
|
|
31
|
+
/**
|
|
32
|
+
* Memoized `buildHeadingIdMap` for the engine, with the map's IDENTITY held
|
|
33
|
+
* stable across content changes that don't touch any heading.
|
|
34
|
+
*
|
|
35
|
+
* `content` changes on every streamed token, so the `useMemo` alone rebuilt
|
|
36
|
+
* a fresh `Map` per token; that map is the context value, so EVERY heading
|
|
37
|
+
* consumer in every already-completed block re-rendered on every token —
|
|
38
|
+
* the same identity-churn class `NO_BROKEN_LINKS` exists to prevent, just
|
|
39
|
+
* one layer down. Rebuilding is cheap; re-rendering the consumers is not, so
|
|
40
|
+
* the newly built map is compared to the previous one and the previous
|
|
41
|
+
* object is returned when the entries match.
|
|
42
|
+
*/
|
|
43
|
+
export declare function useHeadingIdMap(content: string, sectionIds?: HeadingSection[]): HeadingIdMap;
|
|
44
|
+
/**
|
|
45
|
+
* Fallback id for a heading the source scan could NOT see — in practice only
|
|
46
|
+
* a heading synthesized by a caller remark/rehype plugin, which carries no
|
|
47
|
+
* source position. (Setext, blockquote/list-nested ATX and multiple raw
|
|
48
|
+
* `<hN>`s on one line are all scanned now, so they no longer land here.)
|
|
49
|
+
*
|
|
50
|
+
* Routed through the SAME dedupe shape as the map so a fallback id can never
|
|
51
|
+
* collide with an assigned one. It stays PURE — `taken` is derived from the
|
|
52
|
+
* map, not from render order — which is why two position-less headings with
|
|
53
|
+
* IDENTICAL text still collide with each other: disambiguating those would
|
|
54
|
+
* require the shared mutable counter this module deleted.
|
|
55
|
+
*/
|
|
56
|
+
export declare function resolveFallbackHeadingId(base: string, taken: ReadonlySet<string>): string;
|
|
57
|
+
/**
|
|
58
|
+
* The ids already assigned by the document's heading-id map. Cached per map
|
|
59
|
+
* IDENTITY, which `useHeadingIdMap` now keeps stable across heading-free
|
|
60
|
+
* token growth — so this is O(headings) once, not per heading per token.
|
|
61
|
+
*/
|
|
62
|
+
export declare function useAssignedHeadingIds(): ReadonlySet<string>;
|
|
63
|
+
/** Extract plain text from React children (headings receive mixed nodes). */
|
|
64
|
+
export declare function extractText(node: any): string;
|
|
65
|
+
//# sourceMappingURL=heading-ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading-ids.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/heading-ids.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,oDAAoD;AACpD,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAUtD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,iCAAmB,CAAA;AAIxD;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,uCAAiD,CAAA;AAEjF,iEAAiE;AAEjE,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAK1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,cAAc,EAAE,GAC5B,YAAY,CAoEd;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,cAAc,EAAE,GAC5B,YAAY,CAQd;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAMzF;AAKD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,CAAC,MAAM,CAAC,CAO3D;AAED,6EAA6E;AAE7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAK7C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified markdown module — public surface.
|
|
3
|
+
*
|
|
4
|
+
* ONE engine (`MarkdownEngine`), two named compositions:
|
|
5
|
+
* - `SimpleMarkdownRenderer` — chat/doc surfaces (embed-free bundle)
|
|
6
|
+
* - `RichMarkdownRenderer` — authored-content surfaces (shortcodes,
|
|
7
|
+
* social embeds, Video SSOT, OG previews)
|
|
8
|
+
*/
|
|
9
|
+
export { MarkdownEngine, type MarkdownEngineProps } from './engine';
|
|
10
|
+
export { SimpleMarkdownRenderer, type SimpleMarkdownRendererProps, type ResolveLinkResult, } from './simple-markdown-renderer';
|
|
11
|
+
export { RichMarkdownRenderer, type RichMarkdownRendererProps, } from './rich/rich-markdown-renderer';
|
|
12
|
+
export { processShortcodes } from './rich/shortcodes';
|
|
13
|
+
export { SAFE_HTML_TAGS, SVG_TAGS, buildEffectiveTagSet, buildSanitizeSchema, cardAwareUrlTransform, escapeUnknownHtmlTags, rehypeStripUnsafe, } from './sanitize';
|
|
14
|
+
export { TEXT_SIZE_PRESETS, resolveTextSizeConfig, type TextSizeConfig, type TextSizeClassMap, type TextSizeElement, type TextSizePreset, } from './text-size';
|
|
15
|
+
export { MermaidDiagram } from './mermaid-diagram';
|
|
16
|
+
export { buildHeadingIdMap, useHeadingIdMap, extractText, type HeadingSection, type HeadingIdMap, } from './heading-ids';
|
|
17
|
+
export { splitStreamingBlocks, completeStreamingTail, type StreamingBlock } from './streaming';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EACL,sBAAsB,EACtB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,EACpB,KAAK,yBAAyB,GAC/B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EACL,cAAc,EACd,QAAQ,EACR,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,YAAY,GAClB,MAAM,eAAe,CAAC;AAKvB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single MermaidDiagram for the unified markdown engine (dark theme only —
|
|
3
|
+
* the old RichMarkdownRenderer's light-theme branch was dead code behind a
|
|
4
|
+
* hardcoded `isDarkMode = true` and is deleted, not carried over).
|
|
5
|
+
*
|
|
6
|
+
* `mermaid` stays a dynamic import so neither chat nor content bundles pay
|
|
7
|
+
* for it unless a diagram is actually rendered.
|
|
8
|
+
*/
|
|
9
|
+
import React from 'react';
|
|
10
|
+
/**
|
|
11
|
+
* SECURITY SSOT for the mermaid renderer — the ONLY place these knobs are
|
|
12
|
+
* written. `./__tests__/mermaid-security.test.ts` imports THIS constant and
|
|
13
|
+
* spreads it into its own `mermaid.initialize`, so the fixture and the
|
|
14
|
+
* component can no longer drift: flipping `securityLevel` to `'loose'` here
|
|
15
|
+
* fails the suite (verified by doing exactly that).
|
|
16
|
+
*
|
|
17
|
+
* This renderer sits on the CHAT path, so the diagram source is MODEL output
|
|
18
|
+
* — untrusted by construction — and the rendered SVG goes through
|
|
19
|
+
* `dangerouslySetInnerHTML`. The pre-unification renderer used `'loose'`,
|
|
20
|
+
* which permits raw HTML inside labels and enables mermaid's `click`
|
|
21
|
+
* interaction directive: a node label like `A["<img src=x onerror=...>"]`
|
|
22
|
+
* would have produced LIVE HTML.
|
|
23
|
+
*
|
|
24
|
+
* - `securityLevel: 'strict'` encodes HTML tags in text and disables click
|
|
25
|
+
* handlers.
|
|
26
|
+
* - `htmlLabels: false` renders labels as SVG `<text>` instead of a
|
|
27
|
+
* foreignObject HTML subtree, so there is no HTML surface at all. Verified:
|
|
28
|
+
* no authored diagram in this repo or in the consuming hub's markdown uses
|
|
29
|
+
* HTML labels (not even `<br/>`), so 'antiscript' (which still allows tags)
|
|
30
|
+
* is not needed. (`htmlLabels` is set at the ROOT — `flowchart.htmlLabels`
|
|
31
|
+
* is deprecated in mermaid 11 and the root value takes precedence.)
|
|
32
|
+
* - `secure` is the allowlist of config keys a `%%{init}%%` directive in the
|
|
33
|
+
* diagram SOURCE may NOT override. mermaid's default list covers
|
|
34
|
+
* `securityLevel` but NOT `htmlLabels`, so model-authored source could
|
|
35
|
+
* otherwise re-enable HTML labels while `securityLevel` stayed locked.
|
|
36
|
+
* Adding `htmlLabels` (plus `secure` itself and the resource limits) closes
|
|
37
|
+
* that hole.
|
|
38
|
+
*
|
|
39
|
+
* jsdom NOTE: with `htmlLabels` unlocked, a `%%{init: {"htmlLabels": true}}%%`
|
|
40
|
+
* directive was observed to make `mermaid.render` never settle under jsdom
|
|
41
|
+
* (>60s, against a passing two-render control). This was NOT reproduced in a
|
|
42
|
+
* real browser and may well be an artifact of jsdom having no layout — do not
|
|
43
|
+
* read it as a confirmed browser DoS. Either way the render below is wrapped
|
|
44
|
+
* in a timeout so a non-settling render surfaces the error state instead of
|
|
45
|
+
* sitting on "Rendering diagram…" forever.
|
|
46
|
+
*/
|
|
47
|
+
export declare const MERMAID_SECURITY_OPTIONS: {
|
|
48
|
+
htmlLabels: false;
|
|
49
|
+
securityLevel: "strict";
|
|
50
|
+
secure: string[];
|
|
51
|
+
};
|
|
52
|
+
/** Upper bound on a single `mermaid.render`. Generous enough that no honest
|
|
53
|
+
* diagram hits it; short enough that a wedged render becomes a visible error
|
|
54
|
+
* instead of a permanent skeleton. */
|
|
55
|
+
export declare const MERMAID_RENDER_TIMEOUT_MS = 15000;
|
|
56
|
+
/**
|
|
57
|
+
* ODS-TOKENS FLAG (ODS_TOKEN_RULES §Colors / §Typography / §General):
|
|
58
|
+
* `mermaidStyles` below and the `themeVariables` / `fontFamily` / `fontSize`
|
|
59
|
+
* block in `MermaidDiagram` carry RAW hex colors, a literal font-family and
|
|
60
|
+
* literal px font sizes.
|
|
61
|
+
*
|
|
62
|
+
* Reason: mermaid's configuration is not CSS — `themeVariables` is a
|
|
63
|
+
* JavaScript API whose values are baked into the generated SVG as literal
|
|
64
|
+
* attribute strings, so a `var(--color-…)` reference resolves to nothing
|
|
65
|
+
* there. On top of that, ODS has NO 10-step categorical color ramp, and
|
|
66
|
+
* mermaid's `cScale0…cScale9` requires exactly one. The palette is carried
|
|
67
|
+
* over VERBATIM from the pre-unification RichMarkdownRenderer, so this is
|
|
68
|
+
* parity, not new divergence; the missing categorical-ramp tokens are
|
|
69
|
+
* flagged here for addition to ODS.
|
|
70
|
+
*
|
|
71
|
+
* Scope: this exemption covers THIS file only, and only the mermaid config
|
|
72
|
+
* surface. Do NOT copy this pattern — every other style in the markdown
|
|
73
|
+
* module uses ODS semantic classes.
|
|
74
|
+
*/
|
|
75
|
+
export declare const mermaidStyles = "\n .mermaid-svg-container svg {\n max-width: 100% !important;\n height: auto !important;\n min-height: 200px;\n font-family: 'DM Sans', sans-serif !important;\n font-size: 14px !important;\n }\n @media (min-width: 1520px) {\n .mermaid-svg-container svg {\n max-width: 900px !important;\n max-height: 700px !important;\n min-height: 300px;\n font-size: 16px !important;\n }\n }\n @media (min-width: 768px) and (max-width: 1519px) {\n .mermaid-svg-container svg {\n max-width: 700px !important;\n max-height: 600px !important;\n min-height: 250px;\n font-size: 15px !important;\n }\n }\n @media (max-width: 767px) {\n .mermaid-svg-container svg {\n max-width: 90vw !important;\n max-height: 400px !important;\n min-height: 200px;\n font-size: 13px !important;\n }\n }\n .mermaid-svg-container svg[width] { width: 100% !important; }\n .mermaid-svg-container .node rect,\n .mermaid-svg-container .node circle,\n .mermaid-svg-container .node ellipse,\n .mermaid-svg-container .node polygon { stroke-width: 2px !important; }\n .mermaid-svg-container .edgePath path { stroke-width: 2px !important; }\n @media (min-width: 768px) {\n .mermaid-svg-container .node text,\n .mermaid-svg-container .edgeLabel text { font-size: 14px !important; }\n }\n @media (min-width: 1520px) {\n .mermaid-svg-container .node text,\n .mermaid-svg-container .edgeLabel text { font-size: 16px !important; }\n }\n";
|
|
76
|
+
export declare const MermaidDiagram: React.FC<{
|
|
77
|
+
chart: string;
|
|
78
|
+
}>;
|
|
79
|
+
//# sourceMappingURL=mermaid-diagram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid-diagram.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/mermaid-diagram.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,wBAAwB;;;;CA6BqC,CAAC;AAE3E;;uCAEuC;AACvC,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAkBhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,aAAa,u+CA8CzB,CAAC;AAQF,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAkJtD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Components } from 'react-markdown';
|
|
2
|
+
import type { TextSizeElement } from '../text-size';
|
|
3
|
+
export interface BuildRichEmbedOverridesOptions {
|
|
4
|
+
ogApiBaseUrl: string;
|
|
5
|
+
ogEndpointPath: string;
|
|
6
|
+
textSizes: Record<TextSizeElement, string>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Overrides spread LAST onto the engine's base map: `code` (fence-language
|
|
10
|
+
* embeds), `div` (shortcode-expanded embeds), `img` (MarkdownImage with
|
|
11
|
+
* runtime transformImageSrc), `video` (raw tags → Video SSOT).
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildRichEmbedOverrides({ ogApiBaseUrl, ogEndpointPath, textSizes, }: BuildRichEmbedOverridesOptions): Partial<Components>;
|
|
14
|
+
//# sourceMappingURL=embed-overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed-overrides.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/markdown/rich/embed-overrides.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AASjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAiBpD,MAAM,WAAW,8BAA8B;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,YAAY,EACZ,cAAc,EACd,SAAS,GACV,EAAE,8BAA8B,GAAG,OAAO,CAAC,UAAU,CAAC,CAiJtD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RichMarkdownRenderer — the content composition over the unified
|
|
3
|
+
* `MarkdownEngine`: RuntimeProvider + shortcodes + embed overrides +
|
|
4
|
+
* fetch-based internal-link resolver + `article` typography.
|
|
5
|
+
*
|
|
6
|
+
* This IS the real component (the old 1223-line standalone implementation
|
|
7
|
+
* was deleted in the unification). Public prop surface is unchanged, so
|
|
8
|
+
* every hub/app call site compiles untouched. Deltas vs the old
|
|
9
|
+
* implementation are the ones reviewed in the unification plan: the
|
|
10
|
+
* sanitize stack + tag-escape pre-pass now apply to content surfaces
|
|
11
|
+
* (`extraAllowedHtmlTags={['video','source']}` keeps authored video
|
|
12
|
+
* working), the engine is memoized, and the dead light-mode branches are
|
|
13
|
+
* gone.
|
|
14
|
+
*/
|
|
15
|
+
import React from 'react';
|
|
16
|
+
import { type MarkdownEngineProps } from '../engine';
|
|
17
|
+
import { type RichMarkdownRuntime } from '../../../embeds/rich-markdown-runtime';
|
|
18
|
+
/**
|
|
19
|
+
* The engine props this composition OWNS and therefore does not forward:
|
|
20
|
+
* shortcode preprocessing, the embed component map, the `article` text
|
|
21
|
+
* preset, the fetch link resolver, the rich tag allowlist, and streaming
|
|
22
|
+
* (authored content is never streamed).
|
|
23
|
+
*/
|
|
24
|
+
type RichOwnedEngineProps = 'extraAllowedHtmlTags' | 'preprocessContent' | 'componentOverrides' | 'textSize' | 'onResolveLink' | 'additionalRemarkPlugins' | 'streaming';
|
|
25
|
+
/**
|
|
26
|
+
* Derived from `MarkdownEngineProps` rather than hand-copied. The previous
|
|
27
|
+
* shape restated 7 engine props here and a THIRD time in `InnerProps`, so
|
|
28
|
+
* every engine prop doc/type change had to be mirrored in three places (and
|
|
29
|
+
* a missed mirror type-checks fine while silently dropping the prop).
|
|
30
|
+
*/
|
|
31
|
+
export interface RichMarkdownRendererProps extends Partial<RichMarkdownRuntime>, Omit<MarkdownEngineProps, RichOwnedEngineProps> {
|
|
32
|
+
/** Source for resolving internal links (default: 'openframe-docs'). Registry id from DOC_SOURCES. */
|
|
33
|
+
resolveSource?: string;
|
|
34
|
+
/** Path of the internal link-resolver endpoint. Default '/api/docs/resolve-link'. */
|
|
35
|
+
resolveLinkEndpointUrl?: string;
|
|
36
|
+
}
|
|
37
|
+
/** Memoized — see the engine's memo rationale. */
|
|
38
|
+
export declare const RichMarkdownRenderer: React.NamedExoticComponent<RichMarkdownRendererProps>;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=rich-markdown-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-markdown-renderer.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/markdown/rich/rich-markdown-renderer.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAqC,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAmC,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEtF,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAQ/C;;;;;GAKG;AACH,KAAK,oBAAoB,GACrB,sBAAsB,GACtB,mBAAmB,GACnB,oBAAoB,GACpB,UAAU,GACV,eAAe,GACf,yBAAyB,GACzB,WAAW,CAAC;AAEhB;;;;;GAKG;AACH,MAAM,WAAW,yBACf,SAAQ,OAAO,CAAC,mBAAmB,CAAC,EAClC,IAAI,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;IACjD,qGAAqG;IACrG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AA0HD,kDAAkD;AAClD,eAAO,MAAM,oBAAoB,uDAAiC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shortcode + auto-URL-embed preprocessing for the rich (content)
|
|
3
|
+
* composition. Moved verbatim from the old RichMarkdownRenderer — the
|
|
4
|
+
* `{{youtube:...}}` / `{% youtube %}` / thumbnail-link / auto-URL grammar
|
|
5
|
+
* is authored-content SSOT; chat surfaces never run this.
|
|
6
|
+
*/
|
|
7
|
+
export declare const processShortcodes: (content: string) => string;
|
|
8
|
+
//# sourceMappingURL=shortcodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcodes.d.ts","sourceRoot":"","sources":["../../../../../src/components/ui/markdown/rich/shortcodes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,KAAG,MAkKnD,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tags the TEXT pre-pass forwards as raw HTML. Anything outside this set
|
|
3
|
+
* (plus per-composition `extraAllowedHtmlTags`) gets its angle brackets
|
|
4
|
+
* escaped and renders as plain text.
|
|
5
|
+
*
|
|
6
|
+
* `video` is deliberately NOT in the baseline: chat strips <video>
|
|
7
|
+
* server-side and playback goes through the <Video> SSOT. The rich
|
|
8
|
+
* composition opts back in via `extraAllowedHtmlTags={['video', 'source']}`
|
|
9
|
+
* so authored content (blog publisher video injection) keeps working.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SAFE_HTML_TAGS: Set<string>;
|
|
12
|
+
/**
|
|
13
|
+
* Inline SVG element set, in the CANONICAL case parse5 produces for SVG
|
|
14
|
+
* foreign content (`linearGradient`, `clipPath`, … are camelCase in the
|
|
15
|
+
* HTML parser's SVG adjustment table, so the sanitize schema must match
|
|
16
|
+
* that spelling; the text pre-pass lowercases before lookup).
|
|
17
|
+
*
|
|
18
|
+
* Inline `<svg>` renders in real published posts (hand-authored diagrams
|
|
19
|
+
* and inline icon markup — NOT `<use href>` sprite references, which are
|
|
20
|
+
* deliberately dropped; see SVG_ATTRIBUTES). The Rich renderer had NO pre-pass
|
|
21
|
+
* and NO sanitizer, so it always rendered; without this set the unified
|
|
22
|
+
* engine would escape it to visible source text.
|
|
23
|
+
*
|
|
24
|
+
* SEVERAL OF THESE NAMES ARE ALSO HTML ELEMENTS (`title`, `desc`, `text`,
|
|
25
|
+
* `g`, `line`, `use`, `symbol`, `marker`, `mask`, `pattern`) — admitting
|
|
26
|
+
* them UNCONSTRAINED let a post or a chat message emit a bare `<title>`,
|
|
27
|
+
* which React 19 hoists into `<head>` (browser-tab + SEO title hijack) and
|
|
28
|
+
* whose RAWTEXT content model swallows the rest of the document when
|
|
29
|
+
* unclosed. They are therefore pinned to an `svg` ancestor in
|
|
30
|
+
* `SVG_ONLY_ANCESTORS` below; outside `<svg>` the sanitizer drops them.
|
|
31
|
+
*/
|
|
32
|
+
export declare const SVG_TAGS: Set<string>;
|
|
33
|
+
/** Effective pre-pass tag set for a composition (lowercased for lookup). */
|
|
34
|
+
export declare function buildEffectiveTagSet(extraAllowedHtmlTags?: string[]): Set<string>;
|
|
35
|
+
export interface BuildSanitizeSchemaOptions {
|
|
36
|
+
extraAllowedHtmlTags?: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The engine's sanitize schema: defaultSchema ∪ SAFE_HTML_TAGS ∪ extras.
|
|
40
|
+
* - `extraAllowedHtmlTags` is unioned into tagNames here AND into the
|
|
41
|
+
* pre-pass set (buildEffectiveTagSet) — the coupled-allowlist invariant.
|
|
42
|
+
* - `clobberPrefix: ''` + empty `clobber`: authored raw-HTML anchors
|
|
43
|
+
* (`<h2 id="…">`) keep their ids so `[jump](#anchor)` deep-links work.
|
|
44
|
+
* (The renderer's own heading ids are injected at the React layer,
|
|
45
|
+
* post-rehype, and were never affected.)
|
|
46
|
+
* - `card`/`mention` protocols registered for href so chat markers survive
|
|
47
|
+
* (the urlTransform below is the second gate).
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildSanitizeSchema(options?: BuildSanitizeSchemaOptions): {
|
|
50
|
+
tagNames: string[];
|
|
51
|
+
attributes: Record<string, (string | [string, ...unknown[]])[]>;
|
|
52
|
+
ancestors: Record<string, string[]>;
|
|
53
|
+
required: Record<string, Record<string, unknown>>;
|
|
54
|
+
clobberPrefix: string;
|
|
55
|
+
clobber: never[];
|
|
56
|
+
protocols: {
|
|
57
|
+
href: string[];
|
|
58
|
+
};
|
|
59
|
+
allowComments?: boolean | null | undefined;
|
|
60
|
+
allowDoctypes?: boolean | null | undefined;
|
|
61
|
+
strip?: Array<string> | null | undefined;
|
|
62
|
+
};
|
|
63
|
+
export declare function rehypeStripUnsafe(): (tree: any) => void;
|
|
64
|
+
/**
|
|
65
|
+
* PARAGRAPH SEGMENTS, NOT LINES (round 18 — SECURITY). A CommonMark code span
|
|
66
|
+
* CROSSES LINE BREAKS: `` `foo\n</textarea>` `` is one `inlineCode` node, so
|
|
67
|
+
* that `</textarea>` is a code sample and not a closer — yet this scan (and
|
|
68
|
+
* `PROTECTED_SPAN_RE`, whose body class is `[^\n]`) was strictly PER LINE, so
|
|
69
|
+
* the mask never saw the span, the closer stayed visible in the haystack,
|
|
70
|
+
* `hasLaterCloser` returned true, and a prose `<textarea>` above it stayed LIVE
|
|
71
|
+
* (`escapeUnknownHtmlTags` returned the input BYTE-IDENTICAL; the renderer
|
|
72
|
+
* emitted `<code>foo </textarea></code>` — proving the closer is a code sample
|
|
73
|
+
* — beside a live textarea swallowing the prose). This is the shape that is not
|
|
74
|
+
* a CONTAINER at all, so no container sweep could ever have reached it.
|
|
75
|
+
*
|
|
76
|
+
* A code span CANNOT cross a paragraph break, so the scan unit is a maximal run
|
|
77
|
+
* of non-blank lines. Blank lines still terminate a segment, which keeps the
|
|
78
|
+
* fail-CLOSED direction (an unterminated opener consumes at most its own
|
|
79
|
+
* paragraph, never the rest of the document) and keeps the bound linear — the
|
|
80
|
+
* `suffMax` / cursor structure is unchanged, `\n` is simply an ordinary
|
|
81
|
+
* character inside a segment.
|
|
82
|
+
*
|
|
83
|
+
* `PROTECTED_SPAN_RE` (the CARVE) is deliberately left per-line: it rounds the
|
|
84
|
+
* other way, so at worst a multi-line code sample renders as escaped text.
|
|
85
|
+
*/
|
|
86
|
+
declare function findInlineCodeRanges(source: string): Array<[number, number]>;
|
|
87
|
+
/** Exported for the differential fuzz against the retired regex. */
|
|
88
|
+
export declare const __findInlineCodeRangesForTest: typeof findInlineCodeRanges;
|
|
89
|
+
/**
|
|
90
|
+
* Build the haystack `hasLaterCloser` searches: a LENGTH-PRESERVING lowercased
|
|
91
|
+
* copy of the document with every region that cannot contain a REAL closing
|
|
92
|
+
* tag blanked to spaces.
|
|
93
|
+
*
|
|
94
|
+
* Why this exists: the escaping pass carefully carves code out, but the
|
|
95
|
+
* closer search used to run over the RAW document. So a `</textarea>` sitting
|
|
96
|
+
* inside a code fence, an inline-code span, or another tag's attribute string
|
|
97
|
+
* satisfied "is closed later", the prose opener was left LIVE, and parse5's
|
|
98
|
+
* RAWTEXT span swallowed the rest of the message anyway — the whole fix was
|
|
99
|
+
* one code sample away from being bypassed, which is exactly what an LLM
|
|
100
|
+
* answer about HTML looks like.
|
|
101
|
+
*
|
|
102
|
+
* Masking (rather than deleting) keeps every index identical to the original
|
|
103
|
+
* string, so the caller's offset arithmetic is unchanged. THE LENGTH
|
|
104
|
+
* INVARIANT IS LOAD-BEARING — see `foldAsciiCase`.
|
|
105
|
+
*
|
|
106
|
+
* CARVE DECISION (deliberate, do not "unify"): these tracker-derived regions
|
|
107
|
+
* are NOT fed to the escaping carve, even though that would stop an authored
|
|
108
|
+
* EOF-terminated fence body from rendering as literal `<their>`.
|
|
109
|
+
*
|
|
110
|
+
* The genuine asymmetry is the EOF-TERMINATED fence, and only that one. The
|
|
111
|
+
* tracker protects an unclosed opener all the way to end of input, so a single
|
|
112
|
+
* stray ``` line — mid-stream, or inside an open raw-HTML block where a ```
|
|
113
|
+
* line is content rather than a fence — would carve the ENTIRE remainder of the
|
|
114
|
+
* document out of the escaping pass. `PROTECTED_SPAN_RE` protects nothing at
|
|
115
|
+
* all there (it only recognizes a fence CLOSED by a same-marker run), so its
|
|
116
|
+
* failure mode is bounded: a code sample renders as escaped text. In the carve
|
|
117
|
+
* an over-detected region is a region that is NOT escaped — a fail-OPEN, i.e.
|
|
118
|
+
* exactly the swallow this module exists to prevent — so the materially larger
|
|
119
|
+
* fail-open surface decides it.
|
|
120
|
+
*
|
|
121
|
+
* SHARED over-detection (e.g. a ``` line inside an HTML block — `<div>`,
|
|
122
|
+
* `<pre>`, `<details>` — where CommonMark says the line is HTML content, not a
|
|
123
|
+
* fence) was previously dismissed here as "not an argument either way". THAT
|
|
124
|
+
* WAS WRONG: it is precisely the residual fail-open. The intersection guard
|
|
125
|
+
* below only reconciles DISAGREEMENT, so when BOTH engines open the same bogus
|
|
126
|
+
* fence the guard is a no-op and a live `<textarea>` inside it is pushed
|
|
127
|
+
* verbatim, swallowing the rest of the message (reproduced for all three tags).
|
|
128
|
+
* What actually closes it is the CARVE BALANCE GUARD in
|
|
129
|
+
* `escapeUnknownHtmlTags`: a protected span may contain no UNBALANCED RAWTEXT
|
|
130
|
+
* opener. Neither engine needs to learn about HTML blocks for that to hold.
|
|
131
|
+
*
|
|
132
|
+
* What makes keeping two engines SAFE is therefore the pair of guards in
|
|
133
|
+
* `escapeUnknownHtmlTags`: a carve span the mask did not blank is escaped
|
|
134
|
+
* rather than pushed through verbatim, and a span carrying an unbalanced
|
|
135
|
+
* RAWTEXT opener is escaped even when both engines agree. Over-detection can
|
|
136
|
+
* then only cost cosmetics. Before the first guard the regex's info-string-tolerant
|
|
137
|
+
* closer let it desync and open a span from a line CommonMark treats as
|
|
138
|
+
* ordinary text, sheltering a live `<textarea>` from escaping entirely
|
|
139
|
+
* (`mismatched-fence-carve-does-not-shelter-opener`). The remaining tradeoff is
|
|
140
|
+
* pinned by `unclosed-fence-body-renders-escaped` rather than left as prose.
|
|
141
|
+
*/
|
|
142
|
+
declare function buildCloserHaystack(text: string): string;
|
|
143
|
+
/** Exported for the length-preservation invariant test only. */
|
|
144
|
+
export declare const __buildCloserHaystackForTest: typeof buildCloserHaystack;
|
|
145
|
+
export declare function escapeUnknownHtmlTags(text: string, allowedTags?: Set<string>): string;
|
|
146
|
+
/**
|
|
147
|
+
* Extends react-markdown's default safe-protocol allowlist with the two
|
|
148
|
+
* internal schemes the chat remark plugins emit (`card://`, `mention://`),
|
|
149
|
+
* for `href` ONLY. All other URLs go through `defaultUrlTransform`.
|
|
150
|
+
*/
|
|
151
|
+
export declare function cardAwareUrlTransform(url: string, key: string): string;
|
|
152
|
+
export {};
|
|
153
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/sanitize.ts"],"names":[],"mappings":"AA4CA;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,aAqBzB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,QAAQ,aAKnB,CAAA;AAqDF,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAEjF;AAkGD,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;CAChC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,0BAA+B;;;;;;;;;;;;;EAgG3E;AA2DD,wBAAgB,iBAAiB,KAEvB,MAAM,GAAG,UA6ElB;AA+HD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,iBAAS,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6ErE;AAED,oEAAoE;AACpE,eAAO,MAAM,6BAA6B,6BAAuB,CAAA;AA6/DjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,iBAAS,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0DjD;AAED,gEAAgE;AAChE,eAAO,MAAM,4BAA4B,4BAAsB,CAAA;AAkgB/D,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,WAAW,GAAE,GAAG,CAAC,MAAM,CAAkB,GACxC,MAAM,CAgGR;AAoED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAItE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SimpleMarkdownRenderer — the chat/doc composition over the unified
|
|
3
|
+
* `MarkdownEngine`. This IS the real component (not a compat alias): the
|
|
4
|
+
* old 966-line standalone implementation was deleted in the unification;
|
|
5
|
+
* its entire prop surface maps 1:1 onto the engine. Chat consumers keep
|
|
6
|
+
* layering `additionalRemarkPlugins` (card/mention links) and
|
|
7
|
+
* `componentOverrides` exactly as before.
|
|
8
|
+
*/
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { type MarkdownEngineProps } from './engine';
|
|
11
|
+
import type { ResolveLinkResult } from '../../../types/doc-source';
|
|
12
|
+
export type { ResolveLinkResult };
|
|
13
|
+
export interface SimpleMarkdownRendererProps extends Omit<MarkdownEngineProps, 'extraAllowedHtmlTags'> {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A type-narrowed ALIAS of the engine, not a wrapper: the composition adds
|
|
17
|
+
* no behavior (it only hides `extraAllowedHtmlTags` from the prop surface),
|
|
18
|
+
* and `MarkdownEngine` is already `memo`'d. Wrapping it in a second `memo`
|
|
19
|
+
* bought nothing and cost an extra shallow-compare pass plus a fiber per
|
|
20
|
+
* chat segment.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SimpleMarkdownRenderer: React.NamedExoticComponent<SimpleMarkdownRendererProps>;
|
|
23
|
+
//# sourceMappingURL=simple-markdown-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-markdown-renderer.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/markdown/simple-markdown-renderer.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC,MAAM,WAAW,2BACf,SAAQ,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;CAAG;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EACf,KAAK,CAAC,oBAAoB,CAAC,2BAA2B,CAAC,CAAC"}
|