@avasapp/agent-bridge 0.5.0 → 0.6.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 +20 -6
- package/dist/adapters/ably.cjs +79 -3
- package/dist/adapters/ably.d.cts +2 -1
- package/dist/adapters/async-storage.cjs +158 -0
- package/dist/adapters/async-storage.d.cts +14 -0
- package/dist/adapters/device.cjs +1110 -0
- package/dist/adapters/device.d.cts +49 -0
- package/dist/adapters/expo-router.cjs +112 -6
- package/dist/adapters/expo-router.d.cts +1 -1
- package/dist/adapters/jotai.cjs +266 -0
- package/dist/adapters/jotai.d.cts +19 -0
- package/dist/adapters/react-native-mmkv.cjs +80 -0
- package/dist/adapters/react-native-mmkv.d.cts +3 -1
- package/dist/adapters/react-native-webview.d.cts +1 -1
- package/dist/adapters/react-navigation.cjs +293 -0
- package/dist/adapters/react-navigation.d.cts +55 -0
- package/dist/adapters/redux.cjs +322 -0
- package/dist/adapters/redux.d.cts +28 -0
- package/dist/adapters/secure-store.cjs +169 -0
- package/dist/adapters/secure-store.d.cts +28 -0
- package/dist/adapters/socket-io.cjs +77 -3
- package/dist/adapters/socket-io.d.cts +2 -1
- package/dist/adapters/tanstack-query.d.cts +1 -1
- package/dist/adapters/zustand.cjs +193 -22
- package/dist/adapters/zustand.d.cts +11 -15
- package/dist/{chunk-3QIG7A5W.js → chunk-Y6QFU5ON.js} +233 -26
- package/dist/cli.js +1383 -255
- package/dist/client/index.cjs +233 -27
- package/dist/client/index.d.ts +67 -4
- package/dist/client/index.js +5 -3
- package/dist/expo/index.d.cts +1 -1
- package/dist/network/index.cjs +320 -73
- package/dist/network/index.d.cts +18 -3
- package/dist/noop/async-storage.cjs +26 -0
- package/dist/noop/device.cjs +26 -0
- package/dist/noop/jotai.cjs +26 -0
- package/dist/noop/react-navigation.cjs +26 -0
- package/dist/noop/realtime.cjs +6 -1
- package/dist/noop/redux.cjs +28 -0
- package/dist/noop/secure-store.cjs +26 -0
- package/dist/realtime/index.cjs +71 -4
- package/dist/realtime/index.d.cts +21 -2
- package/dist/runtime/index.cjs +822 -140
- package/dist/runtime/index.d.cts +2 -2
- package/dist/store-common-j0cHHvBr.d.cts +23 -0
- package/dist/{types-BmpykP1P.d.cts → types-qlwdcGjt.d.cts} +22 -0
- package/entries/async-storage.cjs +9 -0
- package/entries/device.cjs +9 -0
- package/entries/jotai.cjs +9 -0
- package/entries/react-navigation.cjs +9 -0
- package/entries/redux.cjs +9 -0
- package/entries/secure-store.cjs +9 -0
- package/package.json +32 -1
- package/skills/agent-bridge/SKILL.md +39 -8
- package/skills/agent-bridge/references/device.md +21 -0
- package/skills/agent-bridge/references/flows.md +13 -3
- package/skills/agent-bridge/references/network.md +19 -1
- package/skills/agent-bridge/references/realtime.md +1 -1
- package/skills/agent-bridge/references/restore.md +21 -3
- package/skills/agent-bridge/references/screen.md +8 -2
- package/skills/agent-bridge/references/state.md +21 -1
package/dist/network/index.d.cts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import { T as Tools } from '../types-
|
|
1
|
+
import { T as Tools } from '../types-qlwdcGjt.cjs';
|
|
2
2
|
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Which requests a mock answers. A bare string is a URL substring. In the
|
|
5
|
+
* object form every key given must match, and at least one of `url`, `path`,
|
|
6
|
+
* `body` or `graphql` is needed.
|
|
7
|
+
*/
|
|
4
8
|
type MockMatch = string | {
|
|
5
9
|
/** A substring of the URL, a RegExp, or `{ regex }` from JSON. */
|
|
6
|
-
url
|
|
10
|
+
url?: string | RegExp | {
|
|
7
11
|
regex: string;
|
|
8
12
|
flags?: string;
|
|
9
13
|
};
|
|
14
|
+
/** The whole path of the URL on any host, query ignored: "/orders/:id" (one segment) or "/files/*" (the rest). "/orders" does not match "/orders/5/items". */
|
|
15
|
+
path?: string;
|
|
10
16
|
/** Any method when left out. */
|
|
11
17
|
method?: string;
|
|
18
|
+
/** A JSON request body must contain this: objects match key by key, arrays match in length and position, other values are equal. */
|
|
19
|
+
body?: Record<string, unknown> | unknown[];
|
|
20
|
+
/** The GraphQL operationName, from the JSON body or the `?operationName=` query. */
|
|
21
|
+
graphql?: string;
|
|
12
22
|
};
|
|
13
23
|
type MockResponse = {
|
|
14
24
|
/** Defaults to 200. */
|
|
@@ -59,6 +69,9 @@ type LogEntry = {
|
|
|
59
69
|
pending?: boolean;
|
|
60
70
|
requestBody?: string;
|
|
61
71
|
responseBody?: string;
|
|
72
|
+
/** From net.entry only; names are lower case. Credential values are cut unless `{ full: true }`. */
|
|
73
|
+
requestHeaders?: Record<string, string>;
|
|
74
|
+
responseHeaders?: Record<string, string>;
|
|
62
75
|
/** From net.entry: a body shown is only a preview because the whole one was too large or is gone. */
|
|
63
76
|
truncated?: boolean;
|
|
64
77
|
error?: string;
|
|
@@ -128,6 +141,8 @@ declare function strictNetwork(options?: StrictOptions): () => void;
|
|
|
128
141
|
type NetworkToolsOptions = {
|
|
129
142
|
/** Extra URLs never to log or mock: substrings or RegExps. */
|
|
130
143
|
skip?: Array<string | RegExp>;
|
|
144
|
+
/** How many requests `net.log` keeps. Default 100. */
|
|
145
|
+
logSize?: number;
|
|
131
146
|
};
|
|
132
147
|
/** Read the request log and mock responses: `net.*`. */
|
|
133
148
|
declare function networkTools(options?: NetworkToolsOptions): Tools;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/noop/async-storage.ts
|
|
21
|
+
var async_storage_exports = {};
|
|
22
|
+
__export(async_storage_exports, {
|
|
23
|
+
asyncStorageTools: () => asyncStorageTools
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(async_storage_exports);
|
|
26
|
+
var asyncStorageTools = () => ({});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/noop/device.ts
|
|
21
|
+
var device_exports = {};
|
|
22
|
+
__export(device_exports, {
|
|
23
|
+
deviceTools: () => deviceTools
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(device_exports);
|
|
26
|
+
var deviceTools = () => ({});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/noop/jotai.ts
|
|
21
|
+
var jotai_exports = {};
|
|
22
|
+
__export(jotai_exports, {
|
|
23
|
+
jotaiTools: () => jotaiTools
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(jotai_exports);
|
|
26
|
+
var jotaiTools = () => ({});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/noop/react-navigation.ts
|
|
21
|
+
var react_navigation_exports = {};
|
|
22
|
+
__export(react_navigation_exports, {
|
|
23
|
+
navTools: () => navTools
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(react_navigation_exports);
|
|
26
|
+
var navTools = () => ({});
|
package/dist/noop/realtime.cjs
CHANGED
|
@@ -23,7 +23,8 @@ __export(realtime_exports, {
|
|
|
23
23
|
createRealtimeTap: () => createRealtimeTap,
|
|
24
24
|
fakeableConnection: () => fakeableConnection,
|
|
25
25
|
realtimeAdapter: () => realtimeAdapter,
|
|
26
|
-
tapListeners: () => tapListeners
|
|
26
|
+
tapListeners: () => tapListeners,
|
|
27
|
+
tapOutgoing: () => tapOutgoing
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(realtime_exports);
|
|
29
30
|
var createRealtimeTap = () => ({
|
|
@@ -32,9 +33,13 @@ var createRealtimeTap = () => ({
|
|
|
32
33
|
unsubscribe: () => {
|
|
33
34
|
}
|
|
34
35
|
}),
|
|
36
|
+
sent: () => {
|
|
37
|
+
},
|
|
35
38
|
tools: {}
|
|
36
39
|
});
|
|
37
40
|
var tapListeners = () => {
|
|
38
41
|
};
|
|
42
|
+
var tapOutgoing = () => {
|
|
43
|
+
};
|
|
39
44
|
var fakeableConnection = () => void 0;
|
|
40
45
|
var realtimeAdapter = () => () => ({});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/noop/redux.ts
|
|
21
|
+
var redux_exports = {};
|
|
22
|
+
__export(redux_exports, {
|
|
23
|
+
bridgeReducer: () => bridgeReducer,
|
|
24
|
+
reduxTools: () => reduxTools
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(redux_exports);
|
|
27
|
+
var reduxTools = () => ({});
|
|
28
|
+
var bridgeReducer = (reducer) => reducer;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/noop/secure-store.ts
|
|
21
|
+
var secure_store_exports = {};
|
|
22
|
+
__export(secure_store_exports, {
|
|
23
|
+
secureStoreTools: () => secureStoreTools
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(secure_store_exports);
|
|
26
|
+
var secureStoreTools = () => ({});
|
package/dist/realtime/index.cjs
CHANGED
|
@@ -23,7 +23,8 @@ __export(realtime_exports, {
|
|
|
23
23
|
createRealtimeTap: () => createRealtimeTap,
|
|
24
24
|
fakeableConnection: () => fakeableConnection,
|
|
25
25
|
realtimeAdapter: () => realtimeAdapter,
|
|
26
|
-
tapListeners: () => tapListeners
|
|
26
|
+
tapListeners: () => tapListeners,
|
|
27
|
+
tapOutgoing: () => tapOutgoing
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(realtime_exports);
|
|
29
30
|
|
|
@@ -75,6 +76,21 @@ function tapListeners(tap, target, options) {
|
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
}
|
|
79
|
+
function tapOutgoing(tap, target, options) {
|
|
80
|
+
const methods = target;
|
|
81
|
+
for (const name of list(options.methods)) {
|
|
82
|
+
const send = methods[name];
|
|
83
|
+
if (typeof send !== "function") continue;
|
|
84
|
+
methods[name] = function(...args) {
|
|
85
|
+
try {
|
|
86
|
+
const channel = options.skip?.(this) ? void 0 : options.channel(args);
|
|
87
|
+
if (channel !== void 0) tap.sent(channel, options.describe(args));
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
return send.apply(this, args);
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
78
94
|
function fakeableConnection(target, options) {
|
|
79
95
|
const methods = target;
|
|
80
96
|
const events = methods?.[options.events];
|
|
@@ -119,6 +135,46 @@ function realtimeAdapter(install) {
|
|
|
119
135
|
};
|
|
120
136
|
}
|
|
121
137
|
|
|
138
|
+
// src/network/headers.ts
|
|
139
|
+
var SECRET = /auth|cookie|token|secret|session|password|passwd|signature|api-?key|credential|jwt/i;
|
|
140
|
+
|
|
141
|
+
// src/realtime/snapshot.ts
|
|
142
|
+
var MAX_STRING = 2e3;
|
|
143
|
+
var MAX_ITEMS = 50;
|
|
144
|
+
var MAX_DEPTH = 5;
|
|
145
|
+
var isPlain = (v) => {
|
|
146
|
+
const proto = Object.getPrototypeOf(v);
|
|
147
|
+
return proto === Object.prototype || proto === null;
|
|
148
|
+
};
|
|
149
|
+
function snapshot(value, depth = 0) {
|
|
150
|
+
if (typeof value === "string")
|
|
151
|
+
return value.length > MAX_STRING ? `${value.slice(0, MAX_STRING)}\u2026 (+${value.length - MAX_STRING} chars)` : value;
|
|
152
|
+
if (typeof value === "function") return "[function]";
|
|
153
|
+
if (!value || typeof value !== "object") return value;
|
|
154
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer)
|
|
155
|
+
return `[${value.constructor.name} ${value.byteLength} bytes]`;
|
|
156
|
+
if (depth >= MAX_DEPTH) return "[\u2026]";
|
|
157
|
+
if (Array.isArray(value)) {
|
|
158
|
+
const items = value.slice(0, MAX_ITEMS).map((v) => snapshot(v, depth + 1));
|
|
159
|
+
if (value.length > MAX_ITEMS) items.push(`\u2026 (+${value.length - MAX_ITEMS} items)`);
|
|
160
|
+
return items;
|
|
161
|
+
}
|
|
162
|
+
if (value instanceof Date) return value.toISOString();
|
|
163
|
+
if (!isPlain(value)) return `[${value.constructor?.name ?? "object"}]`;
|
|
164
|
+
const out = {};
|
|
165
|
+
for (const key of Object.keys(value).slice(0, MAX_ITEMS))
|
|
166
|
+
out[key] = snapshot(value[key], depth + 1);
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
function redact(value, depth = 0) {
|
|
170
|
+
if (!value || typeof value !== "object" || depth >= MAX_DEPTH + 1) return value;
|
|
171
|
+
if (Array.isArray(value)) return value.map((v) => redact(v, depth + 1));
|
|
172
|
+
const out = {};
|
|
173
|
+
for (const [key, v] of Object.entries(value))
|
|
174
|
+
out[key] = SECRET.test(key) ? "[redacted]" : redact(v, depth + 1);
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
|
|
122
178
|
// src/realtime/tap.ts
|
|
123
179
|
var LOG_SIZE = 50;
|
|
124
180
|
var ALL = "*";
|
|
@@ -162,6 +218,17 @@ function createRealtimeTap(options = {}) {
|
|
|
162
218
|
}
|
|
163
219
|
if (!dropped) entry.deliver(message, ...rest);
|
|
164
220
|
}
|
|
221
|
+
const sent = (channel, summary) => {
|
|
222
|
+
log.push({
|
|
223
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
224
|
+
channel,
|
|
225
|
+
...summary,
|
|
226
|
+
..."data" in summary && { data: snapshot(summary.data) },
|
|
227
|
+
injected: false,
|
|
228
|
+
sent: true
|
|
229
|
+
});
|
|
230
|
+
if (log.length > LOG_SIZE) log.splice(0, log.length - LOG_SIZE);
|
|
231
|
+
};
|
|
165
232
|
const wrap = (channel, listener, wrapOptions = {}) => {
|
|
166
233
|
const entry = {
|
|
167
234
|
deliver: listener,
|
|
@@ -211,11 +278,11 @@ function createRealtimeTap(options = {}) {
|
|
|
211
278
|
}))
|
|
212
279
|
},
|
|
213
280
|
[`${ns}.log`]: {
|
|
214
|
-
description: `Recent messages, real and
|
|
281
|
+
description: `Recent messages, real, injected, and ones the app sent (sent: true) (socket.emit, Ably publish), newest first (last ${LOG_SIZE}). Filter: { channel?, event?, limit?, full? }; clear: true empties the log after reading. Sent messages are copied and cut, and keys like token, password or authorization show [redacted] unless full: true.`,
|
|
215
282
|
run: (filter = {}) => {
|
|
216
283
|
const entries = log.filter(
|
|
217
284
|
(e) => (!filter.channel || e.channel === filter.channel) && (!filter.event || e.event === filter.event)
|
|
218
|
-
).reverse().slice(0, filter.limit ?? 20);
|
|
285
|
+
).reverse().slice(0, filter.limit ?? 20).map((e) => e.sent && !filter.full && "data" in e ? { ...e, data: redact(e.data) } : e);
|
|
219
286
|
if (filter.clear) log.length = 0;
|
|
220
287
|
return entries;
|
|
221
288
|
}
|
|
@@ -276,5 +343,5 @@ function createRealtimeTap(options = {}) {
|
|
|
276
343
|
return { state: faked ?? connection.state(), real: connection.state(), faked: faked !== null };
|
|
277
344
|
}
|
|
278
345
|
};
|
|
279
|
-
return { wrap, tools };
|
|
346
|
+
return { wrap, sent, tools };
|
|
280
347
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as Tools } from '../types-
|
|
1
|
+
import { T as Tools } from '../types-qlwdcGjt.cjs';
|
|
2
2
|
|
|
3
3
|
/** How a message shows up in `realtime.log`. */
|
|
4
4
|
type MessageSummary = {
|
|
@@ -58,6 +58,8 @@ type RealtimeTap<M> = {
|
|
|
58
58
|
listener: (message: M, ...rest: unknown[]) => void;
|
|
59
59
|
unsubscribe: () => void;
|
|
60
60
|
};
|
|
61
|
+
/** Logs a message the app sent, so an agent can check "did the app send X". */
|
|
62
|
+
sent: (channel: string, summary: MessageSummary) => void;
|
|
61
63
|
/** `realtime.*`, or `<namespace>.*`. */
|
|
62
64
|
tools: Tools;
|
|
63
65
|
};
|
|
@@ -67,6 +69,8 @@ type RealtimeLogEntry = MessageSummary & {
|
|
|
67
69
|
injected: boolean;
|
|
68
70
|
/** Why the app didn't get it. */
|
|
69
71
|
dropped?: 'muted' | 'connection';
|
|
72
|
+
/** True for a message the app sent (`socket.emit`, an Ably `publish`), not one it received. */
|
|
73
|
+
sent?: true;
|
|
70
74
|
};
|
|
71
75
|
/**
|
|
72
76
|
* Lets the agent see, fake and drop realtime messages, whatever library
|
|
@@ -98,6 +102,21 @@ type TapListenersOptions<M> = {
|
|
|
98
102
|
* Removing works in every usual form: all, by key, by listener, or both.
|
|
99
103
|
*/
|
|
100
104
|
declare function tapListeners<M>(tap: RealtimeTap<M>, target: object, options: TapListenersOptions<M>): void;
|
|
105
|
+
type TapOutgoingOptions = {
|
|
106
|
+
/** Methods that send, e.g. "emit" or "publish". */
|
|
107
|
+
methods: string | string[];
|
|
108
|
+
/** The channel a call is for, from its arguments. Return undefined to leave the call unlogged. */
|
|
109
|
+
channel: (args: unknown[]) => string | undefined;
|
|
110
|
+
/** What to log for the call. */
|
|
111
|
+
describe: (args: unknown[]) => MessageSummary;
|
|
112
|
+
/** True for a call that repeats one already logged, e.g. socket.io re-sending from its retry queue. */
|
|
113
|
+
skip?: (target: object) => boolean;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Logs what the app sends through `target`'s methods in `realtime.log`
|
|
117
|
+
* (`sent: true`). The call itself always goes through untouched.
|
|
118
|
+
*/
|
|
119
|
+
declare function tapOutgoing(tap: Pick<RealtimeTap<never>, 'sent'>, target: object, options: TapOutgoingOptions): void;
|
|
101
120
|
type FakeableConnectionOptions = {
|
|
102
121
|
/** The property holding the state, e.g. "state" or "connected". */
|
|
103
122
|
property: string;
|
|
@@ -137,4 +156,4 @@ declare function fakeableConnection(target: object | undefined, options: Fakeabl
|
|
|
137
156
|
*/
|
|
138
157
|
declare function realtimeAdapter<C extends object, O extends object>(install: (client: C, options: O) => Pick<RealtimeTap<unknown>, 'tools'>): (client: C, options?: O) => Tools;
|
|
139
158
|
|
|
140
|
-
export { type FakeableConnectionOptions, type MessageSummary, type RealtimeConnection, type RealtimeLogEntry, type RealtimeTap, type RealtimeTapOptions, type TapListenersOptions, type WrapOptions, createRealtimeTap, fakeableConnection, realtimeAdapter, tapListeners };
|
|
159
|
+
export { type FakeableConnectionOptions, type MessageSummary, type RealtimeConnection, type RealtimeLogEntry, type RealtimeTap, type RealtimeTapOptions, type TapListenersOptions, type TapOutgoingOptions, type WrapOptions, createRealtimeTap, fakeableConnection, realtimeAdapter, tapListeners, tapOutgoing };
|