From 77b7669b56b459bf59b69d9a2410ea24a62f72d9 Mon Sep 17 00:00:00 2001 From: Yeasir H Date: Sat, 27 Jan 2024 01:13:55 -0800 Subject: [PATCH] simplified api & improved jsDocs --- src/BrotherSdk.ts | 118 +++++++++++++++++++++++-------------- src/adapter.ts | 5 +- src/helpers.ts | 108 ++++++++++++++++++--------------- src/index.ts | 3 +- src/types.ts | 55 +++++++---------- test/browser/playground.js | 10 ++-- 6 files changed, 163 insertions(+), 136 deletions(-) diff --git a/src/BrotherSdk.ts b/src/BrotherSdk.ts index c8d9333..2d41943 100644 --- a/src/BrotherSdk.ts +++ b/src/BrotherSdk.ts @@ -1,12 +1,12 @@ import { getAbsolutePath, - getPrintOption, - getEncodingOption, + getExportType, + getFileExtension, + getStartPrintOptions, } from "./helpers"; import { Data, - Config, - Encoding, + PrintConfig, ImageOptions, } from "./types"; import { @@ -129,30 +129,65 @@ export default class BrotherSdk { /** * **Method For Printing A Label** * - * asynchronously print a label using the specified configurations. + * Asynchronously print a label using the specified configurations. * * @param {Object} data - * an object containing key-value pairs, where each key represents an object ID, + * An object containing key-value pairs, where each key represents an object ID, * and the corresponding value is the text to be set on that object. - * @param {Object} config - * { object } + * @param {Object} [config] + * Optional * @param {Number} [config.copies = 1] - * number of copies to be printed. + * Number of copies to print. * @param {String} [config.printName = "BPAC-Document"] - * print document name. - * @param {String} [config.option = "default"] - * use the `PrinterOptions` enum for valid options. formally "quality" + * Print document name. + * @param {boolean} [config.autoCut = false] + * Auto cut is applied. + * @param {boolean} [config.cutPause = false] + * Pause to cut is applied. Valid only with models not supporting the auto cut function. + * @param {boolean} [config.cutMark = false] + * Cut mark is inserted. Valid only with models not supporting the auto cut function. + * @param {boolean} [config.halfCut = false] + * Executes half cut. + * @param {boolean} [config.chainPrint = false] + * Continuous printing is performed. The final label is not cut, but when the next + * labels are output, the preceding blank is cut in line with the cut option setting. + * @param {boolean} [config.tailCut = false] + * Whenever a label is output, the trailing end of the form is forcibly cut to + * leave a leading blank for the next label output. + * @param {boolean} [config.specialTape = false] + * No cutting is performed when printing on special tape. + * Valid only with PT-2430PC. + * @param {boolean} [config.cutAtEnd = false] + * "Cut at end" is performed. + * @param {boolean} [config.noCut = false] + * No cutting is performed. Valid only with models supporting cut functions. + * @param {boolean} [config.mirroring = false] + * Executes mirror printing. + * @param {boolean} [config.quality = false] + * Fine-quality printing is performed. + * @param {boolean} [config.highSpeed = false] + * High-speed printing is performed. + * @param {boolean} [config.highResolution = false] + * High-resolution printing is performed. + * @param {boolean} [config.color = false] + * Color printing is performed. + * @param {boolean} [config.mono = false] + * Monochrome printing is performed. Valid only with models supporting + * the color printing function. + * @param {boolean} [config.continue = false] + * Combines with printing for the following DoPrint( ) so that it is a single print job. + * As a result, when the next DoPrints are called up, the front margins are not output. */ - async print(data: Data, config: Config): Promise { - const copies:number = config?.copies || 1; - const printName:string = config?.printName || "BPAC-Document"; - const opts:number = getPrintOption(config?.option); + async print(data: Data, config?: PrintConfig): Promise { + const { copies = 1, printName = "BPAC-Document", ...rest } = config || {}; + + const bitmaskNumber = getStartPrintOptions(rest); await this.#isPrintReady(); await openTemplate(this.templatePath); await populateObjectsInTemplate(data); - await startPrint(printName, opts); + await startPrint(printName, bitmaskNumber); await printOut(copies); await endPrint(); await closeTemplate(); @@ -163,21 +198,21 @@ export default class BrotherSdk { /** * **Method For Retrieving The Label's Image Data** * - * asynchronously retrieves and returns Base64-encoded image data for a label. + * Asynchronously retrieves and returns Base64-encoded image data for a label. * * @param {object} data - * an object containing key-value pairs, where each key represents an object ID, + * An object containing key-value pairs, where each key represents an object ID, * and the corresponding value is the text to be set on that object. * @param {object} options - * { object } + * Optional * @param {string} options.height - * if the vertical size (dpi) of the image to be acquired is specified as 0, it + * If the vertical size (dpi) of the image to be acquired is specified as 0, it * becomes a size that maintains the aspect ratio based on width. * @param {string} options.width - * horizontal size (dpi) of the image to be acquired. If 0 is specified, + * Horizontal size (dpi) of the image to be acquired. If 0 is specified, * it becomes a size that maintains the aspect ratio based on height. * @returns {Promise} - * a promise that resolves to a Base64 encoded string representing the image data. + * A promise that resolves to a Base64 encoded string representing the image data. */ async getImageData( data: Data, @@ -198,12 +233,12 @@ export default class BrotherSdk { /** * **Retrieve The Printer's Name** * - * asynchronously retrieves the printers name for the current context. + * Asynchronously retrieves the printers name for the current context. * * @returns {Promise} - * a promise that resolves with the name of the printer. + * A promise that resolves with the name of the printer. * @throws {Error} - * fails to get the printer name. + * Fails to get the printer name. * */ async getPrinterName(): Promise { @@ -217,35 +252,30 @@ export default class BrotherSdk { /** * **Export Label To File** * - * asynchronously populate & export a copy of the file in various formats. + * Asynchronously populate & export a copy of the file in various formats. * * @param {Object} data - * an object containing key-value pairs, where each key represents + * An object containing key-value pairs, where each key represents * an object ID, and the corresponding value is the text to be set on that object. * @param {String} [filePathOrFileName = ""] - * provide a file name or absolute path. - * - "myLabel.lbx" to be store in exportDir. - * - "C:/Templates/myLabel.lbx" to override the exportDir. - * @param {("default" | "lbx" | "lbl" | "lbi" | "bmp" | "paf")} [encoding = "default"] - * file encoding type. + * Provide a file name or absolute path. + * - e.g. = "myLabel.lbx" will be stored in exportDir. + * - e.g. = "C:/Templates/myLabel.lbx" to override the exportDir. + * - Supported types = .lbx | .lbl | .lbi | .bmp | .paf * @param {Number} [resolution = 0] - * provide a resolution in dpi used for the conversion into bitmap format. + * Provide a resolution in dpi used for the conversion into bitmap format. * Specifies the resolution of the output device. * (Screen: 72 or 96; output to SC-2000: 600) * If a value of 0 is specified, the printer resolution is used. * - * The resolution param is only valid for LBI and BMP formats. - * @returns {Promise} + * The resolution param is only valid for .lbi and .bmp extensions. * @throws {Error} - * fails to export. + * Fails to export. */ - async export( - data: Data = {}, - filePathOrFileName: string = "", - encoding: Encoding = Encoding.Default, - resolution: number = 0, - ): Promise { - const fileType = getEncodingOption(encoding); + async export(data: Data, filePathOrFileName: string, resolution: number = 0): Promise { + const fileExt = getFileExtension(filePathOrFileName); + const fileType = getExportType(fileExt); + const path:string = getAbsolutePath( this.exportDir, filePathOrFileName, diff --git a/src/adapter.ts b/src/adapter.ts index 8e94202..7135681 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -26,9 +26,8 @@ export const getPrinters = async (): Promise => { return printers; }; -// Fix these params -export const startPrint = async (printName:string, options:number): Promise => { - const isComplete = await doc.StartPrint(printName, options); +export const startPrint = async (printName:string, bitmask:number): Promise => { + const isComplete = await doc.StartPrint(printName, bitmask); return isComplete; }; diff --git a/src/helpers.ts b/src/helpers.ts index af12847..b0cb12b 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,4 +1,23 @@ -import { PrinterOptions, Encoding } from "./types"; +import { StartPrintOptions } from "./types"; + +const optionBitmaskMap: { [key in keyof StartPrintOptions]: number } = { + autoCut: 0x1, + cutPause: 0x1, + cutMark: 0x2, + halfCut: 0x200, + chainPrint: 0x400, + tailCut: 0x800, + specialTape: 0x00080000, + cutAtEnd: 0x04000000, + noCut: 0x10000000, + mirroring: 0x4, + quality: 0x00010000, + highSpeed: 0x01000000, + highResolution: 0x02000000, + color: 0x8, + mono: 0x10000000, + continue: 0x40000000, +}; export const getAbsolutePath = (basePath: string, filePathOrFileName: string): string => { // eslint-disable-next-line no-useless-escape @@ -14,60 +33,51 @@ export const getAbsolutePath = (basePath: string, filePathOrFileName: string): s return filePathOrFileName; }; -export const getPrintOption = (option?:PrinterOptions): number => { - switch (option) { - case PrinterOptions.Default: - return 0x0; - case PrinterOptions.AutoCut: - case PrinterOptions.CutPause: +export const getExportType = (fileExt:string) => { + switch (fileExt) { + case ".lbx": return 0x1; - case PrinterOptions.CutMark: + case ".lbl": return 0x2; - case PrinterOptions.HalfCut: - return 0x200; - case PrinterOptions.ChainPrint: - return 0x400; - case PrinterOptions.TailCut: - return 0x800; - case PrinterOptions.SpecialTape: - return 0x00080000; - case PrinterOptions.CutAtEnd: - return 0x04000000; - case PrinterOptions.NoCut: - return 0x10000000; - case PrinterOptions.Mirroring: + case ".lbi": + return 0x3; + case ".bmp": return 0x4; - case PrinterOptions.Quality: - return 0x00010000; - case PrinterOptions.HighSpeed: - return 0x01000000; - case PrinterOptions.HighResolution: - return 0x02000000; - case PrinterOptions.Color: - case PrinterOptions.Mono: - return 0x8; - case PrinterOptions.Continue: - return 0x40000000; + case ".paf": + return 0x5; default: - return 0x0; + throw new Error(`Invalid extension: Expected ".lbx | .lbl | .lbi | .bmp | .paf", received ${fileExt}.`); } }; -export const getEncodingOption = (fileType?:Encoding) => { - switch (fileType) { - case Encoding.Default: - return 0x0; - case Encoding.Lbx: - return 0x1; - case Encoding.Lbl: - return 0x2; - case Encoding.Lbi: - return 0x3; - case Encoding.Bmp: - return 0x4; - case Encoding.Paf: - return 0x5; - default: - throw new Error(`Invalid encoding. Received ${fileType}.`); +export const getStartPrintOptions = (options: StartPrintOptions): number => { + const combinedBitmask: number[] = []; + + Object.entries(options).forEach(([key, value]) => { + const k = key as keyof StartPrintOptions; + + if (value === true && optionBitmaskMap[k] !== undefined) { + const bitmaskValue: number | undefined = optionBitmaskMap[k]; + + if (bitmaskValue !== undefined) { + combinedBitmask.push(bitmaskValue); + } + } + }); + + // eslint-disable-next-line no-bitwise + return combinedBitmask.reduce((acc, val) => acc | val, 0x0); +}; + +export const getFileExtension = (filePathOrFileName:string): string => { + const lastDotIdx:number = filePathOrFileName.lastIndexOf("."); + + if (lastDotIdx === -1) { + throw new Error(`No extension provided for file: ${filePathOrFileName}`); } + + const extension:string = filePathOrFileName.slice(lastDotIdx); + const normalizedExt:string = extension.toLowerCase(); + + return normalizedExt; }; diff --git a/src/index.ts b/src/index.ts index e564466..de9b874 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,4 @@ import BrotherSdk from "./BrotherSdk"; -import { Encoding, PrinterOptions } from "./types"; -export { BrotherSdk, Encoding, PrinterOptions }; +export { BrotherSdk }; export default BrotherSdk; diff --git a/src/types.ts b/src/types.ts index 3e1d1d6..daba8ef 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,11 +1,31 @@ export type Data = Record; -export type Config = { +export type PrintOptions = { copies?: number; printName?: string; - option?: PrinterOptions; }; +export type StartPrintOptions = { + autoCut?: boolean; + cutPause?: boolean, + cutMark?: boolean, + halfCut?: boolean, + chainPrint?: boolean, + tailCut?: boolean, + specialTape?: boolean, + cutAtEnd?: boolean, + noCut?: boolean, + mirroring?: boolean, + quality?: boolean, + highSpeed?: boolean, + highResolution?: boolean, + color?: boolean, + mono?: boolean, + continue?: boolean, +}; + +export type PrintConfig = PrintOptions & StartPrintOptions; + export type ImageOptions = { width?: number; height?:number; @@ -18,34 +38,3 @@ export enum ObjectTypes { Datetime = 3, Clipart = 4, } - -export enum Encoding { - Default = "default", - Lbx = "lbx", - Lbl = "lbl", - Lbi = "lbi", - Bmp = "bmp", - Paf = "paf", -} - -export enum PrinterOptions { - Default = "default", - AutoCut = "auto-cut", - CutPause = "cut-pause", - CutMark = "cut-mark", - HalfCut = "half-cut", - ChainPrint = "chain-print", - TailCut = "tail-cut", - SpecialTape = "special-tape", - CutAtEnd = "cut-at-end", - NoCut = "no-cut", - Mirroring = "mirror", - Quality = "quality", - HighSpeed = "high-speed", - HighResolution = "high-resolution", - Color = "color", - Mono = "mono", - Continue = "continue", - Fast = "fast", // Deprecated: Use HighSpeed for faster printing. - High = "high", // Deprecated: Use HighResolution for higher print resolution. -} diff --git a/test/browser/playground.js b/test/browser/playground.js index 7460375..a96b3a8 100644 --- a/test/browser/playground.js +++ b/test/browser/playground.js @@ -17,11 +17,11 @@ const data = { barcode: "074608352052", image: "C:/Users/YMH/Desktop/Storage Drive Files/Logos/Monogram/my-logo.png", }; - +/* {autoCut: true, mirroring: true, specialTape:true} */ const printTag = async () => { try { - const status = await tag.print(data); - console.log({ status }); + const complete = await tag.print(data); + console.log({ complete }); } catch (error) { console.log({ error }); } @@ -39,8 +39,8 @@ const previewTag = async () => { const exportTag = async () => { try { - const status = await tag.export(data, "my-tag.bmp", "bmp", 300); - console.log({status}) + const complete = await tag.export(data, "custom-label.bmp", 300); + console.log({complete}) } catch (error) { console.log({ error }); }