Files
dashlibstorage/src/store/labeltemplate/create.js
2026-09-27 22:01:56 +02:00

122 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
};
}