import * as mssqlPic from '../../providers/mssql/queries/articlepic.js'; import * as sqlitePic from '../../providers/sqlite3/queries/articlepic.js'; import resolveArticleBySku from './resolveArticleBySku.js'; import { recordImageOrderHistory } from '../articlehistory/record.js'; import makeRunner from '../runner.js'; export default function orderImages(provider) { const resolve = resolveArticleBySku(provider); const isSqlite = provider?.dialect === 'sqlite3'; const queries = isSqlite ? sqlitePic : mssqlPic; /** * Reorders the images of an article by its SKU. * * @param {number} googleAuthId - The id of the Google auth user. * @param {string} sku - The article SKU. * @param {object} input - The reorder input. * @param {Array} input.fullHashes - The full image hashes in their new order. * @param {object} [tx] - Optional transaction to run within. * @returns {Promise<{fullHashes: Array}>} The applied order. * @throws {Error} If the order is invalid. * * @example * const result = await store.article.orderImages(42, 'SKU-1', { fullHashes: ['a', 'b'] }); * // => { fullHashes: ['a', 'b'] } */ return async (googleAuthId, sku, { fullHashes }, tx) => { if (!Array.isArray(fullHashes)) { throw new Error('Invalid image order'); } const runOrder = async (runner) => { const { articleId, companyuserId } = await resolve(googleAuthId, sku, runner); const current = await runner.query(queries.LIST_HASHES_BY_ARTICLE, { articleId }); const existing = new Set(current.rows.map((r) => r.fullHash)); if (fullHashes.length !== existing.size) { throw new Error('Invalid image order'); } const seen = new Set(); for (const fullHash of fullHashes) { if (!existing.has(fullHash) || seen.has(fullHash)) { throw new Error('Invalid image order'); } seen.add(fullHash); } await runner.query(queries.SET_TEMP_SORTS, { articleId }); for (let sort = 0; sort < fullHashes.length; sort++) { const update = await runner.query(queries.UPDATE_SORT_BY_HASH, { articleId, fullHash: fullHashes[sort], sort, }); if (!update.rowsAffected) { throw new Error('Invalid image order'); } } const oldOrder = current.rows.map((r) => r.fullHash); const isSameOrder = oldOrder.length === fullHashes.length && oldOrder.every((h, i) => h === fullHashes[i]); if (!isSameOrder) { await recordImageOrderHistory(runner, { articleId, companyuserId, fullHashes, }); } return { fullHashes }; }; if (tx) { return runOrder(makeRunner(provider, tx)); } if (typeof provider?.transaction === 'function') { return provider.transaction(runOrder); } return runOrder(makeRunner(provider)); }; }