Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Docs: a workspace knowledge base people and agents write together | 1 | /** |
| 2 | * Full-text search over pages (D1's FTS5): turning what someone typed into | |
| 3 | * a safe query, and deciding which spaces a search may look in. Pure. | |
| 4 | */ | |
| 5 | ||
| 6 | /** | |
| 7 | * A query as FTS5 understands it: each word quoted (so `-`, `:` and | |
| 8 | * operators are text, never syntax), every word required, the last one a | |
| 9 | * prefix so results come as you type. Null when nothing searchable is left. | |
| 10 | */ | |
| 11 | export function ftsQuery(text: string): string | null { | |
| 12 | const words = String(text ?? "") | |
| 13 | .toLowerCase() | |
| 14 | .split(/[^\p{L}\p{N}_]+/u) | |
| 15 | .filter(Boolean) | |
| 16 | .slice(0, 12); | |
| 17 | if (!words.length) return null; | |
| 18 | return words.map((w, i) => `"${w.replace(/"/g, "")}"${i === words.length - 1 ? "*" : ""}`).join(" "); | |
| 19 | } | |
| 20 | ||
| 21 | /** | |
| 22 | * Which spaces a search looks in: those the reader may read, narrowed to | |
| 23 | * one space when asked. An empty list means search nothing. | |
| 24 | */ | |
| 25 | export function searchSpaces(readable: string[], only: string | null | undefined): string[] { | |
| 26 | if (!only) return readable; | |
| 27 | return readable.includes(only) ? [only] : []; | |
| 28 | } | |
| 29 | ||
| 30 | /** Whether a page belongs under a project filter: it, or its space, is linked to the project. */ | |
| 31 | export function inProject(project: string | null | undefined, pageProjects: string[], spaceProjects: string[]): boolean { | |
| 32 | if (!project) return true; | |
| 33 | const want = project.toLowerCase(); | |
| 34 | return pageProjects.some((p) => p.toLowerCase() === want) || spaceProjects.some((p) => p.toLowerCase() === want); | |
| 35 | } | |
| 36 | ||
| 37 | /** A project reference as stored: `owner/name`, lowercased; null when it is not one. */ | |
| 38 | export function projectRef(value: string): string | null { | |
| 39 | const s = String(value ?? "").trim().replace(/^\/+|\/+$/g, "").toLowerCase(); | |
| 40 | return /^[a-z0-9][a-z0-9._-]{0,99}\/[a-z0-9._-]{1,100}$/.test(s) ? s : null; | |
| 41 | } |