@elastic/isomer-sdk 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.txt +0 -286
- package/README.md +13 -2
- package/THIRD_PARTY_LICENSES.md +1 -885
- package/dist/author/authored_fields.d.ts +93 -18
- package/dist/author/authored_fields.d.ts.map +1 -1
- package/dist/author/authored_fields.js +63 -43
- package/dist/author/authored_fields.js.map +1 -1
- package/dist/author/authoring_input.d.ts +7 -0
- package/dist/author/authoring_input.d.ts.map +1 -0
- package/dist/author/authoring_input.js +66 -0
- package/dist/author/authoring_input.js.map +1 -0
- package/dist/author/authoring_model.d.ts +33 -0
- package/dist/author/authoring_model.d.ts.map +1 -0
- package/dist/author/authoring_model.js +142 -0
- package/dist/author/authoring_model.js.map +1 -0
- package/dist/author/declarations.d.ts +13 -0
- package/dist/author/declarations.d.ts.map +1 -0
- package/dist/author/declarations.js +288 -0
- package/dist/author/declarations.js.map +1 -0
- package/dist/author/index.d.ts +4 -1
- package/dist/author/index.d.ts.map +1 -1
- package/dist/author/index.js +4 -1
- package/dist/author/index.js.map +1 -1
- package/dist/author/jsx_shim.d.ts +50 -30
- package/dist/author/jsx_shim.d.ts.map +1 -1
- package/dist/author/jsx_shim.js +146 -138
- package/dist/author/jsx_shim.js.map +1 -1
- package/dist/author/print_jsx.d.ts +19 -0
- package/dist/author/print_jsx.d.ts.map +1 -0
- package/dist/author/print_jsx.js +372 -0
- package/dist/author/print_jsx.js.map +1 -0
- package/dist/author/prompt.d.ts +2 -2
- package/dist/author/prompt.d.ts.map +1 -1
- package/dist/author/prompt.js +7 -2
- package/dist/author/prompt.js.map +1 -1
- package/dist/author/schema_to_typescript.d.ts +37 -0
- package/dist/author/schema_to_typescript.d.ts.map +1 -0
- package/dist/author/schema_to_typescript.js +289 -0
- package/dist/author/schema_to_typescript.js.map +1 -0
- package/dist/cjs/author/authored_fields.js +68 -47
- package/dist/cjs/author/authored_fields.js.map +1 -1
- package/dist/cjs/author/authoring_input.js +70 -0
- package/dist/cjs/author/authoring_input.js.map +1 -0
- package/dist/cjs/author/authoring_model.js +149 -0
- package/dist/cjs/author/authoring_model.js.map +1 -0
- package/dist/cjs/author/declarations.js +292 -0
- package/dist/cjs/author/declarations.js.map +1 -0
- package/dist/cjs/author/index.js +10 -1
- package/dist/cjs/author/index.js.map +1 -1
- package/dist/cjs/author/jsx_shim.js +148 -140
- package/dist/cjs/author/jsx_shim.js.map +1 -1
- package/dist/cjs/author/print_jsx.js +378 -0
- package/dist/cjs/author/print_jsx.js.map +1 -0
- package/dist/cjs/author/prompt.js +7 -2
- package/dist/cjs/author/prompt.js.map +1 -1
- package/dist/cjs/author/schema_to_typescript.js +298 -0
- package/dist/cjs/author/schema_to_typescript.js.map +1 -0
- package/dist/cjs/composition/body_node_base.js +11 -4
- package/dist/cjs/composition/body_node_base.js.map +1 -1
- package/dist/cjs/composition/error.js +2 -0
- package/dist/cjs/composition/error.js.map +1 -1
- package/dist/cjs/composition/index.js +2 -1
- package/dist/cjs/composition/index.js.map +1 -1
- package/dist/cjs/composition/structured_value.js.map +1 -1
- package/dist/cjs/define/frame.js +2 -3
- package/dist/cjs/define/frame.js.map +1 -1
- package/dist/cjs/define/index.js +7 -1
- package/dist/cjs/define/index.js.map +1 -1
- package/dist/cjs/define/primitive_example.js +26 -0
- package/dist/cjs/define/primitive_example.js.map +1 -0
- package/dist/cjs/define/primitive_icon.js +17 -0
- package/dist/cjs/define/primitive_icon.js.map +1 -0
- package/dist/cjs/define/primitive_module.js +24 -7
- package/dist/cjs/define/primitive_module.js.map +1 -1
- package/dist/cjs/define/slack_assets.js.map +1 -1
- package/dist/cjs/entries/index.js +8 -2
- package/dist/cjs/entries/index.js.map +1 -1
- package/dist/cjs/entries/markdown.js +2 -1
- package/dist/cjs/entries/markdown.js.map +1 -1
- package/dist/cjs/entries/slack.js +1 -2
- package/dist/cjs/entries/slack.js.map +1 -1
- package/dist/cjs/pack/capabilities.js +17 -11
- package/dist/cjs/pack/capabilities.js.map +1 -1
- package/dist/cjs/pack/compose.js +4 -1
- package/dist/cjs/pack/compose.js.map +1 -1
- package/dist/cjs/pack/index.js +2 -1
- package/dist/cjs/pack/index.js.map +1 -1
- package/dist/cjs/pack/primitive_pack.js +27 -5
- package/dist/cjs/pack/primitive_pack.js.map +1 -1
- package/dist/cjs/render/anchors.js +1 -1
- package/dist/cjs/render/anchors.js.map +1 -1
- package/dist/cjs/render/format_number.js +2 -1
- package/dist/cjs/render/format_number.js.map +1 -1
- package/dist/cjs/render/html/envelope.js +12 -6
- package/dist/cjs/render/html/envelope.js.map +1 -1
- package/dist/cjs/render/layout_check.js.map +1 -1
- package/dist/cjs/render/markdown/builder.js +18 -8
- package/dist/cjs/render/markdown/builder.js.map +1 -1
- package/dist/cjs/render/markdown/format.js +70 -30
- package/dist/cjs/render/markdown/format.js.map +1 -1
- package/dist/cjs/render/markdown/host_tags.js +67 -0
- package/dist/cjs/render/markdown/host_tags.js.map +1 -0
- package/dist/cjs/render/markdown/index.js +3 -1
- package/dist/cjs/render/markdown/index.js.map +1 -1
- package/dist/cjs/render/markdown/split.js +325 -0
- package/dist/cjs/render/markdown/split.js.map +1 -0
- package/dist/cjs/render/primitive_dispatch.js +11 -25
- package/dist/cjs/render/primitive_dispatch.js.map +1 -1
- package/dist/cjs/render/react/content.js +3 -1
- package/dist/cjs/render/react/content.js.map +1 -1
- package/dist/cjs/render/slack/format.js +1 -601
- package/dist/cjs/render/slack/format.js.map +1 -1
- package/dist/cjs/render/slack/index.js +1 -2
- package/dist/cjs/render/slack/index.js.map +1 -1
- package/dist/cjs/render/slack/markdown_content.js +172 -115
- package/dist/cjs/render/slack/markdown_content.js.map +1 -1
- package/dist/cjs/testing/conformance.js +40 -24
- package/dist/cjs/testing/conformance.js.map +1 -1
- package/dist/cjs/testing/icon.js +248 -0
- package/dist/cjs/testing/icon.js.map +1 -0
- package/dist/cjs/testing/index.js +3 -1
- package/dist/cjs/testing/index.js.map +1 -1
- package/dist/cjs/testing/registration.js +5 -3
- package/dist/cjs/testing/registration.js.map +1 -1
- package/dist/cjs/validate/authoring_schema.js +17 -1
- package/dist/cjs/validate/authoring_schema.js.map +1 -1
- package/dist/cjs/validate/index.js +2 -1
- package/dist/cjs/validate/index.js.map +1 -1
- package/dist/cjs/validate/json_schema.js +10 -3
- package/dist/cjs/validate/json_schema.js.map +1 -1
- package/dist/cjs/validate/url.js +2 -1
- package/dist/cjs/validate/url.js.map +1 -1
- package/dist/cjs/validate/validation.js +2 -45
- package/dist/cjs/validate/validation.js.map +1 -1
- package/dist/composition/body_node_base.d.ts +7 -6
- package/dist/composition/body_node_base.d.ts.map +1 -1
- package/dist/composition/body_node_base.js +10 -3
- package/dist/composition/body_node_base.js.map +1 -1
- package/dist/composition/error.d.ts +2 -0
- package/dist/composition/error.d.ts.map +1 -1
- package/dist/composition/error.js +2 -0
- package/dist/composition/error.js.map +1 -1
- package/dist/composition/index.d.ts +1 -1
- package/dist/composition/index.d.ts.map +1 -1
- package/dist/composition/index.js +1 -1
- package/dist/composition/index.js.map +1 -1
- package/dist/composition/structured_value.d.ts +3 -3
- package/dist/composition/structured_value.d.ts.map +1 -1
- package/dist/composition/structured_value.js.map +1 -1
- package/dist/define/frame.d.ts +9 -20
- package/dist/define/frame.d.ts.map +1 -1
- package/dist/define/frame.js +2 -3
- package/dist/define/frame.js.map +1 -1
- package/dist/define/index.d.ts +3 -1
- package/dist/define/index.d.ts.map +1 -1
- package/dist/define/index.js +3 -1
- package/dist/define/index.js.map +1 -1
- package/dist/define/primitive_example.d.ts +30 -0
- package/dist/define/primitive_example.d.ts.map +1 -0
- package/dist/define/primitive_example.js +21 -0
- package/dist/define/primitive_example.js.map +1 -0
- package/dist/define/primitive_icon.d.ts +11 -0
- package/dist/define/primitive_icon.d.ts.map +1 -0
- package/dist/define/primitive_icon.js +14 -0
- package/dist/define/primitive_icon.js.map +1 -0
- package/dist/define/primitive_module.d.ts +45 -24
- package/dist/define/primitive_module.d.ts.map +1 -1
- package/dist/define/primitive_module.js +24 -7
- package/dist/define/primitive_module.js.map +1 -1
- package/dist/define/slack_assets.d.ts +1 -1
- package/dist/define/slack_assets.d.ts.map +1 -1
- package/dist/define/slack_assets.js.map +1 -1
- package/dist/entries/index.d.ts +3 -3
- package/dist/entries/index.d.ts.map +1 -1
- package/dist/entries/index.js +3 -3
- package/dist/entries/index.js.map +1 -1
- package/dist/entries/markdown.d.ts +1 -1
- package/dist/entries/markdown.d.ts.map +1 -1
- package/dist/entries/markdown.js +1 -1
- package/dist/entries/markdown.js.map +1 -1
- package/dist/entries/slack.d.ts +1 -1
- package/dist/entries/slack.d.ts.map +1 -1
- package/dist/entries/slack.js +1 -1
- package/dist/entries/slack.js.map +1 -1
- package/dist/pack/capabilities.d.ts +24 -10
- package/dist/pack/capabilities.d.ts.map +1 -1
- package/dist/pack/capabilities.js +17 -11
- package/dist/pack/capabilities.js.map +1 -1
- package/dist/pack/compose.d.ts +4 -1
- package/dist/pack/compose.d.ts.map +1 -1
- package/dist/pack/compose.js +4 -1
- package/dist/pack/compose.js.map +1 -1
- package/dist/pack/index.d.ts +2 -2
- package/dist/pack/index.d.ts.map +1 -1
- package/dist/pack/index.js +2 -2
- package/dist/pack/index.js.map +1 -1
- package/dist/pack/primitive_pack.d.ts +14 -3
- package/dist/pack/primitive_pack.d.ts.map +1 -1
- package/dist/pack/primitive_pack.js +25 -4
- package/dist/pack/primitive_pack.js.map +1 -1
- package/dist/render/anchors.d.ts +2 -2
- package/dist/render/anchors.d.ts.map +1 -1
- package/dist/render/anchors.js +1 -1
- package/dist/render/anchors.js.map +1 -1
- package/dist/render/format_number.d.ts.map +1 -1
- package/dist/render/format_number.js +2 -1
- package/dist/render/format_number.js.map +1 -1
- package/dist/render/html/envelope.d.ts +3 -3
- package/dist/render/html/envelope.js +12 -6
- package/dist/render/html/envelope.js.map +1 -1
- package/dist/render/layout_check.d.ts +1 -1
- package/dist/render/layout_check.d.ts.map +1 -1
- package/dist/render/layout_check.js.map +1 -1
- package/dist/render/markdown/builder.d.ts +5 -4
- package/dist/render/markdown/builder.d.ts.map +1 -1
- package/dist/render/markdown/builder.js +16 -7
- package/dist/render/markdown/builder.js.map +1 -1
- package/dist/render/markdown/format.d.ts +9 -0
- package/dist/render/markdown/format.d.ts.map +1 -1
- package/dist/render/markdown/format.js +67 -31
- package/dist/render/markdown/format.js.map +1 -1
- package/dist/render/markdown/host_tags.d.ts +14 -0
- package/dist/render/markdown/host_tags.d.ts.map +1 -0
- package/dist/render/markdown/host_tags.js +63 -0
- package/dist/render/markdown/host_tags.js.map +1 -0
- package/dist/render/markdown/index.d.ts +1 -0
- package/dist/render/markdown/index.d.ts.map +1 -1
- package/dist/render/markdown/index.js +1 -0
- package/dist/render/markdown/index.js.map +1 -1
- package/dist/render/markdown/split.d.ts +32 -0
- package/dist/render/markdown/split.d.ts.map +1 -0
- package/dist/render/markdown/split.js +321 -0
- package/dist/render/markdown/split.js.map +1 -0
- package/dist/render/primitive_dispatch.d.ts +6 -6
- package/dist/render/primitive_dispatch.d.ts.map +1 -1
- package/dist/render/primitive_dispatch.js +12 -26
- package/dist/render/primitive_dispatch.js.map +1 -1
- package/dist/render/react/content.d.ts +1 -1
- package/dist/render/react/content.d.ts.map +1 -1
- package/dist/render/react/content.js +3 -1
- package/dist/render/react/content.js.map +1 -1
- package/dist/render/slack/format.d.ts +0 -25
- package/dist/render/slack/format.d.ts.map +1 -1
- package/dist/render/slack/format.js +1 -599
- package/dist/render/slack/format.js.map +1 -1
- package/dist/render/slack/index.d.ts +1 -1
- package/dist/render/slack/index.d.ts.map +1 -1
- package/dist/render/slack/index.js +1 -1
- package/dist/render/slack/index.js.map +1 -1
- package/dist/render/slack/markdown_content.d.ts +10 -4
- package/dist/render/slack/markdown_content.d.ts.map +1 -1
- package/dist/render/slack/markdown_content.js +169 -113
- package/dist/render/slack/markdown_content.js.map +1 -1
- package/dist/testing/conformance.d.ts +19 -14
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +40 -24
- package/dist/testing/conformance.js.map +1 -1
- package/dist/testing/icon.d.ts +11 -0
- package/dist/testing/icon.d.ts.map +1 -0
- package/dist/testing/icon.js +244 -0
- package/dist/testing/icon.js.map +1 -0
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/registration.d.ts +1 -1
- package/dist/testing/registration.d.ts.map +1 -1
- package/dist/testing/registration.js +6 -4
- package/dist/testing/registration.js.map +1 -1
- package/dist/validate/authoring_schema.d.ts +6 -0
- package/dist/validate/authoring_schema.d.ts.map +1 -1
- package/dist/validate/authoring_schema.js +15 -0
- package/dist/validate/authoring_schema.js.map +1 -1
- package/dist/validate/index.d.ts +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +1 -1
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/json_schema.d.ts.map +1 -1
- package/dist/validate/json_schema.js +10 -3
- package/dist/validate/json_schema.js.map +1 -1
- package/dist/validate/url.d.ts.map +1 -1
- package/dist/validate/url.js +2 -1
- package/dist/validate/url.js.map +1 -1
- package/dist/validate/validation.d.ts +1 -11
- package/dist/validate/validation.d.ts.map +1 -1
- package/dist/validate/validation.js +3 -46
- package/dist/validate/validation.js.map +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout_check.d.ts","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAUrE,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0FAA0F;AAC1F,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;CACzC;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;CACZ;AAqFD;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,SAAS,EACjB,MAAM,SAAS,OAAO,EAAE,EACxB,MAAM,eAAe,EACrB,SAAS,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"layout_check.d.ts","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAUrE,4CAA4C;AAC5C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0FAA0F;AAC1F,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,6BAA6B;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;CACzC;AAED,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;CACZ;AAqFD;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,SAAS,EACjB,MAAM,SAAS,OAAO,EAAE,EACxB,MAAM,eAAe,EACrB,SAAS,OAAO,GAAG,UAAU,KAC5B,aAAa,EAgFf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout_check.js","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type { ChildNodeWalker } from '../composition/body_node_base';\n\nimport {\n anchoredNodePaths,\n LAYOUT_ROOM_ATTRIBUTE,\n NODE_ANCHOR_ATTRIBUTE,\n nodeType,\n pairAnchors,\n} from './anchors';\n\n/** A rectangle on the canvas, in pixels. */\nexport interface LayoutRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** A laid-out element and the elements nested in it, as a layout engine measures them. */\nexport interface LayoutBox extends LayoutRect {\n /** Absent means unscaled. */\n readonly scale?: number;\n /** Text laid out in the box. */\n readonly runs?: readonly LayoutRect[];\n /** Where a {@link NODE_ANCHOR_ATTRIBUTE} is read from. */\n readonly attributes?: Readonly<Record<string, string>>;\n readonly children: readonly LayoutBox[];\n}\n\n/** A node drawn past the room its container gives it, or onto a sibling, by `by` pixels. */\nexport interface LayoutFinding {\n kind: 'overflow' | 'overlap';\n /** In validation's form, e.g. `body[1].items[0]`. */\n path: string;\n type: string;\n /** The sibling an `overlap` lands on. */\n with?: { path: string; type: string };\n by: number;\n}\n\ninterface PlacedNode {\n box: LayoutBox;\n path: string;\n type: string;\n}\n\n// Sub-pixel rounding reads as overflow without it.\nconst tolerance = 1;\n\nconst isScaled = ({ scale = 1 }: LayoutBox): boolean =>\n Math.abs(scale - 1) > 0.001;\n\nconst hasArea = ({ width, height }: LayoutRect): boolean =>\n width > 0 && height > 0;\n\n/** Every anchored box, pre-order, including those inside a scaled box, so a type's count matches its nodes. */\nconst anchoredBoxes = (box: LayoutBox): [string, LayoutBox][] => {\n const value = box.attributes?.[NODE_ANCHOR_ATTRIBUTE];\n return [\n ...(value === undefined ? [] : [[value, box] as [string, LayoutBox]]),\n ...box.children.flatMap(anchoredBoxes),\n ];\n};\n\nconst roomBoxes = (box: LayoutBox): LayoutBox[] => [\n ...(box.attributes?.[LAYOUT_ROOM_ATTRIBUTE] === undefined ? [] : [box]),\n ...box.children.flatMap(roomBoxes),\n];\n\n/**\n * The element boxes a node's own content fills: its box and those under it,\n * down to the nodes nested in it. Text runs are left out because glyphs\n * overhang a tight line height; a scaled box counts as itself alone.\n */\nconst ownBoxes = (\n box: LayoutBox,\n nested: ReadonlySet<LayoutBox>\n): LayoutBox[] => [\n box,\n ...(isScaled(box)\n ? []\n : box.children.flatMap((child) =>\n nested.has(child) ? [] : ownBoxes(child, nested)\n )),\n];\n\n/** What a box paints: its text, or itself when it holds nothing else, like a dot or a rule. */\nconst painted = (box: LayoutBox): LayoutRect[] => {\n if (isScaled(box)) {\n return [box];\n }\n const own =\n box.runs && box.runs.length > 0\n ? box.runs\n : box.children.length === 0\n ? [box]\n : [];\n return [...own.filter(hasArea), ...box.children.flatMap(painted)];\n};\n\nconst pastRoom = (room: LayoutRect, { x, y, width, height }: LayoutRect) =>\n Math.max(\n room.x - x,\n room.y - y,\n x + width - (room.x + room.width),\n y + height - (room.y + room.height)\n );\n\n/** How far `a` and `b` would have to move apart, along one axis, to clear each other. */\nconst overlapOf = (a: LayoutRect, b: LayoutRect): number => {\n const width = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const height = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n if (width <= tolerance || height <= tolerance) {\n return 0;\n }\n return Math.min(\n a.x + a.width - b.x,\n b.x + b.width - a.x,\n a.y + a.height - b.y,\n b.y + b.height - a.y\n );\n};\n\n/**\n * Where the nodes of `body` run past their room or onto each other in\n * `layout`, a measured render on `surface` with node anchors on. Empty when\n * nothing does.\n *\n * A node's room is the box of its nearest anchored or `layoutRoom` ancestor,\n * or `layout` at the top level, and only siblings under one room are\n * compared. Nothing inside a scaled box is checked. A finding is advice, not an error:\n * an overlap may be intended.\n */\nexport const checkLayout = (\n layout: LayoutBox,\n body: readonly unknown[],\n walk: ChildNodeWalker,\n surface: 'react' | 'svg'\n): LayoutFinding[] => {\n const nodes = anchoredNodePaths(body, walk, surface);\n const anchored = anchoredBoxes(layout);\n const boxes = pairAnchors(\n anchored,\n nodes.map(({ node }) => node)\n );\n const placed = new Map<LayoutBox, PlacedNode>();\n boxes.forEach((box, index) => {\n const { node, path } = nodes[index]!;\n const type = nodeType(node);\n if (box !== undefined && type !== undefined) {\n placed.set(box, { box, path, type });\n }\n });\n\n // Every anchored box bounds its ancestors' content, paired or not.\n const nested = new Set(anchored.map(([, box]) => box));\n const bounding = new Set([...nested, ...roomBoxes(layout)]);\n const rooms = new Map<PlacedNode, LayoutBox>();\n const siblings = new Map<LayoutBox | undefined, PlacedNode[]>();\n const visit = (box: LayoutBox, parent: LayoutBox | undefined): void => {\n const node = placed.get(box);\n if (node !== undefined) {\n rooms.set(node, parent ?? layout);\n siblings.set(parent, [...(siblings.get(parent) ?? []), node]);\n }\n if (!isScaled(box)) {\n box.children.forEach((child) =>\n visit(child, bounding.has(box) ? box : parent)\n );\n }\n };\n visit(layout, undefined);\n\n const overflows = [...rooms].flatMap(([node, room]): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...ownBoxes(node.box, nested)\n .filter(hasArea)\n .map((box) => pastRoom(room, box))\n );\n return by > tolerance\n ? [\n {\n kind: 'overflow',\n path: node.path,\n type: node.type,\n by: Math.round(by),\n },\n ]\n : [];\n });\n\n const overlaps = [...siblings.values()].flatMap((group) => {\n const paints = group.map(({ box }) => painted(box));\n return group.flatMap((first, i) =>\n group.slice(i + 1).flatMap((second, offset): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...paints[i]!.flatMap((a) =>\n paints[i + 1 + offset]!.map((b) => overlapOf(a, b))\n )\n );\n return by > 0\n ? [\n {\n kind: 'overlap',\n path: first.path,\n type: first.type,\n with: { path: second.path, type: second.type },\n by: Math.round(by),\n },\n ]\n : [];\n })\n );\n });\n\n return [...overflows, ...overlaps];\n};\n"]}
|
|
1
|
+
{"version":3,"file":"layout_check.js","sourceRoot":"","sources":["../../src/render/layout_check.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport type { ChildNodeWalker } from '../composition/body_node_base';\n\nimport {\n anchoredNodePaths,\n LAYOUT_ROOM_ATTRIBUTE,\n NODE_ANCHOR_ATTRIBUTE,\n nodeType,\n pairAnchors,\n} from './anchors';\n\n/** A rectangle on the canvas, in pixels. */\nexport interface LayoutRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** A laid-out element and the elements nested in it, as a layout engine measures them. */\nexport interface LayoutBox extends LayoutRect {\n /** Absent means unscaled. */\n readonly scale?: number;\n /** Text laid out in the box. */\n readonly runs?: readonly LayoutRect[];\n /** Where a {@link NODE_ANCHOR_ATTRIBUTE} is read from. */\n readonly attributes?: Readonly<Record<string, string>>;\n readonly children: readonly LayoutBox[];\n}\n\n/** A node drawn past the room its container gives it, or onto a sibling, by `by` pixels. */\nexport interface LayoutFinding {\n kind: 'overflow' | 'overlap';\n /** In validation's form, e.g. `body[1].items[0]`. */\n path: string;\n type: string;\n /** The sibling an `overlap` lands on. */\n with?: { path: string; type: string };\n by: number;\n}\n\ninterface PlacedNode {\n box: LayoutBox;\n path: string;\n type: string;\n}\n\n// Sub-pixel rounding reads as overflow without it.\nconst tolerance = 1;\n\nconst isScaled = ({ scale = 1 }: LayoutBox): boolean =>\n Math.abs(scale - 1) > 0.001;\n\nconst hasArea = ({ width, height }: LayoutRect): boolean =>\n width > 0 && height > 0;\n\n/** Every anchored box, pre-order, including those inside a scaled box, so a type's count matches its nodes. */\nconst anchoredBoxes = (box: LayoutBox): [string, LayoutBox][] => {\n const value = box.attributes?.[NODE_ANCHOR_ATTRIBUTE];\n return [\n ...(value === undefined ? [] : [[value, box] as [string, LayoutBox]]),\n ...box.children.flatMap(anchoredBoxes),\n ];\n};\n\nconst roomBoxes = (box: LayoutBox): LayoutBox[] => [\n ...(box.attributes?.[LAYOUT_ROOM_ATTRIBUTE] === undefined ? [] : [box]),\n ...box.children.flatMap(roomBoxes),\n];\n\n/**\n * The element boxes a node's own content fills: its box and those under it,\n * down to the nodes nested in it. Text runs are left out because glyphs\n * overhang a tight line height; a scaled box counts as itself alone.\n */\nconst ownBoxes = (\n box: LayoutBox,\n nested: ReadonlySet<LayoutBox>\n): LayoutBox[] => [\n box,\n ...(isScaled(box)\n ? []\n : box.children.flatMap((child) =>\n nested.has(child) ? [] : ownBoxes(child, nested)\n )),\n];\n\n/** What a box paints: its text, or itself when it holds nothing else, like a dot or a rule. */\nconst painted = (box: LayoutBox): LayoutRect[] => {\n if (isScaled(box)) {\n return [box];\n }\n const own =\n box.runs && box.runs.length > 0\n ? box.runs\n : box.children.length === 0\n ? [box]\n : [];\n return [...own.filter(hasArea), ...box.children.flatMap(painted)];\n};\n\nconst pastRoom = (room: LayoutRect, { x, y, width, height }: LayoutRect) =>\n Math.max(\n room.x - x,\n room.y - y,\n x + width - (room.x + room.width),\n y + height - (room.y + room.height)\n );\n\n/** How far `a` and `b` would have to move apart, along one axis, to clear each other. */\nconst overlapOf = (a: LayoutRect, b: LayoutRect): number => {\n const width = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const height = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n if (width <= tolerance || height <= tolerance) {\n return 0;\n }\n return Math.min(\n a.x + a.width - b.x,\n b.x + b.width - a.x,\n a.y + a.height - b.y,\n b.y + b.height - a.y\n );\n};\n\n/**\n * Where the nodes of `body` run past their room or onto each other in\n * `layout`, a measured render on `surface` with node anchors on. Empty when\n * nothing does.\n *\n * A node's room is the box of its nearest anchored or `layoutRoom` ancestor,\n * or `layout` at the top level, and only siblings under one room are\n * compared. Nothing inside a scaled box is checked. A finding is advice, not an error:\n * an overlap may be intended.\n */\nexport const checkLayout = (\n layout: LayoutBox,\n body: readonly unknown[],\n walk: ChildNodeWalker,\n surface: 'react' | 'snapshot'\n): LayoutFinding[] => {\n const nodes = anchoredNodePaths(body, walk, surface);\n const anchored = anchoredBoxes(layout);\n const boxes = pairAnchors(\n anchored,\n nodes.map(({ node }) => node)\n );\n const placed = new Map<LayoutBox, PlacedNode>();\n boxes.forEach((box, index) => {\n const { node, path } = nodes[index]!;\n const type = nodeType(node);\n if (box !== undefined && type !== undefined) {\n placed.set(box, { box, path, type });\n }\n });\n\n // Every anchored box bounds its ancestors' content, paired or not.\n const nested = new Set(anchored.map(([, box]) => box));\n const bounding = new Set([...nested, ...roomBoxes(layout)]);\n const rooms = new Map<PlacedNode, LayoutBox>();\n const siblings = new Map<LayoutBox | undefined, PlacedNode[]>();\n const visit = (box: LayoutBox, parent: LayoutBox | undefined): void => {\n const node = placed.get(box);\n if (node !== undefined) {\n rooms.set(node, parent ?? layout);\n siblings.set(parent, [...(siblings.get(parent) ?? []), node]);\n }\n if (!isScaled(box)) {\n box.children.forEach((child) =>\n visit(child, bounding.has(box) ? box : parent)\n );\n }\n };\n visit(layout, undefined);\n\n const overflows = [...rooms].flatMap(([node, room]): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...ownBoxes(node.box, nested)\n .filter(hasArea)\n .map((box) => pastRoom(room, box))\n );\n return by > tolerance\n ? [\n {\n kind: 'overflow',\n path: node.path,\n type: node.type,\n by: Math.round(by),\n },\n ]\n : [];\n });\n\n const overlaps = [...siblings.values()].flatMap((group) => {\n const paints = group.map(({ box }) => painted(box));\n return group.flatMap((first, i) =>\n group.slice(i + 1).flatMap((second, offset): LayoutFinding[] => {\n const by = Math.max(\n 0,\n ...paints[i]!.flatMap((a) =>\n paints[i + 1 + offset]!.map((b) => overlapOf(a, b))\n )\n );\n return by > 0\n ? [\n {\n kind: 'overlap',\n path: first.path,\n type: first.type,\n with: { path: second.path, type: second.type },\n by: Math.round(by),\n },\n ]\n : [];\n })\n );\n });\n\n return [...overflows, ...overlaps];\n};\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type MarkdownBlock, type MarkdownContent, type MarkdownInline, type MarkdownInlineInput } from '../../define/markdown_content.js';
|
|
2
2
|
/** The node type of Markdown printed as written. */
|
|
3
3
|
export declare const VERBATIM_TYPE = "isomerVerbatim";
|
|
4
|
+
export declare const verbatim: (markdown: string, source?: string) => MarkdownBlock;
|
|
4
5
|
/**
|
|
5
6
|
* Builds Markdown as content rather than strings, so escaping follows where
|
|
6
7
|
* each value lands. Links and images apply the URL policy in
|
|
@@ -36,11 +37,11 @@ export declare const md: {
|
|
|
36
37
|
table: (columns: readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[], rows: readonly (readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[])[]) => MarkdownBlock;
|
|
37
38
|
/** An unsafe `language` is dropped. */
|
|
38
39
|
codeBlock: (value: string, language?: string) => MarkdownBlock;
|
|
39
|
-
/** Authored Markdown source, after {@link
|
|
40
|
-
authored: (source: string) =>
|
|
40
|
+
/** Authored Markdown source, after {@link sanitizeAuthoredSource}; whitespace-only source is dropped. */
|
|
41
|
+
authored: (source: string) => MarkdownContent;
|
|
41
42
|
};
|
|
42
|
-
/**
|
|
43
|
-
export declare const
|
|
43
|
+
/** Parsed mdast blocks as GFM, unsanitized, for `md.authored` to sanitize as it sanitizes source. */
|
|
44
|
+
export declare const printParsed: (nodes: readonly unknown[]) => string;
|
|
44
45
|
/** `content` as flat mdast blocks, typed `unknown` so no declaration names mdast. */
|
|
45
46
|
export declare const markdownBlocks: (content: MarkdownContent) => readonly unknown[];
|
|
46
47
|
/** `content` as GFM, without a trailing line break. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EAEpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAYvC,oDAAoD;AACpD,eAAO,MAAM,aAAa,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EAEpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,+BAA+B,CAAC;AAYvC,oDAAoD;AACpD,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAqF9C,eAAO,MAAM,QAAQ,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,KAAG,aAK/B,CAAC;AAe/B;;;;;;;;GAQG;AACH,eAAO,MAAM,EAAE;kBACC,MAAM,KAAG,cAAc;0BACf,mBAAmB,EAAE,KAAG,cAAc;4BAEpC,mBAAmB,EAAE,KAAG,cAAc;kBAEhD,MAAM,KAAG,cAAc;kBAK5B,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,QACrD,MAAM,KACX,cAAc;iBAMJ,MAAM,OAAO,MAAM,KAAG,cAAc;IAMjD,4NAA4N;iBACjN,cAAc;6BACA,mBAAmB,EAAE,KAAG,aAAa;qBAGrD,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,eACf,mBAAmB,EAAE,KACjC,aAAa;IAEhB,mFAAmF;8BACzD,eAAe,EAAE,KAAG,eAAe;IAS7D;;;;OAIG;kBAEM,SAAS,CAAC,mBAAmB,GAAG,eAAe,CAAC,EAAE,uBAC7B;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAChE,aAAa;IAehB,+EAA+E;qBAEpE,SAAS,CAAC,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,CAAC,EAAE,QACpE,SAAS,CAAC,SAAS,CACvB,mBAAmB,GAAG,SAAS,mBAAmB,EAAE,CACrD,EAAE,CAAC,EAAE,KACL,aAAa;IAWhB,uCAAuC;uBACpB,MAAM,aAAa,MAAM,KAAG,aAAa;IAS5D,yGAAyG;uBACtF,MAAM,KAAG,eAAe;CAO5C,CAAC;AA+CF,qGAAqG;AACrG,eAAO,MAAM,WAAW,GAAI,OAAO,SAAS,OAAO,EAAE,KAAG,MAIlC,CAAC;AAEvB,qFAAqF;AACrF,eAAO,MAAM,cAAc,GAAI,SAAS,eAAe,KAAG,SAAS,OAAO,EACpD,CAAC;AAEvB,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,GAAI,SAAS,eAAe,KAAG,MAI1D,CAAC"}
|
|
@@ -9,7 +9,7 @@ import { defaultHandlers, toMarkdown, } from 'mdast-util-to-markdown';
|
|
|
9
9
|
import { oneLine } from '../../composition/one_line.js';
|
|
10
10
|
import { markdownContent, } from '../../define/markdown_content.js';
|
|
11
11
|
import { BLOCKED_HREF, sanitizeAssetUrl, sanitizeNavigationHref, } from '../../validate/url.js';
|
|
12
|
-
import {
|
|
12
|
+
import { sanitizeAuthoredSource } from './format.js';
|
|
13
13
|
// A fence-info string only allows word-ish tokens; anything else would
|
|
14
14
|
// terminate the fence early or inject markdown.
|
|
15
15
|
const FENCE_INFO_RE = /^[\w+#.-]+$/;
|
|
@@ -55,10 +55,13 @@ const isListStart = (start, count) => start !== undefined &&
|
|
|
55
55
|
start >= 0 &&
|
|
56
56
|
start + Math.max(count - 1, 0) <= MAX_LIST_NUMBER;
|
|
57
57
|
// Printed as written, for Markdown that is already safe. Trailing whitespace
|
|
58
|
-
// would add blank lines between blocks.
|
|
59
|
-
|
|
58
|
+
// would add blank lines between blocks. `source` is the authored text when
|
|
59
|
+
// sanitizing degraded it to inert text, whose escapes only Markdown resolves;
|
|
60
|
+
// surfaces that print literal text read it instead.
|
|
61
|
+
export const verbatim = (markdown, source) => block({
|
|
60
62
|
type: VERBATIM_TYPE,
|
|
61
63
|
value: markdown.trimEnd(),
|
|
64
|
+
...(source === undefined ? {} : { source }),
|
|
62
65
|
});
|
|
63
66
|
// An empty wrapper prints its markers alone: `****` reads as a thematic break.
|
|
64
67
|
const wrapper = (type, inputs) => {
|
|
@@ -144,11 +147,15 @@ export const md = {
|
|
|
144
147
|
: null,
|
|
145
148
|
value,
|
|
146
149
|
}),
|
|
147
|
-
/** Authored Markdown source, after {@link
|
|
148
|
-
authored: (source) =>
|
|
150
|
+
/** Authored Markdown source, after {@link sanitizeAuthoredSource}; whitespace-only source is dropped. */
|
|
151
|
+
authored: (source) => {
|
|
152
|
+
if (source.trim() === '') {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
const { markdown, inert } = sanitizeAuthoredSource(source);
|
|
156
|
+
return verbatim(markdown, inert ? source : undefined);
|
|
157
|
+
},
|
|
149
158
|
};
|
|
150
|
-
/** A renderer's string output as content, printed as written. */
|
|
151
|
-
export const markdownFromString = (markdown) => markdown.trim() === '' ? [] : verbatim(markdown);
|
|
152
159
|
const asText = (node, ...rest) => defaultHandlers.text({ type: 'text', value: node.value ?? node.alt ?? '' }, ...rest);
|
|
153
160
|
// The URL policy again at serialization, for content built outside `md`.
|
|
154
161
|
const handlers = {
|
|
@@ -176,6 +183,8 @@ const OPTIONS = {
|
|
|
176
183
|
extensions: [gfmToMarkdown({ tablePipeAlign: false })],
|
|
177
184
|
handlers: handlers,
|
|
178
185
|
};
|
|
186
|
+
/** Parsed mdast blocks as GFM, unsanitized, for `md.authored` to sanitize as it sanitizes source. */
|
|
187
|
+
export const printParsed = (nodes) => toMarkdown({ type: 'root', children: nodes }, { ...OPTIONS, handlers: {} }).replace(/\n$/, '');
|
|
179
188
|
/** `content` as flat mdast blocks, typed `unknown` so no declaration names mdast. */
|
|
180
189
|
export const markdownBlocks = (content) => rootContent(content);
|
|
181
190
|
/** `content` as GFM, without a trailing line break. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Builder content is mdast under a brand. Every mdast type stays inside this\n// module, so no emitted declaration names one.\n\nimport type {\n Blockquote,\n Definition,\n Image,\n Link,\n ListItem,\n PhrasingContent,\n RootContent,\n TableRow,\n} from 'mdast';\nimport { gfmToMarkdown } from 'mdast-util-gfm';\nimport {\n defaultHandlers,\n type Handle,\n type Options,\n toMarkdown,\n} from 'mdast-util-to-markdown';\n\nimport { oneLine } from '../../composition/one_line';\nimport {\n type MarkdownBlock,\n type MarkdownContent,\n markdownContent,\n type MarkdownInline,\n type MarkdownInlineInput,\n} from '../../define/markdown_content';\nimport {\n BLOCKED_HREF,\n sanitizeAssetUrl,\n sanitizeNavigationHref,\n} from '../../validate/url';\n\nimport { sanitizeMarkdownSource } from './format';\n\n// A fence-info string only allows word-ish tokens; anything else would\n// terminate the fence early or inject markdown.\nconst FENCE_INFO_RE = /^[\\w+#.-]+$/;\n/** The node type of Markdown printed as written. */\nexport const VERBATIM_TYPE = 'isomerVerbatim';\n\nconst inline = (node: PhrasingContent): MarkdownInline =>\n Object.assign(node, { [markdownContent]: 'inline' as const });\n\nconst block = (node: RootContent): MarkdownBlock =>\n Object.assign(node, { [markdownContent]: 'block' as const });\n\nconst isContentList = (\n content: MarkdownInline | MarkdownContent\n): content is readonly MarkdownContent[] => Array.isArray(content);\n\nconst isInlineList = (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): label is readonly MarkdownInlineInput[] => Array.isArray(label);\n\nconst phrasing = (input: MarkdownInlineInput): PhrasingContent =>\n typeof input === 'string'\n ? { type: 'text', value: oneLine(input) }\n : (input as unknown as PhrasingContent);\n\nconst emptyText = (): PhrasingContent => ({ type: 'text', value: '' });\n\nconst isEmptyText = (node: PhrasingContent): boolean =>\n node.type === 'text' && node.value === '';\n\n// A break at either edge prints as a literal `\\` or loose markers.\nconst withoutEdgeBreaks = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] => {\n const children = inputs.map(phrasing).filter((node) => !isEmptyText(node));\n let start = 0;\n let end = children.length;\n while (start < end && children[start]!.type === 'break') {\n start += 1;\n }\n while (end > start && children[end - 1]!.type === 'break') {\n end -= 1;\n }\n return children.slice(start, end);\n};\n\n// Only a paragraph breaks a line: a heading with one turns setext, and the\n// Slack fallback reads a line at a time.\nconst inlineChildren = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] =>\n withoutEdgeBreaks(inputs).map((node) =>\n node.type === 'break' ? { type: 'text', value: ' ' } : node\n );\n\nconst rootContent = (content: MarkdownContent): RootContent[] =>\n isContentList(content)\n ? content.flatMap(rootContent)\n : [content as unknown as RootContent];\n\nconst isInlineInput = (\n item: MarkdownInlineInput | MarkdownContent\n): item is MarkdownInlineInput =>\n typeof item === 'string' ||\n (!isContentList(item) && item[markdownContent] === 'inline');\n\nconst itemContent = (\n item: MarkdownInlineInput | MarkdownContent\n): ListItem['children'] =>\n isInlineInput(item)\n ? [{ type: 'paragraph', children: withoutEdgeBreaks([item]) }]\n : (rootContent(item) as ListItem['children']);\n\n// GFM reads a list number of at most nine digits, so the last item's must fit.\nconst MAX_LIST_NUMBER = 999_999_999;\n\nconst isListStart = (\n start: number | undefined,\n count: number\n): start is number =>\n start !== undefined &&\n Number.isInteger(start) &&\n start >= 0 &&\n start + Math.max(count - 1, 0) <= MAX_LIST_NUMBER;\n\n// Printed as written, for Markdown that is already safe. Trailing whitespace\n// would add blank lines between blocks.\nconst verbatim = (markdown: string): MarkdownBlock =>\n block({\n type: VERBATIM_TYPE,\n value: markdown.trimEnd(),\n } as unknown as RootContent);\n\n// An empty wrapper prints its markers alone: `****` reads as a thematic break.\nconst wrapper = (\n type: 'strong' | 'emphasis',\n inputs: MarkdownInlineInput[]\n): MarkdownInline => {\n const children = inlineChildren(inputs);\n return inline(children.length === 0 ? emptyText() : { type, children });\n};\n\nconst inlineRuns = (\n runs: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): PhrasingContent[] => inlineChildren(isInlineList(runs) ? runs : [runs]);\n\n/**\n * Builds Markdown as content rather than strings, so escaping follows where\n * each value lands. Links and images apply the URL policy in\n * `src/validate/url.ts`: a blocked link keeps its label on\n * {@link BLOCKED_HREF}, and a blocked image degrades to its alt text.\n *\n * @example\n * md.list(rows.map((row) => md.paragraph(md.strong(row.label), ': ', row.value)))\n */\nexport const md = {\n text: (value: string): MarkdownInline => inline(phrasing(value)),\n strong: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('strong', children),\n emphasis: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('emphasis', children),\n code: (value: string): MarkdownInline =>\n inline(\n value === '' ? emptyText() : { type: 'inlineCode', value: oneLine(value) }\n ),\n link: (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[],\n href: string\n ): MarkdownInline =>\n inline({\n type: 'link',\n url: sanitizeNavigationHref(href) ?? BLOCKED_HREF,\n children: inlineRuns(label),\n }),\n image: (alt: string, src: string): MarkdownInline => {\n const url = sanitizeAssetUrl(src);\n return url === null\n ? inline(phrasing(alt))\n : inline({ type: 'image', url, alt: oneLine(alt) });\n },\n /** A hard line break, printed as a backslash before the line ending. Inside a heading, strong, emphasis, link label, or table cell it is a space; at the start or end of any of these, or of a paragraph, it is dropped. */\n break: (): MarkdownInline => inline({ type: 'break' }),\n paragraph: (...children: MarkdownInlineInput[]): MarkdownBlock =>\n block({ type: 'paragraph', children: withoutEdgeBreaks(children) }),\n heading: (\n depth: 1 | 2 | 3 | 4 | 5 | 6,\n ...children: MarkdownInlineInput[]\n ): MarkdownBlock =>\n block({ type: 'heading', depth, children: inlineChildren(children) }),\n /** A quote with no blocks, such as one holding only a hidden child, is dropped. */\n blockquote: (...children: MarkdownContent[]): MarkdownContent => {\n const content = rootContent(children);\n return content.length === 0\n ? []\n : block({\n type: 'blockquote',\n children: content as Blockquote['children'],\n });\n },\n /**\n * An item that is inline input becomes one paragraph; one with no blocks,\n * such as a hidden child, is dropped. A `start` that would print a marker\n * GFM does not read as a list number is ignored.\n */\n list: (\n items: readonly (MarkdownInlineInput | MarkdownContent)[],\n { ordered = false, start }: { ordered?: boolean; start?: number } = {}\n ): MarkdownBlock => {\n const children = items.flatMap((item): ListItem[] => {\n const content = itemContent(item);\n return content.length === 0\n ? []\n : [{ type: 'listItem', spread: false, children: content }];\n });\n return block({\n type: 'list',\n ordered,\n ...(isListStart(start, children.length) ? { start } : {}),\n spread: false,\n children,\n });\n },\n /** A cell is one inline run or several. GFM trims a cell's edge whitespace. */\n table: (\n columns: readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[],\n rows: readonly (readonly (\n MarkdownInlineInput | readonly MarkdownInlineInput[]\n )[])[]\n ): MarkdownBlock =>\n block({\n type: 'table',\n children: [columns, ...rows].map((cells): TableRow => ({\n type: 'tableRow',\n children: cells.map((cell) => ({\n type: 'tableCell',\n children: inlineRuns(cell),\n })),\n })),\n }),\n /** An unsafe `language` is dropped. */\n codeBlock: (value: string, language?: string): MarkdownBlock =>\n block({\n type: 'code',\n lang:\n language !== undefined && FENCE_INFO_RE.test(language)\n ? language\n : null,\n value,\n }),\n /** Authored Markdown source, after {@link sanitizeMarkdownSource}. */\n authored: (source: string): MarkdownBlock =>\n verbatim(sanitizeMarkdownSource(source)),\n};\n\n/** A renderer's string output as content, printed as written. */\nexport const markdownFromString = (markdown: string): MarkdownContent =>\n markdown.trim() === '' ? [] : verbatim(markdown);\n\nconst asText: Handle = (\n node: { value?: string; alt?: string | null },\n ...rest\n) =>\n defaultHandlers.text(\n { type: 'text', value: node.value ?? node.alt ?? '' },\n ...rest\n );\n\n// The URL policy again at serialization, for content built outside `md`.\nconst handlers: Record<string, Handle> = {\n link: (node: Link, ...rest) =>\n defaultHandlers.link(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n definition: (node: Definition, ...rest) =>\n defaultHandlers.definition(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n image: (node: Image, ...rest) => {\n const url = sanitizeAssetUrl(node.url);\n return url === null\n ? asText(node, ...rest)\n : defaultHandlers.image({ ...node, url }, ...rest);\n },\n html: asText,\n [VERBATIM_TYPE]: (node: { value: string }) => node.value,\n};\n\nconst OPTIONS: Options = {\n bullet: '-',\n // With `*`, emphasis around strong prints `***x***`, which the Slack\n // fallback cannot split. `_` costs character references around emphasis\n // inside a word.\n emphasis: '_',\n fence: '`',\n listItemIndent: 'one',\n rule: '-',\n strong: '*',\n extensions: [gfmToMarkdown({ tablePipeAlign: false })],\n handlers: handlers as Options['handlers'],\n};\n\n/** `content` as flat mdast blocks, typed `unknown` so no declaration names mdast. */\nexport const markdownBlocks = (content: MarkdownContent): readonly unknown[] =>\n rootContent(content);\n\n/** `content` as GFM, without a trailing line break. */\nexport const serializeMarkdown = (content: MarkdownContent): string =>\n toMarkdown({ type: 'root', children: rootContent(content) }, OPTIONS).replace(\n /\\n$/,\n ''\n );\n"]}
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/render/markdown/builder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Builder content is mdast under a brand. Every mdast type stays inside this\n// module, so no emitted declaration names one.\n\nimport type {\n Blockquote,\n Definition,\n Image,\n Link,\n ListItem,\n PhrasingContent,\n RootContent,\n TableRow,\n} from 'mdast';\nimport { gfmToMarkdown } from 'mdast-util-gfm';\nimport {\n defaultHandlers,\n type Handle,\n type Options,\n toMarkdown,\n} from 'mdast-util-to-markdown';\n\nimport { oneLine } from '../../composition/one_line';\nimport {\n type MarkdownBlock,\n type MarkdownContent,\n markdownContent,\n type MarkdownInline,\n type MarkdownInlineInput,\n} from '../../define/markdown_content';\nimport {\n BLOCKED_HREF,\n sanitizeAssetUrl,\n sanitizeNavigationHref,\n} from '../../validate/url';\n\nimport { sanitizeAuthoredSource } from './format';\n\n// A fence-info string only allows word-ish tokens; anything else would\n// terminate the fence early or inject markdown.\nconst FENCE_INFO_RE = /^[\\w+#.-]+$/;\n/** The node type of Markdown printed as written. */\nexport const VERBATIM_TYPE = 'isomerVerbatim';\n\nconst inline = (node: PhrasingContent): MarkdownInline =>\n Object.assign(node, { [markdownContent]: 'inline' as const });\n\nconst block = (node: RootContent): MarkdownBlock =>\n Object.assign(node, { [markdownContent]: 'block' as const });\n\nconst isContentList = (\n content: MarkdownInline | MarkdownContent\n): content is readonly MarkdownContent[] => Array.isArray(content);\n\nconst isInlineList = (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): label is readonly MarkdownInlineInput[] => Array.isArray(label);\n\nconst phrasing = (input: MarkdownInlineInput): PhrasingContent =>\n typeof input === 'string'\n ? { type: 'text', value: oneLine(input) }\n : (input as unknown as PhrasingContent);\n\nconst emptyText = (): PhrasingContent => ({ type: 'text', value: '' });\n\nconst isEmptyText = (node: PhrasingContent): boolean =>\n node.type === 'text' && node.value === '';\n\n// A break at either edge prints as a literal `\\` or loose markers.\nconst withoutEdgeBreaks = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] => {\n const children = inputs.map(phrasing).filter((node) => !isEmptyText(node));\n let start = 0;\n let end = children.length;\n while (start < end && children[start]!.type === 'break') {\n start += 1;\n }\n while (end > start && children[end - 1]!.type === 'break') {\n end -= 1;\n }\n return children.slice(start, end);\n};\n\n// Only a paragraph breaks a line: a heading with one turns setext, and the\n// Slack fallback reads a line at a time.\nconst inlineChildren = (\n inputs: readonly MarkdownInlineInput[]\n): PhrasingContent[] =>\n withoutEdgeBreaks(inputs).map((node) =>\n node.type === 'break' ? { type: 'text', value: ' ' } : node\n );\n\nconst rootContent = (content: MarkdownContent): RootContent[] =>\n isContentList(content)\n ? content.flatMap(rootContent)\n : [content as unknown as RootContent];\n\nconst isInlineInput = (\n item: MarkdownInlineInput | MarkdownContent\n): item is MarkdownInlineInput =>\n typeof item === 'string' ||\n (!isContentList(item) && item[markdownContent] === 'inline');\n\nconst itemContent = (\n item: MarkdownInlineInput | MarkdownContent\n): ListItem['children'] =>\n isInlineInput(item)\n ? [{ type: 'paragraph', children: withoutEdgeBreaks([item]) }]\n : (rootContent(item) as ListItem['children']);\n\n// GFM reads a list number of at most nine digits, so the last item's must fit.\nconst MAX_LIST_NUMBER = 999_999_999;\n\nconst isListStart = (\n start: number | undefined,\n count: number\n): start is number =>\n start !== undefined &&\n Number.isInteger(start) &&\n start >= 0 &&\n start + Math.max(count - 1, 0) <= MAX_LIST_NUMBER;\n\n// Printed as written, for Markdown that is already safe. Trailing whitespace\n// would add blank lines between blocks. `source` is the authored text when\n// sanitizing degraded it to inert text, whose escapes only Markdown resolves;\n// surfaces that print literal text read it instead.\nexport const verbatim = (markdown: string, source?: string): MarkdownBlock =>\n block({\n type: VERBATIM_TYPE,\n value: markdown.trimEnd(),\n ...(source === undefined ? {} : { source }),\n } as unknown as RootContent);\n\n// An empty wrapper prints its markers alone: `****` reads as a thematic break.\nconst wrapper = (\n type: 'strong' | 'emphasis',\n inputs: MarkdownInlineInput[]\n): MarkdownInline => {\n const children = inlineChildren(inputs);\n return inline(children.length === 0 ? emptyText() : { type, children });\n};\n\nconst inlineRuns = (\n runs: MarkdownInlineInput | readonly MarkdownInlineInput[]\n): PhrasingContent[] => inlineChildren(isInlineList(runs) ? runs : [runs]);\n\n/**\n * Builds Markdown as content rather than strings, so escaping follows where\n * each value lands. Links and images apply the URL policy in\n * `src/validate/url.ts`: a blocked link keeps its label on\n * {@link BLOCKED_HREF}, and a blocked image degrades to its alt text.\n *\n * @example\n * md.list(rows.map((row) => md.paragraph(md.strong(row.label), ': ', row.value)))\n */\nexport const md = {\n text: (value: string): MarkdownInline => inline(phrasing(value)),\n strong: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('strong', children),\n emphasis: (...children: MarkdownInlineInput[]): MarkdownInline =>\n wrapper('emphasis', children),\n code: (value: string): MarkdownInline =>\n inline(\n value === '' ? emptyText() : { type: 'inlineCode', value: oneLine(value) }\n ),\n link: (\n label: MarkdownInlineInput | readonly MarkdownInlineInput[],\n href: string\n ): MarkdownInline =>\n inline({\n type: 'link',\n url: sanitizeNavigationHref(href) ?? BLOCKED_HREF,\n children: inlineRuns(label),\n }),\n image: (alt: string, src: string): MarkdownInline => {\n const url = sanitizeAssetUrl(src);\n return url === null\n ? inline(phrasing(alt))\n : inline({ type: 'image', url, alt: oneLine(alt) });\n },\n /** A hard line break, printed as a backslash before the line ending. Inside a heading, strong, emphasis, link label, or table cell it is a space; at the start or end of any of these, or of a paragraph, it is dropped. */\n break: (): MarkdownInline => inline({ type: 'break' }),\n paragraph: (...children: MarkdownInlineInput[]): MarkdownBlock =>\n block({ type: 'paragraph', children: withoutEdgeBreaks(children) }),\n heading: (\n depth: 1 | 2 | 3 | 4 | 5 | 6,\n ...children: MarkdownInlineInput[]\n ): MarkdownBlock =>\n block({ type: 'heading', depth, children: inlineChildren(children) }),\n /** A quote with no blocks, such as one holding only a hidden child, is dropped. */\n blockquote: (...children: MarkdownContent[]): MarkdownContent => {\n const content = rootContent(children);\n return content.length === 0\n ? []\n : block({\n type: 'blockquote',\n children: content as Blockquote['children'],\n });\n },\n /**\n * An item that is inline input becomes one paragraph; one with no blocks,\n * such as a hidden child, is dropped. A `start` that would print a marker\n * GFM does not read as a list number is ignored.\n */\n list: (\n items: readonly (MarkdownInlineInput | MarkdownContent)[],\n { ordered = false, start }: { ordered?: boolean; start?: number } = {}\n ): MarkdownBlock => {\n const children = items.flatMap((item): ListItem[] => {\n const content = itemContent(item);\n return content.length === 0\n ? []\n : [{ type: 'listItem', spread: false, children: content }];\n });\n return block({\n type: 'list',\n ordered,\n ...(isListStart(start, children.length) ? { start } : {}),\n spread: false,\n children,\n });\n },\n /** A cell is one inline run or several. GFM trims a cell's edge whitespace. */\n table: (\n columns: readonly (MarkdownInlineInput | readonly MarkdownInlineInput[])[],\n rows: readonly (readonly (\n MarkdownInlineInput | readonly MarkdownInlineInput[]\n )[])[]\n ): MarkdownBlock =>\n block({\n type: 'table',\n children: [columns, ...rows].map((cells): TableRow => ({\n type: 'tableRow',\n children: cells.map((cell) => ({\n type: 'tableCell',\n children: inlineRuns(cell),\n })),\n })),\n }),\n /** An unsafe `language` is dropped. */\n codeBlock: (value: string, language?: string): MarkdownBlock =>\n block({\n type: 'code',\n lang:\n language !== undefined && FENCE_INFO_RE.test(language)\n ? language\n : null,\n value,\n }),\n /** Authored Markdown source, after {@link sanitizeAuthoredSource}; whitespace-only source is dropped. */\n authored: (source: string): MarkdownContent => {\n if (source.trim() === '') {\n return [];\n }\n const { markdown, inert } = sanitizeAuthoredSource(source);\n return verbatim(markdown, inert ? source : undefined);\n },\n};\n\nconst asText: Handle = (\n node: { value?: string; alt?: string | null },\n ...rest\n) =>\n defaultHandlers.text(\n { type: 'text', value: node.value ?? node.alt ?? '' },\n ...rest\n );\n\n// The URL policy again at serialization, for content built outside `md`.\nconst handlers: Record<string, Handle> = {\n link: (node: Link, ...rest) =>\n defaultHandlers.link(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n definition: (node: Definition, ...rest) =>\n defaultHandlers.definition(\n { ...node, url: sanitizeNavigationHref(node.url) ?? BLOCKED_HREF },\n ...rest\n ),\n image: (node: Image, ...rest) => {\n const url = sanitizeAssetUrl(node.url);\n return url === null\n ? asText(node, ...rest)\n : defaultHandlers.image({ ...node, url }, ...rest);\n },\n html: asText,\n [VERBATIM_TYPE]: (node: { value: string }) => node.value,\n};\n\nconst OPTIONS: Options = {\n bullet: '-',\n // With `*`, emphasis around strong prints `***x***`, which the Slack\n // fallback cannot split. `_` costs character references around emphasis\n // inside a word.\n emphasis: '_',\n fence: '`',\n listItemIndent: 'one',\n rule: '-',\n strong: '*',\n extensions: [gfmToMarkdown({ tablePipeAlign: false })],\n handlers: handlers as Options['handlers'],\n};\n\n/** Parsed mdast blocks as GFM, unsanitized, for `md.authored` to sanitize as it sanitizes source. */\nexport const printParsed = (nodes: readonly unknown[]): string =>\n toMarkdown(\n { type: 'root', children: nodes as RootContent[] },\n { ...OPTIONS, handlers: {} }\n ).replace(/\\n$/, '');\n\n/** `content` as flat mdast blocks, typed `unknown` so no declaration names mdast. */\nexport const markdownBlocks = (content: MarkdownContent): readonly unknown[] =>\n rootContent(content);\n\n/** `content` as GFM, without a trailing line break. */\nexport const serializeMarkdown = (content: MarkdownContent): string =>\n toMarkdown({ type: 'root', children: rootContent(content) }, OPTIONS).replace(\n /\\n$/,\n ''\n );\n"]}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/** `markdown` as flat GFM mdast blocks, typed `unknown` so no declaration names mdast; `null` past the parse budget or the parser's recursion depth. */
|
|
2
|
+
export declare const parseGfmBlocks: (markdown: string) => readonly unknown[] | null;
|
|
3
|
+
/** {@link sanitizeMarkdownSource}'s result, and whether it degraded to inert text. */
|
|
4
|
+
export declare const sanitizeAuthoredSource: (markdown: string) => {
|
|
5
|
+
markdown: string;
|
|
6
|
+
inert: boolean;
|
|
7
|
+
};
|
|
1
8
|
/** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */
|
|
2
9
|
export declare const sanitizeMarkdownSource: (markdown: string) => string;
|
|
10
|
+
export declare const inert: (markdown: string) => string;
|
|
11
|
+
export declare const exceedsParseBudget: (markdown: string) => boolean;
|
|
3
12
|
//# sourceMappingURL=format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"AAsDA,wJAAwJ;AACxJ,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,KAAG,SAAS,OAAO,EAAE,GAAG,IAYtE,CAAC;AAiJF,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,GACjC,UAAU,MAAM,KACf;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAqBpC,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,KAAG,MACf,CAAC;AAG5C,eAAO,MAAM,KAAK,GAAI,UAAU,MAAM,KAAG,MACmB,CAAC;AAY7D,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,OAgBrD,CAAC"}
|
|
@@ -15,14 +15,35 @@ const escapeLinkLabel = (label) => label.replace(/[[\]\\]/g, '\\$&');
|
|
|
15
15
|
// early or read as a link title. `encodeURIComponent` leaves `(` and `)`
|
|
16
16
|
// unescaped by spec, so those two are mapped by hand.
|
|
17
17
|
const escapeLinkDestination = (href) => href.replace(/[()\s\\]/g, (char) => {
|
|
18
|
-
if (char === '(')
|
|
18
|
+
if (char === '(') {
|
|
19
19
|
return '%28';
|
|
20
|
-
|
|
20
|
+
}
|
|
21
|
+
if (char === ')') {
|
|
21
22
|
return '%29';
|
|
23
|
+
}
|
|
22
24
|
return encodeURIComponent(char);
|
|
23
25
|
});
|
|
24
26
|
const escapeParsedDestination = (href) => escapeLinkDestination(href.replace(/&/g, '&'));
|
|
25
27
|
let parseOptions;
|
|
28
|
+
const parse = (source) => fromMarkdown(source, (parseOptions ??= {
|
|
29
|
+
extensions: [gfm()],
|
|
30
|
+
mdastExtensions: [gfmFromMarkdown()],
|
|
31
|
+
}));
|
|
32
|
+
/** `markdown` as flat GFM mdast blocks, typed `unknown` so no declaration names mdast; `null` past the parse budget or the parser's recursion depth. */
|
|
33
|
+
export const parseGfmBlocks = (markdown) => {
|
|
34
|
+
if (exceedsParseBudget(markdown)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
return parse(markdown).children;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (!(error instanceof RangeError)) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
26
47
|
// Each pass can expose a new sink (an escaped HTML block reveals the Markdown
|
|
27
48
|
// inside it; a blocked link's label may close an outer `](`), so passes repeat
|
|
28
49
|
// until the source is stable.
|
|
@@ -34,11 +55,7 @@ const offsets = (node) => {
|
|
|
34
55
|
return start === undefined || end === undefined ? undefined : [start, end];
|
|
35
56
|
};
|
|
36
57
|
const sanitizePass = (source) => {
|
|
37
|
-
|
|
38
|
-
extensions: [gfm()],
|
|
39
|
-
mdastExtensions: [gfmFromMarkdown()],
|
|
40
|
-
};
|
|
41
|
-
const root = fromMarkdown(source, parseOptions);
|
|
58
|
+
const root = parse(source);
|
|
42
59
|
const definitions = new Map();
|
|
43
60
|
const pending = [...root.children].reverse();
|
|
44
61
|
while (pending.length) {
|
|
@@ -46,8 +63,9 @@ const sanitizePass = (source) => {
|
|
|
46
63
|
if (node.type === 'definition' && !definitions.has(node.identifier)) {
|
|
47
64
|
definitions.set(node.identifier, node);
|
|
48
65
|
}
|
|
49
|
-
if ('children' in node)
|
|
66
|
+
if ('children' in node) {
|
|
50
67
|
pending.push(...[...node.children].reverse());
|
|
68
|
+
}
|
|
51
69
|
}
|
|
52
70
|
const slice = (node) => {
|
|
53
71
|
const range = offsets(node);
|
|
@@ -58,8 +76,9 @@ const sanitizePass = (source) => {
|
|
|
58
76
|
let cursor = start;
|
|
59
77
|
for (const child of children) {
|
|
60
78
|
const range = offsets(child);
|
|
61
|
-
if (!range)
|
|
79
|
+
if (!range) {
|
|
62
80
|
continue;
|
|
81
|
+
}
|
|
63
82
|
out += source.slice(cursor, range[0]) + emit(child);
|
|
64
83
|
cursor = range[1];
|
|
65
84
|
}
|
|
@@ -79,8 +98,9 @@ const sanitizePass = (source) => {
|
|
|
79
98
|
case 'definition': {
|
|
80
99
|
const safe = sanitizeParsedNavigationHref(node.url) ??
|
|
81
100
|
sanitizeParsedAssetUrl(node.url);
|
|
82
|
-
if (safe === node.url)
|
|
101
|
+
if (safe === node.url) {
|
|
83
102
|
return undefined;
|
|
103
|
+
}
|
|
84
104
|
const title = node.title ? ` ${escapeTitle(node.title)}` : '';
|
|
85
105
|
return `[${node.label ?? node.identifier}]: ${safe === null ? BLOCKED_HREF : escapeParsedDestination(safe)}${title}`;
|
|
86
106
|
}
|
|
@@ -100,10 +120,12 @@ const sanitizePass = (source) => {
|
|
|
100
120
|
}
|
|
101
121
|
case 'image': {
|
|
102
122
|
const safe = sanitizeParsedAssetUrl(node.url);
|
|
103
|
-
if (safe === null)
|
|
123
|
+
if (safe === null) {
|
|
104
124
|
return escapeLinkLabel(node.alt ?? '');
|
|
105
|
-
|
|
125
|
+
}
|
|
126
|
+
if (safe === node.url) {
|
|
106
127
|
return undefined;
|
|
128
|
+
}
|
|
107
129
|
const title = node.title ? ` ${escapeTitle(node.title)}` : '';
|
|
108
130
|
return `}${title})`;
|
|
109
131
|
}
|
|
@@ -114,12 +136,15 @@ const sanitizePass = (source) => {
|
|
|
114
136
|
return safe === null ? raw.slice(1, -1) : undefined;
|
|
115
137
|
}
|
|
116
138
|
// A GFM literal (`www.x.com`) is http(s) or mailto by construction.
|
|
117
|
-
if (!raw.startsWith('['))
|
|
139
|
+
if (!raw.startsWith('[')) {
|
|
118
140
|
return undefined;
|
|
119
|
-
|
|
141
|
+
}
|
|
142
|
+
if (safe === null) {
|
|
120
143
|
return emitLabel(node);
|
|
121
|
-
|
|
144
|
+
}
|
|
145
|
+
if (safe === node.url) {
|
|
122
146
|
return undefined;
|
|
147
|
+
}
|
|
123
148
|
const title = node.title ? ` ${escapeTitle(node.title)}` : '';
|
|
124
149
|
return `[${emitLabel(node)}](${escapeParsedDestination(safe)}${title})`;
|
|
125
150
|
}
|
|
@@ -129,57 +154,68 @@ const sanitizePass = (source) => {
|
|
|
129
154
|
};
|
|
130
155
|
const emit = (node) => {
|
|
131
156
|
const replaced = rewrite(node);
|
|
132
|
-
if (replaced !== undefined)
|
|
157
|
+
if (replaced !== undefined) {
|
|
133
158
|
return replaced;
|
|
159
|
+
}
|
|
134
160
|
const range = offsets(node);
|
|
135
|
-
if (!range)
|
|
161
|
+
if (!range) {
|
|
136
162
|
return '';
|
|
163
|
+
}
|
|
137
164
|
return 'children' in node
|
|
138
165
|
? emitChildren(range[0], range[1], node.children)
|
|
139
166
|
: source.slice(...range);
|
|
140
167
|
};
|
|
141
168
|
return emitChildren(0, source.length, root.children);
|
|
142
169
|
};
|
|
143
|
-
/**
|
|
144
|
-
export const
|
|
145
|
-
if (exceedsParseBudget(markdown))
|
|
146
|
-
return inert(markdown);
|
|
170
|
+
/** {@link sanitizeMarkdownSource}'s result, and whether it degraded to inert text. */
|
|
171
|
+
export const sanitizeAuthoredSource = (markdown) => {
|
|
172
|
+
if (exceedsParseBudget(markdown)) {
|
|
173
|
+
return { markdown: inert(markdown), inert: true };
|
|
174
|
+
}
|
|
147
175
|
let current = markdown;
|
|
148
176
|
try {
|
|
149
177
|
for (let pass = 0; pass < MAX_PASSES; pass++) {
|
|
150
178
|
const next = sanitizePass(current);
|
|
151
|
-
if (next === current)
|
|
152
|
-
return current;
|
|
179
|
+
if (next === current) {
|
|
180
|
+
return { markdown: current, inert: false };
|
|
181
|
+
}
|
|
153
182
|
current = next;
|
|
154
183
|
}
|
|
155
184
|
}
|
|
156
185
|
catch (error) {
|
|
157
186
|
// The parser recurses per nesting level, so inline nesting deep enough
|
|
158
187
|
// to exhaust the stack lands here.
|
|
159
|
-
if (!(error instanceof RangeError))
|
|
188
|
+
if (!(error instanceof RangeError)) {
|
|
160
189
|
throw error;
|
|
190
|
+
}
|
|
161
191
|
}
|
|
162
|
-
return inert(current);
|
|
192
|
+
return { markdown: inert(current), inert: true };
|
|
163
193
|
};
|
|
194
|
+
/** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */
|
|
195
|
+
export const sanitizeMarkdownSource = (markdown) => sanitizeAuthoredSource(markdown).markdown;
|
|
164
196
|
// No link, image, definition, or tag can survive without `[` or `<`.
|
|
165
|
-
const inert = (markdown) => markdown.replace(/[[\]\\]/g, '\\$&').replace(/</g, '<');
|
|
197
|
+
export const inert = (markdown) => markdown.replace(/[[\]\\]/g, '\\$&').replace(/</g, '<');
|
|
166
198
|
// GFM parsing is superlinear for some delimiter runs, even without nesting.
|
|
167
199
|
const LINE_PREFIX_RE = /^(?:[ \t>]|[-*+](?=[ \t])|\d{1,9}[.)](?=[ \t]))+/gm;
|
|
168
200
|
const MAX_LINE_PREFIX = 256;
|
|
169
|
-
|
|
201
|
+
// An escaped punctuation character opens nothing, so `\*` counts as one.
|
|
202
|
+
const INLINE_DELIMITER_RE = /\\[!-/:-@[-`{-~]|[[\]*`~<>|\\]|(?<![\p{L}\p{N}])_|_(?![\p{L}\p{N}])/gu;
|
|
170
203
|
const MAX_INLINE_DELIMITERS = 2048;
|
|
171
204
|
const MAX_PARSE_LENGTH = 16_384;
|
|
172
|
-
const exceedsParseBudget = (markdown) => {
|
|
173
|
-
if (markdown.length > MAX_PARSE_LENGTH)
|
|
205
|
+
export const exceedsParseBudget = (markdown) => {
|
|
206
|
+
if (markdown.length > MAX_PARSE_LENGTH) {
|
|
174
207
|
return true;
|
|
208
|
+
}
|
|
175
209
|
for (const [prefix] of markdown.matchAll(LINE_PREFIX_RE)) {
|
|
176
|
-
if (prefix.length > MAX_LINE_PREFIX)
|
|
210
|
+
if (prefix.length > MAX_LINE_PREFIX) {
|
|
177
211
|
return true;
|
|
212
|
+
}
|
|
178
213
|
}
|
|
179
214
|
let delimiters = 0;
|
|
180
215
|
for (const _ of markdown.matchAll(INLINE_DELIMITER_RE)) {
|
|
181
|
-
if (++delimiters > MAX_INLINE_DELIMITERS)
|
|
216
|
+
if (++delimiters > MAX_INLINE_DELIMITERS) {
|
|
182
217
|
return true;
|
|
218
|
+
}
|
|
183
219
|
}
|
|
184
220
|
return false;
|
|
185
221
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Authored Markdown source made safe to print, for `md.authored`.\n\nimport type { Definition, Nodes, Parents } from 'mdast';\nimport { fromMarkdown } from 'mdast-util-from-markdown';\nimport { gfmFromMarkdown } from 'mdast-util-gfm';\nimport { gfm } from 'micromark-extension-gfm';\n\nimport {\n BLOCKED_HREF,\n sanitizeParsedAssetUrl,\n sanitizeParsedNavigationHref,\n} from '../../validate/url';\n\n// Escapes label characters that could close a `[...]` early and smuggle in a\n// hostile destination of their own.\nconst escapeLinkLabel = (label: string): string =>\n label.replace(/[[\\]\\\\]/g, '\\\\$&');\n\n// Percent-encodes destination characters that would terminate the `(...)`\n// early or read as a link title. `encodeURIComponent` leaves `(` and `)`\n// unescaped by spec, so those two are mapped by hand.\nconst escapeLinkDestination = (href: string): string =>\n href.replace(/[()\\s\\\\]/g, (char) => {\n if (char === '(') return '%28';\n if (char === ')') return '%29';\n return encodeURIComponent(char);\n });\n\nconst escapeParsedDestination = (href: string): string =>\n escapeLinkDestination(href.replace(/&/g, '&'));\n\nlet parseOptions: Parameters<typeof fromMarkdown>[1] | undefined;\n\n// Each pass can expose a new sink (an escaped HTML block reveals the Markdown\n// inside it; a blocked link's label may close an outer `](`), so passes repeat\n// until the source is stable.\nconst MAX_PASSES = 16;\n\nconst escapeTitle = (title: string): string =>\n `\"${title.replace(/[\"\\\\]/g, '\\\\$&')}\"`;\n\nconst offsets = (node: Nodes): [number, number] | undefined => {\n const start = node.position?.start.offset;\n const end = node.position?.end.offset;\n return start === undefined || end === undefined ? undefined : [start, end];\n};\n\nconst sanitizePass = (source: string): string => {\n parseOptions ??= {\n extensions: [gfm()],\n mdastExtensions: [gfmFromMarkdown()],\n };\n const root = fromMarkdown(source, parseOptions);\n const definitions = new Map<string, Definition>();\n const pending: Nodes[] = [...root.children].reverse();\n while (pending.length) {\n const node = pending.pop()!;\n if (node.type === 'definition' && !definitions.has(node.identifier)) {\n definitions.set(node.identifier, node);\n }\n if ('children' in node) pending.push(...[...node.children].reverse());\n }\n\n const slice = (node: Nodes): string => {\n const range = offsets(node);\n return range ? source.slice(...range) : '';\n };\n\n const emitChildren = (\n start: number,\n end: number,\n children: readonly Nodes[]\n ): string => {\n let out = '';\n let cursor = start;\n for (const child of children) {\n const range = offsets(child);\n if (!range) continue;\n out += source.slice(cursor, range[0]) + emit(child);\n cursor = range[1];\n }\n return out + source.slice(cursor, end);\n };\n\n const emitLabel = (node: Parents): string => {\n const first = node.children[0];\n const last = node.children[node.children.length - 1];\n const from = first && offsets(first);\n const to = last && offsets(last);\n return from && to ? emitChildren(from[0], to[1], node.children) : '';\n };\n\n const rewrite = (node: Nodes): string | undefined => {\n switch (node.type) {\n case 'html':\n return slice(node).replace(/</g, '<');\n case 'definition': {\n const safe =\n sanitizeParsedNavigationHref(node.url) ??\n sanitizeParsedAssetUrl(node.url);\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${node.label ?? node.identifier}]: ${\n safe === null ? BLOCKED_HREF : escapeParsedDestination(safe)\n }${title}`;\n }\n case 'imageReference': {\n const definition = definitions.get(node.identifier);\n return definition && sanitizeParsedAssetUrl(definition.url) === null\n ? escapeLinkLabel(node.alt ?? '')\n : undefined;\n }\n case 'linkReference': {\n const definition = definitions.get(node.identifier);\n return definition &&\n sanitizeParsedNavigationHref(definition.url) === null &&\n sanitizeParsedAssetUrl(definition.url) !== null\n ? emitLabel(node)\n : undefined;\n }\n case 'image': {\n const safe = sanitizeParsedAssetUrl(node.url);\n if (safe === null) return escapeLinkLabel(node.alt ?? '');\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `}${title})`;\n }\n case 'link': {\n const raw = slice(node);\n const safe = sanitizeParsedNavigationHref(node.url);\n if (raw.startsWith('<')) {\n return safe === null ? raw.slice(1, -1) : undefined;\n }\n // A GFM literal (`www.x.com`) is http(s) or mailto by construction.\n if (!raw.startsWith('[')) return undefined;\n if (safe === null) return emitLabel(node);\n if (safe === node.url) return undefined;\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${emitLabel(node)}](${escapeParsedDestination(safe)}${title})`;\n }\n default:\n return undefined;\n }\n };\n\n const emit = (node: Nodes): string => {\n const replaced = rewrite(node);\n if (replaced !== undefined) return replaced;\n const range = offsets(node);\n if (!range) return '';\n return 'children' in node\n ? emitChildren(range[0], range[1], node.children)\n : source.slice(...range);\n };\n\n return emitChildren(0, source.length, root.children);\n};\n\n/** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */\nexport const sanitizeMarkdownSource = (markdown: string): string => {\n if (exceedsParseBudget(markdown)) return inert(markdown);\n let current = markdown;\n try {\n for (let pass = 0; pass < MAX_PASSES; pass++) {\n const next = sanitizePass(current);\n if (next === current) return current;\n current = next;\n }\n } catch (error) {\n // The parser recurses per nesting level, so inline nesting deep enough\n // to exhaust the stack lands here.\n if (!(error instanceof RangeError)) throw error;\n }\n return inert(current);\n};\n\n// No link, image, definition, or tag can survive without `[` or `<`.\nconst inert = (markdown: string): string =>\n markdown.replace(/[[\\]\\\\]/g, '\\\\$&').replace(/</g, '<');\n\n// GFM parsing is superlinear for some delimiter runs, even without nesting.\nconst LINE_PREFIX_RE = /^(?:[ \\t>]|[-*+](?=[ \\t])|\\d{1,9}[.)](?=[ \\t]))+/gm;\nconst MAX_LINE_PREFIX = 256;\nconst INLINE_DELIMITER_RE =\n /[[\\]*`~<>|\\\\]|(?<![\\p{L}\\p{N}])_|_(?![\\p{L}\\p{N}])/gu;\nconst MAX_INLINE_DELIMITERS = 2048;\n\nconst MAX_PARSE_LENGTH = 16_384;\n\nconst exceedsParseBudget = (markdown: string): boolean => {\n if (markdown.length > MAX_PARSE_LENGTH) return true;\n for (const [prefix] of markdown.matchAll(LINE_PREFIX_RE)) {\n if (prefix.length > MAX_LINE_PREFIX) return true;\n }\n let delimiters = 0;\n for (const _ of markdown.matchAll(INLINE_DELIMITER_RE)) {\n if (++delimiters > MAX_INLINE_DELIMITERS) return true;\n }\n return false;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/render/markdown/format.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Authored Markdown source made safe to print, for `md.authored`, and the GFM\n// parse it shares with the Slack fallback.\n\nimport type { Definition, Nodes, Parents, Root } from 'mdast';\nimport { fromMarkdown } from 'mdast-util-from-markdown';\nimport { gfmFromMarkdown } from 'mdast-util-gfm';\nimport { gfm } from 'micromark-extension-gfm';\n\nimport {\n BLOCKED_HREF,\n sanitizeParsedAssetUrl,\n sanitizeParsedNavigationHref,\n} from '../../validate/url';\n\n// Escapes label characters that could close a `[...]` early and smuggle in a\n// hostile destination of their own.\nconst escapeLinkLabel = (label: string): string =>\n label.replace(/[[\\]\\\\]/g, '\\\\$&');\n\n// Percent-encodes destination characters that would terminate the `(...)`\n// early or read as a link title. `encodeURIComponent` leaves `(` and `)`\n// unescaped by spec, so those two are mapped by hand.\nconst escapeLinkDestination = (href: string): string =>\n href.replace(/[()\\s\\\\]/g, (char) => {\n if (char === '(') {\n return '%28';\n }\n if (char === ')') {\n return '%29';\n }\n return encodeURIComponent(char);\n });\n\nconst escapeParsedDestination = (href: string): string =>\n escapeLinkDestination(href.replace(/&/g, '&'));\n\nlet parseOptions: Parameters<typeof fromMarkdown>[1] | undefined;\n\nconst parse = (source: string): Root =>\n fromMarkdown(\n source,\n (parseOptions ??= {\n extensions: [gfm()],\n mdastExtensions: [gfmFromMarkdown()],\n })\n );\n\n/** `markdown` as flat GFM mdast blocks, typed `unknown` so no declaration names mdast; `null` past the parse budget or the parser's recursion depth. */\nexport const parseGfmBlocks = (markdown: string): readonly unknown[] | null => {\n if (exceedsParseBudget(markdown)) {\n return null;\n }\n try {\n return parse(markdown).children;\n } catch (error) {\n if (!(error instanceof RangeError)) {\n throw error;\n }\n return null;\n }\n};\n\n// Each pass can expose a new sink (an escaped HTML block reveals the Markdown\n// inside it; a blocked link's label may close an outer `](`), so passes repeat\n// until the source is stable.\nconst MAX_PASSES = 16;\n\nconst escapeTitle = (title: string): string =>\n `\"${title.replace(/[\"\\\\]/g, '\\\\$&')}\"`;\n\nconst offsets = (node: Nodes): [number, number] | undefined => {\n const start = node.position?.start.offset;\n const end = node.position?.end.offset;\n return start === undefined || end === undefined ? undefined : [start, end];\n};\n\nconst sanitizePass = (source: string): string => {\n const root = parse(source);\n const definitions = new Map<string, Definition>();\n const pending: Nodes[] = [...root.children].reverse();\n while (pending.length) {\n const node = pending.pop()!;\n if (node.type === 'definition' && !definitions.has(node.identifier)) {\n definitions.set(node.identifier, node);\n }\n if ('children' in node) {\n pending.push(...[...node.children].reverse());\n }\n }\n\n const slice = (node: Nodes): string => {\n const range = offsets(node);\n return range ? source.slice(...range) : '';\n };\n\n const emitChildren = (\n start: number,\n end: number,\n children: readonly Nodes[]\n ): string => {\n let out = '';\n let cursor = start;\n for (const child of children) {\n const range = offsets(child);\n if (!range) {\n continue;\n }\n out += source.slice(cursor, range[0]) + emit(child);\n cursor = range[1];\n }\n return out + source.slice(cursor, end);\n };\n\n const emitLabel = (node: Parents): string => {\n const first = node.children[0];\n const last = node.children[node.children.length - 1];\n const from = first && offsets(first);\n const to = last && offsets(last);\n return from && to ? emitChildren(from[0], to[1], node.children) : '';\n };\n\n const rewrite = (node: Nodes): string | undefined => {\n switch (node.type) {\n case 'html':\n return slice(node).replace(/</g, '<');\n case 'definition': {\n const safe =\n sanitizeParsedNavigationHref(node.url) ??\n sanitizeParsedAssetUrl(node.url);\n if (safe === node.url) {\n return undefined;\n }\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${node.label ?? node.identifier}]: ${\n safe === null ? BLOCKED_HREF : escapeParsedDestination(safe)\n }${title}`;\n }\n case 'imageReference': {\n const definition = definitions.get(node.identifier);\n return definition && sanitizeParsedAssetUrl(definition.url) === null\n ? escapeLinkLabel(node.alt ?? '')\n : undefined;\n }\n case 'linkReference': {\n const definition = definitions.get(node.identifier);\n return definition &&\n sanitizeParsedNavigationHref(definition.url) === null &&\n sanitizeParsedAssetUrl(definition.url) !== null\n ? emitLabel(node)\n : undefined;\n }\n case 'image': {\n const safe = sanitizeParsedAssetUrl(node.url);\n if (safe === null) {\n return escapeLinkLabel(node.alt ?? '');\n }\n if (safe === node.url) {\n return undefined;\n }\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `}${title})`;\n }\n case 'link': {\n const raw = slice(node);\n const safe = sanitizeParsedNavigationHref(node.url);\n if (raw.startsWith('<')) {\n return safe === null ? raw.slice(1, -1) : undefined;\n }\n // A GFM literal (`www.x.com`) is http(s) or mailto by construction.\n if (!raw.startsWith('[')) {\n return undefined;\n }\n if (safe === null) {\n return emitLabel(node);\n }\n if (safe === node.url) {\n return undefined;\n }\n const title = node.title ? ` ${escapeTitle(node.title)}` : '';\n return `[${emitLabel(node)}](${escapeParsedDestination(safe)}${title})`;\n }\n default:\n return undefined;\n }\n };\n\n const emit = (node: Nodes): string => {\n const replaced = rewrite(node);\n if (replaced !== undefined) {\n return replaced;\n }\n const range = offsets(node);\n if (!range) {\n return '';\n }\n return 'children' in node\n ? emitChildren(range[0], range[1], node.children)\n : source.slice(...range);\n };\n\n return emitChildren(0, source.length, root.children);\n};\n\n/** {@link sanitizeMarkdownSource}'s result, and whether it degraded to inert text. */\nexport const sanitizeAuthoredSource = (\n markdown: string\n): { markdown: string; inert: boolean } => {\n if (exceedsParseBudget(markdown)) {\n return { markdown: inert(markdown), inert: true };\n }\n let current = markdown;\n try {\n for (let pass = 0; pass < MAX_PASSES; pass++) {\n const next = sanitizePass(current);\n if (next === current) {\n return { markdown: current, inert: false };\n }\n current = next;\n }\n } catch (error) {\n // The parser recurses per nesting level, so inline nesting deep enough\n // to exhaust the stack lands here.\n if (!(error instanceof RangeError)) {\n throw error;\n }\n }\n return { markdown: inert(current), inert: true };\n};\n\n/** Sanitizes GFM destinations and HTML; excessive syntax or length degrades to inert text. */\nexport const sanitizeMarkdownSource = (markdown: string): string =>\n sanitizeAuthoredSource(markdown).markdown;\n\n// No link, image, definition, or tag can survive without `[` or `<`.\nexport const inert = (markdown: string): string =>\n markdown.replace(/[[\\]\\\\]/g, '\\\\$&').replace(/</g, '<');\n\n// GFM parsing is superlinear for some delimiter runs, even without nesting.\nconst LINE_PREFIX_RE = /^(?:[ \\t>]|[-*+](?=[ \\t])|\\d{1,9}[.)](?=[ \\t]))+/gm;\nconst MAX_LINE_PREFIX = 256;\n// An escaped punctuation character opens nothing, so `\\*` counts as one.\nconst INLINE_DELIMITER_RE =\n /\\\\[!-/:-@[-`{-~]|[[\\]*`~<>|\\\\]|(?<![\\p{L}\\p{N}])_|_(?![\\p{L}\\p{N}])/gu;\nconst MAX_INLINE_DELIMITERS = 2048;\n\nconst MAX_PARSE_LENGTH = 16_384;\n\nexport const exceedsParseBudget = (markdown: string): boolean => {\n if (markdown.length > MAX_PARSE_LENGTH) {\n return true;\n }\n for (const [prefix] of markdown.matchAll(LINE_PREFIX_RE)) {\n if (prefix.length > MAX_LINE_PREFIX) {\n return true;\n }\n }\n let delimiters = 0;\n for (const _ of markdown.matchAll(INLINE_DELIMITER_RE)) {\n if (++delimiters > MAX_INLINE_DELIMITERS) {\n return true;\n }\n }\n return false;\n};\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** A tag found by {@link findHostTags}. */
|
|
2
|
+
export interface HostTag {
|
|
3
|
+
/** Offset of the `<` in the source. */
|
|
4
|
+
readonly index: number;
|
|
5
|
+
/** The tag as written. */
|
|
6
|
+
readonly raw: string;
|
|
7
|
+
/** The name as listed in the options. */
|
|
8
|
+
readonly name: string;
|
|
9
|
+
/** Values as written, keyed by lower-cased name; a bare attribute is `''`. */
|
|
10
|
+
readonly attributes: Readonly<Record<string, string>>;
|
|
11
|
+
}
|
|
12
|
+
/** Every tag named in `names` (matched case-insensitively and whole), in source order. */
|
|
13
|
+
export declare const findHostTags: (source: string, names: readonly string[]) => HostTag[];
|
|
14
|
+
//# sourceMappingURL=host_tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host_tags.d.ts","sourceRoot":"","sources":["../../../src/render/markdown/host_tags.ts"],"names":[],"mappings":"AAaA,2CAA2C;AAC3C,MAAM,WAAW,OAAO;IACtB,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0BAA0B;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACvD;AA6CD,0FAA0F;AAC1F,eAAO,MAAM,YAAY,GACvB,QAAQ,MAAM,EACd,OAAO,SAAS,MAAM,EAAE,KACvB,OAAO,EAwBT,CAAC"}
|