hazo_pdf 1.7.0 → 2.0.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.
Files changed (36) hide show
  1. package/SETUP_CHECKLIST.md +693 -0
  2. package/config/hazo_pdf_config.ini.sample +42 -0
  3. package/db_setup_postgres.sql +17 -0
  4. package/db_setup_sqlite.sql +13 -0
  5. package/dist/{chunk-NQ6KUJWG.js → chunk-7M53O3HF.js} +14 -4
  6. package/dist/chunk-7M53O3HF.js.map +1 -0
  7. package/dist/{chunk-4JJOUQ62.js → chunk-KDOQ3FIO.js} +176 -87
  8. package/dist/chunk-KDOQ3FIO.js.map +1 -0
  9. package/dist/{chunk-KHB3VZJQ.js → chunk-LFFCPDWC.js} +14 -3
  10. package/dist/chunk-LFFCPDWC.js.map +1 -0
  11. package/dist/{chunk-264BTVJT.js → chunk-TZJ5S57X.js} +18 -31
  12. package/dist/chunk-TZJ5S57X.js.map +1 -0
  13. package/dist/index.d.ts +9 -5
  14. package/dist/index.js +35 -16
  15. package/dist/index.js.map +1 -1
  16. package/dist/{pdf_saver-7FA4DAXI.js → pdf_saver-T6SEDYEE.js} +3 -3
  17. package/dist/{pdf_viewer-B6S5PJJB.js → pdf_viewer-TFCSUGWU.js} +3 -3
  18. package/dist/server/index.d.ts +5 -1
  19. package/dist/server/index.js +219 -81
  20. package/dist/server/index.js.map +1 -1
  21. package/dist/server/{text_search-2OZOVUIP.js → text_search-PVDG5Y6I.js} +14 -3
  22. package/dist/server/text_search-PVDG5Y6I.js.map +1 -0
  23. package/dist/styles/full.css +5821 -7156
  24. package/dist/styles/full.css.map +1 -1
  25. package/dist/styles/index.css +4844 -3929
  26. package/dist/styles/index.css.map +1 -1
  27. package/dist/{text_search-I2KZ7DTW.js → text_search-SO4ZOMIZ.js} +2 -2
  28. package/package.json +51 -36
  29. package/dist/chunk-264BTVJT.js.map +0 -1
  30. package/dist/chunk-4JJOUQ62.js.map +0 -1
  31. package/dist/chunk-KHB3VZJQ.js.map +0 -1
  32. package/dist/chunk-NQ6KUJWG.js.map +0 -1
  33. package/dist/server/text_search-2OZOVUIP.js.map +0 -1
  34. /package/dist/{pdf_saver-7FA4DAXI.js.map → pdf_saver-T6SEDYEE.js.map} +0 -0
  35. /package/dist/{pdf_viewer-B6S5PJJB.js.map → pdf_viewer-TFCSUGWU.js.map} +0 -0
  36. /package/dist/{text_search-I2KZ7DTW.js.map → text_search-SO4ZOMIZ.js.map} +0 -0
@@ -2,6 +2,48 @@
2
2
  # This file allows you to customize the styling and appearance of hazo_pdf components.
3
3
  # All values are commented out by default - uncomment and modify values as needed.
4
4
  # If a value is not specified, the default value will be used.
5
+ #
6
+ # Per hazo workspace standard S7, values may also be overridden via env vars:
7
+ # HAZO_PDF_<SECTION>_<KEY>=value
8
+ # e.g. HAZO_PDF_EXTRACTION_SQLITE_PATH=/var/lib/app/prompt_library.sqlite
9
+ #
10
+ # Per D-019, a per-environment overlay file at config/hazo_pdf_config.<HAZO_ENV>.ini
11
+ # is layered on top of this base file when HAZO_ENV is set.
12
+
13
+ # =============================================================================
14
+ # [general] - Workspace-standard general configuration
15
+ # =============================================================================
16
+ [general]
17
+
18
+ # Deployment environment label. Falls back to NODE_ENV, then 'development'.
19
+ # env = production
20
+
21
+ # Optional path to the styling INI consumed by PdfViewer's config_loader.
22
+ # config_file = config/hazo_pdf_config.ini
23
+
24
+ # =============================================================================
25
+ # [log.overrides] - Per-namespace log level overrides (workspace standard)
26
+ # Format: <namespace> = trace|debug|info|warn|error
27
+ # =============================================================================
28
+ [log.overrides]
29
+
30
+ # hazo_pdf = debug
31
+ # hazo_pdf/extract = info
32
+ # hazo_pdf/split = info
33
+
34
+ # =============================================================================
35
+ # [extraction] - Server-side document extraction defaults
36
+ # =============================================================================
37
+ [extraction]
38
+
39
+ # SQLite path used to bootstrap hazo_files + hazo_llm_api on the server
40
+ # sqlite_path = prompt_library.sqlite
41
+
42
+ # Default storage type when none is provided by the caller (local | google_drive)
43
+ # default_storage_type = local
44
+
45
+ # Max recursion depth for hazo_llm_api dynamic extraction
46
+ # max_depth = 10
5
47
 
6
48
  # =============================================================================
7
49
  # [fonts] - Font configuration for FreeText annotations
@@ -0,0 +1,17 @@
1
+ -- hazo_pdf database schema (PostgreSQL)
2
+ -- Idempotent (safe to run multiple times)
3
+ --
4
+ -- hazo_pdf does NOT own any database tables of its own. The package is a
5
+ -- view + annotation + extraction utility that operates on PDFs supplied by
6
+ -- the consumer. Its server-side extraction helpers (extract_document_data,
7
+ -- extract_text_snippet) persist metadata to the hazo_files table — run
8
+ -- hazo_files/db_setup_postgres.sql to provision that schema.
9
+ --
10
+ -- This file exists so the workspace-standard S6 check stays satisfied if a
11
+ -- migrations/ directory is added later, and to give consumers a single
12
+ -- predictable entry point ("run db_setup_postgres.sql for every hazo_*
13
+ -- package you depend on").
14
+
15
+ -- No-op placeholder — keep PostgREST happy when this file is sourced in a
16
+ -- cascade alongside other hazo_* db_setup files.
17
+ SELECT pg_notify('pgrst', 'reload schema');
@@ -0,0 +1,13 @@
1
+ -- hazo_pdf database schema (SQLite)
2
+ -- Idempotent (safe to run multiple times)
3
+ --
4
+ -- hazo_pdf does NOT own any database tables of its own. The package is a
5
+ -- view + annotation + extraction utility that operates on PDFs supplied by
6
+ -- the consumer. Its server-side extraction helpers (extract_document_data,
7
+ -- extract_text_snippet) persist metadata to the hazo_files table — run
8
+ -- hazo_files/db_setup_sqlite.sql to provision that schema.
9
+
10
+ -- No-op placeholder. SELECT 1 is the cheapest idempotent statement that
11
+ -- keeps the file syntactically valid for tools that batch-source every
12
+ -- hazo_* db_setup_sqlite.sql.
13
+ SELECT 1;
@@ -2,9 +2,10 @@
2
2
  import {
3
3
  default_config,
4
4
  get_logger
5
- } from "./chunk-264BTVJT.js";
5
+ } from "./chunk-TZJ5S57X.js";
6
6
 
7
7
  // src/utils/pdf_saver.ts
8
+ import { HazoExternalError, HazoUnavailableError } from "hazo_core/errors";
8
9
  async function save_annotations_to_pdf(pdf_source, annotations, _output_filename, config, page_rotations) {
9
10
  const logger = get_logger();
10
11
  try {
@@ -14,7 +15,12 @@ async function save_annotations_to_pdf(pdf_source, annotations, _output_filename
14
15
  logger.info(`Fetching PDF from: ${pdf_source}`);
15
16
  const pdf_response = await fetch(pdf_source);
16
17
  if (!pdf_response.ok) {
17
- throw new Error(`Failed to fetch PDF: ${pdf_response.status} ${pdf_response.statusText}`);
18
+ throw new HazoExternalError({
19
+ code: "HAZO_PDF_EXTERNAL_FETCH_FAILED",
20
+ pkg: "hazo_pdf",
21
+ message: `Failed to fetch PDF: ${pdf_response.status} ${pdf_response.statusText}`,
22
+ httpStatus: 502
23
+ });
18
24
  }
19
25
  pdf_bytes = await pdf_response.arrayBuffer();
20
26
  logger.debug(`PDF fetched, size: ${pdf_bytes.byteLength} bytes`);
@@ -194,7 +200,11 @@ async function save_annotations_to_pdf(pdf_source, annotations, _output_filename
194
200
  return modified_pdf_bytes;
195
201
  } catch (error) {
196
202
  if (error && typeof error === "object" && "message" in error && typeof error.message === "string" && error.message.includes("pdf-lib")) {
197
- throw new Error("pdf-lib is required to save annotations to PDF. Please install it: npm install pdf-lib");
203
+ throw new HazoUnavailableError({
204
+ code: "HAZO_PDF_OPTIONAL_DEP_MISSING",
205
+ pkg: "hazo_pdf",
206
+ message: "pdf-lib is required to save annotations to PDF. Please install it: npm install pdf-lib"
207
+ });
198
208
  }
199
209
  logger.error("Error saving PDF", { data: error });
200
210
  throw error;
@@ -227,4 +237,4 @@ export {
227
237
  download_pdf,
228
238
  save_and_download_pdf
229
239
  };
230
- //# sourceMappingURL=chunk-NQ6KUJWG.js.map
240
+ //# sourceMappingURL=chunk-7M53O3HF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/pdf_saver.ts"],"sourcesContent":["/**\n * PDF Saver Utility\n * Saves annotations directly into PDF documents using pdf-lib\n * This allows annotations to be embedded in the PDF file itself\n */\n\nimport type { PdfAnnotation, PdfViewerConfig } from '../types';\nimport { default_config } from '../config/default_config';\nimport { HazoExternalError, HazoUnavailableError } from 'hazo_core/errors';\nimport { get_logger } from './logger';\n\n/**\n * Save annotations into a PDF document\n * This function loads the PDF (from URL or ArrayBuffer), adds annotations, and returns the modified PDF\n * @param pdf_source - URL of the PDF file OR ArrayBuffer containing PDF data\n * @param annotations - Array of annotations to save\n * @param output_filename - Name for the saved PDF file (default: original filename with '_annotated' suffix)\n * @param config - Optional configuration for styling values\n * @param page_rotations - Optional map of page rotations (page_index -> degrees: 0, 90, 180, 270)\n * @returns Promise that resolves to the modified PDF as Uint8Array\n */\nexport async function save_annotations_to_pdf(\n pdf_source: string | ArrayBuffer,\n annotations: PdfAnnotation[],\n _output_filename?: string, // Currently unused, kept for API compatibility\n config?: PdfViewerConfig | null,\n page_rotations?: Map<number, number>\n): Promise<Uint8Array> {\n const logger = get_logger();\n try {\n // Dynamically import pdf-lib\n const { PDFDocument, rgb, degrees } = await import('pdf-lib');\n\n // Get PDF bytes from source (URL or ArrayBuffer)\n let pdf_bytes: ArrayBuffer;\n\n if (typeof pdf_source === 'string') {\n // Fetch the PDF from URL\n logger.info(`Fetching PDF from: ${pdf_source}`);\n const pdf_response = await fetch(pdf_source);\n if (!pdf_response.ok) {\n throw new HazoExternalError({\n code: 'HAZO_PDF_EXTERNAL_FETCH_FAILED',\n pkg: 'hazo_pdf',\n message: `Failed to fetch PDF: ${pdf_response.status} ${pdf_response.statusText}`,\n httpStatus: 502,\n });\n }\n pdf_bytes = await pdf_response.arrayBuffer();\n logger.debug(`PDF fetched, size: ${pdf_bytes.byteLength} bytes`);\n } else {\n // Use provided ArrayBuffer directly\n pdf_bytes = pdf_source;\n logger.debug(`Using provided PDF data, size: ${pdf_bytes.byteLength} bytes`);\n }\n \n // Load the PDF document\n const pdf_doc = await PDFDocument.load(pdf_bytes);\n logger.info(`PDF loaded, pages: ${pdf_doc.getPageCount()}`);\n\n // Apply page rotations if provided\n if (page_rotations && page_rotations.size > 0) {\n logger.debug('Applying page rotations', { data: Object.fromEntries(page_rotations) });\n const pages = pdf_doc.getPages();\n page_rotations.forEach((rotation, page_index) => {\n if (page_index >= 0 && page_index < pages.length && rotation !== 0) {\n const page = pages[page_index];\n // Get existing rotation and add our rotation to it\n const existing_rotation = page.getRotation().angle;\n const new_rotation = (existing_rotation + rotation) % 360;\n page.setRotation(degrees(new_rotation));\n logger.debug(`Page ${page_index}: rotation ${existing_rotation}° -> ${new_rotation}°`);\n }\n });\n }\n\n // Get config values or use defaults\n const fonts_config = config?.fonts || default_config.fonts;\n const highlight_config = config?.highlight_annotation || default_config.highlight_annotation;\n const square_config = config?.square_annotation || default_config.square_annotation;\n const freetext_config = config?.freetext_annotation || default_config.freetext_annotation;\n \n // Add annotations to each page\n for (const annotation of annotations) {\n if (annotation.page_index >= pdf_doc.getPageCount()) {\n logger.warn(`Annotation ${annotation.id} references page ${annotation.page_index}, but PDF only has ${pdf_doc.getPageCount()} pages. Skipping.`);\n continue;\n }\n \n const page = pdf_doc.getPage(annotation.page_index);\n const [x1, y1, x2, y2] = annotation.rect;\n \n // PDF coordinate system: bottom-left is origin (pdfjs-dist)\n // pdf-lib uses bottom-left as origin too, so coordinates should be fine\n // But we need to ensure rect is normalized\n const rect_x = Math.min(x1, x2);\n const rect_y = Math.min(y1, y2);\n const rect_width = Math.abs(x2 - x1);\n const rect_height = Math.abs(y2 - y1);\n \n // Parse color (hex or rgb to RGB for pdf-lib)\n // Supports both hex (#RRGGBB) and rgb(r, g, b) formats\n let color = rgb(0, 0, 0); // Default black\n if (annotation.color) {\n const color_str = annotation.color.trim();\n \n // Handle rgb(r, g, b) format\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = color_str.match(rgb_pattern);\n if (rgb_match) {\n const r = parseInt(rgb_match[1], 10);\n const g = parseInt(rgb_match[2], 10);\n const b = parseInt(rgb_match[3], 10);\n // Validate RGB values (0-255) and convert to 0-1 range for pdf-lib\n if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {\n color = rgb(r / 255, g / 255, b / 255);\n } else {\n logger.warn(`Invalid RGB values for annotation ${annotation.id}: r=${r}, g=${g}, b=${b}`);\n }\n } else if (color_str.startsWith('#')) {\n // Handle hex format (#RRGGBB)\n const hex = color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n const r = parseInt(hex.substring(0, 2), 16) / 255;\n const g = parseInt(hex.substring(2, 4), 16) / 255;\n const b = parseInt(hex.substring(4, 6), 16) / 255;\n color = rgb(r, g, b);\n } else {\n logger.warn(`Invalid hex color format for annotation ${annotation.id}: ${color_str}`);\n }\n } else {\n logger.warn(`Unrecognized color format for annotation ${annotation.id}: ${color_str}`);\n }\n }\n \n // Create annotation based on type using pdf-lib's annotation methods\n try {\n switch (annotation.type) {\n case 'Square': {\n // Create a rectangle/square annotation\n page.drawRectangle({\n x: rect_x,\n y: rect_y,\n width: rect_width,\n height: rect_height,\n borderColor: color,\n borderWidth: 2,\n borderOpacity: 0.8,\n });\n \n // Add text comment if present\n if (annotation.contents) {\n const comment_color_str = (annotation.color || square_config.square_border_color).trim();\n let comment_r = 0, comment_g = 0, comment_b = 0;\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = comment_color_str.match(rgb_pattern);\n if (rgb_match) {\n comment_r = parseInt(rgb_match[1], 10) / 255;\n comment_g = parseInt(rgb_match[2], 10) / 255;\n comment_b = parseInt(rgb_match[3], 10) / 255;\n } else if (comment_color_str.startsWith('#')) {\n const hex = comment_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n comment_r = parseInt(hex.substring(0, 2), 16) / 255;\n comment_g = parseInt(hex.substring(2, 4), 16) / 255;\n comment_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n \n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y + rect_height + 5,\n size: fonts_config.freetext_font_size_default,\n color: rgb(comment_r, comment_g, comment_b),\n });\n }\n break;\n }\n \n case 'Highlight': {\n // Create a highlight annotation (semi-transparent rectangle)\n const highlight_color_str = (annotation.color || highlight_config.highlight_fill_color).trim();\n let highlight_r = 255 / 255, highlight_g = 255 / 255, highlight_b = 0 / 255; // Default yellow\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = highlight_color_str.match(rgb_pattern);\n if (rgb_match) {\n highlight_r = parseInt(rgb_match[1], 10) / 255;\n highlight_g = parseInt(rgb_match[2], 10) / 255;\n highlight_b = parseInt(rgb_match[3], 10) / 255;\n } else if (highlight_color_str.startsWith('#')) {\n const hex = highlight_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n highlight_r = parseInt(hex.substring(0, 2), 16) / 255;\n highlight_g = parseInt(hex.substring(2, 4), 16) / 255;\n highlight_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n const highlight_color = rgb(highlight_r, highlight_g, highlight_b);\n \n page.drawRectangle({\n x: rect_x,\n y: rect_y,\n width: rect_width,\n height: rect_height,\n color: highlight_color,\n opacity: highlight_config.highlight_fill_opacity,\n });\n \n // Add text comment if present\n if (annotation.contents) {\n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y + rect_height + 5,\n size: fonts_config.freetext_font_size_default,\n color: rgb(0, 0, 0),\n });\n }\n break;\n }\n \n case 'FreeText': {\n // Create a free text annotation\n if (annotation.contents) {\n // Text color priority: annotation.color > freetext_text_color > font_foreground_color > default black\n const text_color_str = (annotation.color || \n freetext_config.freetext_text_color || \n fonts_config.font_foreground_color || \n '#000000').trim();\n let text_r = 0, text_g = 0, text_b = 0;\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = text_color_str.match(rgb_pattern);\n if (rgb_match) {\n text_r = parseInt(rgb_match[1], 10) / 255;\n text_g = parseInt(rgb_match[2], 10) / 255;\n text_b = parseInt(rgb_match[3], 10) / 255;\n } else if (text_color_str.startsWith('#')) {\n const hex = text_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n text_r = parseInt(hex.substring(0, 2), 16) / 255;\n text_g = parseInt(hex.substring(2, 4), 16) / 255;\n text_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n \n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y,\n size: fonts_config.freetext_font_size_default,\n color: rgb(text_r, text_g, text_b),\n maxWidth: rect_width,\n });\n }\n break;\n }\n \n default:\n logger.warn(`Unsupported annotation type: ${annotation.type}`);\n }\n } catch (annotation_error) {\n logger.error(`Error adding annotation ${annotation.id}`, { data: annotation_error });\n // Continue with other annotations\n }\n }\n \n // Save the PDF\n const modified_pdf_bytes = await pdf_doc.save();\n logger.info(`PDF modified, size: ${modified_pdf_bytes.length} bytes`);\n \n return modified_pdf_bytes;\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error &&\n typeof error.message === 'string' && error.message.includes('pdf-lib')) {\n throw new HazoUnavailableError({\n code: 'HAZO_PDF_OPTIONAL_DEP_MISSING',\n pkg: 'hazo_pdf',\n message: 'pdf-lib is required to save annotations to PDF. Please install it: npm install pdf-lib',\n });\n }\n logger.error('Error saving PDF', { data: error as Record<string, unknown> });\n throw error;\n }\n}\n\n/**\n * Download PDF bytes as a file\n * @param pdf_bytes - PDF file bytes\n * @param filename - Name for the downloaded file\n */\nexport function download_pdf(pdf_bytes: Uint8Array, filename: string): void {\n // Create a new ArrayBuffer view to ensure compatibility with Blob constructor\n // Uint8Array.buffer can be SharedArrayBuffer, which Blob doesn't accept directly\n const buffer = new Uint8Array(pdf_bytes).buffer;\n const blob = new Blob([buffer], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n}\n\n/**\n * Save annotations to PDF and download\n * @param pdf_source - URL of the PDF file OR ArrayBuffer containing PDF data\n * @param annotations - Array of annotations to save\n * @param output_filename - Name for the saved PDF file (default: original filename with '_annotated' suffix)\n * @param config - Optional configuration for styling values\n * @param page_rotations - Optional map of page rotations (page_index -> degrees: 0, 90, 180, 270)\n */\nexport async function save_and_download_pdf(\n pdf_source: string | ArrayBuffer,\n annotations: PdfAnnotation[],\n output_filename?: string,\n config?: PdfViewerConfig | null,\n page_rotations?: Map<number, number>\n): Promise<void> {\n const pdf_bytes = await save_annotations_to_pdf(pdf_source, annotations, output_filename, config, page_rotations);\n\n // Generate output filename\n const original_filename = typeof pdf_source === 'string'\n ? (pdf_source.split('/').pop() || 'document.pdf')\n : 'document.pdf';\n const filename_without_ext = original_filename.replace(/\\.pdf$/i, '');\n const final_filename = output_filename || `${filename_without_ext}_annotated.pdf`;\n\n // Download the modified PDF\n download_pdf(pdf_bytes, final_filename);\n const logger = get_logger();\n logger.info(`PDF saved as: ${final_filename}`);\n}\n\n"],"mappings":"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","names":[]}