@richardmcquiston01/online-catalog-cms 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +387 -0
- package/dist/index.cjs +1550 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +558 -0
- package/dist/index.d.ts +558 -0
- package/dist/index.js +1527 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rich-text/builders.ts","../src/rich-text/validate.ts","../src/installer/Installer.ts","../src/services/CategoryService.ts","../src/services/ImageService.ts","../src/services/ProductService.ts","../src/catalog.ts","../src/adapters/database/relational/BaseSQLAdapter.ts","../src/utils/slug.ts","../src/adapters/database/relational/rowMappers.ts","../src/adapters/database/relational/SQLCategoryRepository.ts","../src/adapters/database/relational/SQLImageRepository.ts","../src/adapters/database/relational/SQLProductRepository.ts","../src/adapters/database/sqlite/SQLiteAdapter.ts","../src/adapters/database/postgres/PostgresAdapter.ts","../src/adapters/database/mysql/MySQLAdapter.ts","../src/adapters/database/redis/RedisAdapter.ts","../src/adapters/database/mongodb/MongoDBAdapter.ts","../src/adapters/storage/local/LocalStorageAdapter.ts","../src/adapters/storage/s3/S3Adapter.ts","../src/adapters/storage/external/ExternalURLAdapter.ts"],"names":["image","randomUUID","createRequire","require","__dirname","fileURLToPath","MIGRATION_PATH","join","readFileSync","loadDriver"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n BlockquoteNode,\n HeadingNode,\n InlineNode,\n LinkNode,\n ListNode,\n ParagraphNode,\n RichTextDocument,\n RichTextImageNode,\n TextNode,\n} from '../types/rich-text.js';\n\n/** Create a plain text inline node. */\nexport function text(\n content: string,\n options: { bold?: boolean; italic?: boolean; code?: boolean } = {},\n): TextNode {\n return { type: 'text', text: content, ...options };\n}\n\n/** Create a hyperlink inline node. */\nexport function link(href: string, children: InlineNode[]): LinkNode {\n return { type: 'link', href, children };\n}\n\n/** Create a paragraph block node. */\nexport function paragraph(\n children: InlineNode[],\n cssClass?: string,\n): ParagraphNode {\n return { type: 'paragraph', children, ...(cssClass ? { cssClass } : {}) };\n}\n\n/** Create a heading block node (h1–h6). */\nexport function heading(\n level: 1 | 2 | 3 | 4 | 5 | 6,\n children: InlineNode[],\n cssClass?: string,\n): HeadingNode {\n return {\n type: 'heading',\n level,\n children,\n ...(cssClass ? { cssClass } : {}),\n };\n}\n\n/** Create an inline image node. */\nexport function image(\n src: string,\n alt: string,\n cssClass?: string,\n): RichTextImageNode {\n return { type: 'image', src, alt, ...(cssClass ? { cssClass } : {}) };\n}\n\n/** Create an unordered list node. */\nexport function unorderedList(\n items: InlineNode[][],\n cssClass?: string,\n): ListNode {\n return {\n type: 'list',\n ordered: false,\n items,\n ...(cssClass ? { cssClass } : {}),\n };\n}\n\n/** Create an ordered list node. */\nexport function orderedList(\n items: InlineNode[][],\n cssClass?: string,\n): ListNode {\n return {\n type: 'list',\n ordered: true,\n items,\n ...(cssClass ? { cssClass } : {}),\n };\n}\n\n/** Create a blockquote node. */\nexport function blockquote(\n children: InlineNode[],\n cssClass?: string,\n): BlockquoteNode {\n return {\n type: 'blockquote',\n children,\n ...(cssClass ? { cssClass } : {}),\n };\n}\n\n/** Wrap an array of block nodes into a complete RichTextDocument. */\nexport function document(nodes: RichTextDocument['nodes']): RichTextDocument {\n return { version: 1, nodes };\n}\n","import type {\n InlineNode,\n RichTextDocument,\n RichTextNode,\n} from '../types/rich-text.js';\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isInlineNode(value: unknown): value is InlineNode {\n if (!isObject(value)) return false;\n if (value.type === 'text') {\n return typeof value.text === 'string';\n }\n if (value.type === 'link') {\n return (\n typeof value.href === 'string' &&\n Array.isArray(value.children) &&\n (value.children as unknown[]).every(isInlineNode)\n );\n }\n return false;\n}\n\nfunction isRichTextNode(value: unknown): value is RichTextNode {\n if (!isObject(value)) return false;\n const type = value.type;\n\n if (type === 'paragraph' || type === 'blockquote') {\n return (\n Array.isArray(value.children) &&\n (value.children as unknown[]).every(isInlineNode)\n );\n }\n\n if (type === 'heading') {\n const level = value.level;\n return (\n typeof level === 'number' &&\n level >= 1 &&\n level <= 6 &&\n Array.isArray(value.children) &&\n (value.children as unknown[]).every(isInlineNode)\n );\n }\n\n if (type === 'image') {\n return typeof value.src === 'string' && typeof value.alt === 'string';\n }\n\n if (type === 'list') {\n return (\n typeof value.ordered === 'boolean' &&\n Array.isArray(value.items) &&\n (value.items as unknown[]).every(\n (item) =>\n Array.isArray(item) && (item as unknown[]).every(isInlineNode),\n )\n );\n }\n\n return false;\n}\n\n/**\n * Returns true if `value` is a valid {@link RichTextDocument}.\n * Use this at system boundaries (e.g. API input) before persisting content.\n */\nexport function isRichTextDocument(value: unknown): value is RichTextDocument {\n if (!isObject(value)) return false;\n if (value.version !== 1) return false;\n if (!Array.isArray(value.nodes)) return false;\n return (value.nodes as unknown[]).every(isRichTextNode);\n}\n\n/**\n * Throws a `TypeError` if `value` is not a valid {@link RichTextDocument}.\n */\nexport function assertRichTextDocument(\n value: unknown,\n): asserts value is RichTextDocument {\n if (!isRichTextDocument(value)) {\n throw new TypeError(\n 'Invalid RichTextDocument: must be { version: 1, nodes: RichTextNode[] }',\n );\n }\n}\n","import type {\n DatabaseAdapter,\n VerificationResult,\n} from '../interfaces/DatabaseAdapter.js';\n\nexport interface InstallOptions {\n /** If true, describe what would happen without making changes. */\n dryRun?: boolean;\n}\n\n/** Wraps adapter initialization and verification with helpful logging. */\nexport class Installer {\n constructor(private readonly adapter: DatabaseAdapter) {}\n\n /**\n * Run database migrations and verify the resulting schema.\n * @returns The verification result after migration.\n */\n async install(options: InstallOptions = {}): Promise<VerificationResult> {\n if (options.dryRun) {\n return this.adapter.verify();\n }\n\n await this.adapter.initialize();\n return this.adapter.verify();\n }\n\n /** Check that the schema is correct without running migrations. */\n async verify(): Promise<VerificationResult> {\n return this.adapter.verify();\n }\n}\n","import type { CategoryRepository } from '../interfaces/index.js';\nimport type {\n Category,\n CategoryFilter,\n CreateCategoryInput,\n UpdateCategoryInput,\n} from '../types/index.js';\n\n/** High-level category operations. */\nexport class CategoryService {\n constructor(private readonly repo: CategoryRepository) {}\n\n async create(input: CreateCategoryInput): Promise<Category> {\n return this.repo.create(input);\n }\n\n async get(id: string): Promise<Category | null> {\n return this.repo.get(id);\n }\n\n async update(id: string, input: UpdateCategoryInput): Promise<Category> {\n return this.repo.update(id, input);\n }\n\n async delete(id: string): Promise<void> {\n return this.repo.delete(id);\n }\n\n async list(filter?: CategoryFilter): Promise<Category[]> {\n return this.repo.list(filter);\n }\n}\n","import type { Readable } from 'node:stream';\nimport type { ImageRepository, StorageAdapter } from '../interfaces/index.js';\nimport type { CreateImageInput, Image } from '../types/index.js';\n\nexport interface UploadImageInput {\n productId: string;\n file: Buffer | Readable;\n filename: string;\n altText: string;\n contentType?: string;\n sortOrder?: number;\n}\n\n/** Handles image uploads and associates them with products. */\nexport class ImageService {\n constructor(\n private readonly repo: ImageRepository,\n private readonly storage?: StorageAdapter,\n ) {}\n\n /**\n * Upload a file via the storage adapter and create an image record.\n * Requires a storage adapter to be configured.\n */\n async upload(input: UploadImageInput): Promise<Image> {\n if (!this.storage) {\n throw new Error(\n 'A storage adapter must be configured on OnlineCatalog to upload images.',\n );\n }\n\n const url = await this.storage.upload(input.file, input.filename, {\n contentType: input.contentType,\n });\n\n return this.repo.create({\n productId: input.productId,\n url,\n altText: input.altText,\n sortOrder: input.sortOrder,\n });\n }\n\n /** Associate an already-hosted image URL with a product. */\n async addUrl(input: CreateImageInput): Promise<Image> {\n return this.repo.create(input);\n }\n\n async get(id: string): Promise<Image | null> {\n return this.repo.get(id);\n }\n\n async delete(id: string): Promise<void> {\n const image = await this.repo.get(id);\n if (!image) return;\n\n if (this.storage) {\n await this.storage.delete(image.url).catch(() => {});\n }\n\n await this.repo.delete(id);\n }\n\n async listByProduct(productId: string): Promise<Image[]> {\n return this.repo.listByProduct(productId);\n }\n}\n","import type { ProductRepository, StorageAdapter } from '../interfaces/index.js';\nimport type {\n CreateProductInput,\n Product,\n ProductFilter,\n UpdateProductInput,\n} from '../types/index.js';\n\n/** High-level product operations. Wraps the DB repository with slug generation. */\nexport class ProductService {\n constructor(\n private readonly repo: ProductRepository,\n private readonly storage?: StorageAdapter,\n ) {}\n\n async create(input: CreateProductInput): Promise<Product> {\n return this.repo.create(input);\n }\n\n async get(id: string): Promise<Product | null> {\n return this.repo.get(id);\n }\n\n async update(id: string, input: UpdateProductInput): Promise<Product> {\n return this.repo.update(id, input);\n }\n\n async delete(id: string): Promise<void> {\n const product = await this.repo.get(id);\n if (!product) return;\n\n // Delete associated images from storage if available\n if (this.storage) {\n for (const image of product.images) {\n await this.storage.delete(image.url).catch(() => {});\n }\n }\n\n await this.repo.delete(id);\n }\n\n async list(filter?: ProductFilter): Promise<Product[]> {\n return this.repo.list(filter);\n }\n}\n","import { Installer } from './installer/Installer.js';\nimport type { DatabaseAdapter } from './interfaces/DatabaseAdapter.js';\nimport type { StorageAdapter } from './interfaces/StorageAdapter.js';\nimport { CategoryService } from './services/CategoryService.js';\nimport { ImageService } from './services/ImageService.js';\nimport { ProductService } from './services/ProductService.js';\n\nexport interface OnlineCatalogConfig {\n /** Database adapter for persisting catalog data. */\n db: DatabaseAdapter;\n /** Storage adapter for image/file uploads. Optional. */\n storage?: StorageAdapter;\n}\n\n/**\n * Main entry point for online-catalog-cms.\n *\n * @example\n * ```ts\n * const catalog = new OnlineCatalog({ db: new SQLiteAdapter({ filename: './catalog.db' }) });\n * await catalog.initialize();\n * const product = await catalog.products.create({ name: 'Widget', price: 999, description: ... });\n * ```\n */\nexport class OnlineCatalog {\n readonly products: ProductService;\n readonly categories: CategoryService;\n readonly images: ImageService;\n readonly installer: Installer;\n\n private readonly db: DatabaseAdapter;\n\n constructor(config: OnlineCatalogConfig) {\n this.db = config.db;\n this.products = new ProductService(config.db.products, config.storage);\n this.categories = new CategoryService(config.db.categories);\n this.images = new ImageService(config.db.images, config.storage);\n this.installer = new Installer(config.db);\n }\n\n /**\n * Initialize the catalog. Runs database migrations on first use.\n * Must be called before any other method.\n */\n async initialize(): Promise<void> {\n await this.db.initialize();\n }\n\n /** Release all resources held by the database adapter. */\n async close(): Promise<void> {\n await this.db.close();\n }\n}\n","import type { VerificationResult } from '../../../interfaces/DatabaseAdapter.js';\n\nexport interface SQLRunner {\n /** Execute a statement that returns no rows. */\n run(sql: string, params?: unknown[]): Promise<void>;\n /** Execute a query and return all rows. */\n all<T>(sql: string, params?: unknown[]): Promise<T[]>;\n /** Execute a query and return the first row, or undefined. */\n get<T>(sql: string, params?: unknown[]): Promise<T | undefined>;\n}\n\nconst REQUIRED_TABLES = [\n 'occ_category',\n 'occ_product',\n 'occ_image',\n 'occ_migration',\n] as const;\n\n/**\n * Shared logic for relational SQL adapters: migration runner and schema\n * verification. Concrete adapters extend this and supply a `SQLRunner`.\n */\nexport abstract class BaseSQLAdapter {\n protected abstract readonly db: SQLRunner;\n\n /** Dialect-specific table existence query — must return rows with a `name` column. */\n protected abstract tableExistsQuery(table: string): string;\n\n protected abstract get migrationSql(): string;\n\n async initialize(): Promise<void> {\n const migration = this.migrationSql;\n const statements = migration\n .split(';')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n for (const stmt of statements) {\n await this.db.run(stmt);\n }\n }\n\n async verify(): Promise<VerificationResult> {\n const issues: string[] = [];\n\n for (const table of REQUIRED_TABLES) {\n const row = await this.db.get<{ name: string }>(\n this.tableExistsQuery(table),\n );\n if (!row) {\n issues.push(`Missing table: ${table}`);\n }\n }\n\n return { ok: issues.length === 0, issues };\n }\n}\n","/** Convert a string to a URL-safe slug. */\nexport function generateSlug(value: string): string {\n return value\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n","import type { Category } from '../../../types/category.js';\nimport type { Image } from '../../../types/image.js';\nimport type { Product } from '../../../types/product.js';\nimport type { RichTextDocument } from '../../../types/rich-text.js';\n\nexport interface ProductRow {\n id: string;\n name: string;\n slug: string;\n description: string;\n price: number;\n sku: string | null;\n category_id: string | null;\n metadata: string;\n created_at: string | Date;\n updated_at: string | Date;\n}\n\nexport interface CategoryRow {\n id: string;\n name: string;\n slug: string;\n parent_id: string | null;\n metadata: string;\n created_at: string | Date;\n updated_at: string | Date;\n}\n\nexport interface ImageRow {\n id: string;\n product_id: string;\n url: string;\n alt_text: string;\n sort_order: number;\n created_at: string | Date;\n}\n\nfunction toDate(value: string | Date): Date {\n return value instanceof Date ? value : new Date(value);\n}\n\nexport function productFromRow(row: ProductRow, images: Image[]): Product {\n return {\n id: row.id,\n name: row.name,\n slug: row.slug,\n description: JSON.parse(row.description) as RichTextDocument,\n price: row.price,\n sku: row.sku,\n categoryId: row.category_id,\n images,\n metadata: JSON.parse(row.metadata) as Record<string, unknown>,\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at),\n };\n}\n\nexport function categoryFromRow(row: CategoryRow): Category {\n return {\n id: row.id,\n name: row.name,\n slug: row.slug,\n parentId: row.parent_id,\n metadata: JSON.parse(row.metadata) as Record<string, unknown>,\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at),\n };\n}\n\nexport function imageFromRow(row: ImageRow): Image {\n return {\n id: row.id,\n productId: row.product_id,\n url: row.url,\n altText: row.alt_text,\n sortOrder: row.sort_order,\n createdAt: toDate(row.created_at),\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport type { CategoryRepository } from '../../../interfaces/DatabaseAdapter.js';\nimport type {\n Category,\n CategoryFilter,\n CreateCategoryInput,\n UpdateCategoryInput,\n} from '../../../types/category.js';\nimport { generateSlug } from '../../../utils/slug.js';\nimport type { SQLRunner } from './BaseSQLAdapter.js';\nimport { type CategoryRow, categoryFromRow } from './rowMappers.js';\n\nexport class SQLCategoryRepository implements CategoryRepository {\n constructor(private readonly db: SQLRunner) {}\n\n async create(input: CreateCategoryInput): Promise<Category> {\n const id = randomUUID();\n const now = new Date().toISOString();\n const slug = input.slug ?? generateSlug(input.name);\n\n await this.db.run(\n `INSERT INTO occ_category (id, name, slug, parent_id, metadata, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n input.name,\n slug,\n input.parentId ?? null,\n JSON.stringify(input.metadata ?? {}),\n now,\n now,\n ],\n );\n\n const category = await this.get(id);\n if (!category)\n throw new Error(`Failed to fetch category after insert: ${id}`);\n return category;\n }\n\n async get(id: string): Promise<Category | null> {\n const row = await this.db.get<CategoryRow>(\n 'SELECT * FROM occ_category WHERE id = ?',\n [id],\n );\n return row ? categoryFromRow(row) : null;\n }\n\n async update(id: string, input: UpdateCategoryInput): Promise<Category> {\n const existing = await this.get(id);\n if (!existing) throw new Error(`Category not found: ${id}`);\n\n const now = new Date().toISOString();\n await this.db.run(\n `UPDATE occ_category SET\n name = ?,\n slug = ?,\n parent_id = ?,\n metadata = ?,\n updated_at = ?\n WHERE id = ?`,\n [\n input.name ?? existing.name,\n input.slug ?? existing.slug,\n input.parentId !== undefined ? input.parentId : existing.parentId,\n JSON.stringify(input.metadata ?? existing.metadata),\n now,\n id,\n ],\n );\n\n const updated = await this.get(id);\n if (!updated)\n throw new Error(`Failed to fetch category after update: ${id}`);\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n await this.db.run('DELETE FROM occ_category WHERE id = ?', [id]);\n }\n\n async list(filter: CategoryFilter = {}): Promise<Category[]> {\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter.parentId !== undefined) {\n if (filter.parentId === null) {\n conditions.push('parent_id IS NULL');\n } else {\n conditions.push('parent_id = ?');\n params.push(filter.parentId);\n }\n }\n if (filter.search) {\n conditions.push('name LIKE ?');\n params.push(`%${filter.search}%`);\n }\n\n const where =\n conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const limit = filter.limit !== undefined ? `LIMIT ${filter.limit}` : '';\n const offset = filter.offset !== undefined ? `OFFSET ${filter.offset}` : '';\n\n const rows = await this.db.all<CategoryRow>(\n `SELECT * FROM occ_category ${where} ORDER BY name ASC ${limit} ${offset}`,\n params,\n );\n\n return rows.map(categoryFromRow);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { ImageRepository } from '../../../interfaces/DatabaseAdapter.js';\nimport type { CreateImageInput, Image } from '../../../types/image.js';\nimport type { SQLRunner } from './BaseSQLAdapter.js';\nimport { type ImageRow, imageFromRow } from './rowMappers.js';\n\nexport class SQLImageRepository implements ImageRepository {\n constructor(private readonly db: SQLRunner) {}\n\n async create(input: CreateImageInput): Promise<Image> {\n const id = randomUUID();\n const now = new Date().toISOString();\n const sortOrder = input.sortOrder ?? 0;\n\n await this.db.run(\n `INSERT INTO occ_image (id, product_id, url, alt_text, sort_order, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`,\n [id, input.productId, input.url, input.altText, sortOrder, now],\n );\n\n const image = await this.get(id);\n if (!image) throw new Error(`Failed to fetch image after insert: ${id}`);\n return image;\n }\n\n async get(id: string): Promise<Image | null> {\n const row = await this.db.get<ImageRow>(\n 'SELECT * FROM occ_image WHERE id = ?',\n [id],\n );\n return row ? imageFromRow(row) : null;\n }\n\n async delete(id: string): Promise<void> {\n await this.db.run('DELETE FROM occ_image WHERE id = ?', [id]);\n }\n\n async listByProduct(productId: string): Promise<Image[]> {\n const rows = await this.db.all<ImageRow>(\n 'SELECT * FROM occ_image WHERE product_id = ? ORDER BY sort_order ASC',\n [productId],\n );\n return rows.map(imageFromRow);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { ProductRepository } from '../../../interfaces/DatabaseAdapter.js';\nimport type {\n CreateProductInput,\n Product,\n ProductFilter,\n UpdateProductInput,\n} from '../../../types/product.js';\nimport { generateSlug } from '../../../utils/slug.js';\nimport type { SQLRunner } from './BaseSQLAdapter.js';\nimport {\n type ImageRow,\n type ProductRow,\n imageFromRow,\n productFromRow,\n} from './rowMappers.js';\n\nexport class SQLProductRepository implements ProductRepository {\n constructor(private readonly db: SQLRunner) {}\n\n async create(input: CreateProductInput): Promise<Product> {\n const id = randomUUID();\n const now = new Date().toISOString();\n const slug = input.slug ?? generateSlug(input.name);\n\n await this.db.run(\n `INSERT INTO occ_product\n (id, name, slug, description, price, sku, category_id, metadata, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n id,\n input.name,\n slug,\n JSON.stringify(input.description),\n input.price,\n input.sku ?? null,\n input.categoryId ?? null,\n JSON.stringify(input.metadata ?? {}),\n now,\n now,\n ],\n );\n\n const product = await this.get(id);\n if (!product)\n throw new Error(`Failed to fetch product after insert: ${id}`);\n return product;\n }\n\n async get(id: string): Promise<Product | null> {\n const row = await this.db.get<ProductRow>(\n 'SELECT * FROM occ_product WHERE id = ?',\n [id],\n );\n if (!row) return null;\n\n const imageRows = await this.db.all<ImageRow>(\n 'SELECT * FROM occ_image WHERE product_id = ? ORDER BY sort_order ASC',\n [id],\n );\n return productFromRow(row, imageRows.map(imageFromRow));\n }\n\n async update(id: string, input: UpdateProductInput): Promise<Product> {\n const existing = await this.get(id);\n if (!existing) throw new Error(`Product not found: ${id}`);\n\n const now = new Date().toISOString();\n await this.db.run(\n `UPDATE occ_product SET\n name = ?,\n slug = ?,\n description = ?,\n price = ?,\n sku = ?,\n category_id = ?,\n metadata = ?,\n updated_at = ?\n WHERE id = ?`,\n [\n input.name ?? existing.name,\n input.slug ?? existing.slug,\n JSON.stringify(input.description ?? existing.description),\n input.price ?? existing.price,\n input.sku !== undefined ? input.sku : existing.sku,\n input.categoryId !== undefined ? input.categoryId : existing.categoryId,\n JSON.stringify(input.metadata ?? existing.metadata),\n now,\n id,\n ],\n );\n\n const updated = await this.get(id);\n if (!updated)\n throw new Error(`Failed to fetch product after update: ${id}`);\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n await this.db.run('DELETE FROM occ_product WHERE id = ?', [id]);\n }\n\n async list(filter: ProductFilter = {}): Promise<Product[]> {\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter.categoryId !== undefined) {\n conditions.push('category_id = ?');\n params.push(filter.categoryId);\n }\n if (filter.search) {\n conditions.push('(name LIKE ? OR sku LIKE ?)');\n params.push(`%${filter.search}%`, `%${filter.search}%`);\n }\n if (filter.minPrice !== undefined) {\n conditions.push('price >= ?');\n params.push(filter.minPrice);\n }\n if (filter.maxPrice !== undefined) {\n conditions.push('price <= ?');\n params.push(filter.maxPrice);\n }\n\n const where =\n conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const limit = filter.limit !== undefined ? `LIMIT ${filter.limit}` : '';\n const offset = filter.offset !== undefined ? `OFFSET ${filter.offset}` : '';\n\n const rows = await this.db.all<ProductRow>(\n `SELECT * FROM occ_product ${where} ORDER BY created_at DESC ${limit} ${offset}`,\n params,\n );\n\n const products: Product[] = [];\n for (const row of rows) {\n const imageRows = await this.db.all<ImageRow>(\n 'SELECT * FROM occ_image WHERE product_id = ? ORDER BY sort_order ASC',\n [row.id],\n );\n products.push(productFromRow(row, imageRows.map(imageFromRow)));\n }\n return products;\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type {\n CategoryRepository,\n DatabaseAdapter,\n ImageRepository,\n ProductRepository,\n VerificationResult,\n} from '../../../interfaces/DatabaseAdapter.js';\nimport {\n BaseSQLAdapter,\n type SQLRunner,\n} from '../relational/BaseSQLAdapter.js';\nimport { SQLCategoryRepository } from '../relational/SQLCategoryRepository.js';\nimport { SQLImageRepository } from '../relational/SQLImageRepository.js';\nimport { SQLProductRepository } from '../relational/SQLProductRepository.js';\n\nexport interface SQLiteConfig {\n /** Path to the SQLite database file. Use ':memory:' for an in-memory DB. */\n filename: string;\n}\n\n// ── Bun:sqlite runner ────────────────────────────────────────────────────────\n\nclass BunSQLiteRunner implements SQLRunner {\n // biome-ignore lint/suspicious/noExplicitAny: bun:sqlite Database type\n constructor(private readonly db: any) {}\n\n async run(sql: string, params: unknown[] = []): Promise<void> {\n this.db.run(sql, params);\n }\n\n async all<T>(sql: string, params: unknown[] = []): Promise<T[]> {\n return this.db.query(sql).all(...params) as T[];\n }\n\n async get<T>(sql: string, params: unknown[] = []): Promise<T | undefined> {\n return this.db.query(sql).get(...params) as T | undefined;\n }\n}\n\n// ── better-sqlite3 runner ────────────────────────────────────────────────────\n\nclass BetterSqliteRunner implements SQLRunner {\n // biome-ignore lint/suspicious/noExplicitAny: better-sqlite3 Database type\n constructor(private readonly db: any) {}\n\n async run(sql: string, params: unknown[] = []): Promise<void> {\n this.db.prepare(sql).run(...params);\n }\n\n async all<T>(sql: string, params: unknown[] = []): Promise<T[]> {\n return this.db.prepare(sql).all(...params) as T[];\n }\n\n async get<T>(sql: string, params: unknown[] = []): Promise<T | undefined> {\n return this.db.prepare(sql).get(...params) as T | undefined;\n }\n}\n\n// ── Factory: pick the available driver ───────────────────────────────────────\n\ninterface SQLiteInstance {\n runner: SQLRunner;\n // biome-ignore lint/suspicious/noExplicitAny: driver-specific handle\n instance: any;\n close(): void;\n}\n\nasync function createSQLiteInstance(filename: string): Promise<SQLiteInstance> {\n // Try bun:sqlite first (zero-dependency in Bun runtime)\n try {\n const { Database } = await import('bun:sqlite');\n const db = new Database(filename);\n db.exec('PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;');\n return {\n runner: new BunSQLiteRunner(db),\n instance: db,\n close: () => db.close(),\n };\n } catch {\n // Fall back to better-sqlite3 (Node.js environments)\n }\n\n try {\n const { createRequire } = await import('node:module');\n const require = createRequire(import.meta.url);\n // biome-ignore lint/suspicious/noExplicitAny: dynamic require\n const Database = require('better-sqlite3') as any;\n const db = new Database(filename);\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n return {\n runner: new BetterSqliteRunner(db),\n instance: db,\n close: () => db.close(),\n };\n } catch {\n throw new Error(\n 'No SQLite driver found. In Bun environments, bun:sqlite is built-in. ' +\n 'In Node.js environments, run: bun add better-sqlite3',\n );\n }\n}\n\n// ── Adapter ──────────────────────────────────────────────────────────────────\n\nconst __dirname = fileURLToPath(new URL('.', import.meta.url));\nconst MIGRATION_PATH = join(\n __dirname,\n '../relational/migrations/001_initial.sql',\n);\n\n/** SQLite database adapter. Uses bun:sqlite in Bun, better-sqlite3 in Node.js. */\nexport class SQLiteAdapter extends BaseSQLAdapter implements DatabaseAdapter {\n private runner?: SQLRunner;\n private closeHandle?: () => void;\n private readonly config: SQLiteConfig;\n\n private _products?: ProductRepository;\n private _categories?: CategoryRepository;\n private _images?: ImageRepository;\n\n constructor(config: SQLiteConfig) {\n super();\n this.config = config;\n }\n\n protected get db(): SQLRunner {\n if (!this.runner) throw new Error('Call initialize() first');\n return this.runner;\n }\n\n get products(): ProductRepository {\n if (!this._products) throw new Error('Call initialize() first');\n return this._products;\n }\n\n get categories(): CategoryRepository {\n if (!this._categories) throw new Error('Call initialize() first');\n return this._categories;\n }\n\n get images(): ImageRepository {\n if (!this._images) throw new Error('Call initialize() first');\n return this._images;\n }\n\n /** Must be called before any other method. Sets up the SQLite driver. */\n override async initialize(): Promise<void> {\n const { runner, close } = await createSQLiteInstance(this.config.filename);\n this.runner = runner;\n this._products = new SQLProductRepository(runner);\n this._categories = new SQLCategoryRepository(runner);\n this._images = new SQLImageRepository(runner);\n this.closeHandle = close;\n\n await super.initialize();\n }\n\n protected get migrationSql(): string {\n return readFileSync(MIGRATION_PATH, 'utf8');\n }\n\n protected tableExistsQuery(table: string): string {\n return `SELECT name FROM sqlite_master WHERE type='table' AND name='${table}'`;\n }\n\n override async verify(): Promise<VerificationResult> {\n return super.verify();\n }\n\n async close(): Promise<void> {\n this.closeHandle?.();\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type {\n CategoryRepository,\n DatabaseAdapter,\n ImageRepository,\n ProductRepository,\n VerificationResult,\n} from '../../../interfaces/DatabaseAdapter.js';\nimport {\n BaseSQLAdapter,\n type SQLRunner,\n} from '../relational/BaseSQLAdapter.js';\nimport { SQLCategoryRepository } from '../relational/SQLCategoryRepository.js';\nimport { SQLImageRepository } from '../relational/SQLImageRepository.js';\nimport { SQLProductRepository } from '../relational/SQLProductRepository.js';\n\nexport interface PostgresConfig {\n /** postgres.js connection string or config object. */\n url: string;\n}\n\ntype Sql = import('postgres').Sql;\n\nfunction loadDriver(): (url: string) => Sql {\n try {\n const require = createRequire(import.meta.url);\n // postgres.js exports the connection factory as default\n // biome-ignore lint/suspicious/noExplicitAny: dynamic require\n const mod = require('postgres') as any;\n return mod.default ?? mod;\n } catch {\n throw new Error('postgres is not installed. Run: bun add postgres');\n }\n}\n\nclass PostgresSQLRunner implements SQLRunner {\n constructor(private readonly sql: Sql) {}\n\n async run(query: string, params: unknown[] = []): Promise<void> {\n await this.sql.unsafe(query, params as never[]);\n }\n\n async all<T>(query: string, params: unknown[] = []): Promise<T[]> {\n const rows = await this.sql.unsafe(query, params as never[]);\n return rows as unknown as T[];\n }\n\n async get<T>(query: string, params: unknown[] = []): Promise<T | undefined> {\n const rows = await this.sql.unsafe(query, params as never[]);\n return (rows as unknown as T[])[0];\n }\n}\n\nconst __dirname = fileURLToPath(new URL('.', import.meta.url));\nconst MIGRATION_PATH = join(\n __dirname,\n '../relational/migrations/001_initial.sql',\n);\n\n/** PostgreSQL database adapter using postgres.js. */\nexport class PostgresAdapter extends BaseSQLAdapter implements DatabaseAdapter {\n protected readonly db: SQLRunner;\n readonly products: ProductRepository;\n readonly categories: CategoryRepository;\n readonly images: ImageRepository;\n\n private readonly sql: Sql;\n\n constructor(config: PostgresConfig) {\n super();\n const connect = loadDriver();\n this.sql = connect(config.url);\n const runner = new PostgresSQLRunner(this.sql);\n this.db = runner;\n this.products = new SQLProductRepository(runner);\n this.categories = new SQLCategoryRepository(runner);\n this.images = new SQLImageRepository(runner);\n }\n\n protected get migrationSql(): string {\n return readFileSync(MIGRATION_PATH, 'utf8');\n }\n\n protected tableExistsQuery(table: string): string {\n return `SELECT table_name AS name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = '${table}'`;\n }\n\n override async verify(): Promise<VerificationResult> {\n return super.verify();\n }\n\n async close(): Promise<void> {\n await this.sql.end();\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type {\n CategoryRepository,\n DatabaseAdapter,\n ImageRepository,\n ProductRepository,\n VerificationResult,\n} from '../../../interfaces/DatabaseAdapter.js';\nimport {\n BaseSQLAdapter,\n type SQLRunner,\n} from '../relational/BaseSQLAdapter.js';\nimport { SQLCategoryRepository } from '../relational/SQLCategoryRepository.js';\nimport { SQLImageRepository } from '../relational/SQLImageRepository.js';\nimport { SQLProductRepository } from '../relational/SQLProductRepository.js';\n\nexport interface MySQLConfig {\n host: string;\n port?: number;\n user: string;\n password: string;\n database: string;\n}\n\ntype Pool = import('mysql2/promise').Pool;\n\nfunction loadDriver(): { createPool: (config: MySQLConfig) => Pool } {\n try {\n const require = createRequire(import.meta.url);\n return require('mysql2/promise') as {\n createPool: (config: MySQLConfig) => Pool;\n };\n } catch {\n throw new Error('mysql2 is not installed. Run: bun add mysql2');\n }\n}\n\nclass MySQLSQLRunner implements SQLRunner {\n constructor(private readonly pool: Pool) {}\n\n // mysql2 types require `ExecuteValues` (any[]), so we cast here.\n async run(query: string, params: unknown[] = []): Promise<void> {\n // biome-ignore lint/suspicious/noExplicitAny: mysql2 ExecuteValues\n await this.pool.execute(query, params as any[]);\n }\n\n async all<T>(query: string, params: unknown[] = []): Promise<T[]> {\n // biome-ignore lint/suspicious/noExplicitAny: mysql2 ExecuteValues\n const [rows] = await this.pool.execute(query, params as any[]);\n return rows as T[];\n }\n\n async get<T>(query: string, params: unknown[] = []): Promise<T | undefined> {\n // biome-ignore lint/suspicious/noExplicitAny: mysql2 ExecuteValues\n const [rows] = await this.pool.execute(query, params as any[]);\n return (rows as T[])[0];\n }\n}\n\nconst __dirname = fileURLToPath(new URL('.', import.meta.url));\nconst MIGRATION_PATH = join(\n __dirname,\n '../relational/migrations/001_initial.sql',\n);\n\n/** MySQL / MariaDB adapter using mysql2. */\nexport class MySQLAdapter extends BaseSQLAdapter implements DatabaseAdapter {\n protected readonly db: SQLRunner;\n readonly products: ProductRepository;\n readonly categories: CategoryRepository;\n readonly images: ImageRepository;\n\n private readonly pool: Pool;\n\n constructor(config: MySQLConfig) {\n super();\n const { createPool } = loadDriver();\n this.pool = createPool(config);\n const runner = new MySQLSQLRunner(this.pool);\n this.db = runner;\n this.products = new SQLProductRepository(runner);\n this.categories = new SQLCategoryRepository(runner);\n this.images = new SQLImageRepository(runner);\n }\n\n protected get migrationSql(): string {\n // MySQL uses backtick quoting and doesn't support ON CONFLICT — adjust.\n return readFileSync(MIGRATION_PATH, 'utf8').replace(\n /ON CONFLICT \\(version\\) DO NOTHING/g,\n '',\n );\n }\n\n protected tableExistsQuery(table: string): string {\n return `SELECT table_name AS name FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = '${table}'`;\n }\n\n override async verify(): Promise<VerificationResult> {\n return super.verify();\n }\n\n async close(): Promise<void> {\n await this.pool.end();\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { createRequire } from 'node:module';\nimport type {\n CategoryRepository,\n DatabaseAdapter,\n ImageRepository,\n ProductRepository,\n VerificationResult,\n} from '../../../interfaces/DatabaseAdapter.js';\nimport type {\n Category,\n CategoryFilter,\n CreateCategoryInput,\n UpdateCategoryInput,\n} from '../../../types/category.js';\nimport type { CreateImageInput, Image } from '../../../types/image.js';\nimport type {\n CreateProductInput,\n Product,\n ProductFilter,\n UpdateProductInput,\n} from '../../../types/product.js';\nimport { generateSlug } from '../../../utils/slug.js';\n\nexport interface RedisConfig {\n /** ioredis connection URL, e.g. 'redis://localhost:6379'. */\n url: string;\n /** Optional key prefix to namespace all catalog keys. Defaults to 'occ'. */\n keyPrefix?: string;\n}\n\ntype Redis = import('ioredis').Redis;\ntype RedisConstructor = new (url: string) => Redis;\n\nfunction loadDriver(): RedisConstructor {\n try {\n const require = createRequire(import.meta.url);\n // biome-ignore lint/suspicious/noExplicitAny: dynamic require\n const mod = require('ioredis') as any;\n return (mod.default ?? mod) as RedisConstructor;\n } catch {\n throw new Error('ioredis is not installed. Run: bun add ioredis');\n }\n}\n\n/**\n * Redis adapter. Data is stored as JSON strings in Redis hashes.\n *\n * Key layout:\n * {prefix}:product:{id} — product JSON\n * {prefix}:products:all — set of all product IDs\n * {prefix}:products:cat:{catId} — set of product IDs by category\n * {prefix}:category:{id} — category JSON\n * {prefix}:categories:all — set of all category IDs\n * {prefix}:image:{id} — image JSON\n * {prefix}:images:product:{pid} — sorted set of image IDs by sort_order\n */\nexport class RedisAdapter implements DatabaseAdapter {\n private readonly client: Redis;\n private readonly prefix: string;\n\n readonly products: ProductRepository;\n readonly categories: CategoryRepository;\n readonly images: ImageRepository;\n\n constructor(config: RedisConfig) {\n const RedisClass = loadDriver();\n this.client = new RedisClass(config.url);\n this.prefix = config.keyPrefix ?? 'occ';\n\n this.products = new RedisProductRepository(this.client, this.prefix);\n this.categories = new RedisCategoryRepository(this.client, this.prefix);\n this.images = new RedisImageRepository(this.client, this.prefix);\n }\n\n async initialize(): Promise<void> {\n await this.client.ping();\n }\n\n async verify(): Promise<VerificationResult> {\n try {\n await this.client.ping();\n return { ok: true, issues: [] };\n } catch (err) {\n return {\n ok: false,\n issues: [`Redis connection failed: ${String(err)}`],\n };\n }\n }\n\n async close(): Promise<void> {\n await this.client.quit();\n }\n}\n\nclass RedisProductRepository implements ProductRepository {\n constructor(\n private readonly client: Redis,\n private readonly prefix: string,\n ) {}\n\n private key(id: string) {\n return `${this.prefix}:product:${id}`;\n }\n\n async create(input: CreateProductInput): Promise<Product> {\n const id = randomUUID();\n const now = new Date().toISOString();\n const product: Product = {\n id,\n name: input.name,\n slug: input.slug ?? generateSlug(input.name),\n description: input.description,\n price: input.price,\n sku: input.sku ?? null,\n categoryId: input.categoryId ?? null,\n images: [],\n metadata: input.metadata ?? {},\n createdAt: new Date(now),\n updatedAt: new Date(now),\n };\n\n await this.client.set(this.key(id), JSON.stringify(product));\n await this.client.sadd(`${this.prefix}:products:all`, id);\n if (product.categoryId) {\n await this.client.sadd(\n `${this.prefix}:products:cat:${product.categoryId}`,\n id,\n );\n }\n return product;\n }\n\n async get(id: string): Promise<Product | null> {\n const raw = await this.client.get(this.key(id));\n if (!raw) return null;\n const product = JSON.parse(raw) as Product;\n product.createdAt = new Date(product.createdAt);\n product.updatedAt = new Date(product.updatedAt);\n return product;\n }\n\n async update(id: string, input: UpdateProductInput): Promise<Product> {\n const existing = await this.get(id);\n if (!existing) throw new Error(`Product not found: ${id}`);\n\n const oldCategoryId = existing.categoryId;\n const now = new Date().toISOString();\n\n const updated: Product = {\n ...existing,\n name: input.name ?? existing.name,\n slug: input.slug ?? existing.slug,\n description: input.description ?? existing.description,\n price: input.price ?? existing.price,\n sku: input.sku !== undefined ? input.sku : existing.sku,\n categoryId:\n input.categoryId !== undefined ? input.categoryId : existing.categoryId,\n metadata: input.metadata ?? existing.metadata,\n updatedAt: new Date(now),\n };\n\n await this.client.set(this.key(id), JSON.stringify(updated));\n\n if (oldCategoryId !== updated.categoryId) {\n if (oldCategoryId) {\n await this.client.srem(\n `${this.prefix}:products:cat:${oldCategoryId}`,\n id,\n );\n }\n if (updated.categoryId) {\n await this.client.sadd(\n `${this.prefix}:products:cat:${updated.categoryId}`,\n id,\n );\n }\n }\n\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n const existing = await this.get(id);\n await this.client.del(this.key(id));\n await this.client.srem(`${this.prefix}:products:all`, id);\n if (existing?.categoryId) {\n await this.client.srem(\n `${this.prefix}:products:cat:${existing.categoryId}`,\n id,\n );\n }\n }\n\n async list(filter: ProductFilter = {}): Promise<Product[]> {\n let ids: string[];\n\n if (filter.categoryId !== undefined) {\n ids = await this.client.smembers(\n `${this.prefix}:products:cat:${filter.categoryId}`,\n );\n } else {\n ids = await this.client.smembers(`${this.prefix}:products:all`);\n }\n\n const products: Product[] = [];\n for (const id of ids) {\n const product = await this.get(id);\n if (!product) continue;\n\n if (\n filter.search &&\n !product.name.toLowerCase().includes(filter.search.toLowerCase())\n )\n continue;\n if (filter.minPrice !== undefined && product.price < filter.minPrice)\n continue;\n if (filter.maxPrice !== undefined && product.price > filter.maxPrice)\n continue;\n\n products.push(product);\n }\n\n products.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n\n const start = filter.offset ?? 0;\n const end = filter.limit !== undefined ? start + filter.limit : undefined;\n return products.slice(start, end);\n }\n}\n\nclass RedisCategoryRepository implements CategoryRepository {\n constructor(\n private readonly client: Redis,\n private readonly prefix: string,\n ) {}\n\n private key(id: string) {\n return `${this.prefix}:category:${id}`;\n }\n\n async create(input: CreateCategoryInput): Promise<Category> {\n const id = randomUUID();\n const now = new Date().toISOString();\n const category: Category = {\n id,\n name: input.name,\n slug: input.slug ?? generateSlug(input.name),\n parentId: input.parentId ?? null,\n metadata: input.metadata ?? {},\n createdAt: new Date(now),\n updatedAt: new Date(now),\n };\n\n await this.client.set(this.key(id), JSON.stringify(category));\n await this.client.sadd(`${this.prefix}:categories:all`, id);\n return category;\n }\n\n async get(id: string): Promise<Category | null> {\n const raw = await this.client.get(this.key(id));\n if (!raw) return null;\n const category = JSON.parse(raw) as Category;\n category.createdAt = new Date(category.createdAt);\n category.updatedAt = new Date(category.updatedAt);\n return category;\n }\n\n async update(id: string, input: UpdateCategoryInput): Promise<Category> {\n const existing = await this.get(id);\n if (!existing) throw new Error(`Category not found: ${id}`);\n\n const now = new Date().toISOString();\n const updated: Category = {\n ...existing,\n name: input.name ?? existing.name,\n slug: input.slug ?? existing.slug,\n parentId:\n input.parentId !== undefined ? input.parentId : existing.parentId,\n metadata: input.metadata ?? existing.metadata,\n updatedAt: new Date(now),\n };\n\n await this.client.set(this.key(id), JSON.stringify(updated));\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n await this.client.del(this.key(id));\n await this.client.srem(`${this.prefix}:categories:all`, id);\n }\n\n async list(filter: CategoryFilter = {}): Promise<Category[]> {\n const ids = await this.client.smembers(`${this.prefix}:categories:all`);\n const categories: Category[] = [];\n\n for (const id of ids) {\n const category = await this.get(id);\n if (!category) continue;\n\n if (filter.parentId !== undefined) {\n if (category.parentId !== filter.parentId) continue;\n }\n if (\n filter.search &&\n !category.name.toLowerCase().includes(filter.search.toLowerCase())\n )\n continue;\n\n categories.push(category);\n }\n\n categories.sort((a, b) => a.name.localeCompare(b.name));\n\n const start = filter.offset ?? 0;\n const end = filter.limit !== undefined ? start + filter.limit : undefined;\n return categories.slice(start, end);\n }\n}\n\nclass RedisImageRepository implements ImageRepository {\n constructor(\n private readonly client: Redis,\n private readonly prefix: string,\n ) {}\n\n private key(id: string) {\n return `${this.prefix}:image:${id}`;\n }\n\n async create(input: CreateImageInput): Promise<Image> {\n const id = randomUUID();\n const now = new Date().toISOString();\n const image: Image = {\n id,\n productId: input.productId,\n url: input.url,\n altText: input.altText,\n sortOrder: input.sortOrder ?? 0,\n createdAt: new Date(now),\n };\n\n await this.client.set(this.key(id), JSON.stringify(image));\n await this.client.zadd(\n `${this.prefix}:images:product:${input.productId}`,\n image.sortOrder,\n id,\n );\n return image;\n }\n\n async get(id: string): Promise<Image | null> {\n const raw = await this.client.get(this.key(id));\n if (!raw) return null;\n const image = JSON.parse(raw) as Image;\n image.createdAt = new Date(image.createdAt);\n return image;\n }\n\n async delete(id: string): Promise<void> {\n const image = await this.get(id);\n await this.client.del(this.key(id));\n if (image) {\n await this.client.zrem(\n `${this.prefix}:images:product:${image.productId}`,\n id,\n );\n }\n }\n\n async listByProduct(productId: string): Promise<Image[]> {\n const ids = await this.client.zrange(\n `${this.prefix}:images:product:${productId}`,\n 0,\n -1,\n );\n const images: Image[] = [];\n for (const id of ids) {\n const image = await this.get(id);\n if (image) images.push(image);\n }\n return images;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { createRequire } from 'node:module';\nimport type {\n CategoryRepository,\n DatabaseAdapter,\n ImageRepository,\n ProductRepository,\n VerificationResult,\n} from '../../../interfaces/DatabaseAdapter.js';\nimport type {\n Category,\n CategoryFilter,\n CreateCategoryInput,\n UpdateCategoryInput,\n} from '../../../types/category.js';\nimport type { CreateImageInput, Image } from '../../../types/image.js';\nimport type {\n CreateProductInput,\n Product,\n ProductFilter,\n UpdateProductInput,\n} from '../../../types/product.js';\nimport { generateSlug } from '../../../utils/slug.js';\n\nexport interface MongoDBConfig {\n /** MongoDB connection string, e.g. 'mongodb://localhost:27017'. */\n url: string;\n /** Database name. Defaults to 'online_catalog'. */\n database?: string;\n}\n\ntype MongoClient = import('mongodb').MongoClient;\ntype Db = import('mongodb').Db;\ntype Collection<T extends object> = import('mongodb').Collection<T>;\ntype MongoClientConstructor = new (url: string) => MongoClient;\n\nfunction loadDriver(): MongoClientConstructor {\n try {\n const require = createRequire(import.meta.url);\n const { MongoClient } = require('mongodb') as {\n MongoClient: MongoClientConstructor;\n };\n return MongoClient;\n } catch {\n throw new Error('mongodb is not installed. Run: bun add mongodb');\n }\n}\n\ninterface ProductDoc {\n _id: string;\n name: string;\n slug: string;\n description: unknown;\n price: number;\n sku: string | null;\n categoryId: string | null;\n metadata: Record<string, unknown>;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface CategoryDoc {\n _id: string;\n name: string;\n slug: string;\n parentId: string | null;\n metadata: Record<string, unknown>;\n createdAt: Date;\n updatedAt: Date;\n}\n\ninterface ImageDoc {\n _id: string;\n productId: string;\n url: string;\n altText: string;\n sortOrder: number;\n createdAt: Date;\n}\n\n/** MongoDB adapter. Each entity type maps to its own collection. */\nexport class MongoDBAdapter implements DatabaseAdapter {\n private readonly client: MongoClient;\n private readonly dbName: string;\n\n readonly products: ProductRepository;\n readonly categories: CategoryRepository;\n readonly images: ImageRepository;\n\n constructor(config: MongoDBConfig) {\n const MongoClient = loadDriver();\n this.client = new MongoClient(config.url);\n this.dbName = config.database ?? 'online_catalog';\n\n const db = () => this.client.db(this.dbName);\n this.products = new MongoProductRepository(db);\n this.categories = new MongoCategoryRepository(db);\n this.images = new MongoImageRepository(db);\n }\n\n async initialize(): Promise<void> {\n await this.client.connect();\n const db = this.client.db(this.dbName);\n await db\n .collection('occ_product')\n .createIndex({ slug: 1 }, { unique: true });\n await db.collection('occ_product').createIndex({ categoryId: 1 });\n await db\n .collection('occ_category')\n .createIndex({ slug: 1 }, { unique: true });\n await db\n .collection('occ_image')\n .createIndex({ productId: 1, sortOrder: 1 });\n }\n\n async verify(): Promise<VerificationResult> {\n try {\n await this.client.db(this.dbName).command({ ping: 1 });\n return { ok: true, issues: [] };\n } catch (err) {\n return {\n ok: false,\n issues: [`MongoDB connection failed: ${String(err)}`],\n };\n }\n }\n\n async close(): Promise<void> {\n await this.client.close();\n }\n}\n\nclass MongoProductRepository implements ProductRepository {\n constructor(private readonly db: () => Db) {}\n\n private col(): Collection<ProductDoc> {\n return this.db().collection<ProductDoc>('occ_product');\n }\n\n private imgCol(): Collection<ImageDoc> {\n return this.db().collection<ImageDoc>('occ_image');\n }\n\n private async toProduct(doc: ProductDoc): Promise<Product> {\n const images = await this.imgCol()\n .find({ productId: doc._id })\n .sort({ sortOrder: 1 })\n .toArray();\n\n return {\n id: doc._id,\n name: doc.name,\n slug: doc.slug,\n description: doc.description as Product['description'],\n price: doc.price,\n sku: doc.sku,\n categoryId: doc.categoryId,\n images: images.map((img) => ({\n id: img._id,\n productId: img.productId,\n url: img.url,\n altText: img.altText,\n sortOrder: img.sortOrder,\n createdAt: img.createdAt,\n })),\n metadata: doc.metadata,\n createdAt: doc.createdAt,\n updatedAt: doc.updatedAt,\n };\n }\n\n async create(input: CreateProductInput): Promise<Product> {\n const id = randomUUID();\n const now = new Date();\n const doc: ProductDoc = {\n _id: id,\n name: input.name,\n slug: input.slug ?? generateSlug(input.name),\n description: input.description,\n price: input.price,\n sku: input.sku ?? null,\n categoryId: input.categoryId ?? null,\n metadata: input.metadata ?? {},\n createdAt: now,\n updatedAt: now,\n };\n await this.col().insertOne(doc);\n return this.toProduct(doc);\n }\n\n async get(id: string): Promise<Product | null> {\n const doc = await this.col().findOne({ _id: id });\n if (!doc) return null;\n return this.toProduct(doc);\n }\n\n async update(id: string, input: UpdateProductInput): Promise<Product> {\n const existing = await this.get(id);\n if (!existing) throw new Error(`Product not found: ${id}`);\n\n const now = new Date();\n await this.col().updateOne(\n { _id: id },\n {\n $set: {\n name: input.name ?? existing.name,\n slug: input.slug ?? existing.slug,\n description: input.description ?? existing.description,\n price: input.price ?? existing.price,\n sku: input.sku !== undefined ? input.sku : existing.sku,\n categoryId:\n input.categoryId !== undefined\n ? input.categoryId\n : existing.categoryId,\n metadata: input.metadata ?? existing.metadata,\n updatedAt: now,\n },\n },\n );\n\n const updated = await this.get(id);\n if (!updated)\n throw new Error(`Failed to fetch product after update: ${id}`);\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n await this.col().deleteOne({ _id: id });\n }\n\n async list(filter: ProductFilter = {}): Promise<Product[]> {\n // biome-ignore lint/suspicious/noExplicitAny: mongo filter type\n const query: any = {};\n if (filter.categoryId !== undefined) query.categoryId = filter.categoryId;\n if (filter.minPrice !== undefined || filter.maxPrice !== undefined) {\n query.price = {};\n if (filter.minPrice !== undefined) query.price.$gte = filter.minPrice;\n if (filter.maxPrice !== undefined) query.price.$lte = filter.maxPrice;\n }\n if (filter.search) {\n query.$or = [\n { name: { $regex: filter.search, $options: 'i' } },\n { sku: { $regex: filter.search, $options: 'i' } },\n ];\n }\n\n let cursor = this.col().find(query).sort({ createdAt: -1 });\n if (filter.offset) cursor = cursor.skip(filter.offset);\n if (filter.limit) cursor = cursor.limit(filter.limit);\n\n const docs = await cursor.toArray();\n return Promise.all(docs.map((doc) => this.toProduct(doc)));\n }\n}\n\nclass MongoCategoryRepository implements CategoryRepository {\n constructor(private readonly db: () => Db) {}\n\n private col(): Collection<CategoryDoc> {\n return this.db().collection<CategoryDoc>('occ_category');\n }\n\n private toCategory(doc: CategoryDoc): Category {\n return {\n id: doc._id,\n name: doc.name,\n slug: doc.slug,\n parentId: doc.parentId,\n metadata: doc.metadata,\n createdAt: doc.createdAt,\n updatedAt: doc.updatedAt,\n };\n }\n\n async create(input: CreateCategoryInput): Promise<Category> {\n const id = randomUUID();\n const now = new Date();\n const doc: CategoryDoc = {\n _id: id,\n name: input.name,\n slug: input.slug ?? generateSlug(input.name),\n parentId: input.parentId ?? null,\n metadata: input.metadata ?? {},\n createdAt: now,\n updatedAt: now,\n };\n await this.col().insertOne(doc);\n return this.toCategory(doc);\n }\n\n async get(id: string): Promise<Category | null> {\n const doc = await this.col().findOne({ _id: id });\n return doc ? this.toCategory(doc) : null;\n }\n\n async update(id: string, input: UpdateCategoryInput): Promise<Category> {\n const existing = await this.get(id);\n if (!existing) throw new Error(`Category not found: ${id}`);\n\n const now = new Date();\n await this.col().updateOne(\n { _id: id },\n {\n $set: {\n name: input.name ?? existing.name,\n slug: input.slug ?? existing.slug,\n parentId:\n input.parentId !== undefined ? input.parentId : existing.parentId,\n metadata: input.metadata ?? existing.metadata,\n updatedAt: now,\n },\n },\n );\n\n const updated = await this.get(id);\n if (!updated)\n throw new Error(`Failed to fetch category after update: ${id}`);\n return updated;\n }\n\n async delete(id: string): Promise<void> {\n await this.col().deleteOne({ _id: id });\n }\n\n async list(filter: CategoryFilter = {}): Promise<Category[]> {\n // biome-ignore lint/suspicious/noExplicitAny: mongo filter type\n const query: any = {};\n if (filter.parentId !== undefined) query.parentId = filter.parentId;\n if (filter.search) {\n query.name = { $regex: filter.search, $options: 'i' };\n }\n\n let cursor = this.col().find(query).sort({ name: 1 });\n if (filter.offset) cursor = cursor.skip(filter.offset);\n if (filter.limit) cursor = cursor.limit(filter.limit);\n\n const docs = await cursor.toArray();\n return docs.map((doc) => this.toCategory(doc));\n }\n}\n\nclass MongoImageRepository implements ImageRepository {\n constructor(private readonly db: () => Db) {}\n\n private col(): Collection<ImageDoc> {\n return this.db().collection<ImageDoc>('occ_image');\n }\n\n async create(input: CreateImageInput): Promise<Image> {\n const id = randomUUID();\n const now = new Date();\n const doc: ImageDoc = {\n _id: id,\n productId: input.productId,\n url: input.url,\n altText: input.altText,\n sortOrder: input.sortOrder ?? 0,\n createdAt: now,\n };\n await this.col().insertOne(doc);\n return {\n id: doc._id,\n productId: doc.productId,\n url: doc.url,\n altText: doc.altText,\n sortOrder: doc.sortOrder,\n createdAt: doc.createdAt,\n };\n }\n\n async get(id: string): Promise<Image | null> {\n const doc = await this.col().findOne({ _id: id });\n if (!doc) return null;\n return {\n id: doc._id,\n productId: doc.productId,\n url: doc.url,\n altText: doc.altText,\n sortOrder: doc.sortOrder,\n createdAt: doc.createdAt,\n };\n }\n\n async delete(id: string): Promise<void> {\n await this.col().deleteOne({ _id: id });\n }\n\n async listByProduct(productId: string): Promise<Image[]> {\n const docs = await this.col()\n .find({ productId })\n .sort({ sortOrder: 1 })\n .toArray();\n return docs.map((doc) => ({\n id: doc._id,\n productId: doc.productId,\n url: doc.url,\n altText: doc.altText,\n sortOrder: doc.sortOrder,\n createdAt: doc.createdAt,\n }));\n }\n}\n","import { createWriteStream, existsSync, mkdirSync, unlinkSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport type {\n StorageAdapter,\n UploadOptions,\n} from '../../../interfaces/StorageAdapter.js';\n\nexport interface LocalStorageConfig {\n /** Absolute path to the directory where uploaded files will be stored. */\n uploadDir: string;\n /**\n * Base URL prefix for returned file URLs, e.g. 'http://localhost:3000/uploads'.\n * Defaults to '/uploads' (a relative path).\n */\n baseUrl?: string;\n}\n\n/** Storage adapter that writes files to the local filesystem. */\nexport class LocalStorageAdapter implements StorageAdapter {\n private readonly uploadDir: string;\n private readonly baseUrl: string;\n\n constructor(config: LocalStorageConfig) {\n this.uploadDir = resolve(config.uploadDir);\n this.baseUrl = config.baseUrl ?? '/uploads';\n\n if (!existsSync(this.uploadDir)) {\n mkdirSync(this.uploadDir, { recursive: true });\n }\n }\n\n async upload(\n file: Buffer | Readable,\n filename: string,\n _options?: UploadOptions,\n ): Promise<string> {\n const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, '_');\n const uniqueName = `${Date.now()}-${safeName}`;\n const filePath = join(this.uploadDir, uniqueName);\n\n if (Buffer.isBuffer(file)) {\n await Bun.write(filePath, file);\n } else {\n const writeStream = createWriteStream(filePath);\n await pipeline(file, writeStream);\n }\n\n return this.getPublicUrl(uniqueName);\n }\n\n async delete(url: string): Promise<void> {\n const key = this.urlToKey(url);\n if (!key) return;\n const filePath = join(this.uploadDir, key);\n if (existsSync(filePath)) {\n unlinkSync(filePath);\n }\n }\n\n getPublicUrl(key: string): string {\n return `${this.baseUrl}/${key}`;\n }\n\n private urlToKey(url: string): string | null {\n const prefix = `${this.baseUrl}/`;\n if (url.startsWith(prefix)) {\n return url.slice(prefix.length);\n }\n return null;\n }\n}\n","import { createRequire } from 'node:module';\nimport { extname } from 'node:path';\nimport type { Readable } from 'node:stream';\nimport type {\n StorageAdapter,\n UploadOptions,\n} from '../../../interfaces/StorageAdapter.js';\n\nexport interface S3Config {\n bucket: string;\n region: string;\n /** Custom endpoint for S3-compatible services (MinIO, Cloudflare R2, etc.). */\n endpoint?: string;\n accessKeyId: string;\n secretAccessKey: string;\n /** Whether objects should default to public-read ACL. Defaults to true. */\n publicRead?: boolean;\n}\n\ntype S3Client = import('@aws-sdk/client-s3').S3Client;\ntype PutObjectCommand = import('@aws-sdk/client-s3').PutObjectCommand;\ntype DeleteObjectCommand = import('@aws-sdk/client-s3').DeleteObjectCommand;\n\ninterface AWSS3Module {\n S3Client: new (config: object) => S3Client;\n PutObjectCommand: new (input: object) => PutObjectCommand;\n DeleteObjectCommand: new (input: object) => DeleteObjectCommand;\n}\n\nfunction loadDriver(): AWSS3Module {\n try {\n const require = createRequire(import.meta.url);\n return require('@aws-sdk/client-s3') as AWSS3Module;\n } catch {\n throw new Error(\n '@aws-sdk/client-s3 is not installed. Run: bun add @aws-sdk/client-s3',\n );\n }\n}\n\n/** S3-compatible storage adapter using @aws-sdk/client-s3. */\nexport class S3Adapter implements StorageAdapter {\n private readonly client: S3Client;\n private readonly bucket: string;\n private readonly publicRead: boolean;\n private readonly baseUrl: string;\n private readonly aws: AWSS3Module;\n\n constructor(config: S3Config) {\n this.aws = loadDriver();\n this.bucket = config.bucket;\n this.publicRead = config.publicRead ?? true;\n\n this.client = new this.aws.S3Client({\n region: config.region,\n endpoint: config.endpoint,\n credentials: {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n },\n forcePathStyle: !!config.endpoint,\n });\n\n if (config.endpoint) {\n this.baseUrl = `${config.endpoint.replace(/\\/$/, '')}/${config.bucket}`;\n } else {\n this.baseUrl = `https://${config.bucket}.s3.${config.region}.amazonaws.com`;\n }\n }\n\n async upload(\n file: Buffer | Readable,\n filename: string,\n options?: UploadOptions,\n ): Promise<string> {\n const safeName = filename.replace(/[^a-zA-Z0-9._/-]/g, '_');\n const key = `${Date.now()}-${safeName}`;\n const contentType = options?.contentType ?? guessContentType(filename);\n\n const command = new this.aws.PutObjectCommand({\n Bucket: this.bucket,\n Key: key,\n Body: file,\n ContentType: contentType,\n ACL: this.publicRead ? 'public-read' : 'private',\n });\n\n await (\n this.client as unknown as { send: (cmd: object) => Promise<void> }\n ).send(command);\n return this.getPublicUrl(key);\n }\n\n async delete(url: string): Promise<void> {\n const key = this.urlToKey(url);\n if (!key) return;\n\n const command = new this.aws.DeleteObjectCommand({\n Bucket: this.bucket,\n Key: key,\n });\n\n await (\n this.client as unknown as { send: (cmd: object) => Promise<void> }\n ).send(command);\n }\n\n getPublicUrl(key: string): string {\n return `${this.baseUrl}/${key}`;\n }\n\n private urlToKey(url: string): string | null {\n const prefix = `${this.baseUrl}/`;\n if (url.startsWith(prefix)) {\n return url.slice(prefix.length);\n }\n return null;\n }\n}\n\nfunction guessContentType(filename: string): string {\n const ext = extname(filename).toLowerCase();\n const map: Record<string, string> = {\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.png': 'image/png',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.svg': 'image/svg+xml',\n '.avif': 'image/avif',\n };\n return map[ext] ?? 'application/octet-stream';\n}\n","import type { Readable } from 'node:stream';\nimport type {\n StorageAdapter,\n UploadOptions,\n} from '../../../interfaces/StorageAdapter.js';\n\n/**\n * Storage adapter for externally-hosted images.\n * `upload` is not supported — pass URLs directly in `CreateImageInput.url`\n * and this adapter stores them as-is.\n */\nexport class ExternalURLAdapter implements StorageAdapter {\n async upload(\n _file: Buffer | Readable,\n _filename: string,\n _options?: UploadOptions,\n ): Promise<string> {\n throw new Error(\n 'ExternalURLAdapter does not support uploads. ' +\n 'Pass the image URL directly in CreateImageInput.url.',\n );\n }\n\n async delete(_url: string): Promise<void> {\n // External URLs cannot be deleted via this adapter.\n }\n\n getPublicUrl(key: string): string {\n return key;\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@richardmcquiston01/online-catalog-cms",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Headless TypeScript CMS engine for managing an online product catalog",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "Richard McQuiston <richard.mcquiston01@gmail.com>",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.cjs",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"cms",
|
|
23
|
+
"catalog",
|
|
24
|
+
"headless",
|
|
25
|
+
"typescript",
|
|
26
|
+
"sqlite",
|
|
27
|
+
"postgres",
|
|
28
|
+
"mysql",
|
|
29
|
+
"mongodb",
|
|
30
|
+
"redis",
|
|
31
|
+
"s3"
|
|
32
|
+
],
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/RichardMcQuiston01/online-catalog-cms.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/RichardMcQuiston01/online-catalog-cms/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/RichardMcQuiston01/online-catalog-cms#readme",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18.0.0",
|
|
43
|
+
"bun": ">=1.0.0"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"test": "bun test",
|
|
49
|
+
"test:watch": "bun test --watch",
|
|
50
|
+
"lint": "biome check .",
|
|
51
|
+
"lint:fix": "biome check --write .",
|
|
52
|
+
"prepublishOnly": "bun run typecheck && bun run test && bun run build",
|
|
53
|
+
"demo": "bunx serve demo"
|
|
54
|
+
},
|
|
55
|
+
"optionalDependencies": {
|
|
56
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
57
|
+
"better-sqlite3": "^9.0.0",
|
|
58
|
+
"ioredis": "^5.0.0",
|
|
59
|
+
"mongodb": "^6.0.0",
|
|
60
|
+
"mysql2": "^3.0.0",
|
|
61
|
+
"postgres": "^3.0.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@biomejs/biome": "^1.9.0",
|
|
65
|
+
"@types/better-sqlite3": "^7.0.0",
|
|
66
|
+
"@types/node": "^22.0.0",
|
|
67
|
+
"bun-types": "^1.3.14",
|
|
68
|
+
"tsup": "^8.0.0",
|
|
69
|
+
"typescript": "^5.0.0",
|
|
70
|
+
"vitest": "^2.0.0"
|
|
71
|
+
},
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public"
|
|
74
|
+
},
|
|
75
|
+
"trustedDependencies": [
|
|
76
|
+
"@biomejs/biome"
|
|
77
|
+
]
|
|
78
|
+
}
|