feat: HTML-to-PDF layout options and watermark positioning#13
feat: HTML-to-PDF layout options and watermark positioning#13
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds schema enhancements to support HTML-to-PDF layout options and watermark positioning customization, extracted from the larger PR #12 for focused review. The changes enable fine-grained control over HTML-to-PDF conversion parameters and expand watermark customization capabilities beyond the basic centered positioning.
Changes:
- Added HTML-to-PDF layout control: page orientation, size presets (A0-A8, Letter, Legal), custom dimensions, and margins
- Enabled watermark positioning offsets (top, right, bottom, left) and font customization (family, size, style)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/schemas.ts
Outdated
| bottom: WatermarkDimensionSchema.optional().describe('Offset of the watermark from the bottom edge of a page.'), | ||
| left: WatermarkDimensionSchema.optional().describe('Offset of the watermark from the left edge of a page.'), | ||
| fontFamily: z.string().optional().describe('The font family to use for text watermarks.'), | ||
| fontSize: z.number().optional().describe('Font size in points for text watermarks.'), |
There was a problem hiding this comment.
The fontSize field should have validation to prevent non-positive values, as font sizes must be greater than zero. Consider adding .positive() or .min(1) validation to ensure valid font sizes.
| fontSize: z.number().optional().describe('Font size in points for text watermarks.'), | |
| fontSize: z.number().positive().optional().describe('Font size in points for text watermarks.'), |
src/schemas.ts
Outdated
| layout: HTMLLayoutSchema.describe( | ||
| 'Page layout options for HTML-to-PDF conversion. Only applies when the input is an HTML file. ' + | ||
| 'Supports orientation, page size, and margins.', | ||
| ), |
There was a problem hiding this comment.
The new HTML layout options for FilePartSchema (orientation, page size, margins) are not covered by any tests. Consider adding test cases that exercise these new fields to ensure they work correctly with HTML-to-PDF conversion.
| top: WatermarkDimensionSchema.optional().describe('Offset of the watermark from the top edge of a page.'), | ||
| right: WatermarkDimensionSchema.optional().describe('Offset of the watermark from the right edge of a page.'), | ||
| bottom: WatermarkDimensionSchema.optional().describe('Offset of the watermark from the bottom edge of a page.'), | ||
| left: WatermarkDimensionSchema.optional().describe('Offset of the watermark from the left edge of a page.'), | ||
| fontFamily: z.string().optional().describe('The font family to use for text watermarks.'), | ||
| fontSize: z.number().optional().describe('Font size in points for text watermarks.'), | ||
| fontStyle: z | ||
| .array(z.enum(['bold', 'italic'])) | ||
| .optional() | ||
| .describe('Font style for text watermarks. Can be italic, bold, or both.'), |
There was a problem hiding this comment.
The new watermark positioning fields (top, right, bottom, left) and font customization fields (fontFamily, fontSize, fontStyle) are not covered by any tests. Consider adding test cases that use these new fields to verify they work correctly with the watermark action.
src/schemas.ts
Outdated
| .string() | ||
| .optional() | ||
| .describe("Used to determine the file type when the file content type is not available and can't be inferred."), | ||
| layout: HTMLLayoutSchema.describe( |
There was a problem hiding this comment.
The layout field should be optional since it only applies to HTML input files. Without marking it as optional, this field will be required for all file parts, including PDFs and other non-HTML formats. Add .optional() before .describe() to fix this issue, similar to how password, pages, and content_type fields are handled.
| layout: HTMLLayoutSchema.describe( | |
| layout: HTMLLayoutSchema.optional().describe( |
src/schemas.ts
Outdated
| left: z.number().describe('Left margin in millimeters.'), | ||
| top: z.number().describe('Top margin in millimeters.'), | ||
| right: z.number().describe('Right margin in millimeters.'), | ||
| bottom: z.number().describe('Bottom margin in millimeters.'), |
There was a problem hiding this comment.
The margin fields (left, top, right, bottom) should have validation to prevent negative values, as negative margins don't make sense in the context of HTML-to-PDF conversion. Consider adding .min(0) validation to each margin field, similar to how opacity is validated on line 255.
| left: z.number().describe('Left margin in millimeters.'), | |
| top: z.number().describe('Top margin in millimeters.'), | |
| right: z.number().describe('Right margin in millimeters.'), | |
| bottom: z.number().describe('Bottom margin in millimeters.'), | |
| left: z.number().min(0).describe('Left margin in millimeters.'), | |
| top: z.number().min(0).describe('Top margin in millimeters.'), | |
| right: z.number().min(0).describe('Right margin in millimeters.'), | |
| bottom: z.number().min(0).describe('Bottom margin in millimeters.'), |
src/schemas.ts
Outdated
| width: z.number().describe('Page width in millimeters.'), | ||
| height: z.number().describe('Page height in millimeters.'), |
There was a problem hiding this comment.
The custom page size dimensions (width and height) should have validation to prevent non-positive values, as page dimensions must be greater than zero. Consider adding .min(0) or .positive() validation to both width and height fields.
| width: z.number().describe('Page width in millimeters.'), | |
| height: z.number().describe('Page height in millimeters.'), | |
| width: z | |
| .number() | |
| .positive() | |
| .describe('Page width in millimeters.'), | |
| height: z | |
| .number() | |
| .positive() | |
| .describe('Page height in millimeters.'), |
|
Addressed all 6 Copilot review comments in d1d1521: Schema validations:
Tests added: Build clean, all tests passing (125 insertions, 9 deletions). |
| .optional() | ||
| .describe('Page margins in millimeters.'), | ||
| }) | ||
| .optional() |
There was a problem hiding this comment.
NIT: We can remove this optional. It's up to the consumer to decide if the schema is optional, i.e. FilePartSchema.
- Add PageSizePresetSchema (A0-A8, Letter, Legal) - Add HTMLLayoutSchema with orientation, size, margin options - Add layout field to FilePartSchema for HTML-to-PDF conversion - Enable watermark positioning (top/right/bottom/left offsets) - Enable font customization (fontFamily, fontSize, fontStyle)
…out and watermark fields
d1d1521 to
7df87f4
Compare
Summary
Adds schema enhancements for HTML-to-PDF conversion and watermark positioning.
Changes
HTML-to-PDF Layout Options:
PageSizePresetSchema— enum with A0-A8, Letter, Legal presetsHTMLLayoutSchema— object with orientation, page size, and margin optionslayoutfield added toFilePartSchemafor HTML input filesWatermark Positioning:
top,right,bottom,left(usingWatermarkDimensionSchema)fontFamily,fontSize,fontStyleTesting
Split from #12 per review feedback to keep PRs focused and reviewable.