n8n-nodes-jmap 0.2.0 → 0.2.2

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.
@@ -123,11 +123,12 @@ export declare function downloadBlob(this: IExecuteFunctions, accountId: string,
123
123
  * Interface for attachment options
124
124
  */
125
125
  export interface IAttachmentOptions {
126
- extractArchives?: boolean;
127
126
  includeInline?: boolean;
128
127
  mimeTypeFilter?: string;
129
128
  }
130
129
  /**
131
- * Get attachments from an email and return them as binary data
130
+ * Get attachments from an email and return them as binary data.
131
+ * Each attachment is returned as a separate item with binary data in the 'file' field.
132
+ * To extract archives (ZIP, tar.gz), chain with the n8n Compression node.
132
133
  */
133
134
  export declare function getAttachments(this: IExecuteFunctions, accountId: string, emailId: string, options?: IAttachmentOptions): Promise<INodeExecutionData[]>;
@@ -1,40 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
2
  Object.defineProperty(exports, "__esModule", { value: true });
39
3
  exports.JMAP_CAPABILITIES = void 0;
40
4
  exports.getJmapSession = getJmapSession;
@@ -58,8 +22,6 @@ exports.getThreads = getThreads;
58
22
  exports.downloadBlob = downloadBlob;
59
23
  exports.getAttachments = getAttachments;
60
24
  const n8n_workflow_1 = require("n8n-workflow");
61
- const adm_zip_1 = __importDefault(require("adm-zip"));
62
- const tar = __importStar(require("tar"));
63
25
  // Standard JMAP capabilities
64
26
  exports.JMAP_CAPABILITIES = {
65
27
  CORE: 'urn:ietf:params:jmap:core',
@@ -511,147 +473,12 @@ function matchesMimeType(mimeType, filter) {
511
473
  return normalizedMime === normalizedFilter;
512
474
  }
513
475
  /**
514
- * Check if a MIME type is a ZIP archive
515
- */
516
- function isZipMimeType(mimeType) {
517
- const zipTypes = [
518
- 'application/zip',
519
- 'application/x-zip-compressed',
520
- 'application/x-zip',
521
- ];
522
- return zipTypes.includes(mimeType.toLowerCase());
523
- }
524
- /**
525
- * Check if a MIME type is a tar.gz archive
526
- */
527
- function isTarGzMimeType(mimeType) {
528
- const tarGzTypes = [
529
- 'application/gzip',
530
- 'application/x-gzip',
531
- 'application/x-tar',
532
- 'application/x-compressed-tar',
533
- ];
534
- return tarGzTypes.includes(mimeType.toLowerCase());
535
- }
536
- /**
537
- * Check if filename suggests tar.gz
538
- */
539
- function isTarGzFilename(filename) {
540
- const lower = filename.toLowerCase();
541
- return lower.endsWith('.tar.gz') || lower.endsWith('.tgz');
542
- }
543
- /**
544
- * Get file extension from filename
545
- */
546
- function getFileExtension(filename) {
547
- const parts = filename.split('.');
548
- if (parts.length > 1) {
549
- return parts[parts.length - 1].toLowerCase();
550
- }
551
- return '';
552
- }
553
- /**
554
- * Guess MIME type from filename extension
555
- */
556
- function guessMimeType(filename) {
557
- const ext = getFileExtension(filename).toLowerCase();
558
- const mimeTypes = {
559
- pdf: 'application/pdf',
560
- doc: 'application/msword',
561
- docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
562
- xls: 'application/vnd.ms-excel',
563
- xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
564
- ppt: 'application/vnd.ms-powerpoint',
565
- pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
566
- txt: 'text/plain',
567
- csv: 'text/csv',
568
- json: 'application/json',
569
- xml: 'application/xml',
570
- html: 'text/html',
571
- htm: 'text/html',
572
- jpg: 'image/jpeg',
573
- jpeg: 'image/jpeg',
574
- png: 'image/png',
575
- gif: 'image/gif',
576
- svg: 'image/svg+xml',
577
- webp: 'image/webp',
578
- mp3: 'audio/mpeg',
579
- wav: 'audio/wav',
580
- mp4: 'video/mp4',
581
- avi: 'video/x-msvideo',
582
- zip: 'application/zip',
583
- tar: 'application/x-tar',
584
- gz: 'application/gzip',
585
- };
586
- return mimeTypes[ext] || 'application/octet-stream';
587
- }
588
- /**
589
- * Extract files from a ZIP archive
590
- */
591
- function extractZip(buffer) {
592
- const files = [];
593
- const zip = new adm_zip_1.default(buffer);
594
- const entries = zip.getEntries();
595
- for (const entry of entries) {
596
- if (!entry.isDirectory) {
597
- const data = entry.getData();
598
- const name = entry.entryName.split('/').pop() || entry.entryName;
599
- files.push({
600
- name,
601
- data,
602
- mimeType: guessMimeType(name),
603
- });
604
- }
605
- }
606
- return files;
607
- }
608
- /**
609
- * Extract files from a tar.gz archive
610
- */
611
- async function extractTarGz(buffer) {
612
- const files = [];
613
- return new Promise((resolve, reject) => {
614
- const chunks = new Map();
615
- const parser = new tar.Parser();
616
- parser.on('entry', (entry) => {
617
- if (entry.type === 'File') {
618
- const entryChunks = [];
619
- entry.on('data', (chunk) => {
620
- entryChunks.push(chunk);
621
- });
622
- entry.on('end', () => {
623
- const name = entry.path.split('/').pop() || entry.path;
624
- chunks.set(name, entryChunks);
625
- });
626
- }
627
- else {
628
- entry.resume();
629
- }
630
- });
631
- parser.on('end', () => {
632
- for (const [name, entryChunks] of chunks) {
633
- const data = Buffer.concat(entryChunks);
634
- files.push({
635
- name,
636
- data,
637
- mimeType: guessMimeType(name),
638
- });
639
- }
640
- resolve(files);
641
- });
642
- parser.on('error', reject);
643
- const { Gunzip } = require('zlib');
644
- const gunzip = new Gunzip();
645
- gunzip.pipe(parser);
646
- gunzip.write(buffer);
647
- gunzip.end();
648
- });
649
- }
650
- /**
651
- * Get attachments from an email and return them as binary data
476
+ * Get attachments from an email and return them as binary data.
477
+ * Each attachment is returned as a separate item with binary data in the 'file' field.
478
+ * To extract archives (ZIP, tar.gz), chain with the n8n Compression node.
652
479
  */
653
480
  async function getAttachments(accountId, emailId, options = {}) {
654
- const { extractArchives = false, includeInline = false, mimeTypeFilter = '' } = options;
481
+ const { includeInline = false, mimeTypeFilter = '' } = options;
655
482
  // Get email with attachments metadata
656
483
  const emails = await getEmails.call(this, accountId, [emailId], [
657
484
  'id',
@@ -686,63 +513,17 @@ async function getAttachments(accountId, emailId, options = {}) {
686
513
  }
687
514
  // Download the attachment
688
515
  const buffer = await downloadBlob.call(this, accountId, attachment.blobId, attachment.name, attachment.type);
689
- // Check if this is an archive that should be extracted
690
- const isZip = isZipMimeType(attachment.type);
691
- const isTarGz = isTarGzMimeType(attachment.type) || isTarGzFilename(attachment.name);
692
- if (extractArchives && (isZip || isTarGz)) {
693
- // Extract archive contents
694
- let extractedFiles = [];
695
- try {
696
- if (isZip) {
697
- extractedFiles = extractZip(buffer);
698
- }
699
- else if (isTarGz) {
700
- extractedFiles = await extractTarGz(buffer);
701
- }
702
- }
703
- catch (error) {
704
- // If extraction fails, return the archive as-is
705
- extractedFiles = [];
706
- }
707
- if (extractedFiles.length > 0) {
708
- // Return each extracted file as a separate item
709
- for (const file of extractedFiles) {
710
- const binaryData = await this.helpers.prepareBinaryData(file.data, file.name, file.mimeType);
711
- results.push({
712
- json: {
713
- emailId: email.id,
714
- emailSubject: email.subject,
715
- attachmentIndex,
716
- originalFileName: attachment.name,
717
- fileName: file.name,
718
- mimeType: file.mimeType,
719
- fileSize: file.data.length,
720
- wasExtractedFromArchive: true,
721
- sourceArchiveName: attachment.name,
722
- },
723
- binary: {
724
- file: binaryData,
725
- },
726
- });
727
- attachmentIndex++;
728
- }
729
- continue;
730
- }
731
- // If extraction failed or no files, fall through to return the archive as-is
732
- }
733
- // Return the attachment as-is (not an archive, or extraction disabled/failed)
516
+ // Prepare binary data for n8n
734
517
  const binaryData = await this.helpers.prepareBinaryData(buffer, attachment.name, attachment.type);
735
518
  results.push({
736
519
  json: {
737
520
  emailId: email.id,
738
521
  emailSubject: email.subject,
739
522
  attachmentIndex,
740
- originalFileName: attachment.name,
741
523
  fileName: attachment.name,
742
524
  mimeType: attachment.type,
743
525
  fileSize: attachment.size,
744
- wasExtractedFromArchive: false,
745
- sourceArchiveName: null,
526
+ isInline: attachment.isInline || false,
746
527
  },
747
528
  binary: {
748
529
  file: binaryData,
@@ -429,13 +429,6 @@ class Jmap {
429
429
  },
430
430
  },
431
431
  options: [
432
- {
433
- displayName: 'Extract Archives',
434
- name: 'extractArchives',
435
- type: 'boolean',
436
- default: false,
437
- description: 'Whether to extract ZIP and tar.gz archives and return their contents as individual files',
438
- },
439
432
  {
440
433
  displayName: 'Include Inline Images',
441
434
  name: 'includeInline',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-jmap",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "n8n community node for JMAP email protocol (RFC 8620/8621) - Works with Apache James, Twake Mail, Fastmail, and other JMAP-compatible servers",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -46,9 +46,7 @@
46
46
  ]
47
47
  },
48
48
  "devDependencies": {
49
- "@types/adm-zip": "^0.5.7",
50
49
  "@types/node": "^20.0.0",
51
- "@types/tar": "^6.1.13",
52
50
  "@typescript-eslint/eslint-plugin": "^7.0.0",
53
51
  "@typescript-eslint/parser": "^7.0.0",
54
52
  "eslint": "^8.56.0",
@@ -59,9 +57,5 @@
59
57
  },
60
58
  "peerDependencies": {
61
59
  "n8n-workflow": "*"
62
- },
63
- "dependencies": {
64
- "adm-zip": "^0.5.16",
65
- "tar": "^7.5.2"
66
60
  }
67
61
  }