n8n-nodes-sendit 1.3.0 → 1.3.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/README.md CHANGED
@@ -4,10 +4,13 @@ This is an n8n community node for [SendIt](https://sendit.infiniteappsai.com), a
4
4
 
5
5
  [n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.
6
6
 
7
- ## Release Notes (v1.2.0)
7
+ ## Release Notes (v1.3.1)
8
8
 
9
- `1.2.0` is a major maintainability and feature parity release:
9
+ `1.3.1` is a verification-readiness release:
10
10
 
11
+ - **n8n verification readiness**: Added GitHub Actions provenance publishing support for npm releases
12
+ - **Cloud-safe media upload**: Removed host file path reads; media uploads now use n8n binary data only
13
+ - **Standalone package fix**: Removed package imports from the SendIt server codebase
11
14
  - **Refactored architecture**: Monolithic 2,842-line node split into handler-per-resource dispatch map (23 handler modules)
12
15
  - **New resources**: Dead Letter Queue, Audit Log, Conversions
13
16
  - **Expanded resources**: Brand Voice (get/update/delete), Webhooks (list/get/update), AI (reply suggestions, mention summary, feedback)
@@ -49,7 +52,7 @@ Add a **SendIt Trigger** node as the first node in a new workflow. Select events
49
52
 
50
53
  Read content ideas from a spreadsheet, generate AI copy, publish to multiple platforms, and get notified on success.
51
54
 
52
- ## Node Coverage (v1.2.0)
55
+ ## Node Coverage (v1.3.1)
53
56
 
54
57
  ### Trigger
55
58
 
@@ -40,29 +40,29 @@ class SendIt {
40
40
  type: 'options',
41
41
  noDataExpression: true,
42
42
  options: [
43
- { name: '📝 Post', value: 'post' },
44
- { name: '📅 Scheduled Post', value: 'scheduledPost' },
45
- { name: '📎 Media', value: 'media' },
46
- { name: '🤖 AI', value: 'ai' },
47
- { name: '🎨 AI Media', value: 'aiMedia' },
48
- { name: 'đŸ’¯ Content Score', value: 'contentScore' },
49
- { name: 'đŸ“Ŧ Inbox', value: 'inbox' },
50
- { name: '👂 Listening', value: 'listening' },
51
- { name: '👤 Account', value: 'account' },
52
- { name: '📚 Library', value: 'library' },
53
- { name: 'đŸŽ™ī¸ Brand Voice', value: 'brandVoice' },
54
- { name: 'đŸ“Ŗ Campaign', value: 'campaign' },
55
- { name: '✅ Approvals', value: 'approvals' },
56
- { name: '📊 Analytics', value: 'analytics' },
57
- { name: '🔍 Validation', value: 'validation' },
58
- { name: '📈 Conversions', value: 'conversions' },
59
- { name: '🔗 Webhooks', value: 'webhooks' },
60
- { name: '💀 Dead Letter', value: 'deadLetter' },
61
- { name: '📋 Audit Log', value: 'auditLog' },
62
- { name: 'đŸ“Ļ Bulk Schedule', value: 'bulkSchedule' },
63
- { name: '🔌 Connect', value: 'connect' },
64
- { name: 'â„šī¸ Meta', value: 'meta' },
65
- { name: 'âš™ī¸ Advanced', value: 'advanced' },
43
+ { name: 'Post', value: 'post' },
44
+ { name: 'Scheduled Post', value: 'scheduledPost' },
45
+ { name: 'Media', value: 'media' },
46
+ { name: 'AI', value: 'ai' },
47
+ { name: 'AI Media', value: 'aiMedia' },
48
+ { name: 'Content Score', value: 'contentScore' },
49
+ { name: 'Inbox', value: 'inbox' },
50
+ { name: 'Listening', value: 'listening' },
51
+ { name: 'Account', value: 'account' },
52
+ { name: 'Library', value: 'library' },
53
+ { name: 'Brand Voice', value: 'brandVoice' },
54
+ { name: 'Campaign', value: 'campaign' },
55
+ { name: 'Approvals', value: 'approvals' },
56
+ { name: 'Analytics', value: 'analytics' },
57
+ { name: 'Validation', value: 'validation' },
58
+ { name: 'Conversions', value: 'conversions' },
59
+ { name: 'Webhooks', value: 'webhooks' },
60
+ { name: 'Dead Letter', value: 'deadLetter' },
61
+ { name: 'Audit Log', value: 'auditLog' },
62
+ { name: 'Bulk Schedule', value: 'bulkSchedule' },
63
+ { name: 'Connect', value: 'connect' },
64
+ { name: 'Meta', value: 'meta' },
65
+ { name: 'Advanced', value: 'advanced' },
66
66
  ],
67
67
  default: 'post',
68
68
  },
@@ -773,18 +773,6 @@ class SendIt {
773
773
  },
774
774
  description: 'URL to an image or video. Required for Instagram, TikTok, and Pinterest. Optional for LinkedIn, X, Threads, and others.',
775
775
  },
776
- {
777
- displayName: 'Input Mode',
778
- name: 'mediaInputMode',
779
- type: 'options',
780
- options: [
781
- { name: 'Binary Data', value: 'binary' },
782
- { name: 'File Path', value: 'filePath' },
783
- ],
784
- default: 'binary',
785
- displayOptions: { show: { resource: ['media'], operation: ['upload'] } },
786
- description: 'How to provide the media file',
787
- },
788
776
  {
789
777
  displayName: 'Binary Property',
790
778
  name: 'binaryPropertyName',
@@ -794,25 +782,10 @@ class SendIt {
794
782
  show: {
795
783
  resource: ['media'],
796
784
  operation: ['upload'],
797
- mediaInputMode: ['binary'],
798
785
  },
799
786
  },
800
787
  description: 'Name of the binary property containing the file',
801
788
  },
802
- {
803
- displayName: 'File Path',
804
- name: 'filePath',
805
- type: 'string',
806
- default: '',
807
- displayOptions: {
808
- show: {
809
- resource: ['media'],
810
- operation: ['upload'],
811
- mediaInputMode: ['filePath'],
812
- },
813
- },
814
- description: 'Absolute path to the media file',
815
- },
816
789
  {
817
790
  displayName: 'AI Prompt',
818
791
  name: 'aiPrompt',
@@ -9,31 +9,21 @@ exports.PLATFORM_OPTIONS = [
9
9
  { name: 'LinkedIn Page', value: 'linkedin-page' },
10
10
  { name: 'Facebook', value: 'facebook' },
11
11
  { name: 'Instagram', value: 'instagram' },
12
- { name: 'Instagram Standalone', value: 'instagram-standalone' },
13
12
  { name: 'Threads', value: 'threads' },
14
13
  { name: 'Bluesky', value: 'bluesky' },
15
14
  { name: 'Mastodon', value: 'mastodon' },
16
- { name: 'Warpcast', value: 'warpcast' },
17
15
  { name: 'Nostr', value: 'nostr' },
18
- { name: 'VK', value: 'vk' },
19
16
  { name: 'YouTube', value: 'youtube' },
20
17
  { name: 'TikTok', value: 'tiktok' },
21
- { name: 'Reddit', value: 'reddit' },
22
18
  { name: 'Lemmy', value: 'lemmy' },
23
19
  { name: 'Discord', value: 'discord' },
24
20
  { name: 'Slack', value: 'slack' },
25
21
  { name: 'Telegram', value: 'telegram' },
26
22
  { name: 'Pinterest', value: 'pinterest' },
27
23
  { name: 'Dribbble', value: 'dribbble' },
28
- { name: 'Medium', value: 'medium' },
29
24
  { name: 'DEV.to', value: 'devto' },
30
25
  { name: 'Hashnode', value: 'hashnode' },
31
- { name: 'WordPress', value: 'wordpress' },
32
26
  { name: 'Google My Business', value: 'gmb' },
33
- { name: 'Listmonk', value: 'listmonk' },
34
- { name: 'Skool', value: 'skool' },
35
27
  { name: 'Whop', value: 'whop' },
36
- { name: 'Kick', value: 'kick' },
37
- { name: 'Twitch', value: 'twitch' },
38
28
  { name: 'Product Hunt', value: 'producthunt' },
39
29
  ];
@@ -1,70 +1,15 @@
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.handleMedia = void 0;
37
4
  const n8n_workflow_1 = require("n8n-workflow");
38
5
  const helpers_1 = require("../helpers");
39
6
  const handleMedia = async (context, operation, i, optionalHeaders) => {
40
7
  if (operation === 'upload') {
41
- const inputMode = context.getNodeParameter('mediaInputMode', i);
42
- if (inputMode === 'binary') {
43
- const binaryPropertyName = context.getNodeParameter('binaryPropertyName', i);
44
- const binaryData = context.helpers.assertBinaryData(i, binaryPropertyName);
45
- const buffer = await context.helpers.getBinaryDataBuffer(i, binaryPropertyName);
46
- const formData = new FormData();
47
- formData.append('file', new Blob([buffer]), binaryData.fileName || 'upload');
48
- return (0, helpers_1.sendRequest)(context, {
49
- method: 'POST',
50
- url: '/media/upload',
51
- body: formData,
52
- }, optionalHeaders);
53
- }
54
- const filePath = context.getNodeParameter('filePath', i);
55
- const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
56
- const path = await Promise.resolve().then(() => __importStar(require('path')));
57
- const resolved = path.resolve(filePath);
58
- try {
59
- await fs.access(resolved);
60
- }
61
- catch {
62
- throw new n8n_workflow_1.NodeOperationError(context.getNode(), `File not found: ${resolved}`);
63
- }
64
- const fileBuffer = await fs.readFile(resolved);
65
- const fileName = path.basename(resolved);
8
+ const binaryPropertyName = context.getNodeParameter('binaryPropertyName', i);
9
+ const binaryData = context.helpers.assertBinaryData(i, binaryPropertyName);
10
+ const buffer = await context.helpers.getBinaryDataBuffer(i, binaryPropertyName);
66
11
  const formData = new FormData();
67
- formData.append('file', new Blob([fileBuffer]), fileName);
12
+ formData.append('file', new Blob([buffer]), binaryData.fileName || 'upload');
68
13
  return (0, helpers_1.sendRequest)(context, {
69
14
  method: 'POST',
70
15
  url: '/media/upload',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-sendit",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "n8n community node for SendIt - Multi-platform social media publishing",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -44,6 +44,7 @@
44
44
  ],
45
45
  "n8n": {
46
46
  "n8nNodesApiVersion": 1,
47
+ "strict": true,
47
48
  "credentials": [
48
49
  "dist/credentials/SendItApi.credentials.js"
49
50
  ],
@@ -53,9 +54,10 @@
53
54
  ]
54
55
  },
55
56
  "devDependencies": {
57
+ "@n8n/node-cli": "^0.29.1",
58
+ "@types/node": "^20.10.0",
56
59
  "@typescript-eslint/eslint-plugin": "^8.19.0",
57
60
  "@typescript-eslint/parser": "^8.19.0",
58
- "@types/node": "^20.10.0",
59
61
  "eslint": "^9.17.0",
60
62
  "n8n-workflow": "^1.0.0",
61
63
  "prettier": "^3.1.0",