@semiont/api-client 0.2.2-build.15 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{types.d.ts → index-DHh0ToZB.d.ts} +460 -6
- package/dist/index.d.ts +909 -13
- package/dist/index.js +1598 -60
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -12
- package/dist/utils/index.js +597 -26
- package/dist/utils/index.js.map +1 -1
- package/package.json +11 -8
- package/dist/__tests__/client.test.d.ts +0 -28
- package/dist/__tests__/client.test.d.ts.map +0 -1
- package/dist/__tests__/client.test.js +0 -567
- package/dist/__tests__/client.test.js.map +0 -1
- package/dist/__tests__/sse-client.test.d.ts +0 -7
- package/dist/__tests__/sse-client.test.d.ts.map +0 -1
- package/dist/__tests__/sse-client.test.js +0 -421
- package/dist/__tests__/sse-client.test.js.map +0 -1
- package/dist/__tests__/sse-stream.test.d.ts +0 -7
- package/dist/__tests__/sse-stream.test.d.ts.map +0 -1
- package/dist/__tests__/sse-stream.test.js +0 -394
- package/dist/__tests__/sse-stream.test.js.map +0 -1
- package/dist/__tests__/svg-selectors.test.d.ts +0 -5
- package/dist/__tests__/svg-selectors.test.d.ts.map +0 -1
- package/dist/__tests__/svg-selectors.test.js +0 -124
- package/dist/__tests__/svg-selectors.test.js.map +0 -1
- package/dist/branded-types.d.ts +0 -70
- package/dist/branded-types.d.ts.map +0 -1
- package/dist/branded-types.js +0 -62
- package/dist/branded-types.js.map +0 -1
- package/dist/client.d.ts +0 -243
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -460
- package/dist/client.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mime-utils.d.ts +0 -27
- package/dist/mime-utils.d.ts.map +0 -1
- package/dist/mime-utils.js +0 -49
- package/dist/mime-utils.js.map +0 -1
- package/dist/sse/index.d.ts +0 -343
- package/dist/sse/index.d.ts.map +0 -1
- package/dist/sse/index.js +0 -404
- package/dist/sse/index.js.map +0 -1
- package/dist/sse/stream.d.ts +0 -58
- package/dist/sse/stream.d.ts.map +0 -1
- package/dist/sse/stream.js +0 -187
- package/dist/sse/stream.js.map +0 -1
- package/dist/sse/types.d.ts +0 -295
- package/dist/sse/types.d.ts.map +0 -1
- package/dist/sse/types.js +0 -10
- package/dist/sse/types.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -7
- package/dist/types.js.map +0 -1
- package/dist/utils/annotations.d.ts +0 -191
- package/dist/utils/annotations.d.ts.map +0 -1
- package/dist/utils/annotations.js +0 -404
- package/dist/utils/annotations.js.map +0 -1
- package/dist/utils/events.d.ts +0 -74
- package/dist/utils/events.d.ts.map +0 -1
- package/dist/utils/events.js +0 -329
- package/dist/utils/events.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/locales.d.ts +0 -31
- package/dist/utils/locales.d.ts.map +0 -1
- package/dist/utils/locales.js +0 -83
- package/dist/utils/locales.js.map +0 -1
- package/dist/utils/resources.d.ts +0 -34
- package/dist/utils/resources.d.ts.map +0 -1
- package/dist/utils/resources.js +0 -63
- package/dist/utils/resources.js.map +0 -1
- package/dist/utils/validation.d.ts +0 -57
- package/dist/utils/validation.d.ts.map +0 -1
- package/dist/utils/validation.js +0 -89
- package/dist/utils/validation.js.map +0 -1
package/dist/utils/index.js
CHANGED
|
@@ -1,28 +1,599 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
// src/branded-types.ts
|
|
2
|
+
function resourceUri(uri) {
|
|
3
|
+
if (!uri.startsWith("http://") && !uri.startsWith("https://")) {
|
|
4
|
+
throw new TypeError(`Expected ResourceUri, got: ${uri}`);
|
|
5
|
+
}
|
|
6
|
+
return uri;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/utils/annotations.ts
|
|
10
|
+
function getBodySource(body) {
|
|
11
|
+
if (Array.isArray(body)) {
|
|
12
|
+
for (const item of body) {
|
|
13
|
+
if (typeof item === "object" && item !== null && "type" in item && "source" in item) {
|
|
14
|
+
const itemType = item.type;
|
|
15
|
+
const itemSource = item.source;
|
|
16
|
+
if (itemType === "SpecificResource" && typeof itemSource === "string") {
|
|
17
|
+
return resourceUri(itemSource);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (typeof body === "object" && body !== null && "type" in body && "source" in body) {
|
|
24
|
+
const bodyType = body.type;
|
|
25
|
+
const bodySource = body.source;
|
|
26
|
+
if (bodyType === "SpecificResource" && typeof bodySource === "string") {
|
|
27
|
+
return resourceUri(bodySource);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function getBodyType(body) {
|
|
33
|
+
if (Array.isArray(body)) {
|
|
34
|
+
if (body.length === 0) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (typeof body[0] === "object" && body[0] !== null && "type" in body[0]) {
|
|
38
|
+
const firstType = body[0].type;
|
|
39
|
+
if (firstType === "TextualBody" || firstType === "SpecificResource") {
|
|
40
|
+
return firstType;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (typeof body === "object" && body !== null && "type" in body) {
|
|
46
|
+
const bodyType = body.type;
|
|
47
|
+
if (bodyType === "TextualBody" || bodyType === "SpecificResource") {
|
|
48
|
+
return bodyType;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
function isBodyResolved(body) {
|
|
54
|
+
return getBodySource(body) !== null;
|
|
55
|
+
}
|
|
56
|
+
function getTargetSource(target) {
|
|
57
|
+
if (typeof target === "string") {
|
|
58
|
+
return resourceUri(target);
|
|
59
|
+
}
|
|
60
|
+
return resourceUri(target.source);
|
|
61
|
+
}
|
|
62
|
+
function getTargetSelector(target) {
|
|
63
|
+
if (typeof target === "string") {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
return target.selector;
|
|
67
|
+
}
|
|
68
|
+
function hasTargetSelector(target) {
|
|
69
|
+
return typeof target !== "string" && target.selector !== void 0;
|
|
70
|
+
}
|
|
71
|
+
function getEntityTypes(annotation) {
|
|
72
|
+
if (Array.isArray(annotation.body)) {
|
|
73
|
+
const entityTags = [];
|
|
74
|
+
for (const item of annotation.body) {
|
|
75
|
+
if (typeof item === "object" && item !== null && "type" in item && "value" in item && "purpose" in item) {
|
|
76
|
+
const itemType = item.type;
|
|
77
|
+
const itemValue = item.value;
|
|
78
|
+
const itemPurpose = item.purpose;
|
|
79
|
+
if (itemType === "TextualBody" && itemPurpose === "tagging" && typeof itemValue === "string" && itemValue.length > 0) {
|
|
80
|
+
entityTags.push(itemValue);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return entityTags;
|
|
85
|
+
}
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
function isHighlight(annotation) {
|
|
89
|
+
return annotation.motivation === "highlighting";
|
|
90
|
+
}
|
|
91
|
+
function isReference(annotation) {
|
|
92
|
+
return annotation.motivation === "linking";
|
|
93
|
+
}
|
|
94
|
+
function isAssessment(annotation) {
|
|
95
|
+
return annotation.motivation === "assessing";
|
|
96
|
+
}
|
|
97
|
+
function isComment(annotation) {
|
|
98
|
+
return annotation.motivation === "commenting";
|
|
99
|
+
}
|
|
100
|
+
function isTag(annotation) {
|
|
101
|
+
return annotation.motivation === "tagging";
|
|
102
|
+
}
|
|
103
|
+
function getCommentText(annotation) {
|
|
104
|
+
if (!isComment(annotation)) return void 0;
|
|
105
|
+
const body = Array.isArray(annotation.body) ? annotation.body[0] : annotation.body;
|
|
106
|
+
if (body && "value" in body) {
|
|
107
|
+
return body.value;
|
|
108
|
+
}
|
|
109
|
+
return void 0;
|
|
110
|
+
}
|
|
111
|
+
function getTagCategory(annotation) {
|
|
112
|
+
if (!isTag(annotation)) return void 0;
|
|
113
|
+
const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];
|
|
114
|
+
const taggingBody = bodies.find((b) => b && "purpose" in b && b.purpose === "tagging");
|
|
115
|
+
if (taggingBody && "value" in taggingBody) {
|
|
116
|
+
return taggingBody.value;
|
|
117
|
+
}
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
function getTagSchemaId(annotation) {
|
|
121
|
+
if (!isTag(annotation)) return void 0;
|
|
122
|
+
const bodies = Array.isArray(annotation.body) ? annotation.body : [annotation.body];
|
|
123
|
+
const classifyingBody = bodies.find((b) => b && "purpose" in b && b.purpose === "classifying");
|
|
124
|
+
if (classifyingBody && "value" in classifyingBody) {
|
|
125
|
+
return classifyingBody.value;
|
|
126
|
+
}
|
|
127
|
+
return void 0;
|
|
128
|
+
}
|
|
129
|
+
function isStubReference(annotation) {
|
|
130
|
+
return isReference(annotation) && !isBodyResolved(annotation.body);
|
|
131
|
+
}
|
|
132
|
+
function isResolvedReference(annotation) {
|
|
133
|
+
return isReference(annotation) && isBodyResolved(annotation.body);
|
|
134
|
+
}
|
|
135
|
+
function getExactText(selector) {
|
|
136
|
+
if (!selector) {
|
|
137
|
+
return "";
|
|
138
|
+
}
|
|
139
|
+
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
140
|
+
const quoteSelector = selectors.find((s) => s.type === "TextQuoteSelector");
|
|
141
|
+
if (quoteSelector) {
|
|
142
|
+
return quoteSelector.exact;
|
|
143
|
+
}
|
|
144
|
+
return "";
|
|
145
|
+
}
|
|
146
|
+
function getAnnotationExactText(annotation) {
|
|
147
|
+
const selector = getTargetSelector(annotation.target);
|
|
148
|
+
return getExactText(selector);
|
|
149
|
+
}
|
|
150
|
+
function getPrimarySelector(selector) {
|
|
151
|
+
if (Array.isArray(selector)) {
|
|
152
|
+
if (selector.length === 0) {
|
|
153
|
+
throw new Error("Empty selector array");
|
|
154
|
+
}
|
|
155
|
+
const first = selector[0];
|
|
156
|
+
if (!first) {
|
|
157
|
+
throw new Error("Invalid selector array");
|
|
158
|
+
}
|
|
159
|
+
return first;
|
|
160
|
+
}
|
|
161
|
+
return selector;
|
|
162
|
+
}
|
|
163
|
+
function getTextPositionSelector(selector) {
|
|
164
|
+
if (!selector) return null;
|
|
165
|
+
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
166
|
+
const found = selectors.find((s) => s.type === "TextPositionSelector");
|
|
167
|
+
if (!found) return null;
|
|
168
|
+
return found.type === "TextPositionSelector" ? found : null;
|
|
169
|
+
}
|
|
170
|
+
function getTextQuoteSelector(selector) {
|
|
171
|
+
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
172
|
+
const found = selectors.find((s) => s.type === "TextQuoteSelector");
|
|
173
|
+
if (!found) return null;
|
|
174
|
+
return found.type === "TextQuoteSelector" ? found : null;
|
|
175
|
+
}
|
|
176
|
+
function getSvgSelector(selector) {
|
|
177
|
+
if (!selector) return null;
|
|
178
|
+
const selectors = Array.isArray(selector) ? selector : [selector];
|
|
179
|
+
const found = selectors.find((s) => s.type === "SvgSelector");
|
|
180
|
+
if (!found) return null;
|
|
181
|
+
return found.type === "SvgSelector" ? found : null;
|
|
182
|
+
}
|
|
183
|
+
function validateSvgMarkup(svg) {
|
|
184
|
+
if (!svg.includes('xmlns="http://www.w3.org/2000/svg"')) {
|
|
185
|
+
return 'SVG must include xmlns="http://www.w3.org/2000/svg" attribute';
|
|
186
|
+
}
|
|
187
|
+
if (!svg.includes("<svg") || !svg.includes("</svg>")) {
|
|
188
|
+
return "SVG must have opening and closing tags";
|
|
189
|
+
}
|
|
190
|
+
const shapeElements = ["rect", "circle", "ellipse", "polygon", "polyline", "path", "line"];
|
|
191
|
+
const hasShape = shapeElements.some(
|
|
192
|
+
(shape) => svg.includes(`<${shape}`) || svg.includes(`<${shape} `)
|
|
193
|
+
);
|
|
194
|
+
if (!hasShape) {
|
|
195
|
+
return "SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)";
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
function extractBoundingBox(svg) {
|
|
200
|
+
const viewBoxMatch = svg.match(/<svg[^>]*viewBox="([^"]+)"/);
|
|
201
|
+
if (viewBoxMatch) {
|
|
202
|
+
const values = viewBoxMatch[1].split(/\s+/).map(parseFloat);
|
|
203
|
+
if (values.length === 4 && values.every((v) => !isNaN(v))) {
|
|
204
|
+
return {
|
|
205
|
+
x: values[0],
|
|
206
|
+
y: values[1],
|
|
207
|
+
width: values[2],
|
|
208
|
+
height: values[3]
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const svgTagMatch = svg.match(/<svg[^>]*>/);
|
|
213
|
+
if (svgTagMatch) {
|
|
214
|
+
const svgTag = svgTagMatch[0];
|
|
215
|
+
const widthMatch = svgTag.match(/width="([^"]+)"/);
|
|
216
|
+
const heightMatch = svgTag.match(/height="([^"]+)"/);
|
|
217
|
+
if (widthMatch && heightMatch) {
|
|
218
|
+
const width = parseFloat(widthMatch[1]);
|
|
219
|
+
const height = parseFloat(heightMatch[1]);
|
|
220
|
+
if (!isNaN(width) && !isNaN(height)) {
|
|
221
|
+
return { x: 0, y: 0, width, height };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/utils/events.ts
|
|
229
|
+
function getAnnotationUriFromEvent(event) {
|
|
230
|
+
const eventData = event.event;
|
|
231
|
+
const payload = eventData.payload;
|
|
232
|
+
if (!payload) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
switch (eventData.type) {
|
|
236
|
+
case "annotation.added":
|
|
237
|
+
return payload.annotation?.id || null;
|
|
238
|
+
case "annotation.removed":
|
|
239
|
+
case "annotation.body.updated":
|
|
240
|
+
if (payload.annotationId && eventData.resourceId) {
|
|
241
|
+
try {
|
|
242
|
+
const resourceUri2 = eventData.resourceId;
|
|
243
|
+
const baseUrl = resourceUri2.substring(0, resourceUri2.lastIndexOf("/resources/"));
|
|
244
|
+
return `${baseUrl}/annotations/${payload.annotationId}`;
|
|
245
|
+
} catch (e) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
default:
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function isEventRelatedToAnnotation(event, annotationUri) {
|
|
255
|
+
const eventAnnotationUri = getAnnotationUriFromEvent(event);
|
|
256
|
+
return eventAnnotationUri === annotationUri;
|
|
257
|
+
}
|
|
258
|
+
function isResourceEvent(event) {
|
|
259
|
+
return event && typeof event.event === "object" && typeof event.event.id === "string" && typeof event.event.timestamp === "string" && typeof event.event.resourceId === "string" && typeof event.event.type === "string" && typeof event.metadata === "object" && typeof event.metadata.sequenceNumber === "number";
|
|
260
|
+
}
|
|
261
|
+
function formatEventType(type, t, payload) {
|
|
262
|
+
switch (type) {
|
|
263
|
+
case "resource.created":
|
|
264
|
+
return t("resourceCreated");
|
|
265
|
+
case "resource.cloned":
|
|
266
|
+
return t("resourceCloned");
|
|
267
|
+
case "resource.archived":
|
|
268
|
+
return t("resourceArchived");
|
|
269
|
+
case "resource.unarchived":
|
|
270
|
+
return t("resourceUnarchived");
|
|
271
|
+
case "annotation.added": {
|
|
272
|
+
const motivation = payload?.annotation?.motivation;
|
|
273
|
+
if (motivation === "highlighting") return t("highlightAdded");
|
|
274
|
+
if (motivation === "linking") return t("referenceCreated");
|
|
275
|
+
if (motivation === "assessing") return t("assessmentAdded");
|
|
276
|
+
return t("annotationAdded");
|
|
277
|
+
}
|
|
278
|
+
case "annotation.removed": {
|
|
279
|
+
return t("annotationRemoved");
|
|
280
|
+
}
|
|
281
|
+
case "annotation.body.updated": {
|
|
282
|
+
return t("annotationBodyUpdated");
|
|
283
|
+
}
|
|
284
|
+
case "entitytag.added":
|
|
285
|
+
return t("entitytagAdded");
|
|
286
|
+
case "entitytag.removed":
|
|
287
|
+
return t("entitytagRemoved");
|
|
288
|
+
case "entitytype.added":
|
|
289
|
+
return t("entitytypeAdded");
|
|
290
|
+
case "job.completed":
|
|
291
|
+
case "job.started":
|
|
292
|
+
case "job.progress":
|
|
293
|
+
case "job.failed":
|
|
294
|
+
return t("jobEvent");
|
|
295
|
+
default:
|
|
296
|
+
const _exhaustiveCheck = type;
|
|
297
|
+
return _exhaustiveCheck;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function getEventEmoji(type, payload) {
|
|
301
|
+
switch (type) {
|
|
302
|
+
case "resource.created":
|
|
303
|
+
case "resource.cloned":
|
|
304
|
+
case "resource.archived":
|
|
305
|
+
case "resource.unarchived":
|
|
306
|
+
return "\u{1F4C4}";
|
|
307
|
+
case "annotation.added": {
|
|
308
|
+
const motivation = payload?.annotation?.motivation;
|
|
309
|
+
if (motivation === "highlighting") return "\u{1F7E1}";
|
|
310
|
+
if (motivation === "linking") return "\u{1F535}";
|
|
311
|
+
if (motivation === "assessing") return "\u{1F534}";
|
|
312
|
+
return "\u{1F4DD}";
|
|
313
|
+
}
|
|
314
|
+
case "annotation.removed": {
|
|
315
|
+
return "\u{1F5D1}\uFE0F";
|
|
316
|
+
}
|
|
317
|
+
case "annotation.body.updated": {
|
|
318
|
+
return "\u270F\uFE0F";
|
|
319
|
+
}
|
|
320
|
+
case "entitytag.added":
|
|
321
|
+
case "entitytag.removed":
|
|
322
|
+
return "\u{1F3F7}\uFE0F";
|
|
323
|
+
case "entitytype.added":
|
|
324
|
+
return "\u{1F3F7}\uFE0F";
|
|
325
|
+
// Same emoji as entitytag (global entity type collection)
|
|
326
|
+
case "job.completed":
|
|
327
|
+
return "\u{1F517}";
|
|
328
|
+
// Link emoji for linked document creation
|
|
329
|
+
case "job.started":
|
|
330
|
+
case "job.progress":
|
|
331
|
+
return "\u2699\uFE0F";
|
|
332
|
+
// Gear for job processing
|
|
333
|
+
case "job.failed":
|
|
334
|
+
return "\u274C";
|
|
335
|
+
// X mark for failed jobs
|
|
336
|
+
default:
|
|
337
|
+
const _exhaustiveCheck = type;
|
|
338
|
+
return _exhaustiveCheck;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function formatRelativeTime(timestamp, t) {
|
|
342
|
+
const date = new Date(timestamp);
|
|
343
|
+
const now = /* @__PURE__ */ new Date();
|
|
344
|
+
const diffMs = now.getTime() - date.getTime();
|
|
345
|
+
const diffMins = Math.floor(diffMs / 6e4);
|
|
346
|
+
const diffHours = Math.floor(diffMs / 36e5);
|
|
347
|
+
const diffDays = Math.floor(diffMs / 864e5);
|
|
348
|
+
if (diffMins < 1) return t("justNow");
|
|
349
|
+
if (diffMins < 60) return t("minutesAgo", { count: diffMins });
|
|
350
|
+
if (diffHours < 24) return t("hoursAgo", { count: diffHours });
|
|
351
|
+
if (diffDays < 7) return t("daysAgo", { count: diffDays });
|
|
352
|
+
return date.toLocaleDateString();
|
|
353
|
+
}
|
|
354
|
+
function truncateText(text, maxLength = 50) {
|
|
355
|
+
const trimmed = text.trim();
|
|
356
|
+
return trimmed.length > maxLength ? trimmed.substring(0, maxLength) + "..." : trimmed;
|
|
357
|
+
}
|
|
358
|
+
function getEventDisplayContent(event, annotations, allEvents) {
|
|
359
|
+
const eventData = event.event;
|
|
360
|
+
const payload = eventData.payload;
|
|
361
|
+
switch (eventData.type) {
|
|
362
|
+
case "resource.created":
|
|
363
|
+
case "resource.cloned": {
|
|
364
|
+
return { exact: payload.name, isQuoted: false, isTag: false };
|
|
365
|
+
}
|
|
366
|
+
// Unified annotation events
|
|
367
|
+
case "annotation.body.updated": {
|
|
368
|
+
const annotation = annotations.find(
|
|
369
|
+
(a) => a.id.endsWith(`/annotations/${payload.annotationId}`)
|
|
370
|
+
);
|
|
371
|
+
if (annotation?.target) {
|
|
372
|
+
try {
|
|
373
|
+
const targetSelector = getTargetSelector(annotation.target);
|
|
374
|
+
const exact = getExactText(targetSelector);
|
|
375
|
+
if (exact) {
|
|
376
|
+
return { exact: truncateText(exact), isQuoted: true, isTag: false };
|
|
377
|
+
}
|
|
378
|
+
} catch {
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
case "annotation.removed": {
|
|
384
|
+
const addedEvent = allEvents.find(
|
|
385
|
+
(e) => e.event.type === "annotation.added" && e.event.payload.annotation?.id?.endsWith(`/annotations/${payload.annotationId}`)
|
|
386
|
+
);
|
|
387
|
+
if (addedEvent) {
|
|
388
|
+
const addedPayload = addedEvent.event.payload;
|
|
389
|
+
try {
|
|
390
|
+
const exact = getExactText(addedPayload.annotation.target.selector);
|
|
391
|
+
if (exact) {
|
|
392
|
+
return { exact: truncateText(exact), isQuoted: true, isTag: false };
|
|
393
|
+
}
|
|
394
|
+
} catch {
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
case "annotation.added": {
|
|
400
|
+
try {
|
|
401
|
+
const exact = getExactText(payload.annotation.target.selector);
|
|
402
|
+
if (exact) {
|
|
403
|
+
return { exact: truncateText(exact), isQuoted: true, isTag: false };
|
|
404
|
+
}
|
|
405
|
+
} catch {
|
|
406
|
+
}
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
case "entitytag.added":
|
|
410
|
+
case "entitytag.removed": {
|
|
411
|
+
return { exact: payload.entityType, isQuoted: false, isTag: true };
|
|
412
|
+
}
|
|
413
|
+
case "job.completed": {
|
|
414
|
+
if (payload.annotationUri) {
|
|
415
|
+
const annotation = annotations.find(
|
|
416
|
+
(a) => a.id === payload.annotationUri
|
|
417
|
+
);
|
|
418
|
+
if (annotation?.target) {
|
|
419
|
+
try {
|
|
420
|
+
const targetSelector = getTargetSelector(annotation.target);
|
|
421
|
+
const exact = getExactText(targetSelector);
|
|
422
|
+
if (exact) {
|
|
423
|
+
return { exact: truncateText(exact), isQuoted: true, isTag: false };
|
|
424
|
+
}
|
|
425
|
+
} catch {
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
default:
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
function getEventEntityTypes(event) {
|
|
436
|
+
const eventData = event.event;
|
|
437
|
+
if (eventData.type === "annotation.added") {
|
|
438
|
+
const payload = eventData.payload;
|
|
439
|
+
const motivation = payload?.annotation?.motivation;
|
|
440
|
+
if (motivation === "linking") {
|
|
441
|
+
return payload.annotation?.body?.entityTypes ?? [];
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return [];
|
|
445
|
+
}
|
|
446
|
+
function getResourceCreationDetails(event) {
|
|
447
|
+
const eventData = event.event;
|
|
448
|
+
const payload = eventData.payload;
|
|
449
|
+
if (eventData.type === "resource.created") {
|
|
450
|
+
return {
|
|
451
|
+
type: "created",
|
|
452
|
+
method: payload.creationMethod || "unknown",
|
|
453
|
+
userId: eventData.userId,
|
|
454
|
+
metadata: payload.metadata
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
if (eventData.type === "resource.cloned") {
|
|
458
|
+
return {
|
|
459
|
+
type: "cloned",
|
|
460
|
+
method: payload.creationMethod || "clone",
|
|
461
|
+
userId: eventData.userId,
|
|
462
|
+
sourceDocId: payload.parentResourceId,
|
|
463
|
+
parentResourceId: payload.parentResourceId,
|
|
464
|
+
metadata: payload.metadata
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/utils/locales.ts
|
|
471
|
+
var LOCALES = [
|
|
472
|
+
{ code: "ar", nativeName: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629", englishName: "Arabic" },
|
|
473
|
+
{ code: "bn", nativeName: "\u09AC\u09BE\u0982\u09B2\u09BE", englishName: "Bengali" },
|
|
474
|
+
{ code: "cs", nativeName: "\u010Ce\u0161tina", englishName: "Czech" },
|
|
475
|
+
{ code: "da", nativeName: "Dansk", englishName: "Danish" },
|
|
476
|
+
{ code: "de", nativeName: "Deutsch", englishName: "German" },
|
|
477
|
+
{ code: "el", nativeName: "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", englishName: "Greek" },
|
|
478
|
+
{ code: "en", nativeName: "English", englishName: "English" },
|
|
479
|
+
{ code: "es", nativeName: "Espa\xF1ol", englishName: "Spanish" },
|
|
480
|
+
{ code: "fa", nativeName: "\u0641\u0627\u0631\u0633\u06CC", englishName: "Persian" },
|
|
481
|
+
{ code: "fi", nativeName: "Suomi", englishName: "Finnish" },
|
|
482
|
+
{ code: "fr", nativeName: "Fran\xE7ais", englishName: "French" },
|
|
483
|
+
{ code: "he", nativeName: "\u05E2\u05D1\u05E8\u05D9\u05EA", englishName: "Hebrew" },
|
|
484
|
+
{ code: "hi", nativeName: "\u0939\u093F\u0928\u094D\u0926\u0940", englishName: "Hindi" },
|
|
485
|
+
{ code: "id", nativeName: "Bahasa Indonesia", englishName: "Indonesian" },
|
|
486
|
+
{ code: "it", nativeName: "Italiano", englishName: "Italian" },
|
|
487
|
+
{ code: "ja", nativeName: "\u65E5\u672C\u8A9E", englishName: "Japanese" },
|
|
488
|
+
{ code: "ko", nativeName: "\uD55C\uAD6D\uC5B4", englishName: "Korean" },
|
|
489
|
+
{ code: "ms", nativeName: "Bahasa Melayu", englishName: "Malay" },
|
|
490
|
+
{ code: "nl", nativeName: "Nederlands", englishName: "Dutch" },
|
|
491
|
+
{ code: "no", nativeName: "Norsk", englishName: "Norwegian" },
|
|
492
|
+
{ code: "pl", nativeName: "Polski", englishName: "Polish" },
|
|
493
|
+
{ code: "pt", nativeName: "Portugu\xEAs", englishName: "Portuguese" },
|
|
494
|
+
{ code: "ro", nativeName: "Rom\xE2n\u0103", englishName: "Romanian" },
|
|
495
|
+
{ code: "sv", nativeName: "Svenska", englishName: "Swedish" },
|
|
496
|
+
{ code: "th", nativeName: "\u0E44\u0E17\u0E22", englishName: "Thai" },
|
|
497
|
+
{ code: "tr", nativeName: "T\xFCrk\xE7e", englishName: "Turkish" },
|
|
498
|
+
{ code: "uk", nativeName: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", englishName: "Ukrainian" },
|
|
499
|
+
{ code: "vi", nativeName: "Ti\u1EBFng Vi\u1EC7t", englishName: "Vietnamese" },
|
|
500
|
+
{ code: "zh", nativeName: "\u4E2D\u6587", englishName: "Chinese" }
|
|
501
|
+
];
|
|
502
|
+
var localeByCode = new Map(
|
|
503
|
+
LOCALES.map((locale) => [locale.code.toLowerCase(), locale])
|
|
504
|
+
);
|
|
505
|
+
function getLocaleInfo(code) {
|
|
506
|
+
if (!code) return void 0;
|
|
507
|
+
return localeByCode.get(code.toLowerCase());
|
|
508
|
+
}
|
|
509
|
+
function getLocaleNativeName(code) {
|
|
510
|
+
return getLocaleInfo(code)?.nativeName;
|
|
511
|
+
}
|
|
512
|
+
function getLocaleEnglishName(code) {
|
|
513
|
+
return getLocaleInfo(code)?.englishName;
|
|
514
|
+
}
|
|
515
|
+
function formatLocaleDisplay(code) {
|
|
516
|
+
if (!code) return void 0;
|
|
517
|
+
const info = getLocaleInfo(code);
|
|
518
|
+
if (!info) return code;
|
|
519
|
+
return `${info.nativeName} (${code.toLowerCase()})`;
|
|
520
|
+
}
|
|
521
|
+
function getAllLocaleCodes() {
|
|
522
|
+
return LOCALES.map((l) => l.code);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// src/utils/resources.ts
|
|
526
|
+
function getResourceId(resource) {
|
|
527
|
+
if (!resource) return void 0;
|
|
528
|
+
const fullId = resource["@id"];
|
|
529
|
+
if (fullId.includes("/resources/")) {
|
|
530
|
+
const parts = fullId.split("/resources/");
|
|
531
|
+
const lastPart = parts[parts.length - 1];
|
|
532
|
+
return lastPart || void 0;
|
|
533
|
+
}
|
|
534
|
+
return void 0;
|
|
535
|
+
}
|
|
536
|
+
function getPrimaryRepresentation(resource) {
|
|
537
|
+
if (!resource?.representations) return void 0;
|
|
538
|
+
const reps = Array.isArray(resource.representations) ? resource.representations : [resource.representations];
|
|
539
|
+
return reps[0];
|
|
540
|
+
}
|
|
541
|
+
function getPrimaryMediaType(resource) {
|
|
542
|
+
return getPrimaryRepresentation(resource)?.mediaType;
|
|
543
|
+
}
|
|
544
|
+
function getChecksum(resource) {
|
|
545
|
+
return getPrimaryRepresentation(resource)?.checksum;
|
|
546
|
+
}
|
|
547
|
+
function getLanguage(resource) {
|
|
548
|
+
return getPrimaryRepresentation(resource)?.language;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// src/utils/validation.ts
|
|
552
|
+
var JWTTokenSchema = {
|
|
553
|
+
parse(token) {
|
|
554
|
+
if (typeof token !== "string") {
|
|
555
|
+
throw new Error("Token must be a string");
|
|
556
|
+
}
|
|
557
|
+
if (!token || token.length === 0) {
|
|
558
|
+
throw new Error("Token is required");
|
|
559
|
+
}
|
|
560
|
+
const jwtRegex = /^[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]*$/;
|
|
561
|
+
if (!jwtRegex.test(token)) {
|
|
562
|
+
throw new Error("Invalid JWT token format");
|
|
563
|
+
}
|
|
564
|
+
return token;
|
|
565
|
+
},
|
|
566
|
+
safeParse(token) {
|
|
567
|
+
try {
|
|
568
|
+
const validated = this.parse(token);
|
|
569
|
+
return { success: true, data: validated };
|
|
570
|
+
} catch (error) {
|
|
571
|
+
return {
|
|
572
|
+
success: false,
|
|
573
|
+
error: error instanceof Error ? error.message : "Invalid JWT token"
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
}
|
|
21
577
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
578
|
+
function validateData(schema, data) {
|
|
579
|
+
try {
|
|
580
|
+
const validated = schema.parse(data);
|
|
581
|
+
return { success: true, data: validated };
|
|
582
|
+
} catch (error) {
|
|
583
|
+
return {
|
|
584
|
+
success: false,
|
|
585
|
+
error: error instanceof Error ? error.message : "Validation failed"
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
function isValidEmail(email) {
|
|
590
|
+
if (email.length < 1 || email.length > 255) {
|
|
591
|
+
return false;
|
|
592
|
+
}
|
|
593
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
594
|
+
return emailRegex.test(email);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
export { JWTTokenSchema, LOCALES, extractBoundingBox, formatEventType, formatLocaleDisplay, formatRelativeTime, getAllLocaleCodes, getAnnotationExactText, getAnnotationUriFromEvent, getBodySource, getBodyType, getChecksum, getCommentText, getEntityTypes, getEventDisplayContent, getEventEmoji, getEventEntityTypes, getExactText, getLanguage, getLocaleEnglishName, getLocaleInfo, getLocaleNativeName, getPrimaryMediaType, getPrimaryRepresentation, getPrimarySelector, getResourceCreationDetails, getResourceId, getSvgSelector, getTagCategory, getTagSchemaId, getTargetSelector, getTargetSource, getTextPositionSelector, getTextQuoteSelector, hasTargetSelector, isAssessment, isBodyResolved, isComment, isEventRelatedToAnnotation, isHighlight, isReference, isResolvedReference, isResourceEvent, isStubReference, isTag, isValidEmail, validateData, validateSvgMarkup };
|
|
598
|
+
//# sourceMappingURL=index.js.map
|
|
28
599
|
//# sourceMappingURL=index.js.map
|