@poe-platform/safe-bash 0.1.744 → 0.1.746
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 +10 -1
- package/dist/image-ast/browser/sharp.d.ts +1 -1
- package/dist/image-ast/index.js +133 -35
- package/dist/image-ast/sharp.d.ts +1 -1
- package/dist/safe-bash/chunks/{chunk-2CO4WCMK.js → chunk-3ZNXN3XO.js} +434 -245
- package/dist/safe-bash/chunks/{chunk-2F7Q532M.js → chunk-4GK4FAT6.js} +3 -3
- package/dist/safe-bash/chunks/{chunk-WCNFCN2G.js → chunk-BS6QFRNX.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-IZZ7KX4E.js → chunk-JCXAGOEK.js} +40 -3
- package/dist/safe-bash/chunks/{chunk-WN7FYUWU.js → chunk-MC2KZY3D.js} +26 -13
- package/dist/safe-bash/chunks/{chunk-I3DOFJSJ.js → chunk-MUWJPSGN.js} +2 -2
- package/dist/safe-bash/chunks/{chunk-7RP6WOWK.js → chunk-OF2PDE3W.js} +2 -2
- package/dist/safe-bash/chunks/{pdf-renderer-3TVUXNBT.js → pdf-renderer-4APIM7F7.js} +2 -2
- package/dist/safe-bash/chunks/{src-5VZS2ZKB.js → src-T2WAWJXF.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-DRCPJVZF.js → chunk-44N2IRVP.js} +17 -5
- package/dist/safe-bash/command-chunks/{chunk-LYKC7WJB.js → chunk-6742OVAC.js} +37 -3
- package/dist/safe-bash/command-chunks/{chunk-BMBXSLVX.js → chunk-6QU5OLPJ.js} +2 -2
- package/dist/safe-bash/command-chunks/{chunk-YHANNN7I.js → chunk-S3BO2NJT.js} +7 -0
- package/dist/safe-bash/commands/basic.d.ts +2 -0
- package/dist/safe-bash/commands/basic.js +236 -9
- package/dist/safe-bash/commands/pr/index.browser.js +1 -1
- package/dist/safe-bash/commands/streams.js +9 -56
- package/dist/safe-bash/commands/table-text/index.js +5 -1
- package/dist/safe-bash/commands/text.js +13 -2
- package/dist/safe-bash/commands/time-env/shared.js +2 -2
- package/dist/safe-bash/commands/time-env/sleep.js +6 -4
- package/dist/safe-bash/commands/timeout/index.d.ts +7 -0
- package/dist/safe-bash/commands/timeout/index.js +52 -32
- package/dist/safe-bash/commands/timeout/scheduler.js +7 -6
- package/dist/safe-bash/core.browser.js +3475 -883
- package/dist/safe-bash/opt-in/commands/shuf/random.js +2 -3
- package/dist/safe-bash/opt-in/shell/extensions/read/index.js +1 -2
- package/dist/safe-bash/opt-in/shell/extensions/trap/index.d.ts +1 -2
- package/dist/safe-bash/opt-in/shell/extensions/trap/index.js +1 -8
- package/dist/safe-bash/playwright/adapter.d.ts +2 -0
- package/dist/safe-bash/playwright/capability-events.d.ts +7 -0
- package/dist/safe-bash/playwright/capability-events.js +11 -3
- package/dist/safe-bash/playwright/controller.d.ts +14 -0
- package/dist/safe-bash/playwright/controller.js +36 -8
- package/dist/safe-bash/playwright/index.d.ts +1 -0
- package/dist/safe-bash/playwright/index.js +1 -0
- package/dist/safe-bash/playwright/private-target-transport.d.ts +1 -0
- package/dist/safe-bash/playwright/private-target-transport.js +21 -21
- package/dist/safe-bash/shell/runtime.d.ts +34 -2
- package/dist/safe-bash/shell/runtime.js +4107 -947
- package/dist/safe-bash/shell/sync-jq-expression.d.ts +6 -0
- package/dist/safe-bash/shell/sync-jq-expression.js +46 -0
- package/dist/safe-bash-command-cal/index.js +32 -12
- package/dist/safe-bash-command-hostname/index.js +22 -7
- package/dist/safe-bash-command-id/index.js +28 -9
- package/dist/safe-bash-command-pandoc/command.js +1 -1
- package/dist/safe-bash-command-pandoc/index.js +1 -1
- package/dist/safe-bash-command-ssconvert/command.d.ts +2 -2
- package/dist/safe-bash-command-ssconvert/contracts.d.ts +4 -0
- package/dist/safe-bash-command-ssconvert/engine.d.ts +2 -2
- package/dist/safe-bash-command-ssconvert/index.js +421 -237
- package/dist/safe-bash-command-whoami/index.js +26 -12
- package/dist/safe-bash-command-wkhtmltopdf/index.js +24 -11
- package/dist/safe-bash-command-wkhtmltopdf/limits.d.ts +1 -1
- package/dist/safe-bash-command-wkhtmltopdf/resources.d.ts +1 -1
- package/dist/safe-bash-query-engine/index.js +3 -3
- package/dist/safe-bash-query-engine/interpreter.js +1 -1
- package/dist/safe-bash-query-engine/parser.js +1 -1
- package/dist/safe-bash-query-engine/query-core.js +3 -3
- package/dist/safe-playwright-cloudflare/browser-private-transport.js +8 -13
- package/dist/safe-playwright-cloudflare/browser-storage-control.js +13 -4
- package/dist/safe-playwright-cloudflare/browser-trace-archive.js +1 -1
- package/package.json +18 -14
- package/dist/image-ast/streams/node.d.ts +0 -10
- package/dist/image-ast/streams/node.js +0 -5
- package/dist/image-ast/streams/web.js +0 -94
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { randomFillSync } from "node:crypto";
|
|
2
1
|
import { yieldTurn } from "@poe-platform/safe-bash/contracts/yield";
|
|
3
2
|
import { Diagnostic, quote, wordMax } from "./args.js";
|
|
4
3
|
import { ownedBytes, virtualPath } from "./input.js";
|
|
@@ -74,7 +73,7 @@ export class RandomIntegers {
|
|
|
74
73
|
this.bytes = new Uint8Array(next.value);
|
|
75
74
|
}
|
|
76
75
|
else {
|
|
77
|
-
this.bytes =
|
|
76
|
+
this.bytes = globalThis.crypto.getRandomValues(new Uint8Array(4096));
|
|
78
77
|
}
|
|
79
78
|
this.offset = 0;
|
|
80
79
|
this.signal.throwIfAborted();
|
|
@@ -91,7 +90,7 @@ export class RandomIntegers {
|
|
|
91
90
|
throw new Error("shuf random source is closed");
|
|
92
91
|
while (this.maximum < target) {
|
|
93
92
|
if (this.offset === this.bytes.length) {
|
|
94
|
-
this.bytes =
|
|
93
|
+
this.bytes = globalThis.crypto.getRandomValues(this.bytes.length === 4096 ? this.bytes : new Uint8Array(4096));
|
|
95
94
|
this.offset = 0;
|
|
96
95
|
}
|
|
97
96
|
this.value = ((this.value << 8n) + BigInt(this.bytes[this.offset++])) & wordMax;
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
export { portableTrapExtension as trapExtension } from "@poe-platform/safe-bash/optional-host";
|
|
2
2
|
export type { TrapExtensionOptions, TrapSignalHost } from "@poe-platform/safe-bash/optional-host";
|
|
3
|
-
export declare function trapExtension(configuration?: TrapExtensionOptions): import("@poe-platform/safe-bash/optional-host").ShellExtension;
|
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { portableTrapExtension } from "@poe-platform/safe-bash/optional-host";
|
|
3
|
-
export function trapExtension(configuration = {}) {
|
|
4
|
-
return portableTrapExtension({
|
|
5
|
-
...configuration,
|
|
6
|
-
signalNames: configuration.signalNames ?? { ...constants.signals, ...(platform() === "darwin" ? { SIGEMT: 7 } : {}) },
|
|
7
|
-
});
|
|
8
|
-
}
|
|
1
|
+
export { portableTrapExtension as trapExtension } from "@poe-platform/safe-bash/optional-host";
|
|
@@ -108,6 +108,7 @@ export interface PlaywrightFrame {
|
|
|
108
108
|
evaluate?<Result, Argument>(callback: (argument: Argument) => Result, argument: Argument): Promise<Result>;
|
|
109
109
|
evaluateHandle?(callback: (input: FrameSnapshotInput) => FrameSnapshotCapsule, input: FrameSnapshotInput): Promise<PlaywrightSnapshotHandle>;
|
|
110
110
|
locator(selector: string): {
|
|
111
|
+
click?(options?: PlaywrightActionOptions): Promise<void>;
|
|
111
112
|
elementHandles?: () => Promise<PlaywrightElementHandle[]>;
|
|
112
113
|
evaluate?: (callback: (node: SnapshotNode) => string) => Promise<string>;
|
|
113
114
|
};
|
|
@@ -172,6 +173,7 @@ export interface PlaywrightPage {
|
|
|
172
173
|
timeout?: number;
|
|
173
174
|
}): Promise<unknown>;
|
|
174
175
|
title?(): Promise<string>;
|
|
176
|
+
content?(): Promise<string>;
|
|
175
177
|
hideHighlight?(): Promise<void>;
|
|
176
178
|
waitForTimeout?(milliseconds: number): Promise<void>;
|
|
177
179
|
setViewportSize?(size: {
|
|
@@ -2,6 +2,13 @@ import type { PlaywrightAbility } from './abilities.js';
|
|
|
2
2
|
import type { PlaywrightContext, PlaywrightPage } from './adapter.js';
|
|
3
3
|
import type { PlaywrightCommand } from './catalog.js';
|
|
4
4
|
import type { PlaywrightSessionConfiguration } from './session-configuration.js';
|
|
5
|
+
export interface PlaywrightNavigationSummary {
|
|
6
|
+
readonly url: string;
|
|
7
|
+
readonly status?: number;
|
|
8
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
9
|
+
}
|
|
10
|
+
/** Read retained navigation metadata without browser I/O; absent after eviction or cleanup. */
|
|
11
|
+
export declare function getPlaywrightMainFrameNavigation(context: PlaywrightContext, page: PlaywrightPage): PlaywrightNavigationSummary | undefined;
|
|
5
12
|
export declare function observePlaywrightCapabilities(context: PlaywrightContext, registerCleanup: (cleanup: () => Promise<void>) => void, limits: {
|
|
6
13
|
maxCommandBytes: number;
|
|
7
14
|
maxArtifactBytes: number;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { PlaywrightResourceLimitError } from './resource-limit.js';
|
|
2
2
|
import { capabilityArtifact, capabilityArtifactName, capabilityResult, numeric, requirePage, requireSession, unsupported } from './capability-result.js';
|
|
3
3
|
const states = new WeakMap();
|
|
4
|
+
/** Read retained navigation metadata without browser I/O; absent after eviction or cleanup. */
|
|
5
|
+
export function getPlaywrightMainFrameNavigation(context, page) {
|
|
6
|
+
const record = states.get(context)?.pages.get(pageIdentity(page))?.requests[0];
|
|
7
|
+
if (!record?.mainFrameNavigation)
|
|
8
|
+
return undefined;
|
|
9
|
+
return { url: record.url, ...(record.response ? { status: record.response.status, headers: record.response.headers } : {}) };
|
|
10
|
+
}
|
|
4
11
|
// A host may wrap Page navigation methods while native events retain the raw Page.
|
|
5
12
|
// Playwright's main frame remains stable across those wrappers and navigations.
|
|
6
13
|
function pageIdentity(page) { return page.mainFrame?.() ?? page; }
|
|
@@ -60,7 +67,8 @@ export function observePlaywrightCapabilities(context, registerCleanup, limits)
|
|
|
60
67
|
} // Worker-only requests have no selected page.
|
|
61
68
|
const page = frame.page();
|
|
62
69
|
const events = pageEvents(page);
|
|
63
|
-
|
|
70
|
+
const mainFrameNavigation = native.isNavigationRequest() && frame.parentFrame() === null;
|
|
71
|
+
if (mainFrameNavigation) {
|
|
64
72
|
for (const record of [...events.requests])
|
|
65
73
|
forget(record);
|
|
66
74
|
events.nextRequestIndex = 0;
|
|
@@ -69,7 +77,7 @@ export function observePlaywrightCapabilities(context, registerCleanup, limits)
|
|
|
69
77
|
delete events.log;
|
|
70
78
|
events.consoleCursor = events.nextConsoleIndex;
|
|
71
79
|
}
|
|
72
|
-
const record = { index: ++events.nextRequestIndex, native, url: native.url(), method: native.method(), type: native.resourceType(), headers: { ...native.headers() } };
|
|
80
|
+
const record = { index: ++events.nextRequestIndex, native, url: native.url(), method: native.method(), type: native.resourceType(), headers: { ...native.headers() }, mainFrameNavigation };
|
|
73
81
|
requests.set(native, record);
|
|
74
82
|
events.requests.push(record);
|
|
75
83
|
// Keep native body access lazy: copying postData here turns uploads into a
|
|
@@ -83,7 +91,7 @@ export function observePlaywrightCapabilities(context, registerCleanup, limits)
|
|
|
83
91
|
const record = requests.get(native.request());
|
|
84
92
|
if (!record)
|
|
85
93
|
return;
|
|
86
|
-
const response = { native, status: native.status(), statusText: native.statusText(), headers: { ...native.headers() } };
|
|
94
|
+
const response = { native, status: native.status(), statusText: native.statusText(), headers: Object.freeze({ ...native.headers() }) };
|
|
87
95
|
record.response = response;
|
|
88
96
|
const retained = history.get(record);
|
|
89
97
|
retain(record, retained.bytes + byteLength(JSON.stringify({ status: response.status, statusText: response.statusText, headers: response.headers })), retained.evict);
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
import type { PlaywrightAdapter, PlaywrightContext, PlaywrightContextOptions, PlaywrightLease, PlaywrightPage } from './adapter.js';
|
|
2
2
|
import { type PlaywrightInvocation } from './invocation.js';
|
|
3
3
|
import { type PlaywrightAbilities } from './abilities.js';
|
|
4
|
+
import { type PlaywrightNavigationSummary } from './capability-events.js';
|
|
4
5
|
import { type PlaywrightSessionConfiguration } from './session-configuration.js';
|
|
5
6
|
import { type PlaywrightCheckpointOutcome } from './checkpoint.js';
|
|
6
7
|
import { type PlaywrightOperationOutcome, type PlaywrightRecoveryResult } from './recovery.js';
|
|
8
|
+
export interface PlaywrightSnapshotHookContext<TSnapshot> {
|
|
9
|
+
readonly command: string;
|
|
10
|
+
readonly format: 'yaml' | 'json';
|
|
11
|
+
readonly context: PlaywrightContext;
|
|
12
|
+
readonly page: PlaywrightPage;
|
|
13
|
+
readonly snapshot: TSnapshot;
|
|
14
|
+
readonly navigation?: PlaywrightNavigationSummary;
|
|
15
|
+
readonly signal: AbortSignal;
|
|
16
|
+
recapture(): Promise<TSnapshot>;
|
|
17
|
+
}
|
|
18
|
+
export type PlaywrightSnapshotHook = <TSnapshot>(request: PlaywrightSnapshotHookContext<TSnapshot>) => Promise<TSnapshot>;
|
|
7
19
|
export interface PlaywrightControllerOptions {
|
|
8
20
|
/** Clock for fallback operation receipts, retained for at most 24 hours across 16 aliases. */
|
|
9
21
|
readonly operationClock?: () => number;
|
|
10
22
|
readonly adapter?: PlaywrightAdapter;
|
|
23
|
+
/** Runs inside the command queue after capture. Recapture does not invoke the hook again. */
|
|
24
|
+
readonly onSnapshot?: PlaywrightSnapshotHook;
|
|
11
25
|
readonly abilities?: PlaywrightAbilities;
|
|
12
26
|
readonly persistence?: PlaywrightSessionPersistence;
|
|
13
27
|
/** Opt in only when this controller and persistence are bound to one authenticated owner. */
|
|
@@ -9,7 +9,7 @@ import { PlaywrightReportedError, playwrightCliCompatibilityVersion, playwrightC
|
|
|
9
9
|
import { capabilityArtifactName } from './capability-result.js';
|
|
10
10
|
import { isPlaywrightSnapshotRef, resolvePlaywrightTarget } from './targets.js';
|
|
11
11
|
import { capturePlaywrightTargetScreenshot } from './target-screenshot.js';
|
|
12
|
-
import { flushPlaywrightConsole, observePlaywrightCapabilities } from './capability-events.js';
|
|
12
|
+
import { flushPlaywrightConsole, getPlaywrightMainFrameNavigation, observePlaywrightCapabilities } from './capability-events.js';
|
|
13
13
|
import { getPlaywrightModal, observePlaywrightModals, onPlaywrightModal } from './modal-capabilities.js';
|
|
14
14
|
import { findPlaywrightSnapshot } from './find.js';
|
|
15
15
|
import { collectPlaywrightDownloads, observePlaywrightDownloads } from './download-capabilities.js';
|
|
@@ -30,8 +30,10 @@ export function createPlaywrightController(options = {}) {
|
|
|
30
30
|
throw new TypeError('Invalid Playwright configuration');
|
|
31
31
|
if (options.adapter !== undefined && (!options.adapter || typeof options.adapter.acquire !== 'function'))
|
|
32
32
|
throw new TypeError('An injected Playwright adapter is required');
|
|
33
|
-
if (Object.keys(options).some(key => !['adapter', 'abilities', 'limits', 'billing', 'persistence', 'namedSessionAttachment', 'operationClock'].includes(key)))
|
|
33
|
+
if (Object.keys(options).some(key => !['adapter', 'abilities', 'limits', 'billing', 'persistence', 'namedSessionAttachment', 'operationClock', 'onSnapshot'].includes(key)))
|
|
34
34
|
throw new TypeError('Unsupported Playwright configuration');
|
|
35
|
+
if (options.onSnapshot !== undefined && typeof options.onSnapshot !== 'function')
|
|
36
|
+
throw new TypeError('Invalid Playwright snapshot hook');
|
|
35
37
|
if (options.operationClock !== undefined && typeof options.operationClock !== 'function')
|
|
36
38
|
throw new TypeError('Invalid Playwright operation clock');
|
|
37
39
|
if (options.namedSessionAttachment !== undefined && typeof options.namedSessionAttachment !== 'boolean')
|
|
@@ -966,10 +968,7 @@ export function createPlaywrightController(options = {}) {
|
|
|
966
968
|
if (consoleLink)
|
|
967
969
|
sections.push({ title: 'Events', content: `- New console entries: ${consoleLink}` });
|
|
968
970
|
}
|
|
969
|
-
|
|
970
|
-
const title = await page.title?.();
|
|
971
|
-
sections.push({ title: 'Page', content: `- Page URL: ${page.url()}${title === undefined ? '' : `\n- Page Title: ${title}`}` });
|
|
972
|
-
}
|
|
971
|
+
const pageSectionIndex = sections.length;
|
|
973
972
|
if (snapshot !== 'none' && (page.frames || page.ariaSnapshot || page._snapshotForAI || page.ariaSnapshotJSON || session.lease?.captureSnapshotJSON)) {
|
|
974
973
|
const snapshotOptions = { timeout: sessionSnapshotTimeout(session), ...(session.configuration?.snapshot?.boxes === undefined ? {} : { boxes: session.configuration.snapshot.boxes }), ...(session.lease?.captureSnapshotReferences ? { captureReferences: session.lease.captureSnapshotReferences } : {}) };
|
|
975
974
|
if (parsed.command === 'snapshot') {
|
|
@@ -984,16 +983,40 @@ export function createPlaywrightController(options = {}) {
|
|
|
984
983
|
if (parsed.args[0])
|
|
985
984
|
snapshotOptions.root = await resolveTarget(session, parsed.args[0]);
|
|
986
985
|
}
|
|
986
|
+
const captureWithHook = async (format, capture) => {
|
|
987
|
+
let active = true;
|
|
988
|
+
const recapture = async () => {
|
|
989
|
+
if (!active)
|
|
990
|
+
throw new Error('Playwright snapshot hook has completed');
|
|
991
|
+
check();
|
|
992
|
+
const value = await capture();
|
|
993
|
+
check();
|
|
994
|
+
return value;
|
|
995
|
+
};
|
|
996
|
+
try {
|
|
997
|
+
const initial = await recapture();
|
|
998
|
+
if (!options.onSnapshot)
|
|
999
|
+
return initial;
|
|
1000
|
+
const navigation = getPlaywrightMainFrameNavigation(session.lease.context, page);
|
|
1001
|
+
const result = await options.onSnapshot({ command: parsed.command, format, context: session.lease.context, page,
|
|
1002
|
+
snapshot: initial, ...(navigation ? { navigation } : {}), signal: local.signal, recapture });
|
|
1003
|
+
check();
|
|
1004
|
+
return result;
|
|
1005
|
+
}
|
|
1006
|
+
finally {
|
|
1007
|
+
active = false;
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
987
1010
|
retained = false;
|
|
988
1011
|
if (parsed.command === 'snapshot' && parsed.json && filename === undefined) {
|
|
989
|
-
const tree = await session.snapshot.captureJSON(page, local.signal, { ...snapshotOptions, ...(session.lease?.captureSnapshotJSON ? { captureJSON: session.lease.captureSnapshotJSON } : {}) });
|
|
1012
|
+
const tree = await captureWithHook('json', () => session.snapshot.captureJSON(page, local.signal, { ...snapshotOptions, ...(session.lease?.captureSnapshotJSON ? { captureJSON: session.lease.captureSnapshotJSON } : {}) }));
|
|
990
1013
|
check();
|
|
991
1014
|
retained = parsed.command === 'snapshot';
|
|
992
1015
|
sections.push({ title: 'Snapshot', content: { json: tree }, codeframe: 'json' });
|
|
993
1016
|
return { sections };
|
|
994
1017
|
}
|
|
995
1018
|
retained = false;
|
|
996
|
-
const text = await session.snapshot.capture(page, local.signal, snapshotOptions);
|
|
1019
|
+
const text = await captureWithHook('yaml', () => session.snapshot.capture(page, local.signal, snapshotOptions));
|
|
997
1020
|
check();
|
|
998
1021
|
retained = parsed.command === 'snapshot';
|
|
999
1022
|
if (filename !== undefined || snapshot === 'file' && invocation.writeArtifact) {
|
|
@@ -1009,6 +1032,11 @@ export function createPlaywrightController(options = {}) {
|
|
|
1009
1032
|
else
|
|
1010
1033
|
sections.push({ title: 'Snapshot', content: text.trimEnd(), codeframe: 'yaml' });
|
|
1011
1034
|
}
|
|
1035
|
+
if (parsed.command !== 'snapshot' || !parsed.json) {
|
|
1036
|
+
const title = await page.title?.();
|
|
1037
|
+
check();
|
|
1038
|
+
sections.splice(pageSectionIndex, 0, { title: 'Page', content: `- Page URL: ${page.url()}${title === undefined ? '' : `\n- Page Title: ${title}`}` });
|
|
1039
|
+
}
|
|
1012
1040
|
return { sections };
|
|
1013
1041
|
};
|
|
1014
1042
|
const checkSession = (session) => {
|
|
@@ -2,6 +2,7 @@ export * from './adapter.js';
|
|
|
2
2
|
export { parseBrowserProfile, encodeBrowserProfile, restoreBrowserProfile, checkpointBrowserProfile, type BrowserProfile, type BrowserProfileLimits, type BrowserProfileContext } from './profile.js';
|
|
3
3
|
export * from './billing.js';
|
|
4
4
|
export * from './controller.js';
|
|
5
|
+
export { getPlaywrightMainFrameNavigation, type PlaywrightNavigationSummary } from './capability-events.js';
|
|
5
6
|
export { parsePlaywrightOperationOutcome, type PlaywrightRecoveryResult, type PlaywrightOperationOutcome } from './recovery.js';
|
|
6
7
|
export * from './catalog.js';
|
|
7
8
|
export * from './network-policy.js';
|
|
@@ -2,6 +2,7 @@ export * from './adapter.js';
|
|
|
2
2
|
export { parseBrowserProfile, encodeBrowserProfile, restoreBrowserProfile, checkpointBrowserProfile } from './profile.js';
|
|
3
3
|
export * from './billing.js';
|
|
4
4
|
export * from './controller.js';
|
|
5
|
+
export { getPlaywrightMainFrameNavigation } from './capability-events.js';
|
|
5
6
|
export { parsePlaywrightOperationOutcome } from './recovery.js';
|
|
6
7
|
export * from './catalog.js';
|
|
7
8
|
export * from './network-policy.js';
|
|
@@ -5,6 +5,7 @@ export interface PlaywrightCDPTransport {
|
|
|
5
5
|
onmessage?: ((message: object) => void) | undefined;
|
|
6
6
|
onclose?: ((reason?: string) => void) | undefined;
|
|
7
7
|
}
|
|
8
|
+
/** Omitted limits and Infinity are unlimited; positive finite values opt into budgets. */
|
|
8
9
|
export interface PlaywrightPrivateTargetTransportLimits {
|
|
9
10
|
maxMessageBytes?: number;
|
|
10
11
|
maxGraphNodes?: number;
|
|
@@ -5,7 +5,7 @@ function identity(value) {
|
|
|
5
5
|
return typeof value === 'string' && value.length > 0 && value.length <= 1024 && !value.includes('\0');
|
|
6
6
|
}
|
|
7
7
|
const admittedGraphs = new WeakMap();
|
|
8
|
-
function preflightProtocolJson(text, maxBytes, maxNodes =
|
|
8
|
+
function preflightProtocolJson(text, maxBytes, maxNodes = Infinity, maxDepth = Infinity, byteErrorMessage = 'CDP message byte limit exceeded') {
|
|
9
9
|
let bytes = 0;
|
|
10
10
|
let nodes = 0;
|
|
11
11
|
let depth = 0;
|
|
@@ -110,8 +110,8 @@ function freezeProtocolGraph(root) {
|
|
|
110
110
|
}
|
|
111
111
|
export function admitPlaywrightProtocolFrame(data, options = {}) {
|
|
112
112
|
const maxBytes = options.maxBytes ?? Infinity;
|
|
113
|
-
const maxGraphNodes = options.maxGraphNodes ??
|
|
114
|
-
const maxGraphDepth = options.maxGraphDepth ??
|
|
113
|
+
const maxGraphNodes = options.maxGraphNodes ?? Infinity;
|
|
114
|
+
const maxGraphDepth = options.maxGraphDepth ?? Infinity;
|
|
115
115
|
if (typeof data !== 'string')
|
|
116
116
|
throw new Error('Private browser frame limit or type violation');
|
|
117
117
|
const stats = preflightProtocolJson(data, maxBytes, maxGraphNodes, maxGraphDepth, 'Private browser frame limit or type violation');
|
|
@@ -123,29 +123,25 @@ export function admitPlaywrightProtocolFrame(data, options = {}) {
|
|
|
123
123
|
return value;
|
|
124
124
|
}
|
|
125
125
|
export function createPlaywrightPrivateTargetTransport(upstream, options = {}) {
|
|
126
|
+
for (const [name, value] of Object.entries(options)) {
|
|
127
|
+
if (value !== undefined && value !== Infinity && (!Number.isSafeInteger(value) || value <= 0 || (name.endsWith('TimeoutMs') && value > 2147483647))) {
|
|
128
|
+
throw new TypeError(`Invalid private transport limit: ${name}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
126
131
|
const limits = {
|
|
127
|
-
maxGraphNodes:
|
|
128
|
-
maxGraphDepth:
|
|
129
|
-
maxQueuedCommands:
|
|
130
|
-
maxBufferedMessages:
|
|
131
|
-
maxPrivateTargets:
|
|
132
|
-
maxPrivateSessions:
|
|
133
|
-
creationTimeoutMs:
|
|
134
|
-
commandTimeoutMs:
|
|
135
|
-
...options,
|
|
132
|
+
maxGraphNodes: options.maxGraphNodes ?? Infinity,
|
|
133
|
+
maxGraphDepth: options.maxGraphDepth ?? Infinity,
|
|
134
|
+
maxQueuedCommands: options.maxQueuedCommands ?? Infinity,
|
|
135
|
+
maxBufferedMessages: options.maxBufferedMessages ?? Infinity,
|
|
136
|
+
maxPrivateTargets: options.maxPrivateTargets ?? Infinity,
|
|
137
|
+
maxPrivateSessions: options.maxPrivateSessions ?? Infinity,
|
|
138
|
+
creationTimeoutMs: options.creationTimeoutMs ?? Infinity,
|
|
139
|
+
commandTimeoutMs: options.commandTimeoutMs ?? Infinity,
|
|
136
140
|
maxMessageBytes: options.maxMessageBytes ?? Infinity,
|
|
137
141
|
maxPendingBytes: options.maxPendingBytes ?? Infinity,
|
|
138
142
|
maxBufferedBytes: options.maxBufferedBytes ?? Infinity,
|
|
139
143
|
maxPendingCommands: options.maxPendingCommands ?? Infinity,
|
|
140
144
|
};
|
|
141
|
-
for (const [name, value] of Object.entries(limits)) {
|
|
142
|
-
if (['maxPendingCommands', 'maxMessageBytes', 'maxPendingBytes', 'maxBufferedBytes'].includes(name) && options[name] === undefined)
|
|
143
|
-
continue;
|
|
144
|
-
if (!Number.isSafeInteger(value) || value <= 0 || (name.endsWith('TimeoutMs') && value > 2147483647)) {
|
|
145
|
-
throw new TypeError(`Invalid private transport limit: ${name}`);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const encoder = new TextEncoder();
|
|
149
145
|
const targets = new Set();
|
|
150
146
|
const sessions = new Map();
|
|
151
147
|
const retiredTargets = new Set();
|
|
@@ -166,6 +162,8 @@ export function createPlaywrightPrivateTargetTransport(upstream, options = {}) {
|
|
|
166
162
|
let commandTimer;
|
|
167
163
|
let timedCommandId;
|
|
168
164
|
function scheduleCommandDeadline() {
|
|
165
|
+
if (!Number.isFinite(limits.commandTimeoutMs))
|
|
166
|
+
return;
|
|
169
167
|
// Uniform deadlines and monotonic insertion order keep the oldest command
|
|
170
168
|
// first, even when replies arrive out of order. Only that command needs a timer.
|
|
171
169
|
const first = pending.entries().next().value;
|
|
@@ -550,7 +548,9 @@ export function createPlaywrightPrivateTargetTransport(upstream, options = {}) {
|
|
|
550
548
|
if (targets.size >= limits.maxPrivateTargets)
|
|
551
549
|
throw new Error('Private target identity capacity exceeded');
|
|
552
550
|
const entry = { active: true, failed: false,
|
|
553
|
-
timer:
|
|
551
|
+
timer: Number.isFinite(limits.creationTimeoutMs)
|
|
552
|
+
? setTimeout(() => retire(new Error('Native target creation identity timed out')), limits.creationTimeoutMs)
|
|
553
|
+
: undefined };
|
|
554
554
|
creation = entry;
|
|
555
555
|
return {
|
|
556
556
|
commit(targetId) { finish(entry, true, targetId); },
|
|
@@ -322,7 +322,6 @@ interface InvokeOutcomeRecord {
|
|
|
322
322
|
consumed: boolean;
|
|
323
323
|
selection?: CancellationSelection<CommandResult> | undefined;
|
|
324
324
|
}
|
|
325
|
-
/** Internal to the shell/runtime pair; it is not exported by the package root. */
|
|
326
325
|
export declare class RuntimeCancellationState {
|
|
327
326
|
private _records;
|
|
328
327
|
private _diagnostics;
|
|
@@ -506,6 +505,7 @@ export declare class Runtime {
|
|
|
506
505
|
private trySyncScript;
|
|
507
506
|
private isPureSyncValueWord;
|
|
508
507
|
private extractPosixBracketCondExpr;
|
|
508
|
+
private execSyncUnsetStep;
|
|
509
509
|
private extractSyncUnsetVars;
|
|
510
510
|
private extractSyncShiftCount;
|
|
511
511
|
private extractSyncLocalDeclStep;
|
|
@@ -514,6 +514,7 @@ export declare class Runtime {
|
|
|
514
514
|
private evalSyncNestedForWords;
|
|
515
515
|
private isSyncEchoCallOk;
|
|
516
516
|
private extractSyncReadHereStringSpec;
|
|
517
|
+
private isPureSyncSubIfOrCase;
|
|
517
518
|
private canSyncLoopBody;
|
|
518
519
|
private extractIntLoopStep;
|
|
519
520
|
private buildSyncLoopBody;
|
|
@@ -524,13 +525,22 @@ export declare class Runtime {
|
|
|
524
525
|
private evalSyncRedirectWord;
|
|
525
526
|
private evalSyncRedirectSuffix;
|
|
526
527
|
private encodeSyncRedirectWordsToScratch;
|
|
528
|
+
private _activePrintfInductionName;
|
|
529
|
+
private _activeLoopBodyScript;
|
|
530
|
+
private _activeLoopCondScript;
|
|
531
|
+
private _activeLoopVarName;
|
|
532
|
+
private isVarUnmutatedInScript;
|
|
533
|
+
private isVarUnmutatedInActiveLoop;
|
|
534
|
+
private isFileReadOnlyScript;
|
|
535
|
+
private extractLoopInvariantJqInput;
|
|
527
536
|
private canSyncPrintfInductionBody;
|
|
528
537
|
private isSyncPrintfCallOk;
|
|
529
538
|
private isSimpleRedirectEchoWord;
|
|
539
|
+
private syncStringLength;
|
|
540
|
+
private execSyncReadHereStringStep;
|
|
530
541
|
private splitSyncReadLine;
|
|
531
542
|
private execSyncLocalDeclStep;
|
|
532
543
|
private _syncTouchedPositionals;
|
|
533
|
-
private _syncPendingVarAttrs;
|
|
534
544
|
private flushSyncPositionals;
|
|
535
545
|
private execSyncShiftStep;
|
|
536
546
|
private evalSyncPrintfStep;
|
|
@@ -666,6 +676,28 @@ export declare class Runtime {
|
|
|
666
676
|
}>, value: ShellValue, state: State, io: IO, hereString: boolean): Promise<ShellValue>;
|
|
667
677
|
word(word: Word, state: State, io: IO, split?: boolean, pattern?: boolean, hereString?: boolean, conditionalPattern?: boolean, regexAppend?: (text: string, literal: boolean, value: ShellValue) => void): Promise<string[]>;
|
|
668
678
|
private fastValueWord;
|
|
679
|
+
private expandSyncTrCharArray;
|
|
680
|
+
private evalSyncTr;
|
|
681
|
+
private evalSyncJqPathOps;
|
|
682
|
+
private evalSyncJq;
|
|
683
|
+
private evalSyncDirname;
|
|
684
|
+
private evalSyncBasename;
|
|
685
|
+
private parseSyncCutSpec;
|
|
686
|
+
private evalSyncCut;
|
|
687
|
+
private evalSyncSed;
|
|
688
|
+
private evalSyncGrep;
|
|
689
|
+
private evalSyncAwk;
|
|
690
|
+
private formatSyncTransformQ;
|
|
691
|
+
private wcMaxLineWidth;
|
|
692
|
+
private compareSyncVersion;
|
|
693
|
+
private evalSyncNl;
|
|
694
|
+
private evalSyncPaste;
|
|
695
|
+
private evalSyncNumfmt;
|
|
696
|
+
private evalSyncSort;
|
|
697
|
+
private normalizeSyncWcFlag;
|
|
698
|
+
private evalSyncUniq;
|
|
699
|
+
private sortSyncLines;
|
|
700
|
+
private translateSyncTr;
|
|
669
701
|
private expandSyncTrCharSet;
|
|
670
702
|
private syncBase64Encode;
|
|
671
703
|
private syncBase64DecodeBytes;
|