File size: 1,822 Bytes
1b756c8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { ClassicPreset } from 'rete';
import { BaseWorkflowNode } from './base-node';
import { pdfSocket } from '../sockets';
import type { PDFData, SocketData } from '../types';
import { PDFDocument } from 'pdf-lib';
import { loadPyMuPDF } from '../../utils/pymupdf-loader.js';

export class ImageInputNode extends BaseWorkflowNode {
  readonly category = 'Input' as const;
  readonly icon = 'ph-image';
  readonly description = 'Upload images and convert to PDF';

  private files: File[] = [];

  constructor() {
    super('Image Input');
    this.addOutput('pdf', new ClassicPreset.Output(pdfSocket, 'PDF'));
  }

  async addFiles(fileList: File[]): Promise<void> {
    for (const file of fileList) {
      if (file.type.startsWith('image/')) {
        this.files.push(file);
      }
    }
  }

  removeFile(index: number): void {
    this.files.splice(index, 1);
  }

  hasFile(): boolean {
    return this.files.length > 0;
  }

  getFileCount(): number {
    return this.files.length;
  }

  getFilenames(): string[] {
    return this.files.map((f) => f.name);
  }

  getFilename(): string {
    if (this.files.length === 0) return '';
    if (this.files.length === 1) return this.files[0].name;
    return `${this.files.length} images`;
  }

  async data(
    _inputs: Record<string, SocketData[]>
  ): Promise<Record<string, SocketData>> {
    if (this.files.length === 0) {
      throw new Error('No images uploaded in Image Input node');
    }

    const pymupdf = await loadPyMuPDF();
    const pdfBlob = await pymupdf.imagesToPdf(this.files);
    const bytes = new Uint8Array(await pdfBlob.arrayBuffer());
    const document = await PDFDocument.load(bytes);

    const result: PDFData = {
      type: 'pdf',
      document,
      bytes,
      filename: 'images.pdf',
    };

    return { pdf: result };
  }
}