@stepflowjs/trigger-postgres 0.0.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/dist/index.d.ts +67 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Trigger, TriggerHandler } from '@stepflowjs/core';
|
|
2
|
+
|
|
3
|
+
interface PostgresChangeTriggerConfig {
|
|
4
|
+
/** PostgreSQL connection string */
|
|
5
|
+
connectionString: string;
|
|
6
|
+
/** LISTEN/NOTIFY channel name */
|
|
7
|
+
channel: string;
|
|
8
|
+
/** Optional table to watch for changes */
|
|
9
|
+
table?: string;
|
|
10
|
+
/** Operations to watch (if table is specified) */
|
|
11
|
+
operations?: ("INSERT" | "UPDATE" | "DELETE")[];
|
|
12
|
+
}
|
|
13
|
+
interface PostgresChangePayload {
|
|
14
|
+
operation?: "INSERT" | "UPDATE" | "DELETE";
|
|
15
|
+
table?: string;
|
|
16
|
+
old?: Record<string, unknown>;
|
|
17
|
+
new?: Record<string, unknown>;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* PostgreSQL LISTEN/NOTIFY trigger for Stepflow workflows
|
|
22
|
+
*
|
|
23
|
+
* Listens to PostgreSQL NOTIFY events on a specified channel. Optionally creates
|
|
24
|
+
* database triggers to automatically notify on table changes (INSERT, UPDATE, DELETE).
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const trigger = new PostgresChangeTrigger({
|
|
29
|
+
* connectionString: process.env.DATABASE_URL,
|
|
30
|
+
* channel: 'order_changes',
|
|
31
|
+
* table: 'orders',
|
|
32
|
+
* operations: ['INSERT', 'UPDATE'],
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* await trigger.start(async (event) => {
|
|
36
|
+
* await stepflow.trigger('process-order', event.data);
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare class PostgresChangeTrigger implements Trigger<PostgresChangeTriggerConfig> {
|
|
41
|
+
readonly config: PostgresChangeTriggerConfig;
|
|
42
|
+
readonly type = "postgres-change";
|
|
43
|
+
private client?;
|
|
44
|
+
private pool;
|
|
45
|
+
private handler?;
|
|
46
|
+
constructor(config: PostgresChangeTriggerConfig);
|
|
47
|
+
/**
|
|
48
|
+
* Start the trigger with a handler function
|
|
49
|
+
* @param handler Function to call when PostgreSQL notifications are received
|
|
50
|
+
*/
|
|
51
|
+
start(handler: TriggerHandler): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Set up database trigger function and trigger on the specified table
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
private setupTableTrigger;
|
|
57
|
+
/**
|
|
58
|
+
* Stop the trigger and clean up resources
|
|
59
|
+
*/
|
|
60
|
+
stop(): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Health check - verifies database connection
|
|
63
|
+
*/
|
|
64
|
+
healthCheck(): Promise<boolean>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export { type PostgresChangePayload, PostgresChangeTrigger, type PostgresChangeTriggerConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import pg from "pg";
|
|
3
|
+
var { Pool } = pg;
|
|
4
|
+
var PostgresChangeTrigger = class {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
this.pool = new Pool({ connectionString: config.connectionString });
|
|
8
|
+
}
|
|
9
|
+
type = "postgres-change";
|
|
10
|
+
client;
|
|
11
|
+
pool;
|
|
12
|
+
handler;
|
|
13
|
+
/**
|
|
14
|
+
* Start the trigger with a handler function
|
|
15
|
+
* @param handler Function to call when PostgreSQL notifications are received
|
|
16
|
+
*/
|
|
17
|
+
async start(handler) {
|
|
18
|
+
this.handler = handler;
|
|
19
|
+
this.client = await this.pool.connect();
|
|
20
|
+
if (this.config.table) {
|
|
21
|
+
await this.setupTableTrigger();
|
|
22
|
+
}
|
|
23
|
+
await this.client.query(`LISTEN ${this.config.channel}`);
|
|
24
|
+
this.client.on("notification", async (msg) => {
|
|
25
|
+
if (msg.channel === this.config.channel && this.handler) {
|
|
26
|
+
try {
|
|
27
|
+
let payload = {};
|
|
28
|
+
if (msg.payload) {
|
|
29
|
+
try {
|
|
30
|
+
payload = JSON.parse(msg.payload);
|
|
31
|
+
} catch {
|
|
32
|
+
payload = { message: msg.payload };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const event = {
|
|
36
|
+
id: crypto.randomUUID(),
|
|
37
|
+
type: this.type,
|
|
38
|
+
source: this.config.channel,
|
|
39
|
+
data: payload,
|
|
40
|
+
metadata: {
|
|
41
|
+
channel: msg.channel,
|
|
42
|
+
table: this.config.table,
|
|
43
|
+
operation: payload.operation
|
|
44
|
+
},
|
|
45
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
46
|
+
};
|
|
47
|
+
await this.handler(event);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error("Error handling PostgreSQL notification:", error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
this.client.on("error", (error) => {
|
|
54
|
+
console.error("PostgreSQL client error:", error);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set up database trigger function and trigger on the specified table
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
async setupTableTrigger() {
|
|
62
|
+
if (!this.client || !this.config.table) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const {
|
|
66
|
+
table,
|
|
67
|
+
channel,
|
|
68
|
+
operations = ["INSERT", "UPDATE", "DELETE"]
|
|
69
|
+
} = this.config;
|
|
70
|
+
const functionName = `${table}_notify_${channel}`;
|
|
71
|
+
const triggerName = `${table}_trigger_${channel}`;
|
|
72
|
+
try {
|
|
73
|
+
await this.client.query(`
|
|
74
|
+
CREATE OR REPLACE FUNCTION ${functionName}()
|
|
75
|
+
RETURNS trigger AS $$
|
|
76
|
+
DECLARE
|
|
77
|
+
payload json;
|
|
78
|
+
BEGIN
|
|
79
|
+
-- Build JSON payload with operation and row data
|
|
80
|
+
IF (TG_OP = 'DELETE') THEN
|
|
81
|
+
payload = json_build_object(
|
|
82
|
+
'operation', TG_OP,
|
|
83
|
+
'table', TG_TABLE_NAME,
|
|
84
|
+
'old', row_to_json(OLD)
|
|
85
|
+
);
|
|
86
|
+
ELSIF (TG_OP = 'UPDATE') THEN
|
|
87
|
+
payload = json_build_object(
|
|
88
|
+
'operation', TG_OP,
|
|
89
|
+
'table', TG_TABLE_NAME,
|
|
90
|
+
'old', row_to_json(OLD),
|
|
91
|
+
'new', row_to_json(NEW)
|
|
92
|
+
);
|
|
93
|
+
ELSIF (TG_OP = 'INSERT') THEN
|
|
94
|
+
payload = json_build_object(
|
|
95
|
+
'operation', TG_OP,
|
|
96
|
+
'table', TG_TABLE_NAME,
|
|
97
|
+
'new', row_to_json(NEW)
|
|
98
|
+
);
|
|
99
|
+
END IF;
|
|
100
|
+
|
|
101
|
+
-- Send notification
|
|
102
|
+
PERFORM pg_notify('${channel}', payload::text);
|
|
103
|
+
|
|
104
|
+
-- Return appropriate row
|
|
105
|
+
IF (TG_OP = 'DELETE') THEN
|
|
106
|
+
RETURN OLD;
|
|
107
|
+
ELSE
|
|
108
|
+
RETURN NEW;
|
|
109
|
+
END IF;
|
|
110
|
+
END;
|
|
111
|
+
$$ LANGUAGE plpgsql;
|
|
112
|
+
`);
|
|
113
|
+
await this.client.query(`
|
|
114
|
+
DROP TRIGGER IF EXISTS ${triggerName} ON ${table};
|
|
115
|
+
`);
|
|
116
|
+
const triggerOps = operations.join(" OR ");
|
|
117
|
+
await this.client.query(`
|
|
118
|
+
CREATE TRIGGER ${triggerName}
|
|
119
|
+
AFTER ${triggerOps} ON ${table}
|
|
120
|
+
FOR EACH ROW
|
|
121
|
+
EXECUTE FUNCTION ${functionName}();
|
|
122
|
+
`);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error("Error setting up table trigger:", error);
|
|
125
|
+
throw new Error(
|
|
126
|
+
`Failed to set up trigger on table "${table}": ${error.message}`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Stop the trigger and clean up resources
|
|
132
|
+
*/
|
|
133
|
+
async stop() {
|
|
134
|
+
if (this.client) {
|
|
135
|
+
try {
|
|
136
|
+
await this.client.query(`UNLISTEN ${this.config.channel}`);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error("Error during UNLISTEN:", error);
|
|
139
|
+
} finally {
|
|
140
|
+
this.client.release();
|
|
141
|
+
this.client = void 0;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
await this.pool.end();
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error("Error closing pool:", error);
|
|
148
|
+
}
|
|
149
|
+
this.handler = void 0;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Health check - verifies database connection
|
|
153
|
+
*/
|
|
154
|
+
async healthCheck() {
|
|
155
|
+
try {
|
|
156
|
+
await this.pool.query("SELECT 1");
|
|
157
|
+
return true;
|
|
158
|
+
} catch {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
export {
|
|
164
|
+
PostgresChangeTrigger
|
|
165
|
+
};
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Trigger, TriggerHandler, TriggerEvent } from \"@stepflowjs/core\";\nimport pg from \"pg\";\n\nconst { Pool } = pg;\ntype PoolClient = pg.PoolClient;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PostgresChangeTriggerConfig {\n /** PostgreSQL connection string */\n connectionString: string;\n /** LISTEN/NOTIFY channel name */\n channel: string;\n /** Optional table to watch for changes */\n table?: string;\n /** Operations to watch (if table is specified) */\n operations?: (\"INSERT\" | \"UPDATE\" | \"DELETE\")[];\n}\n\nexport interface PostgresChangePayload {\n operation?: \"INSERT\" | \"UPDATE\" | \"DELETE\";\n table?: string;\n old?: Record<string, unknown>;\n new?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n// ============================================================================\n// PostgresChangeTrigger Implementation\n// ============================================================================\n\n/**\n * PostgreSQL LISTEN/NOTIFY trigger for Stepflow workflows\n *\n * Listens to PostgreSQL NOTIFY events on a specified channel. Optionally creates\n * database triggers to automatically notify on table changes (INSERT, UPDATE, DELETE).\n *\n * @example\n * ```typescript\n * const trigger = new PostgresChangeTrigger({\n * connectionString: process.env.DATABASE_URL,\n * channel: 'order_changes',\n * table: 'orders',\n * operations: ['INSERT', 'UPDATE'],\n * });\n *\n * await trigger.start(async (event) => {\n * await stepflow.trigger('process-order', event.data);\n * });\n * ```\n */\nexport class PostgresChangeTrigger implements Trigger<PostgresChangeTriggerConfig> {\n readonly type = \"postgres-change\";\n private client?: PoolClient;\n private pool: pg.Pool;\n private handler?: TriggerHandler;\n\n constructor(readonly config: PostgresChangeTriggerConfig) {\n this.pool = new Pool({ connectionString: config.connectionString });\n }\n\n /**\n * Start the trigger with a handler function\n * @param handler Function to call when PostgreSQL notifications are received\n */\n async start(handler: TriggerHandler): Promise<void> {\n this.handler = handler;\n\n // Connect a dedicated client for LISTEN\n this.client = await this.pool.connect();\n\n // Set up table trigger if table is specified\n if (this.config.table) {\n await this.setupTableTrigger();\n }\n\n // Start listening on the channel\n await this.client.query(`LISTEN ${this.config.channel}`);\n\n // Handle notifications\n this.client.on(\"notification\", async (msg) => {\n if (msg.channel === this.config.channel && this.handler) {\n try {\n // Parse payload (may be JSON or plain text)\n let payload: PostgresChangePayload = {};\n if (msg.payload) {\n try {\n payload = JSON.parse(msg.payload);\n } catch {\n // If not JSON, treat as plain text\n payload = { message: msg.payload };\n }\n }\n\n // Create trigger event\n const event: TriggerEvent = {\n id: crypto.randomUUID(),\n type: this.type,\n source: this.config.channel,\n data: payload,\n metadata: {\n channel: msg.channel,\n table: this.config.table,\n operation: payload.operation,\n },\n timestamp: new Date(),\n };\n\n await this.handler(event);\n } catch (error) {\n console.error(\"Error handling PostgreSQL notification:\", error);\n }\n }\n });\n\n // Handle connection errors\n this.client.on(\"error\", (error) => {\n console.error(\"PostgreSQL client error:\", error);\n });\n }\n\n /**\n * Set up database trigger function and trigger on the specified table\n * @private\n */\n private async setupTableTrigger(): Promise<void> {\n if (!this.client || !this.config.table) {\n return;\n }\n\n const {\n table,\n channel,\n operations = [\"INSERT\", \"UPDATE\", \"DELETE\"],\n } = this.config;\n const functionName = `${table}_notify_${channel}`;\n const triggerName = `${table}_trigger_${channel}`;\n\n try {\n // Create or replace the trigger function\n await this.client.query(`\n CREATE OR REPLACE FUNCTION ${functionName}()\n RETURNS trigger AS $$\n DECLARE\n payload json;\n BEGIN\n -- Build JSON payload with operation and row data\n IF (TG_OP = 'DELETE') THEN\n payload = json_build_object(\n 'operation', TG_OP,\n 'table', TG_TABLE_NAME,\n 'old', row_to_json(OLD)\n );\n ELSIF (TG_OP = 'UPDATE') THEN\n payload = json_build_object(\n 'operation', TG_OP,\n 'table', TG_TABLE_NAME,\n 'old', row_to_json(OLD),\n 'new', row_to_json(NEW)\n );\n ELSIF (TG_OP = 'INSERT') THEN\n payload = json_build_object(\n 'operation', TG_OP,\n 'table', TG_TABLE_NAME,\n 'new', row_to_json(NEW)\n );\n END IF;\n\n -- Send notification\n PERFORM pg_notify('${channel}', payload::text);\n\n -- Return appropriate row\n IF (TG_OP = 'DELETE') THEN\n RETURN OLD;\n ELSE\n RETURN NEW;\n END IF;\n END;\n $$ LANGUAGE plpgsql;\n `);\n\n // Drop existing trigger if it exists\n await this.client.query(`\n DROP TRIGGER IF EXISTS ${triggerName} ON ${table};\n `);\n\n // Create trigger for specified operations\n const triggerOps = operations.join(\" OR \");\n await this.client.query(`\n CREATE TRIGGER ${triggerName}\n AFTER ${triggerOps} ON ${table}\n FOR EACH ROW\n EXECUTE FUNCTION ${functionName}();\n `);\n } catch (error) {\n console.error(\"Error setting up table trigger:\", error);\n throw new Error(\n `Failed to set up trigger on table \"${table}\": ${(error as Error).message}`,\n );\n }\n }\n\n /**\n * Stop the trigger and clean up resources\n */\n async stop(): Promise<void> {\n if (this.client) {\n try {\n // Stop listening\n await this.client.query(`UNLISTEN ${this.config.channel}`);\n } catch (error) {\n console.error(\"Error during UNLISTEN:\", error);\n } finally {\n // Release the client back to the pool\n this.client.release();\n this.client = undefined;\n }\n }\n\n // Close the pool\n try {\n await this.pool.end();\n } catch (error) {\n console.error(\"Error closing pool:\", error);\n }\n\n this.handler = undefined;\n }\n\n /**\n * Health check - verifies database connection\n */\n async healthCheck(): Promise<boolean> {\n try {\n await this.pool.query(\"SELECT 1\");\n return true;\n } catch {\n return false;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stepflowjs/trigger-postgres",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "PostgreSQL LISTEN/NOTIFY trigger for Stepflow",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"pg": "^8.13.0",
|
|
20
|
+
"@stepflowjs/core": "0.0.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/pg": "^8.11.0",
|
|
24
|
+
"tsup": "^8.5.1",
|
|
25
|
+
"vitest": "^4.0.17"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"typescript": "^5.0.0"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"author": "Stepflow Contributors",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://stepflow-production.up.railway.app",
|
|
35
|
+
"directory": "packages/triggers/postgres"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://stepflow-production.up.railway.app",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://stepflow-production.up.railway.app"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"stepflow",
|
|
43
|
+
"trigger",
|
|
44
|
+
"postgres",
|
|
45
|
+
"postgresql",
|
|
46
|
+
"listen",
|
|
47
|
+
"notify",
|
|
48
|
+
"workflow",
|
|
49
|
+
"orchestration"
|
|
50
|
+
],
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup",
|
|
56
|
+
"dev": "tsup --watch",
|
|
57
|
+
"typecheck": "tsc --noEmit",
|
|
58
|
+
"test": "vitest",
|
|
59
|
+
"clean": "rm -rf dist"
|
|
60
|
+
}
|
|
61
|
+
}
|