Lock the access-layer decision (REST only) and start implementation per SPEC. - monorepo (npm workspaces): packages/docmost-client = DocmostClient + lib/* copied 1:1 from docmost-mcp/src (backport target), plus bannered sync methods (listTrash, restorePage, listAllSpacePages, exportPageBody, listRecentSince / collectRecentSince cursor scan) - engine stays the root app per AGENTS.md (src/, test/, build/, data/, settings.ts); add roundtrip.ts (SPEC §11 idempotency harness), pull.ts (SPEC §6 read-only Docmost->FS mirror), sanitize.ts (SPEC §12 filenames, path-traversal-safe) - Dockerfile builds the workspace lib before the app; vitest gates CI - exportPageBody never touches /comments (SPEC §3); serializeDocmostMarkdownBody emits meta + body only - SPEC: resolve access-layer (REST), reflect root-engine layout + REST pagination - tests: sanitize (incl. dot-traversal), collectRecentSince (cutoff/dedup/cap), stripBlockIds, markdown round-trip byte-stability Note: raw ProseMirror round-trip is byte-stable in Markdown but not yet attribute- idempotent (SPEC §11 Задача №0, before Phase 2).
30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
import { readFile } from 'node:fs/promises';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { dirname, join } from 'node:path';
|
|
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
convertProseMirrorToMarkdown,
|
|
markdownToProseMirror,
|
|
} from 'docmost-client';
|
|
|
|
// Resolve the fixture relative to this test file so the test is CWD-independent.
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const FIXTURE = join(here, 'fixtures', 'sample-doc.json');
|
|
|
|
describe('round-trip idempotency (SPEC §11)', () => {
|
|
it('markdown is byte-stable across export -> import -> export', async () => {
|
|
const doc = JSON.parse(await readFile(FIXTURE, 'utf8'));
|
|
|
|
// export -> import -> export
|
|
const md1 = convertProseMirrorToMarkdown(doc);
|
|
const doc2 = await markdownToProseMirror(md1);
|
|
const md2 = convertProseMirrorToMarkdown(doc2);
|
|
|
|
// The property git actually needs: a second export reproduces the first
|
|
// byte-for-byte. We intentionally do NOT deep-equal doc vs doc2 — the
|
|
// converter reconstructs schema default attrs (e.g. indent:null), a known
|
|
// SPEC §11 divergence that does not affect markdown stability.
|
|
expect(md2).toBe(md1);
|
|
});
|
|
});
|