122 lines
3.6 KiB
JavaScript
122 lines
3.6 KiB
JavaScript
import {
|
||
CREATE as MSSQL_CREATE,
|
||
} from '../../providers/mssql/queries/labeltemplate.js';
|
||
import {
|
||
CREATE as SQLITE_CREATE,
|
||
} from '../../providers/sqlite3/queries/labeltemplate.js';
|
||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||
import makeRunner from '../runner.js';
|
||
|
||
const VALID_TYPES = new Set(['zpl']);
|
||
const VALID_DPIS = new Set([203, 300]);
|
||
|
||
function shape(row) {
|
||
return {
|
||
id: row.id,
|
||
company_id: row.company_id ?? row.companyId,
|
||
name: row.name,
|
||
width: row.width,
|
||
height: row.height,
|
||
dpi: row.dpi,
|
||
type: row.type,
|
||
content: typeof row.content === 'string' ? JSON.parse(row.content) : row.content,
|
||
thumb: row.thumb ?? null,
|
||
};
|
||
}
|
||
|
||
export default function create(provider) {
|
||
const access = resolveSelectedCompanyAccess(provider);
|
||
const isSqlite = provider?.dialect === 'sqlite3';
|
||
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
|
||
|
||
/**
|
||
* Creates a new label template for the user's selected company.
|
||
*
|
||
* @param {number} googleAuthId - The id of the Google auth user.
|
||
* @param {object} input - Label template input.
|
||
* @param {string} input.name - Template name.
|
||
* @param {number} input.width - Canvas width in pixels.
|
||
* @param {number} input.height - Canvas height in pixels.
|
||
* @param {number} input.dpi - Printer DPI (203 or 300).
|
||
* @param {string} input.type - Template type ("zpl").
|
||
* @param {object} input.content - Template content (JSON).
|
||
* @param {Buffer|null} [input.thumb] - 50×50 1-bit PNG thumbnail buffer.
|
||
* @param {object} [tx] - Optional transaction to run within.
|
||
* @returns {Promise<{id: number, company_id: number, name: string, width: number, height: number, dpi: number, type: string, content: object, thumb: Buffer|null}>}
|
||
* @throws {Error} If required fields are missing or invalid.
|
||
*
|
||
* @example
|
||
* const template = await store.labeltemplate.create(googleAuthId, {
|
||
* name: 'Product Label',
|
||
* width: 448,
|
||
* height: 200,
|
||
* dpi: 203,
|
||
* type: 'zpl',
|
||
* content: { objects: [] },
|
||
* });
|
||
*/
|
||
return async (googleAuthId, input = {}, tx) => {
|
||
const name = typeof input.name === 'string' ? input.name.trim() : '';
|
||
if (!name) {
|
||
throw new Error('Name required');
|
||
}
|
||
|
||
const width = Number(input.width);
|
||
if (!Number.isInteger(width) || width <= 0) {
|
||
throw new Error('Invalid width');
|
||
}
|
||
|
||
const height = Number(input.height);
|
||
if (!Number.isInteger(height) || height <= 0) {
|
||
throw new Error('Invalid height');
|
||
}
|
||
|
||
const dpi = Number(input.dpi);
|
||
if (!VALID_DPIS.has(dpi)) {
|
||
throw new Error('Invalid dpi: must be 203 or 300');
|
||
}
|
||
|
||
const type = typeof input.type === 'string' ? input.type.trim() : '';
|
||
if (!type || !VALID_TYPES.has(type)) {
|
||
throw new Error('Invalid type: must be "zpl"');
|
||
}
|
||
|
||
if (input.content == null) {
|
||
throw new Error('Content required');
|
||
}
|
||
const content = typeof input.content === 'string'
|
||
? input.content
|
||
: JSON.stringify(input.content);
|
||
|
||
const thumb = input.thumb instanceof Buffer ? input.thumb : null;
|
||
|
||
const runner = makeRunner(provider, tx);
|
||
const { companyId } = await access(googleAuthId, runner);
|
||
|
||
const result = await runner.query(createSql, {
|
||
companyId,
|
||
name,
|
||
width,
|
||
height,
|
||
dpi,
|
||
type,
|
||
content,
|
||
thumb,
|
||
});
|
||
|
||
const row = result.rows[0] ?? {
|
||
id: result.insertId,
|
||
company_id: companyId,
|
||
name,
|
||
width,
|
||
height,
|
||
dpi,
|
||
type,
|
||
content,
|
||
thumb,
|
||
};
|
||
|
||
return shape(row);
|
||
};
|
||
}
|