n8n-nodes-version 0.5.0 → 0.6.0

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
@@ -14,19 +14,16 @@ n8n nodes to check the current installed version, monitor for updates, and fetch
14
14
  ## Features
15
15
 
16
16
  - **Advanced Version Analysis**: Identifies Major, Minor, and Patch updates using SemVer diffing.
17
- - **Enhanced Changelog**: Automatically extracts "Breaking Changes" and "Deprecations" from GitHub release notes.
18
- - **Compatibility Auditing**: Scans local `node_modules` for community nodes and checks compatibility against target n8n versions.
19
- - **Automated Git Backups**: Exports workflows and commits them to a GitHub repository automatically.
20
- - **Granular Triggers**: Filter version updates by SemVer relevance (e.g., only trigger on Major updates).
17
+ - **Enhanced Changelog**: Fetch release notes from GitHub for the latest, current, or any custom version.
21
18
 
22
19
  ## Installation
23
20
 
24
21
  ### via n8n UI (Recommended)
25
22
 
26
- 1. Go to **Settings > Community Nodes**.
27
- 2. Click **Install a community node**.
28
- 3. Enter `n8n-nodes-version` in the text field.
29
- 4. Agree to the risks and click **Install**.
23
+ 1. Go to **Settings > Community Nodes**.
24
+ 2. Click **Install a community node**.
25
+ 3. Enter `n8n-nodes-version` in the text field.
26
+ 4. Agree to the risks and click **Install**.
30
27
 
31
28
  ### via npm (CLI)
32
29
 
@@ -40,15 +37,15 @@ npm install n8n-nodes-version
40
37
 
41
38
  ## Nodes
42
39
 
43
- ### n8n Version Node (v2)
40
+ ### n8n Version Node (v3)
44
41
 
45
- Manages version information, compatibility audits, and backups.
42
+ Manages version information and changelogs.
46
43
 
47
44
  **Resources & Operations:**
48
45
 
49
- - **Version Info**: Get version status (`getInfo`) or fetch release notes (`getChangelog`).
50
- - **Compatibility**: Audit installed community nodes (`audit`).
51
- - **Backup**: Export and push all workflows to Git (`gitBackup`).
46
+ - **Version Info**:
47
+ - **Get Info**: Returns current installed version and checks if a newer version is available.
48
+ - **Get Changelog**: Fetches release notes from GitHub. Supports checking for `Latest`, `Current`, or a `Custom` version string.
52
49
 
53
50
  ### n8n Version Trigger (v2)
54
51
 
@@ -56,8 +53,6 @@ A schedule-based trigger with advanced filtering.
56
53
 
57
54
  **Configuration:**
58
55
 
59
- **Configuration:**
60
-
61
56
  - **Trigger On**: Choose between `Interval` (simple presets) or `Custom Cron Expression`.
62
57
  - **Trigger Condition**: Choose between `Update Available` or `Always`.
63
58
  - **SemVer Level**: Filter triggers by `Major`, `Minor`, or `Patch` update relevance.
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.N8nVersionTrigger = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const cron_1 = require("cron");
4
6
  const VersionUtils_1 = require("../VersionUtils");
5
7
  class N8nVersionTrigger {
6
8
  constructor() {
@@ -9,8 +11,8 @@ class N8nVersionTrigger {
9
11
  name: 'n8nVersionTrigger',
10
12
  icon: 'file:n8n-version.svg',
11
13
  group: ['trigger'],
12
- version: 3,
13
- description: 'Triggers workflow based on n8n version status',
14
+ version: 2,
15
+ description: 'Triggers workflow based on n8n version status using cron schedule',
14
16
  defaults: {
15
17
  name: 'n8n Version Trigger',
16
18
  },
@@ -18,25 +20,65 @@ class N8nVersionTrigger {
18
20
  outputs: ['main'],
19
21
  properties: [
20
22
  {
21
- displayName: 'Trigger Frequency',
23
+ displayName: 'Trigger On',
24
+ name: 'triggerOn',
25
+ type: 'options',
26
+ options: [
27
+ {
28
+ name: 'Interval',
29
+ value: 'interval',
30
+ },
31
+ {
32
+ name: 'Custom Cron Expression',
33
+ value: 'custom',
34
+ },
35
+ ],
36
+ default: 'interval',
37
+ description: 'How to specify the schedule',
38
+ },
39
+ {
40
+ displayName: 'Interval',
22
41
  name: 'interval',
23
42
  type: 'options',
43
+ displayOptions: {
44
+ show: {
45
+ triggerOn: ['interval'],
46
+ },
47
+ },
24
48
  options: [
25
49
  {
26
50
  name: 'Every Minute',
27
- value: 60,
51
+ value: '* * * * *',
28
52
  },
29
53
  {
30
54
  name: 'Every Hour',
31
- value: 3600,
55
+ value: '0 * * * *',
32
56
  },
33
57
  {
34
58
  name: 'Every Day',
35
- value: 86400,
59
+ value: '0 0 * * *',
60
+ },
61
+ {
62
+ name: 'Every Week',
63
+ value: '0 0 * * 0',
36
64
  },
37
65
  ],
38
- default: 3600,
39
- description: 'How often to check for updates (in seconds)',
66
+ default: '0 * * * *',
67
+ description: 'How often to check for updates',
68
+ },
69
+ {
70
+ displayName: 'Cron Expression',
71
+ name: 'cronExpression',
72
+ type: 'string',
73
+ default: '0 * * * *',
74
+ displayOptions: {
75
+ show: {
76
+ triggerOn: ['custom'],
77
+ },
78
+ },
79
+ required: true,
80
+ placeholder: '0 * * * *',
81
+ description: 'Standard cron expression',
40
82
  },
41
83
  {
42
84
  displayName: 'Trigger Condition',
@@ -140,78 +182,90 @@ class N8nVersionTrigger {
140
182
  };
141
183
  }
142
184
  async trigger() {
143
- const intervalSeconds = this.getNodeParameter('interval', 3600);
185
+ const triggerOn = this.getNodeParameter('triggerOn');
186
+ let cronExpression = '';
187
+ if (triggerOn === 'interval') {
188
+ cronExpression = this.getNodeParameter('interval');
189
+ }
190
+ else {
191
+ cronExpression = this.getNodeParameter('cronExpression');
192
+ }
144
193
  const triggerCondition = this.getNodeParameter('triggerCondition');
145
194
  const semverFilter = this.getNodeParameter('semverFilter', 'patch');
146
195
  const ignorePrerelease = this.getNodeParameter('ignorePrerelease', true);
147
196
  const fetchChangelog = this.getNodeParameter('fetchChangelog', false);
148
197
  const changelogVersion = this.getNodeParameter('changelogVersion', 'latest');
149
198
  const stripLinks = this.getNodeParameter('stripLinks', false);
150
- // Initial check immediately? usually triggers wait.
151
- const executeTrigger = async () => {
152
- try {
153
- const { isLatest, currentVersion, latestVersion, updateType, error } = await (0, VersionUtils_1.checkIsLatest)();
154
- if (ignorePrerelease && (latestVersion === null || latestVersion === void 0 ? void 0 : latestVersion.includes('-'))) {
155
- return;
156
- }
157
- let shouldTrigger = false;
158
- if (triggerCondition === 'always') {
159
- shouldTrigger = true;
160
- }
161
- else if (triggerCondition === 'update' && !isLatest) {
162
- if (semverFilter === 'patch') {
163
- shouldTrigger = true;
199
+ let job;
200
+ try {
201
+ job = new cron_1.CronJob(cronExpression, async () => {
202
+ try {
203
+ const { isLatest, currentVersion, latestVersion, updateType, error } = await (0, VersionUtils_1.checkIsLatest)();
204
+ if (ignorePrerelease && (latestVersion === null || latestVersion === void 0 ? void 0 : latestVersion.includes('-'))) {
205
+ return;
164
206
  }
165
- else if (semverFilter === 'minor' && (updateType === 'minor' || updateType === 'major')) {
207
+ let shouldTrigger = false;
208
+ if (triggerCondition === 'always') {
166
209
  shouldTrigger = true;
167
210
  }
168
- else if (semverFilter === 'major' && updateType === 'major') {
169
- shouldTrigger = true;
211
+ else if (triggerCondition === 'update' && !isLatest) {
212
+ if (semverFilter === 'patch') {
213
+ shouldTrigger = true;
214
+ }
215
+ else if (semverFilter === 'minor' && (updateType === 'minor' || updateType === 'major')) {
216
+ shouldTrigger = true;
217
+ }
218
+ else if (semverFilter === 'major' && updateType === 'major') {
219
+ shouldTrigger = true;
220
+ }
170
221
  }
171
- }
172
- if (shouldTrigger) {
173
- const json = {
174
- currentVersion,
175
- latestVersion,
176
- isLatest,
177
- updateType,
178
- error: error || undefined,
179
- triggeredAt: new Date().toISOString(),
180
- triggerCondition,
181
- };
182
- if (fetchChangelog) {
183
- let versionToFetch = changelogVersion === 'latest'
184
- ? (latestVersion || await (0, VersionUtils_1.getLatestN8nVersion)())
185
- : currentVersion;
186
- if (versionToFetch && versionToFetch !== 'unknown') {
187
- const changelogInfo = await (0, VersionUtils_1.getChangelog)(versionToFetch);
188
- json.changelog = changelogInfo.changelog;
189
- json.changelogVersion = changelogInfo.version;
190
- if (changelogInfo.error)
191
- json.changelogError = changelogInfo.error;
192
- if (stripLinks && json.changelog) {
193
- json.changelog = json.changelog.replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1');
222
+ if (shouldTrigger) {
223
+ const json = {
224
+ currentVersion,
225
+ latestVersion,
226
+ isLatest,
227
+ updateType,
228
+ error: error || undefined,
229
+ triggeredAt: new Date().toISOString(),
230
+ triggerCondition,
231
+ };
232
+ if (fetchChangelog) {
233
+ let versionToFetch = changelogVersion === 'latest'
234
+ ? (latestVersion || await (0, VersionUtils_1.getLatestN8nVersion)())
235
+ : currentVersion;
236
+ if (versionToFetch && versionToFetch !== 'unknown') {
237
+ const changelogInfo = await (0, VersionUtils_1.getChangelog)(versionToFetch);
238
+ json.changelog = changelogInfo.changelog;
239
+ json.changelogVersion = changelogInfo.version;
240
+ if (changelogInfo.error)
241
+ json.changelogError = changelogInfo.error;
242
+ if (stripLinks && json.changelog) {
243
+ json.changelog = json.changelog.replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1');
244
+ }
194
245
  }
195
246
  }
247
+ this.emit([
248
+ [
249
+ {
250
+ json,
251
+ },
252
+ ],
253
+ ]);
196
254
  }
197
- this.emit([
198
- [
199
- {
200
- json,
201
- },
202
- ],
203
- ]);
204
255
  }
205
- }
206
- catch (err) {
207
- console.error('[VersionTrigger] Error during check:', err);
208
- }
209
- };
210
- // Run one check immediately? Standards usually say triggers start by waiting, or execute once if "Execute Trigger" logic.
211
- // `setInterval` waits first.
212
- const intervalId = setInterval(executeTrigger, intervalSeconds * 1000);
256
+ catch (err) {
257
+ console.error('[VersionTrigger] Error during cron execution:', err);
258
+ }
259
+ }, null, true);
260
+ }
261
+ catch (err) {
262
+ const errorMessage = err instanceof Error ? err.message : String(err);
263
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid cron expression: ${errorMessage}. Please use standard cron format (e.g., "0 * * * *" for hourly).`);
264
+ }
213
265
  async function closeFunction() {
214
- clearInterval(intervalId);
266
+ if (job) {
267
+ job.stop();
268
+ }
215
269
  }
216
270
  return {
217
271
  closeFunction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-version",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "private": false,
5
5
  "description": "n8n node to check for new n8n versions, view changelogs, and inspect workflows",
6
6
  "keywords": [