UNPKG

libreoffice-file-converter

Version:

Simple NodeJS wrapper for libreoffice CLI for converting office documents to different formats

1 lines 23.5 kB
{"version":3,"sources":["../src/constants/env.ts","../src/constants/paths.ts","../src/helpers/libreoffice.ts","../src/helpers/child-process.ts","../src/helpers/fs.ts","../src/helpers/primitives.ts","../src/libreoffice-file-converter.ts"],"names":["PROGRAM_FILES","PROGRAM_FILES_86","DARWIN_PATHS","LINUX_PATHS","WIN32_PATHS","join","process","env","getLibreOfficeExecutablePaths","platform","getLibreOfficeExecutablePath","binaryPaths","paths","existingPaths","Promise","all","map","path","access","filter","Boolean","Error","getLibreOfficeCommandArgs","installationDir","inputPath","outputDir","format","inputFilter","outputFilter","filterSegment","length","args","pathToFileURL","toString","push","hasLibreOfficeError","stderr","toLowerCase","includes","isBuffer","value","Buffer","processOutputToString","processOutput","execFileAsync","options","debug","resolve","reject","execFile","error","stdout","stderrString","stdoutString","debugInfo","inspect","colors","sorted","write","libreOfficeError","getTemporaryFilePath","temporaryDir","getProcessedFilePath","temporaryDirPath","insideTemporaryDir","startsWith","inputPathSegments","split","sep","inputFileNameSegment","inputFileNameSegments","inputFileName","slice","writeStream","readStream","createWriteStream","pipeline","isObject","item","Array","isArray","deepMerge","objects","reduce","target","source","Object","keys","forEach","key","targetValue","sourceValue","LibreOfficeFileConverter","constructor","_options","setGracefulCleanup","convert","callOptions","mergedOptions","mergeOptions","tmpOptions","dir","prefix","unsafeCleanup","read","childProcessOptions","libreOfficeExecutablePath","libreOfficeCommandArgs","output","processedFilePath","readFile","outputPath","stream","createReadStream","input","temporaryFilePath","buffer","writeFile"],"mappings":"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","file":"index.mjs","sourcesContent":["export const PROGRAM_FILES = 'PROGRAMFILES';\n\nexport const PROGRAM_FILES_86 = 'PROGRAMFILES(X86)';\n","import { join } from 'node:path';\nimport process from 'node:process';\n\nimport { PROGRAM_FILES, PROGRAM_FILES_86 } from './env';\n\nexport const DARWIN_PATHS = (): readonly string[] => ['/Applications/LibreOffice.app/Contents/MacOS/soffice'];\n\nexport const LINUX_PATHS = (): readonly string[] => [\n '/usr/bin/libreoffice',\n '/usr/bin/soffice',\n '/snap/bin/libreoffice',\n '/opt/libreoffice/program/soffice',\n '/opt/libreoffice7.6/program/soffice',\n];\n\nexport const WIN32_PATHS = (): readonly string[] => [\n join(process.env[PROGRAM_FILES_86] || '', 'LIBREO~1/program/soffice.exe'),\n join(process.env[PROGRAM_FILES_86] || '', 'LibreOffice/program/soffice.exe'),\n join(process.env[PROGRAM_FILES] || '', 'LibreOffice/program/soffice.exe'),\n];\n","import { access } from 'node:fs/promises';\nimport process from 'node:process';\nimport { pathToFileURL } from 'node:url';\n\nimport { DARWIN_PATHS, LINUX_PATHS, WIN32_PATHS } from '../constants';\n\nexport const getLibreOfficeExecutablePaths = (): readonly string[] => {\n if (process.platform === 'darwin') {\n return DARWIN_PATHS();\n }\n\n if (process.platform === 'linux') {\n return LINUX_PATHS();\n }\n\n if (process.platform === 'win32') {\n return WIN32_PATHS();\n }\n\n return [];\n};\n\nexport const getLibreOfficeExecutablePath = async (binaryPaths: readonly string[] = []): Promise<string> => {\n const paths = [...binaryPaths, ...getLibreOfficeExecutablePaths()];\n\n const existingPaths = await Promise.all(\n paths.map(async (path) => {\n try {\n await access(path);\n } catch {\n return false;\n }\n\n return path;\n }),\n );\n\n const [path] = existingPaths.filter(Boolean);\n\n if (!path) {\n throw new Error('Could not find soffice binary');\n }\n\n return path;\n};\n\nexport const getLibreOfficeCommandArgs = (\n installationDir: string,\n inputPath: string,\n outputDir: string,\n format: string,\n inputFilter?: string,\n outputFilter?: string,\n): readonly string[] => {\n const filterSegment = outputFilter && outputFilter.length > 0 ? `:${outputFilter}` : '';\n\n const args = [`-env:UserInstallation=${pathToFileURL(installationDir).toString()}`, '--headless'];\n\n if (inputFilter && inputFilter.length > 0) {\n args.push(`--infilter=${inputFilter}`);\n }\n\n args.push('--convert-to', `${format}${filterSegment}`, '--outdir', outputDir, inputPath);\n\n return args;\n};\n\nexport const hasLibreOfficeError = (stderr: string): boolean => {\n return stderr?.toLowerCase()?.includes('error:');\n};\n","import { Buffer } from 'node:buffer';\nimport { execFile } from 'node:child_process';\nimport type { ExecFileOptions } from 'node:child_process';\nimport process from 'node:process';\nimport { inspect } from 'node:util';\n\nimport { hasLibreOfficeError } from './libreoffice';\n\nconst isBuffer = (value: unknown): value is Buffer => {\n return Buffer.isBuffer(value);\n};\n\nconst processOutputToString = (processOutput: string | Buffer): string => {\n return isBuffer(processOutput) ? processOutput.toString('utf-8') : processOutput;\n};\n\nexport const execFileAsync = (\n path: string,\n args: readonly string[],\n options?: ExecFileOptions,\n debug?: boolean,\n): Promise<void> => {\n return new Promise((resolve, reject) => {\n execFile(path, args, options, (error, stdout, stderr) => {\n const stderrString = processOutputToString(stderr);\n const stdoutString = processOutputToString(stdout);\n\n if (debug) {\n const debugInfo = inspect(\n {\n args,\n path,\n stderr: stderrString,\n stdout: stdoutString,\n },\n {\n colors: true,\n sorted: true,\n },\n );\n\n process.stdout.write(`LibreOffice debug output:\\n${debugInfo}\\n`);\n }\n\n const libreOfficeError = hasLibreOfficeError(stderrString);\n\n if (error || libreOfficeError) {\n return reject(error || new Error(stderrString));\n }\n\n return resolve();\n });\n });\n};\n","import { createWriteStream } from 'node:fs';\nimport { join, sep } from 'node:path';\nimport { pipeline } from 'node:stream';\nimport type { Readable } from 'node:stream';\n\nexport const getTemporaryFilePath = (temporaryDir: string): string => {\n return join(temporaryDir, 'source');\n};\n\nexport const getProcessedFilePath = (temporaryDirPath: string, inputPath: string, format: string): string => {\n const insideTemporaryDir = inputPath.startsWith(temporaryDirPath);\n\n if (insideTemporaryDir) {\n return `${inputPath}.${format}`;\n }\n\n const inputPathSegments = inputPath.split(sep);\n const inputFileNameSegment =\n inputPathSegments.length > 0 ? inputPathSegments[inputPathSegments.length - 1] : inputPathSegments[0];\n const inputFileNameSegments = inputFileNameSegment?.split('.');\n\n const inputFileName =\n inputFileNameSegments?.length && inputFileNameSegments.length > 1\n ? inputFileNameSegments?.slice(0, -1).join('.')\n : inputFileNameSegments?.[0];\n\n return `${temporaryDirPath}${sep}${inputFileName}.${format}`;\n};\n\nexport const writeStream = (path: string, readStream: Readable): Promise<void> => {\n return new Promise((resolve, reject) => {\n const writeStream = createWriteStream(path);\n\n pipeline(readStream, writeStream, (error) => {\n if (error) {\n return reject(error);\n }\n\n return resolve();\n });\n });\n};\n","export const isObject = (item: unknown): item is Record<string, unknown> => {\n return Boolean(item && typeof item === 'object' && !Array.isArray(item));\n};\n\nexport const deepMerge = <T extends Record<string, unknown>>(...objects: readonly T[]): T => {\n return objects.reduce<T>((target, source) => {\n Object.keys(source).forEach((key: keyof T) => {\n const targetValue = target[key];\n const sourceValue = source[key];\n\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n target[key] = [...targetValue, ...sourceValue] as T[keyof T];\n\n return;\n }\n\n if (isObject(targetValue) && isObject(sourceValue)) {\n target[key] = deepMerge(targetValue, sourceValue);\n\n return;\n }\n\n target[key] = sourceValue;\n });\n\n return target;\n }, {} as T);\n};\n","import type { Buffer } from 'node:buffer';\nimport { createReadStream } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport type { Readable } from 'node:stream';\nimport { dir, setGracefulCleanup } from 'tmp-promise';\n\nimport {\n deepMerge,\n execFileAsync,\n getLibreOfficeCommandArgs,\n getLibreOfficeExecutablePath,\n getProcessedFilePath,\n getTemporaryFilePath,\n writeStream,\n} from './helpers';\nimport type {\n ConvertOptions,\n ConvertOptionsInput,\n ConvertOutputOptionsBuffer,\n ConvertOutputOptionsFile,\n ConvertOutputOptionsStream,\n LibreOfficeFileConverterOptions,\n} from './types';\n\n/**\n * Simple NodeJS wrapper for libreoffice CLI for converting office documents to different formats.\n *\n * @example\n * ```ts\n * const libreOfficeFileConverter = new LibreOfficeFileConverter({ childProcessOptions: { timeout: 60 * 1000 } });\n * ```\n *\n * @class\n * @public\n */\nexport class LibreOfficeFileConverter {\n private readonly _options: LibreOfficeFileConverterOptions;\n\n /**\n * Create an instance of the LibreOfficeFileConverter.\n *\n * @example\n * ```ts\n * const libreOfficeFileConverter = new LibreOfficeFileConverter({ childProcessOptions: { timeout: 60 * 1000 } });\n * ```\n *\n * @param options The LibreOfficeFileConverter options.\n *\n * @constructor\n * @public\n */\n constructor(options: LibreOfficeFileConverterOptions = {}) {\n this._options = options;\n\n setGracefulCleanup();\n }\n\n /**\n * Converts provided input to the requested format.\n *\n * @example\n * ```ts\n * const outputBuffer = await libreOfficeFileConverter.convert({\n * buffer: inputBuffer,\n * format: 'pdf',\n * input: 'buffer',\n * output: 'buffer',\n * });\n * ```\n *\n * @param options Convert options: input and output type, format, filter, converter options.\n *\n * @returns Buffer of the converted input.\n *\n * @overload\n * @public\n */\n public async convert(options: ConvertOptionsInput & ConvertOutputOptionsBuffer): Promise<Buffer>;\n\n /**\n * Converts provided input to the requested format.\n *\n * @example\n * ```ts\n * await libreOfficeFileConverter.convert({\n * format: 'pdf',\n * input: 'file',\n * inputPath,\n * output: 'file',\n * outputPath,\n * });\n * ```\n *\n * @param options Convert options: input and output type, format, filter, converter options.\n *\n * @overload\n * @public\n */\n public async convert(options: ConvertOptionsInput & ConvertOutputOptionsFile): Promise<void>;\n\n /**\n * Converts provided input to the requested format.\n *\n * @example\n * ```ts\n * const outputStream = await libreOfficeFileConverter.convert({\n * format: 'pdf',\n * input: 'stream',\n * stream: inputStream,\n * output: 'stream',\n * });\n * ```\n *\n * @param options Convert options: input and output type, format, filter, converter options.\n *\n * @returns Readable stream of the converted input.\n *\n * @overload\n * @public\n */\n public async convert(options: ConvertOptionsInput & ConvertOutputOptionsStream): Promise<Readable>;\n\n /**\n * Converts provided input to the requested format.\n *\n * @example\n * ```ts\n * const outputBuffer = await libreOfficeFileConverter.convert({\n * buffer: inputBuffer,\n * format: 'pdf',\n * input: 'buffer',\n * output: 'buffer',\n * });\n * ```\n *\n * @param options Convert options: input and output type, format, filter, converter options.\n *\n * @returns Buffer, readable stream or void depending on the convert options.\n *\n * @public\n */\n public async convert(options: ConvertOptions): Promise<Buffer | Readable | void> {\n const { filter, format, inputFilter, options: callOptions = {}, outputFilter } = options;\n\n const mergedOptions = this.mergeOptions(callOptions);\n const { tmpOptions } = mergedOptions;\n\n const temporaryDir = await dir({\n prefix: 'libreoffice-file-converter',\n unsafeCleanup: true,\n ...tmpOptions,\n });\n\n const inputPath = await this.write(options, temporaryDir.path);\n\n await this.process(inputPath, temporaryDir.path, format, inputFilter || filter, outputFilter, mergedOptions);\n\n return this.read(options, temporaryDir.path, inputPath);\n }\n\n private mergeOptions(options: LibreOfficeFileConverterOptions = {}): LibreOfficeFileConverterOptions {\n return deepMerge(this._options, options);\n }\n\n private async process(\n inputPath: string,\n outputDir: string,\n format: string,\n inputFilter?: string,\n outputFilter?: string,\n options: LibreOfficeFileConverterOptions = {},\n ): Promise<void> {\n const { binaryPaths, childProcessOptions, debug, tmpOptions } = options;\n\n const libreOfficeExecutablePath = await getLibreOfficeExecutablePath(binaryPaths);\n\n const installationDir = await dir({\n prefix: 'soffice',\n unsafeCleanup: true,\n ...tmpOptions,\n });\n\n const libreOfficeCommandArgs = getLibreOfficeCommandArgs(\n installationDir.path,\n inputPath,\n outputDir,\n format,\n inputFilter,\n outputFilter,\n );\n\n await execFileAsync(libreOfficeExecutablePath, libreOfficeCommandArgs, childProcessOptions, debug);\n }\n\n private async read(\n options: ConvertOptions,\n temporaryDirPath: string,\n inputPath: string,\n ): Promise<Buffer | Readable | void> {\n const { format, output } = options;\n\n const processedFilePath = getProcessedFilePath(temporaryDirPath, inputPath, format);\n\n if (output === 'buffer') {\n return readFile(processedFilePath);\n }\n\n if (output === 'file') {\n const { outputPath } = options;\n\n const stream = createReadStream(processedFilePath);\n\n return writeStream(outputPath, stream);\n }\n\n if (output === 'stream') {\n return createReadStream(processedFilePath);\n }\n }\n\n private async write(options: ConvertOptions, temporaryDirPath: string): Promise<string> {\n const { input } = options;\n\n const temporaryFilePath = getTemporaryFilePath(temporaryDirPath);\n\n if (input === 'buffer') {\n const { buffer } = options;\n\n await writeFile(temporaryFilePath, buffer);\n\n return temporaryFilePath;\n }\n\n if (input === 'file') {\n const { inputPath } = options;\n\n return inputPath;\n }\n\n if (input === 'stream') {\n const { stream } = options;\n\n await writeStream(temporaryFilePath, stream);\n\n return temporaryFilePath;\n }\n\n return temporaryFilePath;\n }\n}\n"]}