From aeebc47379f1515a03cfa35ca0a9ac7c1b888171 Mon Sep 17 00:00:00 2001 From: Anthony GAEREMYNCK <1@anthony.sh> Date: Thu, 30 Jul 2026 09:06:12 +0200 Subject: [PATCH] feat: add converter registry Co-Authored-By: Claude Sonnet 5 --- src/converters/registry.js | 24 ++++++++++++++++++++++++ test/converters/registry.test.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/converters/registry.js create mode 100644 test/converters/registry.test.js diff --git a/src/converters/registry.js b/src/converters/registry.js new file mode 100644 index 0000000..9d61e1e --- /dev/null +++ b/src/converters/registry.js @@ -0,0 +1,24 @@ +let entries = new Map(); + +function key(sourceFormat, targetFormat) { + return `${sourceFormat}->${targetFormat}`; +} + +export function register({ family, sourceFormat, targetFormat, convert }) { + entries.set(key(sourceFormat, targetFormat), { family, convert }); +} + +export function resolve(sourceFormat, targetFormat) { + return entries.get(key(sourceFormat, targetFormat)) ?? null; +} + +export function listTargetFormats(sourceFormat) { + const prefix = `${sourceFormat}->`; + return [...entries.keys()] + .filter((k) => k.startsWith(prefix)) + .map((k) => k.slice(prefix.length)); +} + +export function _resetForTests() { + entries = new Map(); +} diff --git a/test/converters/registry.test.js b/test/converters/registry.test.js new file mode 100644 index 0000000..d258824 --- /dev/null +++ b/test/converters/registry.test.js @@ -0,0 +1,32 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { register, resolve, listTargetFormats, _resetForTests } from '../../src/converters/registry.js'; + +beforeEach(() => { + _resetForTests(); +}); + +describe('converter registry', () => { + it('resolves a registered source/target pair', () => { + const convert = async () => {}; + register({ family: 'image', sourceFormat: 'png', targetFormat: 'webp', convert }); + + const entry = resolve('png', 'webp'); + + expect(entry.family).toBe('image'); + expect(entry.convert).toBe(convert); + }); + + it('returns null for an unregistered pair', () => { + expect(resolve('png', 'made-up')).toBeNull(); + }); + + it('lists all target formats registered for a source format', () => { + register({ family: 'image', sourceFormat: 'png', targetFormat: 'webp', convert: async () => {} }); + register({ family: 'image', sourceFormat: 'png', targetFormat: 'jpg', convert: async () => {} }); + register({ family: 'document', sourceFormat: 'docx', targetFormat: 'pdf', convert: async () => {} }); + + expect(listTargetFormats('png').sort()).toEqual(['jpg', 'webp']); + expect(listTargetFormats('docx')).toEqual(['pdf']); + expect(listTargetFormats('unknown-format')).toEqual([]); + }); +});