@journeyapps/pdf-reports
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -14,4 +14,19 @@ import { PdfOptions, PdfResult } from "./pdf"; | ||
export interface DocRaptorOptions { | ||
name?: string; | ||
pipeline?: number; | ||
prince_options?: any; | ||
javascript?: boolean; | ||
ignore_console_messages?: boolean; | ||
ignore_resource_errors?: boolean; | ||
strict?: boolean; | ||
help?: boolean; | ||
tag?: string; | ||
test?: boolean; | ||
user_credentials?: string; | ||
doc?: any; | ||
document_content?: string; | ||
document_url?: string; | ||
type?: string; | ||
referrer?: string; | ||
async?: boolean; | ||
callback_url?: string; | ||
} |
@@ -29,9 +29,7 @@ "use strict"; | ||
const body = { | ||
doc: { | ||
type: 'pdf', | ||
javascript: true, | ||
test: options.test || apiKey == null, | ||
prince_options: { | ||
no_compress: false | ||
} | ||
type: 'pdf', | ||
javascript: true, | ||
test: options.test || apiKey == null, | ||
prince_options: { | ||
no_compress: false | ||
} | ||
@@ -42,10 +40,10 @@ }; | ||
} | ||
if (docraptor && docraptor.doc) { | ||
Object.assign(body.doc, docraptor.doc); | ||
if (docraptor && docraptor) { | ||
Object.assign(body, docraptor); | ||
} | ||
if (options.html) { | ||
body.doc.html_content = options.html; | ||
body.document_content = options.html; | ||
} | ||
else if (options.url) { | ||
body.doc.document_url = options.url; | ||
body.document_url = options.url; | ||
} | ||
@@ -66,2 +64,1 @@ const response = yield node_fetch_1.default('https://docraptor.com/docs', { | ||
exports.generatePdfDocRaptor = generatePdfDocRaptor; | ||
//# sourceMappingURL=docraptor.js.map |
@@ -9,2 +9,1 @@ "use strict"; | ||
__export(require("./s3")); | ||
//# sourceMappingURL=index.js.map |
@@ -8,8 +8,27 @@ /// <reference types="node" /> | ||
*/ | ||
export declare function generatePdf(options: PdfGeneratorOptions): Promise<GeneratedPdfResult>; | ||
export declare function generatePdf(options: PdfGeneratorOptions): Promise<PdfResult>; | ||
/** | ||
* Class represening the result of a generated PDF. | ||
* | ||
* Depending on the method used to generate the DPF, the buffer may be | ||
* in memory already, or may have to be downloaded first. | ||
*/ | ||
export declare class PdfResult { | ||
private _buffer; | ||
protected _buffer: Buffer; | ||
constructor(buffer?: Buffer); | ||
/** | ||
* Return a Buffer with the PDF data. | ||
* | ||
* The data is downloaded if required. | ||
*/ | ||
toBuffer(): Promise<Buffer>; | ||
/** | ||
* Same as toBuffer(), but converts the data to a base64-encoded string. | ||
*/ | ||
toBase64(): Promise<string>; | ||
/** | ||
* Formats the generated for inclusion in an email as an attachment. | ||
* | ||
* @param name - the name for the file | ||
*/ | ||
toEmailAttachment(name: string): Promise<{ | ||
@@ -16,0 +35,0 @@ content: string; |
@@ -67,2 +67,8 @@ "use strict"; | ||
} | ||
/** | ||
* Class represening the result of a generated PDF. | ||
* | ||
* Depending on the method used to generate the DPF, the buffer may be | ||
* in memory already, or may have to be downloaded first. | ||
*/ | ||
class PdfResult { | ||
@@ -72,2 +78,7 @@ constructor(buffer) { | ||
} | ||
/** | ||
* Return a Buffer with the PDF data. | ||
* | ||
* The data is downloaded if required. | ||
*/ | ||
toBuffer() { | ||
@@ -84,2 +95,5 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
/** | ||
* Same as toBuffer(), but converts the data to a base64-encoded string. | ||
*/ | ||
toBase64() { | ||
@@ -90,2 +104,7 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
/** | ||
* Formats the generated for inclusion in an email as an attachment. | ||
* | ||
* @param name - the name for the file | ||
*/ | ||
toEmailAttachment(name) { | ||
@@ -124,2 +143,1 @@ return __awaiter(this, void 0, void 0, function* () { | ||
exports.GeneratedPdfResult = GeneratedPdfResult; | ||
//# sourceMappingURL=pdf.js.map |
@@ -6,2 +6,6 @@ /// <reference types="node" /> | ||
* | ||
* This has roughly the same effect as (await generatePdf(options)).uploadToS3(s3options). | ||
* However, this version is more efficient, since the service uploads directly to the S3 bucket | ||
* when generating the PDF, instead of first downloading it locally and then uploading it again. | ||
* | ||
* @param options - pdf options | ||
@@ -11,2 +15,14 @@ * @param upload - s3 options | ||
export declare function generateAndUploadPdf(options: PdfGeneratorOptions, upload: S3UploadOptions): Promise<S3UploadResult>; | ||
/** | ||
* Upload the PDF to S3. | ||
* | ||
* Note: It is more efficient to use the generateAndUploadPdf method, which | ||
* uploads to S3 directly from the PDF service, instead of first downloading | ||
* and then uploading again. | ||
* | ||
* When using DocRaptor, this is the only option for uploading to S3. | ||
* | ||
* @param options - S3 details and credentials | ||
*/ | ||
export declare function uploadToS3(pdf: Buffer | PdfResult, options: S3UploadOptions): Promise<S3UploadResult>; | ||
export declare class S3UploadResult extends PdfResult { | ||
@@ -17,10 +33,16 @@ readonly path: string; | ||
private readonly s3Options; | ||
constructor(path: string, options: S3UploadOptions); | ||
constructor(path: string, options: S3UploadOptions, buffer?: Buffer); | ||
/** | ||
* Return a signed URL, that can be used in an email for example. | ||
* | ||
* @param expiresAfterSeconds - number of seconds after which the URL will expire. Defaults to 7 days. | ||
*/ | ||
getSignedUrl(expiresAfterSeconds?: number): any; | ||
protected download(): Promise<Buffer>; | ||
} | ||
export interface S3Options { | ||
export interface S3Credentials { | ||
region: string; | ||
accessKeyId?: string; | ||
secretAccessKey?: string; | ||
sessionToken?: string; | ||
} | ||
@@ -43,3 +65,3 @@ export interface S3UploadOptions { | ||
*/ | ||
s3Options: S3Options; | ||
credentials: S3Credentials; | ||
} |
@@ -16,2 +16,6 @@ "use strict"; | ||
* | ||
* This has roughly the same effect as (await generatePdf(options)).uploadToS3(s3options). | ||
* However, this version is more efficient, since the service uploads directly to the S3 bucket | ||
* when generating the PDF, instead of first downloading it locally and then uploading it again. | ||
* | ||
* @param options - pdf options | ||
@@ -24,4 +28,4 @@ * @param upload - s3 options | ||
const bucketName = upload.bucket; | ||
const s3Options = upload.s3Options; | ||
const s3 = new AWS.S3(s3Options); | ||
const credentials = upload.credentials; | ||
const s3 = new AWS.S3(credentials); | ||
const path = (upload.prefix || '') + upload.name; | ||
@@ -38,4 +42,39 @@ const url = s3.getSignedUrl('putObject', { | ||
exports.generateAndUploadPdf = generateAndUploadPdf; | ||
/** | ||
* Upload the PDF to S3. | ||
* | ||
* Note: It is more efficient to use the generateAndUploadPdf method, which | ||
* uploads to S3 directly from the PDF service, instead of first downloading | ||
* and then uploading again. | ||
* | ||
* When using DocRaptor, this is the only option for uploading to S3. | ||
* | ||
* @param options - S3 details and credentials | ||
*/ | ||
function uploadToS3(pdf, options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const AWS = require('aws-sdk'); | ||
let buffer; | ||
if (pdf instanceof Buffer) { | ||
buffer = pdf; | ||
} | ||
else { | ||
buffer = yield pdf.toBuffer(); | ||
} | ||
const bucketName = options.bucket; | ||
const credentials = options.credentials; | ||
const s3 = new AWS.S3(credentials); | ||
const path = (options.prefix || '') + options.name; | ||
yield s3.putObject({ | ||
Bucket: options.bucket, | ||
Key: path, | ||
Body: buffer, | ||
ContentType: 'application/pdf' | ||
}).promise(); | ||
return new S3UploadResult(path, options, buffer); | ||
}); | ||
} | ||
exports.uploadToS3 = uploadToS3; | ||
class S3UploadResult extends pdf_1.PdfResult { | ||
constructor(path, options) { | ||
constructor(path, options, buffer) { | ||
super(); | ||
@@ -45,3 +84,11 @@ this.bucket = options.bucket; | ||
this.name = options.name; | ||
if (buffer) { | ||
this._buffer = buffer; | ||
} | ||
} | ||
/** | ||
* Return a signed URL, that can be used in an email for example. | ||
* | ||
* @param expiresAfterSeconds - number of seconds after which the URL will expire. Defaults to 7 days. | ||
*/ | ||
getSignedUrl(expiresAfterSeconds) { | ||
@@ -73,2 +120,1 @@ const AWS = require('aws-sdk'); | ||
exports.S3UploadResult = S3UploadResult; | ||
//# sourceMappingURL=s3.js.map |
{ | ||
"name": "@journeyapps/pdf-reports", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"main": "lib/index.js", | ||
@@ -9,4 +9,5 @@ "repository": "https://github.com/journeyapps/pdf-reports", | ||
"scripts": { | ||
"prepack": "rm -rf ./lib && export NODE_ENV=production && ./node_modules/.bin/tsc -p tsconfig.json", | ||
"postversion": "git push origin $(git rev-parse --abbrev-ref HEAD) --tags" | ||
"prepack": "rm -rf ./lib && export NODE_ENV=production && ./node_modules/.bin/tsc --project tsconfig.production.json", | ||
"postversion": "git push origin $(git rev-parse --abbrev-ref HEAD) --tags", | ||
"test": "./node_modules/.bin/mocha src/**/*.spec.ts" | ||
}, | ||
@@ -18,6 +19,13 @@ "peerDependencies": { | ||
"devDependencies": { | ||
"@types/chai": "^4.0.10", | ||
"@types/mocha": "^2.2.44", | ||
"@types/node": "^8.0.53", | ||
"@types/node-fetch": "^1.6.7", | ||
"aws-sdk": "^2.168.0", | ||
"chai": "^4.1.2", | ||
"mocha": "^4.0.1", | ||
"node-fetch": "^1.7.3", | ||
"ts-node": "^4.0.1", | ||
"typescript": "^2.6.2" | ||
} | ||
} |
125
README.md
@@ -9,1 +9,126 @@ # pdf-reports | ||
# Usage | ||
## Basic Usage | ||
```js | ||
const pdf = require("@journeyapps/pdf-reports"); | ||
const fs = require("fs"); | ||
pdf.setApiToken(process.env.JOURNEY_PDF_KEY); | ||
async function test() { | ||
const result = await pdf.generatePdf({ html: "<h1>Test Pdf</h1>" }); | ||
const buffer = await result.toBuffer(); | ||
fs.writeFileSync("out.pdf", buffer); | ||
} | ||
test().catch(console.error); | ||
``` | ||
## Upload to S3 | ||
```js | ||
const pdf = require("@journeyapps/pdf-reports"); | ||
const fs = require("fs"); | ||
pdf.setApiToken(process.env.JOURNEY_PDF_KEY); | ||
const BASE_UPLOAD_CONFIG = { | ||
bucket: process.env.JOURNEY_PDF_BUCKET, | ||
prefix: 'test-reports/', | ||
credentials: { | ||
accessKeyId: process.env.AWS_ACCESS_KEY_ID, | ||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, | ||
region: 'us-east-1' | ||
} | ||
}; | ||
async function test() { | ||
// This function uploads the PDF directly to S3 from the service, | ||
// no intermediate download is required. | ||
const result = await pdf.generateAndUploadPdf({ | ||
html: "<h1>Test PDF</h1>", | ||
{name: 'test1.pdf', ...BASE_UPLOAD_CONFIG} | ||
}); | ||
// URL is valid for 7 days by default | ||
const url = result.getSignedUrl(); | ||
console.log('url', url); | ||
} | ||
test().catch(console.error); | ||
``` | ||
## Other Options | ||
```js | ||
// Generate from an online URL | ||
await pdf.generatePdf({ url: "https://en.wikipedia.org/wiki/Portable_Document_Format" }); | ||
// Specify print options | ||
await pdf.generatePdf({ | ||
html: "<h1>Test PDF</h1>", | ||
print: { | ||
// These are the defaults used by the service. | ||
// Specify any of these to override the value. | ||
landscape: false, | ||
displayHeaderFooter: false, | ||
printBackground: true, | ||
scale: 1, | ||
paperWidth: 8.27, // A4 | ||
paperHeight: 11.69, // A4 | ||
marginTop: 0, | ||
marginBottom: 0, | ||
marginLeft: 0, | ||
marginRight: 0, | ||
pageRanges: '' | ||
} | ||
}); | ||
``` | ||
## Using DocRaptor | ||
By default, a Chrome rendering service is used. To use DocRaptor instead, | ||
use the `generatePdfDocRaptor` function instead: | ||
```js | ||
const pdf = require("@journeyapps/pdf-reports"); | ||
const fs = require("fs"); | ||
pdf.setDocRaptorToken(process.env.DOCRAPTOR_TOKEN); | ||
async function test() { | ||
const result = await pdf.generatePdfDocRaptor({ | ||
html: "<h1>Test Pdf</h1>", | ||
docraptor: { | ||
// Any additional DocRaptor API options here | ||
} | ||
}); | ||
const buffer = await result.toBuffer(); | ||
fs.writeFileSync("out.pdf", buffer); | ||
// The PDF may be uploaded to S3 afterwards: | ||
const s3result = await pdf.uploadToS3(result, {name: 'test1.pdf', ...BASE_UPLOAD_CONFIG}}); | ||
const url = s3result.getSignedUrl(); | ||
console.log('url', url); | ||
} | ||
test().catch(console.error); | ||
``` | ||
# Development | ||
## Setup | ||
Clone this repo, then run: | ||
yarn | ||
## Tests | ||
To run the tests, the following environment variables are required: | ||
JOURNEY_PDF_KEY # Key for the PDF service | ||
JOURNEY_PDF_BUCKET # AWS bucket name to store test reports | ||
# AWS Credentials | ||
AWS_ACCESS_KEY_ID | ||
AWS_SECRET_ACCESS_KEY | ||
Then run: | ||
yarn test |
@@ -19,10 +19,8 @@ import fetch from "node-fetch"; | ||
const apiKey = (docraptor && docraptor.user_credentials) || docRaptorToken; | ||
const body: any = { | ||
doc: { | ||
type: 'pdf', | ||
javascript: true, | ||
test: options.test || apiKey == null, | ||
prince_options: { | ||
no_compress: false | ||
} | ||
const body: DocRaptorOptions = { | ||
type: 'pdf', | ||
javascript: true, | ||
test: options.test || apiKey == null, | ||
prince_options: { | ||
no_compress: false | ||
} | ||
@@ -33,10 +31,10 @@ }; | ||
} | ||
if (docraptor && docraptor.doc) { | ||
Object.assign(body.doc, docraptor.doc); | ||
if (docraptor && docraptor) { | ||
Object.assign(body, docraptor); | ||
} | ||
if (options.html) { | ||
body.doc.html_content = options.html; | ||
body.document_content = options.html; | ||
} else if(options.url) { | ||
body.doc.document_url = options.url; | ||
body.document_url = options.url; | ||
} | ||
@@ -65,4 +63,23 @@ | ||
export interface DocRaptorOptions { | ||
name?: string; | ||
pipeline?: number; | ||
prince_options?: any; | ||
javascript?: boolean; | ||
ignore_console_messages?: boolean; | ||
ignore_resource_errors?: boolean; | ||
strict?: boolean; | ||
help?: boolean; | ||
tag?: string; | ||
// Our library already configures these options | ||
test?: boolean; | ||
user_credentials?: string; | ||
doc?: any; | ||
document_content?: string; | ||
document_url?: string; | ||
// These options are not supported by us, but we document it anyway | ||
type?: string; | ||
referrer?: string; | ||
async?: boolean; | ||
callback_url?: string; | ||
} |
import fetch from "node-fetch"; | ||
import { S3Credentials } from "./index"; | ||
import { S3UploadOptions, uploadToS3 } from "./s3"; | ||
@@ -14,3 +16,3 @@ var globalToken: string = null; | ||
*/ | ||
export async function generatePdf(options: PdfGeneratorOptions) { | ||
export async function generatePdf(options: PdfGeneratorOptions): Promise<PdfResult> { | ||
const token = options.token || globalToken; | ||
@@ -60,5 +62,10 @@ if (token == null) { | ||
/** | ||
* Class represening the result of a generated PDF. | ||
* | ||
* Depending on the method used to generate the DPF, the buffer may be | ||
* in memory already, or may have to be downloaded first. | ||
*/ | ||
export class PdfResult { | ||
private _buffer: Buffer; | ||
protected _buffer: Buffer; | ||
@@ -69,2 +76,7 @@ constructor(buffer?: Buffer) { | ||
/** | ||
* Return a Buffer with the PDF data. | ||
* | ||
* The data is downloaded if required. | ||
*/ | ||
async toBuffer(): Promise<Buffer> { | ||
@@ -81,2 +93,5 @@ if (!this._buffer) { | ||
/** | ||
* Same as toBuffer(), but converts the data to a base64-encoded string. | ||
*/ | ||
async toBase64(): Promise<string> { | ||
@@ -86,2 +101,7 @@ return (await this.toBuffer()).toString('base64'); | ||
/** | ||
* Formats the generated for inclusion in an email as an attachment. | ||
* | ||
* @param name - the name for the file | ||
*/ | ||
async toEmailAttachment(name: string) { | ||
@@ -88,0 +108,0 @@ return { |
@@ -8,2 +8,6 @@ import { generatePdf, PdfGeneratorOptions, PdfResult } from "./pdf"; | ||
* | ||
* This has roughly the same effect as (await generatePdf(options)).uploadToS3(s3options). | ||
* However, this version is more efficient, since the service uploads directly to the S3 bucket | ||
* when generating the PDF, instead of first downloading it locally and then uploading it again. | ||
* | ||
* @param options - pdf options | ||
@@ -16,4 +20,4 @@ * @param upload - s3 options | ||
const bucketName = upload.bucket; | ||
const s3Options = upload.s3Options; | ||
const s3 = new AWS.S3(s3Options); | ||
const credentials = upload.credentials; | ||
const s3 = new AWS.S3(credentials); | ||
@@ -33,2 +37,39 @@ const path = (upload.prefix || '') + upload.name; | ||
/** | ||
* Upload the PDF to S3. | ||
* | ||
* Note: It is more efficient to use the generateAndUploadPdf method, which | ||
* uploads to S3 directly from the PDF service, instead of first downloading | ||
* and then uploading again. | ||
* | ||
* When using DocRaptor, this is the only option for uploading to S3. | ||
* | ||
* @param options - S3 details and credentials | ||
*/ | ||
export async function uploadToS3(pdf: Buffer | PdfResult, options: S3UploadOptions): Promise<S3UploadResult> { | ||
const AWS = require('aws-sdk'); | ||
let buffer: Buffer; | ||
if (pdf instanceof Buffer) { | ||
buffer = pdf; | ||
} else { | ||
buffer = await pdf.toBuffer(); | ||
} | ||
const bucketName = options.bucket; | ||
const credentials = options.credentials; | ||
const s3 = new AWS.S3(credentials); | ||
const path = (options.prefix || '') + options.name; | ||
await s3.putObject({ | ||
Bucket: options.bucket, | ||
Key: path, | ||
Body: buffer, | ||
ContentType: 'application/pdf' | ||
}).promise(); | ||
return new S3UploadResult(path, options, buffer); | ||
} | ||
export class S3UploadResult extends PdfResult { | ||
@@ -38,5 +79,5 @@ readonly path: string; | ||
readonly bucket: string; | ||
private readonly s3Options: S3Options; | ||
private readonly s3Options: S3Credentials; | ||
constructor(path: string, options: S3UploadOptions) { | ||
constructor(path: string, options: S3UploadOptions, buffer?: Buffer) { | ||
super(); | ||
@@ -46,4 +87,12 @@ this.bucket = options.bucket; | ||
this.name = options.name; | ||
if (buffer) { | ||
this._buffer = buffer; | ||
} | ||
} | ||
/** | ||
* Return a signed URL, that can be used in an email for example. | ||
* | ||
* @param expiresAfterSeconds - number of seconds after which the URL will expire. Defaults to 7 days. | ||
*/ | ||
getSignedUrl(expiresAfterSeconds?: number) { | ||
@@ -78,6 +127,7 @@ const AWS = require('aws-sdk'); | ||
export interface S3Options { | ||
export interface S3Credentials { | ||
region: string; | ||
accessKeyId?: string; | ||
secretAccessKey?: string; | ||
sessionToken?: string; | ||
} | ||
@@ -104,3 +154,3 @@ | ||
*/ | ||
s3Options: S3Options; | ||
credentials: S3Credentials; | ||
} |
@@ -13,3 +13,3 @@ { | ||
"rootDir": "src", | ||
"declaration": true, | ||
"declaration": false, | ||
"allowJs": false, | ||
@@ -25,5 +25,4 @@ "types": [ | ||
"exclude": [ | ||
"node_modules/**/*", | ||
"**/*.spec.ts" | ||
"node_modules/**/*" | ||
] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
51010
975
134
2
10
24