From 22a1b5de57b5906c393316af5e4f251fed8eaa20 Mon Sep 17 00:00:00 2001 From: Richard R Date: Sat, 30 May 2026 11:15:19 -0600 Subject: [PATCH] test(unit): migrate batch2 document and parser suites to vitest --- ... canonicalize-epub-segment.vitest.spec.ts} | 6 +-- ...cstore.spec.ts => docstore.vitest.spec.ts} | 15 ++++-- ....spec.ts => document-cache.vitest.spec.ts} | 41 ++++++++++---- ... => html-audiobook-adapter.vitest.spec.ts} | 8 +-- ...cks.spec.ts => html-blocks.vitest.spec.ts} | 10 ++-- ...s => pdf-audiobook-adapter.vitest.spec.ts} | 8 +-- ....ts => pdf-build-page-text.vitest.spec.ts} | 4 +- ...ec.ts => pdf-force-reparse.vitest.spec.ts} | 4 +- ...df-merge-text-with-regions.vitest.spec.ts} | 18 ++++++- ...parse-normalize-text-items.vitest.spec.ts} | 12 ++++- ...f-stitch-cross-page-blocks.vitest.spec.ts} | 19 +++---- ...pec.ts => pdf-tts-planning.vitest.spec.ts} | 4 +- tests/unit/support/document-fixtures.ts | 54 +++++++++++++++++++ vitest.config.ts | 10 ++++ 14 files changed, 161 insertions(+), 52 deletions(-) rename tests/unit/{canonicalize-epub-segment.spec.ts => canonicalize-epub-segment.vitest.spec.ts} (97%) rename tests/unit/{docstore.spec.ts => docstore.vitest.spec.ts} (79%) rename tests/unit/{document-cache.spec.ts => document-cache.vitest.spec.ts} (71%) rename tests/unit/{html-audiobook-adapter.spec.ts => html-audiobook-adapter.vitest.spec.ts} (95%) rename tests/unit/{html-blocks.spec.ts => html-blocks.vitest.spec.ts} (94%) rename tests/unit/{pdf-audiobook-adapter.spec.ts => pdf-audiobook-adapter.vitest.spec.ts} (96%) rename tests/unit/{pdf-build-page-text.spec.ts => pdf-build-page-text.vitest.spec.ts} (92%) rename tests/unit/{pdf-force-reparse.spec.ts => pdf-force-reparse.vitest.spec.ts} (89%) rename tests/unit/{pdf-merge-text-with-regions.spec.ts => pdf-merge-text-with-regions.vitest.spec.ts} (59%) rename tests/unit/{pdf-parse-normalize-text-items.spec.ts => pdf-parse-normalize-text-items.vitest.spec.ts} (69%) rename tests/unit/{pdf-stitch-cross-page-blocks.spec.ts => pdf-stitch-cross-page-blocks.vitest.spec.ts} (89%) rename tests/unit/{pdf-tts-planning.spec.ts => pdf-tts-planning.vitest.spec.ts} (97%) create mode 100644 tests/unit/support/document-fixtures.ts diff --git a/tests/unit/canonicalize-epub-segment.spec.ts b/tests/unit/canonicalize-epub-segment.vitest.spec.ts similarity index 97% rename from tests/unit/canonicalize-epub-segment.spec.ts rename to tests/unit/canonicalize-epub-segment.vitest.spec.ts index 42a02b8..164d857 100644 --- a/tests/unit/canonicalize-epub-segment.spec.ts +++ b/tests/unit/canonicalize-epub-segment.vitest.spec.ts @@ -1,4 +1,4 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { canonicalizeEpubSegmentAgainstSpineText, @@ -6,7 +6,7 @@ import { } from '../../src/lib/client/epub/canonicalize-epub-segment'; import { planCanonicalTtsSegments } from '../../src/lib/shared/tts-segment-plan'; -test.describe('canonicalizeEpubSegmentAgainstSpineText', () => { +describe('canonicalizeEpubSegmentAgainstSpineText', () => { test('maps an exact sentence to the canonical segment identity', () => { const spineText = [ 'First section sentence with enough words to stand alone.', @@ -95,7 +95,7 @@ test.describe('canonicalizeEpubSegmentAgainstSpineText', () => { }); }); -test.describe('canonicalizeEpubSegmentsAgainstSpineText', () => { +describe('canonicalizeEpubSegmentsAgainstSpineText', () => { test('maps overlap-boundary drift sentences to forward canonical segments', () => { const sourceSentences = [ 'The star was particularly bright when the station lights switched off for cycle night.', diff --git a/tests/unit/docstore.spec.ts b/tests/unit/docstore.vitest.spec.ts similarity index 79% rename from tests/unit/docstore.spec.ts rename to tests/unit/docstore.vitest.spec.ts index 7e9f144..684cc52 100644 --- a/tests/unit/docstore.spec.ts +++ b/tests/unit/docstore.vitest.spec.ts @@ -1,10 +1,10 @@ -import { test, expect } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { getMigratedDocumentFileName } from '../../src/lib/server/storage/docstore-legacy'; -test.describe('Docstore Filename Safety', () => { +describe('docstore filename safety', () => { const id = 'a'.repeat(64); // Simulate sha256 hex ID - test('should generate standard filename for short names', () => { + test('generates stable file names for short inputs', () => { const name = 'test-file.pdf'; const result = getMigratedDocumentFileName(id, name); expect(result).toBe(`${id}__test-file.pdf`); @@ -50,4 +50,13 @@ test.describe('Docstore Filename Safety', () => { expect(result.length).toBe(240); expect(result).not.toContain('truncated-'); }); + + test('drops path traversal and null-byte fragments from migrated file names', () => { + const dirtyName = '../nested/\u0000financial-report.pdf'; + const result = getMigratedDocumentFileName(id, dirtyName); + + expect(result).toBe(`${id}__financial-report.pdf`); + expect(result).not.toContain('..'); + expect(result).not.toContain('\u0000'); + }); }); diff --git a/tests/unit/document-cache.spec.ts b/tests/unit/document-cache.vitest.spec.ts similarity index 71% rename from tests/unit/document-cache.spec.ts rename to tests/unit/document-cache.vitest.spec.ts index 061db9a..c807c39 100644 --- a/tests/unit/document-cache.spec.ts +++ b/tests/unit/document-cache.vitest.spec.ts @@ -1,16 +1,17 @@ -import { test, expect } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import type { BaseDocument, EPUBDocument, HTMLDocument, PDFDocument } from '../../src/types/documents'; import { ensureCachedDocumentCore } from '../../src/lib/client/cache/documents'; +import { makeBaseDocument } from './support/document-fixtures'; -test.describe('document-cache-core', () => { +describe('document-cache-core', () => { test('returns cached PDF without downloading', async () => { - const meta: BaseDocument = { + const meta: BaseDocument = makeBaseDocument({ id: 'pdf1', name: 'a.pdf', size: 10, - lastModified: Date.now(), + lastModified: 1_700_000_000_001, type: 'pdf', - }; + }); let downloads = 0; const cached: PDFDocument = { ...meta, type: 'pdf', data: new ArrayBuffer(1) }; @@ -32,13 +33,13 @@ test.describe('document-cache-core', () => { }); test('downloads and stores on cache miss (EPUB)', async () => { - const meta: BaseDocument = { + const meta: BaseDocument = makeBaseDocument({ id: 'epub1', name: 'b.epub', size: 10, - lastModified: Date.now(), + lastModified: 1_700_000_000_002, type: 'epub', - }; + }); const store = new Map(); let downloads = 0; @@ -63,13 +64,13 @@ test.describe('document-cache-core', () => { }); test('downloads, decodes, and stores HTML on cache miss', async () => { - const meta: BaseDocument = { + const meta: BaseDocument = makeBaseDocument({ id: 'html1', name: 'c.txt', size: 5, - lastModified: Date.now(), + lastModified: 1_700_000_000_003, type: 'html', - }; + }); const store = new Map(); let decodedCalls = 0; @@ -92,4 +93,22 @@ test.describe('document-cache-core', () => { expect(result.type).toBe('html'); expect((result as HTMLDocument).data).toBe('hello'); }); + + test('throws deterministic cache error when download succeeds but backend misses persisted PDF', async () => { + const meta = makeBaseDocument({ + id: 'pdf-cache-miss', + type: 'pdf', + }); + + await expect( + ensureCachedDocumentCore(meta, { + get: async () => null, + putPdf: async () => { /* simulate write path without persisted row */ }, + putEpub: async () => { /* unused */ }, + putHtml: async () => { /* unused */ }, + download: async () => new Uint8Array([1, 2, 3]).buffer, + decodeText: () => '', + }), + ).rejects.toThrow('Failed to cache PDF'); + }); }); diff --git a/tests/unit/html-audiobook-adapter.spec.ts b/tests/unit/html-audiobook-adapter.vitest.spec.ts similarity index 95% rename from tests/unit/html-audiobook-adapter.spec.ts rename to tests/unit/html-audiobook-adapter.vitest.spec.ts index 9395533..7fda86c 100644 --- a/tests/unit/html-audiobook-adapter.spec.ts +++ b/tests/unit/html-audiobook-adapter.vitest.spec.ts @@ -1,11 +1,11 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { createHtmlAudiobookSourceAdapter } from '../../src/lib/client/audiobooks/adapters/html'; import { parseHtmlBlocks, type HtmlBlock } from '../../src/lib/client/html/blocks'; const blocksFromMd = (src: string): HtmlBlock[] => parseHtmlBlocks(src, false); const blocksFromTxt = (src: string): HtmlBlock[] => parseHtmlBlocks(src, true); -test.describe('createHtmlAudiobookSourceAdapter (markdown chapter splitting)', () => { +describe('createHtmlAudiobookSourceAdapter (markdown chapter splitting)', () => { test('starts a new chapter at each h1/h2 heading by default', async () => { const blocks = blocksFromMd( [ @@ -95,7 +95,7 @@ test.describe('createHtmlAudiobookSourceAdapter (markdown chapter splitting)', ( }); }); -test.describe('createHtmlAudiobookSourceAdapter (txt chapter splitting)', () => { +describe('createHtmlAudiobookSourceAdapter (txt chapter splitting)', () => { test('chunks TXT documents into "Part N" of 50 blocks by default', async () => { const blocks = blocksFromTxt( Array.from({ length: 120 }, (_, i) => `Block ${i + 1}.`).join('\n\n'), @@ -130,7 +130,7 @@ test.describe('createHtmlAudiobookSourceAdapter (txt chapter splitting)', () => }); }); -test.describe('createHtmlAudiobookSourceAdapter — prepareChapter', () => { +describe('createHtmlAudiobookSourceAdapter — prepareChapter', () => { test('returns the same chapter by index that prepareChapters lists', async () => { const blocks = blocksFromMd(['# A', '', 'one', '', '## B', '', 'two'].join('\n')); const adapter = createHtmlAudiobookSourceAdapter({ diff --git a/tests/unit/html-blocks.spec.ts b/tests/unit/html-blocks.vitest.spec.ts similarity index 94% rename from tests/unit/html-blocks.spec.ts rename to tests/unit/html-blocks.vitest.spec.ts index 533d153..02f6b0e 100644 --- a/tests/unit/html-blocks.spec.ts +++ b/tests/unit/html-blocks.vitest.spec.ts @@ -1,4 +1,4 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { mdToPlainText, parseHtmlBlocks, @@ -6,7 +6,7 @@ import { splitTxtBlocks, } from '../../src/lib/client/html/blocks'; -test.describe('parseHtmlBlocks (markdown)', () => { +describe('parseHtmlBlocks (markdown)', () => { test('splits headings, paragraphs, and lists into separate blocks', () => { const src = [ '# Title', @@ -55,7 +55,7 @@ test.describe('parseHtmlBlocks (markdown)', () => { }); }); -test.describe('parseHtmlBlocks (txt)', () => { +describe('parseHtmlBlocks (txt)', () => { test('splits on blank-line boundaries and preserves intra-block whitespace', () => { const src = 'First block\nmore.\n\nSecond block.\n\n\nThird block.'; const blocks = parseHtmlBlocks(src, true); @@ -73,7 +73,7 @@ test.describe('parseHtmlBlocks (txt)', () => { }); }); -test.describe('mdToPlainText badge/image stripping', () => { +describe('mdToPlainText badge/image stripping', () => { // The bug: badge alt text was being kept in plainText. Since the rendered // DOM is just an with no text node, the sentence-highlight pattern // matcher couldn't find those words and the WHOLE first-segment match @@ -124,7 +124,7 @@ test.describe('mdToPlainText badge/image stripping', () => { }); }); -test.describe('buildFullDocumentText-style integration (badge-only blocks)', () => { +describe('buildFullDocumentText-style integration (badge-only blocks)', () => { // If a paragraph is composed only of badges, its plainText is empty after // stripping. The reader filters empty plainText out of the TTS source // (`useHtmlDocument#buildFullDocumentText`), so badge blocks don't generate diff --git a/tests/unit/pdf-audiobook-adapter.spec.ts b/tests/unit/pdf-audiobook-adapter.vitest.spec.ts similarity index 96% rename from tests/unit/pdf-audiobook-adapter.spec.ts rename to tests/unit/pdf-audiobook-adapter.vitest.spec.ts index dd110b5..17cebce 100644 --- a/tests/unit/pdf-audiobook-adapter.spec.ts +++ b/tests/unit/pdf-audiobook-adapter.vitest.spec.ts @@ -1,15 +1,15 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { createPdfAudiobookSourceAdapter } from '../../src/lib/client/audiobooks/adapters/pdf'; import type { ParsedPdfDocument } from '../../src/types/parsed-pdf'; import type { DocumentSettings } from '../../src/types/document-settings'; -test.describe('pdf audiobook adapter', () => { +describe('pdf audiobook adapter', () => { test('builds chapters from paragraph titles and filters skipped kinds', async () => { const parsed: ParsedPdfDocument = { schemaVersion: 1, documentId: 'doc-1', parserVersion: 'test', - parsedAt: Date.now(), + parsedAt: 1_700_000_000_000, pages: [ { pageNumber: 1, @@ -77,7 +77,7 @@ test.describe('pdf audiobook adapter', () => { schemaVersion: 1, documentId: 'doc-2', parserVersion: 'test', - parsedAt: Date.now(), + parsedAt: 1_700_000_000_001, pages: [ { pageNumber: 1, diff --git a/tests/unit/pdf-build-page-text.spec.ts b/tests/unit/pdf-build-page-text.vitest.spec.ts similarity index 92% rename from tests/unit/pdf-build-page-text.spec.ts rename to tests/unit/pdf-build-page-text.vitest.spec.ts index 247507c..6604d2d 100644 --- a/tests/unit/pdf-build-page-text.spec.ts +++ b/tests/unit/pdf-build-page-text.vitest.spec.ts @@ -1,8 +1,8 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { buildPageTextFromBlocks } from '../../src/lib/client/pdf-block-text'; import type { ParsedPdfPage } from '../../src/types/parsed-pdf'; -test.describe('buildPageTextFromBlocks', () => { +describe('buildPageTextFromBlocks', () => { test('filters skipped kinds and preserves reading order', () => { const page: ParsedPdfPage = { pageNumber: 1, diff --git a/tests/unit/pdf-force-reparse.spec.ts b/tests/unit/pdf-force-reparse.vitest.spec.ts similarity index 89% rename from tests/unit/pdf-force-reparse.spec.ts rename to tests/unit/pdf-force-reparse.vitest.spec.ts index 95c2ce4..6db012b 100644 --- a/tests/unit/pdf-force-reparse.spec.ts +++ b/tests/unit/pdf-force-reparse.vitest.spec.ts @@ -1,4 +1,4 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { FORCE_REPARSE_CONFIRM_MESSAGE, FORCE_REPARSE_CONFIRM_TEXT, @@ -6,7 +6,7 @@ import { isForceReparseDisabled, } from '../../src/lib/client/pdf/force-reparse'; -test.describe('pdf force reparse controls', () => { +describe('pdf force reparse controls', () => { test('disables action while parse is pending or running', () => { expect(isForceReparseDisabled('pending')).toBeTruthy(); expect(isForceReparseDisabled('running')).toBeTruthy(); diff --git a/tests/unit/pdf-merge-text-with-regions.spec.ts b/tests/unit/pdf-merge-text-with-regions.vitest.spec.ts similarity index 59% rename from tests/unit/pdf-merge-text-with-regions.spec.ts rename to tests/unit/pdf-merge-text-with-regions.vitest.spec.ts index 86bd435..135e9c3 100644 --- a/tests/unit/pdf-merge-text-with-regions.spec.ts +++ b/tests/unit/pdf-merge-text-with-regions.vitest.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { mergeTextWithRegions } from '@openreader/compute-core'; -test.describe('mergeTextWithRegions', () => { +describe('mergeTextWithRegions', () => { test('assigns text items to containing regions by centroid and joins in reading order', () => { const regions = [ { bbox: [0, 0, 100, 50] as [number, number, number, number], label: 'text' as const }, @@ -20,4 +20,18 @@ test.describe('mergeTextWithRegions', () => { expect(merged[0].text).toBe('hello world'); expect(merged[1].text).toBe('Figure 1.2'); }); + + test('drops text whose centroid is outside every region', () => { + const regions = [ + { bbox: [0, 0, 50, 50] as [number, number, number, number], label: 'text' as const }, + ]; + const textItems = [ + { text: 'inside', x: 10, y: 10, width: 10, height: 8 }, + { text: 'outside', x: 80, y: 80, width: 12, height: 8 }, + ]; + + const merged = mergeTextWithRegions(regions, textItems); + expect(merged).toHaveLength(1); + expect(merged[0].text).toBe('inside'); + }); }); diff --git a/tests/unit/pdf-parse-normalize-text-items.spec.ts b/tests/unit/pdf-parse-normalize-text-items.vitest.spec.ts similarity index 69% rename from tests/unit/pdf-parse-normalize-text-items.spec.ts rename to tests/unit/pdf-parse-normalize-text-items.vitest.spec.ts index aac976c..3ceccd0 100644 --- a/tests/unit/pdf-parse-normalize-text-items.spec.ts +++ b/tests/unit/pdf-parse-normalize-text-items.vitest.spec.ts @@ -1,4 +1,4 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { normalizeTextItemsForLayout } from '@openreader/compute-core'; import type { TextItem } from 'pdfjs-dist/types/src/display/api'; @@ -19,7 +19,7 @@ function makeTextItem( } as unknown as TextItem; } -test.describe('normalizeTextItemsForLayout', () => { +describe('normalizeTextItemsForLayout', () => { test('keeps horizontal body text and drops rotated/skewed margin text', () => { const horizontal = makeTextItem( 'Powered by large language models', @@ -36,4 +36,12 @@ test.describe('normalizeTextItemsForLayout', () => { expect(normalized).toHaveLength(1); expect(normalized[0]?.text).toBe('Powered by large language models'); }); + + test('drops malformed/vertical-only runs so downstream layout planning sees no body text', () => { + const vertical = makeTextItem('Side label', [0, 10, -10, 0, 30, 200]); + const skewed = makeTextItem('Watermark', [10, 5, 2, 10, 200, 500]); + + const normalized = normalizeTextItemsForLayout([vertical, skewed], 800); + expect(normalized).toEqual([]); + }); }); diff --git a/tests/unit/pdf-stitch-cross-page-blocks.spec.ts b/tests/unit/pdf-stitch-cross-page-blocks.vitest.spec.ts similarity index 89% rename from tests/unit/pdf-stitch-cross-page-blocks.spec.ts rename to tests/unit/pdf-stitch-cross-page-blocks.vitest.spec.ts index 86e6d4a..0aa37e6 100644 --- a/tests/unit/pdf-stitch-cross-page-blocks.spec.ts +++ b/tests/unit/pdf-stitch-cross-page-blocks.vitest.spec.ts @@ -1,6 +1,7 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { stitchCrossPageBlocks } from '@openreader/compute-core'; import type { ParsedPdfBlock, ParsedPdfDocument, ParsedPdfBlockKind } from '../../src/types/parsed-pdf'; +import { makeParsedPdfDocument, makeParsedPdfPage } from './support/document-fixtures'; function makeBlock( id: string, @@ -23,19 +24,13 @@ function makeBlock( } function makeDoc(page1Blocks: ParsedPdfBlock[], page2Blocks: ParsedPdfBlock[]): ParsedPdfDocument { - return { - schemaVersion: 1, - documentId: 'doc', - parserVersion: 'test', - parsedAt: 0, - pages: [ - { pageNumber: 1, width: 100, height: 100, blocks: page1Blocks }, - { pageNumber: 2, width: 100, height: 100, blocks: page2Blocks }, - ], - }; + return makeParsedPdfDocument([ + makeParsedPdfPage(1, page1Blocks), + makeParsedPdfPage(2, page2Blocks), + ]); } -test.describe('stitchCrossPageBlocks', () => { +describe('stitchCrossPageBlocks', () => { test('stitches paragraph continuation across footer/header noise', () => { const doc = makeDoc( [ diff --git a/tests/unit/pdf-tts-planning.spec.ts b/tests/unit/pdf-tts-planning.vitest.spec.ts similarity index 97% rename from tests/unit/pdf-tts-planning.spec.ts rename to tests/unit/pdf-tts-planning.vitest.spec.ts index 1066d7b..c9314dd 100644 --- a/tests/unit/pdf-tts-planning.spec.ts +++ b/tests/unit/pdf-tts-planning.vitest.spec.ts @@ -1,4 +1,4 @@ -import { expect, test } from '@playwright/test'; +import { describe, expect, test } from 'vitest'; import { buildPdfPageSourceUnits, buildPdfPrefetchPayload } from '../../src/lib/client/pdf-tts-planning'; import type { ParsedPdfPage } from '../../src/types/parsed-pdf'; @@ -39,7 +39,7 @@ function buildPage(pageNumber: number): ParsedPdfPage { }; } -test.describe('pdf tts planning helpers', () => { +describe('pdf tts planning helpers', () => { test('buildPdfPageSourceUnits uses parsed blocks, honors skip kinds, and pins locator page', () => { const page = buildPage(2); const units = buildPdfPageSourceUnits(page, 2, ['header']); diff --git a/tests/unit/support/document-fixtures.ts b/tests/unit/support/document-fixtures.ts new file mode 100644 index 0000000..aefe931 --- /dev/null +++ b/tests/unit/support/document-fixtures.ts @@ -0,0 +1,54 @@ +import type { BaseDocument } from '../../../src/types/documents'; +import type { ParsedPdfBlock, ParsedPdfBlockKind, ParsedPdfDocument, ParsedPdfPage } from '../../../src/types/parsed-pdf'; + +export function makeBaseDocument(overrides: Partial = {}): BaseDocument { + return { + id: 'doc-1', + name: 'document.pdf', + size: 1_024, + lastModified: 1_700_000_000_000, + type: 'pdf', + ...overrides, + }; +} + +export function makeParsedPdfBlock(input: { + id: string; + kind: ParsedPdfBlockKind; + text: string; + page: number; + readingOrder: number; +}): ParsedPdfBlock { + return { + id: input.id, + kind: input.kind, + text: input.text, + fragments: [ + { + page: input.page, + bbox: [0, 0, 100, 10], + text: input.text, + readingOrder: input.readingOrder, + }, + ], + }; +} + +export function makeParsedPdfPage(pageNumber: number, blocks: ParsedPdfBlock[]): ParsedPdfPage { + return { + pageNumber, + width: 800, + height: 1_200, + blocks, + }; +} + +export function makeParsedPdfDocument(pages: ParsedPdfPage[]): ParsedPdfDocument { + return { + schemaVersion: 1, + documentId: 'doc-fixture', + parserVersion: 'test', + parsedAt: 1_700_000_000_000, + pages, + }; +} diff --git a/vitest.config.ts b/vitest.config.ts index fe7ca8b..c3e8a47 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,7 +2,17 @@ import { defineConfig } from 'vitest/config'; import { fileURLToPath } from 'node:url'; const srcDir = fileURLToPath(new URL('./src/', import.meta.url)); +const computeCoreIndex = fileURLToPath(new URL('./compute/core/src/index.ts', import.meta.url)); +const computeCoreApiContracts = fileURLToPath(new URL('./compute/core/src/api-contracts/index.ts', import.meta.url)); +const computeCoreControlPlane = fileURLToPath(new URL('./compute/core/src/control-plane/index.ts', import.meta.url)); +const computeCoreLocalRuntime = fileURLToPath(new URL('./compute/core/src/local-runtime.ts', import.meta.url)); +const computeCoreTypes = fileURLToPath(new URL('./compute/core/src/types/index.ts', import.meta.url)); const alias = [ + { find: /^@openreader\/compute-core$/, replacement: computeCoreIndex }, + { find: /^@openreader\/compute-core\/api-contracts$/, replacement: computeCoreApiContracts }, + { find: /^@openreader\/compute-core\/control-plane$/, replacement: computeCoreControlPlane }, + { find: /^@openreader\/compute-core\/local-runtime$/, replacement: computeCoreLocalRuntime }, + { find: /^@openreader\/compute-core\/types$/, replacement: computeCoreTypes }, { find: /^@\//, replacement: `${srcDir}` }, { find: '@', replacement: srcDir }, ];