import { GET_BY_COMPANY_AND_ID as MSSQL_GET_BY_ID, UPDATE as MSSQL_UPDATE, } from '../../providers/mssql/queries/printer.js'; import { GET_BY_COMPANY_AND_ID as SQLITE_GET_BY_ID, UPDATE as SQLITE_UPDATE, } from '../../providers/sqlite3/queries/printer.js'; import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js'; import makeRunner from '../runner.js'; const VALID_TYPES = new Set(['esc/pos', 'zpl', 'ipp']); function shape(row) { return { id: row.id, company_id: row.company_id ?? row.companyId, address: row.address, type: row.type, model: row.model ?? null, serial: row.serial ?? null, sort: row.sort, desc: row.desc ?? null, }; } function optionalString(value) { if (value == null || value === '') return null; const s = String(value).trim(); return s || null; } export default function update(provider) { const access = resolveSelectedCompanyAccess(provider); const isSqlite = provider?.dialect === 'sqlite3'; const getSql = isSqlite ? SQLITE_GET_BY_ID : MSSQL_GET_BY_ID; const updateSql = isSqlite ? SQLITE_UPDATE : MSSQL_UPDATE; /** * Updates a printer for the user's selected company. * * @param {number} googleAuthId - The id of the Google auth user. * @param {number} id - The printer ID to update. * @param {object} input - Update payload. * @param {string} [input.address] - The printer address. * @param {string} [input.type] - The printer type ("esc/pos", "zpl", or "ipp"). * @param {string|null} [input.model] - The printer model. * @param {string|null} [input.serial] - The printer serial. * @param {number} [input.sort] - The sort order. * @param {string|null} [input.desc] - The description. * @param {object} [tx] - Optional transaction to run within. * @returns {Promise<{id: number, company_id: number, address: string, type: string, model: string|null, serial: string|null, sort: number, desc: string|null}>} * @throws {Error} If printer not found, address is empty, type is invalid, or sort is invalid. */ return async (googleAuthId, id, input = {}, tx) => { const numericId = Number(id); if (!Number.isInteger(numericId) || numericId <= 0) { throw new Error('Printer not found'); } const runner = makeRunner(provider, tx); const { companyId } = await access(googleAuthId, runner); const existing = await runner.query(getSql, { id: numericId, companyId }); const current = existing.rows[0]; if (!current) { throw new Error('Printer not found'); } let address = current.address; if (input.address !== undefined) { const cleaned = typeof input.address === 'string' ? input.address.trim() : ''; if (!cleaned) { throw new Error('Address required'); } address = cleaned; } let type = current.type; if (input.type !== undefined) { const cleaned = typeof input.type === 'string' ? input.type.trim() : ''; if (!cleaned || !VALID_TYPES.has(cleaned)) { throw new Error('Invalid printer type: must be "esc/pos", "zpl", or "ipp"'); } type = cleaned; } let sort = current.sort; if (input.sort !== undefined) { if (!Number.isFinite(input.sort)) { throw new Error('Invalid sort'); } sort = input.sort; } const model = input.model !== undefined ? optionalString(input.model) : (current.model ?? null); const serial = input.serial !== undefined ? optionalString(input.serial) : (current.serial ?? null); const desc = input.desc !== undefined ? optionalString(input.desc) : (current.desc ?? null); const result = await runner.query(updateSql, { id: numericId, companyId, address, type, model, serial, sort, desc, }); const row = result.rows[0] ?? { id: numericId, company_id: companyId, address, type, model, serial, sort, desc, }; return shape(row); }; }