@formepdf/cli 0.2.1 → 0.3.0
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/dev.js +22 -1
- package/dist/preview/index.html +46 -0
- package/package.json +3 -3
package/dist/dev.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createServer } from 'node:http';
|
|
2
2
|
import { readFile, writeFile, unlink } from 'node:fs/promises';
|
|
3
|
-
import { resolve, basename, join } from 'node:path';
|
|
3
|
+
import { resolve, basename, dirname, join } from 'node:path';
|
|
4
4
|
import { pathToFileURL } from 'node:url';
|
|
5
5
|
import { watch } from 'chokidar';
|
|
6
6
|
import { WebSocketServer } from 'ws';
|
|
@@ -165,6 +165,8 @@ export function startDevServer(inputPath, options) {
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
+
// Resolve font file paths relative to the template directory
|
|
169
|
+
await resolveFontPaths(doc, absoluteInput);
|
|
168
170
|
const { pdf, layout } = await renderPdfWithLayout(JSON.stringify(doc));
|
|
169
171
|
// Skip if a newer build started
|
|
170
172
|
if (buildId !== buildCounter)
|
|
@@ -305,3 +307,22 @@ function hasAnySourceLocation(doc) {
|
|
|
305
307
|
}
|
|
306
308
|
return children.some(check);
|
|
307
309
|
}
|
|
310
|
+
function uint8ArrayToBase64(bytes) {
|
|
311
|
+
return Buffer.from(bytes).toString('base64');
|
|
312
|
+
}
|
|
313
|
+
async function resolveFontPaths(doc, templatePath) {
|
|
314
|
+
const fonts = doc.fonts;
|
|
315
|
+
if (!fonts?.length)
|
|
316
|
+
return;
|
|
317
|
+
const templateDir = dirname(templatePath);
|
|
318
|
+
for (const font of fonts) {
|
|
319
|
+
if (font.src instanceof Uint8Array) {
|
|
320
|
+
font.src = uint8ArrayToBase64(font.src);
|
|
321
|
+
}
|
|
322
|
+
else if (typeof font.src === 'string' && !font.src.startsWith('data:')) {
|
|
323
|
+
const fontPath = resolve(templateDir, font.src);
|
|
324
|
+
const bytes = await readFile(fontPath);
|
|
325
|
+
font.src = uint8ArrayToBase64(new Uint8Array(bytes));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
package/dist/preview/index.html
CHANGED
|
@@ -1226,6 +1226,17 @@
|
|
|
1226
1226
|
// Computed styles
|
|
1227
1227
|
let html = '';
|
|
1228
1228
|
|
|
1229
|
+
const sizeProps = [];
|
|
1230
|
+
if (s.width != null) sizeProps.push(['width', s.width + 'pt']);
|
|
1231
|
+
if (s.height != null) sizeProps.push(['height', s.height + 'pt']);
|
|
1232
|
+
if (s.minWidth != null) sizeProps.push(['min-width', fmt(s.minWidth) + 'pt']);
|
|
1233
|
+
if (s.minHeight != null) sizeProps.push(['min-height', fmt(s.minHeight) + 'pt']);
|
|
1234
|
+
if (s.maxWidth != null) sizeProps.push(['max-width', fmt(s.maxWidth) + 'pt']);
|
|
1235
|
+
if (s.maxHeight != null) sizeProps.push(['max-height', fmt(s.maxHeight) + 'pt']);
|
|
1236
|
+
if (sizeProps.length) {
|
|
1237
|
+
html += renderStyleSection('Sizing', sizeProps);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1229
1240
|
const posProps = [];
|
|
1230
1241
|
if (s.position && s.position !== 'Relative') {
|
|
1231
1242
|
posProps.push(['position', s.position.toLowerCase()]);
|
|
@@ -1242,8 +1253,14 @@
|
|
|
1242
1253
|
if (s.flexDirection !== 'Column') layoutProps.push(['flex-direction', s.flexDirection]);
|
|
1243
1254
|
if (s.justifyContent !== 'FlexStart') layoutProps.push(['justify-content', s.justifyContent]);
|
|
1244
1255
|
if (s.alignItems !== 'Stretch') layoutProps.push(['align-items', s.alignItems]);
|
|
1256
|
+
if (s.alignSelf) layoutProps.push(['align-self', s.alignSelf]);
|
|
1245
1257
|
if (s.flexWrap !== 'NoWrap') layoutProps.push(['flex-wrap', s.flexWrap]);
|
|
1258
|
+
if (s.flexGrow > 0) layoutProps.push(['flex-grow', String(s.flexGrow)]);
|
|
1259
|
+
if (s.flexShrink !== 1) layoutProps.push(['flex-shrink', String(s.flexShrink)]);
|
|
1260
|
+
if (s.flexBasis != null) layoutProps.push(['flex-basis', s.flexBasis + 'pt']);
|
|
1246
1261
|
if (s.gap > 0) layoutProps.push(['gap', fmt(s.gap) + 'pt']);
|
|
1262
|
+
if (s.rowGap > 0 && s.rowGap !== s.gap) layoutProps.push(['row-gap', fmt(s.rowGap) + 'pt']);
|
|
1263
|
+
if (s.columnGap > 0 && s.columnGap !== s.gap) layoutProps.push(['column-gap', fmt(s.columnGap) + 'pt']);
|
|
1247
1264
|
if (layoutProps.length) {
|
|
1248
1265
|
html += renderStyleSection('Layout', layoutProps);
|
|
1249
1266
|
}
|
|
@@ -1266,6 +1283,9 @@
|
|
|
1266
1283
|
if (s.fontStyle !== 'Normal') typoProps.push(['font-style', s.fontStyle]);
|
|
1267
1284
|
if (s.lineHeight !== 1.4) typoProps.push(['line-height', fmt(s.lineHeight)]);
|
|
1268
1285
|
if (s.textAlign !== 'Left') typoProps.push(['text-align', s.textAlign]);
|
|
1286
|
+
if (s.letterSpacing !== 0) typoProps.push(['letter-spacing', fmt(s.letterSpacing) + 'pt']);
|
|
1287
|
+
if (s.textDecoration !== 'None') typoProps.push(['text-decoration', s.textDecoration.toLowerCase()]);
|
|
1288
|
+
if (s.textTransform !== 'None') typoProps.push(['text-transform', s.textTransform.toLowerCase()]);
|
|
1269
1289
|
html += renderStyleSection('Typography', typoProps);
|
|
1270
1290
|
|
|
1271
1291
|
const visualProps = [];
|
|
@@ -1284,6 +1304,15 @@
|
|
|
1284
1304
|
html += renderStyleSection('Link & Bookmark', linkProps);
|
|
1285
1305
|
}
|
|
1286
1306
|
|
|
1307
|
+
const pageProps = [];
|
|
1308
|
+
if (s.breakable) pageProps.push(['breakable', 'true']);
|
|
1309
|
+
if (s.breakBefore) pageProps.push(['break-before', 'true']);
|
|
1310
|
+
if (s.minWidowLines !== 2) pageProps.push(['min-widow-lines', String(s.minWidowLines)]);
|
|
1311
|
+
if (s.minOrphanLines !== 2) pageProps.push(['min-orphan-lines', String(s.minOrphanLines)]);
|
|
1312
|
+
if (pageProps.length) {
|
|
1313
|
+
html += renderStyleSection('Page Behavior', pageProps);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1287
1316
|
inspectorStyles.innerHTML = html;
|
|
1288
1317
|
|
|
1289
1318
|
// Copy Style button
|
|
@@ -1352,6 +1381,8 @@
|
|
|
1352
1381
|
'NoWrap': 'nowrap', 'Wrap': 'wrap',
|
|
1353
1382
|
'Normal': 'normal', 'Italic': 'italic',
|
|
1354
1383
|
'Left': 'left', 'Right': 'right', 'Justify': 'justify',
|
|
1384
|
+
'None': 'none', 'Underline': 'underline', 'LineThrough': 'line-through',
|
|
1385
|
+
'Uppercase': 'uppercase', 'Lowercase': 'lowercase', 'Capitalize': 'capitalize',
|
|
1355
1386
|
};
|
|
1356
1387
|
function mapEnum(v) { return enumMap[v] || v; }
|
|
1357
1388
|
|
|
@@ -1375,11 +1406,23 @@
|
|
|
1375
1406
|
|
|
1376
1407
|
const props = [];
|
|
1377
1408
|
|
|
1409
|
+
if (s.width != null) props.push(`width: ${s.width}`);
|
|
1410
|
+
if (s.height != null) props.push(`height: ${s.height}`);
|
|
1411
|
+
if (s.minWidth != null) props.push(`minWidth: ${s.minWidth}`);
|
|
1412
|
+
if (s.minHeight != null) props.push(`minHeight: ${s.minHeight}`);
|
|
1413
|
+
if (s.maxWidth != null) props.push(`maxWidth: ${s.maxWidth}`);
|
|
1414
|
+
if (s.maxHeight != null) props.push(`maxHeight: ${s.maxHeight}`);
|
|
1378
1415
|
if (s.flexDirection !== 'Column') props.push(`flexDirection: '${mapEnum(s.flexDirection)}'`);
|
|
1379
1416
|
if (s.justifyContent !== 'FlexStart') props.push(`justifyContent: '${mapEnum(s.justifyContent)}'`);
|
|
1380
1417
|
if (s.alignItems !== 'Stretch') props.push(`alignItems: '${mapEnum(s.alignItems)}'`);
|
|
1418
|
+
if (s.alignSelf) props.push(`alignSelf: '${mapEnum(s.alignSelf)}'`);
|
|
1381
1419
|
if (s.flexWrap !== 'NoWrap') props.push(`flexWrap: '${mapEnum(s.flexWrap)}'`);
|
|
1420
|
+
if (s.flexGrow > 0) props.push(`flexGrow: ${s.flexGrow}`);
|
|
1421
|
+
if (s.flexShrink !== 1) props.push(`flexShrink: ${s.flexShrink}`);
|
|
1422
|
+
if (s.flexBasis != null) props.push(`flexBasis: ${s.flexBasis}`);
|
|
1382
1423
|
if (s.gap > 0) props.push(`gap: ${s.gap}`);
|
|
1424
|
+
if (s.rowGap > 0) props.push(`rowGap: ${s.rowGap}`);
|
|
1425
|
+
if (s.columnGap > 0) props.push(`columnGap: ${s.columnGap}`);
|
|
1383
1426
|
|
|
1384
1427
|
if (!edgesAllZero(s.margin)) props.push(`margin: ${fmtEdges(s.margin)}`);
|
|
1385
1428
|
if (!edgesAllZero(s.padding)) props.push(`padding: ${fmtEdges(s.padding)}`);
|
|
@@ -1391,6 +1434,9 @@
|
|
|
1391
1434
|
if (s.fontStyle !== 'Normal') props.push(`fontStyle: '${mapEnum(s.fontStyle)}'`);
|
|
1392
1435
|
if (s.lineHeight !== 1.4) props.push(`lineHeight: ${s.lineHeight}`);
|
|
1393
1436
|
if (s.textAlign !== 'Left') props.push(`textAlign: '${mapEnum(s.textAlign)}'`);
|
|
1437
|
+
if (s.letterSpacing !== 0) props.push(`letterSpacing: ${s.letterSpacing}`);
|
|
1438
|
+
if (s.textDecoration !== 'None') props.push(`textDecoration: '${mapEnum(s.textDecoration)}'`);
|
|
1439
|
+
if (s.textTransform !== 'None') props.push(`textTransform: '${mapEnum(s.textTransform)}'`);
|
|
1394
1440
|
|
|
1395
1441
|
if (s.opacity < 1) props.push(`opacity: ${s.opacity}`);
|
|
1396
1442
|
if (!colorEq(s.color, 0, 0, 0)) props.push(`color: '${colorToHex(s.color)}'`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formepdf/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "CLI for Forme PDF rendering engine — dev server with live preview and build command",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"dist"
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@formepdf/core": "0.
|
|
18
|
-
"@formepdf/react": "0.
|
|
17
|
+
"@formepdf/core": "0.3.0",
|
|
18
|
+
"@formepdf/react": "0.3.0",
|
|
19
19
|
"esbuild": "^0.24.0",
|
|
20
20
|
"chokidar": "^4.0.0",
|
|
21
21
|
"ws": "^8.18.0",
|