@imgly/plugin-print-ready-pdfs-web 1.1.1 → 1.68.0-rc.1

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/CHANGELOG.md CHANGED
@@ -1,59 +1,3 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [1.1.1] - 2025-12-18
9
-
10
- ### Fixed
11
-
12
- - Fixed Webpack 5 compatibility issue where Node.js module imports (`module`, `path`, `fs`, `url`) caused build failures in Angular 17+ and other Webpack 5 environments ([#11471](https://github.com/imgly/ubq/issues/11471))
13
-
14
- ## [1.1.0] - 2025-12-03
15
-
16
- ### Added
17
-
18
- - Export `Logger` class for controlling log verbosity
19
- - Export `LogLevel` type for TypeScript users
20
-
21
- ### Changed
22
-
23
- - Library is now silent by default (log level set to `warn` instead of `info`)
24
- - Ghostscript WASM module suppresses stdout/stderr output by default
25
-
26
- ### Fixed
27
-
28
- - Eliminated Ghostscript warnings about PDF 1.5 features ("Can't use Object streams", "Can't use an XRef stream") by disabling `-dWriteObjStms` and `-dWriteXRefStm` when targeting PDF 1.4 compatibility
29
-
30
- ## [1.0.0] - 2025-10-21
31
-
32
- ### Changed
33
-
34
- - Promoted to stable release
35
-
36
- ## [0.1.0-rc.1] - 2025-10-16
37
-
38
- ### Added
39
-
40
- - Initial release candidate for Print-Ready PDFs plugin
41
- - Full PDF/X-3:2003 compliance with RGB to CMYK conversion
42
- - Three bundled ICC profiles:
43
- - FOGRA39 (ISO Coated v2) - European printing standard
44
- - GRACoL 2013 - US commercial printing standard
45
- - sRGB IEC61966-2.1 - Digital/web distribution
46
- - Custom ICC profile support for specialized printing requirements
47
- - Function overloading for batch PDF processing
48
- - Configurable OutputIntent metadata (identifier and description)
49
- - Transparency flattening control (enabled by default for PDF/X-3 compliance)
50
- - Browser-based PDF processing (100% client-side, no server required)
51
- - Node.js compatibility
52
-
53
- ### Notes
54
-
55
- - This is a release candidate for testing and feedback
56
- - Source code available at: https://github.com/imgly/plugins
57
- - Ghostscript WASM components are AGPL-3.0 licensed
58
- - Client-side execution model minimizes AGPL compliance concerns
59
- - For commercial licensing guidance, consult legal counsel or contact IMG.LY support
3
+ See the main [CE.SDK CHANGELOG](https://img.ly/docs/cesdk/changelog/) for all plugin changes.
package/README.md CHANGED
@@ -1,442 +1,9 @@
1
1
  # @imgly/plugin-print-ready-pdfs-web
2
2
 
3
- **Transform CE.SDK PDFs into Print-Ready CMYK Files**
3
+ Print-Ready PDFs plugin for CE.SDK editor - PDF/X conversion and export functionality. Contains AGPL-3.0 licensed Ghostscript WASM.
4
4
 
5
- Convert CE.SDK's standard PDF exports into fully **PDF/X-3 compliant, CMYK-based print-ready files** with embedded ICC output intents. This plugin hooks directly into CE.SDK's export process, ensuring your designs are automatically prepared for professional commercial printing workflows.
5
+ For documentation, visit: https://img.ly/docs/cesdk
6
6
 
7
- ## The Problem
7
+ ## License
8
8
 
9
- Your users design beautiful materials in CE.SDK. But professional printing requires specific PDF standards:
10
-
11
- - CMYK color space instead of RGB
12
- - PDF/X-3 or PDF/X-4 compliance
13
- - Embedded ICC color profiles for accurate color reproduction
14
-
15
- ## The Solution
16
-
17
- This plugin automatically converts CE.SDK's RGB PDFs into print-ready files that meet professional printing requirements:
18
-
19
- - ✅ **CMYK Color Space**: Converts RGB to CMYK using professional ICC profiles
20
- - ✅ **PDF/X Standards**: Generates PDF/X-3 compliant files for commercial printing
21
- - ✅ **Color Profile Support**: Embeds industry-standard or custom ICC profiles
22
- - ✅ **100% Client-Side**: Everything runs in the browser—zero backend infrastructure
23
- - ✅ **Drop-in Integration**: One function call transforms any PDF
24
-
25
- ## Key Features
26
-
27
- - **Drop-in Replacement**: Works seamlessly with CE.SDK's existing export functionality
28
- - **100% Client-Side**: All processing happens in the browser—no server infrastructure required
29
- - **Industry Profiles Included**: Ships with FOGRA39 (Europe), GRACoL 2013 (US), and sRGB profiles
30
- - **Custom Profile Support**: Bring your own ICC profile to match sophisticated print pipelines
31
- - **PDF/X-3 Compliant**: Generates files that meet commercial printing standards
32
-
33
- ## Installation
34
-
35
- ```bash
36
- npm install @imgly/plugin-print-ready-pdfs-web
37
- ```
38
-
39
- ## Quick Start
40
-
41
- Just one function call transforms any PDF into a print-ready file:
42
-
43
- ```javascript
44
- import { convertToPDFX3 } from '@imgly/plugin-print-ready-pdfs-web';
45
-
46
- // Convert CE.SDK's RGB PDF to print-ready CMYK
47
- const printReadyPDF = await convertToPDFX3(pdfBlob, {
48
- outputProfile: 'fogra39', // European printing standard
49
- title: 'My Print Document',
50
- });
51
-
52
- // That's it! The PDF is now ready for professional printing
53
- ```
54
-
55
- ## Drop-in CE.SDK Integration
56
-
57
- Add print-ready export to your existing CE.SDK implementation with minimal code changes:
58
-
59
- ```javascript
60
- import CreativeEditorSDK from '@cesdk/cesdk-js';
61
- import { convertToPDFX3 } from '@imgly/plugin-print-ready-pdfs-web';
62
-
63
- const config = {
64
- license: 'your-cesdk-license',
65
- };
66
-
67
- const cesdk = await CreativeEditorSDK.create('#editor', config);
68
- await cesdk.createDesignScene();
69
-
70
- // Add custom export button to the navigation bar
71
- cesdk.ui.insertNavigationBarOrderComponent('last', {
72
- id: 'ly.img.actions.navigationBar',
73
- children: [
74
- {
75
- key: 'export-print-ready-pdf',
76
- id: 'ly.img.action.navigationBar',
77
- label: 'Export Print-Ready PDF',
78
- iconName: '@imgly/Download',
79
- onClick: async () => {
80
- const sceneId = cesdk.engine.scene.get();
81
- const pdfBlob = await cesdk.engine.block.export(
82
- sceneId,
83
- 'application/pdf'
84
- );
85
- const printReadyBlob = await convertToPDFX3(pdfBlob, {
86
- outputProfile: 'fogra39',
87
- title: 'Print-Ready Export',
88
- });
89
-
90
- // Download
91
- const url = URL.createObjectURL(printReadyBlob);
92
- const link = document.createElement('a');
93
- link.href = url;
94
- link.download = 'design-print-ready.pdf';
95
- link.click();
96
- URL.revokeObjectURL(url);
97
- },
98
- },
99
- ],
100
- });
101
- ```
102
-
103
- ## API Reference
104
-
105
- ### `convertToPDFX3(pdf, options)` / `convertToPDFX3(pdfs, options)`
106
-
107
- Converts RGB PDF(s) to print-ready format. This function supports both single PDF conversion and batch processing through function overloading.
108
-
109
- **Single PDF Conversion:**
110
-
111
- ```typescript
112
- convertToPDFX3(pdf: Blob, options: PDFX3Options): Promise<Blob>
113
- ```
114
-
115
- **Parameters:**
116
- - `pdf` (Blob): Input PDF file as a Blob object
117
- - `options` (PDFX3Options): Conversion configuration
118
-
119
- **Returns:** Promise<Blob> - The print-ready PDF file
120
-
121
- **Batch Processing:**
122
-
123
- ```typescript
124
- convertToPDFX3(pdfs: Blob[], options: PDFX3Options): Promise<Blob[]>
125
- ```
126
-
127
- **Parameters:**
128
- - `pdfs` (Blob[]): Array of input PDF files as Blob objects
129
- - `options` (PDFX3Options): Conversion configuration (applied to all PDFs)
130
-
131
- **Returns:** Promise<Blob[]> - Array of print-ready PDF files
132
-
133
- **Options Interface:**
134
-
135
- ```typescript
136
- interface PDFX3Options {
137
- // Required
138
- outputProfile: 'gracol' | 'fogra39' | 'srgb' | 'custom';
139
-
140
- // Optional
141
- customProfile?: Blob; // Required only if outputProfile is 'custom'
142
- title?: string; // Document title
143
- outputConditionIdentifier?: string; // ICC profile identifier for OutputIntent
144
- outputCondition?: string; // Human-readable output condition description
145
- flattenTransparency?: boolean; // Flatten transparency (default: true for PDF/X-3)
146
- }
147
- ```
148
-
149
- **Note:** Batch processing handles each PDF sequentially to avoid overwhelming the WASM module.
150
-
151
- **OutputIntent Metadata:**
152
-
153
- The `outputConditionIdentifier` and `outputCondition` fields control the PDF/X-3 OutputIntent metadata:
154
-
155
- - **Built-in profiles** (fogra39, gracol, srgb): Use preset values automatically (e.g., "FOGRA39", "ISO Coated v2 (ECI)")
156
- - **Custom profiles**: Specify your own identifiers and descriptions
157
- - Both fields are optional and have sensible defaults
158
-
159
- ### Included Color Profiles
160
-
161
- The plugin ships with industry-standard ICC profiles for immediate use:
162
-
163
- | Profile | Purpose | Standard |
164
- | ----------- | ------------------------------- | ------------------------------------------------- |
165
- | `'fogra39'` | European CMYK printing standard | FOGRA39 (ISO Coated v2) - Offset printing profile |
166
- | `'gracol'` | US CMYK printing standard | GRACoL 2013 - Commercial printing profile |
167
- | `'srgb'` | Digital/web distribution | sRGB - When CMYK conversion isn't required |
168
- | `'custom'` | Specific color requirements | Load any ICC profile for exact color matching |
169
-
170
- ## Real-World Usage
171
-
172
- ### High-Level CE.SDK Export API
173
-
174
- The simplest way to integrate with CE.SDK's high-level export function:
175
-
176
- ```javascript
177
- import CreativeEditorSDK from '@cesdk/cesdk-js';
178
- import { convertToPDFX3 } from '@imgly/plugin-print-ready-pdfs-web';
179
-
180
- const cesdk = await CreativeEditorSDK.create('#editor', config);
181
-
182
- // Export and convert to print-ready in one flow
183
- const { blobs } = await cesdk.export({
184
- mimeType: 'application/pdf'
185
- });
186
-
187
- // Function overloading automatically handles array input
188
- const printReadyBlobs = await convertToPDFX3(blobs, {
189
- outputProfile: 'fogra39',
190
- title: 'Print-Ready Export',
191
- });
192
-
193
- // Download the first print-ready PDF
194
- const url = URL.createObjectURL(printReadyBlobs[0]);
195
- const link = document.createElement('a');
196
- link.href = url;
197
- link.download = 'design-print-ready.pdf';
198
- link.click();
199
- URL.revokeObjectURL(url);
200
- ```
201
-
202
- ### Professional Printing Requirements
203
-
204
- ```javascript
205
- import { convertToPDFX3 } from '@imgly/plugin-print-ready-pdfs-web';
206
-
207
- // Your user designed materials in CE.SDK
208
- const designPDF = await cesdk.engine.block.export(sceneId, 'application/pdf');
209
-
210
- // Convert to print-ready format with CMYK and PDF/X-3 compliance
211
- const printReadyPDF = await convertToPDFX3(designPDF, {
212
- outputProfile: 'fogra39', // Industry-standard CMYK profile
213
- title: 'Marketing Materials - Q4 2024',
214
- });
215
-
216
- // PDF now meets professional printing requirements
217
- ```
218
-
219
- ### Regional Color Standards
220
-
221
- ```javascript
222
- // US Commercial Printing Standard
223
- const usPrintReady = await convertToPDFX3(pdfBlob, {
224
- outputProfile: 'gracol', // GRACoL 2013 CMYK profile
225
- title: 'US Print Production',
226
- });
227
-
228
- // European Printing Standard
229
- const euPrintReady = await convertToPDFX3(pdfBlob, {
230
- outputProfile: 'fogra39', // FOGRA39 CMYK profile
231
- title: 'EU Print Production',
232
- });
233
- ```
234
-
235
- ### Custom Color Profiles
236
-
237
- Bring your own ICC profile for specialized printing requirements:
238
-
239
- ```javascript
240
- // Load a specific ICC profile for exact color requirements
241
- const customProfile = await fetch('/profiles/custom-cmyk-profile.icc').then(
242
- (r) => r.blob()
243
- );
244
-
245
- const printReadyPDF = await convertToPDFX3(pdfBlob, {
246
- outputProfile: 'custom',
247
- customProfile: customProfile,
248
- title: 'Specialized Print Output',
249
- outputConditionIdentifier: 'Custom_Newsprint_CMYK',
250
- outputCondition: 'Custom newsprint profile for high-speed web press'
251
- });
252
-
253
- // PDF now uses your exact CMYK color profile with custom metadata
254
- ```
255
-
256
- **Override Built-in Profile Metadata:**
257
-
258
- You can also override the metadata for built-in profiles:
259
-
260
- ```javascript
261
- const printReadyPDF = await convertToPDFX3(pdfBlob, {
262
- outputProfile: 'fogra39',
263
- title: 'Custom FOGRA39 Variant',
264
- outputConditionIdentifier: 'FOGRA39_Modified',
265
- outputCondition: 'Modified ISO Coated v2 for specific press'
266
- });
267
- ```
268
-
269
- ### Batch Processing
270
-
271
- Process multiple PDFs using the overloaded function:
272
-
273
- ```javascript
274
- import { convertToPDFX3 } from '@imgly/plugin-print-ready-pdfs-web';
275
-
276
- // Array input automatically triggers batch processing (sequential)
277
- const printReadyPDFs = await convertToPDFX3(pdfBlobs, {
278
- outputProfile: 'gracol',
279
- title: 'Batch Export',
280
- });
281
-
282
- // Or process in parallel for maximum speed (use with caution for large files)
283
- const printReadyPDFs = await Promise.all(
284
- pdfBlobs.map((pdf) =>
285
- convertToPDFX3(pdf, {
286
- outputProfile: 'gracol',
287
- title: 'Batch Export',
288
- })
289
- )
290
- );
291
- ```
292
-
293
- **Note:** When passing an array, PDFs are processed sequentially to avoid overwhelming the WASM module. For parallel processing, use `Promise.all` with individual calls. Sequential processing is recommended for reliability.
294
-
295
- ## Testing
296
-
297
- Test the integration with a complete CE.SDK example:
298
-
299
- ```bash
300
- # Start the test server
301
- npm run test:cesdk
302
-
303
- # Open http://localhost:3001 in your browser
304
- # Create designs and export with different print profiles
305
- ```
306
-
307
- The test interface includes:
308
-
309
- - Live CE.SDK editor
310
- - Navigation bar with print-ready export options
311
- - Real-time conversion and download
312
-
313
- ## PDF/X-3 Compliance Details
314
-
315
- The plugin ensures full PDF/X-3:2003 compliance by:
316
-
317
- ### OutputIntent
318
-
319
- Every converted PDF includes a properly configured OutputIntent entry with:
320
- - **DestOutputProfile**: The embedded ICC profile data
321
- - **OutputConditionIdentifier**: Standard identifier (e.g., "FOGRA39", "GRACoL 2013")
322
- - **OutputCondition**: Human-readable description of the printing condition
323
- - **S**: Set to `/GTS_PDFX` for PDF/X-3 standard
324
-
325
- ### Trapped Entry
326
-
327
- The `/Trapped` field is automatically set to `/False` in the PDF document info dictionary, indicating that trapping operations have not been performed. This is the correct value since the plugin performs color conversion but does not apply trapping.
328
-
329
- Per the PDF/X-3 specification, this field must be set to either `/True` or `/False` (not `/Unknown`).
330
-
331
- ### Text and Vector Preservation
332
-
333
- Text and vector graphics are preserved in their original vector format during conversion. Only the color space is converted from RGB to CMYK—no rasterization occurs for non-transparent content.
334
-
335
- ### Transparency Handling
336
-
337
- **Important:** PDF/X-3:2003 is based on PDF 1.3 which does not support transparency. By default, the plugin flattens all transparency to ensure compliance:
338
-
339
- ```javascript
340
- // Default behavior - flattens transparency (PDF/X-3 compliant)
341
- const printReadyPDF = await convertToPDFX3(pdfBlob, {
342
- outputProfile: 'fogra39',
343
- title: 'Print Ready',
344
- // flattenTransparency: true (default)
345
- });
346
- ```
347
-
348
- **Transparency Flattening Behavior:**
349
- - **Pages with transparency** → Rasterized to bitmap at high resolution
350
- - **Pages without transparency** → Preserved as vectors (text, shapes remain editable)
351
- - **Mixed content** → Only transparent elements are rasterized
352
-
353
- **Why Flattening is Required:**
354
-
355
- PDF/X-3 is based on PDF 1.3, which predates PDF transparency features (introduced in PDF 1.4). Therefore, **transparency flattening is mandatory** for PDF/X-3 compliance—this is a requirement of the standard itself, not a limitation of the tooling. Any PDF with transparency must have those elements composited into opaque equivalents before it can be a valid PDF/X-3 file.
356
-
357
- **⚠️ Known Issue: Black Backgrounds During Flattening**
358
-
359
- During the flattening process, certain elements with transparency may render with black backgrounds instead of their intended appearance. Affected elements include:
360
-
361
- - Gradients that fade to transparent
362
- - PNG images with alpha channels (e.g., stickers, icons)
363
- - Text with emoji characters
364
- - Overlapping semi-transparent elements
365
-
366
- **Workaround - Preserve Transparency:**
367
-
368
- If visual fidelity is more important than strict PDF/X-3 compliance, you can disable transparency flattening:
369
-
370
- ```javascript
371
- // Preserve transparency for better visual fidelity
372
- const printReadyPDF = await convertToPDFX3(pdfBlob, {
373
- outputProfile: 'fogra39',
374
- title: 'Visual Fidelity Preserved',
375
- flattenTransparency: false, // Preserves appearance but may not be strictly PDF/X-3 compliant
376
- });
377
- ```
378
-
379
- **Trade-offs:**
380
- | Setting | Visual Fidelity | PDF/X-3 Compliance |
381
- |---------|----------------|-------------------|
382
- | `flattenTransparency: true` (default) | May have artifacts | Strictly compliant |
383
- | `flattenTransparency: false` | Preserved | May not validate if transparency exists |
384
-
385
- **Avoiding Transparency Issues in CE.SDK:**
386
-
387
- To ensure best results with PDF/X-3, design without transparency:
388
- - Use 100% opacity for all elements
389
- - Avoid PNG images with alpha channels
390
- - Use solid fills instead of gradient opacity
391
- - Avoid gradients that fade to transparent
392
- - Export without blend modes
393
-
394
- ## Known Limitations
395
-
396
- - **Transparency Flattening Required**: PDF/X-3 is based on PDF 1.3 which does not support transparency. Transparency flattening is mandatory for compliance. During flattening, elements with transparency may render with black backgrounds (affects gradients with alpha, PNGs with transparency, emojis). Use `flattenTransparency: false` as a workaround if visual fidelity is more important than strict compliance. See [Transparency Handling](#transparency-handling) for details.
397
- - **Spot Colors**: Currently, spot colors (Pantone, custom inks) are converted to CMYK during the PDF/X-3 conversion process. This is a limitation of the current Ghostscript WASM implementation. If preserving spot colors is critical for your workflow, consider server-side PDF processing solutions.
398
- - **PDF/X Versions**: Only supports PDF/X-3:2003 (not X-1a or X-4 yet)
399
-
400
- ## License Considerations
401
-
402
- This plugin uses Ghostscript WebAssembly (AGPL-3.0 licensed) with **client-side browser execution**:
403
-
404
- ### How It Works
405
-
406
- - Ghostscript WASM loads dynamically in the user's browser
407
- - All PDF processing happens client-side on the user's device
408
- - No AGPL code runs on your servers
409
- - Similar to users installing a browser extension
410
-
411
- ### Usage Guidelines
412
-
413
- ✅ **Generally Safe For:**
414
-
415
- - Open source projects
416
- - Internal/private applications
417
- - Commercial websites (processing happens in user's browser)
418
- - SaaS applications (no server-side AGPL code execution)
419
-
420
- ⚠️ **Considerations:**
421
-
422
- - If you bundle/modify the WASM module directly
423
- - If you prevent users from accessing the source
424
- - If you process PDFs server-side
425
-
426
- ### Why Browser Execution Matters
427
-
428
- Since the AGPL-licensed Ghostscript runs entirely in the end user's browser rather than as a network service:
429
-
430
- 1. Your servers never execute AGPL code
431
- 2. You're not providing a "network service" under AGPL terms
432
- 3. The architecture is similar to CDN-delivered JavaScript libraries
433
-
434
- For specific legal guidance, consult with legal counsel. For technical questions, contact IMG.LY support.
435
-
436
- ## Support
437
-
438
- For questions about CE.SDK integration or print workflows:
439
-
440
- - [CE.SDK Documentation](https://img.ly/docs)
441
- - [GitHub Issues](https://github.com/imgly/plugins/issues)
442
- - [IMG.LY Support](https://img.ly/support)
9
+ This plugin is part of the IMG.LY plugin ecosystem for CreativeEditor SDK.
@@ -0,0 +1,14 @@
1
+ import type { EmscriptenModule } from '../types/ghostscript';
2
+ export interface LoaderOptions {
3
+ timeout?: number;
4
+ }
5
+ export declare class GhostscriptLoader {
6
+ private static instance;
7
+ private static readonly TIMEOUT_MS;
8
+ static load(options?: LoaderOptions): Promise<EmscriptenModule>;
9
+ private static loadInternal;
10
+ private static loadFromBundle;
11
+ private static loadWithTimeout;
12
+ static reset(): void;
13
+ }
14
+ //# sourceMappingURL=ghostscript-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ghostscript-loader.d.ts","sourceRoot":"","sources":["../../src/core/ghostscript-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAK7D,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0C;IAEjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAS;WAE9B,IAAI,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC;mBASpD,YAAY;mBA2BZ,cAAc;mBAwBd,eAAe;IAepC,MAAM,CAAC,KAAK,IAAI,IAAI;CAGrB"}
@@ -0,0 +1,22 @@
1
+ import type { EmscriptenModule } from '../types/ghostscript';
2
+ export interface FileEntry {
3
+ path: string;
4
+ data: Uint8Array;
5
+ cleanup: boolean;
6
+ }
7
+ export declare class VirtualFileSystem {
8
+ private readonly module;
9
+ private readonly fs;
10
+ private readonly logger;
11
+ private readonly managedFiles;
12
+ private readonly workingDir;
13
+ constructor(module: EmscriptenModule, workingDir?: string);
14
+ private initialize;
15
+ private createDirIfNotExists;
16
+ writeBlob(path: string, blob: Blob, managed?: boolean): Promise<void>;
17
+ writeText(path: string, content: string, managed?: boolean): void;
18
+ readFile(path: string): Uint8Array;
19
+ exists(path: string): boolean;
20
+ cleanup(): void;
21
+ }
22
+ //# sourceMappingURL=virtual-filesystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtual-filesystem.d.ts","sourceRoot":"","sources":["../../src/core/virtual-filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,sBAAsB,CAAC;AAI3E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,iBAAiB;IAU1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAe;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0B;IAEvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGjB,MAAM,EAAE,gBAAgB,EACzC,UAAU,SAAc;IAQ1B,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,oBAAoB;IAWtB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,IAAI;IAe9D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAWlC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAS7B,OAAO,IAAI,IAAI;CAehB"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @imgly/plugin-pdfx-web - Print-Ready PDF conversion for CE.SDK
3
+ *
4
+ * IMPORTANT: This package includes Ghostscript WASM binaries licensed under AGPL-3.0.
5
+ * Commercial users must ensure license compliance. See README.md for details.
6
+ */
7
+ export { convertToPDFX3 } from './pdfx';
8
+ export { Logger } from './utils/logger';
9
+ export type { PDFX3Options } from './types/pdfx';
10
+ export type { LogLevel } from './utils/logger';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAGxC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGxC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- var f=class o{constructor(t){this.component=t}static globalLogLevel="warn";static logs=[];static maxLogs=1e3;static setLogLevel(t){o.globalLogLevel=t}static getLogs(){return[...o.logs]}static clearLogs(){o.logs=[]}debug(t,e){this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}log(t,e,i){let r={debug:0,info:1,warn:2,error:3};if(r[t]<r[o.globalLogLevel])return;let s={timestamp:Date.now(),level:t,component:this.component,message:e,data:i};o.logs.push(s),o.logs.length>o.maxLogs&&(o.logs=o.logs.slice(-o.maxLogs));let n=`[${new Date().toISOString()}] [${t.toUpperCase()}] [${this.component}]`,l=i?`${e} ${JSON.stringify(i)}`:e;switch(t){case"debug":console.debug(n,l);break;case"info":console.info(n,l);break;case"warn":console.warn(n,l);break;case"error":console.error(n,l);break;default:break}}};var F=class{supportsWebAssembly(){try{return typeof WebAssembly=="object"&&typeof WebAssembly.instantiate=="function"}catch{return!1}}};async function L(o={}){let{silent:t=!0}=o,e=typeof process<"u"&&process.versions!=null&&process.versions.node!=null,i,r;if(e){let c=typeof process<"u"&&(process.env.VITEST==="true"||!1),w=new Function("s","return import(s)"),u=c?p=>import(p):w,g=await u("module"),d=await u("path"),y=g.createRequire,v=d.dirname,D=d.join,P=y(import.meta.url).resolve("./gs.js"),C=v(P);r=D(C,"gs.wasm"),i=await u(P)}else i=await import(new URL("./gs.js",import.meta.url).href),r=new URL("./gs.wasm",import.meta.url).href;let s=i.default||i,n={locateFile:c=>c==="gs.wasm"?r:c};return t&&(n.print=()=>{},n.printErr=()=>{}),await s(n)}var b=class{static instance=null;static TIMEOUT_MS=3e4;static async load(t={}){return this.instance?this.instance:(this.instance=this.loadInternal(t),this.instance)}static async loadInternal(t){let e=new f("GhostscriptLoader");if(!new F().supportsWebAssembly())throw new Error("WebAssembly not supported in this browser");let r=t.timeout||this.TIMEOUT_MS;try{return e.info("Loading bundled Ghostscript (AGPL-3.0 licensed)"),e.info("Source available at: https://github.com/imgly/plugins"),await this.loadWithTimeout(()=>this.loadFromBundle(),r)}catch(s){throw e.error("Ghostscript loading failed",{error:s.message}),new Error(`Failed to load Ghostscript: ${s.message}`)}}static async loadFromBundle(){let t=new f("GhostscriptInit");try{t.info("Initializing Ghostscript module");let e=await L();return t.info("Ghostscript module initialized successfully",{version:e.version||"unknown",hasFS:!!e.FS,hasCallMain:!!e.callMain}),e}catch(e){throw t.error("Ghostscript initialization failed",{error:e}),new Error(`Ghostscript initialization failed: ${e.message}`)}}static async loadWithTimeout(t,e){return Promise.race([t(),new Promise((i,r)=>{setTimeout(()=>r(new Error(`Loading timeout after ${e}ms`)),e)})])}static reset(){this.instance=null}};var m=class{static async toUint8Array(t){if(t.arrayBuffer){let e=await t.arrayBuffer();return new Uint8Array(e)}return new Promise((e,i)=>{let r=new FileReader;r.onload=()=>{r.result instanceof ArrayBuffer?e(new Uint8Array(r.result)):i(new Error("Failed to read blob as ArrayBuffer"))},r.onerror=()=>i(r.error),r.readAsArrayBuffer(t)})}static async validatePDF(t){try{let e=await this.toUint8Array(t),i=new Uint8Array([37,80,68,70]);if(e.length<4)return!1;for(let r=0;r<4;r++)if(e[r]!==i[r])return!1;return!0}catch{return!1}}};var E=class{constructor(t,e="/tmp/pdfx"){this.module=t;this.fs=t.FS,this.logger=new f("VirtualFileSystem"),this.workingDir=e,this.initialize()}fs;logger;managedFiles=new Set;workingDir;initialize(){try{this.createDirIfNotExists(this.workingDir),this.createDirIfNotExists(`${this.workingDir}/input`),this.createDirIfNotExists(`${this.workingDir}/output`),this.createDirIfNotExists(`${this.workingDir}/profiles`),this.createDirIfNotExists(`${this.workingDir}/temp`),this.logger.info("Virtual filesystem initialized",{workingDir:this.workingDir})}catch(t){throw this.logger.error("Failed to initialize virtual filesystem",{error:t}),new Error(`VFS initialization failed: ${t}`)}}createDirIfNotExists(t){try{this.fs.mkdir(t)}catch(e){if(e.code!=="EEXIST")throw e}}async writeBlob(t,e,i=!0){try{let r=await m.toUint8Array(e);this.fs.writeFile(t,r),i&&this.managedFiles.add(t),this.logger.debug("File written",{path:t,size:r.length})}catch(r){throw this.logger.error("Failed to write blob",{path:t,error:r}),new Error(`Failed to write file ${t}: ${r}`)}}writeText(t,e,i=!0){try{this.fs.writeFile(t,e),i&&this.managedFiles.add(t),this.logger.debug("Text file written",{path:t,length:e.length})}catch(r){throw this.logger.error("Failed to write text",{path:t,error:r}),new Error(`Failed to write text file ${t}: ${r}`)}}readFile(t){try{let e=this.fs.readFile(t);return this.logger.debug("File read",{path:t,size:e.length}),e}catch(e){throw this.logger.error("Failed to read file",{path:t,error:e}),new Error(`Failed to read file ${t}: ${e}`)}}exists(t){try{return this.fs.stat(t),!0}catch{return!1}}cleanup(){let t=0;for(let e of this.managedFiles)try{this.fs.unlink(e),t++}catch(i){this.logger.warn("Failed to cleanup file",{path:e,error:i})}this.managedFiles.clear(),this.logger.info("Filesystem cleanup completed",{cleanedCount:t})}};async function q(o,t){if(Array.isArray(o)){if(o.length===0)return[];let e=[];for(let i=0;i<o.length;i++)try{let r=await B(o[i],t);e.push(r)}catch(r){throw new Error(`Failed to convert PDF ${i+1} of ${o.length}: ${r instanceof Error?r.message:String(r)}`)}return e}return B(o,t)}async function B(o,t){if(!(o instanceof Blob))throw new Error("Input must be a Blob");if(o.size===0)throw new Error("Input PDF is empty");if(o.size>100*1024*1024)throw new Error(`Input PDF too large (${o.size} bytes). Maximum: 100MB`);if(!t.outputProfile)throw new Error('outputProfile is required. Must be one of: "gracol", "fogra39", "srgb", "custom"');let e=["gracol","fogra39","srgb","custom"];if(!e.includes(t.outputProfile))throw new Error(`Invalid outputProfile "${t.outputProfile}". Must be one of: ${e.join(", ")}`);if(t.outputProfile==="custom"&&!t.customProfile)throw new Error('customProfile Blob is required when outputProfile is "custom"');if(t.customProfile&&!(t.customProfile instanceof Blob))throw new Error("customProfile must be a Blob");if(!await m.validatePDF(o))throw new Error("Invalid PDF format");let r=await b.load(),s=new E(r);try{let n="/tmp/input.pdf",l="/tmp/output.pdf",c="/tmp/pdfx_def.ps",w="/tmp/custom.icc";if(await s.writeBlob(n,o),t.outputProfile==="custom"&&t.customProfile)await s.writeBlob(w,t.customProfile);else if(t.outputProfile!=="custom"){let a=O[t.outputProfile],k=`/tmp/${a.file}`,X=typeof process<"u"&&process.versions?.node!=null,I;if(X){let S=process.env.VITEST==="true"||!1,h=new Function("s","return import(s)"),x=S?W=>import(W):h,{readFileSync:R}=await x("fs"),{fileURLToPath:U}=await x("url"),{dirname:N,join:z}=await x("path"),_=N(U(import.meta.url)),V=z(_,a.file),j=R(V);I=new Blob([j],{type:"application/vnd.iccprofile"})}else{let S=new URL(a.file,import.meta.url).href,h=await fetch(S);if(!h.ok)throw new Error(`Failed to load ICC profile ${a.file}: ${h.statusText}`);I=await h.blob()}await s.writeBlob(k,I)}let u,g,d;if(t.outputProfile==="custom")u=w,g=t.outputConditionIdentifier||"Custom Profile",d=t.outputCondition||"Custom ICC Profile";else{let a=O[t.outputProfile];u=`/tmp/${a.file}`,g=t.outputConditionIdentifier||a.identifier,d=t.outputCondition||a.info}let y=s.readFile(u),v=Array.from(y).map(a=>a.toString(16).padStart(2,"0")).join(""),D=y.slice(16,20),P=String.fromCharCode(...D).trim()==="CMYK",C=K(t,v,g,d);s.writeText(c,C);let p=["-dBATCH","-dNOPAUSE","-sDEVICE=pdfwrite","-dCompatibilityLevel=1.4","-dWriteObjStms=false","-dWriteXRefStm=false","-dPDFSETTINGS=/prepress","-dSetPageSize=false","-dAutoRotatePages=/None"];t.flattenTransparency!==!1&&p.push("-dHaveTransparency=false"),P?p.push("-sColorConversionStrategy=CMYK","-dProcessColorModel=/DeviceCMYK","-dConvertCMYKImagesToRGB=false"):p.push("-sColorConversionStrategy=RGB"),p.push(`-sOutputFile=${l}`,c,n);let T=await r.callMain(p);if(T!==0)throw new Error(`Ghostscript conversion failed with exit code ${T}`);let $=s.readFile(l),A=new Uint8Array($),G=new Blob([A],{type:"application/pdf"});return s.cleanup(),G}catch(n){throw s.cleanup(),n}}var O={gracol:{file:"GRACoL2013_CRPC6.icc",identifier:"CGATS 21.2",info:"GRACoL 2013 CRPC6"},fogra39:{file:"ISOcoated_v2_eci.icc",identifier:"FOGRA39",info:"ISO Coated v2 (ECI)"},srgb:{file:"sRGB_IEC61966-2-1.icc",identifier:"sRGB IEC61966-2.1",info:"sRGB IEC61966-2.1"}};function K(o,t,e,i){return`%!
1
+ var f=class o{constructor(t){this.component=t}static globalLogLevel="warn";static logs=[];static maxLogs=1e3;static setLogLevel(t){o.globalLogLevel=t}static getLogs(){return[...o.logs]}static clearLogs(){o.logs=[]}debug(t,e){this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}log(t,e,i){let r={debug:0,info:1,warn:2,error:3};if(r[t]<r[o.globalLogLevel])return;let s={timestamp:Date.now(),level:t,component:this.component,message:e,data:i};o.logs.push(s),o.logs.length>o.maxLogs&&(o.logs=o.logs.slice(-o.maxLogs));let n=`[${new Date().toISOString()}] [${t.toUpperCase()}] [${this.component}]`,l=i?`${e} ${JSON.stringify(i)}`:e;switch(t){case"debug":console.debug(n,l);break;case"info":console.info(n,l);break;case"warn":console.warn(n,l);break;case"error":console.error(n,l);break;default:break}}};var F=class{supportsWebAssembly(){try{return typeof WebAssembly=="object"&&typeof WebAssembly.instantiate=="function"}catch{return!1}}};async function L(o={}){let{silent:t=!0}=o,e=typeof process<"u"&&process.versions!=null&&process.versions.node!=null,i,r;if(e){let c=typeof process<"u"&&(process.env.VITEST==="true"||!1),w=new Function("s","return import(s)"),u=c?p=>import(p):w,g=await u("module"),d=await u("path"),y=g.createRequire,v=d.dirname,D=d.join,P=y(import.meta.url).resolve("./gs.js"),C=v(P);r=D(C,"gs.wasm"),i=await u(P)}else i=await import(new URL("./gs.js",import.meta.url).href),r=new URL("./gs.wasm",import.meta.url).href;let s=i.default||i,n={locateFile:c=>c==="gs.wasm"?r:c};return t&&(n.print=()=>{},n.printErr=()=>{}),await s(n)}var b=class{static instance=null;static TIMEOUT_MS=3e4;static async load(t={}){return this.instance?this.instance:(this.instance=this.loadInternal(t),this.instance)}static async loadInternal(t){let e=new f("GhostscriptLoader");if(!new F().supportsWebAssembly())throw new Error("WebAssembly not supported in this browser");let r=t.timeout||this.TIMEOUT_MS;try{return e.info("Loading bundled Ghostscript (AGPL-3.0 licensed)"),e.info("Source available at: https://img.ly/docs/cesdk"),await this.loadWithTimeout(()=>this.loadFromBundle(),r)}catch(s){throw e.error("Ghostscript loading failed",{error:s.message}),new Error(`Failed to load Ghostscript: ${s.message}`)}}static async loadFromBundle(){let t=new f("GhostscriptInit");try{t.info("Initializing Ghostscript module");let e=await L();return t.info("Ghostscript module initialized successfully",{version:e.version||"unknown",hasFS:!!e.FS,hasCallMain:!!e.callMain}),e}catch(e){throw t.error("Ghostscript initialization failed",{error:e}),new Error(`Ghostscript initialization failed: ${e.message}`)}}static async loadWithTimeout(t,e){return Promise.race([t(),new Promise((i,r)=>{setTimeout(()=>r(new Error(`Loading timeout after ${e}ms`)),e)})])}static reset(){this.instance=null}};var m=class{static async toUint8Array(t){if(t.arrayBuffer){let e=await t.arrayBuffer();return new Uint8Array(e)}return new Promise((e,i)=>{let r=new FileReader;r.onload=()=>{r.result instanceof ArrayBuffer?e(new Uint8Array(r.result)):i(new Error("Failed to read blob as ArrayBuffer"))},r.onerror=()=>i(r.error),r.readAsArrayBuffer(t)})}static async validatePDF(t){try{let e=await this.toUint8Array(t),i=new Uint8Array([37,80,68,70]);if(e.length<4)return!1;for(let r=0;r<4;r++)if(e[r]!==i[r])return!1;return!0}catch{return!1}}};var E=class{constructor(t,e="/tmp/pdfx"){this.module=t;this.fs=t.FS,this.logger=new f("VirtualFileSystem"),this.workingDir=e,this.initialize()}fs;logger;managedFiles=new Set;workingDir;initialize(){try{this.createDirIfNotExists(this.workingDir),this.createDirIfNotExists(`${this.workingDir}/input`),this.createDirIfNotExists(`${this.workingDir}/output`),this.createDirIfNotExists(`${this.workingDir}/profiles`),this.createDirIfNotExists(`${this.workingDir}/temp`),this.logger.info("Virtual filesystem initialized",{workingDir:this.workingDir})}catch(t){throw this.logger.error("Failed to initialize virtual filesystem",{error:t}),new Error(`VFS initialization failed: ${t}`)}}createDirIfNotExists(t){try{this.fs.mkdir(t)}catch(e){if(e.code!=="EEXIST")throw e}}async writeBlob(t,e,i=!0){try{let r=await m.toUint8Array(e);this.fs.writeFile(t,r),i&&this.managedFiles.add(t),this.logger.debug("File written",{path:t,size:r.length})}catch(r){throw this.logger.error("Failed to write blob",{path:t,error:r}),new Error(`Failed to write file ${t}: ${r}`)}}writeText(t,e,i=!0){try{this.fs.writeFile(t,e),i&&this.managedFiles.add(t),this.logger.debug("Text file written",{path:t,length:e.length})}catch(r){throw this.logger.error("Failed to write text",{path:t,error:r}),new Error(`Failed to write text file ${t}: ${r}`)}}readFile(t){try{let e=this.fs.readFile(t);return this.logger.debug("File read",{path:t,size:e.length}),e}catch(e){throw this.logger.error("Failed to read file",{path:t,error:e}),new Error(`Failed to read file ${t}: ${e}`)}}exists(t){try{return this.fs.stat(t),!0}catch{return!1}}cleanup(){let t=0;for(let e of this.managedFiles)try{this.fs.unlink(e),t++}catch(i){this.logger.warn("Failed to cleanup file",{path:e,error:i})}this.managedFiles.clear(),this.logger.info("Filesystem cleanup completed",{cleanedCount:t})}};async function q(o,t){if(Array.isArray(o)){if(o.length===0)return[];let e=[];for(let i=0;i<o.length;i++)try{let r=await B(o[i],t);e.push(r)}catch(r){throw new Error(`Failed to convert PDF ${i+1} of ${o.length}: ${r instanceof Error?r.message:String(r)}`)}return e}return B(o,t)}async function B(o,t){if(!(o instanceof Blob))throw new Error("Input must be a Blob");if(o.size===0)throw new Error("Input PDF is empty");if(o.size>100*1024*1024)throw new Error(`Input PDF too large (${o.size} bytes). Maximum: 100MB`);if(!t.outputProfile)throw new Error('outputProfile is required. Must be one of: "gracol", "fogra39", "srgb", "custom"');let e=["gracol","fogra39","srgb","custom"];if(!e.includes(t.outputProfile))throw new Error(`Invalid outputProfile "${t.outputProfile}". Must be one of: ${e.join(", ")}`);if(t.outputProfile==="custom"&&!t.customProfile)throw new Error('customProfile Blob is required when outputProfile is "custom"');if(t.customProfile&&!(t.customProfile instanceof Blob))throw new Error("customProfile must be a Blob");if(!await m.validatePDF(o))throw new Error("Invalid PDF format");let r=await b.load(),s=new E(r);try{let n="/tmp/input.pdf",l="/tmp/output.pdf",c="/tmp/pdfx_def.ps",w="/tmp/custom.icc";if(await s.writeBlob(n,o),t.outputProfile==="custom"&&t.customProfile)await s.writeBlob(w,t.customProfile);else if(t.outputProfile!=="custom"){let a=O[t.outputProfile],G=`/tmp/${a.file}`,X=typeof process<"u"&&process.versions?.node!=null,I;if(X){let S=process.env.VITEST==="true"||!1,h=new Function("s","return import(s)"),x=S?W=>import(W):h,{readFileSync:R}=await x("fs"),{fileURLToPath:U}=await x("url"),{dirname:N,join:z}=await x("path"),_=N(U(import.meta.url)),V=z(_,a.file),j=R(V);I=new Blob([j],{type:"application/vnd.iccprofile"})}else{let S=new URL(a.file,import.meta.url).href,h=await fetch(S);if(!h.ok)throw new Error(`Failed to load ICC profile ${a.file}: ${h.statusText}`);I=await h.blob()}await s.writeBlob(G,I)}let u,g,d;if(t.outputProfile==="custom")u=w,g=t.outputConditionIdentifier||"Custom Profile",d=t.outputCondition||"Custom ICC Profile";else{let a=O[t.outputProfile];u=`/tmp/${a.file}`,g=t.outputConditionIdentifier||a.identifier,d=t.outputCondition||a.info}let y=s.readFile(u),v=Array.from(y).map(a=>a.toString(16).padStart(2,"0")).join(""),D=y.slice(16,20),P=String.fromCharCode(...D).trim()==="CMYK",C=K(t,v,g,d);s.writeText(c,C);let p=["-dBATCH","-dNOPAUSE","-sDEVICE=pdfwrite","-dCompatibilityLevel=1.4","-dWriteObjStms=false","-dWriteXRefStm=false","-dPDFSETTINGS=/prepress","-dSetPageSize=false","-dAutoRotatePages=/None"];t.flattenTransparency!==!1&&p.push("-dHaveTransparency=false"),P?p.push("-sColorConversionStrategy=CMYK","-dProcessColorModel=/DeviceCMYK","-dConvertCMYKImagesToRGB=false"):p.push("-sColorConversionStrategy=RGB"),p.push(`-sOutputFile=${l}`,c,n);let T=await r.callMain(p);if(T!==0)throw new Error(`Ghostscript conversion failed with exit code ${T}`);let $=s.readFile(l),A=new Uint8Array($),k=new Blob([A],{type:"application/pdf"});return s.cleanup(),k}catch(n){throw s.cleanup(),n}}var O={gracol:{file:"GRACoL2013_CRPC6.icc",identifier:"CGATS 21.2",info:"GRACoL 2013 CRPC6"},fogra39:{file:"ISOcoated_v2_eci.icc",identifier:"FOGRA39",info:"ISO Coated v2 (ECI)"},srgb:{file:"sRGB_IEC61966-2-1.icc",identifier:"sRGB IEC61966-2.1",info:"sRGB IEC61966-2.1"}};function K(o,t,e,i){return`%!
2
2
  % PDF/X-3 Definition File
3
3
  [ /Title (${o.title||"Untitled"}) /DOCINFO pdfmark
4
4
  [ /Trapped /False /DOCINFO pdfmark
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/utils/logger.ts", "../src/utils/browser-detection.ts", "../src/wasm/ghostscript-module.ts", "../src/core/ghostscript-loader.ts", "../src/utils/blob-utils.ts", "../src/core/virtual-filesystem.ts", "../src/pdfx.ts"],
4
- "sourcesContent": ["/* eslint-disable no-console */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LogEntry {\n timestamp: number;\n level: LogLevel;\n component: string;\n message: string;\n data?: any;\n}\n\nexport class Logger {\n private static globalLogLevel: LogLevel = 'warn';\n\n private static logs: LogEntry[] = [];\n\n private static maxLogs = 1000;\n\n constructor(private component: string) {}\n\n static setLogLevel(level: LogLevel): void {\n Logger.globalLogLevel = level;\n }\n\n static getLogs(): LogEntry[] {\n return [...Logger.logs];\n }\n\n static clearLogs(): void {\n Logger.logs = [];\n }\n\n debug(message: string, data?: any): void {\n this.log('debug', message, data);\n }\n\n info(message: string, data?: any): void {\n this.log('info', message, data);\n }\n\n warn(message: string, data?: any): void {\n this.log('warn', message, data);\n }\n\n error(message: string, data?: any): void {\n this.log('error', message, data);\n }\n\n private log(level: LogLevel, message: string, data?: any): void {\n const levelOrder: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n if (levelOrder[level] < levelOrder[Logger.globalLogLevel]) {\n return;\n }\n\n const entry: LogEntry = {\n timestamp: Date.now(),\n level,\n component: this.component,\n message,\n data,\n };\n\n Logger.logs.push(entry);\n\n // Keep logs under the limit\n if (Logger.logs.length > Logger.maxLogs) {\n Logger.logs = Logger.logs.slice(-Logger.maxLogs);\n }\n\n // Console output\n const prefix = `[${new Date().toISOString()}] [${level.toUpperCase()}] [${\n this.component\n }]`;\n const logMessage = data ? `${message} ${JSON.stringify(data)}` : message;\n\n switch (level) {\n case 'debug':\n console.debug(prefix, logMessage);\n break;\n case 'info':\n console.info(prefix, logMessage);\n break;\n case 'warn':\n console.warn(prefix, logMessage);\n break;\n case 'error':\n console.error(prefix, logMessage);\n break;\n default:\n // All log levels handled above\n break;\n }\n }\n}\n", "export class BrowserDetection {\n supportsWebAssembly(): boolean {\n try {\n return (\n typeof WebAssembly === 'object' &&\n typeof WebAssembly.instantiate === 'function'\n );\n } catch {\n return false;\n }\n }\n}\n", "// Wrapper for the Ghostscript WASM module to ensure proper loading\nimport type {\n EmscriptenModule,\n GhostscriptModuleFactory,\n} from '../types/ghostscript';\n\nexport interface GhostscriptModuleOptions {\n /**\n * Whether to suppress Ghostscript's stdout/stderr output.\n * Default: true (silent mode)\n */\n silent?: boolean;\n}\n\nexport default async function createGhostscriptModule(\n options: GhostscriptModuleOptions = {}\n): Promise<EmscriptenModule> {\n const { silent = true } = options;\n // Check if we're in Node.js\n const isNode =\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null;\n\n let GhostscriptModule: any;\n let wasmPath: string;\n\n if (isNode) {\n // Node.js: Use require.resolve to find gs.js relative to this module\n // Use indirect dynamic import to prevent Webpack 5 from statically analyzing these imports\n // But use direct imports in test environments (vitest) where indirect imports bypass mocking\n // See: https://github.com/imgly/ubq/issues/11471\n const isTestEnv =\n typeof process !== 'undefined' &&\n (process.env.VITEST === 'true' || process.env.NODE_ENV === 'test');\n\n // Helper for dynamic imports - uses indirect import in production to avoid Webpack static analysis\n // Note: new Function() could fail in CSP-restricted environments, but CSP is a browser\n // security mechanism and doesn't apply to Node.js. This code only runs in Node.js (isNode check above).\n // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func\n const indirectImport = new Function('s', 'return import(s)') as (\n s: string\n ) => Promise<any>;\n const dynamicImport = isTestEnv ? (s: string) => import(s) : indirectImport;\n\n const moduleLib = await dynamicImport('module');\n const pathLib = await dynamicImport('path');\n const createRequire = moduleLib.createRequire;\n const dirname = pathLib.dirname;\n const join = pathLib.join;\n\n const requireForESM = createRequire(import.meta.url);\n\n // Resolve gs.js directly (it's copied to dist/ alongside the bundle)\n const gsPath = requireForESM.resolve('./gs.js');\n const moduleDir = dirname(gsPath);\n wasmPath = join(moduleDir, 'gs.wasm');\n\n GhostscriptModule = await dynamicImport(gsPath);\n } else {\n // Browser: Use URL-based imports\n const moduleUrl = new URL('./gs.js', import.meta.url).href;\n GhostscriptModule = await import(/* webpackIgnore: true */ moduleUrl);\n wasmPath = new URL('./gs.wasm', import.meta.url).href;\n }\n\n const factory = (GhostscriptModule.default ||\n GhostscriptModule) as GhostscriptModuleFactory;\n\n // Configure the module to load WASM from the bundled location\n const moduleConfig: Record<string, unknown> = {\n locateFile: (filename: string) => {\n if (filename === 'gs.wasm') {\n return wasmPath;\n }\n return filename;\n },\n };\n\n // Suppress Ghostscript stdout/stderr output in silent mode\n if (silent) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n moduleConfig.print = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n moduleConfig.printErr = () => {};\n }\n\n const module = await factory(moduleConfig);\n\n return module;\n}\n", "import type { EmscriptenModule } from '../types/ghostscript';\nimport { Logger } from '../utils/logger';\nimport { BrowserDetection } from '../utils/browser-detection';\nimport createGhostscriptModule from '../wasm/ghostscript-module';\n\nexport interface LoaderOptions {\n timeout?: number;\n}\n\nexport class GhostscriptLoader {\n private static instance: Promise<EmscriptenModule> | null = null;\n\n private static readonly TIMEOUT_MS = 30000;\n\n static async load(options: LoaderOptions = {}): Promise<EmscriptenModule> {\n if (this.instance) {\n return this.instance;\n }\n\n this.instance = this.loadInternal(options);\n return this.instance;\n }\n\n private static async loadInternal(\n options: LoaderOptions\n ): Promise<EmscriptenModule> {\n const logger = new Logger('GhostscriptLoader');\n const browser = new BrowserDetection();\n\n // Check browser compatibility\n if (!browser.supportsWebAssembly()) {\n throw new Error('WebAssembly not supported in this browser');\n }\n\n const timeout = options.timeout || this.TIMEOUT_MS;\n\n try {\n logger.info('Loading bundled Ghostscript (AGPL-3.0 licensed)');\n logger.info('Source available at: https://github.com/imgly/plugins');\n return await this.loadWithTimeout(() => this.loadFromBundle(), timeout);\n } catch (error) {\n logger.error('Ghostscript loading failed', {\n error: (error as Error).message,\n });\n throw new Error(\n `Failed to load Ghostscript: ${(error as Error).message}`\n );\n }\n }\n\n private static async loadFromBundle(): Promise<EmscriptenModule> {\n // Use the bundled WASM module with proper configuration\n const logger = new Logger('GhostscriptInit');\n\n try {\n logger.info('Initializing Ghostscript module');\n\n const module = await createGhostscriptModule();\n\n logger.info('Ghostscript module initialized successfully', {\n version: module.version || 'unknown',\n hasFS: !!module.FS,\n hasCallMain: !!module.callMain,\n });\n\n return module;\n } catch (error) {\n logger.error('Ghostscript initialization failed', { error });\n throw new Error(\n `Ghostscript initialization failed: ${(error as Error).message}`\n );\n }\n }\n\n private static async loadWithTimeout<T>(\n operation: () => Promise<T>,\n timeoutMs: number\n ): Promise<T> {\n return Promise.race([\n operation(),\n new Promise<never>((_, reject) => {\n setTimeout(\n () => reject(new Error(`Loading timeout after ${timeoutMs}ms`)),\n timeoutMs\n );\n }),\n ]);\n }\n\n static reset(): void {\n this.instance = null;\n }\n}\n", "export class BlobUtils {\n static async toUint8Array(blob: Blob): Promise<Uint8Array> {\n if (blob.arrayBuffer) {\n const buffer = await blob.arrayBuffer();\n return new Uint8Array(buffer);\n }\n\n // Fallback for older browsers\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n if (reader.result instanceof ArrayBuffer) {\n resolve(new Uint8Array(reader.result));\n } else {\n reject(new Error('Failed to read blob as ArrayBuffer'));\n }\n };\n reader.onerror = () => reject(reader.error);\n reader.readAsArrayBuffer(blob);\n });\n }\n\n static async validatePDF(blob: Blob): Promise<boolean> {\n try {\n const data = await this.toUint8Array(blob);\n\n // Check PDF magic number\n const pdfHeader = new Uint8Array([0x25, 0x50, 0x44, 0x46]); // %PDF\n\n if (data.length < 4) {\n return false;\n }\n\n for (let i = 0; i < 4; i++) {\n if (data[i] !== pdfHeader[i]) {\n return false;\n }\n }\n\n return true;\n } catch {\n return false;\n }\n }\n}\n", "import type { EmscriptenModule, EmscriptenFS } from '../types/ghostscript';\nimport { Logger } from '../utils/logger';\nimport { BlobUtils } from '../utils/blob-utils';\n\nexport interface FileEntry {\n path: string;\n data: Uint8Array;\n cleanup: boolean;\n}\n\nexport class VirtualFileSystem {\n private readonly fs: EmscriptenFS;\n\n private readonly logger: Logger;\n\n private readonly managedFiles: Set<string> = new Set();\n\n private readonly workingDir: string;\n\n constructor(\n private readonly module: EmscriptenModule,\n workingDir = '/tmp/pdfx'\n ) {\n this.fs = module.FS;\n this.logger = new Logger('VirtualFileSystem');\n this.workingDir = workingDir;\n this.initialize();\n }\n\n private initialize(): void {\n try {\n // Create working directory structure (handle existing directories gracefully)\n this.createDirIfNotExists(this.workingDir);\n this.createDirIfNotExists(`${this.workingDir}/input`);\n this.createDirIfNotExists(`${this.workingDir}/output`);\n this.createDirIfNotExists(`${this.workingDir}/profiles`);\n this.createDirIfNotExists(`${this.workingDir}/temp`);\n\n this.logger.info('Virtual filesystem initialized', {\n workingDir: this.workingDir,\n });\n } catch (error) {\n this.logger.error('Failed to initialize virtual filesystem', { error });\n throw new Error(`VFS initialization failed: ${error}`);\n }\n }\n\n private createDirIfNotExists(path: string): void {\n try {\n this.fs.mkdir(path);\n } catch (error: any) {\n // Ignore \"File exists\" errors, re-throw others\n if (error.code !== 'EEXIST') {\n throw error;\n }\n }\n }\n\n async writeBlob(path: string, blob: Blob, managed = true): Promise<void> {\n try {\n const data = await BlobUtils.toUint8Array(blob);\n this.fs.writeFile(path, data);\n\n if (managed) {\n this.managedFiles.add(path);\n }\n\n this.logger.debug('File written', { path, size: data.length });\n } catch (error) {\n this.logger.error('Failed to write blob', { path, error });\n throw new Error(`Failed to write file ${path}: ${error}`);\n }\n }\n\n writeText(path: string, content: string, managed = true): void {\n try {\n this.fs.writeFile(path, content);\n\n if (managed) {\n this.managedFiles.add(path);\n }\n\n this.logger.debug('Text file written', { path, length: content.length });\n } catch (error) {\n this.logger.error('Failed to write text', { path, error });\n throw new Error(`Failed to write text file ${path}: ${error}`);\n }\n }\n\n readFile(path: string): Uint8Array {\n try {\n const data = this.fs.readFile(path) as Uint8Array;\n this.logger.debug('File read', { path, size: data.length });\n return data;\n } catch (error) {\n this.logger.error('Failed to read file', { path, error });\n throw new Error(`Failed to read file ${path}: ${error}`);\n }\n }\n\n exists(path: string): boolean {\n try {\n this.fs.stat(path);\n return true;\n } catch {\n return false;\n }\n }\n\n cleanup(): void {\n let cleanedCount = 0;\n\n for (const path of this.managedFiles) {\n try {\n this.fs.unlink(path);\n cleanedCount++;\n } catch (error) {\n this.logger.warn('Failed to cleanup file', { path, error });\n }\n }\n\n this.managedFiles.clear();\n this.logger.info('Filesystem cleanup completed', { cleanedCount });\n }\n}\n", "import type { PDFX3Options } from './types/pdfx';\nimport { GhostscriptLoader } from './core/ghostscript-loader';\nimport { VirtualFileSystem } from './core/virtual-filesystem';\nimport { BlobUtils } from './utils/blob-utils';\n\n/**\n * PDF/X-3 conversion function\n * Converts RGB PDF(s) to PDF/X-3 format using specified output profile\n *\n * @overload\n * @param inputPDF Single PDF blob to convert\n * @param options Conversion configuration\n * @returns Promise resolving to converted PDF blob\n *\n * @overload\n * @param inputPDFs Array of PDF blobs to convert\n * @param options Conversion configuration\n * @returns Promise resolving to array of converted PDF blobs\n */\nexport function convertToPDFX3(\n inputPDF: Blob,\n options: PDFX3Options\n): Promise<Blob>;\nexport function convertToPDFX3(\n inputPDFs: Blob[],\n options: PDFX3Options\n): Promise<Blob[]>;\nexport async function convertToPDFX3(\n input: Blob | Blob[],\n options: PDFX3Options\n): Promise<Blob | Blob[]> {\n // Handle array input (batch processing)\n if (Array.isArray(input)) {\n if (input.length === 0) {\n return [];\n }\n\n // Process each blob sequentially to avoid overwhelming the WASM module\n const results: Blob[] = [];\n for (let i = 0; i < input.length; i++) {\n try {\n // eslint-disable-next-line no-await-in-loop\n const converted = await convertToPDFX3Single(input[i], options);\n results.push(converted);\n } catch (error) {\n throw new Error(\n `Failed to convert PDF ${i + 1} of ${input.length}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n }\n return results;\n }\n\n // Handle single blob input\n return convertToPDFX3Single(input, options);\n}\n\n/**\n * Internal function to convert a single PDF\n */\nasync function convertToPDFX3Single(\n inputPDF: Blob,\n options: PDFX3Options\n): Promise<Blob> {\n // Validate inputs\n if (!(inputPDF instanceof Blob)) {\n throw new Error('Input must be a Blob');\n }\n\n if (inputPDF.size === 0) {\n throw new Error('Input PDF is empty');\n }\n\n if (inputPDF.size > 100 * 1024 * 1024) {\n throw new Error(\n `Input PDF too large (${inputPDF.size} bytes). Maximum: 100MB`\n );\n }\n\n // Validate output profile is provided\n if (!options.outputProfile) {\n throw new Error(\n 'outputProfile is required. Must be one of: \"gracol\", \"fogra39\", \"srgb\", \"custom\"'\n );\n }\n\n // Validate output profile value\n const validProfiles = ['gracol', 'fogra39', 'srgb', 'custom'];\n if (!validProfiles.includes(options.outputProfile)) {\n throw new Error(\n `Invalid outputProfile \"${\n options.outputProfile\n }\". Must be one of: ${validProfiles.join(', ')}`\n );\n }\n\n // Validate custom profile requirement\n if (options.outputProfile === 'custom' && !options.customProfile) {\n throw new Error(\n 'customProfile Blob is required when outputProfile is \"custom\"'\n );\n }\n\n // Validate custom profile if provided\n if (options.customProfile && !(options.customProfile instanceof Blob)) {\n throw new Error('customProfile must be a Blob');\n }\n\n // Validate PDF format\n const isValidPDF = await BlobUtils.validatePDF(inputPDF);\n if (!isValidPDF) {\n throw new Error('Invalid PDF format');\n }\n\n // Load Ghostscript\n const module = await GhostscriptLoader.load();\n const vfs = new VirtualFileSystem(module);\n\n try {\n // Setup file paths\n const inputPath = '/tmp/input.pdf';\n const outputPath = '/tmp/output.pdf';\n const pdfxDefPath = '/tmp/pdfx_def.ps';\n const customProfilePath = '/tmp/custom.icc';\n\n // Write input PDF to virtual filesystem\n await vfs.writeBlob(inputPath, inputPDF);\n\n // Write ICC profiles to virtual filesystem\n if (options.outputProfile === 'custom' && options.customProfile) {\n await vfs.writeBlob(customProfilePath, options.customProfile);\n } else if (options.outputProfile !== 'custom') {\n // Load the bundled ICC profile\n const profileInfo =\n PROFILE_PRESETS[options.outputProfile as keyof typeof PROFILE_PRESETS];\n const profilePath = `/tmp/${profileInfo.file}`;\n\n // Load ICC profile - different approach for Node.js vs browser\n const isNode =\n typeof process !== 'undefined' && process.versions?.node != null;\n\n let profileBlob: Blob;\n\n if (isNode) {\n // Node.js: Load from filesystem using readFileSync\n // Use indirect dynamic import to prevent Webpack 5 from statically analyzing these imports\n // But use direct imports in test environments (vitest) where indirect imports bypass mocking\n // See: https://github.com/imgly/ubq/issues/11471\n const isTestEnv =\n process.env.VITEST === 'true' || process.env.NODE_ENV === 'test';\n\n // Note: new Function() could fail in CSP-restricted environments, but CSP is a browser\n // security mechanism and doesn't apply to Node.js. This code only runs in Node.js (isNode check above).\n // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func\n const indirectImport = new Function('s', 'return import(s)') as (\n s: string\n ) => Promise<any>;\n const dynamicImport = isTestEnv\n ? (s: string) => import(s)\n : indirectImport;\n\n const { readFileSync } = await dynamicImport('fs');\n const { fileURLToPath } = await dynamicImport('url');\n const { dirname, join } = await dynamicImport('path');\n\n // Get the directory of the built module\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const profileFilePath = join(moduleDir, profileInfo.file);\n\n const profileData = readFileSync(profileFilePath);\n profileBlob = new Blob([profileData], {\n type: 'application/vnd.iccprofile',\n });\n } else {\n // Browser: Use fetch\n const profileUrl = new URL(profileInfo.file, import.meta.url).href;\n const profileResponse = await fetch(profileUrl);\n if (!profileResponse.ok) {\n throw new Error(\n `Failed to load ICC profile ${profileInfo.file}: ${profileResponse.statusText}`\n );\n }\n profileBlob = await profileResponse.blob();\n }\n\n await vfs.writeBlob(profilePath, profileBlob);\n }\n\n // Determine ICC profile path and metadata for Ghostscript\n let iccProfilePath: string;\n let outputConditionIdentifier: string;\n let outputCondition: string;\n\n if (options.outputProfile === 'custom') {\n iccProfilePath = customProfilePath;\n // Use custom values or defaults\n outputConditionIdentifier =\n options.outputConditionIdentifier || 'Custom Profile';\n outputCondition = options.outputCondition || 'Custom ICC Profile';\n } else {\n const preset =\n PROFILE_PRESETS[options.outputProfile as keyof typeof PROFILE_PRESETS];\n iccProfilePath = `/tmp/${preset.file}`;\n // Allow overriding preset values\n outputConditionIdentifier =\n options.outputConditionIdentifier || preset.identifier;\n outputCondition = options.outputCondition || preset.info;\n }\n\n // Read ICC profile data and convert to hex for embedding\n // WASM doesn't support (file) (r) file syntax, so we embed directly\n const iccData = vfs.readFile(iccProfilePath);\n const iccHex = Array.from(iccData)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n\n // Determine color conversion strategy based on profile type\n // ICC profile color space is at bytes 16-19\n // 'RGB ' = 0x52474220, 'CMYK' = 0x434D594B\n const colorSpaceBytes = iccData.slice(16, 20);\n const colorSpaceStr = String.fromCharCode(...colorSpaceBytes);\n const isCMYKProfile = colorSpaceStr.trim() === 'CMYK';\n\n // Generate PDF/X-3 definition with ICC profile hex data\n const pdfxDefinition = generatePDFXDef(\n options,\n iccHex,\n outputConditionIdentifier,\n outputCondition\n );\n vfs.writeText(pdfxDefPath, pdfxDefinition);\n\n // Execute Ghostscript conversion\n // For CMYK profiles, convert all colors to CMYK using the ICC profile\n // Note: Transparency flattening will rasterize transparent content\n const gsArgs = [\n '-dBATCH',\n '-dNOPAUSE',\n '-sDEVICE=pdfwrite',\n '-dCompatibilityLevel=1.4',\n // Disable PDF 1.5+ features to avoid warnings with PDF 1.4 compatibility\n '-dWriteObjStms=false',\n '-dWriteXRefStm=false',\n // PDF/X-3 settings\n '-dPDFSETTINGS=/prepress',\n '-dSetPageSize=false',\n '-dAutoRotatePages=/None',\n ];\n\n // Flatten transparency for PDF/X-3 compliance (default: true)\n // HaveTransparency=false tells Ghostscript the target viewer cannot handle\n // PDF 1.4 transparency, so pages with transparency are converted to bitmaps\n const shouldFlattenTransparency = options.flattenTransparency !== false;\n if (shouldFlattenTransparency) {\n gsArgs.push('-dHaveTransparency=false');\n }\n\n // Add color conversion for CMYK profiles\n if (isCMYKProfile) {\n gsArgs.push(\n '-sColorConversionStrategy=CMYK',\n '-dProcessColorModel=/DeviceCMYK',\n '-dConvertCMYKImagesToRGB=false'\n );\n } else {\n // For RGB profiles, we still need a color conversion strategy\n gsArgs.push('-sColorConversionStrategy=RGB');\n }\n\n // Add output file and input files\n gsArgs.push(`-sOutputFile=${outputPath}`, pdfxDefPath, inputPath);\n\n const exitCode = await module.callMain(gsArgs);\n if (exitCode !== 0) {\n throw new Error(\n `Ghostscript conversion failed with exit code ${exitCode}`\n );\n }\n\n // Read output\n const outputData = vfs.readFile(outputPath);\n // Create a copy of the data to ensure it's an ArrayBuffer, not SharedArrayBuffer\n const outputBuffer = new Uint8Array(outputData);\n const outputPDF = new Blob([outputBuffer], { type: 'application/pdf' });\n\n // Cleanup\n vfs.cleanup();\n\n return outputPDF;\n } catch (error) {\n vfs.cleanup();\n throw error;\n }\n}\n\n// Profile presets from the spec\nconst PROFILE_PRESETS = {\n gracol: {\n file: 'GRACoL2013_CRPC6.icc',\n identifier: 'CGATS 21.2',\n info: 'GRACoL 2013 CRPC6',\n },\n fogra39: {\n file: 'ISOcoated_v2_eci.icc',\n identifier: 'FOGRA39',\n info: 'ISO Coated v2 (ECI)',\n },\n srgb: {\n file: 'sRGB_IEC61966-2-1.icc',\n identifier: 'sRGB IEC61966-2.1',\n info: 'sRGB IEC61966-2.1',\n },\n};\n\nfunction generatePDFXDef(\n options: PDFX3Options,\n iccProfileHex: string,\n outputConditionIdentifier: string,\n outputCondition: string\n): string {\n return `%!\n% PDF/X-3 Definition File\n[ /Title (${options.title || 'Untitled'}) /DOCINFO pdfmark\n[ /Trapped /False /DOCINFO pdfmark\n\n% Set PDF/X-3 conformance\n[ /GTS_PDFXVersion (PDF/X-3:2003) /GTS_PDFXConformance (PDF/X-3:2003) /DOCINFO pdfmark\n\n% Set TrimBox to match MediaBox for all pages (required for PDF/X)\n[/TrimBox [0 0 0 0] /PAGE pdfmark\n\n% Embed ICC profile as hex stream\n[/_objdef {icc_PDFX} /type /stream /OBJ pdfmark\n[{icc_PDFX} <</N 4>> /PUT pdfmark\n[{icc_PDFX} <${iccProfileHex}> /PUT pdfmark\n\n% Define OutputIntent with embedded ICC profile\n[/_objdef {OutputIntent_PDFX} /type /dict /OBJ pdfmark\n[{OutputIntent_PDFX} <<\n /Type /OutputIntent\n /S /GTS_PDFX\n /OutputCondition (${outputCondition})\n /OutputConditionIdentifier (${outputConditionIdentifier})\n /RegistryName (http://www.color.org)\n /DestOutputProfile {icc_PDFX}\n>> /PUT pdfmark\n\n% Add OutputIntent to Catalog\n[{Catalog} <</OutputIntents [{OutputIntent_PDFX}]>> /PUT pdfmark`;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable no-console */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LogEntry {\n timestamp: number;\n level: LogLevel;\n component: string;\n message: string;\n data?: any;\n}\n\nexport class Logger {\n private static globalLogLevel: LogLevel = 'warn';\n\n private static logs: LogEntry[] = [];\n\n private static maxLogs = 1000;\n\n constructor(private component: string) {}\n\n static setLogLevel(level: LogLevel): void {\n Logger.globalLogLevel = level;\n }\n\n static getLogs(): LogEntry[] {\n return [...Logger.logs];\n }\n\n static clearLogs(): void {\n Logger.logs = [];\n }\n\n debug(message: string, data?: any): void {\n this.log('debug', message, data);\n }\n\n info(message: string, data?: any): void {\n this.log('info', message, data);\n }\n\n warn(message: string, data?: any): void {\n this.log('warn', message, data);\n }\n\n error(message: string, data?: any): void {\n this.log('error', message, data);\n }\n\n private log(level: LogLevel, message: string, data?: any): void {\n const levelOrder: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n if (levelOrder[level] < levelOrder[Logger.globalLogLevel]) {\n return;\n }\n\n const entry: LogEntry = {\n timestamp: Date.now(),\n level,\n component: this.component,\n message,\n data,\n };\n\n Logger.logs.push(entry);\n\n // Keep logs under the limit\n if (Logger.logs.length > Logger.maxLogs) {\n Logger.logs = Logger.logs.slice(-Logger.maxLogs);\n }\n\n // Console output\n const prefix = `[${new Date().toISOString()}] [${level.toUpperCase()}] [${\n this.component\n }]`;\n const logMessage = data ? `${message} ${JSON.stringify(data)}` : message;\n\n switch (level) {\n case 'debug':\n console.debug(prefix, logMessage);\n break;\n case 'info':\n console.info(prefix, logMessage);\n break;\n case 'warn':\n console.warn(prefix, logMessage);\n break;\n case 'error':\n console.error(prefix, logMessage);\n break;\n default:\n // All log levels handled above\n break;\n }\n }\n}\n", "export class BrowserDetection {\n supportsWebAssembly(): boolean {\n try {\n return (\n typeof WebAssembly === 'object' &&\n typeof WebAssembly.instantiate === 'function'\n );\n } catch {\n return false;\n }\n }\n}\n", "// Wrapper for the Ghostscript WASM module to ensure proper loading\nimport type {\n EmscriptenModule,\n GhostscriptModuleFactory,\n} from '../types/ghostscript';\n\nexport interface GhostscriptModuleOptions {\n /**\n * Whether to suppress Ghostscript's stdout/stderr output.\n * Default: true (silent mode)\n */\n silent?: boolean;\n}\n\nexport default async function createGhostscriptModule(\n options: GhostscriptModuleOptions = {}\n): Promise<EmscriptenModule> {\n const { silent = true } = options;\n // Check if we're in Node.js\n const isNode =\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null;\n\n let GhostscriptModule: any;\n let wasmPath: string;\n\n if (isNode) {\n // Node.js: Use require.resolve to find gs.js relative to this module\n // Use indirect dynamic import to prevent Webpack 5 from statically analyzing these imports\n // But use direct imports in test environments (vitest) where indirect imports bypass mocking\n // See: https://github.com/imgly/ubq/issues/11471\n const isTestEnv =\n typeof process !== 'undefined' &&\n (process.env.VITEST === 'true' || process.env.NODE_ENV === 'test');\n\n // Helper for dynamic imports - uses indirect import in production to avoid Webpack static analysis\n // Note: new Function() could fail in CSP-restricted environments, but CSP is a browser\n // security mechanism and doesn't apply to Node.js. This code only runs in Node.js (isNode check above).\n // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func\n const indirectImport = new Function('s', 'return import(s)') as (\n s: string\n ) => Promise<any>;\n const dynamicImport = isTestEnv ? (s: string) => import(s) : indirectImport;\n\n const moduleLib = await dynamicImport('module');\n const pathLib = await dynamicImport('path');\n const createRequire = moduleLib.createRequire;\n const dirname = pathLib.dirname;\n const join = pathLib.join;\n\n const requireForESM = createRequire(import.meta.url);\n\n // Resolve gs.js directly (it's copied to dist/ alongside the bundle)\n const gsPath = requireForESM.resolve('./gs.js');\n const moduleDir = dirname(gsPath);\n wasmPath = join(moduleDir, 'gs.wasm');\n\n GhostscriptModule = await dynamicImport(gsPath);\n } else {\n // Browser: Use URL-based imports\n const moduleUrl = new URL('./gs.js', import.meta.url).href;\n GhostscriptModule = await import(/* webpackIgnore: true */ moduleUrl);\n wasmPath = new URL('./gs.wasm', import.meta.url).href;\n }\n\n const factory = (GhostscriptModule.default ||\n GhostscriptModule) as GhostscriptModuleFactory;\n\n // Configure the module to load WASM from the bundled location\n const moduleConfig: Record<string, unknown> = {\n locateFile: (filename: string) => {\n if (filename === 'gs.wasm') {\n return wasmPath;\n }\n return filename;\n },\n };\n\n // Suppress Ghostscript stdout/stderr output in silent mode\n if (silent) {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n moduleConfig.print = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n moduleConfig.printErr = () => {};\n }\n\n const module = await factory(moduleConfig);\n\n return module;\n}\n", "import type { EmscriptenModule } from '../types/ghostscript';\nimport { Logger } from '../utils/logger';\nimport { BrowserDetection } from '../utils/browser-detection';\nimport createGhostscriptModule from '../wasm/ghostscript-module';\n\nexport interface LoaderOptions {\n timeout?: number;\n}\n\nexport class GhostscriptLoader {\n private static instance: Promise<EmscriptenModule> | null = null;\n\n private static readonly TIMEOUT_MS = 30000;\n\n static async load(options: LoaderOptions = {}): Promise<EmscriptenModule> {\n if (this.instance) {\n return this.instance;\n }\n\n this.instance = this.loadInternal(options);\n return this.instance;\n }\n\n private static async loadInternal(\n options: LoaderOptions\n ): Promise<EmscriptenModule> {\n const logger = new Logger('GhostscriptLoader');\n const browser = new BrowserDetection();\n\n // Check browser compatibility\n if (!browser.supportsWebAssembly()) {\n throw new Error('WebAssembly not supported in this browser');\n }\n\n const timeout = options.timeout || this.TIMEOUT_MS;\n\n try {\n logger.info('Loading bundled Ghostscript (AGPL-3.0 licensed)');\n logger.info('Source available at: https://img.ly/docs/cesdk');\n return await this.loadWithTimeout(() => this.loadFromBundle(), timeout);\n } catch (error) {\n logger.error('Ghostscript loading failed', {\n error: (error as Error).message,\n });\n throw new Error(\n `Failed to load Ghostscript: ${(error as Error).message}`\n );\n }\n }\n\n private static async loadFromBundle(): Promise<EmscriptenModule> {\n // Use the bundled WASM module with proper configuration\n const logger = new Logger('GhostscriptInit');\n\n try {\n logger.info('Initializing Ghostscript module');\n\n const module = await createGhostscriptModule();\n\n logger.info('Ghostscript module initialized successfully', {\n version: module.version || 'unknown',\n hasFS: !!module.FS,\n hasCallMain: !!module.callMain,\n });\n\n return module;\n } catch (error) {\n logger.error('Ghostscript initialization failed', { error });\n throw new Error(\n `Ghostscript initialization failed: ${(error as Error).message}`\n );\n }\n }\n\n private static async loadWithTimeout<T>(\n operation: () => Promise<T>,\n timeoutMs: number\n ): Promise<T> {\n return Promise.race([\n operation(),\n new Promise<never>((_, reject) => {\n setTimeout(\n () => reject(new Error(`Loading timeout after ${timeoutMs}ms`)),\n timeoutMs\n );\n }),\n ]);\n }\n\n static reset(): void {\n this.instance = null;\n }\n}\n", "export class BlobUtils {\n static async toUint8Array(blob: Blob): Promise<Uint8Array> {\n if (blob.arrayBuffer) {\n const buffer = await blob.arrayBuffer();\n return new Uint8Array(buffer);\n }\n\n // Fallback for older browsers\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => {\n if (reader.result instanceof ArrayBuffer) {\n resolve(new Uint8Array(reader.result));\n } else {\n reject(new Error('Failed to read blob as ArrayBuffer'));\n }\n };\n reader.onerror = () => reject(reader.error);\n reader.readAsArrayBuffer(blob);\n });\n }\n\n static async validatePDF(blob: Blob): Promise<boolean> {\n try {\n const data = await this.toUint8Array(blob);\n\n // Check PDF magic number\n const pdfHeader = new Uint8Array([0x25, 0x50, 0x44, 0x46]); // %PDF\n\n if (data.length < 4) {\n return false;\n }\n\n for (let i = 0; i < 4; i++) {\n if (data[i] !== pdfHeader[i]) {\n return false;\n }\n }\n\n return true;\n } catch {\n return false;\n }\n }\n}\n", "import type { EmscriptenModule, EmscriptenFS } from '../types/ghostscript';\nimport { Logger } from '../utils/logger';\nimport { BlobUtils } from '../utils/blob-utils';\n\nexport interface FileEntry {\n path: string;\n data: Uint8Array;\n cleanup: boolean;\n}\n\nexport class VirtualFileSystem {\n private readonly fs: EmscriptenFS;\n\n private readonly logger: Logger;\n\n private readonly managedFiles: Set<string> = new Set();\n\n private readonly workingDir: string;\n\n constructor(\n private readonly module: EmscriptenModule,\n workingDir = '/tmp/pdfx'\n ) {\n this.fs = module.FS;\n this.logger = new Logger('VirtualFileSystem');\n this.workingDir = workingDir;\n this.initialize();\n }\n\n private initialize(): void {\n try {\n // Create working directory structure (handle existing directories gracefully)\n this.createDirIfNotExists(this.workingDir);\n this.createDirIfNotExists(`${this.workingDir}/input`);\n this.createDirIfNotExists(`${this.workingDir}/output`);\n this.createDirIfNotExists(`${this.workingDir}/profiles`);\n this.createDirIfNotExists(`${this.workingDir}/temp`);\n\n this.logger.info('Virtual filesystem initialized', {\n workingDir: this.workingDir,\n });\n } catch (error) {\n this.logger.error('Failed to initialize virtual filesystem', { error });\n throw new Error(`VFS initialization failed: ${error}`);\n }\n }\n\n private createDirIfNotExists(path: string): void {\n try {\n this.fs.mkdir(path);\n } catch (error: any) {\n // Ignore \"File exists\" errors, re-throw others\n if (error.code !== 'EEXIST') {\n throw error;\n }\n }\n }\n\n async writeBlob(path: string, blob: Blob, managed = true): Promise<void> {\n try {\n const data = await BlobUtils.toUint8Array(blob);\n this.fs.writeFile(path, data);\n\n if (managed) {\n this.managedFiles.add(path);\n }\n\n this.logger.debug('File written', { path, size: data.length });\n } catch (error) {\n this.logger.error('Failed to write blob', { path, error });\n throw new Error(`Failed to write file ${path}: ${error}`);\n }\n }\n\n writeText(path: string, content: string, managed = true): void {\n try {\n this.fs.writeFile(path, content);\n\n if (managed) {\n this.managedFiles.add(path);\n }\n\n this.logger.debug('Text file written', { path, length: content.length });\n } catch (error) {\n this.logger.error('Failed to write text', { path, error });\n throw new Error(`Failed to write text file ${path}: ${error}`);\n }\n }\n\n readFile(path: string): Uint8Array {\n try {\n const data = this.fs.readFile(path) as Uint8Array;\n this.logger.debug('File read', { path, size: data.length });\n return data;\n } catch (error) {\n this.logger.error('Failed to read file', { path, error });\n throw new Error(`Failed to read file ${path}: ${error}`);\n }\n }\n\n exists(path: string): boolean {\n try {\n this.fs.stat(path);\n return true;\n } catch {\n return false;\n }\n }\n\n cleanup(): void {\n let cleanedCount = 0;\n\n for (const path of this.managedFiles) {\n try {\n this.fs.unlink(path);\n cleanedCount++;\n } catch (error) {\n this.logger.warn('Failed to cleanup file', { path, error });\n }\n }\n\n this.managedFiles.clear();\n this.logger.info('Filesystem cleanup completed', { cleanedCount });\n }\n}\n", "import type { PDFX3Options } from './types/pdfx';\nimport { GhostscriptLoader } from './core/ghostscript-loader';\nimport { VirtualFileSystem } from './core/virtual-filesystem';\nimport { BlobUtils } from './utils/blob-utils';\n\n/**\n * PDF/X-3 conversion function\n * Converts RGB PDF(s) to PDF/X-3 format using specified output profile\n *\n * @overload\n * @param inputPDF Single PDF blob to convert\n * @param options Conversion configuration\n * @returns Promise resolving to converted PDF blob\n *\n * @overload\n * @param inputPDFs Array of PDF blobs to convert\n * @param options Conversion configuration\n * @returns Promise resolving to array of converted PDF blobs\n */\nexport function convertToPDFX3(\n inputPDF: Blob,\n options: PDFX3Options\n): Promise<Blob>;\nexport function convertToPDFX3(\n inputPDFs: Blob[],\n options: PDFX3Options\n): Promise<Blob[]>;\nexport async function convertToPDFX3(\n input: Blob | Blob[],\n options: PDFX3Options\n): Promise<Blob | Blob[]> {\n // Handle array input (batch processing)\n if (Array.isArray(input)) {\n if (input.length === 0) {\n return [];\n }\n\n // Process each blob sequentially to avoid overwhelming the WASM module\n const results: Blob[] = [];\n for (let i = 0; i < input.length; i++) {\n try {\n // eslint-disable-next-line no-await-in-loop\n const converted = await convertToPDFX3Single(input[i], options);\n results.push(converted);\n } catch (error) {\n throw new Error(\n `Failed to convert PDF ${i + 1} of ${input.length}: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n }\n }\n return results;\n }\n\n // Handle single blob input\n return convertToPDFX3Single(input, options);\n}\n\n/**\n * Internal function to convert a single PDF\n */\nasync function convertToPDFX3Single(\n inputPDF: Blob,\n options: PDFX3Options\n): Promise<Blob> {\n // Validate inputs\n if (!(inputPDF instanceof Blob)) {\n throw new Error('Input must be a Blob');\n }\n\n if (inputPDF.size === 0) {\n throw new Error('Input PDF is empty');\n }\n\n if (inputPDF.size > 100 * 1024 * 1024) {\n throw new Error(\n `Input PDF too large (${inputPDF.size} bytes). Maximum: 100MB`\n );\n }\n\n // Validate output profile is provided\n if (!options.outputProfile) {\n throw new Error(\n 'outputProfile is required. Must be one of: \"gracol\", \"fogra39\", \"srgb\", \"custom\"'\n );\n }\n\n // Validate output profile value\n const validProfiles = ['gracol', 'fogra39', 'srgb', 'custom'];\n if (!validProfiles.includes(options.outputProfile)) {\n throw new Error(\n `Invalid outputProfile \"${\n options.outputProfile\n }\". Must be one of: ${validProfiles.join(', ')}`\n );\n }\n\n // Validate custom profile requirement\n if (options.outputProfile === 'custom' && !options.customProfile) {\n throw new Error(\n 'customProfile Blob is required when outputProfile is \"custom\"'\n );\n }\n\n // Validate custom profile if provided\n if (options.customProfile && !(options.customProfile instanceof Blob)) {\n throw new Error('customProfile must be a Blob');\n }\n\n // Validate PDF format\n const isValidPDF = await BlobUtils.validatePDF(inputPDF);\n if (!isValidPDF) {\n throw new Error('Invalid PDF format');\n }\n\n // Load Ghostscript\n const module = await GhostscriptLoader.load();\n const vfs = new VirtualFileSystem(module);\n\n try {\n // Setup file paths\n const inputPath = '/tmp/input.pdf';\n const outputPath = '/tmp/output.pdf';\n const pdfxDefPath = '/tmp/pdfx_def.ps';\n const customProfilePath = '/tmp/custom.icc';\n\n // Write input PDF to virtual filesystem\n await vfs.writeBlob(inputPath, inputPDF);\n\n // Write ICC profiles to virtual filesystem\n if (options.outputProfile === 'custom' && options.customProfile) {\n await vfs.writeBlob(customProfilePath, options.customProfile);\n } else if (options.outputProfile !== 'custom') {\n // Load the bundled ICC profile\n const profileInfo =\n PROFILE_PRESETS[options.outputProfile as keyof typeof PROFILE_PRESETS];\n const profilePath = `/tmp/${profileInfo.file}`;\n\n // Load ICC profile - different approach for Node.js vs browser\n const isNode =\n typeof process !== 'undefined' && process.versions?.node != null;\n\n let profileBlob: Blob;\n\n if (isNode) {\n // Node.js: Load from filesystem using readFileSync\n // Use indirect dynamic import to prevent Webpack 5 from statically analyzing these imports\n // But use direct imports in test environments (vitest) where indirect imports bypass mocking\n // See: https://github.com/imgly/ubq/issues/11471\n const isTestEnv =\n process.env.VITEST === 'true' || process.env.NODE_ENV === 'test';\n\n // Note: new Function() could fail in CSP-restricted environments, but CSP is a browser\n // security mechanism and doesn't apply to Node.js. This code only runs in Node.js (isNode check above).\n // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func\n const indirectImport = new Function('s', 'return import(s)') as (\n s: string\n ) => Promise<any>;\n const dynamicImport = isTestEnv\n ? (s: string) => import(s)\n : indirectImport;\n\n const { readFileSync } = await dynamicImport('fs');\n const { fileURLToPath } = await dynamicImport('url');\n const { dirname, join } = await dynamicImport('path');\n\n // Get the directory of the built module\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const profileFilePath = join(moduleDir, profileInfo.file);\n\n const profileData = readFileSync(profileFilePath);\n profileBlob = new Blob([profileData], {\n type: 'application/vnd.iccprofile',\n });\n } else {\n // Browser: Use fetch\n const profileUrl = new URL(profileInfo.file, import.meta.url).href;\n const profileResponse = await fetch(profileUrl);\n if (!profileResponse.ok) {\n throw new Error(\n `Failed to load ICC profile ${profileInfo.file}: ${profileResponse.statusText}`\n );\n }\n profileBlob = await profileResponse.blob();\n }\n\n await vfs.writeBlob(profilePath, profileBlob);\n }\n\n // Determine ICC profile path and metadata for Ghostscript\n let iccProfilePath: string;\n let outputConditionIdentifier: string;\n let outputCondition: string;\n\n if (options.outputProfile === 'custom') {\n iccProfilePath = customProfilePath;\n // Use custom values or defaults\n outputConditionIdentifier =\n options.outputConditionIdentifier || 'Custom Profile';\n outputCondition = options.outputCondition || 'Custom ICC Profile';\n } else {\n const preset =\n PROFILE_PRESETS[options.outputProfile as keyof typeof PROFILE_PRESETS];\n iccProfilePath = `/tmp/${preset.file}`;\n // Allow overriding preset values\n outputConditionIdentifier =\n options.outputConditionIdentifier || preset.identifier;\n outputCondition = options.outputCondition || preset.info;\n }\n\n // Read ICC profile data and convert to hex for embedding\n // WASM doesn't support (file) (r) file syntax, so we embed directly\n const iccData = vfs.readFile(iccProfilePath);\n const iccHex = Array.from(iccData)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n\n // Determine color conversion strategy based on profile type\n // ICC profile color space is at bytes 16-19\n // 'RGB ' = 0x52474220, 'CMYK' = 0x434D594B\n const colorSpaceBytes = iccData.slice(16, 20);\n const colorSpaceStr = String.fromCharCode(...colorSpaceBytes);\n const isCMYKProfile = colorSpaceStr.trim() === 'CMYK';\n\n // Generate PDF/X-3 definition with ICC profile hex data\n const pdfxDefinition = generatePDFXDef(\n options,\n iccHex,\n outputConditionIdentifier,\n outputCondition\n );\n vfs.writeText(pdfxDefPath, pdfxDefinition);\n\n // Execute Ghostscript conversion\n // For CMYK profiles, convert all colors to CMYK using the ICC profile\n // Note: Transparency flattening will rasterize transparent content\n const gsArgs = [\n '-dBATCH',\n '-dNOPAUSE',\n '-sDEVICE=pdfwrite',\n '-dCompatibilityLevel=1.4',\n // Disable PDF 1.5+ features to avoid warnings with PDF 1.4 compatibility\n '-dWriteObjStms=false',\n '-dWriteXRefStm=false',\n // PDF/X-3 settings\n '-dPDFSETTINGS=/prepress',\n '-dSetPageSize=false',\n '-dAutoRotatePages=/None',\n ];\n\n // Flatten transparency for PDF/X-3 compliance (default: true)\n // HaveTransparency=false tells Ghostscript the target viewer cannot handle\n // PDF 1.4 transparency, so pages with transparency are converted to bitmaps\n const shouldFlattenTransparency = options.flattenTransparency !== false;\n if (shouldFlattenTransparency) {\n gsArgs.push('-dHaveTransparency=false');\n }\n\n // Add color conversion for CMYK profiles\n if (isCMYKProfile) {\n gsArgs.push(\n '-sColorConversionStrategy=CMYK',\n '-dProcessColorModel=/DeviceCMYK',\n '-dConvertCMYKImagesToRGB=false'\n );\n } else {\n // For RGB profiles, we still need a color conversion strategy\n gsArgs.push('-sColorConversionStrategy=RGB');\n }\n\n // Add output file and input files\n gsArgs.push(`-sOutputFile=${outputPath}`, pdfxDefPath, inputPath);\n\n const exitCode = await module.callMain(gsArgs);\n if (exitCode !== 0) {\n throw new Error(\n `Ghostscript conversion failed with exit code ${exitCode}`\n );\n }\n\n // Read output\n const outputData = vfs.readFile(outputPath);\n // Create a copy of the data to ensure it's an ArrayBuffer, not SharedArrayBuffer\n const outputBuffer = new Uint8Array(outputData);\n const outputPDF = new Blob([outputBuffer], { type: 'application/pdf' });\n\n // Cleanup\n vfs.cleanup();\n\n return outputPDF;\n } catch (error) {\n vfs.cleanup();\n throw error;\n }\n}\n\n// Profile presets from the spec\nconst PROFILE_PRESETS = {\n gracol: {\n file: 'GRACoL2013_CRPC6.icc',\n identifier: 'CGATS 21.2',\n info: 'GRACoL 2013 CRPC6',\n },\n fogra39: {\n file: 'ISOcoated_v2_eci.icc',\n identifier: 'FOGRA39',\n info: 'ISO Coated v2 (ECI)',\n },\n srgb: {\n file: 'sRGB_IEC61966-2-1.icc',\n identifier: 'sRGB IEC61966-2.1',\n info: 'sRGB IEC61966-2.1',\n },\n};\n\nfunction generatePDFXDef(\n options: PDFX3Options,\n iccProfileHex: string,\n outputConditionIdentifier: string,\n outputCondition: string\n): string {\n return `%!\n% PDF/X-3 Definition File\n[ /Title (${options.title || 'Untitled'}) /DOCINFO pdfmark\n[ /Trapped /False /DOCINFO pdfmark\n\n% Set PDF/X-3 conformance\n[ /GTS_PDFXVersion (PDF/X-3:2003) /GTS_PDFXConformance (PDF/X-3:2003) /DOCINFO pdfmark\n\n% Set TrimBox to match MediaBox for all pages (required for PDF/X)\n[/TrimBox [0 0 0 0] /PAGE pdfmark\n\n% Embed ICC profile as hex stream\n[/_objdef {icc_PDFX} /type /stream /OBJ pdfmark\n[{icc_PDFX} <</N 4>> /PUT pdfmark\n[{icc_PDFX} <${iccProfileHex}> /PUT pdfmark\n\n% Define OutputIntent with embedded ICC profile\n[/_objdef {OutputIntent_PDFX} /type /dict /OBJ pdfmark\n[{OutputIntent_PDFX} <<\n /Type /OutputIntent\n /S /GTS_PDFX\n /OutputCondition (${outputCondition})\n /OutputConditionIdentifier (${outputConditionIdentifier})\n /RegistryName (http://www.color.org)\n /DestOutputProfile {icc_PDFX}\n>> /PUT pdfmark\n\n% Add OutputIntent to Catalog\n[{Catalog} <</OutputIntents [{OutputIntent_PDFX}]>> /PUT pdfmark`;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["Logger", "_Logger", "component", "level", "message", "data", "levelOrder", "entry", "prefix", "logMessage", "BrowserDetection", "createGhostscriptModule", "options", "silent", "isNode", "GhostscriptModule", "wasmPath", "isTestEnv", "indirectImport", "dynamicImport", "s", "moduleLib", "pathLib", "createRequire", "dirname", "join", "gsPath", "moduleDir", "factory", "moduleConfig", "filename", "GhostscriptLoader", "options", "logger", "Logger", "BrowserDetection", "timeout", "error", "module", "createGhostscriptModule", "operation", "timeoutMs", "_", "reject", "BlobUtils", "blob", "buffer", "resolve", "reject", "reader", "data", "pdfHeader", "i", "VirtualFileSystem", "module", "workingDir", "Logger", "error", "path", "blob", "managed", "data", "BlobUtils", "content", "cleanedCount", "convertToPDFX3", "input", "options", "results", "converted", "convertToPDFX3Single", "error", "inputPDF", "validProfiles", "BlobUtils", "module", "GhostscriptLoader", "vfs", "VirtualFileSystem", "inputPath", "outputPath", "pdfxDefPath", "customProfilePath", "profileInfo", "PROFILE_PRESETS", "profilePath", "isNode", "profileBlob", "isTestEnv", "indirectImport", "dynamicImport", "s", "readFileSync", "fileURLToPath", "dirname", "join", "moduleDir", "profileFilePath", "profileData", "profileUrl", "profileResponse", "iccProfilePath", "outputConditionIdentifier", "outputCondition", "preset", "iccData", "iccHex", "b", "colorSpaceBytes", "isCMYKProfile", "pdfxDefinition", "generatePDFXDef", "gsArgs", "exitCode", "outputData", "outputBuffer", "outputPDF", "iccProfileHex"]
7
7
  }
package/dist/pdfx.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { PDFX3Options } from './types/pdfx';
2
+ /**
3
+ * PDF/X-3 conversion function
4
+ * Converts RGB PDF(s) to PDF/X-3 format using specified output profile
5
+ *
6
+ * @overload
7
+ * @param inputPDF Single PDF blob to convert
8
+ * @param options Conversion configuration
9
+ * @returns Promise resolving to converted PDF blob
10
+ *
11
+ * @overload
12
+ * @param inputPDFs Array of PDF blobs to convert
13
+ * @param options Conversion configuration
14
+ * @returns Promise resolving to array of converted PDF blobs
15
+ */
16
+ export declare function convertToPDFX3(inputPDF: Blob, options: PDFX3Options): Promise<Blob>;
17
+ export declare function convertToPDFX3(inputPDFs: Blob[], options: PDFX3Options): Promise<Blob[]>;
18
+ //# sourceMappingURL=pdfx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdfx.d.ts","sourceRoot":"","sources":["../src/pdfx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAKjD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,IAAI,EACd,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAAC;AACjB,wBAAgB,cAAc,CAC5B,SAAS,EAAE,IAAI,EAAE,EACjB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './types/pdfx';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare class BlobUtils {
2
+ static toUint8Array(blob: Blob): Promise<Uint8Array>;
3
+ static validatePDF(blob: Blob): Promise<boolean>;
4
+ }
5
+ //# sourceMappingURL=blob-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob-utils.d.ts","sourceRoot":"","sources":["../../src/utils/blob-utils.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAS;WACP,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;WAqB7C,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;CAsBvD"}
@@ -0,0 +1,4 @@
1
+ export declare class BrowserDetection {
2
+ supportsWebAssembly(): boolean;
3
+ }
4
+ //# sourceMappingURL=browser-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-detection.d.ts","sourceRoot":"","sources":["../../src/utils/browser-detection.ts"],"names":[],"mappings":"AAAA,qBAAa,gBAAgB;IAC3B,mBAAmB,IAAI,OAAO;CAU/B"}
@@ -0,0 +1,24 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export interface LogEntry {
3
+ timestamp: number;
4
+ level: LogLevel;
5
+ component: string;
6
+ message: string;
7
+ data?: any;
8
+ }
9
+ export declare class Logger {
10
+ private component;
11
+ private static globalLogLevel;
12
+ private static logs;
13
+ private static maxLogs;
14
+ constructor(component: string);
15
+ static setLogLevel(level: LogLevel): void;
16
+ static getLogs(): LogEntry[];
17
+ static clearLogs(): void;
18
+ debug(message: string, data?: any): void;
19
+ info(message: string, data?: any): void;
20
+ warn(message: string, data?: any): void;
21
+ error(message: string, data?: any): void;
22
+ private log;
23
+ }
24
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAED,qBAAa,MAAM;IAOL,OAAO,CAAC,SAAS;IAN7B,OAAO,CAAC,MAAM,CAAC,cAAc,CAAoB;IAEjD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAkB;IAErC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAQ;gBAEV,SAAS,EAAE,MAAM;IAErC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAIzC,MAAM,CAAC,OAAO,IAAI,QAAQ,EAAE;IAI5B,MAAM,CAAC,SAAS,IAAI,IAAI;IAIxB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAIxC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAIvC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAIvC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI;IAIxC,OAAO,CAAC,GAAG;CAmDZ"}
@@ -0,0 +1,10 @@
1
+ import type { EmscriptenModule } from '../types/ghostscript';
2
+ export interface GhostscriptModuleOptions {
3
+ /**
4
+ * Whether to suppress Ghostscript's stdout/stderr output.
5
+ * Default: true (silent mode)
6
+ */
7
+ silent?: boolean;
8
+ }
9
+ export default function createGhostscriptModule(options?: GhostscriptModuleOptions): Promise<EmscriptenModule>;
10
+ //# sourceMappingURL=ghostscript-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ghostscript-module.d.ts","sourceRoot":"","sources":["../../src/wasm/ghostscript-module.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAA8B,uBAAuB,CACnD,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,gBAAgB,CAAC,CA0E3B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imgly/plugin-print-ready-pdfs-web",
3
- "version": "1.1.1",
3
+ "version": "1.68.0-rc.1",
4
4
  "description": "Print-Ready PDFs plugin for CE.SDK editor - PDF/X conversion and export functionality. Contains AGPL-3.0 licensed Ghostscript WASM.",
5
5
  "keywords": [
6
6
  "CE.SDK",
@@ -9,10 +9,6 @@
9
9
  "pdfx",
10
10
  "export"
11
11
  ],
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/imgly/plugin-print-ready-pdfs-web.git"
15
- },
16
12
  "license": "SEE LICENSE IN LICENSE.md",
17
13
  "author": {
18
14
  "name": "IMG.LY GmbH",
@@ -31,7 +27,7 @@
31
27
  "types": "./dist/index.d.ts"
32
28
  }
33
29
  },
34
- "homepage": "https://img.ly/products/creative-sdk",
30
+ "homepage": "https://img.ly/docs/cesdk/",
35
31
  "files": [
36
32
  "LICENSE.md",
37
33
  "README.md",
@@ -53,7 +49,6 @@
53
49
  "eslint": "^8.57.1",
54
50
  "http-server": "^14.1.1",
55
51
  "playwright": "^1.54.1",
56
- "pnpm-sync-dependencies-meta-injected": "^0.0.14",
57
52
  "prettier": "^2.8.8",
58
53
  "rimraf": "^6.0.1",
59
54
  "typescript": "^5.7.3",
@@ -61,17 +56,12 @@
61
56
  "wait-on": "8.0.2",
62
57
  "@imgly/plugin-utils": "0.0.0"
63
58
  },
64
- "dependenciesMeta": {
65
- "@imgly/plugin-utils": {
66
- "injected": true
67
- }
68
- },
69
59
  "scripts": {
70
60
  "start": "pnpm dev",
71
61
  "clean": "pnpm exec rimraf dist",
72
62
  "purge": "pnpm exec rimraf node_modules",
73
- "build": "pnpm run clean && pnpm _syncPnpm && pnpm exec node scripts/build.mjs",
74
- "dev": "pnpm exec concurrently 'node scripts/watch.mjs' 'pnpm _syncPnpm --watch' --names 'build,sync deps'",
63
+ "build": "pnpm run clean && pnpm exec node scripts/build.mjs",
64
+ "dev": "pnpm exec concurrently 'node scripts/watch.mjs' --names 'build'",
75
65
  "dev:wait": "pnpm exec wait-on ./dist/index.mjs ./dist/index.d.ts --window 250 --timeout 60000",
76
66
  "dev:types": "tsc --emitDeclarationOnly --watch --preserveWatchOutput",
77
67
  "publish:latest": "pnpm run build && pnpm publish --tag latest --access public",
@@ -81,7 +71,6 @@
81
71
  "check:pretty": "prettier --list-different './src/**/*.{ts,tsx}'",
82
72
  "check:types": "tsc --noEmit",
83
73
  "types:create": "tsc --emitDeclarationOnly",
84
- "_syncPnpm": "pnpm sync-dependencies-meta-injected",
85
74
  "demo:build": "pnpm run build && node scripts/build-demo.mjs",
86
75
  "demo:dev": "pnpm run build && node scripts/build-demo.mjs && cd demo-dist && python3 -m http.server 8080",
87
76
  "test:convert": "node test/convert-test.mjs",