Tools live under tools/<role>/<domain> (checks, generate, release, ci, dev), every tool is a workspace named @open-pencil/<domain>-tools, a shared tools/tsconfig.json backs the new check:tools gate that fixed 55 latent type errors, test:tools runs through bun --filter, the placement check is its own checks/test-homes package, and every tool resolves the repository through resolveWorkspaceRoot. Bun, Node, and mdast types live in a tools-root workspace so they never reach the app program.
21 lines
543 B
TypeScript
21 lines
543 B
TypeScript
import * as v from 'valibot'
|
|
|
|
const jsonObjectSchema = v.record(v.string(), v.unknown())
|
|
|
|
export function parseJSON(text: string, context: string): unknown {
|
|
try {
|
|
return JSON.parse(text)
|
|
} catch {
|
|
throw new Error(`${context}: invalid JSON`)
|
|
}
|
|
}
|
|
|
|
export function parseJSONObject(
|
|
text: string,
|
|
context: string
|
|
): v.InferOutput<typeof jsonObjectSchema> {
|
|
const parsed = v.safeParse(jsonObjectSchema, parseJSON(text, context))
|
|
if (!parsed.success) throw new Error(`${context}: expected an object`)
|
|
return parsed.output
|
|
}
|