@voyantjs/utils 0.3.1 → 0.4.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/index.d.ts CHANGED
@@ -5,5 +5,7 @@ export * from "./kms.js";
5
5
  export * from "./kv.js";
6
6
  export * from "./languages.js";
7
7
  export * from "./localized-countries-regions.js";
8
+ export * from "./pdf-renderer.js";
9
+ export * from "./template-renderer.js";
8
10
  export * from "./timezones.js";
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA"}
package/dist/index.js CHANGED
@@ -5,5 +5,7 @@ export * from "./kms.js";
5
5
  export * from "./kv.js";
6
6
  export * from "./languages.js";
7
7
  export * from "./localized-countries-regions.js";
8
+ export * from "./pdf-renderer.js";
9
+ export * from "./template-renderer.js";
8
10
  export * from "./timezones.js";
9
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,yBAAyB,CAAA;AACvC,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kCAAkC,CAAA;AAChD,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA"}
@@ -0,0 +1,9 @@
1
+ export type PdfContentFormat = "text" | "html" | "markdown" | "lexical_json";
2
+ export interface RenderPdfDocumentInput {
3
+ title?: string | null;
4
+ content: string;
5
+ format?: PdfContentFormat;
6
+ metadataLines?: string[];
7
+ }
8
+ export declare function renderPdfDocument(input: RenderPdfDocumentInput): Promise<Uint8Array>;
9
+ //# sourceMappingURL=pdf-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-renderer.d.ts","sourceRoot":"","sources":["../src/pdf-renderer.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc,CAAA;AAE5E,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CACzB;AAwFD,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiE1F"}
@@ -0,0 +1,139 @@
1
+ import { PDFDocument, rgb, StandardFonts } from "pdf-lib";
2
+ function decodeEntities(input) {
3
+ return input
4
+ .replace(/&nbsp;/gi, " ")
5
+ .replace(/&amp;/gi, "&")
6
+ .replace(/&lt;/gi, "<")
7
+ .replace(/&gt;/gi, ">")
8
+ .replace(/&quot;/gi, '"')
9
+ .replace(/&#39;/gi, "'");
10
+ }
11
+ function stripHtml(input) {
12
+ return decodeEntities(input
13
+ .replace(/<\/(p|div|section|article|h[1-6]|li|tr)>/gi, "\n")
14
+ .replace(/<br\s*\/?>/gi, "\n")
15
+ .replace(/<[^>]+>/g, " ")
16
+ .replace(/[ \t]+\n/g, "\n"));
17
+ }
18
+ function stripMarkdown(input) {
19
+ return input
20
+ .replace(/^#{1,6}\s*/gm, "")
21
+ .replace(/[*_~`>#-]+/g, " ")
22
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
23
+ }
24
+ function extractLexicalText(input) {
25
+ try {
26
+ const root = JSON.parse(input);
27
+ const parts = [];
28
+ const visit = (node) => {
29
+ if (!node || typeof node !== "object")
30
+ return;
31
+ if ("text" in node && typeof node.text === "string") {
32
+ parts.push(node.text);
33
+ }
34
+ if ("children" in node && Array.isArray(node.children)) {
35
+ for (const child of node.children)
36
+ visit(child);
37
+ if (node.type === "paragraph") {
38
+ parts.push("\n");
39
+ }
40
+ }
41
+ };
42
+ visit(root);
43
+ return parts.join(" ");
44
+ }
45
+ catch {
46
+ return input;
47
+ }
48
+ }
49
+ function normalizePdfText(input, format) {
50
+ const text = format === "html"
51
+ ? stripHtml(input)
52
+ : format === "markdown"
53
+ ? stripMarkdown(input)
54
+ : format === "lexical_json"
55
+ ? extractLexicalText(input)
56
+ : input;
57
+ return text
58
+ .replace(/\r\n/g, "\n")
59
+ .replace(/\n{3,}/g, "\n\n")
60
+ .replace(/[ \t]{2,}/g, " ")
61
+ .trim();
62
+ }
63
+ function wrapLine(text, width, measure) {
64
+ const words = text.split(/\s+/).filter(Boolean);
65
+ const lines = [];
66
+ let current = "";
67
+ for (const word of words) {
68
+ const next = current ? `${current} ${word}` : word;
69
+ if (measure(next) <= width || !current) {
70
+ current = next;
71
+ }
72
+ else {
73
+ lines.push(current);
74
+ current = word;
75
+ }
76
+ }
77
+ if (current)
78
+ lines.push(current);
79
+ return lines.length > 0 ? lines : [""];
80
+ }
81
+ export async function renderPdfDocument(input) {
82
+ const pdfDoc = await PDFDocument.create();
83
+ const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
84
+ const bold = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
85
+ const PAGE_WIDTH = 595.28;
86
+ const PAGE_HEIGHT = 841.89;
87
+ const MARGIN = 48;
88
+ const TITLE_SIZE = 18;
89
+ const BODY_SIZE = 10;
90
+ const LINE_HEIGHT = 14;
91
+ const bodyWidth = PAGE_WIDTH - MARGIN * 2;
92
+ const measure = (value) => font.widthOfTextAtSize(value, BODY_SIZE);
93
+ let page = pdfDoc.addPage([PAGE_WIDTH, PAGE_HEIGHT]);
94
+ let y = PAGE_HEIGHT - MARGIN;
95
+ const ensureSpace = (needed) => {
96
+ if (y - needed < MARGIN) {
97
+ page = pdfDoc.addPage([PAGE_WIDTH, PAGE_HEIGHT]);
98
+ y = PAGE_HEIGHT - MARGIN;
99
+ }
100
+ };
101
+ const drawLine = (text, options) => {
102
+ const size = options?.size ?? BODY_SIZE;
103
+ ensureSpace(LINE_HEIGHT);
104
+ page.drawText(text, {
105
+ x: MARGIN,
106
+ y,
107
+ size,
108
+ font: options?.bold ? bold : font,
109
+ color: rgb(0.12, 0.12, 0.12),
110
+ });
111
+ y -= LINE_HEIGHT;
112
+ };
113
+ const title = input.title?.trim();
114
+ if (title) {
115
+ drawLine(title, { bold: true, size: TITLE_SIZE });
116
+ y -= 6;
117
+ }
118
+ for (const meta of input.metadataLines ?? []) {
119
+ const trimmed = meta.trim();
120
+ if (!trimmed)
121
+ continue;
122
+ for (const line of wrapLine(trimmed, bodyWidth, measure)) {
123
+ drawLine(line);
124
+ }
125
+ }
126
+ if ((input.metadataLines?.length ?? 0) > 0) {
127
+ y -= 6;
128
+ }
129
+ const normalized = normalizePdfText(input.content, input.format ?? "text");
130
+ for (const paragraph of normalized.split(/\n{2,}/)) {
131
+ const lines = paragraph.split("\n").flatMap((line) => wrapLine(line, bodyWidth, measure));
132
+ for (const line of lines) {
133
+ drawLine(line);
134
+ }
135
+ y -= 4;
136
+ }
137
+ return pdfDoc.save();
138
+ }
139
+ //# sourceMappingURL=pdf-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-renderer.js","sourceRoot":"","sources":["../src/pdf-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type StructuredTemplateBodyFormat = "html" | "markdown" | "lexical_json";
2
+ export declare function renderMustacheTemplate(body: string, variables: Record<string, unknown>): string;
3
+ export declare function renderStringTemplate(body: string, variables: Record<string, unknown>): string;
4
+ export declare function renderStructuredTemplate(body: string, bodyFormat: StructuredTemplateBodyFormat, variables: Record<string, unknown>): string;
5
+ //# sourceMappingURL=template-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-renderer.d.ts","sourceRoot":"","sources":["../src/template-renderer.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,4BAA4B,GAAG,MAAM,GAAG,UAAU,GAAG,cAAc,CAAA;AAsD/E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAK/F;AAMD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAM7F;AAaD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,4BAA4B,EACxC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,CA6BR"}
@@ -0,0 +1,106 @@
1
+ import { Liquid } from "liquidjs";
2
+ const liquid = new Liquid({
3
+ strictFilters: false,
4
+ strictVariables: false,
5
+ jsTruthy: true,
6
+ });
7
+ liquid.registerFilter("json", (value) => JSON.stringify(value ?? null));
8
+ function resolvePath(obj, path) {
9
+ if (obj === null || obj === undefined)
10
+ return undefined;
11
+ const segments = [];
12
+ const parts = path.split(".");
13
+ for (const part of parts) {
14
+ if (!part)
15
+ continue;
16
+ const indexMatches = [...part.matchAll(/([^[\]]+)|\[(\d+)\]/g)];
17
+ for (const match of indexMatches) {
18
+ if (match[1] !== undefined)
19
+ segments.push(match[1]);
20
+ else if (match[2] !== undefined)
21
+ segments.push(Number.parseInt(match[2], 10));
22
+ }
23
+ }
24
+ let current = obj;
25
+ for (const seg of segments) {
26
+ if (current === null || current === undefined)
27
+ return undefined;
28
+ if (typeof seg === "number") {
29
+ if (!Array.isArray(current))
30
+ return undefined;
31
+ current = current[seg];
32
+ }
33
+ else {
34
+ if (typeof current !== "object")
35
+ return undefined;
36
+ current = current[seg];
37
+ }
38
+ }
39
+ return current;
40
+ }
41
+ function stringifyValue(value) {
42
+ if (value === null || value === undefined)
43
+ return "";
44
+ if (typeof value === "string")
45
+ return value;
46
+ if (typeof value === "number" || typeof value === "boolean")
47
+ return String(value);
48
+ return JSON.stringify(value);
49
+ }
50
+ const MUSTACHE_RE = /\{\{\s*([^}]+?)\s*\}\}/g;
51
+ const LIQUID_CONTROL_RE = /\{%-?[\s\S]*?-?%\}/;
52
+ const LIQUID_FILTER_RE = /\{\{[\s\S]*\|[\s\S]*\}\}/;
53
+ export function renderMustacheTemplate(body, variables) {
54
+ return body.replace(MUSTACHE_RE, (_, path) => {
55
+ const resolved = resolvePath(variables, path.trim());
56
+ return stringifyValue(resolved);
57
+ });
58
+ }
59
+ function shouldUseLiquid(body) {
60
+ return LIQUID_CONTROL_RE.test(body) || LIQUID_FILTER_RE.test(body);
61
+ }
62
+ export function renderStringTemplate(body, variables) {
63
+ if (!shouldUseLiquid(body)) {
64
+ return renderMustacheTemplate(body, variables);
65
+ }
66
+ return liquid.parseAndRenderSync(body, variables);
67
+ }
68
+ function walkLexical(node, variables) {
69
+ const next = { ...node };
70
+ if (typeof next.text === "string") {
71
+ next.text = renderStringTemplate(next.text, variables);
72
+ }
73
+ if (Array.isArray(next.children)) {
74
+ next.children = next.children.map((child) => walkLexical(child, variables));
75
+ }
76
+ return next;
77
+ }
78
+ export function renderStructuredTemplate(body, bodyFormat, variables) {
79
+ if (bodyFormat === "lexical_json") {
80
+ try {
81
+ const parsed = JSON.parse(body);
82
+ if (Array.isArray(parsed)) {
83
+ return JSON.stringify(parsed.map((entry) => {
84
+ if (entry && typeof entry === "object") {
85
+ return walkLexical(entry, variables);
86
+ }
87
+ return entry;
88
+ }));
89
+ }
90
+ if (parsed && typeof parsed === "object") {
91
+ const obj = parsed;
92
+ if (obj.root && typeof obj.root === "object") {
93
+ const result = { ...obj, root: walkLexical(obj.root, variables) };
94
+ return JSON.stringify(result);
95
+ }
96
+ return JSON.stringify(walkLexical(obj, variables));
97
+ }
98
+ return body;
99
+ }
100
+ catch {
101
+ return renderStringTemplate(body, variables);
102
+ }
103
+ }
104
+ return renderStringTemplate(body, variables);
105
+ }
106
+ //# sourceMappingURL=template-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-renderer.js","sourceRoot":"","sources":["../src/template-renderer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/utils",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "license": "FSL-1.1-Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -61,6 +61,14 @@
61
61
  "./cache": {
62
62
  "types": "./dist/cache.d.ts",
63
63
  "import": "./dist/cache.js"
64
+ },
65
+ "./template-renderer": {
66
+ "types": "./dist/template-renderer.d.ts",
67
+ "import": "./dist/template-renderer.js"
68
+ },
69
+ "./pdf-renderer": {
70
+ "types": "./dist/pdf-renderer.d.ts",
71
+ "import": "./dist/pdf-renderer.js"
64
72
  }
65
73
  },
66
74
  "publishConfig": {
@@ -71,8 +79,10 @@
71
79
  ],
72
80
  "dependencies": {
73
81
  "drizzle-orm": "^0.45.2",
82
+ "liquidjs": "^10.24.0",
83
+ "pdf-lib": "^1.17.1",
74
84
  "zod": "^4.3.6",
75
- "@voyantjs/types": "0.3.1"
85
+ "@voyantjs/types": "0.4.0"
76
86
  },
77
87
  "devDependencies": {
78
88
  "@types/node": "^25.5.2",