@nodetool-ai/base-nodes 0.7.0-rc.23 → 0.8.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.
- package/README.md +21 -0
- package/dist/.nodetool-build-stamp +1 -0
- package/dist/builtin-packs.d.ts +17 -0
- package/dist/builtin-packs.d.ts.map +1 -0
- package/dist/builtin-packs.js +95 -0
- package/dist/builtin-packs.js.map +1 -0
- package/dist/index.d.ts +63 -67
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +186 -173
- package/dist/index.js.map +1 -1
- package/dist/platforms/browser.d.ts +19 -0
- package/dist/platforms/browser.d.ts.map +1 -0
- package/dist/platforms/browser.js +29 -0
- package/dist/platforms/browser.js.map +1 -0
- package/package.json +72 -65
- package/dist/lib/audio-wav.d.ts +0 -66
- package/dist/lib/audio-wav.d.ts.map +0 -1
- package/dist/lib/audio-wav.js +0 -215
- package/dist/lib/audio-wav.js.map +0 -1
- package/dist/nodes/agent-tool-hydration.d.ts +0 -10
- package/dist/nodes/agent-tool-hydration.d.ts.map +0 -1
- package/dist/nodes/agent-tool-hydration.js +0 -43
- package/dist/nodes/agent-tool-hydration.js.map +0 -1
- package/dist/nodes/agents.d.ts +0 -262
- package/dist/nodes/agents.d.ts.map +0 -1
- package/dist/nodes/agents.js +0 -2856
- package/dist/nodes/agents.js.map +0 -1
- package/dist/nodes/anthropic.d.ts +0 -26
- package/dist/nodes/anthropic.d.ts.map +0 -1
- package/dist/nodes/anthropic.js +0 -133
- package/dist/nodes/anthropic.js.map +0 -1
- package/dist/nodes/apify.d.ts +0 -120
- package/dist/nodes/apify.d.ts.map +0 -1
- package/dist/nodes/apify.js +0 -618
- package/dist/nodes/apify.js.map +0 -1
- package/dist/nodes/audio.d.ts +0 -301
- package/dist/nodes/audio.d.ts.map +0 -1
- package/dist/nodes/audio.js +0 -1274
- package/dist/nodes/audio.js.map +0 -1
- package/dist/nodes/code-node.d.ts +0 -34
- package/dist/nodes/code-node.d.ts.map +0 -1
- package/dist/nodes/code-node.js +0 -343
- package/dist/nodes/code-node.js.map +0 -1
- package/dist/nodes/code.d.ts +0 -301
- package/dist/nodes/code.d.ts.map +0 -1
- package/dist/nodes/code.js +0 -850
- package/dist/nodes/code.js.map +0 -1
- package/dist/nodes/compare.d.ts +0 -18
- package/dist/nodes/compare.d.ts.map +0 -1
- package/dist/nodes/compare.js +0 -122
- package/dist/nodes/compare.js.map +0 -1
- package/dist/nodes/constant.d.ts +0 -315
- package/dist/nodes/constant.d.ts.map +0 -1
- package/dist/nodes/constant.js +0 -715
- package/dist/nodes/constant.js.map +0 -1
- package/dist/nodes/control.d.ts +0 -83
- package/dist/nodes/control.d.ts.map +0 -1
- package/dist/nodes/control.js +0 -212
- package/dist/nodes/control.js.map +0 -1
- package/dist/nodes/data.d.ts +0 -369
- package/dist/nodes/data.d.ts.map +0 -1
- package/dist/nodes/data.js +0 -1590
- package/dist/nodes/data.js.map +0 -1
- package/dist/nodes/document.d.ts +0 -134
- package/dist/nodes/document.d.ts.map +0 -1
- package/dist/nodes/document.js +0 -984
- package/dist/nodes/document.js.map +0 -1
- package/dist/nodes/extended-placeholders.d.ts +0 -6
- package/dist/nodes/extended-placeholders.d.ts.map +0 -1
- package/dist/nodes/extended-placeholders.js +0 -19
- package/dist/nodes/extended-placeholders.js.map +0 -1
- package/dist/nodes/gemini.d.ts +0 -110
- package/dist/nodes/gemini.d.ts.map +0 -1
- package/dist/nodes/gemini.js +0 -871
- package/dist/nodes/gemini.js.map +0 -1
- package/dist/nodes/generators.d.ts +0 -84
- package/dist/nodes/generators.d.ts.map +0 -1
- package/dist/nodes/generators.js +0 -968
- package/dist/nodes/generators.js.map +0 -1
- package/dist/nodes/image.d.ts +0 -232
- package/dist/nodes/image.d.ts.map +0 -1
- package/dist/nodes/image.js +0 -1395
- package/dist/nodes/image.js.map +0 -1
- package/dist/nodes/input.d.ts +0 -445
- package/dist/nodes/input.d.ts.map +0 -1
- package/dist/nodes/input.js +0 -1459
- package/dist/nodes/input.js.map +0 -1
- package/dist/nodes/kie-dynamic.d.ts +0 -31
- package/dist/nodes/kie-dynamic.d.ts.map +0 -1
- package/dist/nodes/kie-dynamic.js +0 -270
- package/dist/nodes/kie-dynamic.js.map +0 -1
- package/dist/nodes/lib-audio-dsp.d.ts +0 -85
- package/dist/nodes/lib-audio-dsp.d.ts.map +0 -1
- package/dist/nodes/lib-audio-dsp.js +0 -450
- package/dist/nodes/lib-audio-dsp.js.map +0 -1
- package/dist/nodes/lib-audio-effects.d.ts +0 -116
- package/dist/nodes/lib-audio-effects.d.ts.map +0 -1
- package/dist/nodes/lib-audio-effects.js +0 -905
- package/dist/nodes/lib-audio-effects.js.map +0 -1
- package/dist/nodes/lib-browser.d.ts +0 -99
- package/dist/nodes/lib-browser.d.ts.map +0 -1
- package/dist/nodes/lib-browser.js +0 -692
- package/dist/nodes/lib-browser.js.map +0 -1
- package/dist/nodes/lib-charts.d.ts +0 -20
- package/dist/nodes/lib-charts.d.ts.map +0 -1
- package/dist/nodes/lib-charts.js +0 -245
- package/dist/nodes/lib-charts.js.map +0 -1
- package/dist/nodes/lib-datetime.d.ts +0 -108
- package/dist/nodes/lib-datetime.d.ts.map +0 -1
- package/dist/nodes/lib-datetime.js +0 -421
- package/dist/nodes/lib-datetime.js.map +0 -1
- package/dist/nodes/lib-doc-convert.d.ts +0 -19
- package/dist/nodes/lib-doc-convert.d.ts.map +0 -1
- package/dist/nodes/lib-doc-convert.js +0 -257
- package/dist/nodes/lib-doc-convert.js.map +0 -1
- package/dist/nodes/lib-doc-transform.d.ts +0 -39
- package/dist/nodes/lib-doc-transform.d.ts.map +0 -1
- package/dist/nodes/lib-doc-transform.js +0 -335
- package/dist/nodes/lib-doc-transform.js.map +0 -1
- package/dist/nodes/lib-docx.d.ts +0 -106
- package/dist/nodes/lib-docx.d.ts.map +0 -1
- package/dist/nodes/lib-docx.js +0 -595
- package/dist/nodes/lib-docx.js.map +0 -1
- package/dist/nodes/lib-epub.d.ts +0 -55
- package/dist/nodes/lib-epub.d.ts.map +0 -1
- package/dist/nodes/lib-epub.js +0 -220
- package/dist/nodes/lib-epub.js.map +0 -1
- package/dist/nodes/lib-excel.d.ts +0 -74
- package/dist/nodes/lib-excel.d.ts.map +0 -1
- package/dist/nodes/lib-excel.js +0 -448
- package/dist/nodes/lib-excel.js.map +0 -1
- package/dist/nodes/lib-graphql.d.ts +0 -66
- package/dist/nodes/lib-graphql.d.ts.map +0 -1
- package/dist/nodes/lib-graphql.js +0 -333
- package/dist/nodes/lib-graphql.js.map +0 -1
- package/dist/nodes/lib-grid.d.ts +0 -27
- package/dist/nodes/lib-grid.d.ts.map +0 -1
- package/dist/nodes/lib-grid.js +0 -172
- package/dist/nodes/lib-grid.js.map +0 -1
- package/dist/nodes/lib-html-parse.d.ts +0 -108
- package/dist/nodes/lib-html-parse.d.ts.map +0 -1
- package/dist/nodes/lib-html-parse.js +0 -365
- package/dist/nodes/lib-html-parse.js.map +0 -1
- package/dist/nodes/lib-http.d.ts +0 -98
- package/dist/nodes/lib-http.d.ts.map +0 -1
- package/dist/nodes/lib-http.js +0 -267
- package/dist/nodes/lib-http.js.map +0 -1
- package/dist/nodes/lib-image-color-grading.d.ts +0 -3
- package/dist/nodes/lib-image-color-grading.d.ts.map +0 -1
- package/dist/nodes/lib-image-color-grading.js +0 -1386
- package/dist/nodes/lib-image-color-grading.js.map +0 -1
- package/dist/nodes/lib-image-draw.d.ts +0 -3
- package/dist/nodes/lib-image-draw.d.ts.map +0 -1
- package/dist/nodes/lib-image-draw.js +0 -470
- package/dist/nodes/lib-image-draw.js.map +0 -1
- package/dist/nodes/lib-image-enhance.d.ts +0 -3
- package/dist/nodes/lib-image-enhance.d.ts.map +0 -1
- package/dist/nodes/lib-image-enhance.js +0 -731
- package/dist/nodes/lib-image-enhance.js.map +0 -1
- package/dist/nodes/lib-image-filter.d.ts +0 -3
- package/dist/nodes/lib-image-filter.d.ts.map +0 -1
- package/dist/nodes/lib-image-filter.js +0 -684
- package/dist/nodes/lib-image-filter.js.map +0 -1
- package/dist/nodes/lib-image-utils.d.ts +0 -24
- package/dist/nodes/lib-image-utils.d.ts.map +0 -1
- package/dist/nodes/lib-image-utils.js +0 -150
- package/dist/nodes/lib-image-utils.js.map +0 -1
- package/dist/nodes/lib-mail.d.ts +0 -74
- package/dist/nodes/lib-mail.d.ts.map +0 -1
- package/dist/nodes/lib-mail.js +0 -452
- package/dist/nodes/lib-mail.js.map +0 -1
- package/dist/nodes/lib-markdown.d.ts +0 -70
- package/dist/nodes/lib-markdown.d.ts.map +0 -1
- package/dist/nodes/lib-markdown.js +0 -236
- package/dist/nodes/lib-markdown.js.map +0 -1
- package/dist/nodes/lib-nlp.d.ts +0 -98
- package/dist/nodes/lib-nlp.d.ts.map +0 -1
- package/dist/nodes/lib-nlp.js +0 -374
- package/dist/nodes/lib-nlp.js.map +0 -1
- package/dist/nodes/lib-notion.d.ts +0 -99
- package/dist/nodes/lib-notion.d.ts.map +0 -1
- package/dist/nodes/lib-notion.js +0 -601
- package/dist/nodes/lib-notion.js.map +0 -1
- package/dist/nodes/lib-ocr.d.ts +0 -31
- package/dist/nodes/lib-ocr.d.ts.map +0 -1
- package/dist/nodes/lib-ocr.js +0 -143
- package/dist/nodes/lib-ocr.js.map +0 -1
- package/dist/nodes/lib-os.d.ts +0 -312
- package/dist/nodes/lib-os.d.ts.map +0 -1
- package/dist/nodes/lib-os.js +0 -909
- package/dist/nodes/lib-os.js.map +0 -1
- package/dist/nodes/lib-pdf.d.ts +0 -142
- package/dist/nodes/lib-pdf.d.ts.map +0 -1
- package/dist/nodes/lib-pdf.js +0 -871
- package/dist/nodes/lib-pdf.js.map +0 -1
- package/dist/nodes/lib-pptx.d.ts +0 -29
- package/dist/nodes/lib-pptx.d.ts.map +0 -1
- package/dist/nodes/lib-pptx.js +0 -122
- package/dist/nodes/lib-pptx.js.map +0 -1
- package/dist/nodes/lib-rss.d.ts +0 -31
- package/dist/nodes/lib-rss.d.ts.map +0 -1
- package/dist/nodes/lib-rss.js +0 -163
- package/dist/nodes/lib-rss.js.map +0 -1
- package/dist/nodes/lib-s3.d.ts +0 -112
- package/dist/nodes/lib-s3.d.ts.map +0 -1
- package/dist/nodes/lib-s3.js +0 -521
- package/dist/nodes/lib-s3.js.map +0 -1
- package/dist/nodes/lib-secret.d.ts +0 -15
- package/dist/nodes/lib-secret.d.ts.map +0 -1
- package/dist/nodes/lib-secret.js +0 -42
- package/dist/nodes/lib-secret.js.map +0 -1
- package/dist/nodes/lib-sqlite.d.ts +0 -102
- package/dist/nodes/lib-sqlite.d.ts.map +0 -1
- package/dist/nodes/lib-sqlite.js +0 -532
- package/dist/nodes/lib-sqlite.js.map +0 -1
- package/dist/nodes/lib-supabase.d.ts +0 -86
- package/dist/nodes/lib-supabase.d.ts.map +0 -1
- package/dist/nodes/lib-supabase.js +0 -425
- package/dist/nodes/lib-supabase.js.map +0 -1
- package/dist/nodes/lib-svg.d.ts +0 -199
- package/dist/nodes/lib-svg.d.ts.map +0 -1
- package/dist/nodes/lib-svg.js +0 -1027
- package/dist/nodes/lib-svg.js.map +0 -1
- package/dist/nodes/lib-tensorflow.d.ts +0 -71
- package/dist/nodes/lib-tensorflow.d.ts.map +0 -1
- package/dist/nodes/lib-tensorflow.js +0 -351
- package/dist/nodes/lib-tensorflow.js.map +0 -1
- package/dist/nodes/lib-twilio.d.ts +0 -71
- package/dist/nodes/lib-twilio.d.ts.map +0 -1
- package/dist/nodes/lib-twilio.js +0 -469
- package/dist/nodes/lib-twilio.js.map +0 -1
- package/dist/nodes/lib-validate.d.ts +0 -84
- package/dist/nodes/lib-validate.d.ts.map +0 -1
- package/dist/nodes/lib-validate.js +0 -215
- package/dist/nodes/lib-validate.js.map +0 -1
- package/dist/nodes/lib-video-download.d.ts +0 -26
- package/dist/nodes/lib-video-download.d.ts.map +0 -1
- package/dist/nodes/lib-video-download.js +0 -299
- package/dist/nodes/lib-video-download.js.map +0 -1
- package/dist/nodes/messaging.d.ts +0 -88
- package/dist/nodes/messaging.d.ts.map +0 -1
- package/dist/nodes/messaging.js +0 -418
- package/dist/nodes/messaging.js.map +0 -1
- package/dist/nodes/mistral.d.ts +0 -83
- package/dist/nodes/mistral.d.ts.map +0 -1
- package/dist/nodes/mistral.js +0 -450
- package/dist/nodes/mistral.js.map +0 -1
- package/dist/nodes/model3d/analysis.d.ts +0 -13
- package/dist/nodes/model3d/analysis.d.ts.map +0 -1
- package/dist/nodes/model3d/analysis.js +0 -36
- package/dist/nodes/model3d/analysis.js.map +0 -1
- package/dist/nodes/model3d/base.d.ts +0 -11
- package/dist/nodes/model3d/base.d.ts.map +0 -1
- package/dist/nodes/model3d/base.js +0 -20
- package/dist/nodes/model3d/base.js.map +0 -1
- package/dist/nodes/model3d/boolean-ops.d.ts +0 -2
- package/dist/nodes/model3d/boolean-ops.d.ts.map +0 -1
- package/dist/nodes/model3d/boolean-ops.js +0 -172
- package/dist/nodes/model3d/boolean-ops.js.map +0 -1
- package/dist/nodes/model3d/cleanup.d.ts +0 -47
- package/dist/nodes/model3d/cleanup.d.ts.map +0 -1
- package/dist/nodes/model3d/cleanup.js +0 -136
- package/dist/nodes/model3d/cleanup.js.map +0 -1
- package/dist/nodes/model3d/convert.d.ts +0 -14
- package/dist/nodes/model3d/convert.d.ts.map +0 -1
- package/dist/nodes/model3d/convert.js +0 -64
- package/dist/nodes/model3d/convert.js.map +0 -1
- package/dist/nodes/model3d/defaults.d.ts +0 -34
- package/dist/nodes/model3d/defaults.d.ts.map +0 -1
- package/dist/nodes/model3d/defaults.js +0 -28
- package/dist/nodes/model3d/defaults.js.map +0 -1
- package/dist/nodes/model3d/document-ops.d.ts +0 -4
- package/dist/nodes/model3d/document-ops.d.ts.map +0 -1
- package/dist/nodes/model3d/document-ops.js +0 -40
- package/dist/nodes/model3d/document-ops.js.map +0 -1
- package/dist/nodes/model3d/generation.d.ts +0 -39
- package/dist/nodes/model3d/generation.d.ts.map +0 -1
- package/dist/nodes/model3d/generation.js +0 -179
- package/dist/nodes/model3d/generation.js.map +0 -1
- package/dist/nodes/model3d/glb.d.ts +0 -29
- package/dist/nodes/model3d/glb.d.ts.map +0 -1
- package/dist/nodes/model3d/glb.js +0 -255
- package/dist/nodes/model3d/glb.js.map +0 -1
- package/dist/nodes/model3d/index.d.ts +0 -20
- package/dist/nodes/model3d/index.d.ts.map +0 -1
- package/dist/nodes/model3d/index.js +0 -38
- package/dist/nodes/model3d/index.js.map +0 -1
- package/dist/nodes/model3d/io.d.ts +0 -38
- package/dist/nodes/model3d/io.d.ts.map +0 -1
- package/dist/nodes/model3d/io.js +0 -162
- package/dist/nodes/model3d/io.js.map +0 -1
- package/dist/nodes/model3d/mesh-ops.d.ts +0 -40
- package/dist/nodes/model3d/mesh-ops.d.ts.map +0 -1
- package/dist/nodes/model3d/mesh-ops.js +0 -775
- package/dist/nodes/model3d/mesh-ops.js.map +0 -1
- package/dist/nodes/model3d/nodes.d.ts +0 -2
- package/dist/nodes/model3d/nodes.d.ts.map +0 -1
- package/dist/nodes/model3d/nodes.js +0 -2
- package/dist/nodes/model3d/nodes.js.map +0 -1
- package/dist/nodes/model3d/ops.d.ts +0 -37
- package/dist/nodes/model3d/ops.d.ts.map +0 -1
- package/dist/nodes/model3d/ops.js +0 -137
- package/dist/nodes/model3d/ops.js.map +0 -1
- package/dist/nodes/model3d/transforms.d.ts +0 -49
- package/dist/nodes/model3d/transforms.d.ts.map +0 -1
- package/dist/nodes/model3d/transforms.js +0 -142
- package/dist/nodes/model3d/transforms.js.map +0 -1
- package/dist/nodes/model3d/types.d.ts +0 -81
- package/dist/nodes/model3d/types.d.ts.map +0 -1
- package/dist/nodes/model3d/types.js +0 -2
- package/dist/nodes/model3d/types.js.map +0 -1
- package/dist/nodes/model3d/utils.d.ts +0 -34
- package/dist/nodes/model3d/utils.d.ts.map +0 -1
- package/dist/nodes/model3d/utils.js +0 -185
- package/dist/nodes/model3d/utils.js.map +0 -1
- package/dist/nodes/model3d.d.ts +0 -2
- package/dist/nodes/model3d.d.ts.map +0 -1
- package/dist/nodes/model3d.js +0 -2
- package/dist/nodes/model3d.js.map +0 -1
- package/dist/nodes/openai.d.ts +0 -172
- package/dist/nodes/openai.d.ts.map +0 -1
- package/dist/nodes/openai.js +0 -1294
- package/dist/nodes/openai.js.map +0 -1
- package/dist/nodes/output.d.ts +0 -29
- package/dist/nodes/output.d.ts.map +0 -1
- package/dist/nodes/output.js +0 -87
- package/dist/nodes/output.js.map +0 -1
- package/dist/nodes/sandbox.d.ts +0 -63
- package/dist/nodes/sandbox.d.ts.map +0 -1
- package/dist/nodes/sandbox.js +0 -633
- package/dist/nodes/sandbox.js.map +0 -1
- package/dist/nodes/search.d.ts +0 -117
- package/dist/nodes/search.d.ts.map +0 -1
- package/dist/nodes/search.js +0 -607
- package/dist/nodes/search.js.map +0 -1
- package/dist/nodes/team.d.ts +0 -74
- package/dist/nodes/team.d.ts.map +0 -1
- package/dist/nodes/team.js +0 -309
- package/dist/nodes/team.js.map +0 -1
- package/dist/nodes/text-extra.d.ts +0 -633
- package/dist/nodes/text-extra.d.ts.map +0 -1
- package/dist/nodes/text-extra.js +0 -2226
- package/dist/nodes/text-extra.js.map +0 -1
- package/dist/nodes/tool-agents.d.ts +0 -334
- package/dist/nodes/tool-agents.d.ts.map +0 -1
- package/dist/nodes/tool-agents.js +0 -1861
- package/dist/nodes/tool-agents.js.map +0 -1
- package/dist/nodes/triggers.d.ts +0 -107
- package/dist/nodes/triggers.d.ts.map +0 -1
- package/dist/nodes/triggers.js +0 -706
- package/dist/nodes/triggers.js.map +0 -1
- package/dist/nodes/vector.d.ts +0 -168
- package/dist/nodes/vector.d.ts.map +0 -1
- package/dist/nodes/vector.js +0 -1121
- package/dist/nodes/vector.js.map +0 -1
- package/dist/nodes/video.d.ts +0 -387
- package/dist/nodes/video.d.ts.map +0 -1
- package/dist/nodes/video.js +0 -2383
- package/dist/nodes/video.js.map +0 -1
- package/dist/nodes/workflow.d.ts +0 -24
- package/dist/nodes/workflow.d.ts.map +0 -1
- package/dist/nodes/workflow.js +0 -146
- package/dist/nodes/workflow.js.map +0 -1
- package/dist/nodes/workspace.d.ts +0 -203
- package/dist/nodes/workspace.d.ts.map +0 -1
- package/dist/nodes/workspace.js +0 -795
- package/dist/nodes/workspace.js.map +0 -1
package/dist/nodes/triggers.js
DELETED
|
@@ -1,706 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { BaseNode, prop } from "@nodetool-ai/node-sdk";
|
|
8
|
-
import * as fs from "fs";
|
|
9
|
-
import * as path from "path";
|
|
10
|
-
import * as http from "http";
|
|
11
|
-
import { URL } from "url";
|
|
12
|
-
// Minimum wait time in seconds to prevent tight loops when drift compensation
|
|
13
|
-
// causes wait_time to be near zero.
|
|
14
|
-
const MIN_WAIT_SECONDS = 0.001;
|
|
15
|
-
/**
|
|
16
|
-
* Async queue used by trigger nodes to receive events from external sources
|
|
17
|
-
* (HTTP handlers, file watchers, etc.) and yield them in genProcess().
|
|
18
|
-
*/
|
|
19
|
-
class AsyncQueue {
|
|
20
|
-
_buffer = [];
|
|
21
|
-
_waiters = [];
|
|
22
|
-
_closed = false;
|
|
23
|
-
push(item) {
|
|
24
|
-
if (this._closed)
|
|
25
|
-
return;
|
|
26
|
-
if (this._waiters.length > 0) {
|
|
27
|
-
const resolve = this._waiters.shift();
|
|
28
|
-
resolve(item);
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
this._buffer.push(item);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
async get(timeoutMs) {
|
|
35
|
-
if (this._buffer.length > 0) {
|
|
36
|
-
return this._buffer.shift();
|
|
37
|
-
}
|
|
38
|
-
if (this._closed)
|
|
39
|
-
return null;
|
|
40
|
-
return new Promise((resolve) => {
|
|
41
|
-
let timer;
|
|
42
|
-
const waiterResolve = (value) => {
|
|
43
|
-
if (timer !== undefined)
|
|
44
|
-
clearTimeout(timer);
|
|
45
|
-
resolve(value);
|
|
46
|
-
};
|
|
47
|
-
this._waiters.push(waiterResolve);
|
|
48
|
-
if (timeoutMs !== undefined && timeoutMs > 0) {
|
|
49
|
-
timer = setTimeout(() => {
|
|
50
|
-
const idx = this._waiters.indexOf(waiterResolve);
|
|
51
|
-
if (idx >= 0)
|
|
52
|
-
this._waiters.splice(idx, 1);
|
|
53
|
-
resolve(null);
|
|
54
|
-
}, timeoutMs);
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
close() {
|
|
59
|
-
this._closed = true;
|
|
60
|
-
for (const w of this._waiters) {
|
|
61
|
-
w(null);
|
|
62
|
-
}
|
|
63
|
-
this._waiters.length = 0;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
// ---------------------------------------------------------------------------
|
|
67
|
-
// WaitNode — suspends workflow until timeout
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
export class WaitNode extends BaseNode {
|
|
70
|
-
static nodeType = "nodetool.triggers.Wait";
|
|
71
|
-
static title = "Wait";
|
|
72
|
-
static description = "Node that suspends workflow execution until externally resumed.\n\n" +
|
|
73
|
-
" This node pauses the workflow at this point and waits for an external\n" +
|
|
74
|
-
" signal (via API call) to continue. When resumed, it outputs the input\n" +
|
|
75
|
-
" data merged with any data provided during the resume call.\n\n" +
|
|
76
|
-
" Use cases:\n" +
|
|
77
|
-
" - Human-in-the-loop workflows requiring approval\n" +
|
|
78
|
-
" - Waiting for external processes to complete\n" +
|
|
79
|
-
" - Pausing workflows for manual data entry\n" +
|
|
80
|
-
" - Synchronization points in multi-step processes\n" +
|
|
81
|
-
" - Interactive chatbot-style workflows\n\n" +
|
|
82
|
-
" The workflow is suspended (not running) while waiting, so it doesn't\n" +
|
|
83
|
-
" consume resources. State is persisted and the workflow can be resumed\n" +
|
|
84
|
-
" even after server restarts.";
|
|
85
|
-
static metadataOutputTypes = {
|
|
86
|
-
data: "any",
|
|
87
|
-
resumed_at: "str",
|
|
88
|
-
waited_seconds: "float"
|
|
89
|
-
};
|
|
90
|
-
async process() {
|
|
91
|
-
const timeoutSeconds = Number(this.timeout_seconds ?? 0);
|
|
92
|
-
const inputData = this.input ?? "";
|
|
93
|
-
const start = Date.now();
|
|
94
|
-
if (timeoutSeconds > 0) {
|
|
95
|
-
await new Promise((resolve) => setTimeout(resolve, Math.floor(timeoutSeconds * 1000)));
|
|
96
|
-
}
|
|
97
|
-
const waitedSeconds = (Date.now() - start) / 1000;
|
|
98
|
-
return {
|
|
99
|
-
data: inputData,
|
|
100
|
-
resumed_at: new Date().toISOString(),
|
|
101
|
-
waited_seconds: waitedSeconds
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
__decorate([
|
|
106
|
-
prop({
|
|
107
|
-
type: "int",
|
|
108
|
-
default: 0,
|
|
109
|
-
title: "Timeout Seconds",
|
|
110
|
-
description: "Optional timeout in seconds (0 = wait indefinitely)",
|
|
111
|
-
min: 0
|
|
112
|
-
})
|
|
113
|
-
], WaitNode.prototype, "timeout_seconds", void 0);
|
|
114
|
-
__decorate([
|
|
115
|
-
prop({
|
|
116
|
-
type: "any",
|
|
117
|
-
default: "",
|
|
118
|
-
title: "Input",
|
|
119
|
-
description: "Input data to pass through to the output when resumed"
|
|
120
|
-
})
|
|
121
|
-
], WaitNode.prototype, "input", void 0);
|
|
122
|
-
// ---------------------------------------------------------------------------
|
|
123
|
-
// ManualTriggerNode — waits for externally pushed events via the runner API
|
|
124
|
-
// ---------------------------------------------------------------------------
|
|
125
|
-
export class ManualTriggerNode extends BaseNode {
|
|
126
|
-
static nodeType = "nodetool.triggers.ManualTrigger";
|
|
127
|
-
static title = "Manual Trigger";
|
|
128
|
-
static description = "Trigger node that waits for manual events pushed via the API.\n\n" +
|
|
129
|
-
" This trigger enables interactive workflows where events are pushed\n" +
|
|
130
|
-
" programmatically through the workflow runner's input API. Each event\n" +
|
|
131
|
-
" pushed to the trigger is emitted and processed by the workflow.\n\n" +
|
|
132
|
-
" This trigger is useful for:\n" +
|
|
133
|
-
" - Building chatbot-style workflows\n" +
|
|
134
|
-
" - Interactive processing pipelines\n" +
|
|
135
|
-
" - Manual batch processing\n" +
|
|
136
|
-
" - Testing and debugging workflows";
|
|
137
|
-
static metadataOutputTypes = {
|
|
138
|
-
data: "any",
|
|
139
|
-
timestamp: "str",
|
|
140
|
-
source: "str",
|
|
141
|
-
event_type: "str"
|
|
142
|
-
};
|
|
143
|
-
static isStreamingInput = true;
|
|
144
|
-
static isStreamingOutput = true;
|
|
145
|
-
async process() {
|
|
146
|
-
return {};
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Streaming run: reads events pushed into the inbox via pushInputValue()
|
|
150
|
-
* and emits them downstream. Keeps running until EOS or max_events.
|
|
151
|
-
*/
|
|
152
|
-
async run(inputs, outputs) {
|
|
153
|
-
const maxEvents = Number(this.max_events ?? 0);
|
|
154
|
-
const triggerName = String(this.name ?? "manual_trigger");
|
|
155
|
-
let eventsProcessed = 0;
|
|
156
|
-
for await (const [handle, item] of inputs.any()) {
|
|
157
|
-
if (handle === "__control__")
|
|
158
|
-
continue;
|
|
159
|
-
const data = item;
|
|
160
|
-
const event = {
|
|
161
|
-
data,
|
|
162
|
-
timestamp: new Date().toISOString(),
|
|
163
|
-
source: triggerName,
|
|
164
|
-
event_type: "manual"
|
|
165
|
-
};
|
|
166
|
-
await outputs.emit("data", event.data);
|
|
167
|
-
await outputs.emit("timestamp", event.timestamp);
|
|
168
|
-
await outputs.emit("source", event.source);
|
|
169
|
-
await outputs.emit("event_type", event.event_type);
|
|
170
|
-
eventsProcessed++;
|
|
171
|
-
if (maxEvents > 0 && eventsProcessed >= maxEvents) {
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
__decorate([
|
|
178
|
-
prop({
|
|
179
|
-
type: "int",
|
|
180
|
-
default: 0,
|
|
181
|
-
title: "Max Events",
|
|
182
|
-
description: "Maximum number of events to process (0 = unlimited)",
|
|
183
|
-
min: 0
|
|
184
|
-
})
|
|
185
|
-
], ManualTriggerNode.prototype, "max_events", void 0);
|
|
186
|
-
__decorate([
|
|
187
|
-
prop({
|
|
188
|
-
type: "str",
|
|
189
|
-
default: "manual_trigger",
|
|
190
|
-
title: "Name",
|
|
191
|
-
description: "Name for this trigger (used in API calls)"
|
|
192
|
-
})
|
|
193
|
-
], ManualTriggerNode.prototype, "name", void 0);
|
|
194
|
-
__decorate([
|
|
195
|
-
prop({
|
|
196
|
-
type: "float",
|
|
197
|
-
default: null,
|
|
198
|
-
title: "Timeout Seconds",
|
|
199
|
-
description: "Timeout waiting for events (None = wait forever)",
|
|
200
|
-
min: 0
|
|
201
|
-
})
|
|
202
|
-
], ManualTriggerNode.prototype, "timeout_seconds", void 0);
|
|
203
|
-
// ---------------------------------------------------------------------------
|
|
204
|
-
// IntervalTriggerNode — fires at regular time intervals
|
|
205
|
-
// ---------------------------------------------------------------------------
|
|
206
|
-
export class IntervalTriggerNode extends BaseNode {
|
|
207
|
-
static nodeType = "nodetool.triggers.IntervalTrigger";
|
|
208
|
-
static title = "Interval Trigger";
|
|
209
|
-
static description = "Trigger node that fires at regular time intervals.\n\n" +
|
|
210
|
-
" This trigger emits events at a configured interval, similar to a timer\n" +
|
|
211
|
-
" or scheduler. Each event contains:\n" +
|
|
212
|
-
" - The tick number (how many times the trigger has fired)\n" +
|
|
213
|
-
" - The current timestamp\n" +
|
|
214
|
-
" - The configured interval\n\n" +
|
|
215
|
-
" This trigger is useful for:\n" +
|
|
216
|
-
" - Periodic data collection or polling\n" +
|
|
217
|
-
" - Scheduled batch processing\n" +
|
|
218
|
-
" - Heartbeat or keepalive workflows\n" +
|
|
219
|
-
" - Time-based automation";
|
|
220
|
-
static metadataOutputTypes = {
|
|
221
|
-
tick: "int",
|
|
222
|
-
elapsed_seconds: "float",
|
|
223
|
-
interval_seconds: "float",
|
|
224
|
-
timestamp: "str",
|
|
225
|
-
source: "str",
|
|
226
|
-
event_type: "str"
|
|
227
|
-
};
|
|
228
|
-
static isStreamingOutput = true;
|
|
229
|
-
async process() {
|
|
230
|
-
return {};
|
|
231
|
-
}
|
|
232
|
-
async *genProcess() {
|
|
233
|
-
const intervalMs = Number(this.interval_seconds ?? 60) * 1000;
|
|
234
|
-
const initialDelayMs = Number(this.initial_delay_seconds ?? 0) * 1000;
|
|
235
|
-
const maxEvents = Number(this.max_events ?? 0);
|
|
236
|
-
const emitOnStart = Boolean(this.emit_on_start ?? true);
|
|
237
|
-
const driftCompensation = Boolean(this.include_drift_compensation ?? true);
|
|
238
|
-
const startTime = Date.now();
|
|
239
|
-
let tickCount = 0;
|
|
240
|
-
// Initial delay
|
|
241
|
-
if (initialDelayMs > 0) {
|
|
242
|
-
await new Promise((r) => setTimeout(r, initialDelayMs));
|
|
243
|
-
}
|
|
244
|
-
// Emit on start if configured
|
|
245
|
-
if (emitOnStart) {
|
|
246
|
-
tickCount++;
|
|
247
|
-
yield this._createEvent(tickCount, startTime);
|
|
248
|
-
if (maxEvents > 0 && tickCount >= maxEvents)
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
// Main loop
|
|
252
|
-
while (true) {
|
|
253
|
-
if (driftCompensation) {
|
|
254
|
-
// Calculate next tick time based on start time
|
|
255
|
-
const nextTickMs = tickCount * intervalMs + initialDelayMs;
|
|
256
|
-
const elapsed = Date.now() - startTime;
|
|
257
|
-
const waitMs = Math.max(MIN_WAIT_SECONDS * 1000, nextTickMs - elapsed);
|
|
258
|
-
await new Promise((r) => setTimeout(r, waitMs));
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
await new Promise((r) => setTimeout(r, intervalMs));
|
|
262
|
-
}
|
|
263
|
-
tickCount++;
|
|
264
|
-
yield this._createEvent(tickCount, startTime);
|
|
265
|
-
if (maxEvents > 0 && tickCount >= maxEvents)
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
_createEvent(tick, startTime) {
|
|
270
|
-
return {
|
|
271
|
-
tick,
|
|
272
|
-
elapsed_seconds: (Date.now() - startTime) / 1000,
|
|
273
|
-
interval_seconds: Number(this.interval_seconds ?? 60),
|
|
274
|
-
timestamp: new Date().toISOString(),
|
|
275
|
-
source: "interval",
|
|
276
|
-
event_type: "tick"
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
__decorate([
|
|
281
|
-
prop({
|
|
282
|
-
type: "int",
|
|
283
|
-
default: 0,
|
|
284
|
-
title: "Max Events",
|
|
285
|
-
description: "Maximum number of events to process (0 = unlimited)",
|
|
286
|
-
min: 0
|
|
287
|
-
})
|
|
288
|
-
], IntervalTriggerNode.prototype, "max_events", void 0);
|
|
289
|
-
__decorate([
|
|
290
|
-
prop({
|
|
291
|
-
type: "float",
|
|
292
|
-
default: 60,
|
|
293
|
-
title: "Interval Seconds",
|
|
294
|
-
description: "Interval between triggers in seconds"
|
|
295
|
-
})
|
|
296
|
-
], IntervalTriggerNode.prototype, "interval_seconds", void 0);
|
|
297
|
-
__decorate([
|
|
298
|
-
prop({
|
|
299
|
-
type: "float",
|
|
300
|
-
default: 0,
|
|
301
|
-
title: "Initial Delay Seconds",
|
|
302
|
-
description: "Delay before the first trigger fires",
|
|
303
|
-
min: 0
|
|
304
|
-
})
|
|
305
|
-
], IntervalTriggerNode.prototype, "initial_delay_seconds", void 0);
|
|
306
|
-
__decorate([
|
|
307
|
-
prop({
|
|
308
|
-
type: "bool",
|
|
309
|
-
default: true,
|
|
310
|
-
title: "Emit On Start",
|
|
311
|
-
description: "Whether to emit an event immediately on start"
|
|
312
|
-
})
|
|
313
|
-
], IntervalTriggerNode.prototype, "emit_on_start", void 0);
|
|
314
|
-
__decorate([
|
|
315
|
-
prop({
|
|
316
|
-
type: "bool",
|
|
317
|
-
default: true,
|
|
318
|
-
title: "Include Drift Compensation",
|
|
319
|
-
description: "Compensate for execution time to maintain accurate intervals"
|
|
320
|
-
})
|
|
321
|
-
], IntervalTriggerNode.prototype, "include_drift_compensation", void 0);
|
|
322
|
-
// ---------------------------------------------------------------------------
|
|
323
|
-
// WebhookTriggerNode — starts an HTTP server and yields on each request
|
|
324
|
-
// ---------------------------------------------------------------------------
|
|
325
|
-
export class WebhookTriggerNode extends BaseNode {
|
|
326
|
-
static nodeType = "nodetool.triggers.WebhookTrigger";
|
|
327
|
-
static title = "Webhook Trigger";
|
|
328
|
-
static description = "Trigger node that starts an HTTP server to receive webhook requests.\n\n" +
|
|
329
|
-
" Each incoming HTTP request is emitted as an event containing:\n" +
|
|
330
|
-
" - The request body (parsed as JSON if applicable)\n" +
|
|
331
|
-
" - Request headers\n" +
|
|
332
|
-
" - Query parameters\n" +
|
|
333
|
-
" - HTTP method\n\n" +
|
|
334
|
-
" This trigger is useful for:\n" +
|
|
335
|
-
" - Receiving notifications from external services\n" +
|
|
336
|
-
" - Building API endpoints that trigger workflows\n" +
|
|
337
|
-
" - Integration with third-party webhook providers";
|
|
338
|
-
static metadataOutputTypes = {
|
|
339
|
-
body: "any",
|
|
340
|
-
headers: "dict[str, any]",
|
|
341
|
-
query: "dict[str, any]",
|
|
342
|
-
method: "str",
|
|
343
|
-
path: "str",
|
|
344
|
-
timestamp: "str",
|
|
345
|
-
source: "str",
|
|
346
|
-
event_type: "str"
|
|
347
|
-
};
|
|
348
|
-
static isStreamingOutput = true;
|
|
349
|
-
async process() {
|
|
350
|
-
return {};
|
|
351
|
-
}
|
|
352
|
-
async *genProcess() {
|
|
353
|
-
const port = Number(this.port ?? 8080);
|
|
354
|
-
const webhookPath = String(this.path ?? "/webhook");
|
|
355
|
-
const host = String(this.host ?? "127.0.0.1");
|
|
356
|
-
const allowedMethods = (Array.isArray(this.methods) ? this.methods : ["POST"]).map((m) => m.toUpperCase());
|
|
357
|
-
const secret = String(this.secret ?? "");
|
|
358
|
-
const maxEvents = Number(this.max_events ?? 0);
|
|
359
|
-
const queue = new AsyncQueue();
|
|
360
|
-
// Create HTTP server
|
|
361
|
-
const server = http.createServer(async (req, res) => {
|
|
362
|
-
const reqUrl = new URL(req.url ?? "/", `http://${host}:${port}`);
|
|
363
|
-
// Check path
|
|
364
|
-
if (reqUrl.pathname !== webhookPath) {
|
|
365
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
366
|
-
res.end("Not Found");
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
// Check method
|
|
370
|
-
const method = (req.method ?? "GET").toUpperCase();
|
|
371
|
-
if (!allowedMethods.includes(method)) {
|
|
372
|
-
res.writeHead(405, { "Content-Type": "text/plain" });
|
|
373
|
-
res.end(`Method ${method} not allowed`);
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
// Check secret
|
|
377
|
-
if (secret) {
|
|
378
|
-
const provided = req.headers["x-webhook-secret"] ?? "";
|
|
379
|
-
if (provided !== secret) {
|
|
380
|
-
res.writeHead(401, { "Content-Type": "text/plain" });
|
|
381
|
-
res.end("Invalid secret");
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
// Read body
|
|
386
|
-
const chunks = [];
|
|
387
|
-
for await (const chunk of req) {
|
|
388
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
389
|
-
}
|
|
390
|
-
const rawBody = Buffer.concat(chunks).toString("utf-8");
|
|
391
|
-
let body = rawBody;
|
|
392
|
-
const contentType = req.headers["content-type"] ?? "";
|
|
393
|
-
if (contentType.includes("application/json")) {
|
|
394
|
-
try {
|
|
395
|
-
body = JSON.parse(rawBody);
|
|
396
|
-
}
|
|
397
|
-
catch {
|
|
398
|
-
// keep raw string
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
// Build query params
|
|
402
|
-
const query = {};
|
|
403
|
-
reqUrl.searchParams.forEach((v, k) => {
|
|
404
|
-
query[k] = v;
|
|
405
|
-
});
|
|
406
|
-
queue.push({
|
|
407
|
-
body,
|
|
408
|
-
headers: { ...req.headers },
|
|
409
|
-
query,
|
|
410
|
-
method,
|
|
411
|
-
path: reqUrl.pathname,
|
|
412
|
-
timestamp: new Date().toISOString(),
|
|
413
|
-
source: req.socket.remoteAddress ?? "",
|
|
414
|
-
event_type: "webhook"
|
|
415
|
-
});
|
|
416
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
417
|
-
res.end(JSON.stringify({ status: "accepted" }));
|
|
418
|
-
});
|
|
419
|
-
// Start server
|
|
420
|
-
await new Promise((resolve, reject) => {
|
|
421
|
-
server.on("error", reject);
|
|
422
|
-
server.listen(port, host, () => resolve());
|
|
423
|
-
});
|
|
424
|
-
let eventsProcessed = 0;
|
|
425
|
-
try {
|
|
426
|
-
while (true) {
|
|
427
|
-
const event = await queue.get();
|
|
428
|
-
if (event === null)
|
|
429
|
-
break;
|
|
430
|
-
yield event;
|
|
431
|
-
eventsProcessed++;
|
|
432
|
-
if (maxEvents > 0 && eventsProcessed >= maxEvents)
|
|
433
|
-
break;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
finally {
|
|
437
|
-
// Shut down HTTP server
|
|
438
|
-
await new Promise((resolve) => {
|
|
439
|
-
server.close(() => resolve());
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
__decorate([
|
|
445
|
-
prop({
|
|
446
|
-
type: "int",
|
|
447
|
-
default: 0,
|
|
448
|
-
title: "Max Events",
|
|
449
|
-
description: "Maximum number of events to process (0 = unlimited)",
|
|
450
|
-
min: 0
|
|
451
|
-
})
|
|
452
|
-
], WebhookTriggerNode.prototype, "max_events", void 0);
|
|
453
|
-
__decorate([
|
|
454
|
-
prop({
|
|
455
|
-
type: "int",
|
|
456
|
-
default: 8080,
|
|
457
|
-
title: "Port",
|
|
458
|
-
description: "Port to listen on for webhook requests",
|
|
459
|
-
min: 1,
|
|
460
|
-
max: 65535
|
|
461
|
-
})
|
|
462
|
-
], WebhookTriggerNode.prototype, "port", void 0);
|
|
463
|
-
__decorate([
|
|
464
|
-
prop({
|
|
465
|
-
type: "str",
|
|
466
|
-
default: "/webhook",
|
|
467
|
-
title: "Path",
|
|
468
|
-
description: "URL path to listen on"
|
|
469
|
-
})
|
|
470
|
-
], WebhookTriggerNode.prototype, "path", void 0);
|
|
471
|
-
__decorate([
|
|
472
|
-
prop({
|
|
473
|
-
type: "str",
|
|
474
|
-
default: "127.0.0.1",
|
|
475
|
-
title: "Host",
|
|
476
|
-
description: "Host address to bind to. Use '0.0.0.0' to listen on all interfaces."
|
|
477
|
-
})
|
|
478
|
-
], WebhookTriggerNode.prototype, "host", void 0);
|
|
479
|
-
__decorate([
|
|
480
|
-
prop({
|
|
481
|
-
type: "list[str]",
|
|
482
|
-
default: ["POST"],
|
|
483
|
-
title: "Methods",
|
|
484
|
-
description: "HTTP methods to accept"
|
|
485
|
-
})
|
|
486
|
-
], WebhookTriggerNode.prototype, "methods", void 0);
|
|
487
|
-
__decorate([
|
|
488
|
-
prop({
|
|
489
|
-
type: "str",
|
|
490
|
-
default: "",
|
|
491
|
-
title: "Secret",
|
|
492
|
-
description: "Optional secret for validating requests (checks X-Webhook-Secret header)"
|
|
493
|
-
})
|
|
494
|
-
], WebhookTriggerNode.prototype, "secret", void 0);
|
|
495
|
-
// ---------------------------------------------------------------------------
|
|
496
|
-
// FileWatchTriggerNode — monitors filesystem changes
|
|
497
|
-
// ---------------------------------------------------------------------------
|
|
498
|
-
export class FileWatchTriggerNode extends BaseNode {
|
|
499
|
-
static nodeType = "nodetool.triggers.FileWatchTrigger";
|
|
500
|
-
static title = "File Watch Trigger";
|
|
501
|
-
static description = "Trigger node that monitors filesystem changes.\n\n" +
|
|
502
|
-
" This trigger monitors a directory or file for changes. When a change\n" +
|
|
503
|
-
" is detected, an event is emitted containing:\n" +
|
|
504
|
-
" - The path of the changed file\n" +
|
|
505
|
-
" - The type of change (created, modified, deleted, moved)\n" +
|
|
506
|
-
" - Timestamp of the event\n\n" +
|
|
507
|
-
" This trigger is useful for:\n" +
|
|
508
|
-
" - Processing files as they arrive in a directory\n" +
|
|
509
|
-
" - Triggering workflows on configuration changes\n" +
|
|
510
|
-
" - Building file-based automation pipelines";
|
|
511
|
-
static metadataOutputTypes = {
|
|
512
|
-
event: "str",
|
|
513
|
-
path: "str",
|
|
514
|
-
dest_path: "str",
|
|
515
|
-
is_directory: "bool",
|
|
516
|
-
timestamp: "str"
|
|
517
|
-
};
|
|
518
|
-
static isStreamingOutput = true;
|
|
519
|
-
async process() {
|
|
520
|
-
return {};
|
|
521
|
-
}
|
|
522
|
-
async *genProcess() {
|
|
523
|
-
const watchPath = path.resolve(String(this.path ?? "."));
|
|
524
|
-
const recursive = Boolean(this.recursive ?? false);
|
|
525
|
-
const patterns = Array.isArray(this.patterns)
|
|
526
|
-
? this.patterns
|
|
527
|
-
: ["*"];
|
|
528
|
-
const ignorePatterns = Array.isArray(this.ignore_patterns)
|
|
529
|
-
? this.ignore_patterns
|
|
530
|
-
: [];
|
|
531
|
-
const watchEvents = Array.isArray(this.events)
|
|
532
|
-
? this.events
|
|
533
|
-
: ["created", "modified", "deleted", "moved"];
|
|
534
|
-
const debounceMs = Number(this.debounce_seconds ?? 0.5) * 1000;
|
|
535
|
-
const maxEvents = Number(this.max_events ?? 0);
|
|
536
|
-
// Verify path exists
|
|
537
|
-
if (!fs.existsSync(watchPath)) {
|
|
538
|
-
throw new Error(`Watch path does not exist: ${watchPath}`);
|
|
539
|
-
}
|
|
540
|
-
const queue = new AsyncQueue();
|
|
541
|
-
const lastEvents = new Map();
|
|
542
|
-
// Simple glob matching
|
|
543
|
-
const matchesPattern = (filename, pattern) => {
|
|
544
|
-
if (pattern === "*")
|
|
545
|
-
return true;
|
|
546
|
-
// Convert glob to regex: *.txt -> ^.*\.txt$
|
|
547
|
-
const regex = new RegExp("^" +
|
|
548
|
-
pattern
|
|
549
|
-
.replace(/\./g, "\\.")
|
|
550
|
-
.replace(/\*/g, ".*")
|
|
551
|
-
.replace(/\?/g, ".") +
|
|
552
|
-
"$");
|
|
553
|
-
return regex.test(filename);
|
|
554
|
-
};
|
|
555
|
-
const shouldProcess = (filePath) => {
|
|
556
|
-
const filename = path.basename(filePath);
|
|
557
|
-
// Check ignore patterns
|
|
558
|
-
for (const p of ignorePatterns) {
|
|
559
|
-
if (matchesPattern(filename, p))
|
|
560
|
-
return false;
|
|
561
|
-
}
|
|
562
|
-
// Check include patterns
|
|
563
|
-
for (const p of patterns) {
|
|
564
|
-
if (matchesPattern(filename, p))
|
|
565
|
-
return true;
|
|
566
|
-
}
|
|
567
|
-
return false;
|
|
568
|
-
};
|
|
569
|
-
const debounce = (filePath) => {
|
|
570
|
-
const now = Date.now();
|
|
571
|
-
const last = lastEvents.get(filePath) ?? 0;
|
|
572
|
-
if (now - last < debounceMs)
|
|
573
|
-
return true;
|
|
574
|
-
lastEvents.set(filePath, now);
|
|
575
|
-
return false;
|
|
576
|
-
};
|
|
577
|
-
const emitEvent = (eventType, filePath, isDirectory) => {
|
|
578
|
-
if (!watchEvents.includes(eventType))
|
|
579
|
-
return;
|
|
580
|
-
if (!shouldProcess(filePath))
|
|
581
|
-
return;
|
|
582
|
-
if (debounce(filePath))
|
|
583
|
-
return;
|
|
584
|
-
queue.push({
|
|
585
|
-
event: eventType,
|
|
586
|
-
path: filePath,
|
|
587
|
-
dest_path: "",
|
|
588
|
-
is_directory: isDirectory,
|
|
589
|
-
timestamp: new Date().toISOString()
|
|
590
|
-
});
|
|
591
|
-
};
|
|
592
|
-
// Use fs.watch for filesystem monitoring
|
|
593
|
-
const watchers = [];
|
|
594
|
-
const watchDir = (dir) => {
|
|
595
|
-
try {
|
|
596
|
-
const watcher = fs.watch(dir, { recursive, persistent: true }, (eventType, filename) => {
|
|
597
|
-
if (!filename)
|
|
598
|
-
return;
|
|
599
|
-
const fullPath = path.join(dir, filename);
|
|
600
|
-
const isDir = fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory();
|
|
601
|
-
// fs.watch emits 'rename' for create/delete and 'change' for modify
|
|
602
|
-
if (eventType === "rename") {
|
|
603
|
-
if (fs.existsSync(fullPath)) {
|
|
604
|
-
emitEvent("created", fullPath, isDir);
|
|
605
|
-
}
|
|
606
|
-
else {
|
|
607
|
-
emitEvent("deleted", fullPath, false);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
else if (eventType === "change") {
|
|
611
|
-
emitEvent("modified", fullPath, isDir);
|
|
612
|
-
}
|
|
613
|
-
});
|
|
614
|
-
watchers.push(watcher);
|
|
615
|
-
}
|
|
616
|
-
catch (_err) {
|
|
617
|
-
// Some paths may not be watchable
|
|
618
|
-
}
|
|
619
|
-
};
|
|
620
|
-
watchDir(watchPath);
|
|
621
|
-
let eventsProcessed = 0;
|
|
622
|
-
try {
|
|
623
|
-
while (true) {
|
|
624
|
-
const event = await queue.get();
|
|
625
|
-
if (event === null)
|
|
626
|
-
break;
|
|
627
|
-
yield event;
|
|
628
|
-
eventsProcessed++;
|
|
629
|
-
if (maxEvents > 0 && eventsProcessed >= maxEvents)
|
|
630
|
-
break;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
finally {
|
|
634
|
-
// Close all watchers
|
|
635
|
-
for (const w of watchers) {
|
|
636
|
-
w.close();
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
__decorate([
|
|
642
|
-
prop({
|
|
643
|
-
type: "int",
|
|
644
|
-
default: 0,
|
|
645
|
-
title: "Max Events",
|
|
646
|
-
description: "Maximum number of events to process (0 = unlimited)",
|
|
647
|
-
min: 0
|
|
648
|
-
})
|
|
649
|
-
], FileWatchTriggerNode.prototype, "max_events", void 0);
|
|
650
|
-
__decorate([
|
|
651
|
-
prop({
|
|
652
|
-
type: "str",
|
|
653
|
-
default: ".",
|
|
654
|
-
title: "Path",
|
|
655
|
-
description: "Path to watch (file or directory)"
|
|
656
|
-
})
|
|
657
|
-
], FileWatchTriggerNode.prototype, "path", void 0);
|
|
658
|
-
__decorate([
|
|
659
|
-
prop({
|
|
660
|
-
type: "bool",
|
|
661
|
-
default: false,
|
|
662
|
-
title: "Recursive",
|
|
663
|
-
description: "Watch subdirectories recursively"
|
|
664
|
-
})
|
|
665
|
-
], FileWatchTriggerNode.prototype, "recursive", void 0);
|
|
666
|
-
__decorate([
|
|
667
|
-
prop({
|
|
668
|
-
type: "list[str]",
|
|
669
|
-
default: ["*"],
|
|
670
|
-
title: "Patterns",
|
|
671
|
-
description: "File patterns to watch (e.g., ['*.txt', '*.json'])"
|
|
672
|
-
})
|
|
673
|
-
], FileWatchTriggerNode.prototype, "patterns", void 0);
|
|
674
|
-
__decorate([
|
|
675
|
-
prop({
|
|
676
|
-
type: "list[str]",
|
|
677
|
-
default: [],
|
|
678
|
-
title: "Ignore Patterns",
|
|
679
|
-
description: "File patterns to ignore"
|
|
680
|
-
})
|
|
681
|
-
], FileWatchTriggerNode.prototype, "ignore_patterns", void 0);
|
|
682
|
-
__decorate([
|
|
683
|
-
prop({
|
|
684
|
-
type: "list[str]",
|
|
685
|
-
default: ["created", "modified", "deleted", "moved"],
|
|
686
|
-
title: "Events",
|
|
687
|
-
description: "Types of events to watch for"
|
|
688
|
-
})
|
|
689
|
-
], FileWatchTriggerNode.prototype, "events", void 0);
|
|
690
|
-
__decorate([
|
|
691
|
-
prop({
|
|
692
|
-
type: "float",
|
|
693
|
-
default: 0.5,
|
|
694
|
-
title: "Debounce Seconds",
|
|
695
|
-
description: "Debounce time to avoid duplicate events",
|
|
696
|
-
min: 0
|
|
697
|
-
})
|
|
698
|
-
], FileWatchTriggerNode.prototype, "debounce_seconds", void 0);
|
|
699
|
-
export const TRIGGER_NODES = [
|
|
700
|
-
WaitNode,
|
|
701
|
-
ManualTriggerNode,
|
|
702
|
-
IntervalTriggerNode,
|
|
703
|
-
WebhookTriggerNode,
|
|
704
|
-
FileWatchTriggerNode
|
|
705
|
-
];
|
|
706
|
-
//# sourceMappingURL=triggers.js.map
|