@live-change/print-service 0.8.113 → 0.8.114

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ import config from './config.js'
2
+ import definition from './definition.js'
3
+
4
+ import { ObservableValue } from '@live-change/dao'
5
+
6
+ const authenticationKey = new ObservableValue(
7
+ config.printAuthenticationKey
8
+ )
9
+
10
+ definition.authenticator({
11
+ async prepareCredentials(credentials) {
12
+ //console.log("PRINT AUTHENTICATOR", credentials, authenticationKey.getValue())
13
+ if(credentials.sessionKey === authenticationKey.getValue()) {
14
+ credentials.roles.push('admin')
15
+ credentials.internal = true
16
+ }
17
+ }
18
+ })
19
+
20
+ const baseUrl = `http://${config.ssrHost}`+`:${config.ssrPort}`
21
+
22
+ export async function getAuthenticatedUrl(path, data) {
23
+ const encodedData = data && encodeURIComponent(JSON.stringify(data))
24
+ return baseUrl + path + (data ? '/' + encodedData : '') +`?sessionKey=${await authenticationKey.getValue()}`
25
+ }
package/browser.js CHANGED
@@ -4,7 +4,7 @@ const app = App.app()
4
4
  import definition from './definition.js'
5
5
  import config from './config.js'
6
6
 
7
- import { chrome } from 'playwright'
7
+ import { chromium } from 'playwright'
8
8
 
9
9
  import PQueue from 'p-queue'
10
10
  import got from "got"
@@ -13,20 +13,20 @@ const browserQueue = new PQueue({ concurrency: config.concurrency })
13
13
 
14
14
  async function newBrowser() {
15
15
  if(config.browserWebSocketDebuggerUrl) {
16
- const browser = await chrome.connect({ wsEndpoint: config.browserWebSocketDebuggerUrl })
16
+ const browser = await chromium.connect({ wsEndpoint: config.browserWebSocketDebuggerUrl })
17
17
  return browser
18
18
  } else if(config.browserUrl) {
19
19
  const browserInfo = await got.post(config.browserUrl + '/json/version').json()
20
- const browser = await chrome.connect({ wsEndpoint: browserInfo.webSocketDebuggerUrl })
20
+ const browser = await chromium.connect({ wsEndpoint: browserInfo.webSocketDebuggerUrl })
21
21
  } else {
22
- const browser = await chrome.launch()
22
+ const browser = await chromium.launch()
23
23
  return browser
24
24
  }
25
25
  }
26
26
 
27
27
  export async function runWithBrowser(func) {
28
28
  return await browserQueue.add(async () => {
29
- const browser = newBrowser()
29
+ const browser = await newBrowser()
30
30
  const result = await func(browser)
31
31
  await browser.close()
32
32
  return result
package/config.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import definition from './definition.js'
2
+ import crypto from 'crypto'
2
3
 
3
4
  const {
4
- browserUrl = 'http://localhost:9222',
5
+ browserUrl,
5
6
  browserWebSocketDebuggerUrl,
6
7
  concurrency = 1,
7
8
  printAuthenticationKey = crypto.randomBytes(24).toString('hex'),
package/index.js CHANGED
@@ -3,6 +3,11 @@ const app = App.app()
3
3
 
4
4
  import definition from './definition.js'
5
5
 
6
- import "./print.js"
6
+ import "./authentication.js"
7
+ import { printToPdfFileTask } from "./printPdf.js"
8
+ import { screenshotToFileTask } from "./screenshot.js"
9
+
10
+ export { printToPdfFileTask, screenshotToFileTask }
11
+
7
12
 
8
13
  export default definition
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/print-service",
3
- "version": "0.8.113",
3
+ "version": "0.8.114",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,13 +21,13 @@
21
21
  "url": "https://www.viamage.com/"
22
22
  },
23
23
  "dependencies": {
24
- "@live-change/framework": "^0.8.113",
25
- "@live-change/relations-plugin": "^0.8.113",
26
- "@live-change/user-service": "^0.8.113",
24
+ "@live-change/framework": "^0.8.114",
25
+ "@live-change/relations-plugin": "^0.8.114",
26
+ "@live-change/user-service": "^0.8.114",
27
27
  "got": "^11.8.6",
28
28
  "p-queue": "^8.0.1",
29
29
  "playwright": "^1.41.2"
30
30
  },
31
- "gitHead": "80dd8415e06d849cc00a7711c635a7388143ce1d",
31
+ "gitHead": "1a5a437aae382d766c2806a11f805370ee8cc40a",
32
32
  "type": "module"
33
33
  }
package/printPdf.js ADDED
@@ -0,0 +1,82 @@
1
+ import App from '@live-change/framework'
2
+ const app = App.app()
3
+
4
+ import definition from './definition.js'
5
+ import config from './config.js'
6
+
7
+ import { task } from '@live-change/task-service'
8
+
9
+ import { runWithBrowser } from './browser.js'
10
+
11
+ import { getAuthenticatedUrl } from './authentication.js'
12
+
13
+ async function sleep(time) {
14
+ return new Promise(resolve => setTimeout(resolve, time))
15
+ }
16
+
17
+ export const printToPdfFileTask = task({
18
+ name: "printToPdfFile",
19
+ properties: {
20
+ path: {
21
+ type: String
22
+ },
23
+ data: {
24
+ type: Object
25
+ },
26
+ timeout: {
27
+ type: Number
28
+ },
29
+ media: {
30
+ type: Object
31
+ },
32
+ options: {
33
+ type: Object
34
+ },
35
+ waitForSelector: {
36
+ type: String
37
+ },
38
+ outputPath: {
39
+ type: String
40
+ }
41
+ },
42
+ async execute({ path, data, timeout, media, options, waitForSelector, outputPath }, { task, trigger, triggerService }, emit) {
43
+ const all = 10
44
+ let at = 0
45
+ const url = await getAuthenticatedUrl(path, data)
46
+ let pdf
47
+ task.progress(at++, all, 'gettingBrowserReady')
48
+ await runWithBrowser(async browser => {
49
+ task.progress(at++, all, 'creatingPage')
50
+ const page = await browser.newPage()
51
+ task.progress(at++, all, 'enteringPage')
52
+ await page.goto(url)
53
+ task.progress(at++, all, 'waitingForLoading')
54
+ while(true) {
55
+ const loadingTasksCount = await page.evaluate(() => api.globals.$allLoadingTasks?.length)
56
+ if(loadingTasksCount === 0) break
57
+ await sleep(100)
58
+ }
59
+ if(waitForSelector) {
60
+ task.progress(at++, all, 'waitingForSelector')
61
+ await page.waitForSelector(waitForSelector)
62
+ } else {
63
+ task.progress(at++, all, 'waitingForNetworkIdle')
64
+ await page.waitForLoadState('networkidle')
65
+ }
66
+ task.progress(at++, all, 'waitingForRendering')
67
+ await sleep(100) // wait for some time to give browser time to render
68
+ task.progress(at++, all, 'printing')
69
+ page.emulateMedia(media ?? { media: 'print' })
70
+ pdf = await page.pdf( options ?? { format: 'A4', printBackground: true })
71
+ task.progress(at++, all, 'closingPage')
72
+ })
73
+ task.progress(at++, all, 'writingPdfToFile')
74
+ await fs.promises.writeFile(outputPath, pdf)
75
+ task.progress(at++, all, 'done')
76
+ return outputPath
77
+ }
78
+ }, definition)
79
+
80
+
81
+
82
+
package/screenshot.js ADDED
@@ -0,0 +1,138 @@
1
+ import App from '@live-change/framework'
2
+ const app = App.app()
3
+
4
+ import definition from './definition.js'
5
+ import config from './config.js'
6
+
7
+ import fs from "fs/promises"
8
+
9
+ import { task } from '@live-change/task-service'
10
+
11
+ import { runWithBrowser } from './browser.js'
12
+
13
+ import { getAuthenticatedUrl } from './authentication.js'
14
+
15
+ async function sleep(time) {
16
+ return new Promise(resolve => setTimeout(resolve, time))
17
+ }
18
+
19
+ export const screenshotToFileTask = task({
20
+ name: "screenshotToFile",
21
+ properties: {
22
+ path: {
23
+ type: String
24
+ },
25
+ data: {
26
+ type: Object
27
+ },
28
+ timeout: {
29
+ type: Number
30
+ },
31
+ viewport: {
32
+ type: Object,
33
+ properties: {
34
+ width: {
35
+ type: Number
36
+ },
37
+ height: {
38
+ type: Number
39
+ }
40
+ }
41
+ },
42
+ media: {
43
+ type: Object
44
+ },
45
+ options: {
46
+ type: Object
47
+ },
48
+ waitForSelector: {
49
+ type: String
50
+ },
51
+ clipSelector: {
52
+ type: String
53
+ },
54
+ outputPath: {
55
+ type: String
56
+ }
57
+ },
58
+ async execute({ path, data, timeout, media, options, waitForSelector, viewport, outputPath, clipSelector },
59
+ { task, trigger, triggerService }, emit) {
60
+ const all = 10
61
+ let at = 0
62
+ const url = await getAuthenticatedUrl(path, data)
63
+ let imageData
64
+ let size
65
+ task.progress(at++, all, 'gettingBrowserReady')
66
+ await runWithBrowser(async browser => {
67
+ console.log("BROWSER", browser)
68
+ task.progress(at++, all, 'creatingPage')
69
+ const page = await browser.newPage()
70
+ if(viewport) page.setViewport(viewport)
71
+ task.progress(at++, all, 'enteringPage')
72
+ await page.goto(url)
73
+ task.progress(at++, all, 'waitingForLoading')
74
+ while(true) {
75
+ const loadingTasksCount = await page.evaluate(() => api.globals.$allLoadingTasks?.length)
76
+ if(loadingTasksCount === 0) break
77
+ await sleep(100)
78
+ }
79
+ if(waitForSelector) {
80
+ task.progress(at++, all, 'waitingForSelector')
81
+ console.log("WAITING FOR SELECTOR", waitForSelector, "AT URL", url)
82
+ const locator = page.locator(waitForSelector)
83
+ await locator.waitFor({ state: 'attached', timeout })
84
+ } else {
85
+ task.progress(at++, all, 'waitingForNetworkIdle')
86
+ await page.waitForLoadState('networkidle')
87
+ }
88
+ task.progress(at++, all, 'waitingForRendering')
89
+ await sleep(100) // wait for some time to give browser time to render
90
+ task.progress(at++, all, 'printing')
91
+ if(media) page.emulateMedia(media)
92
+ const screenshotOptions = {
93
+ type: 'png',
94
+ ...options
95
+ }
96
+ if(clipSelector) {
97
+ const clip = await page.evaluate(selector => {
98
+ const element = document.querySelector(selector)
99
+ if(!element) return null
100
+ const { x, y, width, height } = element.getBoundingClientRect()
101
+ return { x, y, width, height }
102
+ }, clipSelector)
103
+ if(clip) {
104
+ screenshotOptions.clip = clip
105
+ }
106
+ }
107
+ size = screenshotOptions.clip
108
+ if(!size) {
109
+ if(screenshotOptions.fullPage) {
110
+ const bodyHandle = await page.$('body')
111
+ const { width, height } = await bodyHandle.boundingBox()
112
+ await bodyHandle.dispose()
113
+ size = { width, height }
114
+ } else {
115
+ size = await page.evaluate(() => {
116
+ return {
117
+ width: document.documentElement.clientWidth,
118
+ height: document.documentElement.clientHeight
119
+ }
120
+ })
121
+ }
122
+ }
123
+ imageData = await page.screenshot(screenshotOptions)
124
+ task.progress(at++, all, 'closingPage')
125
+ })
126
+ task.progress(at++, all, 'writingScreenshotToFile')
127
+ await fs.writeFile(outputPath, imageData)
128
+ task.progress(at++, all, 'done')
129
+ return {
130
+ path: outputPath,
131
+ size
132
+ }
133
+ }
134
+ }, definition)
135
+
136
+
137
+
138
+
package/print.js DELETED
@@ -1,88 +0,0 @@
1
- import App from '@live-change/framework'
2
- const app = App.app()
3
-
4
- import definition from './definition.js'
5
- import config from './config.js'
6
-
7
- import { task } from '@live-change/task-service'
8
-
9
- import { runWithBrowser } from './browser.js'
10
-
11
- const authenticationKey = new ObservableValue(
12
- config.printAuthenticationKey
13
- )
14
-
15
- definition.authenticator({
16
- async prepareCredentials(credentials) {
17
- //console.log("PRINT AUTHENTICATOR", credentials, authenticationKey.getValue())
18
- if(credentials.sessionKey === authenticationKey.getValue()) {
19
- credentials.roles.push('admin')
20
- credentials.internal = true
21
- }
22
- }
23
- })
24
-
25
- const baseUrl = `http://${config.ssrHost}`+`:${config.ssrPort}`
26
-
27
- export async function getPrintUrl(path, data) {
28
- const encodedData = encodeURIComponent(JSON.stringify(data))
29
- return baseUrl + path+'/' + encodedData +`?sessionKey=${await authenticationKey.getValue()}`
30
- }
31
-
32
- async function sleep(time) {
33
- return new Promise(resolve => setTimeout(resolve, time))
34
- }
35
-
36
- const printToPdfFile = task({
37
- name: "printToPdfFile",
38
- properties: {
39
- path: {
40
- type: String
41
- },
42
- data: {
43
- type: Object
44
- },
45
- timeout: {
46
- type: Number
47
- },
48
- media: {
49
- type: Object
50
- },
51
- options: {
52
- type: Object
53
- },
54
- outputPath: {
55
- type: String
56
- }
57
- },
58
- async execute({ path, data, timeout, media, options, outputPath }, { task, trigger, triggerService }, emit) {
59
- const all = 8
60
- const url = await getPrintUrl(path, data)
61
- task.progress(0, all, 'gettingBrowserReady')
62
- await runWithBrowser(async browser => {
63
- task.progress(1, all, 'creatingPage')
64
- const page = await browser.newPage()
65
- task.progress(2, all, 'enteringPage')
66
- await page.goto(url)
67
- task.progress(3, all, 'waitingForLoading')
68
- while(true) {
69
- const loadingTasksCount = await page.evaluate(() => api.globals.$allLoadingTasks?.length)
70
- if(loadingTasksCount === 0) break
71
- await sleep(100)
72
- }
73
- task.progress(4, all, 'waitingForNetworkIdle')
74
- await page.waitForLoadState('networkidle')
75
- task.progress(5, all, 'waitingForRendering')
76
- await sleep(100) // wait for some time to give browser time to render
77
- task.progress(6, all, 'printing')
78
- page.emulateMedia(media ?? { media: 'print' })
79
- const pdf = await page.pdf( options ?? { format: 'A4', printBackground: true })
80
- task.progress(7, all, 'closingPage')
81
- })
82
- task.progress(9, all, 'writingPdfToFile')
83
- await fs.promises.writeFile(outputPath, pdf)
84
- task.progress(10, all, 'done')
85
- return outputPath
86
- }
87
- })
88
-