@adobe/pdftools-extract-node-sdk
Version:
The Document Services PDF Tools Extract Node.js SDK provides APIs for extracting elements and renditions from PDF
187 lines (169 loc) • 5.1 kB
JavaScript
/*
* Copyright 2019 Adobe
* All Rights Reserved.
*
* NOTICE: Adobe permits you to use, modify, and distribute this file in
* accordance with the terms of the Adobe license agreement accompanying
* it. If you have received this file from a source other than Adobe,
* then your use, modification, or distribution of it requires the prior
* written permission of Adobe.
*/
const inputTypes = require('./input-types'),
moveFile = require('move-file/index'),
extensionMediaTypeMapping = require('../extension-mediatype-mapping'),
path = require('path'),
logger = require('./../logger'),
fs = require('fs');
const deriveMediaTypeFromFilePath = (sourceObject, fileSource, inputType) => {
// Derive media type from local file path when it is not explicitly provided.
if (fileSource && inputType === inputTypes.localFile) {
const fileExtension = path.extname(fileSource);
Object.defineProperty(
sourceObject, '_extension',
{
value: fileExtension.replace('.', ''),
writable: false
}
);
if (extensionMediaTypeMapping[sourceObject._extension]) {
Object.defineProperty(
sourceObject, '_mediaType',
{
value: extensionMediaTypeMapping[sourceObject._extension].mediaType,
writable: false
}
);
}
}
},
getActualTargetFilePath = (destinationPath, extension) => {
const fileBaseDir = path.dirname(destinationPath),
fileBaseName = path.basename(destinationPath, path.extname(destinationPath));
return `${fileBaseDir}${path.sep}${fileBaseName}.${extension}`;
},
/* eslint default-case: 0*/
/**
* Utility function to check if any of the input is empty
* @param fileSource
* @param mediaType
* @param inputType
*/
validate = (fileSource, mediaType, inputType) => {
switch (inputType) {
case inputTypes.stream:
if (!fileSource) {
throw new Error('Readable stream must not be empty');
}
if (!mediaType) {
throw new Error('Media type must be provided for a stream');
}
if (typeof mediaType !== 'string') {
throw new Error('Media type must be a string');
}
break;
case inputTypes.localFile:
if (!fileSource) {
throw new Error('Local file path must not be empty');
}
if (mediaType && typeof mediaType !== 'string') {
throw new Error('Media type must be a string');
}
}
};
class FileInfo {
constructor(fileSource, mediaType, inputType, isOperationResult = false) {
validate(fileSource, mediaType, inputType);
Object.defineProperty(this, '_fileSource', {
value: fileSource,
writable: false
});
Object.defineProperty(this, '_inputType', {
value: inputType,
writable: false
});
this._mediaType = mediaType;
this._isOperationResult = isOperationResult;
if (mediaType) {
// Prevent reassigning of fields
Object.defineProperty(this, '_mediaType', {
value: mediaType,
writable: false
});
Object.defineProperty(this, '_extension', {
value: extensionMediaTypeMapping.getExtensionFromMediaType(mediaType),
writable: false
});
} else {
deriveMediaTypeFromFilePath(this, fileSource, inputType);
}
}
/**
*
* Creates and returns an input stream for this file.
* @returns {MultiStream|null|*}
*/
get asStream() {
switch (this._inputType) {
case inputTypes.localFile:
return fs.createReadStream(this._fileSource);
case inputTypes.stream:
return this._fileSource;
default:
// We don't support url streams currently
return null;
}
}
get extension() {
return this._extension;
}
get fileSource() {
return this._fileSource;
}
get mediaType() {
return this._mediaType;
}
get inputType() {
return this._inputType;
}
get isOperationResult() {
return this._isOperationResult;
}
set isOperationResult(isOperationResult) {
this._isOperationResult = isOperationResult;
}
saveAsFile(destinationPath) {
if (!this._isOperationResult) {
throw new Error('saveAsFile can only be called on operation result instances');
}
if (destinationPath) {
const actualFilePath = getActualTargetFilePath(destinationPath, this._extension);
logger.info(`Moving the file from temporary location ${this._fileSource} to ${actualFilePath}.`);
return moveFile(this._fileSource, actualFilePath, { overwrite: false })
.then(() => {
this._isOperationResult = false;
});
}
throw new Error('No destination path provided for saving file');
}
writeToStream(writableStream) {
if (!this._isOperationResult) {
throw new Error('writeToStream can only be called on operation result instances');
}
if (writableStream) {
logger.info(`Writing the file from temporary location ${this._fileSource} to writable stream.`);
const stream = fs.createReadStream(this._fileSource);
stream.on('end', () => {
fs.unlink(this._fileSource, err => {
if (err) {
throw err;
}
});
this._isOperationResult = false;
});
stream.pipe(writableStream);
} else {
throw new Error('No valid writable stream is provided');
}
}
}
module.exports = FileInfo;