@operor/provider-mock 0.1.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.
@@ -0,0 +1,45 @@
1
+ import EventEmitter from "eventemitter3";
2
+ import { MessageProvider, OutgoingMessage } from "@operor/core";
3
+
4
+ //#region src/MockProvider.d.ts
5
+ interface MockProviderOptions {
6
+ /** Suppress console output. Messages are still captured in sentMessages/receivedMessages. */
7
+ quiet?: boolean;
8
+ /** Label prefix for log lines (e.g. "order-test"). Defaults to "mock". */
9
+ label?: string;
10
+ }
11
+ interface CapturedMessage {
12
+ direction: 'in' | 'out';
13
+ from: string;
14
+ to?: string;
15
+ text: string;
16
+ timestamp: number;
17
+ }
18
+ declare class MockProvider extends EventEmitter implements MessageProvider {
19
+ readonly name = "mock";
20
+ readonly sentMessages: CapturedMessage[];
21
+ readonly receivedMessages: CapturedMessage[];
22
+ private isConnected;
23
+ private messageQueue;
24
+ private quiet;
25
+ private label;
26
+ constructor(options?: MockProviderOptions);
27
+ connect(): Promise<void>;
28
+ disconnect(): Promise<void>;
29
+ sendMessage(to: string, message: OutgoingMessage): Promise<void>;
30
+ /**
31
+ * Simulate receiving a message (for testing)
32
+ */
33
+ simulateIncomingMessage(from: string, text: string): void;
34
+ /**
35
+ * Get connection status
36
+ */
37
+ isActive(): boolean;
38
+ /**
39
+ * Dump full conversation transcript (useful for debugging failed tests).
40
+ */
41
+ dumpTranscript(): string;
42
+ }
43
+ //#endregion
44
+ export { type CapturedMessage, MockProvider, type MockProviderOptions };
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/MockProvider.ts"],"mappings":";;;;UAGiB,mBAAA;;EAEf,KAAA;EAFkC;EAIlC,KAAA;AAAA;AAAA,UAGe,eAAA;EACf,SAAA;EACA,IAAA;EACA,EAAA;EACA,IAAA;EACA,SAAA;AAAA;AAAA,cAGW,YAAA,SAAqB,YAAA,YAAwB,eAAA;EAAA,SACxC,IAAA;EAAA,SACA,YAAA,EAAc,eAAA;EAAA,SACd,gBAAA,EAAkB,eAAA;EAAA,QAC1B,WAAA;EAAA,QACA,YAAA;EAAA,QACA,KAAA;EAAA,QACA,KAAA;cAEI,OAAA,GAAU,mBAAA;EAMhB,OAAA,CAAA,GAAW,OAAA;EAKX,UAAA,CAAA,GAAc,OAAA;EAKd,WAAA,CAAY,EAAA,UAAY,OAAA,EAAS,eAAA,GAAkB,OAAA;EALrC;;;EAqBpB,uBAAA,CAAwB,IAAA,UAAc,IAAA;EAzCkB;;;EAoExD,QAAA,CAAA;EApEwD;;;EA2ExD,cAAA,CAAA;AAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,82 @@
1
+ import EventEmitter from "eventemitter3";
2
+
3
+ //#region src/MockProvider.ts
4
+ var MockProvider = class extends EventEmitter {
5
+ name = "mock";
6
+ sentMessages = [];
7
+ receivedMessages = [];
8
+ isConnected = false;
9
+ messageQueue = [];
10
+ quiet;
11
+ label;
12
+ constructor(options) {
13
+ super();
14
+ this.quiet = options?.quiet ?? false;
15
+ this.label = options?.label ?? "mock";
16
+ }
17
+ async connect() {
18
+ this.isConnected = true;
19
+ if (!this.quiet) console.log(`[${this.label}] connected`);
20
+ }
21
+ async disconnect() {
22
+ this.isConnected = false;
23
+ if (!this.quiet) console.log(`[${this.label}] disconnected`);
24
+ }
25
+ async sendMessage(to, message) {
26
+ if (!this.isConnected) throw new Error("Provider not connected");
27
+ this.sentMessages.push({
28
+ direction: "out",
29
+ from: "agent",
30
+ to,
31
+ text: message.text,
32
+ timestamp: Date.now()
33
+ });
34
+ if (!this.quiet) {
35
+ const preview = message.text.length > 120 ? message.text.slice(0, 120) + "..." : message.text;
36
+ console.log(`[${this.label}] 📤 → ${to}: ${preview}`);
37
+ }
38
+ }
39
+ /**
40
+ * Simulate receiving a message (for testing)
41
+ */
42
+ simulateIncomingMessage(from, text) {
43
+ if (!this.isConnected) throw new Error("Provider not connected");
44
+ const message = {
45
+ id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
46
+ from,
47
+ text,
48
+ timestamp: Date.now(),
49
+ channel: "whatsapp",
50
+ provider: this.name
51
+ };
52
+ this.receivedMessages.push({
53
+ direction: "in",
54
+ from,
55
+ text,
56
+ timestamp: Date.now()
57
+ });
58
+ if (!this.quiet) {
59
+ const preview = text.length > 120 ? text.slice(0, 120) + "..." : text;
60
+ console.log(`[${this.label}] 📥 ← ${from}: ${preview}`);
61
+ }
62
+ this.emit("message", message);
63
+ }
64
+ /**
65
+ * Get connection status
66
+ */
67
+ isActive() {
68
+ return this.isConnected;
69
+ }
70
+ /**
71
+ * Dump full conversation transcript (useful for debugging failed tests).
72
+ */
73
+ dumpTranscript() {
74
+ return [...this.sentMessages, ...this.receivedMessages].sort((a, b) => a.timestamp - b.timestamp).map((m) => {
75
+ return `${m.direction === "in" ? "📥 ←" : "📤 →"} ${m.direction === "in" ? m.from : m.to}: ${m.text}`;
76
+ }).join("\n");
77
+ }
78
+ };
79
+
80
+ //#endregion
81
+ export { MockProvider };
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/MockProvider.ts"],"sourcesContent":["import EventEmitter from 'eventemitter3';\nimport type { MessageProvider, IncomingMessage, OutgoingMessage } from '@operor/core';\n\nexport interface MockProviderOptions {\n /** Suppress console output. Messages are still captured in sentMessages/receivedMessages. */\n quiet?: boolean;\n /** Label prefix for log lines (e.g. \"order-test\"). Defaults to \"mock\". */\n label?: string;\n}\n\nexport interface CapturedMessage {\n direction: 'in' | 'out';\n from: string;\n to?: string;\n text: string;\n timestamp: number;\n}\n\nexport class MockProvider extends EventEmitter implements MessageProvider {\n public readonly name = 'mock';\n public readonly sentMessages: CapturedMessage[] = [];\n public readonly receivedMessages: CapturedMessage[] = [];\n private isConnected = false;\n private messageQueue: IncomingMessage[] = [];\n private quiet: boolean;\n private label: string;\n\n constructor(options?: MockProviderOptions) {\n super();\n this.quiet = options?.quiet ?? false;\n this.label = options?.label ?? 'mock';\n }\n\n async connect(): Promise<void> {\n this.isConnected = true;\n if (!this.quiet) console.log(`[${this.label}] connected`);\n }\n\n async disconnect(): Promise<void> {\n this.isConnected = false;\n if (!this.quiet) console.log(`[${this.label}] disconnected`);\n }\n\n async sendMessage(to: string, message: OutgoingMessage): Promise<void> {\n if (!this.isConnected) {\n throw new Error('Provider not connected');\n }\n\n this.sentMessages.push({ direction: 'out', from: 'agent', to, text: message.text, timestamp: Date.now() });\n\n if (!this.quiet) {\n const preview = message.text.length > 120 ? message.text.slice(0, 120) + '...' : message.text;\n console.log(`[${this.label}] 📤 → ${to}: ${preview}`);\n }\n }\n\n /**\n * Simulate receiving a message (for testing)\n */\n simulateIncomingMessage(from: string, text: string): void {\n if (!this.isConnected) {\n throw new Error('Provider not connected');\n }\n\n const message: IncomingMessage = {\n id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n from,\n text,\n timestamp: Date.now(),\n channel: 'whatsapp',\n provider: this.name,\n };\n\n this.receivedMessages.push({ direction: 'in', from, text, timestamp: Date.now() });\n\n if (!this.quiet) {\n const preview = text.length > 120 ? text.slice(0, 120) + '...' : text;\n console.log(`[${this.label}] 📥 ← ${from}: ${preview}`);\n }\n\n this.emit('message', message);\n }\n\n /**\n * Get connection status\n */\n isActive(): boolean {\n return this.isConnected;\n }\n\n /**\n * Dump full conversation transcript (useful for debugging failed tests).\n */\n dumpTranscript(): string {\n const all = [...this.sentMessages, ...this.receivedMessages]\n .sort((a, b) => a.timestamp - b.timestamp);\n return all.map((m) => {\n const arrow = m.direction === 'in' ? '📥 ←' : '📤 →';\n const who = m.direction === 'in' ? m.from : m.to;\n return `${arrow} ${who}: ${m.text}`;\n }).join('\\n');\n }\n}\n"],"mappings":";;;AAkBA,IAAa,eAAb,cAAkC,aAAwC;CACxE,AAAgB,OAAO;CACvB,AAAgB,eAAkC,EAAE;CACpD,AAAgB,mBAAsC,EAAE;CACxD,AAAQ,cAAc;CACtB,AAAQ,eAAkC,EAAE;CAC5C,AAAQ;CACR,AAAQ;CAER,YAAY,SAA+B;AACzC,SAAO;AACP,OAAK,QAAQ,SAAS,SAAS;AAC/B,OAAK,QAAQ,SAAS,SAAS;;CAGjC,MAAM,UAAyB;AAC7B,OAAK,cAAc;AACnB,MAAI,CAAC,KAAK,MAAO,SAAQ,IAAI,IAAI,KAAK,MAAM,aAAa;;CAG3D,MAAM,aAA4B;AAChC,OAAK,cAAc;AACnB,MAAI,CAAC,KAAK,MAAO,SAAQ,IAAI,IAAI,KAAK,MAAM,gBAAgB;;CAG9D,MAAM,YAAY,IAAY,SAAyC;AACrE,MAAI,CAAC,KAAK,YACR,OAAM,IAAI,MAAM,yBAAyB;AAG3C,OAAK,aAAa,KAAK;GAAE,WAAW;GAAO,MAAM;GAAS;GAAI,MAAM,QAAQ;GAAM,WAAW,KAAK,KAAK;GAAE,CAAC;AAE1G,MAAI,CAAC,KAAK,OAAO;GACf,MAAM,UAAU,QAAQ,KAAK,SAAS,MAAM,QAAQ,KAAK,MAAM,GAAG,IAAI,GAAG,QAAQ,QAAQ;AACzF,WAAQ,IAAI,IAAI,KAAK,MAAM,SAAS,GAAG,IAAI,UAAU;;;;;;CAOzD,wBAAwB,MAAc,MAAoB;AACxD,MAAI,CAAC,KAAK,YACR,OAAM,IAAI,MAAM,yBAAyB;EAG3C,MAAM,UAA2B;GAC/B,IAAI,OAAO,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,OAAO,GAAG,EAAE;GAChE;GACA;GACA,WAAW,KAAK,KAAK;GACrB,SAAS;GACT,UAAU,KAAK;GAChB;AAED,OAAK,iBAAiB,KAAK;GAAE,WAAW;GAAM;GAAM;GAAM,WAAW,KAAK,KAAK;GAAE,CAAC;AAElF,MAAI,CAAC,KAAK,OAAO;GACf,MAAM,UAAU,KAAK,SAAS,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,QAAQ;AACjE,WAAQ,IAAI,IAAI,KAAK,MAAM,SAAS,KAAK,IAAI,UAAU;;AAGzD,OAAK,KAAK,WAAW,QAAQ;;;;;CAM/B,WAAoB;AAClB,SAAO,KAAK;;;;;CAMd,iBAAyB;AAGvB,SAFY,CAAC,GAAG,KAAK,cAAc,GAAG,KAAK,iBAAiB,CACzD,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,UAAU,CACjC,KAAK,MAAM;AAGpB,UAAO,GAFO,EAAE,cAAc,OAAO,SAAS,OAE9B,GADJ,EAAE,cAAc,OAAO,EAAE,OAAO,EAAE,GACvB,IAAI,EAAE;IAC7B,CAAC,KAAK,KAAK"}
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@operor/provider-mock",
3
+ "version": "0.1.0",
4
+ "description": "Mock provider for Agent OS testing",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "dependencies": {
9
+ "eventemitter3": "^5.0.1",
10
+ "@operor/core": "0.1.0"
11
+ },
12
+ "devDependencies": {
13
+ "tsdown": "^0.20.3",
14
+ "typescript": "^5.3.3"
15
+ },
16
+ "scripts": {
17
+ "build": "tsdown",
18
+ "dev": "tsdown --watch"
19
+ }
20
+ }
@@ -0,0 +1,103 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import type { MessageProvider, IncomingMessage, OutgoingMessage } from '@operor/core';
3
+
4
+ export interface MockProviderOptions {
5
+ /** Suppress console output. Messages are still captured in sentMessages/receivedMessages. */
6
+ quiet?: boolean;
7
+ /** Label prefix for log lines (e.g. "order-test"). Defaults to "mock". */
8
+ label?: string;
9
+ }
10
+
11
+ export interface CapturedMessage {
12
+ direction: 'in' | 'out';
13
+ from: string;
14
+ to?: string;
15
+ text: string;
16
+ timestamp: number;
17
+ }
18
+
19
+ export class MockProvider extends EventEmitter implements MessageProvider {
20
+ public readonly name = 'mock';
21
+ public readonly sentMessages: CapturedMessage[] = [];
22
+ public readonly receivedMessages: CapturedMessage[] = [];
23
+ private isConnected = false;
24
+ private messageQueue: IncomingMessage[] = [];
25
+ private quiet: boolean;
26
+ private label: string;
27
+
28
+ constructor(options?: MockProviderOptions) {
29
+ super();
30
+ this.quiet = options?.quiet ?? false;
31
+ this.label = options?.label ?? 'mock';
32
+ }
33
+
34
+ async connect(): Promise<void> {
35
+ this.isConnected = true;
36
+ if (!this.quiet) console.log(`[${this.label}] connected`);
37
+ }
38
+
39
+ async disconnect(): Promise<void> {
40
+ this.isConnected = false;
41
+ if (!this.quiet) console.log(`[${this.label}] disconnected`);
42
+ }
43
+
44
+ async sendMessage(to: string, message: OutgoingMessage): Promise<void> {
45
+ if (!this.isConnected) {
46
+ throw new Error('Provider not connected');
47
+ }
48
+
49
+ this.sentMessages.push({ direction: 'out', from: 'agent', to, text: message.text, timestamp: Date.now() });
50
+
51
+ if (!this.quiet) {
52
+ const preview = message.text.length > 120 ? message.text.slice(0, 120) + '...' : message.text;
53
+ console.log(`[${this.label}] 📤 → ${to}: ${preview}`);
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Simulate receiving a message (for testing)
59
+ */
60
+ simulateIncomingMessage(from: string, text: string): void {
61
+ if (!this.isConnected) {
62
+ throw new Error('Provider not connected');
63
+ }
64
+
65
+ const message: IncomingMessage = {
66
+ id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
67
+ from,
68
+ text,
69
+ timestamp: Date.now(),
70
+ channel: 'whatsapp',
71
+ provider: this.name,
72
+ };
73
+
74
+ this.receivedMessages.push({ direction: 'in', from, text, timestamp: Date.now() });
75
+
76
+ if (!this.quiet) {
77
+ const preview = text.length > 120 ? text.slice(0, 120) + '...' : text;
78
+ console.log(`[${this.label}] 📥 ← ${from}: ${preview}`);
79
+ }
80
+
81
+ this.emit('message', message);
82
+ }
83
+
84
+ /**
85
+ * Get connection status
86
+ */
87
+ isActive(): boolean {
88
+ return this.isConnected;
89
+ }
90
+
91
+ /**
92
+ * Dump full conversation transcript (useful for debugging failed tests).
93
+ */
94
+ dumpTranscript(): string {
95
+ const all = [...this.sentMessages, ...this.receivedMessages]
96
+ .sort((a, b) => a.timestamp - b.timestamp);
97
+ return all.map((m) => {
98
+ const arrow = m.direction === 'in' ? '📥 ←' : '📤 →';
99
+ const who = m.direction === 'in' ? m.from : m.to;
100
+ return `${arrow} ${who}: ${m.text}`;
101
+ }).join('\n');
102
+ }
103
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { MockProvider } from './MockProvider.js';
2
+ export type { MockProviderOptions, CapturedMessage } from './MockProvider.js';
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'tsdown';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm'],
6
+ dts: true,
7
+ clean: true,
8
+ sourcemap: true,
9
+ outExtensions: () => ({ js: '.js', dts: '.d.ts' }),
10
+ });