slackmark 0.5.0 → 0.6.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/README.md +29 -17
- package/dist/adapters/code-fence-adapter.d.ts +1 -1
- package/dist/adapters/code-fence-adapter.d.ts.map +1 -1
- package/dist/adapters/math-block-adapter.d.ts +1 -1
- package/dist/adapters/math-block-adapter.d.ts.map +1 -1
- package/dist/adapters/mermaid-fence-adapter.d.ts.map +1 -1
- package/dist/adapters/try-render-image.d.ts +9 -0
- package/dist/adapters/try-render-image.d.ts.map +1 -0
- package/dist/assemble/message-assembler.d.ts +10 -0
- package/dist/assemble/message-assembler.d.ts.map +1 -1
- package/dist/budget/conversion-context.d.ts +5 -1
- package/dist/budget/conversion-context.d.ts.map +1 -1
- package/dist/budget/operation-scope.d.ts +9 -0
- package/dist/budget/operation-scope.d.ts.map +1 -0
- package/dist/budget/recording-receipt-collector.d.ts +13 -0
- package/dist/budget/recording-receipt-collector.d.ts.map +1 -0
- package/dist/capabilities/capabilities.d.ts.map +1 -1
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/converter/create-converter.d.ts +1 -1
- package/dist/converter/create-converter.d.ts.map +1 -1
- package/dist/converter/resolve-config.d.ts +4 -2
- package/dist/converter/resolve-config.d.ts.map +1 -1
- package/dist/converter/slackmark-converter.d.ts +11 -1
- package/dist/converter/slackmark-converter.d.ts.map +1 -1
- package/dist/errors.d.ts +81 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4901 -3585
- package/dist/index.js.map +1 -1
- package/dist/receipts.d.ts +37 -0
- package/dist/receipts.d.ts.map +1 -0
- package/dist/renderers/codecogs-renderer.d.ts +5 -5
- package/dist/renderers/codecogs-renderer.d.ts.map +1 -1
- package/dist/renderers/kroki-renderer.d.ts +5 -5
- package/dist/renderers/kroki-renderer.d.ts.map +1 -1
- package/dist/renderers/mermaid-ink-renderer.d.ts +5 -5
- package/dist/renderers/mermaid-ink-renderer.d.ts.map +1 -1
- package/dist/renderers/quickchart-renderer.d.ts +5 -5
- package/dist/renderers/quickchart-renderer.d.ts.map +1 -1
- package/dist/renderers/renderer-options.d.ts +4 -0
- package/dist/renderers/renderer-options.d.ts.map +1 -0
- package/dist/renderers/url-utils.d.ts.map +1 -1
- package/dist/renderers.js +401 -248
- package/dist/renderers.js.map +1 -1
- package/dist/slack/fetch-slack-uploader.d.ts +11 -2
- package/dist/slack/fetch-slack-uploader.d.ts.map +1 -1
- package/dist/slack/slack-upload-error.d.ts +18 -2
- package/dist/slack/slack-upload-error.d.ts.map +1 -1
- package/dist/slack.d.ts +1 -1
- package/dist/slack.d.ts.map +1 -1
- package/dist/slack.js +743 -230
- package/dist/slack.js.map +1 -1
- package/dist/types.d.ts +93 -11
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -4
package/dist/renderers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/renderers/encoding.ts","../src/renderers/url-utils.ts","../src/renderers/kroki-renderer.ts","../src/renderers/mermaid-ink-renderer.ts","../src/renderers/codecogs-renderer.ts","../src/renderers/quickchart-renderer.ts"],"sourcesContent":["/**\n * Named Slack Block Kit limits.\n * Sources: https://docs.slack.dev/block-kit and block reference pages (July 2026 research).\n */\n\n/** https://docs.slack.dev/block-kit */\nexport const MAX_BLOCKS_PER_MESSAGE = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/section-block */\nexport const SECTION_TEXT_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_TEXT_MAX_CHARS = 150;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_LEVEL_MAX = 4;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_URL_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_ALT_MAX_CHARS = 2000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/context-block */\nexport const CONTEXT_ELEMENTS_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/markdown-block */\nexport const MARKDOWN_CUMULATIVE_MAX_CHARS = 12_000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_ROWS = 100;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_COLS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_CELL_CHARS_MAX = 10_000;\n\n/** Spec decision: prefer `table` up to this many rows (incl. header). */\nexport const TABLE_PREFERRED_MAX_ROWS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_MAX_DATA_ROWS = 200;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_CELL_CHARS_MAX = 20_000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_TITLE_MAX_CHARS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_LABEL_MAX_CHARS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SEGMENTS_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SERIES_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_POINTS_MAX = 20;\n\n/**\n * Community-reported cap (ENG-4936); not in official docs.\n * Enforced defensively with degradation.\n */\nexport const DATA_VISUALIZATION_MAX_PER_MESSAGE = 2;\n\n/** https://docs.slack.dev/reference/methods/chat.postMessage#truncating */\nexport const MESSAGE_TEXT_SAFETY_MAX_CHARS = 40_000;\n\n/** Undocumented; defensive clamp for rich_text_list.indent. */\nexport const RICH_TEXT_LIST_INDENT_MAX = 6;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_CHILDREN_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_TITLE_MAX_CHARS = 150;\n\n/** Cell wrap heuristic for table column_settings.is_wrapped. */\nexport const TABLE_CELL_WRAP_THRESHOLD = 40;\n\nexport const ELLIPSIS = \"…\";\n","const BASE64URL_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n/**\n * Kroki and mermaid.ink both accept zlib-deflated, unpadded base64url payloads.\n */\nexport async function deflateBase64Url(value: string): Promise<string> {\n const stream = new CompressionStream(\"deflate\");\n const compressed = readAll(stream.readable);\n const writer = stream.writable.getWriter();\n\n await writer.write(new TextEncoder().encode(value));\n await writer.close();\n writer.releaseLock();\n\n return encodeBase64Url(await compressed);\n}\n\nasync function readAll(stream: GfmReadableStream<Uint8Array>): Promise<Uint8Array> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let length = 0;\n\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n if (result.value !== undefined) {\n chunks.push(result.value);\n length += result.value.byteLength;\n }\n }\n reader.releaseLock();\n\n const output = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n output.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return output;\n}\n\nfunction encodeBase64Url(bytes: Uint8Array): string {\n const output: string[] = [];\n for (let index = 0; index < bytes.length; index += 3) {\n const first = bytes[index] ?? 0;\n const second = bytes[index + 1];\n const third = bytes[index + 2];\n\n output.push(\n BASE64URL_ALPHABET[first >> 2] ?? \"\",\n BASE64URL_ALPHABET[((first & 0b11) << 4) | ((second ?? 0) >> 4)] ?? \"\",\n );\n if (second !== undefined) {\n output.push(BASE64URL_ALPHABET[((second & 0b1111) << 2) | ((third ?? 0) >> 6)] ?? \"\");\n }\n if (third !== undefined) {\n output.push(BASE64URL_ALPHABET[third & 0b11_1111] ?? \"\");\n }\n }\n return output.join(\"\");\n}\n","export function normalizeBaseUrl(baseUrl: string): string {\n const normalized = baseUrl.replace(/\\/+$/u, \"\");\n if (normalized.length === 0) {\n throw new TypeError(\"baseUrl must not be empty\");\n }\n return normalized;\n}\n\nexport function normalizeFenceLanguage(lang: string): string {\n return lang.trim().toLowerCase();\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { ImageRenderer, RenderRequest, UrlImage } from \"../types.js\";\n\nimport { deflateBase64Url } from \"./encoding.js\";\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_KROKI_BASE_URL = \"https://kroki.io\";\n\n/**\n * Fence-language aliases for Kroki's supported diagram types.\n *\n * @see https://docs.kroki.io/kroki/setup/usage/\n */\nexport const KROKI_DIAGRAM_TYPES: Readonly<Record<string, string>> = Object.freeze({\n blockdiag: \"blockdiag\",\n bpmn: \"bpmn\",\n bytefield: \"bytefield\",\n c4: \"c4plantuml\",\n c4plantuml: \"c4plantuml\",\n d2: \"d2\",\n dbml: \"dbml\",\n ditaa: \"ditaa\",\n dot: \"graphviz\",\n erd: \"erd\",\n excalidraw: \"excalidraw\",\n graphviz: \"graphviz\",\n mermaid: \"mermaid\",\n nomnoml: \"nomnoml\",\n pikchr: \"pikchr\",\n plantuml: \"plantuml\",\n puml: \"plantuml\",\n structurizr: \"structurizr\",\n svgbob: \"svgbob\",\n symbolator: \"symbolator\",\n tikz: \"tikz\",\n umlet: \"umlet\",\n vega: \"vega\",\n \"vega-lite\": \"vegalite\",\n vegalite: \"vegalite\",\n wavedrom: \"wavedrom\",\n wireviz: \"wireviz\",\n});\n\nexport interface KrokiRendererOptions {\n readonly baseUrl?: string;\n /**\n * Additional or replacement fence-language aliases, merged over the defaults.\n */\n readonly diagramTypes?: Readonly<Record<string, string>>;\n}\n\n/**\n * Produces durable Kroki GET URLs without performing network I/O.\n */\nexport class KrokiRenderer implements ImageRenderer {\n private readonly baseUrl: string;\n private readonly diagramTypes: Readonly<Record<string, string>>;\n\n constructor(options: KrokiRendererOptions = {}) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_KROKI_BASE_URL);\n this.diagramTypes = Object.freeze({\n ...KROKI_DIAGRAM_TYPES,\n ...options.diagramTypes,\n });\n }\n\n canRender(req: RenderRequest): boolean {\n return this.diagramTypes[normalizeFenceLanguage(req.lang)] !== undefined;\n }\n\n async render(req: RenderRequest): Promise<(UrlImage & { readonly altText: string }) | null> {\n const diagramType = this.diagramTypes[normalizeFenceLanguage(req.lang)];\n if (diagramType === undefined) {\n return null;\n }\n\n const encoded = await deflateBase64Url(req.source);\n const imageUrl = `${this.baseUrl}/${encodeURIComponent(diagramType)}/png/${encoded}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { ImageRenderer, RenderRequest, UrlImage } from \"../types.js\";\n\nimport { deflateBase64Url } from \"./encoding.js\";\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_MERMAID_INK_BASE_URL = \"https://mermaid.ink\";\nconst DEFAULT_MERMAID_INK_BACKGROUND = \"!white\";\n\nexport type MermaidInkTheme = \"default\" | \"neutral\" | \"dark\" | \"forest\";\n\nexport interface MermaidInkRendererOptions {\n readonly baseUrl?: string;\n readonly theme?: MermaidInkTheme;\n /**\n * mermaid.ink color value, such as `!white` or `FF0000`.\n */\n readonly bgColor?: string;\n}\n\ninterface MermaidInkState {\n readonly code: string;\n readonly mermaid: {\n readonly theme: MermaidInkTheme;\n };\n}\n\n/**\n * Produces mermaid.ink pako-state PNG URLs without performing network I/O.\n */\nexport class MermaidInkRenderer implements ImageRenderer {\n private readonly baseUrl: string;\n private readonly theme: MermaidInkTheme;\n private readonly bgColor: string;\n\n constructor(options: MermaidInkRendererOptions = {}) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_MERMAID_INK_BASE_URL);\n this.theme = options.theme ?? \"default\";\n this.bgColor = options.bgColor ?? DEFAULT_MERMAID_INK_BACKGROUND;\n }\n\n canRender(req: RenderRequest): boolean {\n return normalizeFenceLanguage(req.lang) === \"mermaid\";\n }\n\n async render(req: RenderRequest): Promise<(UrlImage & { readonly altText: string }) | null> {\n if (!this.canRender(req)) {\n return null;\n }\n\n const state: MermaidInkState = {\n code: req.source,\n mermaid: { theme: this.theme },\n };\n const encoded = await deflateBase64Url(JSON.stringify(state));\n const imageUrl =\n `${this.baseUrl}/img/pako:${encoded}` +\n `?type=png&bgColor=${encodeURIComponent(this.bgColor)}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { ImageRenderer, RenderRequest, UrlImage } from \"../types.js\";\n\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_CODECOGS_BASE_URL = \"https://latex.codecogs.com\";\nconst DEFAULT_CODECOGS_DPI = 200;\nconst MATH_FENCE_LANGUAGES: ReadonlySet<string> = new Set([\"katex\", \"latex\", \"math\", \"tex\"]);\n\nexport interface CodeCogsRendererOptions {\n readonly baseUrl?: string;\n readonly dpi?: number;\n}\n\n/**\n * Produces deterministic CodeCogs `png.image` URLs for display math.\n */\nexport class CodeCogsRenderer implements ImageRenderer {\n private readonly baseUrl: string;\n private readonly dpi: number;\n\n constructor(options: CodeCogsRendererOptions = {}) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_CODECOGS_BASE_URL);\n this.dpi = options.dpi ?? DEFAULT_CODECOGS_DPI;\n\n if (!Number.isInteger(this.dpi) || this.dpi <= 0) {\n throw new RangeError(\"dpi must be a positive integer\");\n }\n }\n\n canRender(req: RenderRequest): boolean {\n return MATH_FENCE_LANGUAGES.has(normalizeFenceLanguage(req.lang));\n }\n\n async render(req: RenderRequest): Promise<(UrlImage & { readonly altText: string }) | null> {\n if (!this.canRender(req)) {\n return null;\n }\n\n const formula = `\\\\dpi{${String(this.dpi)}} ${req.source}`;\n const imageUrl = `${this.baseUrl}/png.image?${encodeURIComponent(formula)}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { ImageRenderer, RenderRequest, UrlImage } from \"../types.js\";\n\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_QUICKCHART_BASE_URL = \"https://quickchart.io\";\nconst DEFAULT_QUICKCHART_WIDTH = 500;\nconst DEFAULT_QUICKCHART_HEIGHT = 300;\nconst DEFAULT_QUICKCHART_BACKGROUND = \"white\";\nconst DEFAULT_QUICKCHART_DEVICE_PIXEL_RATIO = 2;\nconst CHART_FENCE_LANGUAGES: ReadonlySet<string> = new Set([\n \"chart\",\n \"chart.js\",\n \"chartjs\",\n \"quickchart\",\n]);\n\nexport interface QuickChartRendererOptions {\n readonly baseUrl?: string;\n readonly width?: number;\n readonly height?: number;\n readonly backgroundColor?: string;\n readonly devicePixelRatio?: number;\n}\n\n/**\n * Produces full, durable QuickChart GET URLs. It never uses the expiring\n * `/chart/create` short-URL API.\n */\nexport class QuickChartRenderer implements ImageRenderer {\n private readonly baseUrl: string;\n private readonly width: number;\n private readonly height: number;\n private readonly backgroundColor: string;\n private readonly devicePixelRatio: number;\n\n constructor(options: QuickChartRendererOptions = {}) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl ?? DEFAULT_QUICKCHART_BASE_URL);\n this.width = options.width ?? DEFAULT_QUICKCHART_WIDTH;\n this.height = options.height ?? DEFAULT_QUICKCHART_HEIGHT;\n this.backgroundColor = options.backgroundColor ?? DEFAULT_QUICKCHART_BACKGROUND;\n this.devicePixelRatio = options.devicePixelRatio ?? DEFAULT_QUICKCHART_DEVICE_PIXEL_RATIO;\n\n if (!Number.isInteger(this.width) || this.width <= 0) {\n throw new RangeError(\"width must be a positive integer\");\n }\n if (!Number.isInteger(this.height) || this.height <= 0) {\n throw new RangeError(\"height must be a positive integer\");\n }\n if (!Number.isFinite(this.devicePixelRatio) || this.devicePixelRatio <= 0) {\n throw new RangeError(\"devicePixelRatio must be positive\");\n }\n }\n\n canRender(req: RenderRequest): boolean {\n return CHART_FENCE_LANGUAGES.has(normalizeFenceLanguage(req.lang));\n }\n\n async render(req: RenderRequest): Promise<(UrlImage & { readonly altText: string }) | null> {\n if (!this.canRender(req)) {\n return null;\n }\n\n const query = [\n `c=${encodeURIComponent(req.source)}`,\n `width=${String(this.width)}`,\n `height=${String(this.height)}`,\n `backgroundColor=${encodeURIComponent(this.backgroundColor)}`,\n `devicePixelRatio=${String(this.devicePixelRatio)}`,\n \"format=png\",\n ].join(\"&\");\n const imageUrl = `${this.baseUrl}/chart?${query}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"file":"renderers.js","names":[],"sources":["../src/constants.ts","../src/renderers/encoding.ts","../src/errors.ts","../src/renderers/renderer-options.ts","../src/renderers/url-utils.ts","../src/renderers/kroki-renderer.ts","../src/renderers/mermaid-ink-renderer.ts","../src/renderers/codecogs-renderer.ts","../src/renderers/quickchart-renderer.ts"],"sourcesContent":["/**\n * Named Slack Block Kit limits.\n * Sources: https://docs.slack.dev/block-kit and block reference pages (July 2026 research).\n */\n\n/** https://docs.slack.dev/block-kit */\nexport const MAX_BLOCKS_PER_MESSAGE = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/section-block */\nexport const SECTION_TEXT_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_TEXT_MAX_CHARS = 150;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/header-block */\nexport const HEADER_LEVEL_MAX = 4;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_URL_MAX_CHARS = 3000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/image-block */\nexport const IMAGE_ALT_MAX_CHARS = 2000;\n\n/** slackmark renderer safety limit for retained/uploaded image bytes. */\nexport const RENDERED_IMAGE_MAX_BYTES: number = 10 * 1024 * 1024;\n\n/** Portable filename component limit used by renderer output validation. */\nexport const RENDERED_IMAGE_FILENAME_MAX_CHARS = 255;\n\n/** Defensive upper bound for Slack file IDs returned by uploaders. */\nexport const SLACK_FILE_ID_MAX_CHARS = 255;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/context-block */\nexport const CONTEXT_ELEMENTS_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/markdown-block */\nexport const MARKDOWN_CUMULATIVE_MAX_CHARS = 12_000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_ROWS = 100;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_MAX_COLS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/table-block */\nexport const TABLE_CELL_CHARS_MAX = 10_000;\n\n/** Spec decision: prefer `table` up to this many rows (incl. header). */\nexport const TABLE_PREFERRED_MAX_ROWS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_MAX_DATA_ROWS = 200;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-table-block */\nexport const DATA_TABLE_CELL_CHARS_MAX = 20_000;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_TITLE_MAX_CHARS = 50;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_LABEL_MAX_CHARS = 20;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SEGMENTS_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_SERIES_MAX = 12;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block */\nexport const CHART_POINTS_MAX = 20;\n\n/**\n * Community-reported cap (ENG-4936); not in official docs.\n * Enforced defensively with degradation.\n */\nexport const DATA_VISUALIZATION_MAX_PER_MESSAGE = 2;\n\n/** https://docs.slack.dev/reference/methods/chat.postMessage#truncating */\nexport const MESSAGE_TEXT_SAFETY_MAX_CHARS = 40_000;\n\n/** Undocumented; defensive clamp for rich_text_list.indent. */\nexport const RICH_TEXT_LIST_INDENT_MAX = 6;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_CHILDREN_MAX = 10;\n\n/** https://docs.slack.dev/reference/block-kit/blocks/container-block */\nexport const CONTAINER_TITLE_MAX_CHARS = 150;\n\n/** Cell wrap heuristic for table column_settings.is_wrapped. */\nexport const TABLE_CELL_WRAP_THRESHOLD = 40;\n\nexport const ELLIPSIS = \"…\";\n","const BASE64URL_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\n/**\n * Kroki and mermaid.ink both accept zlib-deflated, unpadded base64url payloads.\n */\nexport async function deflateBase64Url(value: string): Promise<string> {\n const stream = new CompressionStream(\"deflate\");\n const compressed = readAll(stream.readable);\n const writer = stream.writable.getWriter();\n\n await writer.write(new TextEncoder().encode(value));\n await writer.close();\n writer.releaseLock();\n\n return encodeBase64Url(await compressed);\n}\n\nasync function readAll(stream: GfmReadableStream<Uint8Array>): Promise<Uint8Array> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let length = 0;\n\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n if (result.value !== undefined) {\n chunks.push(result.value);\n length += result.value.byteLength;\n }\n }\n reader.releaseLock();\n\n const output = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n output.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return output;\n}\n\nfunction encodeBase64Url(bytes: Uint8Array): string {\n const output: string[] = [];\n for (let index = 0; index < bytes.length; index += 3) {\n const first = bytes[index] ?? 0;\n const second = bytes[index + 1];\n const third = bytes[index + 2];\n\n output.push(\n BASE64URL_ALPHABET[first >> 2] ?? \"\",\n BASE64URL_ALPHABET[((first & 0b11) << 4) | ((second ?? 0) >> 4)] ?? \"\",\n );\n if (second !== undefined) {\n output.push(BASE64URL_ALPHABET[((second & 0b1111) << 2) | ((third ?? 0) >> 6)] ?? \"\");\n }\n if (third !== undefined) {\n output.push(BASE64URL_ALPHABET[third & 0b11_1111] ?? \"\");\n }\n }\n return output.join(\"\");\n}\n","import type { UploadReceipt } from \"./receipts.js\";\n\n/**\n * Registry-keyed markers, not module-local symbols.\n *\n * Each published entry (`slackmark`, `slackmark/renderers`, `slackmark/slack`) is bundled\n * without code splitting, so every entry carries its own copy of these classes and\n * `instanceof` is false for an error that crosses an entry boundary. `Symbol.for` keys are\n * shared by every copy, which is what makes the exported guards below reliable. Prefer\n * those guards to `instanceof` for any error that can cross an entry.\n */\nconst RECEIPT_SNAPSHOT_LOCK = Symbol.for(\"slackmark.receiptSnapshotLock\");\nconst OPERATION_ERROR_CARRIER = Symbol.for(\"slackmark.operationErrorCarrier\");\nconst CONFIGURATION_ERROR_BRAND = Symbol.for(\"slackmark.error.configuration\");\nconst OPERATION_ERROR_BRAND = Symbol.for(\"slackmark.error.operation\");\n\n/**\n * Marks a class prototype so instances from any bundled copy answer to one identity.\n * Subclasses inherit the brand, and instances carry no extra own property.\n */\nexport function brandErrorPrototype(prototype: object, brand: symbol): void {\n Object.defineProperty(prototype, brand, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n}\n\n/**\n * Reads a brand without trusting the value: a hostile getter must not escape a guard.\n */\nexport function hasErrorBrand(value: unknown, brand: symbol): boolean {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n try {\n return Reflect.get(value, brand) === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Programmer/configuration error thrown only from the composition root.\n */\nexport interface ConfigurationErrorOptions {\n readonly code?: string | undefined;\n readonly stage?: string | undefined;\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\nexport class ConfigurationError extends Error {\n static {\n brandErrorPrototype(this.prototype, CONFIGURATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: string;\n readonly stage: string | undefined;\n readonly retryable: false;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, options: ConfigurationErrorOptions = {}) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"ConfigurationError\";\n this.code = options.code ?? \"invalid_configuration\";\n this.stage = options.stage;\n this.retryable = false;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport const OperationErrorCode = {\n Aborted: \"operation_aborted\",\n DeadlineExceeded: \"operation_deadline_exceeded\",\n Shutdown: \"operation_shutdown\",\n} as const;\n\nexport type OperationErrorCode = (typeof OperationErrorCode)[keyof typeof OperationErrorCode];\n\nexport interface OperationErrorOptions {\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Operational control-flow error. These failures are never degradations.\n */\nexport class OperationError extends Error {\n static {\n brandErrorPrototype(this.prototype, OPERATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: OperationErrorCode;\n readonly stage: string;\n readonly retryable: boolean;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(\n message: string,\n code: OperationErrorCode,\n stage: string,\n retryable: boolean,\n options: OperationErrorOptions = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"OperationError\";\n this.code = code;\n this.stage = stage;\n this.retryable = retryable;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport class OperationAbortedError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation aborted by caller\", OperationErrorCode.Aborted, stage, false, options);\n this.name = \"OperationAbortedError\";\n }\n}\n\nexport class OperationDeadlineExceededError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation deadline exceeded\", OperationErrorCode.DeadlineExceeded, stage, true, options);\n this.name = \"OperationDeadlineExceededError\";\n }\n}\n\nexport class OperationShutdownError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation interrupted by shutdown\", OperationErrorCode.Shutdown, stage, true, options);\n this.name = \"OperationShutdownError\";\n }\n}\n\n/**\n * Identifies a {@link ConfigurationError} from any entry of this package.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example a `ConfigurationError` from `slackmark/renderers` caught by code\n * that imported the class from `slackmark`.\n */\nexport function isConfigurationError(value: unknown): value is ConfigurationError {\n return hasErrorBrand(value, CONFIGURATION_ERROR_BRAND);\n}\n\n/**\n * Identifies an {@link OperationError} — abort, deadline, or shutdown — from any entry of\n * this package, including its subclasses.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example an abort raised inside `FetchSlackUploader` from `slackmark/slack`\n * caught by code that imported the class from `slackmark`. Narrow further with `code`\n * against {@link OperationErrorCode} rather than testing a subclass with `instanceof`.\n */\nexport function isOperationError(value: unknown): value is OperationError {\n return hasErrorBrand(value, OPERATION_ERROR_BRAND);\n}\n\nexport function cloneOperationError(error: OperationError, fallbackStage: string): OperationError {\n const stage = error.stage.length > 0 ? error.stage : fallbackStage;\n const options: OperationErrorOptions = {\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n };\n let cloned: OperationError;\n switch (error.code) {\n case OperationErrorCode.Aborted:\n cloned = new OperationAbortedError(stage, options);\n break;\n case OperationErrorCode.DeadlineExceeded:\n cloned = new OperationDeadlineExceededError(stage, options);\n break;\n case OperationErrorCode.Shutdown:\n cloned = new OperationShutdownError(stage, options);\n break;\n }\n Reflect.defineProperty(cloned, OPERATION_ERROR_CARRIER, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n return cloned;\n}\n\nexport function isOperationErrorCarrier(error: OperationError): boolean {\n return Reflect.get(error, OPERATION_ERROR_CARRIER) === true;\n}\n\nexport function cloneConfigurationError(error: ConfigurationError): ConfigurationError {\n return new ConfigurationError(error.message, {\n code: error.code,\n stage: error.stage,\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n });\n}\n\nexport function attachReceipts(\n error: unknown,\n receipts: ReadonlyArray<UploadReceipt>,\n settledReceipts?: Promise<ReadonlyArray<UploadReceipt>>,\n): unknown {\n if (!(error instanceof Error)) {\n return error;\n }\n try {\n if (Reflect.get(error, RECEIPT_SNAPSHOT_LOCK) === true) {\n return error;\n }\n } catch {\n return error;\n }\n let existing: ReadonlyArray<UploadReceipt> = [];\n try {\n const candidate = Reflect.get(error, \"receipts\");\n if (Array.isArray(candidate)) {\n existing = candidate.filter(isUploadReceipt);\n }\n } catch {\n existing = [];\n }\n Reflect.defineProperty(error, \"receipts\", {\n configurable: true,\n enumerable: true,\n value: freezeReceipts(mergeReceipts(existing, receipts)),\n writable: false,\n });\n if (settledReceipts !== undefined) {\n const finalReceipts = freezeSettledReceipts(settledReceipts, receipts);\n Reflect.defineProperty(error, \"settledReceipts\", {\n configurable: true,\n enumerable: true,\n value: finalReceipts,\n writable: false,\n });\n }\n return error;\n}\n\nexport function lockReceiptSnapshot(error: unknown): unknown {\n if (error instanceof Error) {\n Reflect.defineProperty(error, RECEIPT_SNAPSHOT_LOCK, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n }\n return error;\n}\n\nasync function freezeSettledReceipts(\n settledReceipts: Promise<ReadonlyArray<UploadReceipt>>,\n fallback: ReadonlyArray<UploadReceipt>,\n): Promise<ReadonlyArray<UploadReceipt>> {\n try {\n return freezeReceipts(await settledReceipts);\n } catch {\n return freezeReceipts(fallback);\n }\n}\n\nfunction mergeReceipts(\n existing: ReadonlyArray<UploadReceipt>,\n incoming: ReadonlyArray<UploadReceipt>,\n): ReadonlyArray<UploadReceipt> {\n const existingGroups = groupReceipts(existing);\n const incomingGroups = groupReceipts(incoming);\n const merged: UploadReceipt[] = [...incoming];\n for (const [key, values] of existingGroups) {\n const overlap = incomingGroups.get(key)?.length ?? 0;\n if (values.length > overlap) {\n merged.push(...values.slice(overlap));\n }\n }\n return merged;\n}\n\nfunction groupReceipts(\n receipts: ReadonlyArray<UploadReceipt>,\n): ReadonlyMap<string, ReadonlyArray<UploadReceipt>> {\n const grouped = new Map<string, UploadReceipt[]>();\n for (const receipt of receipts) {\n const key = receiptKey(receipt);\n const values = grouped.get(key);\n if (values === undefined) {\n grouped.set(key, [receipt]);\n } else {\n values.push(receipt);\n }\n }\n return grouped;\n}\n\nfunction receiptKey(receipt: UploadReceipt): string {\n return [\n receipt.provider,\n receipt.phase,\n receipt.fileId ?? \"\",\n String(receipt.shared),\n receipt.processing,\n String(receipt.status ?? \"\"),\n String(receipt.retryAfterMs ?? \"\"),\n receipt.providerCode ?? \"\",\n receipt.retrySafety,\n ].join(\"\\u0000\");\n}\n\nfunction freezeReceipts(receipts: ReadonlyArray<UploadReceipt>): ReadonlyArray<UploadReceipt> {\n return Object.freeze(receipts.map((receipt) => Object.freeze({ ...receipt })));\n}\n\nfunction isUploadReceipt(value: unknown): value is UploadReceipt {\n return typeof value === \"object\" && value !== null && Reflect.get(value, \"kind\") === \"upload\";\n}\n","import { ConfigurationError } from \"../errors.js\";\n\nexport function snapshotRendererOptions<T extends object>(\n options: T,\n allowed: ReadonlyArray<string>,\n label: string,\n): T {\n if (typeof options !== \"object\" || options === null || Array.isArray(options)) {\n throw invalidRendererOptions(`${label} options must be a plain object`);\n }\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(options);\n keys = Object.keys(options);\n } catch (cause) {\n throw invalidRendererOptions(`${label} options could not be inspected`, cause);\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw invalidRendererOptions(`${label} options must be a plain object`);\n }\n const allowedKeys = new Set(allowed);\n const snapshot: Record<string, unknown> = {};\n for (const key of keys) {\n if (!allowedKeys.has(key)) {\n throw invalidRendererOptions(`Unknown ${label} option: ${key}`);\n }\n try {\n snapshot[key] = Reflect.get(options, key);\n } catch (cause) {\n throw invalidRendererOptions(`${label}.${key} could not be read`, cause);\n }\n }\n return Object.freeze(snapshot) as T;\n}\n\nexport function invalidRendererOptions(message: string, cause?: unknown): ConfigurationError {\n return new ConfigurationError(message, {\n code: \"invalid_renderer_options\",\n stage: \"configuration\",\n cause,\n });\n}\n","import { isConfigurationError } from \"../errors.js\";\nimport { invalidRendererOptions } from \"./renderer-options.js\";\n\nexport function normalizeBaseUrl(baseUrl: string): string {\n if (typeof baseUrl !== \"string\" || baseUrl.length === 0 || baseUrl !== baseUrl.trim()) {\n throw invalidRendererOptions(\"baseUrl must be a nonempty trimmed string\");\n }\n const normalized = baseUrl.replace(/\\/+$/u, \"\");\n try {\n const parsed = new URL(normalized);\n if (parsed.protocol !== \"https:\" || parsed.username.length > 0 || parsed.password.length > 0) {\n throw invalidRendererOptions(\"baseUrl must be credential-free absolute HTTPS\");\n }\n } catch (cause) {\n if (isConfigurationError(cause)) {\n throw cause;\n }\n throw invalidRendererOptions(\"baseUrl must be credential-free absolute HTTPS\", cause);\n }\n return normalized;\n}\n\nexport function normalizeFenceLanguage(lang: string): string {\n return lang.trim().toLowerCase();\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { OperationContext, RenderRequest, UrlImage, UrlImageRenderer } from \"../types.js\";\n\nimport { deflateBase64Url } from \"./encoding.js\";\nimport { invalidRendererOptions, snapshotRendererOptions } from \"./renderer-options.js\";\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_KROKI_BASE_URL = \"https://kroki.io\";\n\n/**\n * Fence-language aliases for Kroki's supported diagram types.\n *\n * @see https://docs.kroki.io/kroki/setup/usage/\n */\nexport const KROKI_DIAGRAM_TYPES: Readonly<Record<string, string>> = Object.freeze({\n blockdiag: \"blockdiag\",\n bpmn: \"bpmn\",\n bytefield: \"bytefield\",\n c4: \"c4plantuml\",\n c4plantuml: \"c4plantuml\",\n d2: \"d2\",\n dbml: \"dbml\",\n ditaa: \"ditaa\",\n dot: \"graphviz\",\n erd: \"erd\",\n excalidraw: \"excalidraw\",\n graphviz: \"graphviz\",\n mermaid: \"mermaid\",\n nomnoml: \"nomnoml\",\n pikchr: \"pikchr\",\n plantuml: \"plantuml\",\n puml: \"plantuml\",\n structurizr: \"structurizr\",\n svgbob: \"svgbob\",\n symbolator: \"symbolator\",\n tikz: \"tikz\",\n umlet: \"umlet\",\n vega: \"vega\",\n \"vega-lite\": \"vegalite\",\n vegalite: \"vegalite\",\n wavedrom: \"wavedrom\",\n wireviz: \"wireviz\",\n});\n\nexport interface KrokiRendererOptions {\n readonly baseUrl?: string;\n /**\n * Additional or replacement fence-language aliases, merged over the defaults.\n */\n readonly diagramTypes?: Readonly<Record<string, string>>;\n}\n\n/**\n * Produces durable Kroki GET URLs without performing network I/O.\n */\nexport class KrokiRenderer implements UrlImageRenderer {\n readonly id: string;\n readonly output: \"url\";\n private readonly baseUrl: string;\n private readonly diagramTypes: Readonly<Record<string, string>>;\n\n constructor(options: KrokiRendererOptions = {}) {\n const validated = snapshotRendererOptions(\n options,\n [\"baseUrl\", \"diagramTypes\"],\n \"KrokiRenderer\",\n );\n this.id = \"kroki\";\n this.output = \"url\";\n this.baseUrl = normalizeBaseUrl(\n validated.baseUrl === undefined ? DEFAULT_KROKI_BASE_URL : validated.baseUrl,\n );\n this.diagramTypes = Object.freeze({\n ...KROKI_DIAGRAM_TYPES,\n ...validateDiagramTypes(validated.diagramTypes),\n });\n }\n\n canRender(req: RenderRequest): boolean {\n return this.diagramTypes[normalizeFenceLanguage(req.lang)] !== undefined;\n }\n\n async render(req: RenderRequest, _context: OperationContext): Promise<UrlImage | null> {\n const diagramType = this.diagramTypes[normalizeFenceLanguage(req.lang)];\n if (diagramType === undefined) {\n return null;\n }\n\n const encoded = await deflateBase64Url(req.source);\n const imageUrl = `${this.baseUrl}/${encodeURIComponent(diagramType)}/png/${encoded}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n\nfunction validateDiagramTypes(\n value: Readonly<Record<string, string>> | undefined,\n): Readonly<Record<string, string>> {\n if (value === undefined) {\n return {};\n }\n let keys: ReadonlyArray<string>;\n try {\n keys = Object.keys(value);\n } catch (cause) {\n throw invalidRendererOptions(\"KrokiRenderer.diagramTypes could not be inspected\", cause);\n }\n const snapshot = snapshotRendererOptions(value, keys, \"KrokiRenderer.diagramTypes\");\n for (const [language, diagramType] of Object.entries(snapshot)) {\n if (language.length === 0 || typeof diagramType !== \"string\" || diagramType.length === 0) {\n throw invalidRendererOptions(\"KrokiRenderer.diagramTypes values must be nonempty strings\");\n }\n }\n return snapshot;\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { OperationContext, RenderRequest, UrlImage, UrlImageRenderer } from \"../types.js\";\n\nimport { deflateBase64Url } from \"./encoding.js\";\nimport { invalidRendererOptions, snapshotRendererOptions } from \"./renderer-options.js\";\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_MERMAID_INK_BASE_URL = \"https://mermaid.ink\";\nconst DEFAULT_MERMAID_INK_BACKGROUND = \"!white\";\n\nexport type MermaidInkTheme = \"default\" | \"neutral\" | \"dark\" | \"forest\";\n\nexport interface MermaidInkRendererOptions {\n readonly baseUrl?: string;\n readonly theme?: MermaidInkTheme;\n /**\n * mermaid.ink color value, such as `!white` or `FF0000`.\n */\n readonly bgColor?: string;\n}\n\ninterface MermaidInkState {\n readonly code: string;\n readonly mermaid: {\n readonly theme: MermaidInkTheme;\n };\n}\n\n/**\n * Produces mermaid.ink pako-state PNG URLs without performing network I/O.\n */\nexport class MermaidInkRenderer implements UrlImageRenderer {\n readonly id: string;\n readonly output: \"url\";\n private readonly baseUrl: string;\n private readonly theme: MermaidInkTheme;\n private readonly bgColor: string;\n\n constructor(options: MermaidInkRendererOptions = {}) {\n const validated = snapshotRendererOptions(\n options,\n [\"baseUrl\", \"theme\", \"bgColor\"],\n \"MermaidInkRenderer\",\n );\n this.id = \"mermaid-ink\";\n this.output = \"url\";\n this.baseUrl = normalizeBaseUrl(\n validated.baseUrl === undefined ? DEFAULT_MERMAID_INK_BASE_URL : validated.baseUrl,\n );\n this.theme = validated.theme === undefined ? \"default\" : validated.theme;\n this.bgColor =\n validated.bgColor === undefined ? DEFAULT_MERMAID_INK_BACKGROUND : validated.bgColor;\n if (\n ![\"default\", \"neutral\", \"dark\", \"forest\"].includes(this.theme) ||\n typeof this.bgColor !== \"string\" ||\n this.bgColor.length === 0\n ) {\n throw invalidRendererOptions(\"MermaidInkRenderer theme or bgColor is invalid\");\n }\n }\n\n canRender(req: RenderRequest): boolean {\n return normalizeFenceLanguage(req.lang) === \"mermaid\";\n }\n\n async render(req: RenderRequest, _context: OperationContext): Promise<UrlImage | null> {\n if (!this.canRender(req)) {\n return null;\n }\n\n const state: MermaidInkState = {\n code: req.source,\n mermaid: { theme: this.theme },\n };\n const encoded = await deflateBase64Url(JSON.stringify(state));\n const imageUrl =\n `${this.baseUrl}/img/pako:${encoded}` +\n `?type=png&bgColor=${encodeURIComponent(this.bgColor)}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { OperationContext, RenderRequest, UrlImage, UrlImageRenderer } from \"../types.js\";\n\nimport { invalidRendererOptions, snapshotRendererOptions } from \"./renderer-options.js\";\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_CODECOGS_BASE_URL = \"https://latex.codecogs.com\";\nconst DEFAULT_CODECOGS_DPI = 200;\nconst MATH_FENCE_LANGUAGES: ReadonlySet<string> = new Set([\"katex\", \"latex\", \"math\", \"tex\"]);\n\nexport interface CodeCogsRendererOptions {\n readonly baseUrl?: string;\n readonly dpi?: number;\n}\n\n/**\n * Produces deterministic CodeCogs `png.image` URLs for display math.\n */\nexport class CodeCogsRenderer implements UrlImageRenderer {\n readonly id: string;\n readonly output: \"url\";\n private readonly baseUrl: string;\n private readonly dpi: number;\n\n constructor(options: CodeCogsRendererOptions = {}) {\n const validated = snapshotRendererOptions(options, [\"baseUrl\", \"dpi\"], \"CodeCogsRenderer\");\n this.id = \"codecogs\";\n this.output = \"url\";\n this.baseUrl = normalizeBaseUrl(\n validated.baseUrl === undefined ? DEFAULT_CODECOGS_BASE_URL : validated.baseUrl,\n );\n this.dpi = validated.dpi === undefined ? DEFAULT_CODECOGS_DPI : validated.dpi;\n\n if (!Number.isInteger(this.dpi) || this.dpi <= 0) {\n throw invalidRendererOptions(\"dpi must be a positive integer\");\n }\n }\n\n canRender(req: RenderRequest): boolean {\n return MATH_FENCE_LANGUAGES.has(normalizeFenceLanguage(req.lang));\n }\n\n async render(req: RenderRequest, _context: OperationContext): Promise<UrlImage | null> {\n if (!this.canRender(req)) {\n return null;\n }\n\n const formula = `\\\\dpi{${String(this.dpi)}} ${req.source}`;\n const imageUrl = `${this.baseUrl}/png.image?${encodeURIComponent(formula)}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n","import { IMAGE_URL_MAX_CHARS } from \"../constants.js\";\nimport type { OperationContext, RenderRequest, UrlImage, UrlImageRenderer } from \"../types.js\";\n\nimport { invalidRendererOptions, snapshotRendererOptions } from \"./renderer-options.js\";\nimport { normalizeBaseUrl, normalizeFenceLanguage } from \"./url-utils.js\";\n\nconst DEFAULT_QUICKCHART_BASE_URL = \"https://quickchart.io\";\nconst DEFAULT_QUICKCHART_WIDTH = 500;\nconst DEFAULT_QUICKCHART_HEIGHT = 300;\nconst DEFAULT_QUICKCHART_BACKGROUND = \"white\";\nconst DEFAULT_QUICKCHART_DEVICE_PIXEL_RATIO = 2;\nconst CHART_FENCE_LANGUAGES: ReadonlySet<string> = new Set([\n \"chart\",\n \"chart.js\",\n \"chartjs\",\n \"quickchart\",\n]);\n\nexport interface QuickChartRendererOptions {\n readonly baseUrl?: string;\n readonly width?: number;\n readonly height?: number;\n readonly backgroundColor?: string;\n readonly devicePixelRatio?: number;\n}\n\n/**\n * Produces full, durable QuickChart GET URLs. It never uses the expiring\n * `/chart/create` short-URL API.\n */\nexport class QuickChartRenderer implements UrlImageRenderer {\n readonly id: string;\n readonly output: \"url\";\n private readonly baseUrl: string;\n private readonly width: number;\n private readonly height: number;\n private readonly backgroundColor: string;\n private readonly devicePixelRatio: number;\n\n constructor(options: QuickChartRendererOptions = {}) {\n const validated = snapshotRendererOptions(\n options,\n [\"baseUrl\", \"width\", \"height\", \"backgroundColor\", \"devicePixelRatio\"],\n \"QuickChartRenderer\",\n );\n this.id = \"quickchart\";\n this.output = \"url\";\n this.baseUrl = normalizeBaseUrl(\n validated.baseUrl === undefined ? DEFAULT_QUICKCHART_BASE_URL : validated.baseUrl,\n );\n this.width = validated.width === undefined ? DEFAULT_QUICKCHART_WIDTH : validated.width;\n this.height = validated.height === undefined ? DEFAULT_QUICKCHART_HEIGHT : validated.height;\n this.backgroundColor =\n validated.backgroundColor === undefined\n ? DEFAULT_QUICKCHART_BACKGROUND\n : validated.backgroundColor;\n this.devicePixelRatio =\n validated.devicePixelRatio === undefined\n ? DEFAULT_QUICKCHART_DEVICE_PIXEL_RATIO\n : validated.devicePixelRatio;\n\n if (!Number.isInteger(this.width) || this.width <= 0) {\n throw invalidRendererOptions(\"width must be a positive integer\");\n }\n if (!Number.isInteger(this.height) || this.height <= 0) {\n throw invalidRendererOptions(\"height must be a positive integer\");\n }\n if (!Number.isFinite(this.devicePixelRatio) || this.devicePixelRatio <= 0) {\n throw invalidRendererOptions(\"devicePixelRatio must be positive\");\n }\n if (typeof this.backgroundColor !== \"string\" || this.backgroundColor.length === 0) {\n throw invalidRendererOptions(\"backgroundColor must be a nonempty string\");\n }\n }\n\n canRender(req: RenderRequest): boolean {\n return CHART_FENCE_LANGUAGES.has(normalizeFenceLanguage(req.lang));\n }\n\n async render(req: RenderRequest, _context: OperationContext): Promise<UrlImage | null> {\n if (!this.canRender(req)) {\n return null;\n }\n\n const query = [\n `c=${encodeURIComponent(req.source)}`,\n `width=${String(this.width)}`,\n `height=${String(this.height)}`,\n `backgroundColor=${encodeURIComponent(this.backgroundColor)}`,\n `devicePixelRatio=${String(this.devicePixelRatio)}`,\n \"format=png\",\n ].join(\"&\");\n const imageUrl = `${this.baseUrl}/chart?${query}`;\n\n // https://docs.slack.dev/reference/block-kit/blocks/image-block\n if (imageUrl.length > IMAGE_URL_MAX_CHARS) {\n return null;\n }\n return {\n kind: \"url\",\n imageUrl,\n altText: req.altText,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type BytesImage, type OperationContext, type SlackUploader, type UploadReceipt } from "../types.js";
|
|
2
2
|
export interface SlackFetchRequestInit {
|
|
3
3
|
readonly method: "POST";
|
|
4
4
|
readonly headers: Readonly<Record<string, string>>;
|
|
5
5
|
readonly body: string | Uint8Array;
|
|
6
|
+
readonly signal?: AbortSignal;
|
|
6
7
|
}
|
|
7
8
|
export interface SlackFetchResponse {
|
|
8
9
|
readonly ok: boolean;
|
|
9
10
|
readonly status: number;
|
|
11
|
+
readonly headers?: {
|
|
12
|
+
get(name: string): string | null;
|
|
13
|
+
};
|
|
10
14
|
json(): Promise<unknown>;
|
|
11
15
|
}
|
|
12
16
|
export type SlackFetch = (input: string, init: SlackFetchRequestInit) => Promise<SlackFetchResponse>;
|
|
@@ -23,6 +27,8 @@ export interface FetchSlackUploaderOptions {
|
|
|
23
27
|
readonly token: string;
|
|
24
28
|
readonly fetch?: SlackFetch;
|
|
25
29
|
readonly channelId?: string;
|
|
30
|
+
readonly requestTimeoutMs?: number;
|
|
31
|
+
readonly waitForProcessing?: boolean;
|
|
26
32
|
readonly poll?: SlackUploadPollOptions;
|
|
27
33
|
}
|
|
28
34
|
/**
|
|
@@ -34,14 +40,17 @@ export declare class FetchSlackUploader implements SlackUploader {
|
|
|
34
40
|
private readonly token;
|
|
35
41
|
private readonly fetcher;
|
|
36
42
|
private readonly channelId;
|
|
43
|
+
private readonly requestTimeoutMs;
|
|
44
|
+
private readonly waitForProcessing;
|
|
37
45
|
private readonly pollIntervalMs;
|
|
38
46
|
private readonly pollMaxAttempts;
|
|
39
47
|
private readonly pollTimeoutMs;
|
|
40
48
|
private readonly sleep;
|
|
41
49
|
private readonly clock;
|
|
42
50
|
constructor(options: FetchSlackUploaderOptions);
|
|
43
|
-
upload(img: BytesImage): Promise<{
|
|
51
|
+
upload(img: BytesImage, context: OperationContext): Promise<{
|
|
44
52
|
readonly fileId: string;
|
|
53
|
+
readonly receipt: UploadReceipt;
|
|
45
54
|
}>;
|
|
46
55
|
private getUploadTarget;
|
|
47
56
|
private uploadBytes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-slack-uploader.d.ts","sourceRoot":"","sources":["../../src/slack/fetch-slack-uploader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"fetch-slack-uploader.d.ts","sourceRoot":"","sources":["../../src/slack/fetch-slack-uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAwBrB,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACxD,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,CACvB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,qBAAqB,KACxB,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC,MAAM,MAAM,gBAAgB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AACvE,MAAM,MAAM,gBAAgB,GAAG,MAAM,MAAM,CAAC;AAE5C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC;CACxC;AAoBD;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IAEzC,YAAY,OAAO,EAAE,yBAAyB,EAY7C;IAEK,MAAM,CACV,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;KAAE,CAAC,CAqEvE;YAEa,eAAe;YAqBf,WAAW;YAqCX,cAAc;YA2Bd,kBAAkB;YA4DlB,YAAY;CA6D3B"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { type UploadReceipt } from "../types.js";
|
|
1
2
|
export declare const SlackUploadStage: {
|
|
3
|
+
readonly Admission: "admission";
|
|
2
4
|
readonly GetUploadUrl: "get-upload-url";
|
|
3
5
|
readonly UploadBytes: "upload-bytes";
|
|
4
6
|
readonly CompleteUpload: "complete-upload";
|
|
@@ -8,8 +10,11 @@ export declare const SlackUploadStage: {
|
|
|
8
10
|
export type SlackUploadStage = (typeof SlackUploadStage)[keyof typeof SlackUploadStage];
|
|
9
11
|
export interface SlackUploadErrorDetails {
|
|
10
12
|
readonly stage: SlackUploadStage;
|
|
11
|
-
readonly status?: number;
|
|
12
|
-
readonly code?: string;
|
|
13
|
+
readonly status?: number | undefined;
|
|
14
|
+
readonly code?: string | undefined;
|
|
15
|
+
readonly retryable?: boolean | undefined;
|
|
16
|
+
readonly retryAfterMs?: number | undefined;
|
|
17
|
+
readonly receipt?: UploadReceipt | undefined;
|
|
13
18
|
readonly cause?: unknown;
|
|
14
19
|
}
|
|
15
20
|
/**
|
|
@@ -20,6 +25,17 @@ export declare class SlackUploadError extends Error {
|
|
|
20
25
|
readonly stage: SlackUploadStage;
|
|
21
26
|
readonly status: number | undefined;
|
|
22
27
|
readonly code: string | undefined;
|
|
28
|
+
readonly retryable: boolean;
|
|
29
|
+
readonly retryAfterMs: number | undefined;
|
|
30
|
+
readonly receipt: UploadReceipt;
|
|
31
|
+
readonly receipts: ReadonlyArray<UploadReceipt>;
|
|
32
|
+
readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;
|
|
23
33
|
constructor(message: string, details: SlackUploadErrorDetails);
|
|
24
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Identifies a {@link SlackUploadError} from any entry of this package. `slackmark` and
|
|
37
|
+
* `slackmark/slack` each bundle their own copy, so `instanceof` is unreliable when the
|
|
38
|
+
* error crosses between them.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isSlackUploadError(value: unknown): value is SlackUploadError;
|
|
25
41
|
//# sourceMappingURL=slack-upload-error.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-upload-error.d.ts","sourceRoot":"","sources":["../../src/slack/slack-upload-error.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slack-upload-error.d.ts","sourceRoot":"","sources":["../../src/slack/slack-upload-error.ts"],"names":[],"mappings":"AACA,OAAO,EAA8C,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAK7F,eAAO,MAAM,gBAAgB;aAC3B,SAAS,EAAE,WAAW;aACtB,YAAY,EAAE,gBAAgB;aAC9B,WAAW,EAAE,cAAc;aAC3B,cAAc,EAAE,iBAAiB;aACjC,QAAQ,EAAE,WAAW;aACrB,iBAAiB,EAAE,oBAAoB;CAC/B,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAExF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IAKzC,SAAkB,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAChD,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;IAEhE,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,EAwB5D;CACF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E"}
|
package/dist/slack.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { FetchSlackUploader } from "./slack/fetch-slack-uploader.js";
|
|
5
5
|
export type { FetchSlackUploaderOptions, SlackFetch, SlackFetchRequestInit, SlackFetchResponse, SlackUploadClock, SlackUploadPollOptions, SlackUploadSleep, } from "./slack/fetch-slack-uploader.js";
|
|
6
|
-
export { SlackUploadError, SlackUploadStage } from "./slack/slack-upload-error.js";
|
|
6
|
+
export { SlackUploadError, SlackUploadStage, isSlackUploadError, } from "./slack/slack-upload-error.js";
|
|
7
7
|
export type { SlackUploadErrorDetails } from "./slack/slack-upload-error.js";
|
|
8
8
|
//# sourceMappingURL=slack.d.ts.map
|
package/dist/slack.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,YAAY,EACV,yBAAyB,EACzB,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,
|
|
1
|
+
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,YAAY,EACV,yBAAyB,EACzB,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC"}
|