@astur-mobile/core 0.5.0-beta.3 → 0.5.0-beta.5

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,34 @@
1
+ import type { NetworkCapabilities, NetworkRedactionOptions, NetworkRequestFilter, NetworkRequestRecord } from '@astur-mobile/protocol';
2
+ /**
3
+ * Network observation for Flutter Android, backed by the Dart VM service's
4
+ * `dart:io` HTTP profiler — the same source Flutter DevTools' Network view uses.
5
+ *
6
+ * Coverage is exactly `dart:io`'s HttpClient: that includes `package:http` and
7
+ * Dio's IO path, because both are built on it. It does NOT include a WebView's
8
+ * own requests, native SDKs, platform channels, or any client that opens its
9
+ * own sockets. Callers should read {@link capabilities} rather than assume.
10
+ *
11
+ * Read-only by design. Interception needs an in-app adapter that can hold a
12
+ * request open, which the profiler cannot do — it reports what already
13
+ * happened.
14
+ */
15
+ export declare const DEFAULT_REDACTED_HEADERS: string[];
16
+ /** 64 KiB. Enough for a JSON payload, small enough that a long run cannot blow up. */
17
+ export declare const DEFAULT_MAX_BODY_BYTES: number;
18
+ export declare const FLUTTER_NETWORK_CAPABILITIES: NetworkCapabilities;
19
+ /** Case-insensitive header redaction, applied before a record is ever returned. */
20
+ export declare function redactHeaders(headers: Record<string, unknown> | undefined, redact: string[]): Record<string, string>;
21
+ /** Keeps a body only when it is within budget, and says why when it is not. */
22
+ export declare function applyBodyLimit(body: string | undefined, maxBytes: number): Pick<NetworkRequestRecord, 'responseBody' | 'bodyOmittedReason'>;
23
+ /**
24
+ * Maps the VM profiler's payload onto {@link NetworkRequestRecord}.
25
+ *
26
+ * Every field is read defensively: the Dart SDK owns this shape and has moved
27
+ * fields between versions, so a missing key must degrade one record rather than
28
+ * throw and lose the whole batch.
29
+ */
30
+ export declare function toNetworkRecords(profile: unknown, options: Required<NetworkRedactionOptions>): NetworkRequestRecord[];
31
+ /** Applies a {@link NetworkRequestFilter} to already-collected records. */
32
+ export declare function filterRecords(records: NetworkRequestRecord[], filter: NetworkRequestFilter | undefined): NetworkRequestRecord[];
33
+ export declare function resolveRedactionOptions(options: NetworkRedactionOptions | undefined): Required<NetworkRedactionOptions>;
34
+ //# sourceMappingURL=network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/flutter/network.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,wBAAwB,UAAyD,CAAC;AAE/F,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD,eAAO,MAAM,4BAA4B,EAAE,mBAO1C,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC5C,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,QAAQ,EAAE,MAAM,GACf,IAAI,CAAC,oBAAoB,EAAE,cAAc,GAAG,mBAAmB,CAAC,CAQlE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GACzC,oBAAoB,EAAE,CA4CxB;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAC3B,OAAO,EAAE,oBAAoB,EAAE,EAC/B,MAAM,EAAE,oBAAoB,GAAG,SAAS,GACvC,oBAAoB,EAAE,CAmBxB;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,uBAAuB,GAAG,SAAS,GAC3C,QAAQ,CAAC,uBAAuB,CAAC,CAKnC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Network observation for Flutter Android, backed by the Dart VM service's
3
+ * `dart:io` HTTP profiler — the same source Flutter DevTools' Network view uses.
4
+ *
5
+ * Coverage is exactly `dart:io`'s HttpClient: that includes `package:http` and
6
+ * Dio's IO path, because both are built on it. It does NOT include a WebView's
7
+ * own requests, native SDKs, platform channels, or any client that opens its
8
+ * own sockets. Callers should read {@link capabilities} rather than assume.
9
+ *
10
+ * Read-only by design. Interception needs an in-app adapter that can hold a
11
+ * request open, which the profiler cannot do — it reports what already
12
+ * happened.
13
+ */
14
+ export const DEFAULT_REDACTED_HEADERS = ['authorization', 'cookie', 'set-cookie', 'x-api-key'];
15
+ /** 64 KiB. Enough for a JSON payload, small enough that a long run cannot blow up. */
16
+ export const DEFAULT_MAX_BODY_BYTES = 64 * 1024;
17
+ export const FLUTTER_NETWORK_CAPABILITIES = {
18
+ observe: true,
19
+ intercept: false,
20
+ transports: ['http'],
21
+ responseBodies: true,
22
+ coverage: "dart:io HttpClient traffic (package:http and Dio included); excludes WebView, native SDK, and platform-channel requests",
23
+ adapterRequired: true
24
+ };
25
+ /** Case-insensitive header redaction, applied before a record is ever returned. */
26
+ export function redactHeaders(headers, redact) {
27
+ const lowered = new Set(redact.map((name) => name.toLowerCase()));
28
+ const out = {};
29
+ for (const [key, value] of Object.entries(headers ?? {})) {
30
+ out[key] = lowered.has(key.toLowerCase())
31
+ ? '<redacted>'
32
+ : Array.isArray(value) ? value.join(', ') : String(value);
33
+ }
34
+ return out;
35
+ }
36
+ /** Keeps a body only when it is within budget, and says why when it is not. */
37
+ export function applyBodyLimit(body, maxBytes) {
38
+ if (body === undefined) {
39
+ return { bodyOmittedReason: 'not-captured' };
40
+ }
41
+ if (Buffer.byteLength(body, 'utf8') > maxBytes) {
42
+ return { bodyOmittedReason: 'too-large' };
43
+ }
44
+ return { responseBody: body };
45
+ }
46
+ /**
47
+ * Maps the VM profiler's payload onto {@link NetworkRequestRecord}.
48
+ *
49
+ * Every field is read defensively: the Dart SDK owns this shape and has moved
50
+ * fields between versions, so a missing key must degrade one record rather than
51
+ * throw and lose the whole batch.
52
+ */
53
+ export function toNetworkRecords(profile, options) {
54
+ const requests = profile?.requests;
55
+ if (!Array.isArray(requests)) {
56
+ return [];
57
+ }
58
+ return requests.flatMap((entry) => {
59
+ // Guard the entry itself, not just its fields: a null/non-object row would
60
+ // otherwise throw and take every other record in the batch with it.
61
+ if (typeof entry !== 'object' || entry === null) {
62
+ return [];
63
+ }
64
+ const row = entry;
65
+ const id = row.id === undefined ? undefined : String(row.id);
66
+ const uri = typeof row.uri === 'string' ? row.uri : undefined;
67
+ if (!id || !uri) {
68
+ return [];
69
+ }
70
+ const request = (row.request ?? {});
71
+ const response = (row.response ?? {});
72
+ const startedMicros = Number(row.startTime ?? 0);
73
+ const endMicros = Number(row.endTime ?? 0);
74
+ const errorText = typeof request.error === 'string'
75
+ ? request.error
76
+ : typeof row.error === 'string' ? row.error : undefined;
77
+ return [{
78
+ id,
79
+ transport: 'http',
80
+ method: typeof row.method === 'string' ? row.method.toUpperCase() : 'GET',
81
+ url: uri,
82
+ requestHeaders: redactHeaders(request.headers, options.redactHeaders),
83
+ ...(response.headers
84
+ ? { responseHeaders: redactHeaders(response.headers, options.redactHeaders) }
85
+ : {}),
86
+ ...(response.statusCode === undefined ? {} : { status: Number(response.statusCode) }),
87
+ // The VM reports microseconds since epoch; the public contract is ms.
88
+ startedAt: Math.round(startedMicros / 1000),
89
+ ...(endMicros > startedMicros ? { durationMs: Math.round((endMicros - startedMicros) / 1000) } : {}),
90
+ ...(errorText ? { error: errorText } : {})
91
+ }];
92
+ });
93
+ }
94
+ /** Applies a {@link NetworkRequestFilter} to already-collected records. */
95
+ export function filterRecords(records, filter) {
96
+ if (!filter) {
97
+ return records;
98
+ }
99
+ return records.filter((record) => {
100
+ if (filter.method && record.method.toUpperCase() !== filter.method.toUpperCase()) {
101
+ return false;
102
+ }
103
+ if (filter.transport && record.transport !== filter.transport) {
104
+ return false;
105
+ }
106
+ if (filter.url instanceof RegExp) {
107
+ return filter.url.test(record.url);
108
+ }
109
+ if (typeof filter.url === 'string') {
110
+ return record.url.includes(filter.url);
111
+ }
112
+ return true;
113
+ });
114
+ }
115
+ export function resolveRedactionOptions(options) {
116
+ return {
117
+ redactHeaders: options?.redactHeaders ?? DEFAULT_REDACTED_HEADERS,
118
+ maxBodyBytes: options?.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES
119
+ };
120
+ }
121
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/flutter/network.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ import type { MobileElementSnapshot } from '@astur-mobile/protocol';
2
+ interface RpcResult {
3
+ [key: string]: unknown;
4
+ }
5
+ export interface FlutterVmServiceOptions {
6
+ /** WebSocket URL of the Dart VM service, e.g. ws://127.0.0.1:PORT/TOKEN/ws */
7
+ url: string;
8
+ requestTimeoutMs?: number;
9
+ /** How long to wait for the first completed frame before serving trees. */
10
+ readyTimeoutMs?: number;
11
+ /** Poll interval while waiting for the first completed frame. */
12
+ readyPollMs?: number;
13
+ /** How long the laid-out element set must stay unchanged before the UI is considered settled. */
14
+ readySettleMs?: number;
15
+ /**
16
+ * Total wall-clock budget for retrying an on-device tree walk that lands
17
+ * mid-build (transient build-lock errors).
18
+ *
19
+ * This is deliberately a time budget rather than an attempt count. Each
20
+ * attempt can itself block for up to `requestTimeoutMs`, so `N retries`
21
+ * bounds the worst case at `N * requestTimeoutMs` — with a handful of
22
+ * retries that is already minutes, which silently blows past the caller's
23
+ * own timeout (see `evaluateStringStable`).
24
+ *
25
+ * Defaults to `requestTimeoutMs + 10s`. Setting it below `requestTimeoutMs`
26
+ * caps the first attempt at less than a full request, turning a slow-but-fine
27
+ * tree walk into a timeout.
28
+ */
29
+ evalBudgetMs?: number;
30
+ /** Delay between tree-walk retries. */
31
+ evalRetryDelayMs?: number;
32
+ }
33
+ export declare class FlutterVmService {
34
+ private ws?;
35
+ private nextId;
36
+ private readonly pending;
37
+ private isolateId?;
38
+ private rootLibId?;
39
+ private screen;
40
+ private readonly url;
41
+ private readonly timeoutMs;
42
+ private readonly readyTimeoutMs;
43
+ private readonly readyPollMs;
44
+ private readonly readySettleMs;
45
+ private readonly evalBudgetMs;
46
+ private readonly evalRetryDelayMs;
47
+ constructor(options: FlutterVmServiceOptions);
48
+ private openSocket;
49
+ /**
50
+ * Attaches for network observation only.
51
+ *
52
+ * Deliberately not {@link connect}: that one binds an isolate by evaluating a
53
+ * Dart expression, which needs the expression compiler that `flutter run`
54
+ * attaches. An app launched any other way — `simctl launch` on the iOS
55
+ * simulator, for instance — has a perfectly good VM service with a working
56
+ * HTTP profiler but no compiler, so requiring evaluation rejects a session
57
+ * that can observe traffic fine.
58
+ *
59
+ * Binds on the capability actually needed instead: an isolate that registered
60
+ * the `dart:io` profiler extensions.
61
+ */
62
+ connectForNetwork(): Promise<boolean>;
63
+ connect(): Promise<void>;
64
+ /**
65
+ * Re-binds to the isolate created by a hot restart. `flutter run`'s `R` tears
66
+ * down the running isolate and starts a *new* one. The old isolate lingers in
67
+ * `getVM` for a moment — and is still readable but FROZEN at its last frame —
68
+ * so binding to it makes tree reads return stale UI (taps reach the live app
69
+ * but the tree never reflects them) or, once it dies, an empty tree. Excluding
70
+ * the pre-restart id is what makes resets land on the live isolate.
71
+ */
72
+ reattach(): Promise<boolean>;
73
+ /**
74
+ * Re-checks readiness on the already-bound isolate without re-resolving it.
75
+ * Used by the reset path to re-wait after re-foregrounding a surfaceless engine
76
+ * (a hot restart can come back with a 0x0 view), so callers can retry cheaply
77
+ * instead of paying the isolate-resolution grace window again.
78
+ */
79
+ ensureReady(): Promise<boolean>;
80
+ /**
81
+ * Binds {@link isolateId}/{@link rootLibId} to a live, evaluable isolate.
82
+ *
83
+ * When `previousIsolateId` is given (a hot-restart reattach), an isolate with a
84
+ * *different* id is strongly preferred — that's the replacement; the old one is
85
+ * the frozen/dying predecessor. We only fall back to the same id after a short
86
+ * grace window (covers the rare case where a restart reuses the id) so we don't
87
+ * grab the predecessor before its replacement has registered. Each candidate is
88
+ * validated with a trivial eval, since a dying isolate can still be listed yet
89
+ * reject evaluations.
90
+ */
91
+ private resolveIsolate;
92
+ getTree(): Promise<MobileElementSnapshot>;
93
+ /**
94
+ * Runs the on-device tree walk and rebuilds the flat, parent-annotated output
95
+ * into a nested snapshot tree. Nesting matters because page logic reads a
96
+ * container's subtree (e.g. the counters under a tap-lab card) — a flat list
97
+ * would leave every container childless. Rows are emitted in pre-order, so a
98
+ * parent always precedes its children and the map is fully populated by the
99
+ * time we wire up links.
100
+ */
101
+ private extractChildren;
102
+ /** Dismisses the soft keyboard by clearing the Flutter primary focus. */
103
+ unfocus(): Promise<void>;
104
+ dispose(): Promise<void>;
105
+ private parseRow;
106
+ /**
107
+ * Blocks until the app's UI has settled, so the first read returns fully
108
+ * laid-out bounds rather than zeros.
109
+ *
110
+ * Two phases:
111
+ * 1. Wait for a completed frame (scheduler idle) with a non-zero screen size —
112
+ * captures the real physical size, which is 0x0 until the view lays out.
113
+ * 2. Wait for the laid-out element set to stop changing across consecutive
114
+ * polls. This is necessary because parts of the tree (e.g. a bottom
115
+ * navigation bar) can lay out a frame or two after the first frame, so they
116
+ * report zero bounds immediately after step 1 — tapping such a node would
117
+ * hit the wrong coordinates. The fingerprint keys on which nodes are present
118
+ * and laid out, not their exact bounds, so a continuously-animating app
119
+ * still settles instead of polling until the timeout.
120
+ */
121
+ private waitForReady;
122
+ /** Identity of the laid-out, labelled nodes — present-and-sized, ignoring exact position so animations still settle. Walks the (now nested) tree. */
123
+ private layoutFingerprint;
124
+ /**
125
+ * Evaluates the on-device tree walk, retrying transient build-lock failures.
126
+ *
127
+ * The walk uses `visitChildren`, which throws if it runs while Flutter is mid-build
128
+ * (app startup, route transitions, animations). Those settle within a frame or two,
129
+ * so a short bounded retry makes reads reliable without callers having to sleep.
130
+ */
131
+ private evaluateStringStable;
132
+ private sleep;
133
+ /**
134
+ * Evaluates a Dart expression and returns its full String result (handles VM
135
+ * string truncation). `deadline` caps every RPC this makes, so paging a large
136
+ * tree cannot outlive the caller's retry budget.
137
+ */
138
+ private evaluateString;
139
+ /**
140
+ * Turns on the Dart VM's HTTP profiler for this isolate.
141
+ *
142
+ * Off by default: with it on the VM retains every request (and its body) for
143
+ * the life of the isolate, so it is enabled only when a test asks to observe,
144
+ * and the buffer is cleared between tests.
145
+ */
146
+ enableHttpProfiling(): Promise<void>;
147
+ /** Drops everything the profiler has buffered so far. */
148
+ clearHttpProfile(): Promise<void>;
149
+ /**
150
+ * Returns the profiler's buffered requests, newest state included.
151
+ *
152
+ * The response shape is owned by the Dart SDK and has changed between
153
+ * versions, so callers must treat every field as optional rather than
154
+ * trusting a schema — see `toNetworkRecords` in the Android driver.
155
+ */
156
+ getHttpProfile(): Promise<RpcResult>;
157
+ /** Full detail (including the response body) for one profiled request. */
158
+ getHttpProfileRequest(id: string): Promise<RpcResult>;
159
+ /**
160
+ * Whether this isolate actually registered the dart:io HTTP profiler
161
+ * extensions. They are absent in some builds, so capability is detected at
162
+ * runtime rather than assumed from the platform.
163
+ */
164
+ supportsHttpProfiling(): Promise<boolean>;
165
+ private call;
166
+ private onMessage;
167
+ private failAllPending;
168
+ }
169
+ export {};
170
+ //# sourceMappingURL=vmService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vmService.d.ts","sourceRoot":"","sources":["../../src/flutter/vmService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAyG5E,UAAU,SAAS;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AASD,MAAM,WAAW,uBAAuB;IACtC,8EAA8E;IAC9E,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iGAAiG;IACjG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,EAAE,CAAC,CAAY;IACvB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6G;IACrI,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,MAAM,CAA+C;IAC7D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,OAAO,EAAE,uBAAuB;YAc9B,UAAU;IAYxB;;;;;;;;;;;;OAYG;IACG,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAKrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9B;;;;;;;OAOG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAKlC;;;;;OAKG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC;;;;;;;;;;OAUG;YACW,cAAc;IAmFtB,OAAO,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAiB/C;;;;;;;OAOG;YACW,eAAe;IAyB7B,yEAAyE;IACnE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9B,OAAO,CAAC,QAAQ;IAgChB;;;;;;;;;;;;;;OAcG;YACW,YAAY;IA2D1B,qJAAqJ;IACrJ,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;OAMG;YACW,oBAAoB;IA6ClC,OAAO,CAAC,KAAK;IAIb;;;;OAIG;YACW,cAAc;IAoC5B;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAO1C,yDAAyD;IACnD,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvC;;;;;;OAMG;IACG,cAAc,IAAI,OAAO,CAAC,SAAS,CAAC;IAI1C,0EAA0E;IACpE,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAI3D;;;;OAIG;IACG,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;IAM/C,OAAO,CAAC,IAAI;IAsBZ,OAAO,CAAC,SAAS;IAgCjB,OAAO,CAAC,cAAc;CAOvB"}