@airnauts/comments-core 0.1.0 → 0.2.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.
|
@@ -58,6 +58,10 @@ export declare const ThreadListResponse: z.ZodObject<{
|
|
|
58
58
|
updatedAt: z.ZodISODateTime;
|
|
59
59
|
lastActivityAt: z.ZodISODateTime;
|
|
60
60
|
schemaVersion: z.ZodNumber;
|
|
61
|
+
rootComment: z.ZodNullable<z.ZodObject<{
|
|
62
|
+
text: z.ZodString;
|
|
63
|
+
createdAt: z.ZodISODateTime;
|
|
64
|
+
}, z.core.$strip>>;
|
|
61
65
|
}, z.core.$strip>>;
|
|
62
66
|
nextCursor: z.ZodNullable<z.ZodString>;
|
|
63
67
|
}, z.core.$strip>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/contract/responses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/contract/responses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKM,CAAA;AACrC,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -344,7 +344,9 @@ var ThreadBase = z7.object({
|
|
|
344
344
|
lastActivityAt: IsoTimestamp,
|
|
345
345
|
schemaVersion: z7.number().int().positive()
|
|
346
346
|
});
|
|
347
|
-
var ThreadListItem = ThreadBase.
|
|
347
|
+
var ThreadListItem = ThreadBase.extend({
|
|
348
|
+
rootComment: z7.object({ text: z7.string(), createdAt: IsoTimestamp }).nullable()
|
|
349
|
+
}).meta({ id: "ThreadListItem" });
|
|
348
350
|
var Thread = ThreadBase.extend({
|
|
349
351
|
comments: z7.array(Comment),
|
|
350
352
|
captureContext: CaptureContext,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/anchor/weights.ts","../src/anchor/decide.ts","../src/anchor/locate-quote.ts","../src/anchor/score.ts","../src/contract/errors.ts","../src/contract/openapi.ts","../src/schemas/comment.ts","../src/ids.ts","../src/schemas/common.ts","../src/schemas/thread.ts","../src/schemas/anchor.ts","../src/schemas/capture.ts","../src/contract/requests.ts","../src/contract/responses.ts","../src/contract/operations.ts","../src/contract/wire.ts","../src/pageKey.ts"],"sourcesContent":["export const DEFAULT_WEIGHTS = {\n stableAttrs: 0.4,\n text: 0.25,\n classes: 0.15,\n role: 0.1,\n sibling: 0.05,\n ancestor: 0.05,\n} as const\n\nexport type WeightKey = keyof typeof DEFAULT_WEIGHTS\n\nexport const DEFAULT_THRESHOLDS = {\n accept: 0.6,\n margin: 0.1,\n} as const\n\nexport type Thresholds = { accept: number; margin: number }\n","import type { ScoreResult } from './score'\nimport { DEFAULT_THRESHOLDS, type Thresholds } from './weights'\n\nexport type Decision<T> =\n | { kind: 'anchored'; winner: T; score: ScoreResult }\n | {\n kind: 'orphaned'\n reason: 'noCandidates' | 'belowAccept' | 'ambiguous'\n }\n\nexport function decide<T>(\n scored: Array<{ ref: T; score: ScoreResult }>,\n opts?: Partial<Thresholds>,\n): Decision<T> {\n const accept = opts?.accept ?? DEFAULT_THRESHOLDS.accept\n const margin = opts?.margin ?? DEFAULT_THRESHOLDS.margin\n const survivors = scored\n .filter((s) => s.score.excluded !== 'tagMismatch')\n .sort((a, b) => b.score.total - a.score.total)\n const best = survivors[0]\n if (!best) return { kind: 'orphaned', reason: 'noCandidates' }\n if (best.score.total < accept) return { kind: 'orphaned', reason: 'belowAccept' }\n const second = survivors[1]\n if (second && best.score.total - second.score.total < margin) {\n return { kind: 'orphaned', reason: 'ambiguous' }\n }\n return { kind: 'anchored', winner: best.ref, score: best.score }\n}\n","export type QuoteContext = { quote: string; prefix: string; suffix: string }\nexport type QuoteOffsets = { start: number; end: number }\n\n/**\n * Build a normalized copy of `s` along with a map from normalized index → original index.\n * Normalization collapses runs of whitespace to a single space and trims; leading\n * whitespace that gets dropped is mapped through so callers can recover original offsets.\n */\nfunction normalizeWithMap(s: string): { normalized: string; toOriginal: number[] } {\n const toOriginal: number[] = []\n let out = ''\n let prevSpace = true // collapse leading whitespace\n for (let i = 0; i < s.length; i++) {\n const ch = s.charAt(i)\n const isWs = /\\s/.test(ch)\n if (isWs) {\n if (prevSpace) continue\n out += ' '\n toOriginal.push(i)\n prevSpace = true\n } else {\n out += ch\n toOriginal.push(i)\n prevSpace = false\n }\n }\n // trim trailing space\n if (out.endsWith(' ')) {\n out = out.slice(0, -1)\n toOriginal.pop()\n }\n return { normalized: out, toOriginal }\n}\n\nfunction normalizeNeedle(s: string): string {\n return s.replace(/\\s+/g, ' ').trim()\n}\n\nfunction originalRange(\n toOriginal: number[],\n normStart: number,\n normLen: number,\n haystackLen: number,\n): QuoteOffsets {\n const start = toOriginal[normStart] ?? haystackLen\n // The end offset in the original is the index *after* the last matched normalized char.\n const lastIdx = normStart + normLen - 1\n const lastOriginal = toOriginal[lastIdx] ?? haystackLen - 1\n return { start, end: lastOriginal + 1 }\n}\n\nfunction indexOfUnique(haystack: string, needle: string): number | null {\n if (needle.length === 0) return null\n const first = haystack.indexOf(needle)\n if (first < 0) return null\n if (haystack.indexOf(needle, first + 1) >= 0) return null\n return first\n}\n\nexport function locateQuote(haystack: string, ctx: QuoteContext): QuoteOffsets | null {\n const { normalized, toOriginal } = normalizeWithMap(haystack)\n const nQuote = normalizeNeedle(ctx.quote)\n const nPrefix = normalizeNeedle(ctx.prefix)\n const nSuffix = normalizeNeedle(ctx.suffix)\n if (nQuote.length === 0) return null\n\n // Strategy 1: exact prefix+quote+suffix.\n if (nPrefix || nSuffix) {\n const composite = `${nPrefix}${nPrefix ? ' ' : ''}${nQuote}${nSuffix ? ' ' : ''}${nSuffix}`\n const idx = indexOfUnique(normalized, composite)\n if (idx !== null) {\n const offset = idx + nPrefix.length + (nPrefix ? 1 : 0)\n return originalRange(toOriginal, offset, nQuote.length, haystack.length)\n }\n }\n\n // Strategy 2: unique quote.\n const qIdx = indexOfUnique(normalized, nQuote)\n if (qIdx !== null) {\n return originalRange(toOriginal, qIdx, nQuote.length, haystack.length)\n }\n\n // Strategy 3: prefix+quote unique.\n if (nPrefix) {\n const composite = `${nPrefix} ${nQuote}`\n const idx = indexOfUnique(normalized, composite)\n if (idx !== null) {\n return originalRange(toOriginal, idx + nPrefix.length + 1, nQuote.length, haystack.length)\n }\n }\n\n // Strategy 4: quote+suffix unique.\n if (nSuffix) {\n const composite = `${nQuote} ${nSuffix}`\n const idx = indexOfUnique(normalized, composite)\n if (idx !== null) {\n return originalRange(toOriginal, idx, nQuote.length, haystack.length)\n }\n }\n\n return null\n}\n","import type { Signals } from '../schemas/anchor'\nimport { DEFAULT_WEIGHTS, type WeightKey } from './weights'\n\nexport type ScoreComponents = Record<WeightKey, number>\n\nexport type ScoreResult = {\n total: number\n components: ScoreComponents\n excluded: false | 'tagMismatch'\n}\n\nconst ZERO_COMPONENTS: ScoreComponents = {\n stableAttrs: 0,\n text: 0,\n classes: 0,\n role: 0,\n sibling: 0,\n ancestor: 0,\n}\n\nexport function scoreCandidate(stored: Signals, candidate: Signals): ScoreResult {\n if (stored.tag.toLowerCase() !== candidate.tag.toLowerCase()) {\n return { total: 0, components: { ...ZERO_COMPONENTS }, excluded: 'tagMismatch' }\n }\n const components: ScoreComponents = {\n stableAttrs: scoreStableAttrs(stored.stableAttrs, candidate.stableAttrs),\n text: scoreText(stored.textSnippet, candidate.textSnippet),\n classes: scoreClasses(stored.classes, candidate.classes),\n role: scoreRole(stored.role, candidate.role),\n sibling: scoreSibling(stored.siblingIndex, candidate.siblingIndex),\n ancestor: scoreAncestor(stored.ancestorTrail, candidate.ancestorTrail),\n }\n const total =\n components.stableAttrs * DEFAULT_WEIGHTS.stableAttrs +\n components.text * DEFAULT_WEIGHTS.text +\n components.classes * DEFAULT_WEIGHTS.classes +\n components.role * DEFAULT_WEIGHTS.role +\n components.sibling * DEFAULT_WEIGHTS.sibling +\n components.ancestor * DEFAULT_WEIGHTS.ancestor\n return { total, components, excluded: false }\n}\n\nfunction priorityOf(key: string, otherCount: number): number {\n if (key === 'id') return 0.5\n if (key === 'data-testid') return 0.3\n if (key.startsWith('data-')) return otherCount > 0 ? 0.2 / otherCount : 0\n return 0\n}\n\nfunction scoreStableAttrs(\n stored: Record<string, string> | undefined,\n candidate: Record<string, string> | undefined,\n): number {\n if (!stored) return 0\n const keys = Object.keys(stored)\n if (keys.length === 0) return 0\n const otherCount = keys.filter((k) => k.startsWith('data-') && k !== 'data-testid').length\n let max = 0\n let raw = 0\n for (const k of keys) {\n const p = priorityOf(k, otherCount)\n max += p\n const storedValue = stored[k]\n if (storedValue !== undefined && candidate?.[k] === storedValue) {\n raw += p\n }\n }\n return max === 0 ? 0 : raw / max\n}\nfunction scoreText(a: string | undefined, b: string | undefined): number {\n if (!a || !b) return 0\n const aPad = a.length < 2 ? `${a} ` : a\n const bPad = b.length < 2 ? `${b} ` : b\n const bigrams = (s: string): Map<string, number> => {\n const m = new Map<string, number>()\n for (let i = 0; i < s.length - 1; i++) {\n const g = s.slice(i, i + 2)\n m.set(g, (m.get(g) ?? 0) + 1)\n }\n return m\n }\n const ba = bigrams(aPad)\n const bb = bigrams(bPad)\n let inter = 0\n for (const [g, n] of ba) {\n const m = bb.get(g)\n if (m !== undefined) inter += Math.min(n, m)\n }\n const totalA = Array.from(ba.values()).reduce((s, n) => s + n, 0)\n const totalB = Array.from(bb.values()).reduce((s, n) => s + n, 0)\n return totalA + totalB === 0 ? 0 : (2 * inter) / (totalA + totalB)\n}\nfunction scoreClasses(a: string[], b: string[]): number {\n if (a.length === 0 && b.length === 0) return 0\n const setA = new Set(a)\n const setB = new Set(b)\n let inter = 0\n for (const x of setA) if (setB.has(x)) inter++\n const union = setA.size + setB.size - inter\n return union === 0 ? 0 : inter / union\n}\nfunction scoreRole(a: string | undefined, b: string | undefined): number {\n if (!a || !b) return 0\n return a === b ? 1 : 0\n}\nfunction scoreSibling(a: number, b: number): number {\n return 1 / (1 + Math.abs(a - b))\n}\nfunction scoreAncestor(a: string[], b: string[]): number {\n if (a.length === 0 && b.length === 0) return 0\n const setA = new Set(a)\n const setB = new Set(b)\n let inter = 0\n for (const x of setA) if (setB.has(x)) inter++\n const union = setA.size + setB.size - inter\n return union === 0 ? 0 : inter / union\n}\n","import { z } from 'zod'\n\nexport const ERROR_CODES = [\n 'VALIDATION_FAILED',\n 'AUTH_INVALID_KEY',\n 'ORIGIN_NOT_ALLOWED',\n 'NOT_FOUND',\n 'CONFLICT',\n 'UPLOAD_TOO_LARGE',\n 'RATE_LIMITED',\n 'INTERNAL',\n] as const\n\nexport const ErrorCode = z.enum(ERROR_CODES)\nexport type ErrorCode = z.infer<typeof ErrorCode>\n\nexport const ErrorResponse = z\n .object({\n error: z.object({\n code: ErrorCode,\n message: z.string(),\n details: z.unknown().optional(),\n }),\n })\n .meta({ id: 'ErrorResponse' })\nexport type ErrorResponse = z.infer<typeof ErrorResponse>\n\nexport const ERROR_STATUS: Record<ErrorCode, number> = {\n VALIDATION_FAILED: 400,\n AUTH_INVALID_KEY: 401,\n ORIGIN_NOT_ALLOWED: 403,\n NOT_FOUND: 404,\n CONFLICT: 409,\n UPLOAD_TOO_LARGE: 413,\n RATE_LIMITED: 429,\n INTERNAL: 500,\n}\n","import {\n createDocument,\n type ZodOpenApiOperationObject,\n type ZodOpenApiPathsObject,\n type ZodOpenApiResponsesObject,\n} from 'zod-openapi'\nimport { ERROR_STATUS, ErrorResponse } from './errors'\nimport { operations } from './operations'\nimport { UploadForm } from './requests'\nimport { KEY_HEADER_NAME } from './wire'\n\nfunction toOpenApiPath(path: string): string {\n return path.replace(/:([A-Za-z0-9_]+)/g, '{$1}')\n}\n\nexport function buildOpenApiDocument(): ReturnType<typeof createDocument> {\n const paths: ZodOpenApiPathsObject = {}\n\n for (const op of operations) {\n // ZodOpenApiResponsesObject only accepts keys matching `${1|2|3|4|5}${string}`,\n // so we cast via unknown to satisfy the template-literal index signature.\n const responses = {} as ZodOpenApiResponsesObject\n ;(responses as Record<string, unknown>)[String(op.success.status)] = {\n description: `${op.operationId} success`,\n content: { 'application/json': { schema: op.success.schema } },\n }\n for (const code of op.errors) {\n ;(responses as Record<string, unknown>)[String(ERROR_STATUS[code])] = {\n description: code,\n content: { 'application/json': { schema: ErrorResponse } },\n }\n }\n\n const operation: ZodOpenApiOperationObject = {\n operationId: op.operationId,\n summary: op.summary,\n responses,\n }\n if (op.params || op.query) {\n operation.requestParams = {}\n if (op.params) operation.requestParams.path = op.params\n if (op.query) operation.requestParams.query = op.query\n }\n if (op.body === 'multipart') {\n operation.requestBody = { content: { 'multipart/form-data': { schema: UploadForm } } }\n } else if (op.body) {\n operation.requestBody = { content: { 'application/json': { schema: op.body } } }\n }\n\n const openApiPath = toOpenApiPath(op.path)\n const method = op.method.toLowerCase() as 'get' | 'post' | 'patch'\n paths[openApiPath] = { ...(paths[openApiPath] ?? {}), [method]: operation }\n }\n\n return createDocument({\n openapi: '3.1.0',\n info: { title: 'Comments API', version: '1.0.0' },\n components: {\n securitySchemes: {\n commentsKey: { type: 'apiKey', in: 'header', name: KEY_HEADER_NAME },\n },\n },\n security: [{ commentsKey: [] }],\n paths,\n })\n}\n","import { z } from 'zod'\nimport { AttachmentId, AuthorId, CommentId } from '../ids'\nimport { Email, IsoTimestamp } from './common'\n\nexport const Author = z\n .object({ id: AuthorId.optional(), email: Email, name: z.string().optional() })\n .meta({ id: 'Author' })\nexport type Author = z.infer<typeof Author>\n\nexport const Attachment = z\n .object({\n id: AttachmentId,\n url: z.url(),\n name: z.string(),\n contentType: z.string(),\n size: z.number().int().nonnegative(),\n w: z.number().int().positive().optional(),\n h: z.number().int().positive().optional(),\n })\n .meta({ id: 'Attachment' })\nexport type Attachment = z.infer<typeof Attachment>\n\nexport const Comment = z\n .object({\n id: CommentId,\n author: Author,\n text: z.string(),\n attachments: z.array(Attachment),\n createdAt: IsoTimestamp,\n editedAt: IsoTimestamp.optional(),\n })\n .meta({ id: 'Comment' })\nexport type Comment = z.infer<typeof Comment>\n","import { z } from 'zod'\n\nexport const ThreadId = z.string().min(1).brand<'ThreadId'>()\nexport type ThreadId = z.infer<typeof ThreadId>\n\nexport const CommentId = z.string().min(1).brand<'CommentId'>()\nexport type CommentId = z.infer<typeof CommentId>\n\nexport const AuthorId = z.string().min(1).brand<'AuthorId'>()\nexport type AuthorId = z.infer<typeof AuthorId>\n\nexport const AttachmentId = z.string().min(1).brand<'AttachmentId'>()\nexport type AttachmentId = z.infer<typeof AttachmentId>\n","import { z } from 'zod'\n\nexport const Email = z.email().meta({ id: 'Email' })\nexport type Email = z.infer<typeof Email>\n\nexport const IsoTimestamp = z.iso.datetime().meta({ id: 'IsoTimestamp' })\nexport type IsoTimestamp = z.infer<typeof IsoTimestamp>\n\n// Opaque pagination token — intentionally NOT registered as a named component\n// (the spec treats the cursor as an opaque string; its codec lives server-side in M3).\nexport const Cursor = z.string().min(1)\nexport type Cursor = z.infer<typeof Cursor>\n","import { z } from 'zod'\nimport { ThreadId } from '../ids'\nimport { Anchor } from './anchor'\nimport { CaptureContext, Provenance } from './capture'\nimport { Author, Comment } from './comment'\nimport { IsoTimestamp } from './common'\n\nexport const ThreadStatus = z.enum(['open', 'resolved'])\nexport type ThreadStatus = z.infer<typeof ThreadStatus>\n\nexport const AnchorState = z.enum(['anchored', 'orphaned'])\nexport type AnchorState = z.infer<typeof AnchorState>\n\nconst ThreadBase = z.object({\n id: ThreadId,\n scope: z.literal('page'),\n pageKey: z.string().nullable(),\n pageUrl: z.url(),\n pageTitle: z.string().optional(),\n anchor: Anchor,\n status: ThreadStatus,\n anchorState: AnchorState,\n selectionLost: z.boolean().optional(),\n commentCount: z.number().int().nonnegative(),\n unresolvedCount: z.number().int().nonnegative(),\n createdBy: Author,\n createdAt: IsoTimestamp,\n updatedAt: IsoTimestamp,\n lastActivityAt: IsoTimestamp,\n schemaVersion: z.number().int().positive(),\n})\n\nexport const ThreadListItem = ThreadBase.meta({ id: 'ThreadListItem' })\nexport type ThreadListItem = z.infer<typeof ThreadListItem>\n\nexport const Thread = ThreadBase.extend({\n comments: z.array(Comment),\n captureContext: CaptureContext,\n provenance: Provenance.optional(),\n}).meta({ id: 'Thread' })\nexport type Thread = z.infer<typeof Thread>\n","import { z } from 'zod'\n\nexport const ANCHOR_SCHEMA_VERSION = 1\n\nconst Selectors = z.tuple([z.string(), z.string()])\n\nexport const Signals = z\n .object({\n tag: z.string(),\n role: z.string().optional(),\n textSnippet: z.string().max(120).optional(),\n classes: z.array(z.string()),\n siblingIndex: z.number().int().nonnegative(),\n ancestorTrail: z.array(z.string()),\n stableAttrs: z.record(z.string(), z.string()).optional(),\n })\n .meta({ id: 'Signals' })\nexport type Signals = z.infer<typeof Signals>\n\nconst SelectionEndpoint = z.object({\n selectors: Selectors,\n textNodeIndex: z.number().int().nonnegative(),\n offset: z.number().int().nonnegative(),\n})\n\nexport const Selection = z\n .object({\n start: SelectionEndpoint,\n end: SelectionEndpoint,\n quote: z.string(),\n prefix: z.string(),\n suffix: z.string(),\n })\n .meta({ id: 'Selection' })\nexport type Selection = z.infer<typeof Selection>\n\nexport const Anchor = z\n .object({\n // Positive int (not z.literal(ANCHOR_SCHEMA_VERSION)) so anchors written under a future\n // schema version still parse (forward-compatible reads); ANCHOR_SCHEMA_VERSION is the write-time default.\n schemaVersion: z.number().int().positive(),\n selectors: Selectors,\n signals: Signals,\n offset: z.object({ fx: z.number().min(0).max(1), fy: z.number().min(0).max(1) }),\n selection: Selection.optional(),\n })\n .meta({ id: 'Anchor' })\nexport type Anchor = z.infer<typeof Anchor>\n","import { z } from 'zod'\n\nexport const CaptureContext = z\n .object({\n viewportW: z.number().int().positive(),\n viewportH: z.number().int().positive(),\n devicePixelRatio: z.number().positive(),\n userAgent: z.string(),\n })\n .meta({ id: 'CaptureContext' })\nexport type CaptureContext = z.infer<typeof CaptureContext>\n\nexport const Provenance = z\n .object({\n commitSha: z.string().optional(),\n branch: z.string().optional(),\n deploymentId: z.string().optional(),\n })\n .meta({ id: 'Provenance' })\nexport type Provenance = z.infer<typeof Provenance>\n","import { z } from 'zod'\nimport { AttachmentId, ThreadId } from '../ids'\nimport { Anchor, Signals } from '../schemas/anchor'\nimport { CaptureContext, Provenance } from '../schemas/capture'\nimport { Author } from '../schemas/comment'\nimport { Cursor } from '../schemas/common'\nimport { AnchorState, ThreadStatus } from '../schemas/thread'\n\nconst Selectors = z.tuple([z.string(), z.string()])\n\n// A comment must carry content: either non-blank text or at least one attachment.\n// Text alone, image alone, or both are all valid — image-only comments are allowed.\nconst hasContent = (c: { text: string; attachmentIds?: readonly string[] }): boolean =>\n c.text.trim().length > 0 || (c.attachmentIds?.length ?? 0) > 0\nconst CONTENT_REQUIRED = { message: 'a comment needs text or an attachment' }\n\nexport const CreateThreadBody = z\n .object({\n pageKey: z.string().optional(),\n pageUrl: z.url(),\n pageTitle: z.string().optional(),\n anchor: Anchor,\n comment: z\n .object({ text: z.string(), attachmentIds: z.array(AttachmentId).optional() })\n .refine(hasContent, CONTENT_REQUIRED),\n author: Author,\n captureContext: CaptureContext,\n provenance: Provenance.optional(),\n })\n .meta({ id: 'CreateThreadBody' })\nexport type CreateThreadBody = z.infer<typeof CreateThreadBody>\n\nexport const ListThreadsQuery = z\n .object({\n pageKey: z.string().optional(),\n status: ThreadStatus.optional(),\n sort: z.literal('updatedAt').optional(),\n cursor: Cursor.optional(),\n })\n .meta({ id: 'ListThreadsQuery' })\nexport type ListThreadsQuery = z.infer<typeof ListThreadsQuery>\n\nexport const ThreadIdParam = z.object({ id: ThreadId })\nexport type ThreadIdParam = z.infer<typeof ThreadIdParam>\n\nexport const AddCommentBody = z\n .object({\n text: z.string(),\n attachmentIds: z.array(AttachmentId).optional(),\n author: Author,\n })\n .refine(hasContent, CONTENT_REQUIRED)\n .meta({ id: 'AddCommentBody' })\nexport type AddCommentBody = z.infer<typeof AddCommentBody>\n\nexport const SetThreadStatusBody = z\n .object({ status: ThreadStatus })\n .meta({ id: 'SetThreadStatusBody' })\nexport type SetThreadStatusBody = z.infer<typeof SetThreadStatusBody>\n\nexport const RefreshAnchorBody = z\n .object({\n selectors: Selectors.optional(),\n signals: Signals.optional(),\n anchorState: AnchorState,\n selectionLost: z.boolean().optional(),\n })\n .meta({ id: 'RefreshAnchorBody' })\nexport type RefreshAnchorBody = z.infer<typeof RefreshAnchorBody>\n\n// Documentation-only shape for the multipart upload (the binary is validated server-side).\nexport const UploadForm = z\n .object({\n file: z.string().meta({ override: { type: 'string', format: 'binary' } }),\n })\n .meta({ id: 'UploadForm' })\nexport type UploadForm = z.infer<typeof UploadForm>\n","import { z } from 'zod'\nimport { ThreadListItem } from '../schemas/thread'\n\nexport const ThreadListResponse = z\n .object({\n threads: z.array(ThreadListItem),\n nextCursor: z.string().nullable(),\n })\n .meta({ id: 'ThreadListResponse' })\nexport type ThreadListResponse = z.infer<typeof ThreadListResponse>\n","import type { z } from 'zod'\nimport { Attachment, Comment } from '../schemas/comment'\nimport { Thread, ThreadListItem } from '../schemas/thread'\nimport type { ErrorCode } from './errors'\nimport {\n AddCommentBody,\n CreateThreadBody,\n ListThreadsQuery,\n RefreshAnchorBody,\n SetThreadStatusBody,\n ThreadIdParam,\n} from './requests'\nimport { ThreadListResponse } from './responses'\n\nexport interface Operation {\n operationId: string\n method: 'GET' | 'POST' | 'PATCH'\n path: string\n summary: string\n params?: z.ZodObject\n query?: z.ZodObject\n body?: z.ZodType | 'multipart'\n success: { status: number; schema: z.ZodType }\n errors: ErrorCode[]\n}\n\nconst AUTH_ERRORS: ErrorCode[] = ['AUTH_INVALID_KEY', 'ORIGIN_NOT_ALLOWED', 'RATE_LIMITED']\n\nexport const operations: Operation[] = [\n {\n operationId: 'createThread',\n method: 'POST',\n path: '/threads',\n summary: 'Create a thread with its first comment',\n body: CreateThreadBody,\n success: { status: 201, schema: Thread },\n errors: ['VALIDATION_FAILED', ...AUTH_ERRORS],\n },\n {\n operationId: 'listThreads',\n method: 'GET',\n path: '/threads',\n summary: 'List threads on a page (?pageKey=) or across all pages (panel)',\n query: ListThreadsQuery,\n success: { status: 200, schema: ThreadListResponse },\n errors: ['VALIDATION_FAILED', ...AUTH_ERRORS],\n },\n {\n operationId: 'getThread',\n method: 'GET',\n path: '/threads/:id',\n summary: 'Get a single thread with its comments',\n params: ThreadIdParam,\n success: { status: 200, schema: Thread },\n errors: ['NOT_FOUND', ...AUTH_ERRORS],\n },\n {\n operationId: 'addComment',\n method: 'POST',\n path: '/threads/:id/comments',\n summary: 'Add a reply to a thread',\n params: ThreadIdParam,\n body: AddCommentBody,\n success: { status: 201, schema: Comment },\n errors: ['VALIDATION_FAILED', 'NOT_FOUND', ...AUTH_ERRORS],\n },\n {\n operationId: 'setThreadStatus',\n method: 'PATCH',\n path: '/threads/:id',\n summary: 'Resolve or reopen a thread',\n params: ThreadIdParam,\n body: SetThreadStatusBody,\n success: { status: 200, schema: Thread },\n errors: ['VALIDATION_FAILED', 'NOT_FOUND', 'CONFLICT', ...AUTH_ERRORS],\n },\n {\n operationId: 'refreshAnchor',\n method: 'PATCH',\n path: '/threads/:id/anchor',\n summary: 'Report a re-match result (self-heal the stored anchor)',\n params: ThreadIdParam,\n body: RefreshAnchorBody,\n success: { status: 200, schema: ThreadListItem },\n errors: ['VALIDATION_FAILED', 'NOT_FOUND', ...AUTH_ERRORS],\n },\n {\n operationId: 'uploadAttachment',\n method: 'POST',\n path: '/uploads',\n summary: 'Upload an image attachment (multipart)',\n body: 'multipart',\n success: { status: 201, schema: Attachment },\n errors: ['VALIDATION_FAILED', 'UPLOAD_TOO_LARGE', ...AUTH_ERRORS],\n },\n]\n","export const KEY_HEADER_NAME = 'x-comments-key'\n","export type PageKeyFn = (url: string) => string\n\nexport function normalizePageKey(url: string | URL): string {\n const u = typeof url === 'string' ? new URL(url) : url\n let pathname = u.pathname\n if (pathname.length > 1 && pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1)\n }\n return `${u.origin}${pathname}`\n}\n"],"mappings":";AAAO,IAAM,kBAAkB;AAAA,EAC7B,aAAa;AAAA,EACb,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AACZ;AAIO,IAAM,qBAAqB;AAAA,EAChC,QAAQ;AAAA,EACR,QAAQ;AACV;;;ACJO,SAAS,OACd,QACA,MACa;AACb,QAAM,SAAS,MAAM,UAAU,mBAAmB;AAClD,QAAM,SAAS,MAAM,UAAU,mBAAmB;AAClD,QAAM,YAAY,OACf,OAAO,CAAC,MAAM,EAAE,MAAM,aAAa,aAAa,EAChD,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,QAAQ,EAAE,MAAM,KAAK;AAC/C,QAAM,OAAO,UAAU,CAAC;AACxB,MAAI,CAAC,KAAM,QAAO,EAAE,MAAM,YAAY,QAAQ,eAAe;AAC7D,MAAI,KAAK,MAAM,QAAQ,OAAQ,QAAO,EAAE,MAAM,YAAY,QAAQ,cAAc;AAChF,QAAM,SAAS,UAAU,CAAC;AAC1B,MAAI,UAAU,KAAK,MAAM,QAAQ,OAAO,MAAM,QAAQ,QAAQ;AAC5D,WAAO,EAAE,MAAM,YAAY,QAAQ,YAAY;AAAA,EACjD;AACA,SAAO,EAAE,MAAM,YAAY,QAAQ,KAAK,KAAK,OAAO,KAAK,MAAM;AACjE;;;ACnBA,SAAS,iBAAiB,GAAyD;AACjF,QAAM,aAAuB,CAAC;AAC9B,MAAI,MAAM;AACV,MAAI,YAAY;AAChB,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,UAAM,KAAK,EAAE,OAAO,CAAC;AACrB,UAAM,OAAO,KAAK,KAAK,EAAE;AACzB,QAAI,MAAM;AACR,UAAI,UAAW;AACf,aAAO;AACP,iBAAW,KAAK,CAAC;AACjB,kBAAY;AAAA,IACd,OAAO;AACL,aAAO;AACP,iBAAW,KAAK,CAAC;AACjB,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,MAAI,IAAI,SAAS,GAAG,GAAG;AACrB,UAAM,IAAI,MAAM,GAAG,EAAE;AACrB,eAAW,IAAI;AAAA,EACjB;AACA,SAAO,EAAE,YAAY,KAAK,WAAW;AACvC;AAEA,SAAS,gBAAgB,GAAmB;AAC1C,SAAO,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACrC;AAEA,SAAS,cACP,YACA,WACA,SACA,aACc;AACd,QAAM,QAAQ,WAAW,SAAS,KAAK;AAEvC,QAAM,UAAU,YAAY,UAAU;AACtC,QAAM,eAAe,WAAW,OAAO,KAAK,cAAc;AAC1D,SAAO,EAAE,OAAO,KAAK,eAAe,EAAE;AACxC;AAEA,SAAS,cAAc,UAAkB,QAA+B;AACtE,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,QAAQ,SAAS,QAAQ,MAAM;AACrC,MAAI,QAAQ,EAAG,QAAO;AACtB,MAAI,SAAS,QAAQ,QAAQ,QAAQ,CAAC,KAAK,EAAG,QAAO;AACrD,SAAO;AACT;AAEO,SAAS,YAAY,UAAkB,KAAwC;AACpF,QAAM,EAAE,YAAY,WAAW,IAAI,iBAAiB,QAAQ;AAC5D,QAAM,SAAS,gBAAgB,IAAI,KAAK;AACxC,QAAM,UAAU,gBAAgB,IAAI,MAAM;AAC1C,QAAM,UAAU,gBAAgB,IAAI,MAAM;AAC1C,MAAI,OAAO,WAAW,EAAG,QAAO;AAGhC,MAAI,WAAW,SAAS;AACtB,UAAM,YAAY,GAAG,OAAO,GAAG,UAAU,MAAM,EAAE,GAAG,MAAM,GAAG,UAAU,MAAM,EAAE,GAAG,OAAO;AACzF,UAAM,MAAM,cAAc,YAAY,SAAS;AAC/C,QAAI,QAAQ,MAAM;AAChB,YAAM,SAAS,MAAM,QAAQ,UAAU,UAAU,IAAI;AACrD,aAAO,cAAc,YAAY,QAAQ,OAAO,QAAQ,SAAS,MAAM;AAAA,IACzE;AAAA,EACF;AAGA,QAAM,OAAO,cAAc,YAAY,MAAM;AAC7C,MAAI,SAAS,MAAM;AACjB,WAAO,cAAc,YAAY,MAAM,OAAO,QAAQ,SAAS,MAAM;AAAA,EACvE;AAGA,MAAI,SAAS;AACX,UAAM,YAAY,GAAG,OAAO,IAAI,MAAM;AACtC,UAAM,MAAM,cAAc,YAAY,SAAS;AAC/C,QAAI,QAAQ,MAAM;AAChB,aAAO,cAAc,YAAY,MAAM,QAAQ,SAAS,GAAG,OAAO,QAAQ,SAAS,MAAM;AAAA,IAC3F;AAAA,EACF;AAGA,MAAI,SAAS;AACX,UAAM,YAAY,GAAG,MAAM,IAAI,OAAO;AACtC,UAAM,MAAM,cAAc,YAAY,SAAS;AAC/C,QAAI,QAAQ,MAAM;AAChB,aAAO,cAAc,YAAY,KAAK,OAAO,QAAQ,SAAS,MAAM;AAAA,IACtE;AAAA,EACF;AAEA,SAAO;AACT;;;AC1FA,IAAM,kBAAmC;AAAA,EACvC,aAAa;AAAA,EACb,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AACZ;AAEO,SAAS,eAAe,QAAiB,WAAiC;AAC/E,MAAI,OAAO,IAAI,YAAY,MAAM,UAAU,IAAI,YAAY,GAAG;AAC5D,WAAO,EAAE,OAAO,GAAG,YAAY,EAAE,GAAG,gBAAgB,GAAG,UAAU,cAAc;AAAA,EACjF;AACA,QAAM,aAA8B;AAAA,IAClC,aAAa,iBAAiB,OAAO,aAAa,UAAU,WAAW;AAAA,IACvE,MAAM,UAAU,OAAO,aAAa,UAAU,WAAW;AAAA,IACzD,SAAS,aAAa,OAAO,SAAS,UAAU,OAAO;AAAA,IACvD,MAAM,UAAU,OAAO,MAAM,UAAU,IAAI;AAAA,IAC3C,SAAS,aAAa,OAAO,cAAc,UAAU,YAAY;AAAA,IACjE,UAAU,cAAc,OAAO,eAAe,UAAU,aAAa;AAAA,EACvE;AACA,QAAM,QACJ,WAAW,cAAc,gBAAgB,cACzC,WAAW,OAAO,gBAAgB,OAClC,WAAW,UAAU,gBAAgB,UACrC,WAAW,OAAO,gBAAgB,OAClC,WAAW,UAAU,gBAAgB,UACrC,WAAW,WAAW,gBAAgB;AACxC,SAAO,EAAE,OAAO,YAAY,UAAU,MAAM;AAC9C;AAEA,SAAS,WAAW,KAAa,YAA4B;AAC3D,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,QAAQ,cAAe,QAAO;AAClC,MAAI,IAAI,WAAW,OAAO,EAAG,QAAO,aAAa,IAAI,MAAM,aAAa;AACxE,SAAO;AACT;AAEA,SAAS,iBACP,QACA,WACQ;AACR,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,aAAa,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,KAAK,MAAM,aAAa,EAAE;AACpF,MAAI,MAAM;AACV,MAAI,MAAM;AACV,aAAW,KAAK,MAAM;AACpB,UAAM,IAAI,WAAW,GAAG,UAAU;AAClC,WAAO;AACP,UAAM,cAAc,OAAO,CAAC;AAC5B,QAAI,gBAAgB,UAAa,YAAY,CAAC,MAAM,aAAa;AAC/D,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO,QAAQ,IAAI,IAAI,MAAM;AAC/B;AACA,SAAS,UAAU,GAAuB,GAA+B;AACvE,MAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,QAAM,OAAO,EAAE,SAAS,IAAI,GAAG,CAAC,MAAM;AACtC,QAAM,OAAO,EAAE,SAAS,IAAI,GAAG,CAAC,MAAM;AACtC,QAAM,UAAU,CAAC,MAAmC;AAClD,UAAM,IAAI,oBAAI,IAAoB;AAClC,aAAS,IAAI,GAAG,IAAI,EAAE,SAAS,GAAG,KAAK;AACrC,YAAM,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;AAC1B,QAAE,IAAI,IAAI,EAAE,IAAI,CAAC,KAAK,KAAK,CAAC;AAAA,IAC9B;AACA,WAAO;AAAA,EACT;AACA,QAAM,KAAK,QAAQ,IAAI;AACvB,QAAM,KAAK,QAAQ,IAAI;AACvB,MAAI,QAAQ;AACZ,aAAW,CAAC,GAAG,CAAC,KAAK,IAAI;AACvB,UAAM,IAAI,GAAG,IAAI,CAAC;AAClB,QAAI,MAAM,OAAW,UAAS,KAAK,IAAI,GAAG,CAAC;AAAA,EAC7C;AACA,QAAM,SAAS,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAChE,QAAM,SAAS,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAChE,SAAO,SAAS,WAAW,IAAI,IAAK,IAAI,SAAU,SAAS;AAC7D;AACA,SAAS,aAAa,GAAa,GAAqB;AACtD,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAC7C,QAAM,OAAO,IAAI,IAAI,CAAC;AACtB,QAAM,OAAO,IAAI,IAAI,CAAC;AACtB,MAAI,QAAQ;AACZ,aAAW,KAAK,KAAM,KAAI,KAAK,IAAI,CAAC,EAAG;AACvC,QAAM,QAAQ,KAAK,OAAO,KAAK,OAAO;AACtC,SAAO,UAAU,IAAI,IAAI,QAAQ;AACnC;AACA,SAAS,UAAU,GAAuB,GAA+B;AACvE,MAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AACrB,SAAO,MAAM,IAAI,IAAI;AACvB;AACA,SAAS,aAAa,GAAW,GAAmB;AAClD,SAAO,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC;AAChC;AACA,SAAS,cAAc,GAAa,GAAqB;AACvD,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAC7C,QAAM,OAAO,IAAI,IAAI,CAAC;AACtB,QAAM,OAAO,IAAI,IAAI,CAAC;AACtB,MAAI,QAAQ;AACZ,aAAW,KAAK,KAAM,KAAI,KAAK,IAAI,CAAC,EAAG;AACvC,QAAM,QAAQ,KAAK,OAAO,KAAK,OAAO;AACtC,SAAO,UAAU,IAAI,IAAI,QAAQ;AACnC;;;ACpHA,SAAS,SAAS;AAEX,IAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,YAAY,EAAE,KAAK,WAAW;AAGpC,IAAM,gBAAgB,EAC1B,OAAO;AAAA,EACN,OAAO,EAAE,OAAO;AAAA,IACd,MAAM;AAAA,IACN,SAAS,EAAE,OAAO;AAAA,IAClB,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAChC,CAAC;AACH,CAAC,EACA,KAAK,EAAE,IAAI,gBAAgB,CAAC;AAGxB,IAAM,eAA0C;AAAA,EACrD,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,UAAU;AACZ;;;ACpCA;AAAA,EACE;AAAA,OAIK;;;ACLP,SAAS,KAAAA,UAAS;;;ACAlB,SAAS,KAAAC,UAAS;AAEX,IAAM,WAAWA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAkB;AAGrD,IAAM,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAmB;AAGvD,IAAM,WAAWA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAkB;AAGrD,IAAM,eAAeA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAsB;;;ACXpE,SAAS,KAAAC,UAAS;AAEX,IAAM,QAAQA,GAAE,MAAM,EAAE,KAAK,EAAE,IAAI,QAAQ,CAAC;AAG5C,IAAM,eAAeA,GAAE,IAAI,SAAS,EAAE,KAAK,EAAE,IAAI,eAAe,CAAC;AAKjE,IAAM,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;;;AFN/B,IAAM,SAASC,GACnB,OAAO,EAAE,IAAI,SAAS,SAAS,GAAG,OAAO,OAAO,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAC7E,KAAK,EAAE,IAAI,SAAS,CAAC;AAGjB,IAAM,aAAaA,GACvB,OAAO;AAAA,EACN,IAAI;AAAA,EACJ,KAAKA,GAAE,IAAI;AAAA,EACX,MAAMA,GAAE,OAAO;AAAA,EACf,aAAaA,GAAE,OAAO;AAAA,EACtB,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EACnC,GAAGA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,EACxC,GAAGA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAC1C,CAAC,EACA,KAAK,EAAE,IAAI,aAAa,CAAC;AAGrB,IAAM,UAAUA,GACpB,OAAO;AAAA,EACN,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,MAAMA,GAAE,OAAO;AAAA,EACf,aAAaA,GAAE,MAAM,UAAU;AAAA,EAC/B,WAAW;AAAA,EACX,UAAU,aAAa,SAAS;AAClC,CAAC,EACA,KAAK,EAAE,IAAI,UAAU,CAAC;;;AG/BzB,SAAS,KAAAC,UAAS;;;ACAlB,SAAS,KAAAC,UAAS;AAEX,IAAM,wBAAwB;AAErC,IAAM,YAAYA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,OAAO,CAAC,CAAC;AAE3C,IAAM,UAAUA,GACpB,OAAO;AAAA,EACN,KAAKA,GAAE,OAAO;AAAA,EACd,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,aAAaA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1C,SAASA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EAC3B,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC3C,eAAeA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EACjC,aAAaA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,OAAO,CAAC,EAAE,SAAS;AACzD,CAAC,EACA,KAAK,EAAE,IAAI,UAAU,CAAC;AAGzB,IAAM,oBAAoBA,GAAE,OAAO;AAAA,EACjC,WAAW;AAAA,EACX,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC5C,QAAQA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AACvC,CAAC;AAEM,IAAM,YAAYA,GACtB,OAAO;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,OAAOA,GAAE,OAAO;AAAA,EAChB,QAAQA,GAAE,OAAO;AAAA,EACjB,QAAQA,GAAE,OAAO;AACnB,CAAC,EACA,KAAK,EAAE,IAAI,YAAY,CAAC;AAGpB,IAAM,SAASA,GACnB,OAAO;AAAA;AAAA;AAAA,EAGN,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACzC,WAAW;AAAA,EACX,SAAS;AAAA,EACT,QAAQA,GAAE,OAAO,EAAE,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;AAAA,EAC/E,WAAW,UAAU,SAAS;AAChC,CAAC,EACA,KAAK,EAAE,IAAI,SAAS,CAAC;;;AC9CxB,SAAS,KAAAC,UAAS;AAEX,IAAM,iBAAiBA,GAC3B,OAAO;AAAA,EACN,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACrC,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACrC,kBAAkBA,GAAE,OAAO,EAAE,SAAS;AAAA,EACtC,WAAWA,GAAE,OAAO;AACtB,CAAC,EACA,KAAK,EAAE,IAAI,iBAAiB,CAAC;AAGzB,IAAM,aAAaA,GACvB,OAAO;AAAA,EACN,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,cAAcA,GAAE,OAAO,EAAE,SAAS;AACpC,CAAC,EACA,KAAK,EAAE,IAAI,aAAa,CAAC;;;AFXrB,IAAM,eAAeC,GAAE,KAAK,CAAC,QAAQ,UAAU,CAAC;AAGhD,IAAM,cAAcA,GAAE,KAAK,CAAC,YAAY,UAAU,CAAC;AAG1D,IAAM,aAAaA,GAAE,OAAO;AAAA,EAC1B,IAAI;AAAA,EACJ,OAAOA,GAAE,QAAQ,MAAM;AAAA,EACvB,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,SAASA,GAAE,IAAI;AAAA,EACf,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,eAAeA,GAAE,QAAQ,EAAE,SAAS;AAAA,EACpC,cAAcA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC3C,iBAAiBA,GAAE,OAAO,EAAE,IAAI,EAAE,YAAY;AAAA,EAC9C,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAC3C,CAAC;AAEM,IAAM,iBAAiB,WAAW,KAAK,EAAE,IAAI,iBAAiB,CAAC;AAG/D,IAAM,SAAS,WAAW,OAAO;AAAA,EACtC,UAAUA,GAAE,MAAM,OAAO;AAAA,EACzB,gBAAgB;AAAA,EAChB,YAAY,WAAW,SAAS;AAClC,CAAC,EAAE,KAAK,EAAE,IAAI,SAAS,CAAC;;;AGvCxB,SAAS,KAAAC,UAAS;AAQlB,IAAMC,aAAYC,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,OAAO,CAAC,CAAC;AAIlD,IAAM,aAAa,CAAC,MAClB,EAAE,KAAK,KAAK,EAAE,SAAS,MAAM,EAAE,eAAe,UAAU,KAAK;AAC/D,IAAM,mBAAmB,EAAE,SAAS,wCAAwC;AAErE,IAAM,mBAAmBA,GAC7B,OAAO;AAAA,EACN,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,SAASA,GAAE,IAAI;AAAA,EACf,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,QAAQ;AAAA,EACR,SAASA,GACN,OAAO,EAAE,MAAMA,GAAE,OAAO,GAAG,eAAeA,GAAE,MAAM,YAAY,EAAE,SAAS,EAAE,CAAC,EAC5E,OAAO,YAAY,gBAAgB;AAAA,EACtC,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,YAAY,WAAW,SAAS;AAClC,CAAC,EACA,KAAK,EAAE,IAAI,mBAAmB,CAAC;AAG3B,IAAM,mBAAmBA,GAC7B,OAAO;AAAA,EACN,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,QAAQ,aAAa,SAAS;AAAA,EAC9B,MAAMA,GAAE,QAAQ,WAAW,EAAE,SAAS;AAAA,EACtC,QAAQ,OAAO,SAAS;AAC1B,CAAC,EACA,KAAK,EAAE,IAAI,mBAAmB,CAAC;AAG3B,IAAM,gBAAgBA,GAAE,OAAO,EAAE,IAAI,SAAS,CAAC;AAG/C,IAAM,iBAAiBA,GAC3B,OAAO;AAAA,EACN,MAAMA,GAAE,OAAO;AAAA,EACf,eAAeA,GAAE,MAAM,YAAY,EAAE,SAAS;AAAA,EAC9C,QAAQ;AACV,CAAC,EACA,OAAO,YAAY,gBAAgB,EACnC,KAAK,EAAE,IAAI,iBAAiB,CAAC;AAGzB,IAAM,sBAAsBA,GAChC,OAAO,EAAE,QAAQ,aAAa,CAAC,EAC/B,KAAK,EAAE,IAAI,sBAAsB,CAAC;AAG9B,IAAM,oBAAoBA,GAC9B,OAAO;AAAA,EACN,WAAWD,WAAU,SAAS;AAAA,EAC9B,SAAS,QAAQ,SAAS;AAAA,EAC1B,aAAa;AAAA,EACb,eAAeC,GAAE,QAAQ,EAAE,SAAS;AACtC,CAAC,EACA,KAAK,EAAE,IAAI,oBAAoB,CAAC;AAI5B,IAAM,aAAaA,GACvB,OAAO;AAAA,EACN,MAAMA,GAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,QAAQ,SAAS,EAAE,CAAC;AAC1E,CAAC,EACA,KAAK,EAAE,IAAI,aAAa,CAAC;;;AC3E5B,SAAS,KAAAC,UAAS;AAGX,IAAM,qBAAqBC,GAC/B,OAAO;AAAA,EACN,SAASA,GAAE,MAAM,cAAc;AAAA,EAC/B,YAAYA,GAAE,OAAO,EAAE,SAAS;AAClC,CAAC,EACA,KAAK,EAAE,IAAI,qBAAqB,CAAC;;;ACkBpC,IAAM,cAA2B,CAAC,oBAAoB,sBAAsB,cAAc;AAEnF,IAAM,aAA0B;AAAA,EACrC;AAAA,IACE,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,EAAE,QAAQ,KAAK,QAAQ,OAAO;AAAA,IACvC,QAAQ,CAAC,qBAAqB,GAAG,WAAW;AAAA,EAC9C;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO;AAAA,IACP,SAAS,EAAE,QAAQ,KAAK,QAAQ,mBAAmB;AAAA,IACnD,QAAQ,CAAC,qBAAqB,GAAG,WAAW;AAAA,EAC9C;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,KAAK,QAAQ,OAAO;AAAA,IACvC,QAAQ,CAAC,aAAa,GAAG,WAAW;AAAA,EACtC;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS,EAAE,QAAQ,KAAK,QAAQ,QAAQ;AAAA,IACxC,QAAQ,CAAC,qBAAqB,aAAa,GAAG,WAAW;AAAA,EAC3D;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS,EAAE,QAAQ,KAAK,QAAQ,OAAO;AAAA,IACvC,QAAQ,CAAC,qBAAqB,aAAa,YAAY,GAAG,WAAW;AAAA,EACvE;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS,EAAE,QAAQ,KAAK,QAAQ,eAAe;AAAA,IAC/C,QAAQ,CAAC,qBAAqB,aAAa,GAAG,WAAW;AAAA,EAC3D;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS,EAAE,QAAQ,KAAK,QAAQ,WAAW;AAAA,IAC3C,QAAQ,CAAC,qBAAqB,oBAAoB,GAAG,WAAW;AAAA,EAClE;AACF;;;AC/FO,IAAM,kBAAkB;;;AVW/B,SAAS,cAAc,MAAsB;AAC3C,SAAO,KAAK,QAAQ,qBAAqB,MAAM;AACjD;AAEO,SAAS,uBAA0D;AACxE,QAAM,QAA+B,CAAC;AAEtC,aAAW,MAAM,YAAY;AAG3B,UAAM,YAAY,CAAC;AAClB,IAAC,UAAsC,OAAO,GAAG,QAAQ,MAAM,CAAC,IAAI;AAAA,MACnE,aAAa,GAAG,GAAG,WAAW;AAAA,MAC9B,SAAS,EAAE,oBAAoB,EAAE,QAAQ,GAAG,QAAQ,OAAO,EAAE;AAAA,IAC/D;AACA,eAAW,QAAQ,GAAG,QAAQ;AAC5B;AAAC,MAAC,UAAsC,OAAO,aAAa,IAAI,CAAC,CAAC,IAAI;AAAA,QACpE,aAAa;AAAA,QACb,SAAS,EAAE,oBAAoB,EAAE,QAAQ,cAAc,EAAE;AAAA,MAC3D;AAAA,IACF;AAEA,UAAM,YAAuC;AAAA,MAC3C,aAAa,GAAG;AAAA,MAChB,SAAS,GAAG;AAAA,MACZ;AAAA,IACF;AACA,QAAI,GAAG,UAAU,GAAG,OAAO;AACzB,gBAAU,gBAAgB,CAAC;AAC3B,UAAI,GAAG,OAAQ,WAAU,cAAc,OAAO,GAAG;AACjD,UAAI,GAAG,MAAO,WAAU,cAAc,QAAQ,GAAG;AAAA,IACnD;AACA,QAAI,GAAG,SAAS,aAAa;AAC3B,gBAAU,cAAc,EAAE,SAAS,EAAE,uBAAuB,EAAE,QAAQ,WAAW,EAAE,EAAE;AAAA,IACvF,WAAW,GAAG,MAAM;AAClB,gBAAU,cAAc,EAAE,SAAS,EAAE,oBAAoB,EAAE,QAAQ,GAAG,KAAK,EAAE,EAAE;AAAA,IACjF;AAEA,UAAM,cAAc,cAAc,GAAG,IAAI;AACzC,UAAM,SAAS,GAAG,OAAO,YAAY;AACrC,UAAM,WAAW,IAAI,EAAE,GAAI,MAAM,WAAW,KAAK,CAAC,GAAI,CAAC,MAAM,GAAG,UAAU;AAAA,EAC5E;AAEA,SAAO,eAAe;AAAA,IACpB,SAAS;AAAA,IACT,MAAM,EAAE,OAAO,gBAAgB,SAAS,QAAQ;AAAA,IAChD,YAAY;AAAA,MACV,iBAAiB;AAAA,QACf,aAAa,EAAE,MAAM,UAAU,IAAI,UAAU,MAAM,gBAAgB;AAAA,MACrE;AAAA,IACF;AAAA,IACA,UAAU,CAAC,EAAE,aAAa,CAAC,EAAE,CAAC;AAAA,IAC9B;AAAA,EACF,CAAC;AACH;;;AW/DO,SAAS,iBAAiB,KAA2B;AAC1D,QAAM,IAAI,OAAO,QAAQ,WAAW,IAAI,IAAI,GAAG,IAAI;AACnD,MAAI,WAAW,EAAE;AACjB,MAAI,SAAS,SAAS,KAAK,SAAS,SAAS,GAAG,GAAG;AACjD,eAAW,SAAS,MAAM,GAAG,EAAE;AAAA,EACjC;AACA,SAAO,GAAG,EAAE,MAAM,GAAG,QAAQ;AAC/B;","names":["z","z","z","z","z","z","z","z","z","Selectors","z","z","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/anchor/weights.ts","../src/anchor/decide.ts","../src/anchor/locate-quote.ts","../src/anchor/score.ts","../src/contract/errors.ts","../src/contract/openapi.ts","../src/schemas/comment.ts","../src/ids.ts","../src/schemas/common.ts","../src/schemas/thread.ts","../src/schemas/anchor.ts","../src/schemas/capture.ts","../src/contract/requests.ts","../src/contract/responses.ts","../src/contract/operations.ts","../src/contract/wire.ts","../src/pageKey.ts"],"sourcesContent":["export const DEFAULT_WEIGHTS = {\n stableAttrs: 0.4,\n text: 0.25,\n classes: 0.15,\n role: 0.1,\n sibling: 0.05,\n ancestor: 0.05,\n} as const\n\nexport type WeightKey = keyof typeof DEFAULT_WEIGHTS\n\nexport const DEFAULT_THRESHOLDS = {\n accept: 0.6,\n margin: 0.1,\n} as const\n\nexport type Thresholds = { accept: number; margin: number }\n","import type { ScoreResult } from './score'\nimport { DEFAULT_THRESHOLDS, type Thresholds } from './weights'\n\nexport type Decision<T> =\n | { kind: 'anchored'; winner: T; score: ScoreResult }\n | {\n kind: 'orphaned'\n reason: 'noCandidates' | 'belowAccept' | 'ambiguous'\n }\n\nexport function decide<T>(\n scored: Array<{ ref: T; score: ScoreResult }>,\n opts?: Partial<Thresholds>,\n): Decision<T> {\n const accept = opts?.accept ?? DEFAULT_THRESHOLDS.accept\n const margin = opts?.margin ?? DEFAULT_THRESHOLDS.margin\n const survivors = scored\n .filter((s) => s.score.excluded !== 'tagMismatch')\n .sort((a, b) => b.score.total - a.score.total)\n const best = survivors[0]\n if (!best) return { kind: 'orphaned', reason: 'noCandidates' }\n if (best.score.total < accept) return { kind: 'orphaned', reason: 'belowAccept' }\n const second = survivors[1]\n if (second && best.score.total - second.score.total < margin) {\n return { kind: 'orphaned', reason: 'ambiguous' }\n }\n return { kind: 'anchored', winner: best.ref, score: best.score }\n}\n","export type QuoteContext = { quote: string; prefix: string; suffix: string }\nexport type QuoteOffsets = { start: number; end: number }\n\n/**\n * Build a normalized copy of `s` along with a map from normalized index → original index.\n * Normalization collapses runs of whitespace to a single space and trims; leading\n * whitespace that gets dropped is mapped through so callers can recover original offsets.\n */\nfunction normalizeWithMap(s: string): { normalized: string; toOriginal: number[] } {\n const toOriginal: number[] = []\n let out = ''\n let prevSpace = true // collapse leading whitespace\n for (let i = 0; i < s.length; i++) {\n const ch = s.charAt(i)\n const isWs = /\\s/.test(ch)\n if (isWs) {\n if (prevSpace) continue\n out += ' '\n toOriginal.push(i)\n prevSpace = true\n } else {\n out += ch\n toOriginal.push(i)\n prevSpace = false\n }\n }\n // trim trailing space\n if (out.endsWith(' ')) {\n out = out.slice(0, -1)\n toOriginal.pop()\n }\n return { normalized: out, toOriginal }\n}\n\nfunction normalizeNeedle(s: string): string {\n return s.replace(/\\s+/g, ' ').trim()\n}\n\nfunction originalRange(\n toOriginal: number[],\n normStart: number,\n normLen: number,\n haystackLen: number,\n): QuoteOffsets {\n const start = toOriginal[normStart] ?? haystackLen\n // The end offset in the original is the index *after* the last matched normalized char.\n const lastIdx = normStart + normLen - 1\n const lastOriginal = toOriginal[lastIdx] ?? haystackLen - 1\n return { start, end: lastOriginal + 1 }\n}\n\nfunction indexOfUnique(haystack: string, needle: string): number | null {\n if (needle.length === 0) return null\n const first = haystack.indexOf(needle)\n if (first < 0) return null\n if (haystack.indexOf(needle, first + 1) >= 0) return null\n return first\n}\n\nexport function locateQuote(haystack: string, ctx: QuoteContext): QuoteOffsets | null {\n const { normalized, toOriginal } = normalizeWithMap(haystack)\n const nQuote = normalizeNeedle(ctx.quote)\n const nPrefix = normalizeNeedle(ctx.prefix)\n const nSuffix = normalizeNeedle(ctx.suffix)\n if (nQuote.length === 0) return null\n\n // Strategy 1: exact prefix+quote+suffix.\n if (nPrefix || nSuffix) {\n const composite = `${nPrefix}${nPrefix ? ' ' : ''}${nQuote}${nSuffix ? ' ' : ''}${nSuffix}`\n const idx = indexOfUnique(normalized, composite)\n if (idx !== null) {\n const offset = idx + nPrefix.length + (nPrefix ? 1 : 0)\n return originalRange(toOriginal, offset, nQuote.length, haystack.length)\n }\n }\n\n // Strategy 2: unique quote.\n const qIdx = indexOfUnique(normalized, nQuote)\n if (qIdx !== null) {\n return originalRange(toOriginal, qIdx, nQuote.length, haystack.length)\n }\n\n // Strategy 3: prefix+quote unique.\n if (nPrefix) {\n const composite = `${nPrefix} ${nQuote}`\n const idx = indexOfUnique(normalized, composite)\n if (idx !== null) {\n return originalRange(toOriginal, idx + nPrefix.length + 1, nQuote.length, haystack.length)\n }\n }\n\n // Strategy 4: quote+suffix unique.\n if (nSuffix) {\n const composite = `${nQuote} ${nSuffix}`\n const idx = indexOfUnique(normalized, composite)\n if (idx !== null) {\n return originalRange(toOriginal, idx, nQuote.length, haystack.length)\n }\n }\n\n return null\n}\n","import type { Signals } from '../schemas/anchor'\nimport { DEFAULT_WEIGHTS, type WeightKey } from './weights'\n\nexport type ScoreComponents = Record<WeightKey, number>\n\nexport type ScoreResult = {\n total: number\n components: ScoreComponents\n excluded: false | 'tagMismatch'\n}\n\nconst ZERO_COMPONENTS: ScoreComponents = {\n stableAttrs: 0,\n text: 0,\n classes: 0,\n role: 0,\n sibling: 0,\n ancestor: 0,\n}\n\nexport function scoreCandidate(stored: Signals, candidate: Signals): ScoreResult {\n if (stored.tag.toLowerCase() !== candidate.tag.toLowerCase()) {\n return { total: 0, components: { ...ZERO_COMPONENTS }, excluded: 'tagMismatch' }\n }\n const components: ScoreComponents = {\n stableAttrs: scoreStableAttrs(stored.stableAttrs, candidate.stableAttrs),\n text: scoreText(stored.textSnippet, candidate.textSnippet),\n classes: scoreClasses(stored.classes, candidate.classes),\n role: scoreRole(stored.role, candidate.role),\n sibling: scoreSibling(stored.siblingIndex, candidate.siblingIndex),\n ancestor: scoreAncestor(stored.ancestorTrail, candidate.ancestorTrail),\n }\n const total =\n components.stableAttrs * DEFAULT_WEIGHTS.stableAttrs +\n components.text * DEFAULT_WEIGHTS.text +\n components.classes * DEFAULT_WEIGHTS.classes +\n components.role * DEFAULT_WEIGHTS.role +\n components.sibling * DEFAULT_WEIGHTS.sibling +\n components.ancestor * DEFAULT_WEIGHTS.ancestor\n return { total, components, excluded: false }\n}\n\nfunction priorityOf(key: string, otherCount: number): number {\n if (key === 'id') return 0.5\n if (key === 'data-testid') return 0.3\n if (key.startsWith('data-')) return otherCount > 0 ? 0.2 / otherCount : 0\n return 0\n}\n\nfunction scoreStableAttrs(\n stored: Record<string, string> | undefined,\n candidate: Record<string, string> | undefined,\n): number {\n if (!stored) return 0\n const keys = Object.keys(stored)\n if (keys.length === 0) return 0\n const otherCount = keys.filter((k) => k.startsWith('data-') && k !== 'data-testid').length\n let max = 0\n let raw = 0\n for (const k of keys) {\n const p = priorityOf(k, otherCount)\n max += p\n const storedValue = stored[k]\n if (storedValue !== undefined && candidate?.[k] === storedValue) {\n raw += p\n }\n }\n return max === 0 ? 0 : raw / max\n}\nfunction scoreText(a: string | undefined, b: string | undefined): number {\n if (!a || !b) return 0\n const aPad = a.length < 2 ? `${a} ` : a\n const bPad = b.length < 2 ? `${b} ` : b\n const bigrams = (s: string): Map<string, number> => {\n const m = new Map<string, number>()\n for (let i = 0; i < s.length - 1; i++) {\n const g = s.slice(i, i + 2)\n m.set(g, (m.get(g) ?? 0) + 1)\n }\n return m\n }\n const ba = bigrams(aPad)\n const bb = bigrams(bPad)\n let inter = 0\n for (const [g, n] of ba) {\n const m = bb.get(g)\n if (m !== undefined) inter += Math.min(n, m)\n }\n const totalA = Array.from(ba.values()).reduce((s, n) => s + n, 0)\n const totalB = Array.from(bb.values()).reduce((s, n) => s + n, 0)\n return totalA + totalB === 0 ? 0 : (2 * inter) / (totalA + totalB)\n}\nfunction scoreClasses(a: string[], b: string[]): number {\n if (a.length === 0 && b.length === 0) return 0\n const setA = new Set(a)\n const setB = new Set(b)\n let inter = 0\n for (const x of setA) if (setB.has(x)) inter++\n const union = setA.size + setB.size - inter\n return union === 0 ? 0 : inter / union\n}\nfunction scoreRole(a: string | undefined, b: string | undefined): number {\n if (!a || !b) return 0\n return a === b ? 1 : 0\n}\nfunction scoreSibling(a: number, b: number): number {\n return 1 / (1 + Math.abs(a - b))\n}\nfunction scoreAncestor(a: string[], b: string[]): number {\n if (a.length === 0 && b.length === 0) return 0\n const setA = new Set(a)\n const setB = new Set(b)\n let inter = 0\n for (const x of setA) if (setB.has(x)) inter++\n const union = setA.size + setB.size - inter\n return union === 0 ? 0 : inter / union\n}\n","import { z } from 'zod'\n\nexport const ERROR_CODES = [\n 'VALIDATION_FAILED',\n 'AUTH_INVALID_KEY',\n 'ORIGIN_NOT_ALLOWED',\n 'NOT_FOUND',\n 'CONFLICT',\n 'UPLOAD_TOO_LARGE',\n 'RATE_LIMITED',\n 'INTERNAL',\n] as const\n\nexport const ErrorCode = z.enum(ERROR_CODES)\nexport type ErrorCode = z.infer<typeof ErrorCode>\n\nexport const ErrorResponse = z\n .object({\n error: z.object({\n code: ErrorCode,\n message: z.string(),\n details: z.unknown().optional(),\n }),\n })\n .meta({ id: 'ErrorResponse' })\nexport type ErrorResponse = z.infer<typeof ErrorResponse>\n\nexport const ERROR_STATUS: Record<ErrorCode, number> = {\n VALIDATION_FAILED: 400,\n AUTH_INVALID_KEY: 401,\n ORIGIN_NOT_ALLOWED: 403,\n NOT_FOUND: 404,\n CONFLICT: 409,\n UPLOAD_TOO_LARGE: 413,\n RATE_LIMITED: 429,\n INTERNAL: 500,\n}\n","import {\n createDocument,\n type ZodOpenApiOperationObject,\n type ZodOpenApiPathsObject,\n type ZodOpenApiResponsesObject,\n} from 'zod-openapi'\nimport { ERROR_STATUS, ErrorResponse } from './errors'\nimport { operations } from './operations'\nimport { UploadForm } from './requests'\nimport { KEY_HEADER_NAME } from './wire'\n\nfunction toOpenApiPath(path: string): string {\n return path.replace(/:([A-Za-z0-9_]+)/g, '{$1}')\n}\n\nexport function buildOpenApiDocument(): ReturnType<typeof createDocument> {\n const paths: ZodOpenApiPathsObject = {}\n\n for (const op of operations) {\n // ZodOpenApiResponsesObject only accepts keys matching `${1|2|3|4|5}${string}`,\n // so we cast via unknown to satisfy the template-literal index signature.\n const responses = {} as ZodOpenApiResponsesObject\n ;(responses as Record<string, unknown>)[String(op.success.status)] = {\n description: `${op.operationId} success`,\n content: { 'application/json': { schema: op.success.schema } },\n }\n for (const code of op.errors) {\n ;(responses as Record<string, unknown>)[String(ERROR_STATUS[code])] = {\n description: code,\n content: { 'application/json': { schema: ErrorResponse } },\n }\n }\n\n const operation: ZodOpenApiOperationObject = {\n operationId: op.operationId,\n summary: op.summary,\n responses,\n }\n if (op.params || op.query) {\n operation.requestParams = {}\n if (op.params) operation.requestParams.path = op.params\n if (op.query) operation.requestParams.query = op.query\n }\n if (op.body === 'multipart') {\n operation.requestBody = { content: { 'multipart/form-data': { schema: UploadForm } } }\n } else if (op.body) {\n operation.requestBody = { content: { 'application/json': { schema: op.body } } }\n }\n\n const openApiPath = toOpenApiPath(op.path)\n const method = op.method.toLowerCase() as 'get' | 'post' | 'patch'\n paths[openApiPath] = { ...(paths[openApiPath] ?? {}), [method]: operation }\n }\n\n return createDocument({\n openapi: '3.1.0',\n info: { title: 'Comments API', version: '1.0.0' },\n components: {\n securitySchemes: {\n commentsKey: { type: 'apiKey', in: 'header', name: KEY_HEADER_NAME },\n },\n },\n security: [{ commentsKey: [] }],\n paths,\n })\n}\n","import { z } from 'zod'\nimport { AttachmentId, AuthorId, CommentId } from '../ids'\nimport { Email, IsoTimestamp } from './common'\n\nexport const Author = z\n .object({ id: AuthorId.optional(), email: Email, name: z.string().optional() })\n .meta({ id: 'Author' })\nexport type Author = z.infer<typeof Author>\n\nexport const Attachment = z\n .object({\n id: AttachmentId,\n url: z.url(),\n name: z.string(),\n contentType: z.string(),\n size: z.number().int().nonnegative(),\n w: z.number().int().positive().optional(),\n h: z.number().int().positive().optional(),\n })\n .meta({ id: 'Attachment' })\nexport type Attachment = z.infer<typeof Attachment>\n\nexport const Comment = z\n .object({\n id: CommentId,\n author: Author,\n text: z.string(),\n attachments: z.array(Attachment),\n createdAt: IsoTimestamp,\n editedAt: IsoTimestamp.optional(),\n })\n .meta({ id: 'Comment' })\nexport type Comment = z.infer<typeof Comment>\n","import { z } from 'zod'\n\nexport const ThreadId = z.string().min(1).brand<'ThreadId'>()\nexport type ThreadId = z.infer<typeof ThreadId>\n\nexport const CommentId = z.string().min(1).brand<'CommentId'>()\nexport type CommentId = z.infer<typeof CommentId>\n\nexport const AuthorId = z.string().min(1).brand<'AuthorId'>()\nexport type AuthorId = z.infer<typeof AuthorId>\n\nexport const AttachmentId = z.string().min(1).brand<'AttachmentId'>()\nexport type AttachmentId = z.infer<typeof AttachmentId>\n","import { z } from 'zod'\n\nexport const Email = z.email().meta({ id: 'Email' })\nexport type Email = z.infer<typeof Email>\n\nexport const IsoTimestamp = z.iso.datetime().meta({ id: 'IsoTimestamp' })\nexport type IsoTimestamp = z.infer<typeof IsoTimestamp>\n\n// Opaque pagination token — intentionally NOT registered as a named component\n// (the spec treats the cursor as an opaque string; its codec lives server-side in M3).\nexport const Cursor = z.string().min(1)\nexport type Cursor = z.infer<typeof Cursor>\n","import { z } from 'zod'\nimport { ThreadId } from '../ids'\nimport { Anchor } from './anchor'\nimport { CaptureContext, Provenance } from './capture'\nimport { Author, Comment } from './comment'\nimport { IsoTimestamp } from './common'\n\nexport const ThreadStatus = z.enum(['open', 'resolved'])\nexport type ThreadStatus = z.infer<typeof ThreadStatus>\n\nexport const AnchorState = z.enum(['anchored', 'orphaned'])\nexport type AnchorState = z.infer<typeof AnchorState>\n\nconst ThreadBase = z.object({\n id: ThreadId,\n scope: z.literal('page'),\n pageKey: z.string().nullable(),\n pageUrl: z.url(),\n pageTitle: z.string().optional(),\n anchor: Anchor,\n status: ThreadStatus,\n anchorState: AnchorState,\n selectionLost: z.boolean().optional(),\n commentCount: z.number().int().nonnegative(),\n unresolvedCount: z.number().int().nonnegative(),\n createdBy: Author,\n createdAt: IsoTimestamp,\n updatedAt: IsoTimestamp,\n lastActivityAt: IsoTimestamp,\n schemaVersion: z.number().int().positive(),\n})\n\nexport const ThreadListItem = ThreadBase.extend({\n rootComment: z.object({ text: z.string(), createdAt: IsoTimestamp }).nullable(),\n}).meta({ id: 'ThreadListItem' })\nexport type ThreadListItem = z.infer<typeof ThreadListItem>\n\nexport const Thread = ThreadBase.extend({\n comments: z.array(Comment),\n captureContext: CaptureContext,\n provenance: Provenance.optional(),\n}).meta({ id: 'Thread' })\nexport type Thread = z.infer<typeof Thread>\n","import { z } from 'zod'\n\nexport const ANCHOR_SCHEMA_VERSION = 1\n\nconst Selectors = z.tuple([z.string(), z.string()])\n\nexport const Signals = z\n .object({\n tag: z.string(),\n role: z.string().optional(),\n textSnippet: z.string().max(120).optional(),\n classes: z.array(z.string()),\n siblingIndex: z.number().int().nonnegative(),\n ancestorTrail: z.array(z.string()),\n stableAttrs: z.record(z.string(), z.string()).optional(),\n })\n .meta({ id: 'Signals' })\nexport type Signals = z.infer<typeof Signals>\n\nconst SelectionEndpoint = z.object({\n selectors: Selectors,\n textNodeIndex: z.number().int().nonnegative(),\n offset: z.number().int().nonnegative(),\n})\n\nexport const Selection = z\n .object({\n start: SelectionEndpoint,\n end: SelectionEndpoint,\n quote: z.string(),\n prefix: z.string(),\n suffix: z.string(),\n })\n .meta({ id: 'Selection' })\nexport type Selection = z.infer<typeof Selection>\n\nexport const Anchor = z\n .object({\n // Positive int (not z.literal(ANCHOR_SCHEMA_VERSION)) so anchors written under a future\n // schema version still parse (forward-compatible reads); ANCHOR_SCHEMA_VERSION is the write-time default.\n schemaVersion: z.number().int().positive(),\n selectors: Selectors,\n signals: Signals,\n offset: z.object({ fx: z.number().min(0).max(1), fy: z.number().min(0).max(1) }),\n selection: Selection.optional(),\n })\n .meta({ id: 'Anchor' })\nexport type Anchor = z.infer<typeof Anchor>\n","import { z } from 'zod'\n\nexport const CaptureContext = z\n .object({\n viewportW: z.number().int().positive(),\n viewportH: z.number().int().positive(),\n devicePixelRatio: z.number().positive(),\n userAgent: z.string(),\n })\n .meta({ id: 'CaptureContext' })\nexport type CaptureContext = z.infer<typeof CaptureContext>\n\nexport const Provenance = z\n .object({\n commitSha: z.string().optional(),\n branch: z.string().optional(),\n deploymentId: z.string().optional(),\n })\n .meta({ id: 'Provenance' })\nexport type Provenance = z.infer<typeof Provenance>\n","import { z } from 'zod'\nimport { AttachmentId, ThreadId } from '../ids'\nimport { Anchor, Signals } from '../schemas/anchor'\nimport { CaptureContext, Provenance } from '../schemas/capture'\nimport { Author } from '../schemas/comment'\nimport { Cursor } from '../schemas/common'\nimport { AnchorState, ThreadStatus } from '../schemas/thread'\n\nconst Selectors = z.tuple([z.string(), z.string()])\n\n// A comment must carry content: either non-blank text or at least one attachment.\n// Text alone, image alone, or both are all valid — image-only comments are allowed.\nconst hasContent = (c: { text: string; attachmentIds?: readonly string[] }): boolean =>\n c.text.trim().length > 0 || (c.attachmentIds?.length ?? 0) > 0\nconst CONTENT_REQUIRED = { message: 'a comment needs text or an attachment' }\n\nexport const CreateThreadBody = z\n .object({\n pageKey: z.string().optional(),\n pageUrl: z.url(),\n pageTitle: z.string().optional(),\n anchor: Anchor,\n comment: z\n .object({ text: z.string(), attachmentIds: z.array(AttachmentId).optional() })\n .refine(hasContent, CONTENT_REQUIRED),\n author: Author,\n captureContext: CaptureContext,\n provenance: Provenance.optional(),\n })\n .meta({ id: 'CreateThreadBody' })\nexport type CreateThreadBody = z.infer<typeof CreateThreadBody>\n\nexport const ListThreadsQuery = z\n .object({\n pageKey: z.string().optional(),\n status: ThreadStatus.optional(),\n sort: z.literal('updatedAt').optional(),\n cursor: Cursor.optional(),\n })\n .meta({ id: 'ListThreadsQuery' })\nexport type ListThreadsQuery = z.infer<typeof ListThreadsQuery>\n\nexport const ThreadIdParam = z.object({ id: ThreadId })\nexport type ThreadIdParam = z.infer<typeof ThreadIdParam>\n\nexport const AddCommentBody = z\n .object({\n text: z.string(),\n attachmentIds: z.array(AttachmentId).optional(),\n author: Author,\n })\n .refine(hasContent, CONTENT_REQUIRED)\n .meta({ id: 'AddCommentBody' })\nexport type AddCommentBody = z.infer<typeof AddCommentBody>\n\nexport const SetThreadStatusBody = z\n .object({ status: ThreadStatus })\n .meta({ id: 'SetThreadStatusBody' })\nexport type SetThreadStatusBody = z.infer<typeof SetThreadStatusBody>\n\nexport const RefreshAnchorBody = z\n .object({\n selectors: Selectors.optional(),\n signals: Signals.optional(),\n anchorState: AnchorState,\n selectionLost: z.boolean().optional(),\n })\n .meta({ id: 'RefreshAnchorBody' })\nexport type RefreshAnchorBody = z.infer<typeof RefreshAnchorBody>\n\n// Documentation-only shape for the multipart upload (the binary is validated server-side).\nexport const UploadForm = z\n .object({\n file: z.string().meta({ override: { type: 'string', format: 'binary' } }),\n })\n .meta({ id: 'UploadForm' })\nexport type UploadForm = z.infer<typeof UploadForm>\n","import { z } from 'zod'\nimport { ThreadListItem } from '../schemas/thread'\n\nexport const ThreadListResponse = z\n .object({\n threads: z.array(ThreadListItem),\n nextCursor: z.string().nullable(),\n })\n .meta({ id: 'ThreadListResponse' })\nexport type ThreadListResponse = z.infer<typeof ThreadListResponse>\n","import type { z } from 'zod'\nimport { Attachment, Comment } from '../schemas/comment'\nimport { Thread, ThreadListItem } from '../schemas/thread'\nimport type { ErrorCode } from './errors'\nimport {\n AddCommentBody,\n CreateThreadBody,\n ListThreadsQuery,\n RefreshAnchorBody,\n SetThreadStatusBody,\n ThreadIdParam,\n} from './requests'\nimport { ThreadListResponse } from './responses'\n\nexport interface Operation {\n operationId: string\n method: 'GET' | 'POST' | 'PATCH'\n path: string\n summary: string\n params?: z.ZodObject\n query?: z.ZodObject\n body?: z.ZodType | 'multipart'\n success: { status: number; schema: z.ZodType }\n errors: ErrorCode[]\n}\n\nconst AUTH_ERRORS: ErrorCode[] = ['AUTH_INVALID_KEY', 'ORIGIN_NOT_ALLOWED', 'RATE_LIMITED']\n\nexport const operations: Operation[] = [\n {\n operationId: 'createThread',\n method: 'POST',\n path: '/threads',\n summary: 'Create a thread with its first comment',\n body: CreateThreadBody,\n success: { status: 201, schema: Thread },\n errors: ['VALIDATION_FAILED', ...AUTH_ERRORS],\n },\n {\n operationId: 'listThreads',\n method: 'GET',\n path: '/threads',\n summary: 'List threads on a page (?pageKey=) or across all pages (panel)',\n query: ListThreadsQuery,\n success: { status: 200, schema: ThreadListResponse },\n errors: ['VALIDATION_FAILED', ...AUTH_ERRORS],\n },\n {\n operationId: 'getThread',\n method: 'GET',\n path: '/threads/:id',\n summary: 'Get a single thread with its comments',\n params: ThreadIdParam,\n success: { status: 200, schema: Thread },\n errors: ['NOT_FOUND', ...AUTH_ERRORS],\n },\n {\n operationId: 'addComment',\n method: 'POST',\n path: '/threads/:id/comments',\n summary: 'Add a reply to a thread',\n params: ThreadIdParam,\n body: AddCommentBody,\n success: { status: 201, schema: Comment },\n errors: ['VALIDATION_FAILED', 'NOT_FOUND', ...AUTH_ERRORS],\n },\n {\n operationId: 'setThreadStatus',\n method: 'PATCH',\n path: '/threads/:id',\n summary: 'Resolve or reopen a thread',\n params: ThreadIdParam,\n body: SetThreadStatusBody,\n success: { status: 200, schema: Thread },\n errors: ['VALIDATION_FAILED', 'NOT_FOUND', 'CONFLICT', ...AUTH_ERRORS],\n },\n {\n operationId: 'refreshAnchor',\n method: 'PATCH',\n path: '/threads/:id/anchor',\n summary: 'Report a re-match result (self-heal the stored anchor)',\n params: ThreadIdParam,\n body: RefreshAnchorBody,\n success: { status: 200, schema: ThreadListItem },\n errors: ['VALIDATION_FAILED', 'NOT_FOUND', ...AUTH_ERRORS],\n },\n {\n operationId: 'uploadAttachment',\n method: 'POST',\n path: '/uploads',\n summary: 'Upload an image attachment (multipart)',\n body: 'multipart',\n success: { status: 201, schema: Attachment },\n errors: ['VALIDATION_FAILED', 'UPLOAD_TOO_LARGE', ...AUTH_ERRORS],\n },\n]\n","export const KEY_HEADER_NAME = 'x-comments-key'\n","export type PageKeyFn = (url: string) => string\n\nexport function normalizePageKey(url: string | URL): string {\n const u = typeof url === 'string' ? new URL(url) : url\n let pathname = u.pathname\n if (pathname.length > 1 && pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1)\n }\n return `${u.origin}${pathname}`\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","Selectors","z","z","z"]}
|
package/dist/openapi.json
CHANGED
|
@@ -1296,6 +1296,29 @@
|
|
|
1296
1296
|
"type": "integer",
|
|
1297
1297
|
"exclusiveMinimum": 0,
|
|
1298
1298
|
"maximum": 9007199254740991
|
|
1299
|
+
},
|
|
1300
|
+
"rootComment": {
|
|
1301
|
+
"anyOf": [
|
|
1302
|
+
{
|
|
1303
|
+
"type": "object",
|
|
1304
|
+
"properties": {
|
|
1305
|
+
"text": {
|
|
1306
|
+
"type": "string"
|
|
1307
|
+
},
|
|
1308
|
+
"createdAt": {
|
|
1309
|
+
"$ref": "#/components/schemas/IsoTimestamp"
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1312
|
+
"required": [
|
|
1313
|
+
"text",
|
|
1314
|
+
"createdAt"
|
|
1315
|
+
],
|
|
1316
|
+
"additionalProperties": false
|
|
1317
|
+
},
|
|
1318
|
+
{
|
|
1319
|
+
"type": "null"
|
|
1320
|
+
}
|
|
1321
|
+
]
|
|
1299
1322
|
}
|
|
1300
1323
|
},
|
|
1301
1324
|
"required": [
|
|
@@ -1312,7 +1335,8 @@
|
|
|
1312
1335
|
"createdAt",
|
|
1313
1336
|
"updatedAt",
|
|
1314
1337
|
"lastActivityAt",
|
|
1315
|
-
"schemaVersion"
|
|
1338
|
+
"schemaVersion",
|
|
1339
|
+
"rootComment"
|
|
1316
1340
|
],
|
|
1317
1341
|
"additionalProperties": false
|
|
1318
1342
|
},
|
package/dist/schemas/thread.d.ts
CHANGED
|
@@ -67,6 +67,10 @@ export declare const ThreadListItem: z.ZodObject<{
|
|
|
67
67
|
updatedAt: z.ZodISODateTime;
|
|
68
68
|
lastActivityAt: z.ZodISODateTime;
|
|
69
69
|
schemaVersion: z.ZodNumber;
|
|
70
|
+
rootComment: z.ZodNullable<z.ZodObject<{
|
|
71
|
+
text: z.ZodString;
|
|
72
|
+
createdAt: z.ZodISODateTime;
|
|
73
|
+
}, z.core.$strip>>;
|
|
70
74
|
}, z.core.$strip>;
|
|
71
75
|
export type ThreadListItem = z.infer<typeof ThreadListItem>;
|
|
72
76
|
export declare const Thread: z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/schemas/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,eAAO,MAAM,YAAY;;;EAA+B,CAAA;AACxD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD,eAAO,MAAM,WAAW;;;EAAmC,CAAA;AAC3D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAqBrD,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/schemas/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,eAAO,MAAM,YAAY;;;EAA+B,CAAA;AACxD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEvD,eAAO,MAAM,WAAW;;;EAAmC,CAAA;AAC3D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAqBrD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAEM,CAAA;AACjC,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;AAE3D,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIM,CAAA;AACzB,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@airnauts/comments-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Framework-agnostic core for the Airnauts embeddable commenting tool: zod schemas, page-key normalization, the scoring/threshold policy, and the OpenAPI contract.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"comments",
|