@athenaintel/react 0.40.2 → 0.41.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 +61 -0
- package/dist/agent-runtime/src/subscription-wake-event.cjs +87 -2
- package/dist/agent-runtime/src/subscription-wake-event.cjs.map +1 -1
- package/dist/agent-runtime/src/subscription-wake-event.js +87 -2
- package/dist/agent-runtime/src/subscription-wake-event.js.map +1 -1
- package/dist/chat/athena-citation-links.cjs +23 -2
- package/dist/chat/athena-citation-links.cjs.map +1 -1
- package/dist/chat/athena-citation-links.d.ts +5 -0
- package/dist/chat/athena-citation-links.js +23 -2
- package/dist/chat/athena-citation-links.js.map +1 -1
- package/dist/chat-ui/index.d.ts +1 -1
- package/dist/chat-ui/mentions/mention-chip.cjs +118 -7
- package/dist/chat-ui/mentions/mention-chip.cjs.map +1 -1
- package/dist/chat-ui/mentions/mention-chip.d.ts +29 -0
- package/dist/chat-ui/mentions/mention-chip.js +120 -9
- package/dist/chat-ui/mentions/mention-chip.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-message-body.cjs +2 -1
- package/dist/chat-ui/rich-text/chat-message-body.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-message-body.js +2 -1
- package/dist/chat-ui/rich-text/chat-message-body.js.map +1 -1
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/references/src/anchors/file-line-range.cjs +70 -0
- package/dist/references/src/anchors/file-line-range.cjs.map +1 -0
- package/dist/references/src/anchors/file-line-range.js +70 -0
- package/dist/references/src/anchors/file-line-range.js.map +1 -0
- package/dist/references/src/anchors/format.cjs +219 -0
- package/dist/references/src/anchors/format.cjs.map +1 -0
- package/dist/references/src/anchors/format.js +219 -0
- package/dist/references/src/anchors/format.js.map +1 -0
- package/dist/references/src/anchors/parse.cjs +408 -0
- package/dist/references/src/anchors/parse.cjs.map +1 -0
- package/dist/references/src/anchors/parse.js +408 -0
- package/dist/references/src/anchors/parse.js.map +1 -0
- package/dist/references/src/anchors/serialize.cjs +185 -0
- package/dist/references/src/anchors/serialize.cjs.map +1 -0
- package/dist/references/src/anchors/serialize.js +185 -0
- package/dist/references/src/anchors/serialize.js.map +1 -0
- package/dist/references/src/anchors/types.cjs +50 -0
- package/dist/references/src/anchors/types.cjs.map +1 -0
- package/dist/references/src/anchors/types.js +50 -0
- package/dist/references/src/anchors/types.js.map +1 -0
- package/dist/references/src/formats/uri/asset-mention-uri.cjs +29 -0
- package/dist/references/src/formats/uri/asset-mention-uri.cjs.map +1 -0
- package/dist/references/src/formats/uri/asset-mention-uri.js +29 -0
- package/dist/references/src/formats/uri/asset-mention-uri.js.map +1 -0
- package/dist/references/src/formats/uri/asset-spaces-url.cjs +64 -0
- package/dist/references/src/formats/uri/asset-spaces-url.cjs.map +1 -0
- package/dist/references/src/formats/uri/asset-spaces-url.js +64 -0
- package/dist/references/src/formats/uri/asset-spaces-url.js.map +1 -0
- package/dist/references/src/formats/uri/template-placeholder.cjs +9 -0
- package/dist/references/src/formats/uri/template-placeholder.cjs.map +1 -0
- package/dist/references/src/formats/uri/template-placeholder.js +9 -0
- package/dist/references/src/formats/uri/template-placeholder.js.map +1 -0
- package/dist/references/src/sheet-name.cjs +10 -0
- package/dist/references/src/sheet-name.cjs.map +1 -0
- package/dist/references/src/sheet-name.js +10 -0
- package/dist/references/src/sheet-name.js.map +1 -0
- package/dist/references/src/version-ref.cjs +61 -0
- package/dist/references/src/version-ref.cjs.map +1 -0
- package/dist/references/src/version-ref.js +61 -0
- package/dist/references/src/version-ref.js.map +1 -0
- package/dist/styles.css +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { quoteSheetName } from "../sheet-name.js";
|
|
2
|
+
const SHORT_EXCERPT_CHARS = 8;
|
|
3
|
+
const LONG_EXCERPT_CHARS = 20;
|
|
4
|
+
function formatAnchorTime(timestamp) {
|
|
5
|
+
const parts = timestamp.split(":");
|
|
6
|
+
if (parts.length !== 3) return timestamp;
|
|
7
|
+
const [hours, minutes, seconds] = parts.map((part) => Number.parseInt(part, 10));
|
|
8
|
+
if ([hours, minutes, seconds].some((part) => Number.isNaN(part)) || hours < 0 || minutes < 0 || minutes >= 60 || seconds < 0 || seconds >= 60) {
|
|
9
|
+
return timestamp;
|
|
10
|
+
}
|
|
11
|
+
const paddedSeconds = seconds.toString().padStart(2, "0");
|
|
12
|
+
if (hours > 0) return `${hours}:${minutes.toString().padStart(2, "0")}:${paddedSeconds}`;
|
|
13
|
+
return `${minutes}:${paddedSeconds}`;
|
|
14
|
+
}
|
|
15
|
+
function slideName(anchor) {
|
|
16
|
+
return anchor.slideIndex != null ? `Slide ${anchor.slideIndex}` : "Slide";
|
|
17
|
+
}
|
|
18
|
+
function truncate(text, max) {
|
|
19
|
+
if (text.length <= max) return text;
|
|
20
|
+
return `${text.slice(0, max)}…`;
|
|
21
|
+
}
|
|
22
|
+
function formatFileLineRange(anchor, mode) {
|
|
23
|
+
const path = mode === "short" ? anchor.path.split("/").pop() ?? anchor.path : anchor.path;
|
|
24
|
+
const lines = anchor.startLine === anchor.endLine ? `${anchor.startLine}` : `${anchor.startLine}-${anchor.endLine}`;
|
|
25
|
+
return `${path}:${lines}`;
|
|
26
|
+
}
|
|
27
|
+
function formatAnchorShort(anchor) {
|
|
28
|
+
switch (anchor.type) {
|
|
29
|
+
case "cell":
|
|
30
|
+
return `cell ${truncate(anchor.cellId, SHORT_EXCERPT_CHARS)}`;
|
|
31
|
+
case "cell_range":
|
|
32
|
+
return `cells ${truncate(anchor.startCellId, SHORT_EXCERPT_CHARS)} - ${truncate(anchor.endCellId, SHORT_EXCERPT_CHARS)}`;
|
|
33
|
+
case "file_line_range":
|
|
34
|
+
return formatFileLineRange(anchor, "short");
|
|
35
|
+
case "line":
|
|
36
|
+
return `L${anchor.line}`;
|
|
37
|
+
case "line_range":
|
|
38
|
+
return `L${anchor.startLine}-${anchor.endLine}`;
|
|
39
|
+
case "msg":
|
|
40
|
+
return "Msg";
|
|
41
|
+
case "msg_range":
|
|
42
|
+
return "Msgs";
|
|
43
|
+
case "msg_block":
|
|
44
|
+
return `¶${anchor.block}`;
|
|
45
|
+
case "msg_section":
|
|
46
|
+
return truncate(anchor.heading, SHORT_EXCERPT_CHARS);
|
|
47
|
+
case "msg_text":
|
|
48
|
+
return truncate(anchor.text, SHORT_EXCERPT_CHARS);
|
|
49
|
+
case "tool_call":
|
|
50
|
+
return "Tool call";
|
|
51
|
+
case "page":
|
|
52
|
+
return `p.${anchor.page}`;
|
|
53
|
+
case "page_range":
|
|
54
|
+
return `p.${anchor.startPage}-${anchor.endPage}`;
|
|
55
|
+
case "page_rect":
|
|
56
|
+
return `p.${anchor.page} (Region)`;
|
|
57
|
+
case "page_text":
|
|
58
|
+
return `p.${anchor.page}`;
|
|
59
|
+
case "path":
|
|
60
|
+
return anchor.line != null ? `${truncate(anchor.path, SHORT_EXCERPT_CHARS)}:${anchor.line}` : truncate(anchor.path, SHORT_EXCERPT_CHARS);
|
|
61
|
+
case "pm_node":
|
|
62
|
+
case "pm_node_range":
|
|
63
|
+
case "pm_mark":
|
|
64
|
+
return "§";
|
|
65
|
+
case "pixel_range":
|
|
66
|
+
return "Region";
|
|
67
|
+
case "rect":
|
|
68
|
+
return "Region";
|
|
69
|
+
case "shape": {
|
|
70
|
+
const n = anchor.shapeIds.length;
|
|
71
|
+
return n === 1 ? `${slideName(anchor)} • shape` : `${slideName(anchor)} • ${n} shapes`;
|
|
72
|
+
}
|
|
73
|
+
case "sheet_cell":
|
|
74
|
+
return anchor.cell;
|
|
75
|
+
case "sheet_range":
|
|
76
|
+
return anchor.range;
|
|
77
|
+
case "sheet_tab":
|
|
78
|
+
return "Sheet tab";
|
|
79
|
+
case "slide":
|
|
80
|
+
return slideName(anchor);
|
|
81
|
+
case "semantic_query":
|
|
82
|
+
return anchor.field ? `Cube · ${truncate(anchor.field, SHORT_EXCERPT_CHARS)}` : "Cube query";
|
|
83
|
+
case "sql_query":
|
|
84
|
+
return anchor.field ? `SQL · ${truncate(anchor.field, SHORT_EXCERPT_CHARS)}` : "SQL query";
|
|
85
|
+
case "time":
|
|
86
|
+
return formatAnchorTime(anchor.time);
|
|
87
|
+
case "time_range":
|
|
88
|
+
return `${formatAnchorTime(anchor.startTime)}-${formatAnchorTime(anchor.endTime)}`;
|
|
89
|
+
case "comment":
|
|
90
|
+
case "comment_thread":
|
|
91
|
+
return "💬";
|
|
92
|
+
default:
|
|
93
|
+
return "•";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function formatAnchorLong(anchor) {
|
|
97
|
+
switch (anchor.type) {
|
|
98
|
+
case "cell":
|
|
99
|
+
return `Cell ${truncate(anchor.cellId, LONG_EXCERPT_CHARS)}`;
|
|
100
|
+
case "cell_range":
|
|
101
|
+
return `Cells ${truncate(anchor.startCellId, LONG_EXCERPT_CHARS)}–${truncate(anchor.endCellId, LONG_EXCERPT_CHARS)}`;
|
|
102
|
+
case "file_line_range":
|
|
103
|
+
return formatFileLineRange(anchor, "long");
|
|
104
|
+
case "line":
|
|
105
|
+
return `Line ${anchor.line}`;
|
|
106
|
+
case "line_range":
|
|
107
|
+
return `Lines ${anchor.startLine}–${anchor.endLine}`;
|
|
108
|
+
case "msg":
|
|
109
|
+
return "Message";
|
|
110
|
+
case "msg_range":
|
|
111
|
+
return "Messages";
|
|
112
|
+
case "msg_block":
|
|
113
|
+
return `Message block ${anchor.block}`;
|
|
114
|
+
case "msg_section":
|
|
115
|
+
return `Section · ${anchor.heading}`;
|
|
116
|
+
case "msg_text":
|
|
117
|
+
return truncate(anchor.text, LONG_EXCERPT_CHARS);
|
|
118
|
+
case "tool_call":
|
|
119
|
+
return "Tool call";
|
|
120
|
+
case "page":
|
|
121
|
+
return `Page ${anchor.page}`;
|
|
122
|
+
case "page_range":
|
|
123
|
+
return `Pages ${anchor.startPage}–${anchor.endPage}`;
|
|
124
|
+
case "page_rect":
|
|
125
|
+
return `Page ${anchor.page} (Region)`;
|
|
126
|
+
case "page_text":
|
|
127
|
+
return `Page ${anchor.page}`;
|
|
128
|
+
case "path":
|
|
129
|
+
return anchor.line != null ? `${anchor.path}:${anchor.line}${anchor.column != null ? `:${anchor.column}` : ""}` : anchor.path;
|
|
130
|
+
case "pm_node":
|
|
131
|
+
case "pm_node_range":
|
|
132
|
+
case "pm_mark":
|
|
133
|
+
return "§";
|
|
134
|
+
case "pixel_range":
|
|
135
|
+
return "Region";
|
|
136
|
+
case "rect":
|
|
137
|
+
return "Region";
|
|
138
|
+
case "shape": {
|
|
139
|
+
const n = anchor.shapeIds.length;
|
|
140
|
+
return n === 1 ? `${slideName(anchor)} — 1 shape` : `${slideName(anchor)} — ${n} shapes`;
|
|
141
|
+
}
|
|
142
|
+
case "sheet_cell":
|
|
143
|
+
return `Cell ${anchor.cell}`;
|
|
144
|
+
case "sheet_range":
|
|
145
|
+
return `Range ${anchor.range}`;
|
|
146
|
+
case "sheet_tab":
|
|
147
|
+
return "Sheet tab";
|
|
148
|
+
case "slide":
|
|
149
|
+
return slideName(anchor);
|
|
150
|
+
case "semantic_query":
|
|
151
|
+
return anchor.field ? `Cube query · ${truncate(anchor.field, LONG_EXCERPT_CHARS)}` : "Cube query";
|
|
152
|
+
case "sql_query":
|
|
153
|
+
return anchor.field ? `SQL query · ${truncate(anchor.field, LONG_EXCERPT_CHARS)}` : "SQL query";
|
|
154
|
+
case "time":
|
|
155
|
+
return formatAnchorTime(anchor.time);
|
|
156
|
+
case "time_range":
|
|
157
|
+
return `${formatAnchorTime(anchor.startTime)} – ${formatAnchorTime(anchor.endTime)}`;
|
|
158
|
+
case "comment":
|
|
159
|
+
case "comment_thread":
|
|
160
|
+
return "Comment";
|
|
161
|
+
default:
|
|
162
|
+
return "";
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function isExcerptOnlyAnchor(anchor) {
|
|
166
|
+
return anchor.type === "pm_node" || anchor.type === "pm_node_range" || anchor.type === "pm_mark" || anchor.type === "msg_text";
|
|
167
|
+
}
|
|
168
|
+
function anchorExcerpt({ anchor, meta }) {
|
|
169
|
+
if (anchor.type === "page_text") return anchor.text;
|
|
170
|
+
if (anchor.type === "msg_text") return (meta == null ? void 0 : meta.excerpt) || anchor.text;
|
|
171
|
+
return meta == null ? void 0 : meta.excerpt;
|
|
172
|
+
}
|
|
173
|
+
function formatShort(anchor, meta) {
|
|
174
|
+
const excerpt = anchorExcerpt({ anchor, meta });
|
|
175
|
+
const sheetName = meta == null ? void 0 : meta.sheetName;
|
|
176
|
+
if (excerpt) {
|
|
177
|
+
const anchorPart = formatAnchorShort(anchor);
|
|
178
|
+
if (isExcerptOnlyAnchor(anchor)) {
|
|
179
|
+
return truncate(excerpt, SHORT_EXCERPT_CHARS);
|
|
180
|
+
}
|
|
181
|
+
if (sheetName && (anchor.type === "sheet_cell" || anchor.type === "sheet_range" || anchor.type === "sheet_tab")) {
|
|
182
|
+
return anchor.type === "sheet_tab" ? sheetName : `${quoteSheetName(sheetName)}!${anchorPart}`;
|
|
183
|
+
}
|
|
184
|
+
return anchorPart;
|
|
185
|
+
}
|
|
186
|
+
if (sheetName && (anchor.type === "sheet_cell" || anchor.type === "sheet_range" || anchor.type === "sheet_tab")) {
|
|
187
|
+
return anchor.type === "sheet_tab" ? sheetName : `${quoteSheetName(sheetName)}!${formatAnchorShort(anchor)}`;
|
|
188
|
+
}
|
|
189
|
+
return formatAnchorShort(anchor);
|
|
190
|
+
}
|
|
191
|
+
function formatLong(anchor, meta) {
|
|
192
|
+
const excerpt = anchorExcerpt({ anchor, meta });
|
|
193
|
+
const sheetName = meta == null ? void 0 : meta.sheetName;
|
|
194
|
+
if (excerpt) {
|
|
195
|
+
let anchorPart = formatAnchorLong(anchor);
|
|
196
|
+
if (sheetName && (anchor.type === "sheet_cell" || anchor.type === "sheet_range" || anchor.type === "sheet_tab")) {
|
|
197
|
+
anchorPart = anchor.type === "sheet_tab" ? `Sheet tab · ${sheetName}` : `${quoteSheetName(sheetName)}!${anchor.type === "sheet_cell" ? anchor.cell : anchor.range}`;
|
|
198
|
+
}
|
|
199
|
+
if (isExcerptOnlyAnchor(anchor)) {
|
|
200
|
+
return truncate(excerpt, LONG_EXCERPT_CHARS);
|
|
201
|
+
}
|
|
202
|
+
return `${anchorPart}: ${truncate(excerpt, LONG_EXCERPT_CHARS)}`;
|
|
203
|
+
}
|
|
204
|
+
if (sheetName && (anchor.type === "sheet_cell" || anchor.type === "sheet_range" || anchor.type === "sheet_tab")) {
|
|
205
|
+
if (anchor.type === "sheet_tab") {
|
|
206
|
+
return `Sheet tab · ${sheetName}`;
|
|
207
|
+
}
|
|
208
|
+
return `${quoteSheetName(sheetName)}!${anchor.type === "sheet_cell" ? anchor.cell : anchor.range}`;
|
|
209
|
+
}
|
|
210
|
+
return formatAnchorLong(anchor);
|
|
211
|
+
}
|
|
212
|
+
function formatReferenceAnchor(anchor, mode = "long", meta) {
|
|
213
|
+
const text = mode === "short" ? formatShort(anchor, meta) : formatLong(anchor, meta);
|
|
214
|
+
return text === "" ? null : text;
|
|
215
|
+
}
|
|
216
|
+
export {
|
|
217
|
+
formatReferenceAnchor
|
|
218
|
+
};
|
|
219
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sources":["../../../../../references/src/anchors/format.ts"],"sourcesContent":["/**\n * `formatReferenceAnchor` — format an anchor into a human-readable citation line.\n *\n * Accepts the `Anchor` directly (+ optional `AssetMeta` for excerpt / sheetName context).\n * Returns `null` when there is nothing to format. Every renderer of a citation\n * chip labels its anchor with it: Olympus's mention chips and the\n * `@athenaintel/react` SDK's chat chips (through `@athenaintel/references/asset-links`).\n */\n\nimport { quoteSheetName } from '../sheet-name';\nimport type { AssetMeta } from '../types';\nimport type { Anchor, FileLineRangeAnchor, ShapeAnchor, SlideAnchor } from './types';\n\nexport type ReferenceAnchorFormatMode = 'short' | 'long';\n\nconst SHORT_EXCERPT_CHARS = 8;\nconst LONG_EXCERPT_CHARS = 20;\n\n/**\n * A stored `HH:MM:SS` time anchor as a reader sees it (`00:05:30` → `5:30`,\n * `01:05:30` → `1:05:30`); anything else is shown as written.\n */\nfunction formatAnchorTime(timestamp: string): string {\n const parts = timestamp.split(':');\n if (parts.length !== 3) return timestamp;\n const [hours, minutes, seconds] = parts.map((part) => Number.parseInt(part, 10));\n if (\n [hours, minutes, seconds].some((part) => Number.isNaN(part)) ||\n hours < 0 ||\n minutes < 0 ||\n minutes >= 60 ||\n seconds < 0 ||\n seconds >= 60\n ) {\n return timestamp;\n }\n const paddedSeconds = seconds.toString().padStart(2, '0');\n if (hours > 0) return `${hours}:${minutes.toString().padStart(2, '0')}:${paddedSeconds}`;\n return `${minutes}:${paddedSeconds}`;\n}\n\n/** `Slide N` by its 1-based display position; a slide cited by id alone is just `Slide`. */\nfunction slideName(anchor: SlideAnchor | ShapeAnchor): string {\n return anchor.slideIndex != null ? `Slide ${anchor.slideIndex}` : 'Slide';\n}\n\nfunction truncate(text: string, max: number): string {\n if (text.length <= max) return text;\n return `${text.slice(0, max)}…`;\n}\n\n/**\n * `path:startLine-endLine`, or `path:startLine` when the range is one line.\n * The short form names the file by its basename (`indexer.py:10-42`); a path\n * is never head-truncated, which would cut off the part that identifies it.\n */\nfunction formatFileLineRange(anchor: FileLineRangeAnchor, mode: ReferenceAnchorFormatMode): string {\n const path = mode === 'short' ? (anchor.path.split('/').pop() ?? anchor.path) : anchor.path;\n const lines =\n anchor.startLine === anchor.endLine\n ? `${anchor.startLine}`\n : `${anchor.startLine}-${anchor.endLine}`;\n return `${path}:${lines}`;\n}\n\nfunction formatAnchorShort(anchor: Anchor): string {\n switch (anchor.type) {\n case 'cell':\n return `cell ${truncate(anchor.cellId, SHORT_EXCERPT_CHARS)}`;\n case 'cell_range':\n return `cells ${truncate(anchor.startCellId, SHORT_EXCERPT_CHARS)} - ${truncate(anchor.endCellId, SHORT_EXCERPT_CHARS)}`;\n case 'file_line_range':\n return formatFileLineRange(anchor, 'short');\n case 'line':\n return `L${anchor.line}`;\n case 'line_range':\n return `L${anchor.startLine}-${anchor.endLine}`;\n case 'msg':\n return 'Msg';\n case 'msg_range':\n return 'Msgs';\n case 'msg_block':\n return `¶${anchor.block}`;\n case 'msg_section':\n return truncate(anchor.heading, SHORT_EXCERPT_CHARS);\n case 'msg_text':\n return truncate(anchor.text, SHORT_EXCERPT_CHARS);\n case 'tool_call':\n return 'Tool call';\n case 'page':\n return `p.${anchor.page}`;\n case 'page_range':\n return `p.${anchor.startPage}-${anchor.endPage}`;\n case 'page_rect':\n return `p.${anchor.page} (Region)`;\n case 'page_text':\n return `p.${anchor.page}`;\n case 'path':\n return anchor.line != null\n ? `${truncate(anchor.path, SHORT_EXCERPT_CHARS)}:${anchor.line}`\n : truncate(anchor.path, SHORT_EXCERPT_CHARS);\n case 'pm_node':\n case 'pm_node_range':\n case 'pm_mark':\n return '§';\n case 'pixel_range':\n return 'Region';\n case 'rect':\n return 'Region';\n case 'shape': {\n const n = anchor.shapeIds.length;\n return n === 1 ? `${slideName(anchor)} • shape` : `${slideName(anchor)} • ${n} shapes`;\n }\n case 'sheet_cell':\n return anchor.cell;\n case 'sheet_range':\n return anchor.range;\n case 'sheet_tab':\n return 'Sheet tab';\n case 'slide':\n return slideName(anchor);\n case 'semantic_query':\n return anchor.field ? `Cube · ${truncate(anchor.field, SHORT_EXCERPT_CHARS)}` : 'Cube query';\n case 'sql_query':\n return anchor.field ? `SQL · ${truncate(anchor.field, SHORT_EXCERPT_CHARS)}` : 'SQL query';\n case 'time':\n return formatAnchorTime(anchor.time);\n case 'time_range':\n return `${formatAnchorTime(anchor.startTime)}-${formatAnchorTime(anchor.endTime)}`;\n case 'comment':\n case 'comment_thread':\n return '💬';\n default:\n return '•';\n }\n}\n\nfunction formatAnchorLong(anchor: Anchor): string {\n switch (anchor.type) {\n case 'cell':\n return `Cell ${truncate(anchor.cellId, LONG_EXCERPT_CHARS)}`;\n case 'cell_range':\n return `Cells ${truncate(anchor.startCellId, LONG_EXCERPT_CHARS)}–${truncate(anchor.endCellId, LONG_EXCERPT_CHARS)}`;\n case 'file_line_range':\n return formatFileLineRange(anchor, 'long');\n case 'line':\n return `Line ${anchor.line}`;\n case 'line_range':\n return `Lines ${anchor.startLine}–${anchor.endLine}`;\n case 'msg':\n return 'Message';\n case 'msg_range':\n return 'Messages';\n case 'msg_block':\n return `Message block ${anchor.block}`;\n case 'msg_section':\n return `Section · ${anchor.heading}`;\n case 'msg_text':\n return truncate(anchor.text, LONG_EXCERPT_CHARS);\n case 'tool_call':\n return 'Tool call';\n case 'page':\n return `Page ${anchor.page}`;\n case 'page_range':\n return `Pages ${anchor.startPage}–${anchor.endPage}`;\n case 'page_rect':\n return `Page ${anchor.page} (Region)`;\n case 'page_text':\n return `Page ${anchor.page}`;\n case 'path':\n return anchor.line != null\n ? `${anchor.path}:${anchor.line}${anchor.column != null ? `:${anchor.column}` : ''}`\n : anchor.path;\n case 'pm_node':\n case 'pm_node_range':\n case 'pm_mark':\n return '§';\n case 'pixel_range':\n return 'Region';\n case 'rect':\n return 'Region';\n case 'shape': {\n const n = anchor.shapeIds.length;\n return n === 1 ? `${slideName(anchor)} — 1 shape` : `${slideName(anchor)} — ${n} shapes`;\n }\n case 'sheet_cell':\n return `Cell ${anchor.cell}`;\n case 'sheet_range':\n return `Range ${anchor.range}`;\n case 'sheet_tab':\n return 'Sheet tab';\n case 'slide':\n return slideName(anchor);\n case 'semantic_query':\n return anchor.field\n ? `Cube query · ${truncate(anchor.field, LONG_EXCERPT_CHARS)}`\n : 'Cube query';\n case 'sql_query':\n return anchor.field\n ? `SQL query · ${truncate(anchor.field, LONG_EXCERPT_CHARS)}`\n : 'SQL query';\n case 'time':\n return formatAnchorTime(anchor.time);\n case 'time_range':\n return `${formatAnchorTime(anchor.startTime)} – ${formatAnchorTime(anchor.endTime)}`;\n case 'comment':\n case 'comment_thread':\n return 'Comment';\n default:\n return '';\n }\n}\n\n/** Anchors whose excerpt *is* the label — the location alone says nothing to a reader. */\nfunction isExcerptOnlyAnchor(anchor: Anchor): boolean {\n return (\n anchor.type === 'pm_node' ||\n anchor.type === 'pm_node_range' ||\n anchor.type === 'pm_mark' ||\n anchor.type === 'msg_text'\n );\n}\n\nfunction anchorExcerpt({ anchor, meta }: { anchor: Anchor; meta?: AssetMeta }): string | undefined {\n if (anchor.type === 'page_text') return anchor.text;\n if (anchor.type === 'msg_text') return meta?.excerpt || anchor.text;\n return meta?.excerpt;\n}\n\nfunction formatShort(anchor: Anchor, meta?: AssetMeta): string {\n const excerpt = anchorExcerpt({ anchor, meta });\n const sheetName = meta?.sheetName;\n\n if (excerpt) {\n const anchorPart = formatAnchorShort(anchor);\n if (isExcerptOnlyAnchor(anchor)) {\n return truncate(excerpt, SHORT_EXCERPT_CHARS);\n }\n if (\n sheetName &&\n (anchor.type === 'sheet_cell' || anchor.type === 'sheet_range' || anchor.type === 'sheet_tab')\n ) {\n return anchor.type === 'sheet_tab' ? sheetName : `${quoteSheetName(sheetName)}!${anchorPart}`;\n }\n return anchorPart;\n }\n if (\n sheetName &&\n (anchor.type === 'sheet_cell' || anchor.type === 'sheet_range' || anchor.type === 'sheet_tab')\n ) {\n return anchor.type === 'sheet_tab'\n ? sheetName\n : `${quoteSheetName(sheetName)}!${formatAnchorShort(anchor)}`;\n }\n return formatAnchorShort(anchor);\n}\n\nfunction formatLong(anchor: Anchor, meta?: AssetMeta): string {\n const excerpt = anchorExcerpt({ anchor, meta });\n const sheetName = meta?.sheetName;\n\n if (excerpt) {\n let anchorPart = formatAnchorLong(anchor);\n if (\n sheetName &&\n (anchor.type === 'sheet_cell' || anchor.type === 'sheet_range' || anchor.type === 'sheet_tab')\n ) {\n anchorPart =\n anchor.type === 'sheet_tab'\n ? `Sheet tab · ${sheetName}`\n : `${quoteSheetName(sheetName)}!${anchor.type === 'sheet_cell' ? anchor.cell : anchor.range}`;\n }\n if (isExcerptOnlyAnchor(anchor)) {\n return truncate(excerpt, LONG_EXCERPT_CHARS);\n }\n return `${anchorPart}: ${truncate(excerpt, LONG_EXCERPT_CHARS)}`;\n }\n if (\n sheetName &&\n (anchor.type === 'sheet_cell' || anchor.type === 'sheet_range' || anchor.type === 'sheet_tab')\n ) {\n if (anchor.type === 'sheet_tab') {\n return `Sheet tab · ${sheetName}`;\n }\n return `${quoteSheetName(sheetName)}!${anchor.type === 'sheet_cell' ? anchor.cell : anchor.range}`;\n }\n return formatAnchorLong(anchor);\n}\n\n/**\n * Format an anchor into a human-readable citation line.\n *\n * `short` — compact: p.5, L42, 1:30, §, …\n * `long` — expanded: Page 5, Lines 10–25, …\n *\n * Pass `meta` when available for excerpt and sheetName context.\n * Returns `null` only if the formatted string is empty.\n */\nexport function formatReferenceAnchor(\n anchor: Anchor,\n mode: ReferenceAnchorFormatMode = 'long',\n meta?: AssetMeta\n): string | null {\n const text = mode === 'short' ? formatShort(anchor, meta) : formatLong(anchor, meta);\n return text === '' ? null : text;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const fileLineRange = require("./file-line-range.cjs");
|
|
4
|
+
const types = require("./types.cjs");
|
|
5
|
+
function parseAnchorFromParams(params) {
|
|
6
|
+
const rawType = params.get("anchor");
|
|
7
|
+
const anchorType = rawType == null ? void 0 : types.LEGACY_ANCHOR_TYPES[rawType] ?? rawType;
|
|
8
|
+
if (!anchorType || !types.isAnchorType(anchorType)) return void 0;
|
|
9
|
+
return parseAnchorByType(anchorType, params);
|
|
10
|
+
}
|
|
11
|
+
function requireString(params, key, ...legacyKeys) {
|
|
12
|
+
const value = params.get(key) ?? legacyKeys.map((k) => params.get(k)).find((v) => v != null);
|
|
13
|
+
if (value == null) throw new Error(`Missing required anchor param: ${key}`);
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function requireNonEmptyString(params, key, ...legacyKeys) {
|
|
17
|
+
const value = requireString(params, key, ...legacyKeys);
|
|
18
|
+
if (value.trim().length === 0) throw new Error(`Anchor param must be non-empty: ${key}`);
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function requireInt(params, key) {
|
|
22
|
+
const raw = requireString(params, key);
|
|
23
|
+
const n = Number.parseInt(raw, 10);
|
|
24
|
+
if (Number.isNaN(n)) throw new Error(`Invalid integer for anchor param ${key}: ${raw}`);
|
|
25
|
+
return n;
|
|
26
|
+
}
|
|
27
|
+
const POSITIVE_INT = /^[1-9]\d*$/;
|
|
28
|
+
function requirePositiveInt(params, key) {
|
|
29
|
+
const raw = requireString(params, key).trim();
|
|
30
|
+
if (!POSITIVE_INT.test(raw)) {
|
|
31
|
+
throw new Error(`Anchor param must be a positive integer: ${key}: ${raw}`);
|
|
32
|
+
}
|
|
33
|
+
return Number(raw);
|
|
34
|
+
}
|
|
35
|
+
function requireSingle(params, key) {
|
|
36
|
+
const values = params.getAll(key);
|
|
37
|
+
const [value] = values;
|
|
38
|
+
if (value == null) throw new Error(`Missing required anchor param: ${key}`);
|
|
39
|
+
if (values.length > 1) throw new Error(`Anchor param must not repeat: ${key}`);
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
const ASCII_DECIMAL = /^\d+$/;
|
|
43
|
+
const PYTHON_INT_MAX_STR_DIGITS = 4300;
|
|
44
|
+
function requireAsciiDecimal(params, key) {
|
|
45
|
+
const raw = requireSingle(params, key);
|
|
46
|
+
if (!ASCII_DECIMAL.test(raw)) {
|
|
47
|
+
throw new Error(`Anchor param must be an ASCII decimal: ${key}: ${raw}`);
|
|
48
|
+
}
|
|
49
|
+
if (raw.length > PYTHON_INT_MAX_STR_DIGITS) {
|
|
50
|
+
throw new Error(`Anchor param is too long to be an integer: ${key}`);
|
|
51
|
+
}
|
|
52
|
+
return Number(raw);
|
|
53
|
+
}
|
|
54
|
+
function parseFileLineRange(params) {
|
|
55
|
+
const path = requireSingle(params, "path");
|
|
56
|
+
if (path.includes("�")) {
|
|
57
|
+
throw new Error("path must not contain U+FFFD (a malformed percent-escape)");
|
|
58
|
+
}
|
|
59
|
+
const anchor = {
|
|
60
|
+
type: "file_line_range",
|
|
61
|
+
path,
|
|
62
|
+
startLine: requireAsciiDecimal(params, "start_line"),
|
|
63
|
+
endLine: requireAsciiDecimal(params, "end_line")
|
|
64
|
+
};
|
|
65
|
+
const problem = fileLineRange.fileLineRangeAnchorProblem(anchor);
|
|
66
|
+
if (problem) throw new Error(problem);
|
|
67
|
+
return anchor;
|
|
68
|
+
}
|
|
69
|
+
function parseSheetId(params) {
|
|
70
|
+
const raw = requireString(params, "sheet_id");
|
|
71
|
+
const n = Number.parseInt(raw, 10);
|
|
72
|
+
return Number.isNaN(n) ? 0 : n;
|
|
73
|
+
}
|
|
74
|
+
function requireFloat(params, key) {
|
|
75
|
+
const raw = requireString(params, key);
|
|
76
|
+
const n = Number.parseFloat(raw);
|
|
77
|
+
if (Number.isNaN(n)) throw new Error(`Invalid number for anchor param ${key}: ${raw}`);
|
|
78
|
+
return n;
|
|
79
|
+
}
|
|
80
|
+
function parseJsonObject(raw) {
|
|
81
|
+
const parsed = JSON.parse(raw);
|
|
82
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
83
|
+
throw new Error("Expected a JSON object");
|
|
84
|
+
}
|
|
85
|
+
return parsed;
|
|
86
|
+
}
|
|
87
|
+
function parseStringRecord(raw) {
|
|
88
|
+
return Object.fromEntries(
|
|
89
|
+
Object.entries(parseJsonObject(raw)).map(([key, value]) => [key, String(value)])
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
function parseOptionalStringRecord(raw) {
|
|
93
|
+
if (raw == null) return void 0;
|
|
94
|
+
try {
|
|
95
|
+
return parseStringRecord(raw);
|
|
96
|
+
} catch {
|
|
97
|
+
return void 0;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function parseOptionalShiftLogFrontier(raw) {
|
|
101
|
+
if (raw == null) return void 0;
|
|
102
|
+
try {
|
|
103
|
+
const frontier = {};
|
|
104
|
+
for (const [writer, seq] of Object.entries(parseJsonObject(raw))) {
|
|
105
|
+
if (typeof seq !== "number" || !Number.isInteger(seq) || seq < 0) return void 0;
|
|
106
|
+
frontier[writer] = seq;
|
|
107
|
+
}
|
|
108
|
+
return frontier;
|
|
109
|
+
} catch {
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function parseRelationship(raw) {
|
|
114
|
+
return raw === "exact" || raw === "supporting" ? raw : void 0;
|
|
115
|
+
}
|
|
116
|
+
function parseAnchorByType(anchorType, params) {
|
|
117
|
+
try {
|
|
118
|
+
switch (anchorType) {
|
|
119
|
+
case "cell":
|
|
120
|
+
return { type: "cell", cellId: requireString(params, "cell_id") };
|
|
121
|
+
case "cell_range":
|
|
122
|
+
return {
|
|
123
|
+
type: "cell_range",
|
|
124
|
+
startCellId: requireString(params, "start_cell_id"),
|
|
125
|
+
endCellId: requireString(params, "end_cell_id")
|
|
126
|
+
};
|
|
127
|
+
case "comment":
|
|
128
|
+
return {
|
|
129
|
+
type: "comment",
|
|
130
|
+
threadId: requireString(params, "thread_id"),
|
|
131
|
+
commentId: requireString(params, "comment_id")
|
|
132
|
+
};
|
|
133
|
+
case "comment_thread":
|
|
134
|
+
return {
|
|
135
|
+
type: "comment_thread",
|
|
136
|
+
threadId: requireString(params, "thread_id")
|
|
137
|
+
};
|
|
138
|
+
case "file_line_range":
|
|
139
|
+
return parseFileLineRange(params);
|
|
140
|
+
case "line":
|
|
141
|
+
return { type: "line", line: requireInt(params, "line") };
|
|
142
|
+
case "line_range":
|
|
143
|
+
return {
|
|
144
|
+
type: "line_range",
|
|
145
|
+
startLine: requireInt(params, "start_line"),
|
|
146
|
+
endLine: requireInt(params, "end_line")
|
|
147
|
+
};
|
|
148
|
+
case "msg":
|
|
149
|
+
return { type: "msg", messageId: requireNonEmptyString(params, "msg_id", "message_id") };
|
|
150
|
+
case "msg_range":
|
|
151
|
+
return {
|
|
152
|
+
type: "msg_range",
|
|
153
|
+
startMessageId: requireNonEmptyString(params, "start_msg_id", "start_message_id"),
|
|
154
|
+
endMessageId: requireNonEmptyString(params, "end_msg_id", "end_message_id")
|
|
155
|
+
};
|
|
156
|
+
case "msg_block": {
|
|
157
|
+
const hash = params.get("hash");
|
|
158
|
+
return {
|
|
159
|
+
type: "msg_block",
|
|
160
|
+
messageId: requireNonEmptyString(params, "msg_id"),
|
|
161
|
+
block: requirePositiveInt(params, "block"),
|
|
162
|
+
...hash ? { hash } : {}
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
case "msg_section": {
|
|
166
|
+
const nth = params.get("nth") != null ? requirePositiveInt(params, "nth") : void 0;
|
|
167
|
+
return {
|
|
168
|
+
type: "msg_section",
|
|
169
|
+
messageId: requireNonEmptyString(params, "msg_id"),
|
|
170
|
+
heading: requireNonEmptyString(params, "heading"),
|
|
171
|
+
...nth != null ? { nth } : {}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
case "msg_text": {
|
|
175
|
+
const block = params.get("block") != null ? requirePositiveInt(params, "block") : void 0;
|
|
176
|
+
const prefix = params.get("prefix");
|
|
177
|
+
const suffix = params.get("suffix");
|
|
178
|
+
return {
|
|
179
|
+
type: "msg_text",
|
|
180
|
+
messageId: requireNonEmptyString(params, "msg_id"),
|
|
181
|
+
text: requireNonEmptyString(params, "text"),
|
|
182
|
+
...block != null ? { block } : {},
|
|
183
|
+
...prefix ? { prefix } : {},
|
|
184
|
+
...suffix ? { suffix } : {}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
case "page":
|
|
188
|
+
return { type: "page", page: requireInt(params, "page") };
|
|
189
|
+
case "page_range":
|
|
190
|
+
return {
|
|
191
|
+
type: "page_range",
|
|
192
|
+
startPage: requireInt(params, "start_page"),
|
|
193
|
+
endPage: requireInt(params, "end_page")
|
|
194
|
+
};
|
|
195
|
+
case "page_rect": {
|
|
196
|
+
const unitRaw = params.get("unit");
|
|
197
|
+
return {
|
|
198
|
+
type: "page_rect",
|
|
199
|
+
page: requireInt(params, "page"),
|
|
200
|
+
x: requireFloat(params, "x"),
|
|
201
|
+
y: requireFloat(params, "y"),
|
|
202
|
+
width: requireFloat(params, "width"),
|
|
203
|
+
height: requireFloat(params, "height"),
|
|
204
|
+
...unitRaw === "percent" || unitRaw === "point" ? { unit: unitRaw } : {}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
case "page_text": {
|
|
208
|
+
const prefix = params.get("prefix");
|
|
209
|
+
const suffix = params.get("suffix");
|
|
210
|
+
const hash = params.get("hash");
|
|
211
|
+
return {
|
|
212
|
+
type: "page_text",
|
|
213
|
+
page: requireInt(params, "page"),
|
|
214
|
+
text: requireString(params, "text"),
|
|
215
|
+
...prefix ? { prefix } : {},
|
|
216
|
+
...suffix ? { suffix } : {},
|
|
217
|
+
...hash ? { hash } : {}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
case "path": {
|
|
221
|
+
const line = params.get("line") != null ? requireInt(params, "line") : void 0;
|
|
222
|
+
const column = line != null && params.get("column") != null ? requireInt(params, "column") : void 0;
|
|
223
|
+
return {
|
|
224
|
+
type: "path",
|
|
225
|
+
path: requireString(params, "path"),
|
|
226
|
+
...line != null ? { line } : {},
|
|
227
|
+
...column != null ? { column } : {}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
case "pixel_range":
|
|
231
|
+
return {
|
|
232
|
+
type: "pixel_range",
|
|
233
|
+
x: requireFloat(params, "x"),
|
|
234
|
+
y: requireFloat(params, "y"),
|
|
235
|
+
width: requireFloat(params, "width"),
|
|
236
|
+
height: requireFloat(params, "height")
|
|
237
|
+
};
|
|
238
|
+
case "pm_node":
|
|
239
|
+
return { type: "pm_node", nodeId: requireString(params, "node_id") };
|
|
240
|
+
case "pm_node_range":
|
|
241
|
+
return {
|
|
242
|
+
type: "pm_node_range",
|
|
243
|
+
startNodeId: requireString(params, "start_node_id"),
|
|
244
|
+
endNodeId: requireString(params, "end_node_id")
|
|
245
|
+
};
|
|
246
|
+
case "pm_mark":
|
|
247
|
+
return { type: "pm_mark", markId: requireString(params, "mark_id") };
|
|
248
|
+
case "rect":
|
|
249
|
+
return {
|
|
250
|
+
type: "rect",
|
|
251
|
+
x: requireFloat(params, "x"),
|
|
252
|
+
y: requireFloat(params, "y"),
|
|
253
|
+
width: requireFloat(params, "width"),
|
|
254
|
+
height: requireFloat(params, "height")
|
|
255
|
+
};
|
|
256
|
+
case "section": {
|
|
257
|
+
const topic = params.get("topic") != null ? requirePositiveInt(params, "topic") : void 0;
|
|
258
|
+
return {
|
|
259
|
+
type: "section",
|
|
260
|
+
section: requireString(params, "section"),
|
|
261
|
+
...topic != null ? { topic } : {}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
case "semantic_query": {
|
|
265
|
+
const anchor = {
|
|
266
|
+
type: "semantic_query",
|
|
267
|
+
query: parseJsonObject(requireString(params, "query"))
|
|
268
|
+
};
|
|
269
|
+
const field = params.get("field");
|
|
270
|
+
if (field != null) anchor.field = field;
|
|
271
|
+
const rowKey = params.get("row_key");
|
|
272
|
+
if (rowKey != null) anchor.rowKey = parseStringRecord(rowKey);
|
|
273
|
+
if (params.get("row_index") != null) anchor.rowIndex = requireInt(params, "row_index");
|
|
274
|
+
const relationship = parseRelationship(params.get("relationship"));
|
|
275
|
+
if (relationship != null) anchor.relationship = relationship;
|
|
276
|
+
if (params.get("schema_version") != null) {
|
|
277
|
+
anchor.schemaVersion = requireInt(params, "schema_version");
|
|
278
|
+
}
|
|
279
|
+
const schemaHash = params.get("schema_hash");
|
|
280
|
+
if (schemaHash != null) anchor.schemaHash = schemaHash;
|
|
281
|
+
const sourceSnapshots = parseOptionalStringRecord(params.get("source_snapshots"));
|
|
282
|
+
if (sourceSnapshots != null) anchor.sourceSnapshots = sourceSnapshots;
|
|
283
|
+
const dataAsOf = params.get("data_as_of");
|
|
284
|
+
if (dataAsOf != null) anchor.dataAsOf = dataAsOf;
|
|
285
|
+
return anchor;
|
|
286
|
+
}
|
|
287
|
+
case "shape": {
|
|
288
|
+
const shapeIds = requireString(params, "shape_ids").split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
289
|
+
if (shapeIds.length === 0) {
|
|
290
|
+
throw new Error("Anchor param must be non-empty: shape_ids");
|
|
291
|
+
}
|
|
292
|
+
const shapeSlideId = params.get("slide_id");
|
|
293
|
+
const shapeSlideIndexRaw = params.get("slide_index");
|
|
294
|
+
return {
|
|
295
|
+
type: "shape",
|
|
296
|
+
shapeIds,
|
|
297
|
+
...shapeSlideId != null ? { slideId: shapeSlideId } : {},
|
|
298
|
+
...shapeSlideIndexRaw != null ? { slideIndex: requireInt(params, "slide_index") } : {}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
case "sheet_cell": {
|
|
302
|
+
const chartId = params.get("chart");
|
|
303
|
+
return {
|
|
304
|
+
type: "sheet_cell",
|
|
305
|
+
sheetId: parseSheetId(params),
|
|
306
|
+
cell: requireString(params, "cell"),
|
|
307
|
+
...chartId ? { chartId } : {}
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
case "sheet_range": {
|
|
311
|
+
const frontier = parseOptionalShiftLogFrontier(params.get("frontier"));
|
|
312
|
+
return {
|
|
313
|
+
type: "sheet_range",
|
|
314
|
+
sheetId: parseSheetId(params),
|
|
315
|
+
range: requireString(params, "range"),
|
|
316
|
+
...frontier ? { frontier } : {}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
case "sheet_tab":
|
|
320
|
+
return {
|
|
321
|
+
type: "sheet_tab",
|
|
322
|
+
sheetId: parseSheetId(params)
|
|
323
|
+
};
|
|
324
|
+
case "sheet_table": {
|
|
325
|
+
const fallbackRange = params.get("fallback_range");
|
|
326
|
+
return {
|
|
327
|
+
type: "sheet_table",
|
|
328
|
+
sheetId: parseSheetId(params),
|
|
329
|
+
tableName: requireString(params, "table_name"),
|
|
330
|
+
...fallbackRange != null ? { fallbackRange } : {}
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
case "lakehouse_table": {
|
|
334
|
+
const tableUuid = params.get("table_uuid");
|
|
335
|
+
const snapshotId = params.get("snapshot_id");
|
|
336
|
+
return {
|
|
337
|
+
type: "lakehouse_table",
|
|
338
|
+
table: requireString(params, "table"),
|
|
339
|
+
...tableUuid ? { tableUuid } : {},
|
|
340
|
+
...snapshotId ? { snapshotId } : {}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
case "slide": {
|
|
344
|
+
let slideId = params.get("slide_id");
|
|
345
|
+
let slideIndex = params.get("slide_index") != null ? requireInt(params, "slide_index") : void 0;
|
|
346
|
+
const bareSlide = params.get("slide");
|
|
347
|
+
if (bareSlide != null && slideId == null && slideIndex == null) {
|
|
348
|
+
const n = Number.parseInt(bareSlide, 10);
|
|
349
|
+
if (Number.isNaN(n)) {
|
|
350
|
+
slideId = bareSlide;
|
|
351
|
+
} else {
|
|
352
|
+
slideIndex = n;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (slideId == null && slideIndex == null) {
|
|
356
|
+
throw new Error("Provide slide_id and/or slide_index (1-based)");
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
type: "slide",
|
|
360
|
+
...slideId != null ? { slideId } : {},
|
|
361
|
+
...slideIndex != null ? { slideIndex } : {}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
case "sql_query": {
|
|
365
|
+
const anchor = { type: "sql_query" };
|
|
366
|
+
const sql = params.get("sql");
|
|
367
|
+
if (sql != null) anchor.sql = sql;
|
|
368
|
+
const snippetId = params.get("query_snippet_asset_id");
|
|
369
|
+
if (snippetId != null) anchor.querySnippetAssetId = snippetId;
|
|
370
|
+
const dialect = params.get("dialect");
|
|
371
|
+
if (dialect != null) anchor.dialect = dialect;
|
|
372
|
+
const field = params.get("field");
|
|
373
|
+
if (field != null) anchor.field = field;
|
|
374
|
+
const rowKey = params.get("row_key");
|
|
375
|
+
if (rowKey != null) anchor.rowKey = parseStringRecord(rowKey);
|
|
376
|
+
if (params.get("row_index") != null) anchor.rowIndex = requireInt(params, "row_index");
|
|
377
|
+
const relationship = parseRelationship(params.get("relationship"));
|
|
378
|
+
if (relationship != null) anchor.relationship = relationship;
|
|
379
|
+
if (anchor.sql === void 0 && anchor.querySnippetAssetId === void 0) {
|
|
380
|
+
return void 0;
|
|
381
|
+
}
|
|
382
|
+
return anchor;
|
|
383
|
+
}
|
|
384
|
+
case "time":
|
|
385
|
+
return { type: "time", time: requireString(params, "time") };
|
|
386
|
+
case "time_range":
|
|
387
|
+
return {
|
|
388
|
+
type: "time_range",
|
|
389
|
+
startTime: requireString(params, "start_time"),
|
|
390
|
+
endTime: requireString(params, "end_time")
|
|
391
|
+
};
|
|
392
|
+
case "tool_call": {
|
|
393
|
+
const messageId = params.get("msg_id") ?? params.get("message_id");
|
|
394
|
+
return {
|
|
395
|
+
type: "tool_call",
|
|
396
|
+
toolCallId: requireString(params, "tool_call_id"),
|
|
397
|
+
...messageId ? { messageId } : {}
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
default:
|
|
401
|
+
return void 0;
|
|
402
|
+
}
|
|
403
|
+
} catch {
|
|
404
|
+
return void 0;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
exports.parseAnchorFromParams = parseAnchorFromParams;
|
|
408
|
+
//# sourceMappingURL=parse.cjs.map
|