@things-factory/integration-headless 7.0.38 → 7.0.40
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.
- package/dist-server/engine/task/headless-pdf-capture-board.d.ts +1 -0
- package/dist-server/engine/task/headless-pdf-capture-board.js +311 -0
- package/dist-server/engine/task/headless-pdf-capture-board.js.map +1 -0
- package/dist-server/engine/task/headless-pdf-capture.js +111 -72
- package/dist-server/engine/task/headless-pdf-capture.js.map +1 -1
- package/dist-server/engine/task/headless-pdf-open.js +255 -25
- package/dist-server/engine/task/headless-pdf-open.js.map +1 -1
- package/dist-server/engine/task/headless-pdf-save.js +17 -47
- package/dist-server/engine/task/headless-pdf-save.js.map +1 -1
- package/dist-server/engine/task/index.d.ts +1 -0
- package/dist-server/engine/task/index.js +1 -0
- package/dist-server/engine/task/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/server/engine/task/headless-pdf-capture-board.ts +363 -0
- package/server/engine/task/headless-pdf-capture.ts +123 -96
- package/server/engine/task/headless-pdf-open.ts +286 -25
- package/server/engine/task/headless-pdf-save.ts +20 -54
- package/server/engine/task/index.ts +1 -0
- package/translations/en.json +5 -2
- package/translations/ja.json +5 -2
- package/translations/ko.json +5 -2
- package/translations/ms.json +5 -2
- package/translations/zh.json +5 -2
|
@@ -2,39 +2,208 @@ import * as ejs from 'ejs'
|
|
|
2
2
|
import { PDFDocument } from 'pdf-lib'
|
|
3
3
|
import { TaskRegistry } from '@things-factory/integration-base'
|
|
4
4
|
import { ConnectionManager } from '@things-factory/integration-base'
|
|
5
|
+
import { access } from '@things-factory/utils'
|
|
5
6
|
|
|
6
7
|
async function HeadlessPDFOpen(step, context) {
|
|
7
8
|
var { connection: connectionName, params: stepOptions } = step
|
|
8
9
|
var {
|
|
10
|
+
accessor,
|
|
9
11
|
coverPage,
|
|
10
12
|
lastPage,
|
|
11
13
|
header,
|
|
12
14
|
footer,
|
|
13
15
|
watermark,
|
|
14
|
-
fileName
|
|
16
|
+
fileName,
|
|
17
|
+
format,
|
|
18
|
+
width,
|
|
19
|
+
height,
|
|
20
|
+
marginTop,
|
|
21
|
+
marginBottom,
|
|
22
|
+
marginLeft,
|
|
23
|
+
marginRight,
|
|
24
|
+
scale,
|
|
25
|
+
printBackground,
|
|
26
|
+
landscape,
|
|
27
|
+
preferCSSPageSize
|
|
15
28
|
} = stepOptions || {}
|
|
16
|
-
|
|
17
|
-
const pdf = await PDFDocument.create()
|
|
29
|
+
const { data, logger } = context
|
|
18
30
|
|
|
19
31
|
const headlessPool = ConnectionManager.getConnectionInstanceByName(context.domain, connectionName)
|
|
20
32
|
let browser
|
|
21
33
|
|
|
34
|
+
// Create a new PDF document using pdf-lib
|
|
35
|
+
const pdfDoc = await PDFDocument.create()
|
|
36
|
+
|
|
22
37
|
try {
|
|
23
38
|
browser = await headlessPool.acquire()
|
|
24
39
|
const page = await browser.newPage()
|
|
25
40
|
|
|
26
|
-
|
|
41
|
+
const templateInput = access(accessor, data)
|
|
42
|
+
|
|
43
|
+
const renderTemplateSafely = (template, data) => {
|
|
44
|
+
try {
|
|
45
|
+
return ejs.render(template, data)
|
|
46
|
+
} catch (error) {
|
|
47
|
+
logger.warn(`Template rendering error: ${error.message}`)
|
|
48
|
+
return template
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Convert Cover Page to PDF and add it to the document (if provided)
|
|
27
53
|
if (coverPage) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
54
|
+
const renderedCoverPage = renderTemplateSafely(coverPage, templateInput)
|
|
55
|
+
|
|
56
|
+
await page.setContent(renderedCoverPage)
|
|
57
|
+
|
|
58
|
+
// Apply header, footer, and watermark using Puppeteer
|
|
59
|
+
// Apply header, footer, and watermark using Puppeteer
|
|
60
|
+
if (header || footer || watermark) {
|
|
61
|
+
await page.evaluate(
|
|
62
|
+
({ header, footer, watermark, isLandscape }) => {
|
|
63
|
+
const setPositioning = (element, position) => {
|
|
64
|
+
element.style.position = 'fixed'
|
|
65
|
+
element.style.left = '0'
|
|
66
|
+
element.style.width = '100%'
|
|
67
|
+
element.style.textAlign = 'center'
|
|
68
|
+
element.style.fontSize = '12px'
|
|
69
|
+
if (position === 'header') {
|
|
70
|
+
element.style.top = '0'
|
|
71
|
+
} else if (position === 'footer') {
|
|
72
|
+
element.style.bottom = '0'
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// if (header) {
|
|
77
|
+
// const headerElement = document.createElement('div')
|
|
78
|
+
// headerElement.innerHTML = header
|
|
79
|
+
// setPositioning(headerElement, 'header')
|
|
80
|
+
// document.body.appendChild(headerElement)
|
|
81
|
+
// }
|
|
82
|
+
|
|
83
|
+
// if (footer) {
|
|
84
|
+
// const footerElement = document.createElement('div')
|
|
85
|
+
// footerElement.innerHTML = footer
|
|
86
|
+
// setPositioning(footerElement, 'footer')
|
|
87
|
+
// document.body.appendChild(footerElement)
|
|
88
|
+
// }
|
|
89
|
+
|
|
90
|
+
if (watermark) {
|
|
91
|
+
const watermarkElement = document.createElement('div')
|
|
92
|
+
watermarkElement.innerHTML = watermark
|
|
93
|
+
watermarkElement.style.position = 'fixed'
|
|
94
|
+
watermarkElement.style.top = isLandscape ? '40%' : '50%'
|
|
95
|
+
watermarkElement.style.left = '50%'
|
|
96
|
+
watermarkElement.style.transform = 'translate(-50%, -50%) rotate(-45deg)'
|
|
97
|
+
watermarkElement.style.opacity = '0.2'
|
|
98
|
+
watermarkElement.style.fontSize = '50px'
|
|
99
|
+
watermarkElement.style.color = 'red'
|
|
100
|
+
watermarkElement.style.pointerEvents = 'none'
|
|
101
|
+
watermarkElement.style.zIndex = '9999'
|
|
102
|
+
document.body.appendChild(watermarkElement)
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{ header, footer, watermark, isLandscape: landscape }
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const pageOptions = {
|
|
110
|
+
format,
|
|
111
|
+
width,
|
|
112
|
+
height,
|
|
113
|
+
margin: {
|
|
114
|
+
top: marginTop,
|
|
115
|
+
right: marginRight,
|
|
116
|
+
bottom: marginBottom,
|
|
117
|
+
left: marginLeft
|
|
118
|
+
},
|
|
119
|
+
scale,
|
|
120
|
+
printBackground,
|
|
121
|
+
landscape,
|
|
122
|
+
displayHeaderFooter: false, // Handled via Puppeteer directly
|
|
123
|
+
preferCSSPageSize
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const coverPageBuffer = await page.pdf(pageOptions)
|
|
127
|
+
const coverPageDoc = await PDFDocument.load(coverPageBuffer)
|
|
128
|
+
const coverPages = await pdfDoc.copyPages(coverPageDoc, coverPageDoc.getPageIndices())
|
|
129
|
+
coverPages.forEach(page => pdfDoc.addPage(page))
|
|
31
130
|
}
|
|
32
131
|
|
|
33
|
-
|
|
132
|
+
var lastPageBuffer
|
|
133
|
+
|
|
134
|
+
// Process Last Page (if provided) but add it later in the save task
|
|
34
135
|
if (lastPage) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
136
|
+
const renderedLastPage = renderTemplateSafely(lastPage, templateInput)
|
|
137
|
+
await page.setContent(renderedLastPage)
|
|
138
|
+
|
|
139
|
+
// Apply header, footer, and watermark using Puppeteer
|
|
140
|
+
if (header || footer || watermark) {
|
|
141
|
+
await page.evaluate(
|
|
142
|
+
({ header, footer, watermark, isLandscape }) => {
|
|
143
|
+
const setPositioning = (element, position) => {
|
|
144
|
+
element.style.position = 'fixed'
|
|
145
|
+
element.style.left = '0'
|
|
146
|
+
element.style.width = '100%'
|
|
147
|
+
element.style.textAlign = 'center'
|
|
148
|
+
element.style.fontSize = '12px'
|
|
149
|
+
if (position === 'header') {
|
|
150
|
+
element.style.top = '0'
|
|
151
|
+
} else if (position === 'footer') {
|
|
152
|
+
element.style.bottom = '0'
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// if (header) {
|
|
157
|
+
// const headerElement = document.createElement('div')
|
|
158
|
+
// headerElement.innerHTML = header
|
|
159
|
+
// setPositioning(headerElement, 'header')
|
|
160
|
+
// document.body.appendChild(headerElement)
|
|
161
|
+
// }
|
|
162
|
+
|
|
163
|
+
// if (footer) {
|
|
164
|
+
// const footerElement = document.createElement('div')
|
|
165
|
+
// footerElement.innerHTML = footer
|
|
166
|
+
// setPositioning(footerElement, 'footer')
|
|
167
|
+
// document.body.appendChild(footerElement)
|
|
168
|
+
// }
|
|
169
|
+
|
|
170
|
+
if (watermark) {
|
|
171
|
+
const watermarkElement = document.createElement('div')
|
|
172
|
+
watermarkElement.innerHTML = watermark
|
|
173
|
+
watermarkElement.style.position = 'fixed'
|
|
174
|
+
watermarkElement.style.top = isLandscape ? '40%' : '50%'
|
|
175
|
+
watermarkElement.style.left = '50%'
|
|
176
|
+
watermarkElement.style.transform = 'translate(-50%, -50%) rotate(-45deg)'
|
|
177
|
+
watermarkElement.style.opacity = '0.2'
|
|
178
|
+
watermarkElement.style.fontSize = '50px'
|
|
179
|
+
watermarkElement.style.color = 'red'
|
|
180
|
+
watermarkElement.style.pointerEvents = 'none'
|
|
181
|
+
watermarkElement.style.zIndex = '9999'
|
|
182
|
+
document.body.appendChild(watermarkElement)
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{ header, footer, watermark, isLandscape: landscape }
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const pageOptions = {
|
|
190
|
+
format,
|
|
191
|
+
width,
|
|
192
|
+
height,
|
|
193
|
+
margin: {
|
|
194
|
+
top: marginTop,
|
|
195
|
+
right: marginRight,
|
|
196
|
+
bottom: marginBottom,
|
|
197
|
+
left: marginLeft
|
|
198
|
+
},
|
|
199
|
+
scale,
|
|
200
|
+
printBackground,
|
|
201
|
+
landscape,
|
|
202
|
+
displayHeaderFooter: false, // Handled via Puppeteer directly
|
|
203
|
+
preferCSSPageSize
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
lastPageBuffer = await page.pdf(pageOptions)
|
|
38
207
|
}
|
|
39
208
|
|
|
40
209
|
await page.close()
|
|
@@ -46,25 +215,29 @@ async function HeadlessPDFOpen(step, context) {
|
|
|
46
215
|
throw error
|
|
47
216
|
}
|
|
48
217
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
lastPage,
|
|
218
|
+
const pdfInfo = {
|
|
219
|
+
pdfDoc,
|
|
220
|
+
lastPageBuffer,
|
|
53
221
|
header,
|
|
54
222
|
footer,
|
|
55
223
|
watermark,
|
|
56
224
|
fileName,
|
|
57
|
-
pageCount:
|
|
225
|
+
pageCount: pdfDoc.getPageCount()
|
|
58
226
|
}
|
|
59
227
|
|
|
60
|
-
context.__headless_pdf =
|
|
228
|
+
context.__headless_pdf = pdfInfo
|
|
61
229
|
|
|
62
230
|
return {
|
|
63
|
-
data
|
|
231
|
+
data: pdfInfo
|
|
64
232
|
}
|
|
65
233
|
}
|
|
66
234
|
|
|
67
235
|
HeadlessPDFOpen.parameterSpec = [
|
|
236
|
+
{
|
|
237
|
+
type: 'scenario-step-input',
|
|
238
|
+
name: 'accessor',
|
|
239
|
+
label: 'accessor'
|
|
240
|
+
},
|
|
68
241
|
{
|
|
69
242
|
type: 'textarea',
|
|
70
243
|
name: 'coverPage',
|
|
@@ -76,26 +249,114 @@ HeadlessPDFOpen.parameterSpec = [
|
|
|
76
249
|
label: 'pdf-last-page'
|
|
77
250
|
},
|
|
78
251
|
{
|
|
79
|
-
type: '
|
|
252
|
+
type: 'string',
|
|
80
253
|
name: 'header',
|
|
81
|
-
label: 'header'
|
|
254
|
+
label: 'header',
|
|
255
|
+
placeholder: 'Page <%= pageNumber %> of <%= totalPages %>'
|
|
82
256
|
},
|
|
83
257
|
{
|
|
84
|
-
type: '
|
|
258
|
+
type: 'string',
|
|
85
259
|
name: 'footer',
|
|
86
|
-
label: 'footer'
|
|
260
|
+
label: 'footer',
|
|
261
|
+
placeholder: 'Page <%= pageNumber %> of <%= totalPages %>'
|
|
87
262
|
},
|
|
88
263
|
{
|
|
89
|
-
type: '
|
|
264
|
+
type: 'string',
|
|
90
265
|
name: 'watermark',
|
|
91
|
-
label: 'watermark'
|
|
266
|
+
label: 'watermark'
|
|
92
267
|
},
|
|
93
268
|
{
|
|
94
269
|
type: 'string',
|
|
95
270
|
name: 'fileName',
|
|
96
|
-
label: 'filename'
|
|
271
|
+
label: 'filename'
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
type: 'select',
|
|
275
|
+
name: 'format',
|
|
276
|
+
label: 'page-format',
|
|
277
|
+
property: {
|
|
278
|
+
options: [
|
|
279
|
+
{ display: '', value: '' },
|
|
280
|
+
{ display: 'A4', value: 'A4' },
|
|
281
|
+
{ display: 'A3', value: 'A3' },
|
|
282
|
+
{ display: 'Letter', value: 'Letter' },
|
|
283
|
+
{ display: 'Legal', value: 'Legal' }
|
|
284
|
+
]
|
|
285
|
+
},
|
|
286
|
+
description: 'Select the paper format for the PDF'
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
type: 'string',
|
|
290
|
+
name: 'width',
|
|
291
|
+
label: 'page-width',
|
|
292
|
+
placeholder: '(e.g., "8.5in", "21cm", "600px")',
|
|
293
|
+
description: 'Specify the width of the page (e.g., "8.5in", "21cm", "600px")'
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
type: 'string',
|
|
297
|
+
name: 'height',
|
|
298
|
+
label: 'page-height',
|
|
299
|
+
placeholder: '(e.g., "11in", "29.7cm", "800px")',
|
|
300
|
+
description: 'Specify the height of the page (e.g., "11in", "29.7cm", "800px")'
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
type: 'string',
|
|
304
|
+
name: 'marginTop',
|
|
305
|
+
label: 'page-margin-top',
|
|
306
|
+
placeholder: '(e.g., "0.5in", "1cm", "100px")',
|
|
307
|
+
description: 'Set the top margin for the page'
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
type: 'string',
|
|
311
|
+
name: 'marginBottom',
|
|
312
|
+
label: 'page-margin-bottom',
|
|
313
|
+
placeholder: '(e.g., "0.5in", "1cm", "100px")',
|
|
314
|
+
description: 'Set the bottom margin for the page'
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
type: 'string',
|
|
318
|
+
name: 'marginLeft',
|
|
319
|
+
label: 'page-margin-left',
|
|
320
|
+
placeholder: '(e.g., "0.5in", "1cm", "100px")',
|
|
321
|
+
description: 'Set the left margin for the page'
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
type: 'string',
|
|
325
|
+
name: 'marginRight',
|
|
326
|
+
label: 'page-margin-right',
|
|
327
|
+
placeholder: '(e.g., "0.5in", "1cm", "100px")',
|
|
328
|
+
description: 'Set the right margin for the page'
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
type: 'number',
|
|
332
|
+
name: 'scale',
|
|
333
|
+
label: 'page-scale',
|
|
334
|
+
defaultValue: 1,
|
|
335
|
+
description: 'Set the scale of the page content (default is 1)'
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
type: 'boolean',
|
|
339
|
+
name: 'printBackground',
|
|
340
|
+
label: 'print-background',
|
|
341
|
+
defaultValue: true,
|
|
342
|
+
description: 'Include background graphics when printing the page'
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
type: 'boolean',
|
|
346
|
+
name: 'landscape',
|
|
347
|
+
label: 'landscape',
|
|
348
|
+
defaultValue: false,
|
|
349
|
+
description: 'Print the PDF in landscape orientation'
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
type: 'boolean',
|
|
353
|
+
name: 'preferCSSPageSize',
|
|
354
|
+
label: 'prefer-css-page-size',
|
|
355
|
+
defaultValue: false,
|
|
356
|
+
description: 'Whether to prefer the CSS-defined page size over the given width and height'
|
|
97
357
|
}
|
|
98
358
|
]
|
|
359
|
+
|
|
99
360
|
HeadlessPDFOpen.help = 'integration/task/headless-pdf-open'
|
|
100
361
|
|
|
101
362
|
TaskRegistry.registerTaskHandler('headless-pdf-open', HeadlessPDFOpen)
|
|
@@ -1,74 +1,39 @@
|
|
|
1
1
|
import * as fs from 'fs'
|
|
2
2
|
import * as path from 'path'
|
|
3
|
-
import { PDFDocument, rgb, degrees } from 'pdf-lib'
|
|
4
|
-
|
|
5
3
|
import { TaskRegistry } from '@things-factory/integration-base'
|
|
4
|
+
import { PDFDocument } from 'pdf-lib'
|
|
6
5
|
|
|
7
6
|
async function HeadlessPDFSave(step, context) {
|
|
8
7
|
var { params: stepOptions } = step
|
|
9
8
|
var { outputPath } = stepOptions || {}
|
|
10
|
-
var {
|
|
11
|
-
|
|
12
|
-
var { pdf, coverPage, lastPage, watermark, fileName } = __headless_pdf
|
|
13
|
-
|
|
14
|
-
// 파일 이름이 설정되지 않았을 경우 기본 파일 이름 생성
|
|
15
|
-
const finalFileName = fileName || `document-${Date.now()}.pdf`
|
|
16
|
-
const savePath = path.join(outputPath || '/path/to/default/storage', finalFileName)
|
|
17
|
-
|
|
18
|
-
// PDF 문서에 coverPage 및 lastPage 추가
|
|
19
|
-
if (coverPage) {
|
|
20
|
-
const coverPageDoc = await PDFDocument.load(coverPage)
|
|
21
|
-
const [cover] = await pdf.copyPages(coverPageDoc, [0])
|
|
22
|
-
|
|
23
|
-
// 커버 페이지에 워터마크 추가
|
|
24
|
-
if (watermark) {
|
|
25
|
-
const fontSize = 50
|
|
26
|
-
const pageWidth = cover.getWidth()
|
|
27
|
-
const pageHeight = cover.getHeight()
|
|
9
|
+
var { __headless_pdf } = context
|
|
28
10
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
color: rgb(0.75, 0.75, 0.75),
|
|
34
|
-
rotate: degrees(-45),
|
|
35
|
-
opacity: 0.5
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
pdf.insertPage(0, cover)
|
|
11
|
+
if (!__headless_pdf || !__headless_pdf.pdfDoc) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
'No PDF document found. Ensure that headless-pdf-open and headless-pdf-capture tasks are executed before saving.'
|
|
14
|
+
)
|
|
40
15
|
}
|
|
41
16
|
|
|
42
|
-
|
|
43
|
-
const lastPageDoc = await PDFDocument.load(lastPage)
|
|
44
|
-
const [last] = await pdf.copyPages(lastPageDoc, [0])
|
|
17
|
+
const pdfDoc = __headless_pdf.pdfDoc
|
|
45
18
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
19
|
+
// Add last page if it exists
|
|
20
|
+
if (__headless_pdf.lastPageBuffer) {
|
|
21
|
+
const lastPageDoc = await PDFDocument.load(__headless_pdf.lastPageBuffer)
|
|
22
|
+
const copiedLastPages = await pdfDoc.copyPages(lastPageDoc, lastPageDoc.getPageIndices())
|
|
23
|
+
copiedLastPages.forEach(page => pdfDoc.addPage(page))
|
|
24
|
+
}
|
|
51
25
|
|
|
52
|
-
|
|
53
|
-
x: pageWidth / 2 - (fontSize * watermark.length) / 4,
|
|
54
|
-
y: pageHeight / 2 - fontSize / 2,
|
|
55
|
-
size: fontSize,
|
|
56
|
-
color: rgb(0.75, 0.75, 0.75),
|
|
57
|
-
rotate: degrees(-45),
|
|
58
|
-
opacity: 0.5
|
|
59
|
-
})
|
|
60
|
-
}
|
|
26
|
+
const pdfBytes = await pdfDoc.save()
|
|
61
27
|
|
|
62
|
-
|
|
63
|
-
|
|
28
|
+
const finalFileName = __headless_pdf.fileName || `document-${Date.now()}.pdf`
|
|
29
|
+
const savePath = path.join(outputPath || './attachments', finalFileName)
|
|
64
30
|
|
|
65
|
-
// PDF
|
|
66
|
-
const pdfBytes = await pdf.save()
|
|
31
|
+
// Save the final PDF to the specified path
|
|
67
32
|
fs.writeFileSync(savePath, pdfBytes)
|
|
68
33
|
|
|
69
34
|
return {
|
|
70
35
|
data: {
|
|
71
|
-
link: savePath
|
|
36
|
+
link: savePath
|
|
72
37
|
}
|
|
73
38
|
}
|
|
74
39
|
}
|
|
@@ -77,7 +42,8 @@ HeadlessPDFSave.parameterSpec = [
|
|
|
77
42
|
{
|
|
78
43
|
type: 'string',
|
|
79
44
|
name: 'outputPath',
|
|
80
|
-
label: 'output-path'
|
|
45
|
+
label: 'output-path',
|
|
46
|
+
description: 'The directory path where the PDF should be saved. Defaults to "./attachments".'
|
|
81
47
|
}
|
|
82
48
|
]
|
|
83
49
|
|
package/translations/en.json
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"label.output-path": "output path",
|
|
9
9
|
"label.page-format": "page format",
|
|
10
10
|
"label.page-height": "page height",
|
|
11
|
-
"label.page-
|
|
11
|
+
"label.page-margin-top": "page margin top",
|
|
12
|
+
"label.page-margin-bottom": "page margin bottom",
|
|
13
|
+
"label.page-margin-left": "page margin left",
|
|
14
|
+
"label.page-margin-right": "page margins right",
|
|
12
15
|
"label.page-width": "page width",
|
|
13
16
|
"label.pdf-cover-page": "cover page template",
|
|
14
17
|
"label.pdf-last-page": "last page template",
|
|
@@ -16,6 +19,6 @@
|
|
|
16
19
|
"label.pool-size-min": "minimum pool size",
|
|
17
20
|
"label.prefer-css-page-size": "prefer css page size",
|
|
18
21
|
"label.print-background": "print background",
|
|
19
|
-
"label.scale": "scale",
|
|
22
|
+
"label.page-scale": "scale",
|
|
20
23
|
"label.watermark": "watermark"
|
|
21
24
|
}
|
package/translations/ja.json
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"label.output-path": "出力パス",
|
|
9
9
|
"label.page-format": "ページ形式",
|
|
10
10
|
"label.page-height": "ページ高さ",
|
|
11
|
-
"label.page-
|
|
11
|
+
"label.page-margin-top": "ページ上余白",
|
|
12
|
+
"label.page-margin-bottom": "ページ下余白",
|
|
13
|
+
"label.page-margin-left": "ページ左余白",
|
|
14
|
+
"label.page-margin-right": "ページ右余白",
|
|
12
15
|
"label.page-width": "ページ幅",
|
|
13
16
|
"label.pdf-cover-page": "表紙テンプレート",
|
|
14
17
|
"label.pdf-last-page": "最終ページテンプレート",
|
|
@@ -16,6 +19,6 @@
|
|
|
16
19
|
"label.pool-size-min": "最小プールサイズ",
|
|
17
20
|
"label.prefer-css-page-size": "cssページサイズを優先",
|
|
18
21
|
"label.print-background": "背景を印刷",
|
|
19
|
-
"label.scale": "スケール",
|
|
22
|
+
"label.page-scale": "スケール",
|
|
20
23
|
"label.watermark": "透かし"
|
|
21
24
|
}
|
package/translations/ko.json
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"label.output-path": "출력 패스",
|
|
9
9
|
"label.page-format": "페이지 형식",
|
|
10
10
|
"label.page-height": "페이지 높이",
|
|
11
|
-
"label.page-
|
|
11
|
+
"label.page-margin-top": "페이지 여백 (위쪽)",
|
|
12
|
+
"label.page-margin-bottom": "페이지 여백 (아래쪽)",
|
|
13
|
+
"label.page-margin-left": "페이지 여백 (왼쪽)",
|
|
14
|
+
"label.page-margin-right": "페이지 여백 (오른쪽)",
|
|
12
15
|
"label.page-width": "페이지 폭",
|
|
13
16
|
"label.pdf-cover-page": "표지 템플릿",
|
|
14
17
|
"label.pdf-last-page": "뒷표지 템플릿",
|
|
@@ -16,6 +19,6 @@
|
|
|
16
19
|
"label.pool-size-min": "최대 풀(Pool) 사이즈",
|
|
17
20
|
"label.prefer-css-page-size": "선호 CSS 페이지 크기",
|
|
18
21
|
"label.print-background": "배경 포함여부",
|
|
19
|
-
"label.scale": "페이지 비율",
|
|
22
|
+
"label.page-scale": "페이지 비율",
|
|
20
23
|
"label.watermark": "워터마크"
|
|
21
24
|
}
|
package/translations/ms.json
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"label.output-path": "laluan output",
|
|
9
9
|
"label.page-format": "format halaman",
|
|
10
10
|
"label.page-height": "tinggi halaman",
|
|
11
|
-
"label.page-
|
|
11
|
+
"label.page-margin-top": "margin atas halaman",
|
|
12
|
+
"label.page-margin-bottom": "margin bawah halaman",
|
|
13
|
+
"label.page-margin-left": "margin kiri halaman",
|
|
14
|
+
"label.page-margin-right": "margin kanan halaman",
|
|
12
15
|
"label.page-width": "lebar halaman",
|
|
13
16
|
"label.pdf-cover-page": "templat muka surat depan",
|
|
14
17
|
"label.pdf-last-page": "templat muka surat terakhir",
|
|
@@ -16,6 +19,6 @@
|
|
|
16
19
|
"label.pool-size-min": "saiz pool minimum",
|
|
17
20
|
"label.prefer-css-page-size": "utamakan saiz halaman css",
|
|
18
21
|
"label.print-background": "cetak latar belakang",
|
|
19
|
-
"label.scale": "skala",
|
|
22
|
+
"label.page-scale": "skala",
|
|
20
23
|
"label.watermark": "tanda air"
|
|
21
24
|
}
|
package/translations/zh.json
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"label.output-path": "输出路径",
|
|
9
9
|
"label.page-format": "页面格式",
|
|
10
10
|
"label.page-height": "页面高度",
|
|
11
|
-
"label.page-
|
|
11
|
+
"label.page-margin-top": "页面上边距",
|
|
12
|
+
"label.page-margin-bottom": "页面下边距",
|
|
13
|
+
"label.page-margin-left": "页面左边距",
|
|
14
|
+
"label.page-margin-right": "页面右边距",
|
|
12
15
|
"label.page-width": "页面宽度",
|
|
13
16
|
"label.pdf-cover-page": "封面模板",
|
|
14
17
|
"label.pdf-last-page": "尾页模板",
|
|
@@ -16,6 +19,6 @@
|
|
|
16
19
|
"label.pool-size-min": "最小池大小",
|
|
17
20
|
"label.prefer-css-page-size": "偏好 css 页面大小",
|
|
18
21
|
"label.print-background": "打印背景",
|
|
19
|
-
"label.scale": "缩放",
|
|
22
|
+
"label.page-scale": "缩放",
|
|
20
23
|
"label.watermark": "水印"
|
|
21
24
|
}
|