UNPKG

@ryhrm-gz/xincodo-lib

Version:

Utilities for working with Xincodo body documents.

242 lines (172 loc) 5.75 kB
--- name: save-before-publish-checks description: > Load when wiring pre-save or pre-publish checks with safeMigrateBody, migrateBody, BodyMigrationError, BodyMigrationIssue, lintBody, BodyLintReport, lint severity policy, persisted JSON handling, future version rejection, and excluding DB persistence or request handling. type: lifecycle library: "@ryhrm-gz/xincodo-lib" library_version: "0.1.0" requires: - building-and-parsing-body - validating-body sources: - "ryhrm-gz/xincodo-lib:README.md" - "ryhrm-gz/xincodo-lib:src/migration.ts" - "ryhrm-gz/xincodo-lib:src/lint.ts" - "ryhrm-gz/xincodo-lib:tests/migration.test.ts" - "ryhrm-gz/xincodo-lib:tests/lint.test.ts" --- # Save Before Publish Checks This skill builds on `building-and-parsing-body` and `validating-body`. Use it to check `Body` data at save or publish boundaries. Do not design database persistence, request handlers, or upload flows in this skill. ## Setup ```ts import { lintBody, safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; export function checkBodyBeforePublish(value: unknown) { const migrated = safeMigrateBody(value); if (!migrated.success) { return { ok: false as const, stage: "migration", issue: migrated.issue }; } const report = lintBody(migrated.output); if (!report.valid) { return { ok: false as const, stage: "lint", report }; } return { ok: true as const, body: migrated.output, warnings: report.warnings }; } ``` Default blocking policy: migration failures and lint errors block. Lint warnings are surfaced for application policy. ## Core Patterns ### Check persisted JSON before save ```ts import { lintBody, safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; const migrated = safeMigrateBody(savedBodyJson); if (!migrated.success) { throw new Error(migrated.issue.message); } const report = lintBody(migrated.output); if (!report.valid) { throw new Error(report.errors.map((issue) => issue.message).join("\n")); } ``` Treat persisted values as unknown input. Do not cast them directly to `Body`. ### Return user-facing check results ```ts import { lintBody, safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; export function checkBody(value: unknown) { const migrated = safeMigrateBody(value); if (!migrated.success) { return { canPublish: false, errors: [migrated.issue.message], warnings: [] as string[], }; } const report = lintBody(migrated.output); return { canPublish: report.valid, errors: report.errors.map((issue) => issue.message), warnings: report.warnings.map((issue) => issue.message), }; } ``` This keeps severity policy explicit without mixing in transport or storage. ### Use throwing migration only inside controlled code ```ts import { BodyMigrationError, migrateBody } from "@ryhrm-gz/xincodo-lib"; try { const body = migrateBody(rawBody); console.log(body.version); } catch (error) { if (error instanceof BodyMigrationError) { console.error(error.issue.message); } } ``` For UI-facing save or publish checks, prefer `safeMigrateBody`. ## Common Mistakes ### HIGH Using throwing migration at app boundary Wrong: ```ts import { lintBody, migrateBody } from "@ryhrm-gz/xincodo-lib"; const body = migrateBody(rawBody); const report = lintBody(body); ``` Correct: ```ts import { lintBody, safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; const migrated = safeMigrateBody(rawBody); if (!migrated.success) { return { ok: false as const, issue: migrated.issue }; } const report = lintBody(migrated.output); ``` `migrateBody` throws `BodyMigrationError`; `safeMigrateBody` returns a result that is better for user-facing save and publish checks. Source: `src/migration.ts`; `tests/migration.test.ts` ### CRITICAL Trusting persisted JSON directly Wrong: ```ts import { lintBody, type Body } from "@ryhrm-gz/xincodo-lib"; const body = savedArticle.body as Body; const report = lintBody(body); ``` Correct: ```ts import { lintBody, safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; const migrated = safeMigrateBody(savedArticle.body); if (!migrated.success) { return { ok: false as const, issue: migrated.issue }; } const report = lintBody(migrated.output); ``` Saved Body JSON should be treated as unknown input and passed through `safeMigrateBody` before linting or rendering. Source: maintainer interview ### HIGH Treating future versions as migratable Wrong: ```ts import { BODY_VERSION, safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; const result = safeMigrateBody({ version: BODY_VERSION + 1, content: [] }); if (!result.success) { await saveRawBody(rawBody); } ``` Correct: ```ts import { safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; const result = safeMigrateBody(rawBody); if (!result.success) { throw new Error(result.issue.message); } ``` Versions greater than `BODY_VERSION` are unsupported because there is no downgrade path. Source: `src/migration.ts`; `tests/migration.test.ts` ### CRITICAL Mixing storage concerns into skill scope Wrong: ```ts await xincodo.saveArticle({ body, databaseUrl, }); ``` Correct: ```ts import { lintBody, safeMigrateBody } from "@ryhrm-gz/xincodo-lib"; const migrated = safeMigrateBody(rawBody); if (!migrated.success) { throw new Error(migrated.issue.message); } const report = lintBody(migrated.output); ``` The library can validate Body data before persistence, but DB schema, request handling, and upload flows are outside its scope. Source: maintainer interview ## References - [Migration issues and lint severities](references/migration-issues-and-lint-severities.md) See also: `building-and-parsing-body/SKILL.md` — persisted JSON should go through `safeMigrateBody` before lint and publish checks can run.