Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
47f7cb18b5 | |||
3faf065c66 | |||
dfffd03790 | |||
796aa905d2 | |||
253fb95143 | |||
f3ea075b72 | |||
af725a7f78 | |||
016e0db797 | |||
4cf8b2e1f8 | |||
67b0aa9d47 | |||
567c6eafea | |||
ff890fb2af | |||
a512fd64b5 | |||
377318a62a | |||
671c871304 | |||
e0cc6b5655 | |||
e74b44b49c | |||
d6f0d88d4a | |||
9674e5b8dc | |||
ea4cf777a9 | |||
8a308fa9e3 | |||
56fa53b701 | |||
2a4ddd4e41 | |||
3d8a63fddd | |||
9d9b1d0399 | |||
739d60d410 | |||
9003034d0d | |||
5002513d21 | |||
12ede2be02 | |||
163ec2bd50 | |||
7744839613 | |||
df803d90cb | |||
5fc22585bf | |||
b8387458db | |||
04aed2556b | |||
4cde3a7fe0 | |||
466d6d47ba |
4
.gitignore
vendored
4
.gitignore
vendored
@ -15,8 +15,6 @@ node_modules/
|
|||||||
|
|
||||||
# builds
|
# builds
|
||||||
dist/
|
dist/
|
||||||
dist_web/
|
dist_*/
|
||||||
dist_serve/
|
|
||||||
dist_ts_web/
|
|
||||||
|
|
||||||
# custom
|
# custom
|
@ -19,22 +19,35 @@ mirror:
|
|||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci git mirror
|
- npmci git mirror
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
- lossless
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
- notpriv
|
||||||
|
|
||||||
snyk:
|
auditProductionDependencies:
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:snyk
|
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
|
stage: security
|
||||||
|
script:
|
||||||
|
- npmci npm prepare
|
||||||
|
- npmci command npm install --production --ignore-scripts
|
||||||
|
- npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
- npmci command npm audit --audit-level=high --only=prod --production
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
|
||||||
|
auditDevDependencies:
|
||||||
|
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
- npmci command npm install --ignore-scripts
|
- npmci command npm install --ignore-scripts
|
||||||
- npmci command snyk test
|
- npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
- npmci command npm audit --audit-level=high --only=dev
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
allow_failure: true
|
||||||
|
|
||||||
# ====================
|
# ====================
|
||||||
# test stage
|
# test stage
|
||||||
@ -49,9 +62,7 @@ testStable:
|
|||||||
- npmci npm test
|
- npmci npm test
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- priv
|
|
||||||
|
|
||||||
testBuild:
|
testBuild:
|
||||||
stage: test
|
stage: test
|
||||||
@ -62,9 +73,7 @@ testBuild:
|
|||||||
- npmci command npm run build
|
- npmci command npm run build
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
stage: release
|
stage: release
|
||||||
@ -84,6 +93,8 @@ release:
|
|||||||
codequality:
|
codequality:
|
||||||
stage: metadata
|
stage: metadata
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
script:
|
script:
|
||||||
- npmci command npm install -g tslint typescript
|
- npmci command npm install -g tslint typescript
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
|
29
.vscode/launch.json
vendored
Normal file
29
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "current file",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"args": [
|
||||||
|
"${relativeFile}"
|
||||||
|
],
|
||||||
|
"runtimeArgs": ["-r", "@gitzone/tsrun"],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"protocol": "inspector",
|
||||||
|
"internalConsoleOptions": "openOnSessionStart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "test.ts",
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"args": [
|
||||||
|
"test/test.ts"
|
||||||
|
],
|
||||||
|
"runtimeArgs": ["-r", "@gitzone/tsrun"],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"protocol": "inspector",
|
||||||
|
"internalConsoleOptions": "openOnSessionStart"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
.vscode/settings.json
vendored
Normal file
26
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"json.schemas": [
|
||||||
|
{
|
||||||
|
"fileMatch": ["/npmextra.json"],
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"npmci": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for npmci"
|
||||||
|
},
|
||||||
|
"gitzone": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for gitzone",
|
||||||
|
"properties": {
|
||||||
|
"projectType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
"npmAccessLevel": "public"
|
"npmAccessLevel": "public"
|
||||||
},
|
},
|
||||||
"gitzone": {
|
"gitzone": {
|
||||||
|
"projectType": "npm",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "gitlab.com",
|
"githost": "gitlab.com",
|
||||||
"gitscope": "pushrocks",
|
"gitscope": "pushrocks",
|
||||||
|
18431
package-lock.json
generated
18431
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
47
package.json
47
package.json
@ -1,44 +1,49 @@
|
|||||||
{
|
{
|
||||||
"name": "@pushrocks/smartpdf",
|
"name": "@pushrocks/smartpdf",
|
||||||
"version": "2.0.1",
|
"version": "3.0.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "create pdfs on the fly",
|
"description": "create pdfs on the fly",
|
||||||
"main": "dist/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
|
"type": "module",
|
||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(tstest test/)",
|
"test": "(tstest test/ --web)",
|
||||||
"format": "(gitzone format)",
|
"build": "(tsbuild --web --allowimplicitany)"
|
||||||
"build": "(tsbuild)"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.17",
|
"@gitzone/tsbuild": "^2.1.60",
|
||||||
"@gitzone/tsrun": "^1.2.8",
|
"@gitzone/tsrun": "^1.2.31",
|
||||||
"@gitzone/tstest": "^1.0.28",
|
"@gitzone/tstest": "^1.0.69",
|
||||||
"@pushrocks/tapbundle": "^3.0.13",
|
"@pushrocks/tapbundle": "^5.0.3",
|
||||||
"@types/node": "^12.12.8",
|
"@types/node": "^17.0.23"
|
||||||
"tslint": "^6.0.0-beta0",
|
|
||||||
"tslint-config-prettier": "^1.18.0"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pushrocks/smartfile": "^7.0.6",
|
"@pushrocks/smartfile": "^9.0.6",
|
||||||
"@pushrocks/smartnetwork": "^1.1.14",
|
"@pushrocks/smartnetwork": "^2.0.14",
|
||||||
"@pushrocks/smartpromise": "^3.0.6",
|
"@pushrocks/smartpath": "^5.0.5",
|
||||||
"@pushrocks/smartpuppeteer": "^1.0.11",
|
"@pushrocks/smartpromise": "^3.1.7",
|
||||||
"@pushrocks/smartunique": "^3.0.1",
|
"@pushrocks/smartpuppeteer": "^2.0.0",
|
||||||
"@types/express": "^4.17.2",
|
"@pushrocks/smartunique": "^3.0.3",
|
||||||
"express": "^4.17.1"
|
"@types/express": "^4.17.13",
|
||||||
|
"express": "^4.17.3",
|
||||||
|
"pdf-merger-js": "^3.4.0",
|
||||||
|
"pdf2json": "^2.0.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
"ts_web/**/*",
|
"ts_web/**/*",
|
||||||
"dist/**/*",
|
"dist/**/*",
|
||||||
"dist_web/**/*",
|
"dist_*/**/*",
|
||||||
|
"dist_ts/**/*",
|
||||||
"dist_ts_web/**/*",
|
"dist_ts_web/**/*",
|
||||||
"assets/**/*",
|
"assets/**/*",
|
||||||
"cli.js",
|
"cli.js",
|
||||||
"npmextra.json",
|
"npmextra.json",
|
||||||
"readme.md"
|
"readme.md"
|
||||||
|
],
|
||||||
|
"browserslist": [
|
||||||
|
"last 1 chrome versions"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
24
readme.md
24
readme.md
@ -8,16 +8,26 @@ Create PDFs fast and smoothly
|
|||||||
* [docs (typedoc)](https://pushrocks.gitlab.io/smartpdf/)
|
* [docs (typedoc)](https://pushrocks.gitlab.io/smartpdf/)
|
||||||
|
|
||||||
## Status for master
|
## Status for master
|
||||||
[](https://gitlab.com/pushrocks/smartpdf/commits/master)
|
|
||||||
[](https://gitlab.com/pushrocks/smartpdf/commits/master)
|
Status Category | Status Badge
|
||||||
[](https://www.npmjs.com/package/@pushrocks/smartpdf)
|
-- | --
|
||||||
[](https://snyk.io/test/npm/@pushrocks/smartpdf)
|
GitLab Pipelines | [](https://lossless.cloud)
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
GitLab Pipline Test Coverage | [](https://lossless.cloud)
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
npm | [](https://lossless.cloud)
|
||||||
[](https://prettier.io/)
|
Snyk | [](https://lossless.cloud)
|
||||||
|
TypeScript Support | [](https://lossless.cloud)
|
||||||
|
node Support | [](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
||||||
|
Code Style | [](https://lossless.cloud)
|
||||||
|
PackagePhobia (total standalone install weight) | [](https://lossless.cloud)
|
||||||
|
PackagePhobia (package size on registry) | [](https://lossless.cloud)
|
||||||
|
BundlePhobia (total size when bundled) | [](https://lossless.cloud)
|
||||||
|
Platform support | [](https://lossless.cloud) [](https://lossless.cloud)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
|
||||||
|
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
|
38
test/test.ts
38
test/test.ts
@ -1,11 +1,11 @@
|
|||||||
import { expect, tap } from '@pushrocks/tapbundle';
|
import { expect, tap } from '@pushrocks/tapbundle';
|
||||||
import * as smartpdf from '../ts/index';
|
import * as smartpdf from '../ts/index.js';
|
||||||
|
|
||||||
let testSmartPdf: smartpdf.SmartPdf;
|
let testSmartPdf: smartpdf.SmartPdf;
|
||||||
|
|
||||||
tap.test('should create a valid instance of smartpdf', async () => {
|
tap.test('should create a valid instance of smartpdf', async () => {
|
||||||
testSmartPdf = new smartpdf.SmartPdf();
|
testSmartPdf = new smartpdf.SmartPdf();
|
||||||
expect(testSmartPdf).to.be.instanceof(smartpdf.SmartPdf);
|
expect(testSmartPdf).toBeInstanceOf(smartpdf.SmartPdf);
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should start the instance', async () => {
|
tap.test('should start the instance', async () => {
|
||||||
@ -13,7 +13,11 @@ tap.test('should start the instance', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should create a pdf from html string', async () => {
|
tap.test('should create a pdf from html string', async () => {
|
||||||
await testSmartPdf.getPdfResultForHtmlString('hi');
|
await testSmartPdf.getA4PdfResultForHtmlString('hi');
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should create a pdf from html string', async () => {
|
||||||
|
await testSmartPdf.getA4PdfResultForHtmlString('hi');
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should create a pdf from website as A4', async () => {
|
tap.test('should create a pdf from website as A4', async () => {
|
||||||
@ -25,18 +29,28 @@ tap.test('should create a pdf from website as single page PDF', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tap.test('should create a valid PDFResult', async () => {
|
tap.test('should create a valid PDFResult', async () => {
|
||||||
const pdfResult = await testSmartPdf.getFullWebsiteAsSinglePdf(
|
const writePDfToDisk = async (urlArg: string, fileName: string) => {
|
||||||
'https://maintainedby.lossless.com'
|
const pdfResult = await testSmartPdf.getFullWebsiteAsSinglePdf(urlArg);
|
||||||
);
|
expect(pdfResult.buffer).toBeInstanceOf(Buffer);
|
||||||
expect(pdfResult.buffer).to.be.instanceOf(Buffer);
|
const fs = await import('fs');
|
||||||
const fs = await import('fs');
|
|
||||||
|
|
||||||
if (!fs.existsSync('.nogit/')) {
|
if (!fs.existsSync('.nogit/')) {
|
||||||
fs.mkdirSync('.nogit/');
|
fs.mkdirSync('.nogit/');
|
||||||
}
|
}
|
||||||
fs.writeFileSync('.nogit/sample.pdf', pdfResult.buffer);
|
fs.writeFileSync(`.nogit/${fileName}`, pdfResult.buffer);
|
||||||
|
};
|
||||||
|
await writePDfToDisk('https://maintainedby.lossless.com/', '1.pdf')
|
||||||
|
await writePDfToDisk('https://rendertron.lossless.one/render/https://fitnessloft.de/impressum/', '2.pdf')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should combine pdfs', async () => {
|
||||||
|
const fs = await import('fs');
|
||||||
|
const buffer1 = fs.readFileSync('.nogit/1.pdf');
|
||||||
|
const buffer2 = fs.readFileSync('.nogit/2.pdf');
|
||||||
|
fs.writeFileSync(`.nogit/combined.pdf`, await testSmartPdf.mergePdfBuffers([buffer1, buffer2]));
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
tap.test('should be able to close properly', async () => {
|
tap.test('should be able to close properly', async () => {
|
||||||
await testSmartPdf.stop();
|
await testSmartPdf.stop();
|
||||||
});
|
});
|
||||||
|
@ -6,4 +6,4 @@ declare global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// normal
|
// normal
|
||||||
export * from './smartpdf.classes.smartpdf';
|
export * from './smartpdf.classes.smartpdf.js';
|
||||||
|
@ -1 +1 @@
|
|||||||
export * from './interface.pdfresult';
|
export * from './interface.pdfresult.js';
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
export interface IPdfResult {
|
export interface IPdfResult {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
metadata: {
|
||||||
|
textExtraction: string;
|
||||||
|
};
|
||||||
buffer: Buffer;
|
buffer: Buffer;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import * as plugins from './smartpdf.plugins';
|
import * as plugins from './smartpdf.plugins.js';
|
||||||
|
|
||||||
export class PdfCandidate {
|
export class PdfCandidate {
|
||||||
pdfId = plugins.smartunique.shortId();
|
public htmlString: string;
|
||||||
doneDeferred = plugins.smartpromise.defer();
|
public pdfId = plugins.smartunique.shortId();
|
||||||
|
public doneDeferred = plugins.smartpromise.defer();
|
||||||
|
|
||||||
constructor(public htmlString) {}
|
constructor(htmlStringArg: string) {
|
||||||
|
this.htmlString = htmlStringArg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import * as plugins from './smartpdf.plugins';
|
import * as plugins from './smartpdf.plugins.js';
|
||||||
import * as paths from './smartpdf.paths';
|
import * as paths from './smartpdf.paths.js';
|
||||||
import { Server } from 'http';
|
import { Server } from 'http';
|
||||||
import { PdfCandidate } from './smartpdf.classes.pdfcandidate';
|
import { PdfCandidate } from './smartpdf.classes.pdfcandidate.js';
|
||||||
|
|
||||||
declare const document;
|
declare const document: any;
|
||||||
|
|
||||||
import * as interfaces from './interfaces';
|
import * as interfaces from './interfaces/index.js';
|
||||||
|
|
||||||
export class SmartPdf {
|
export class SmartPdf {
|
||||||
htmlServerInstance: Server;
|
htmlServerInstance: Server;
|
||||||
@ -19,7 +19,7 @@ export class SmartPdf {
|
|||||||
this._readyDeferred = new plugins.smartpromise.Deferred();
|
this._readyDeferred = new plugins.smartpromise.Deferred();
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(headlessBrowserArg?) {
|
async start(headlessBrowserArg?: plugins.smartpuppeteer.puppeteer.Browser) {
|
||||||
// lets set the external browser in case one is provided
|
// lets set the external browser in case one is provided
|
||||||
this.headlessBrowser = headlessBrowserArg;
|
this.headlessBrowser = headlessBrowserArg;
|
||||||
// setup puppeteer
|
// setup puppeteer
|
||||||
@ -27,7 +27,7 @@ export class SmartPdf {
|
|||||||
this.externalBrowserBool = true;
|
this.externalBrowserBool = true;
|
||||||
} else {
|
} else {
|
||||||
this.headlessBrowser = await plugins.smartpuppeteer.getEnvAwareBrowserInstance({
|
this.headlessBrowser = await plugins.smartpuppeteer.getEnvAwareBrowserInstance({
|
||||||
forceNoSandbox: true
|
forceNoSandbox: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ export class SmartPdf {
|
|||||||
});
|
});
|
||||||
this.htmlServerInstance = plugins.http.createServer(app);
|
this.htmlServerInstance = plugins.http.createServer(app);
|
||||||
const smartnetworkInstance = new plugins.smartnetwork.SmartNetwork();
|
const smartnetworkInstance = new plugins.smartnetwork.SmartNetwork();
|
||||||
const portAvailable = smartnetworkInstance.isLocalPortAvailable(3210);
|
const portAvailable = smartnetworkInstance.isLocalPortUnused(3210);
|
||||||
this.htmlServerInstance.listen(3210, 'localhost');
|
this.htmlServerInstance.listen(3210, 'localhost');
|
||||||
this.htmlServerInstance.on('listening', () => {
|
this.htmlServerInstance.on('listening', () => {
|
||||||
this._readyDeferred.resolve();
|
this._readyDeferred.resolve();
|
||||||
@ -63,13 +63,17 @@ export class SmartPdf {
|
|||||||
/**
|
/**
|
||||||
* returns a pdf for a given html string;
|
* returns a pdf for a given html string;
|
||||||
*/
|
*/
|
||||||
async getPdfResultForHtmlString(htmlStringArg: string): Promise<interfaces.IPdfResult> {
|
async getA4PdfResultForHtmlString(htmlStringArg: string): Promise<interfaces.IPdfResult> {
|
||||||
await this._readyDeferred.promise;
|
await this._readyDeferred.promise;
|
||||||
const pdfCandidate = new PdfCandidate(htmlStringArg);
|
const pdfCandidate = new PdfCandidate(htmlStringArg);
|
||||||
this._candidates[pdfCandidate.pdfId] = pdfCandidate;
|
this._candidates[pdfCandidate.pdfId] = pdfCandidate;
|
||||||
const page = await this.headlessBrowser.newPage();
|
const page = await this.headlessBrowser.newPage();
|
||||||
|
await page.setViewport({
|
||||||
|
width: 794,
|
||||||
|
height: 1122,
|
||||||
|
});
|
||||||
const response = await page.goto(`http://localhost:3210/${pdfCandidate.pdfId}`, {
|
const response = await page.goto(`http://localhost:3210/${pdfCandidate.pdfId}`, {
|
||||||
waitUntil: 'networkidle2'
|
waitUntil: 'networkidle2',
|
||||||
});
|
});
|
||||||
const headers = response.headers();
|
const headers = response.headers();
|
||||||
if (headers['pdf-id'] !== pdfCandidate.pdfId) {
|
if (headers['pdf-id'] !== pdfCandidate.pdfId) {
|
||||||
@ -80,10 +84,10 @@ export class SmartPdf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pdfBuffer = await page.pdf({
|
const pdfBuffer = await page.pdf({
|
||||||
format: 'A4',
|
width: 794,
|
||||||
|
height: 1122,
|
||||||
printBackground: true,
|
printBackground: true,
|
||||||
displayHeaderFooter: false,
|
displayHeaderFooter: false,
|
||||||
preferCSSPageSize: true
|
|
||||||
});
|
});
|
||||||
await page.close();
|
await page.close();
|
||||||
delete this._candidates[pdfCandidate.pdfId];
|
delete this._candidates[pdfCandidate.pdfId];
|
||||||
@ -92,61 +96,107 @@ export class SmartPdf {
|
|||||||
return {
|
return {
|
||||||
id: pdfCandidate.pdfId,
|
id: pdfCandidate.pdfId,
|
||||||
name: `${pdfCandidate.pdfId}.js`,
|
name: `${pdfCandidate.pdfId}.js`,
|
||||||
buffer: pdfBuffer
|
metadata: {
|
||||||
|
textExtraction: await this.extractTextFromPdfBuffer(pdfBuffer),
|
||||||
|
},
|
||||||
|
buffer: pdfBuffer,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPdfResultForWebsite(websiteUrl: string): Promise<interfaces.IPdfResult> {
|
async getPdfResultForWebsite(websiteUrl: string): Promise<interfaces.IPdfResult> {
|
||||||
const page = await this.headlessBrowser.newPage();
|
const page = await this.headlessBrowser.newPage();
|
||||||
await page.emulateMedia('screen');
|
await page.setViewport({
|
||||||
|
width: 1980,
|
||||||
|
height: 1200,
|
||||||
|
});
|
||||||
|
await page.emulateMediaType('screen');
|
||||||
const response = await page.goto(websiteUrl, { waitUntil: 'networkidle2' });
|
const response = await page.goto(websiteUrl, { waitUntil: 'networkidle2' });
|
||||||
const pdfId = plugins.smartunique.shortId();
|
const pdfId = plugins.smartunique.shortId();
|
||||||
const { documentHeight, documentWidth } = await page.evaluate(() => {
|
const { documentHeight, documentWidth } = await page.evaluate(() => {
|
||||||
return {
|
return {
|
||||||
documentHeight: document.height,
|
documentHeight: document.height,
|
||||||
documentWidth: document.width
|
documentWidth: document.width,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const pdfBuffer = await page.pdf({
|
const pdfBuffer = await page.pdf({
|
||||||
format: 'A4',
|
height: documentHeight,
|
||||||
height: documentWidth,
|
|
||||||
width: documentWidth,
|
width: documentWidth,
|
||||||
printBackground: true,
|
printBackground: true,
|
||||||
displayHeaderFooter: false,
|
displayHeaderFooter: false,
|
||||||
preferCSSPageSize: true
|
|
||||||
});
|
});
|
||||||
await page.close();
|
await page.close();
|
||||||
return {
|
return {
|
||||||
id: pdfId,
|
id: pdfId,
|
||||||
name: `${pdfId}.js`,
|
name: `${pdfId}.js`,
|
||||||
buffer: pdfBuffer
|
metadata: {
|
||||||
|
textExtraction: await this.extractTextFromPdfBuffer(pdfBuffer),
|
||||||
|
},
|
||||||
|
buffer: pdfBuffer,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFullWebsiteAsSinglePdf(websiteUrl: string) {
|
async getFullWebsiteAsSinglePdf(websiteUrl: string): Promise<interfaces.IPdfResult> {
|
||||||
const page = await this.headlessBrowser.newPage();
|
const page = await this.headlessBrowser.newPage();
|
||||||
page.emulateMedia('screen');
|
await page.setViewport({
|
||||||
|
width: 1920,
|
||||||
|
height: 1200,
|
||||||
|
});
|
||||||
|
page.emulateMediaType('screen');
|
||||||
const response = await page.goto(websiteUrl, { waitUntil: 'networkidle2' });
|
const response = await page.goto(websiteUrl, { waitUntil: 'networkidle2' });
|
||||||
const pdfId = plugins.smartunique.shortId();
|
const pdfId = plugins.smartunique.shortId();
|
||||||
const { documentHeight, documentWidth } = await page.evaluate(() => {
|
const { documentHeight, documentWidth } = await page.evaluate(() => {
|
||||||
return {
|
return {
|
||||||
documentHeight: document.height,
|
documentHeight: document.body.scrollHeight,
|
||||||
documentWidth: document.width
|
documentWidth: document.body.clientWidth,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
await page.setViewport({
|
||||||
|
width: 1920,
|
||||||
|
height: documentHeight,
|
||||||
|
});
|
||||||
const pdfBuffer = await page.pdf({
|
const pdfBuffer = await page.pdf({
|
||||||
format: 'A4',
|
height: documentHeight,
|
||||||
height: documentWidth,
|
width: 1920,
|
||||||
width: documentWidth,
|
|
||||||
printBackground: true,
|
printBackground: true,
|
||||||
displayHeaderFooter: false,
|
displayHeaderFooter: false,
|
||||||
preferCSSPageSize: true
|
scale: 1,
|
||||||
|
pageRanges: '1'
|
||||||
});
|
});
|
||||||
await page.close();
|
await page.close();
|
||||||
return {
|
return {
|
||||||
id: pdfId,
|
id: pdfId,
|
||||||
name: `${pdfId}.js`,
|
name: `${pdfId}.js`,
|
||||||
buffer: pdfBuffer
|
metadata: {
|
||||||
|
textExtraction: await this.extractTextFromPdfBuffer(pdfBuffer),
|
||||||
|
},
|
||||||
|
buffer: pdfBuffer,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async mergePdfBuffers(pdfBuffers: Buffer[]): Promise<Buffer> {
|
||||||
|
const merger = new plugins.pdfMerger();
|
||||||
|
for (const buffer of pdfBuffers) {
|
||||||
|
merger.add(buffer);
|
||||||
|
}
|
||||||
|
return merger.saveAsBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async extractTextFromPdfBuffer(pdfBufferArg: Buffer): Promise<string> {
|
||||||
|
const deferred = plugins.smartpromise.defer<string>();
|
||||||
|
const pdfParser: any = new plugins.pdf2json();
|
||||||
|
pdfParser.on('pdfParser_dataReady', (pdfData: any) => {
|
||||||
|
let finalText = ''
|
||||||
|
for (const page of pdfData.Pages) {
|
||||||
|
for(const text of page.Texts) {
|
||||||
|
for (const letter of text.R) {
|
||||||
|
finalText = finalText + letter.T;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
deferred.resolve(finalText);
|
||||||
|
});
|
||||||
|
pdfParser.parseBuffer(pdfBufferArg);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
import * as plugins from './smartpdf.plugins';
|
import * as plugins from './smartpdf.plugins.js';
|
||||||
|
|
||||||
export const packageDir = plugins.path.join(__dirname, '../');
|
export const packageDir = plugins.path.join(plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), '../');
|
||||||
|
@ -7,13 +7,17 @@ export { http, path };
|
|||||||
// @pushrocks
|
// @pushrocks
|
||||||
import * as smartfile from '@pushrocks/smartfile';
|
import * as smartfile from '@pushrocks/smartfile';
|
||||||
import * as smartpromise from '@pushrocks/smartpromise';
|
import * as smartpromise from '@pushrocks/smartpromise';
|
||||||
|
import * as smartpath from '@pushrocks/smartpath';
|
||||||
import * as smartpuppeteer from '@pushrocks/smartpuppeteer';
|
import * as smartpuppeteer from '@pushrocks/smartpuppeteer';
|
||||||
import * as smartnetwork from '@pushrocks/smartnetwork';
|
import * as smartnetwork from '@pushrocks/smartnetwork';
|
||||||
import * as smartunique from '@pushrocks/smartunique';
|
import * as smartunique from '@pushrocks/smartunique';
|
||||||
|
|
||||||
export { smartfile, smartpromise, smartpuppeteer, smartunique, smartnetwork };
|
export { smartfile, smartpromise, smartpath, smartpuppeteer, smartunique, smartnetwork };
|
||||||
|
|
||||||
// thirdparty
|
// thirdparty
|
||||||
|
import pdfMerger from 'pdf-merger-js';
|
||||||
|
// @ts-ignore
|
||||||
|
import pdf2json from 'pdf2json';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
|
||||||
export { express };
|
export { pdfMerger, pdf2json, express };
|
||||||
|
8
tsconfig.json
Normal file
8
tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ES2022",
|
||||||
|
"moduleResolution": "nodenext"
|
||||||
|
}
|
||||||
|
}
|
17
tslint.json
17
tslint.json
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["tslint:latest", "tslint-config-prettier"],
|
|
||||||
"rules": {
|
|
||||||
"semicolon": [true, "always"],
|
|
||||||
"no-console": false,
|
|
||||||
"ordered-imports": false,
|
|
||||||
"object-literal-sort-keys": false,
|
|
||||||
"member-ordering": {
|
|
||||||
"options":{
|
|
||||||
"order": [
|
|
||||||
"static-method"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultSeverity": "warning"
|
|
||||||
}
|
|
Reference in New Issue
Block a user