@fkn/lib 0.9.40 → 0.9.42
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/account-generation-B-6Pn0b5.cjs +1 -0
- package/account-generation-XNWOvLea.js +28 -0
- package/account.cjs +1 -1
- package/account.d.ts +11 -0
- package/account.js +8 -20
- package/api--LOXTOpv.cjs +3 -0
- package/{api-Dp-2AT3u.js → api-DIgTslNb.js} +154 -114
- package/{api-BE5zPvFZ.d.ts → api-SwxtiYVU.d.ts} +38 -14
- package/api.cjs +1 -1
- package/api.d.ts +3 -3
- package/api.js +2 -2
- package/attach-policy.cjs +1 -1
- package/attach-policy.js +2 -2
- package/cloud/dns.d.ts +1 -1
- package/cloud/fetch.cjs +1 -1
- package/cloud/fetch.d.ts +1 -1
- package/cloud/fetch.js +1 -1
- package/cloud/fs/promises.d.ts +1 -1
- package/cloud/fs.cjs +1 -1
- package/cloud/fs.d.ts +4 -4
- package/cloud/fs.js +31 -24
- package/cloud/net.d.ts +1 -1
- package/cloud-868OlBKn.cjs +1 -0
- package/{cloud-5eldoFxK.d.ts → cloud-DUH-v10C.d.ts} +6 -4
- package/cloud-f3j4s8yZ.js +545 -0
- package/cloud.cjs +1 -1
- package/cloud.d.ts +4 -4
- package/cloud.js +2 -2
- package/{contract-Cvr_8gCL.d.ts → contract-CCxPKIC7.d.ts} +105 -13
- package/contract.d.ts +3 -2
- package/dgram.cjs +1 -1
- package/dgram.d.ts +2 -2
- package/dgram.js +1 -1
- package/dns.cjs +1 -1
- package/dns.d.ts +1 -1
- package/dns.js +1 -1
- package/extension-BOBuYwZc.js +92 -0
- package/extension-hoUs5yJ7.cjs +1 -0
- package/{extension-DMU-CwMw.d.ts → extension-yhwDSIiD.d.ts} +22 -3
- package/extension.cjs +1 -1
- package/extension.d.ts +3 -3
- package/extension.js +3 -3
- package/fs/promises.cjs +1 -1
- package/fs/promises.d.ts +1 -1
- package/fs/promises.js +1 -1
- package/fs-CVnmXRf7.js +513 -0
- package/{fs--NhtUyYa.d.ts → fs-D0MMRnHC.d.ts} +8 -4
- package/fs-p0bOOj5n.cjs +1 -0
- package/fs.cjs +1 -1
- package/fs.d.ts +4 -3
- package/fs.js +4 -2
- package/{hosts-9dYv63ud.cjs → hosts-GNBhZO3-.cjs} +1 -1
- package/{hosts-BzbzOhG8.js → hosts-t7CKGTRz.js} +4 -1
- package/http.d.ts +1 -1
- package/{index-D2CA-NX5.d.ts → index-BtFiGoVQ.d.ts} +465 -51
- package/{index-kuPqkS_-.d.ts → index-D2lvaQDs.d.ts} +28 -38
- package/index.cjs +1 -1
- package/index.d.ts +17 -17
- package/index.js +62 -59
- package/lib-CfdmsLoI.cjs +53 -0
- package/{lib-C4Eeg9eM.js → lib-DppqX10G.js} +470 -302
- package/{messages-C66ghz_A.d.ts → messages-CRcziTuC.d.ts} +17 -1
- package/messages.cjs +1 -1
- package/messages.d.ts +2 -2
- package/messages.js +2 -2
- package/{net-zThwNoA8.d.ts → net-DcLF-6E-.d.ts} +2 -2
- package/net.cjs +1 -1
- package/net.d.ts +1 -1
- package/net.js +1 -1
- package/{node-fs-BZy9bzKd.js → node-fs-CK2wWIYS.js} +140 -137
- package/node-fs-nfX7wisL.cjs +1 -0
- package/opfs.cjs +1 -1
- package/opfs.js +1 -1
- package/package.json +1 -1
- package/packages.cjs +1 -1
- package/packages.d.ts +1 -1
- package/packages.js +14 -14
- package/{proxy-Dc0gDOxz.d.ts → proxy-CE46SkyA.d.ts} +2 -2
- package/{proxy-DjoPtJH9.cjs → proxy-CFK-KiwE.cjs} +1 -1
- package/{proxy-DMTdQ4dN.js → proxy-Dixbk1WL.js} +1 -1
- package/rooms.cjs +1 -1
- package/rooms.d.ts +1 -1
- package/rooms.js +11 -11
- package/storage-BVr2Rb-d.d.ts +167 -0
- package/storage-D2cUJlVH.cjs +1 -0
- package/storage-Dn1gTLSZ.js +123 -0
- package/api-jOTOA-5n.cjs +0 -3
- package/cloud-BLv19j-W.js +0 -480
- package/cloud-D7aQY4GH.cjs +0 -1
- package/extension-B9v933cT.js +0 -89
- package/extension-D2zMdc2f.cjs +0 -1
- package/fs-CaQFRiIT.cjs +0 -1
- package/fs-D3IsGdnN.js +0 -360
- package/lib-BfAg9mHD.cjs +0 -53
- package/node-fs-BNTPsX5c.cjs +0 -1
- package/storage-BJd-mWHE.cjs +0 -1
- package/storage-DSvL-t80.js +0 -67
- package/storage-ZrY4Y4L5.d.ts +0 -88
|
@@ -47,6 +47,20 @@ type OperationModule = {
|
|
|
47
47
|
* from `args[1]`, so it declares `options => [undefined, options]`.
|
|
48
48
|
*/
|
|
49
49
|
ensureArgs?: (options: Record<string, unknown>) => unknown[];
|
|
50
|
+
/**
|
|
51
|
+
* Maps the arguments a caller passes to the ones the wire carries, on the calling side, before the
|
|
52
|
+
* gate and the executor see them, and gives the chain method its parameter types. It lets a public
|
|
53
|
+
* option take a new name while every backend keeps reading the old one, since a backend resolves
|
|
54
|
+
* options by its own copy. Throw to refuse a call before anything is gated or sent. Absent, the
|
|
55
|
+
* arguments travel verbatim.
|
|
56
|
+
*/
|
|
57
|
+
send?: (...args: any[]) => unknown[];
|
|
58
|
+
/**
|
|
59
|
+
* `false` leaves the operation off the chain types, so a call every backend refuses on a chain is a
|
|
60
|
+
* compile error. Types only: the chain still carries it and the backend still refuses it by name,
|
|
61
|
+
* for a caller the compiler does not see. A surface that serves it declares it itself.
|
|
62
|
+
*/
|
|
63
|
+
typed?: false;
|
|
50
64
|
};
|
|
51
65
|
type KindModules = {
|
|
52
66
|
selectors: Record<string, SelectorModule>;
|
|
@@ -56,6 +70,22 @@ type Modules = {
|
|
|
56
70
|
element: KindModules;
|
|
57
71
|
frame: KindModules;
|
|
58
72
|
};
|
|
73
|
+
/**
|
|
74
|
+
* A chain method answered on the calling side by rewriting the parts collected so far into parts every
|
|
75
|
+
* executor already resolves, rather than by appending a part of its own name. An executor resolves
|
|
76
|
+
* selector names by its own copy of the registry and refuses one it lacks, so a member added this way
|
|
77
|
+
* reaches an older executor with a meaning it already has. `to` is the kind of chain it returns.
|
|
78
|
+
* Throw to refuse a chain the rewrite cannot express. The executor never sees it.
|
|
79
|
+
*/
|
|
80
|
+
type ChainRewrite = {
|
|
81
|
+
to: ChainKind;
|
|
82
|
+
rewrite: (parts: SelectorPart[], ...args: any[]) => SelectorPart[];
|
|
83
|
+
};
|
|
84
|
+
/** Rewrites per kind. One named as a selector of its kind takes that selector's place on the chain. */
|
|
85
|
+
type Rewrites = {
|
|
86
|
+
element?: Record<string, ChainRewrite>;
|
|
87
|
+
frame?: Record<string, ChainRewrite>;
|
|
88
|
+
};
|
|
59
89
|
type OperationOptions = {
|
|
60
90
|
timeout?: number;
|
|
61
91
|
};
|
|
@@ -320,24 +350,33 @@ type Extended<B extends Modules, S extends ModulesSpec> = {
|
|
|
320
350
|
type ArgsOf<M> = M extends {
|
|
321
351
|
resolve: (context: never, ...args: infer A) => unknown;
|
|
322
352
|
} ? A : never;
|
|
353
|
+
type SendArgsOf<M> = M extends {
|
|
354
|
+
send: (...args: infer A) => unknown[];
|
|
355
|
+
} ? A : ArgsOf<M>;
|
|
356
|
+
type RewriteArgsOf<W> = W extends {
|
|
357
|
+
rewrite: (parts: never, ...args: infer A) => unknown;
|
|
358
|
+
} ? A : never;
|
|
323
359
|
type ResultOf<M> = M extends {
|
|
324
360
|
resolve: (...args: never[]) => infer R;
|
|
325
361
|
} ? Awaited<R> : never;
|
|
326
362
|
type ToOf<M> = M extends {
|
|
327
363
|
to: infer K extends ChainKind;
|
|
328
364
|
} ? K : 'element';
|
|
329
|
-
type
|
|
365
|
+
type KindRewrites<R, K extends ChainKind> = K extends keyof R ? (R[K] extends Record<string, ChainRewrite> ? R[K] : {}) : {};
|
|
366
|
+
type ChainOf<M extends Modules, K extends ChainKind, R extends Rewrites> = K extends 'frame' ? FrameLocator$1<M, R> : Locator$1<M, R>;
|
|
330
367
|
/**
|
|
331
368
|
* What `ensure` may carry. An option no gate reads is accepted and ignored rather than refused:
|
|
332
369
|
* `subtree` is the one apps still pass, and the scope it once narrowed is now decided per site by
|
|
333
370
|
* the gate, so passing it changes nothing.
|
|
334
371
|
*/
|
|
335
372
|
type EnsureOptions = OperationOptions & Record<string, unknown>;
|
|
336
|
-
type Chain<M extends Modules, K extends ChainKind> = { [N in keyof M[K]['selectors']]: (...args: ArgsOf<M[K]['selectors'][N]>) => ChainOf<M, ToOf<M[K]['selectors'][N]
|
|
373
|
+
type Chain<M extends Modules, K extends ChainKind, R extends Rewrites = {}> = { [N in Exclude<keyof M[K]['selectors'], keyof KindRewrites<R, K>>]: (...args: ArgsOf<M[K]['selectors'][N]>) => ChainOf<M, ToOf<M[K]['selectors'][N]>, R>; } & { [N in keyof M[K]['operations'] as M[K]['operations'][N] extends {
|
|
374
|
+
typed: false;
|
|
375
|
+
} ? never : N]: (...args: SendArgsOf<M[K]['operations'][N]>) => Promise<ResultOf<M[K]['operations'][N]>>; } & { [N in keyof KindRewrites<R, K>]: (...args: RewriteArgsOf<KindRewrites<R, K>[N]>) => ChainOf<M, ToOf<KindRewrites<R, K>[N]>, R>; } & {
|
|
337
376
|
ensure: (operation: Extract<keyof M[K]['operations'], string>, options?: EnsureOptions) => Promise<void>;
|
|
338
377
|
};
|
|
339
|
-
type Locator$1<M extends Modules = DefaultModules> = Chain<M, 'element'>;
|
|
340
|
-
type FrameLocator<M extends Modules = DefaultModules> = Chain<M, 'frame'>;
|
|
378
|
+
type Locator$1<M extends Modules = DefaultModules, R extends Rewrites = {}> = Chain<M, 'element', R>;
|
|
379
|
+
type FrameLocator$1<M extends Modules = DefaultModules, R extends Rewrites = {}> = Chain<M, 'frame', R>;
|
|
341
380
|
declare namespace video_d_exports {
|
|
342
381
|
export { BoxedVideoElement, RemoteVideoElement, VideoElementState, box, createVideoElementHandle, isType, revive, type };
|
|
343
382
|
}
|
|
@@ -446,7 +485,20 @@ declare const handleRevivableModules: (defaults: DefaultRevivableModules) => rea
|
|
|
446
485
|
type LocatorOptions = OperationOptions & {
|
|
447
486
|
reason?: string;
|
|
448
487
|
};
|
|
488
|
+
/** `click` and `hover`'s options. */
|
|
449
489
|
type PositionOptions = LocatorOptions & {
|
|
490
|
+
/**
|
|
491
|
+
* Where the pointer lands, as a 0..1 fraction of the element's box from its top-left corner: `x`
|
|
492
|
+
* across, `y` down, each 0.5 when left out, so the centre when absent. FKN's name, since
|
|
493
|
+
* Playwright's `position` is in pixels, which no backend serves yet: passing `position` is a
|
|
494
|
+
* TypeError, before anything is sent.
|
|
495
|
+
*/
|
|
496
|
+
relativePosition?: {
|
|
497
|
+
x?: number;
|
|
498
|
+
y?: number;
|
|
499
|
+
};
|
|
500
|
+
};
|
|
501
|
+
type WirePositionOptions = LocatorOptions & {
|
|
450
502
|
position?: {
|
|
451
503
|
x?: number;
|
|
452
504
|
y?: number;
|
|
@@ -588,10 +640,12 @@ declare const locatorModules: Extended<{
|
|
|
588
640
|
readonly element: {
|
|
589
641
|
operations: {
|
|
590
642
|
click: {
|
|
591
|
-
resolve: (context: LocatorContext, options?:
|
|
643
|
+
resolve: (context: LocatorContext, options?: WirePositionOptions) => void;
|
|
644
|
+
send: (options?: PositionOptions) => unknown[];
|
|
592
645
|
};
|
|
593
646
|
hover: {
|
|
594
|
-
resolve: (context: LocatorContext, options?:
|
|
647
|
+
resolve: (context: LocatorContext, options?: WirePositionOptions) => void;
|
|
648
|
+
send: (options?: PositionOptions) => unknown[];
|
|
595
649
|
};
|
|
596
650
|
fill: {
|
|
597
651
|
resolve: (context: LocatorContext, value: string, options?: LocatorOptions) => void;
|
|
@@ -628,6 +682,7 @@ declare const locatorModules: Extended<{
|
|
|
628
682
|
};
|
|
629
683
|
readonly evaluate: {
|
|
630
684
|
readonly kind: "frame";
|
|
685
|
+
readonly typed: false;
|
|
631
686
|
readonly resolve: (_context: LocatorContext, _source: string, _arg?: unknown) => never;
|
|
632
687
|
};
|
|
633
688
|
};
|
|
@@ -635,6 +690,31 @@ declare const locatorModules: Extended<{
|
|
|
635
690
|
}>;
|
|
636
691
|
type LocatorModules = typeof locatorModules;
|
|
637
692
|
//#endregion
|
|
693
|
+
//#region ../web-extension/lib/lib/locator-rewrites.d.ts
|
|
694
|
+
declare const locatorRewrites: {
|
|
695
|
+
readonly element: {
|
|
696
|
+
readonly last: {
|
|
697
|
+
readonly to: 'element';
|
|
698
|
+
readonly rewrite: (parts: SelectorPart[]) => SelectorPart[];
|
|
699
|
+
};
|
|
700
|
+
readonly contentFrame: {
|
|
701
|
+
readonly to: 'frame';
|
|
702
|
+
readonly rewrite: (parts: SelectorPart[]) => SelectorPart[];
|
|
703
|
+
};
|
|
704
|
+
};
|
|
705
|
+
readonly frame: {
|
|
706
|
+
readonly owner: {
|
|
707
|
+
readonly to: 'element';
|
|
708
|
+
readonly rewrite: (parts: SelectorPart[]) => SelectorPart[];
|
|
709
|
+
};
|
|
710
|
+
readonly getByTestId: {
|
|
711
|
+
readonly to: 'element';
|
|
712
|
+
readonly rewrite: (parts: SelectorPart[], testId: string) => SelectorPart[];
|
|
713
|
+
};
|
|
714
|
+
};
|
|
715
|
+
};
|
|
716
|
+
type LocatorRewrites = typeof locatorRewrites;
|
|
717
|
+
//#endregion
|
|
638
718
|
//#region ../web-extension/lib/permission/shared/permission.d.ts
|
|
639
719
|
/**
|
|
640
720
|
* The four categories a grant is asked and stored under. Every descriptor names one, so a key
|
|
@@ -654,7 +734,7 @@ type CategoryMeta = {
|
|
|
654
734
|
heading: string;
|
|
655
735
|
summary: string;
|
|
656
736
|
title: (site: string) => string;
|
|
657
|
-
/** `signedIn` is false when the
|
|
737
|
+
/** `signedIn` is false when the attach's wire carried `syncCookies: false`, which only a library that predates `cookies` sends; `cookies: 'native'` sends true */
|
|
658
738
|
description: (site: string, signedIn: boolean) => string;
|
|
659
739
|
cloudTitle: (site: string) => string;
|
|
660
740
|
cloudDescription: (site: string) => string;
|
|
@@ -888,7 +968,20 @@ declare const permissions: {
|
|
|
888
968
|
};
|
|
889
969
|
//#endregion
|
|
890
970
|
//#region ../web-extension/lib/lib/frame-core.d.ts
|
|
891
|
-
|
|
971
|
+
/**
|
|
972
|
+
* Elements in an attached frame, found again on every call. Playwright's members where FKN has
|
|
973
|
+
* Playwright's meaning, plus `exists`, `videoElement` and the `reason` option. `last()` is the last
|
|
974
|
+
* match; `contentFrame()` enters the iframe a trailing `locator(selector)` matches, as
|
|
975
|
+
* `frameLocator(selector)` would, and is a TypeError on a locator that ends in anything else.
|
|
976
|
+
*/
|
|
977
|
+
type Locator = Locator$1<LocatorModules, LocatorRewrites>;
|
|
978
|
+
/**
|
|
979
|
+
* A frame inside an attached frame, entered with `frameLocator(selector)`. Its document is read
|
|
980
|
+
* as the attached frame's is. `owner()` is Playwright's: a `Locator` on the iframe it entered, whose
|
|
981
|
+
* `contentFrame()` comes back here. `getByTestId` searches from its document root. `evaluate` and
|
|
982
|
+
* `addScriptTag` run on the attached frame only, so neither is offered here.
|
|
983
|
+
*/
|
|
984
|
+
type FrameLocator = FrameLocator$1<LocatorModules, LocatorRewrites>;
|
|
892
985
|
declare const attachFramePermission: {
|
|
893
986
|
readonly scope: 'embed.iframe';
|
|
894
987
|
readonly category: 'interaction';
|
|
@@ -903,28 +996,81 @@ declare const gotoPermission: {
|
|
|
903
996
|
readonly title: 'Open a website inside this app';
|
|
904
997
|
readonly description: 'Lets the app navigate to another site without leaving its window.';
|
|
905
998
|
};
|
|
999
|
+
/**
|
|
1000
|
+
* `frame.goto`'s options. Refused with a TypeError before anything is sent: a `waitUntil` other than
|
|
1001
|
+
* `'load'` or `'commit'` (Playwright's `'domcontentloaded'` and `'networkidle'` are not served, and
|
|
1002
|
+
* `'documentstart'` is now `'commit'`), a `timeout` of 0 or below or not finite, and `timeoutMs`.
|
|
1003
|
+
*/
|
|
906
1004
|
type GotoOptions = {
|
|
907
1005
|
/**
|
|
908
|
-
* When `goto` resolves: `'load'`, the default, once the document it brings fired load;
|
|
909
|
-
*
|
|
910
|
-
* Either way a call made after it runs on the document the goto
|
|
911
|
-
*
|
|
912
|
-
*
|
|
913
|
-
* until it comes, each within its own timeout. If that document has not come by the goto's deadline,
|
|
914
|
-
* `evaluate` and `postMessage` reject, and a locator call runs on whatever document the frame holds,
|
|
915
|
-
* since the goto itself already resolved; on the extension the goto rejects instead.
|
|
1006
|
+
* When `goto` resolves: `'load'`, the default, once the document it brings fired load; `'commit'`,
|
|
1007
|
+
* Playwright's, once that document holds the frame, possibly before the page's own scripts ran and
|
|
1008
|
+
* whether or not it ever fires load. Either way a call made after it runs on the document the goto
|
|
1009
|
+
* brought, never on the one it replaced, and the goto rejects with `TimeoutError` when that
|
|
1010
|
+
* document has not come by its deadline.
|
|
916
1011
|
*
|
|
917
1012
|
* A goto that changes only the fragment of the url the page is at keeps its document. On the cloud
|
|
918
|
-
* backend
|
|
919
|
-
*
|
|
920
|
-
*
|
|
921
|
-
*
|
|
922
|
-
* `'
|
|
923
|
-
|
|
1013
|
+
* backend it resolves, either way, once the page reports the new fragment. Two pages are the
|
|
1014
|
+
* exception there, where such a goto brings a new document like any other: one reached through a
|
|
1015
|
+
* redirect, and one that followed a link onto another origin. On the extension (measured on
|
|
1016
|
+
* Chromium) one awaited to `'load'` resolves, since the frame fires load for it, and one awaited to
|
|
1017
|
+
* `'commit'` runs out at its timeout, since no new document starts.
|
|
1018
|
+
*/
|
|
1019
|
+
waitUntil?: 'commit' | 'load';
|
|
1020
|
+
/**
|
|
1021
|
+
* How long the goto may take, in milliseconds: 30000 when absent. Past it the goto rejects with
|
|
1022
|
+
* `TimeoutError`. A positive number: 0 is a TypeError, since every call ends by its deadline and
|
|
1023
|
+
* so does not take Playwright's "0 disables the timeout".
|
|
924
1024
|
*/
|
|
925
|
-
|
|
1025
|
+
timeout?: number;
|
|
926
1026
|
domains?: string[];
|
|
927
1027
|
};
|
|
1028
|
+
/** `frame.addScriptTag`'s options, Playwright's `content` and FKN's `sourceUrl`. */
|
|
1029
|
+
type AddScriptTagOptions = {
|
|
1030
|
+
/** The script's source text. */
|
|
1031
|
+
content: string;
|
|
1032
|
+
/** Names the script in stack traces through `//# sourceURL`. Absent, its frames name the document. */
|
|
1033
|
+
sourceUrl?: string;
|
|
1034
|
+
};
|
|
1035
|
+
/**
|
|
1036
|
+
* `frame.clearCookies`' options, Playwright's `browserContext.clearCookies` names with its string
|
|
1037
|
+
* semantics: each matches exactly. A cookie is removed when it matches every option given; an
|
|
1038
|
+
* option left out, or `undefined`, matches every cookie. Playwright also takes a RegExp for each,
|
|
1039
|
+
* which FKN refuses for now (`Frame.clearCookies` says why).
|
|
1040
|
+
*/
|
|
1041
|
+
type ClearCookiesOptions = {
|
|
1042
|
+
/** Only cookies with this name. */
|
|
1043
|
+
name?: string;
|
|
1044
|
+
/**
|
|
1045
|
+
* Only cookies with this domain, in the form Playwright reports it: `.youtube.com` for a cookie
|
|
1046
|
+
* its subdomains also receive, `www.youtube.com` for a host-only one, so `'youtube.com'` matches
|
|
1047
|
+
* neither of those. It must be on a site this attachment reaches.
|
|
1048
|
+
*/
|
|
1049
|
+
domain?: string;
|
|
1050
|
+
/** Only cookies with this path, exactly as the cookie carries it. */
|
|
1051
|
+
path?: string;
|
|
1052
|
+
};
|
|
1053
|
+
/**
|
|
1054
|
+
* One `clearCookies` option as it crosses a channel, in the shapes Playwright's own wire carries: a
|
|
1055
|
+
* string as `equals`, a RegExp as its source and flags. The library sends `equals` only for now and
|
|
1056
|
+
* the middle page refuses a pattern; the render proxy shell still reads one.
|
|
1057
|
+
*/
|
|
1058
|
+
type CookieMatchWire = {
|
|
1059
|
+
equals: string;
|
|
1060
|
+
} | {
|
|
1061
|
+
pattern: string;
|
|
1062
|
+
flags: string;
|
|
1063
|
+
};
|
|
1064
|
+
/**
|
|
1065
|
+
* `frame.clearCookies`' options as `createFrame` hands them to `FrameBackend.clearCookies`, already
|
|
1066
|
+
* checked, and as the cloud's channels carry them. Only the options given are present, so no options
|
|
1067
|
+
* at all are `{}`; an absent one matches every cookie.
|
|
1068
|
+
*/
|
|
1069
|
+
type ClearCookiesWire = {
|
|
1070
|
+
name?: CookieMatchWire;
|
|
1071
|
+
domain?: CookieMatchWire;
|
|
1072
|
+
path?: CookieMatchWire;
|
|
1073
|
+
};
|
|
928
1074
|
/** `frame.postMessage`'s options form, as `Window.postMessage` takes it. */
|
|
929
1075
|
type FramePostMessageOptions = {
|
|
930
1076
|
/** The page's origin as the site knows it, or `'*'`, the default. */
|
|
@@ -976,16 +1122,30 @@ type FrameEventListener<K extends keyof FrameEventMap> = (event: FrameEventMap[K
|
|
|
976
1122
|
* window or a new one, a popup). A document with nothing of the page's own to run it in, such as an
|
|
977
1123
|
* error page or a file that is not HTML, cannot be read, and a call on it waits to its deadline.
|
|
978
1124
|
*/
|
|
979
|
-
type Frame = Omit<FrameLocator
|
|
1125
|
+
type Frame = Omit<FrameLocator, 'owner'> & {
|
|
1126
|
+
/**
|
|
1127
|
+
* Navigates the frame to `url`, which must pass the rules an iframe src does, and adds its host
|
|
1128
|
+
* to the attachment. Resolves at `options.waitUntil`, and rejects with `TimeoutError` past
|
|
1129
|
+
* `options.timeout` (`GotoOptions`).
|
|
1130
|
+
*/
|
|
980
1131
|
goto(url: string, options?: GotoOptions): Promise<void>;
|
|
981
1132
|
/** The url last given to `attachFrame` or `goto`, never the frame's live location: a page that moves itself does not change it. */
|
|
982
1133
|
url(): string;
|
|
1134
|
+
/**
|
|
1135
|
+
* Which backend serves this attachment, fixed for its life. The same call can draw a card on one
|
|
1136
|
+
* backend and not the other, and spends a different identity on each, so an app must be able to
|
|
1137
|
+
* tell. A method, as Playwright's scalar facts are (`frame.url()`, `frame.name()`,
|
|
1138
|
+
* `page.isClosed()`). Undefined only for a Frame an app built itself with `createFrame` from a
|
|
1139
|
+
* backend that names none.
|
|
1140
|
+
*/
|
|
1141
|
+
backend(): 'cloud' | 'extension' | undefined;
|
|
983
1142
|
/**
|
|
984
1143
|
* Asks for whole categories on this attachment's hosts, before any call. Resolves per request, in
|
|
985
1144
|
* the order they were asked; a refusal is `allow: false`, never a rejection. An ask naming a
|
|
986
1145
|
* category or key the registry cannot place on a row is a `TypeError`, thrown before it is sent.
|
|
1146
|
+
* Not Playwright's `page.request`, which is an HTTP client; the app asks here and the user grants.
|
|
987
1147
|
*/
|
|
988
|
-
|
|
1148
|
+
requestPermissions(requests: CategoryRequest[]): Promise<CategoryGrant[]>;
|
|
989
1149
|
/**
|
|
990
1150
|
* Runs `pageFunction` inside the attached site's OWN page realm, as a script of that page would:
|
|
991
1151
|
* it sees the site's `window`, its globals and its DOM. The function is sent as source
|
|
@@ -994,21 +1154,26 @@ type Frame = Omit<FrameLocator<LocatorModules>, 'evaluate'> & {
|
|
|
994
1154
|
* does, and is not called. A promise, returned by the function or produced by the expression, is
|
|
995
1155
|
* awaited.
|
|
996
1156
|
*
|
|
997
|
-
* `arg`
|
|
998
|
-
*
|
|
1157
|
+
* `arg` is structured-cloned at the call, in the app's realm, on both backends, and the result
|
|
1158
|
+
* comes back by structured clone, so an `ArrayBuffer` or a typed array of bytes survives the round
|
|
1159
|
+
* trip. A value structured clone refuses in `arg` (a function, a DOM node, an untransferred port)
|
|
1160
|
+
* rejects with the platform's `DataCloneError` before anything is sent; a port goes to the page
|
|
1161
|
+
* with `postMessage`. A thrown error or a rejected promise comes back as an `Error` carrying
|
|
999
1162
|
* the page's own name and message. A result that cannot be cloned (a function, a DOM node) is a
|
|
1000
1163
|
* `LocatorInvalidError`, never a silent `undefined` and never a live handle into the page.
|
|
1001
1164
|
*
|
|
1002
|
-
* Every limit is
|
|
1003
|
-
* - time, both backends: the code has 30 seconds to settle, counted after any consent card
|
|
1004
|
-
* the wait ends there; code that never settles
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
1008
|
-
*
|
|
1165
|
+
* Every limit is refused by name, never a call left pending:
|
|
1166
|
+
* - time, both backends: the code has 30 seconds to settle, counted after any consent card, and
|
|
1167
|
+
* then the call rejects with `TimeoutError`. Only the wait ends there; code that never settles
|
|
1168
|
+
* keeps running in the page.
|
|
1169
|
+
* - size, extension only, a `LocatorInvalidError`: the source with its `arg`, and the result, each
|
|
1170
|
+
* carry at most 32 MiB (binary data by its bytes, text by its UTF-8 size), the most its message
|
|
1171
|
+
* relay carries.
|
|
1172
|
+
* - `Blob`, extension only, a `LocatorInvalidError`: the relay cannot carry one, so pass or return
|
|
1173
|
+
* `await blob.arrayBuffer()`. The cloud backend has neither limit, and returns a `Blob` as a `Blob`.
|
|
1009
1174
|
*
|
|
1010
1175
|
* Needs the Evaluation grant on both backends; an app without it is refused by name. It runs on the
|
|
1011
|
-
* attached frame only: a
|
|
1176
|
+
* attached frame only: a nested `FrameLocator` does not offer it, and a call there anyway is refused.
|
|
1012
1177
|
*
|
|
1013
1178
|
* Called after `goto` resolved, whichever `waitUntil`, it runs once on the document that goto
|
|
1014
1179
|
* brought, never on the one it replaced. On the cloud backend the call waits for that document when
|
|
@@ -1020,10 +1185,118 @@ type Frame = Omit<FrameLocator<LocatorModules>, 'evaluate'> & {
|
|
|
1020
1185
|
* with `ExtensionOperationUnsupportedError`), and it runs where the page's content security policy
|
|
1021
1186
|
* allows it: a frame whose host the app declared has its CSP replaced, so code runs; an undeclared
|
|
1022
1187
|
* frame keeps its CSP, and a page that forbids `eval` refuses with a named error. On the cloud
|
|
1023
|
-
* backend the code runs in the proxied document's realm, which mirage virtualizes
|
|
1024
|
-
*
|
|
1188
|
+
* backend the code runs in the proxied document's realm, which mirage virtualizes: the page's own
|
|
1189
|
+
* eval refusal and Trusted Types requirement do not refuse the source `evaluate` compiles, and every
|
|
1190
|
+
* string that code compiles itself (`eval`, `Function`, a string timer) is held to them, as the
|
|
1191
|
+
* page's own are.
|
|
1025
1192
|
*/
|
|
1026
1193
|
evaluate<R = unknown, A = undefined>(pageFunction: ((arg: A) => R | Promise<R>) | string, arg?: A): Promise<Awaited<R>>;
|
|
1194
|
+
/**
|
|
1195
|
+
* Runs `content` as a classic inline script of the attached document, as one of that page's own
|
|
1196
|
+
* scripts would run: its top-level declarations stay on the page's global for later scripts and
|
|
1197
|
+
* `evaluate` calls, `document.currentScript` is the script while it runs, and the page's own error
|
|
1198
|
+
* listeners see its top-level error. Mirage rewrites it as it rewrites the page's scripts, and the
|
|
1199
|
+
* page's eval refusal and Trusted Types requirement do not refuse it, as for `evaluate`.
|
|
1200
|
+
* Playwright's name and its `content` option; its `url`, `path` and `type` are not served, and FKN's
|
|
1201
|
+
* `sourceUrl` names the script rather than loading one.
|
|
1202
|
+
*
|
|
1203
|
+
* Resolves `undefined` once the script ran; what it installed lives as long as the document, and the
|
|
1204
|
+
* `document` event says when that is gone. Same grant, limit and timing as `evaluate`: the
|
|
1205
|
+
* Evaluation grant (one card covers both), 30000 ms counted after any consent card, the attached
|
|
1206
|
+
* frame only, and after a `goto` the document that goto brought, waited for as `evaluate` waits. It
|
|
1207
|
+
* runs once: it never rides the locator retry loop, and a call whose document left before it
|
|
1208
|
+
* answered rejects and is not run again. Cloud only for now: the extension refuses it by name.
|
|
1209
|
+
*
|
|
1210
|
+
* Refused:
|
|
1211
|
+
* - TypeError, before anything is sent, in this order: `frame.addScriptTag: options must be an
|
|
1212
|
+
* object { content }`; for Playwright's `url`, `path` and `type`, `frame.addScriptTag: "<key>" is
|
|
1213
|
+
* not served; it runs content as a classic inline script`; `frame.addScriptTag: unknown option
|
|
1214
|
+
* "<key>"`; `frame.addScriptTag: content must be a string`; `frame.addScriptTag: sourceUrl must
|
|
1215
|
+
* be a non-empty string with no line break`.
|
|
1216
|
+
* - an `Error` carrying the page's own name and message: the script's top-level throw, after it ran.
|
|
1217
|
+
* - `LocatorDeniedError`: no Evaluation grant, the frame holds no page, or its document is outside
|
|
1218
|
+
* the attachment. Against an FKN page that predates `addScriptTag` the call arrives with no proof
|
|
1219
|
+
* of a grant and the render proxy refuses it: `frame.addScriptTag: the call arrived without an
|
|
1220
|
+
* Evaluation grant, so it was not run`.
|
|
1221
|
+
* - cloud, `LocatorUnsupportedError` `frame.addScriptTag: this render proxy predates addScriptTag;
|
|
1222
|
+
* reload the app`.
|
|
1223
|
+
* - cloud, `LocatorError`: the document of the goto before it had not come by that goto's deadline,
|
|
1224
|
+
* or the app started another goto first, so the script was not run.
|
|
1225
|
+
* - extension, `ExtensionOperationUnsupportedError` (operation `'addScriptTag'`)
|
|
1226
|
+
* `frame.addScriptTag: an extension frame does not run scripts through mirage yet; attach with
|
|
1227
|
+
* cloud.attachFrame`, before anything is dispatched.
|
|
1228
|
+
* - `TimeoutError` `frame.addScriptTag: no answer within 30000ms; the script may or may not have
|
|
1229
|
+
* run`.
|
|
1230
|
+
* - the terminal detach error once the attachment ended.
|
|
1231
|
+
*/
|
|
1232
|
+
addScriptTag(options: AddScriptTagOptions): Promise<void>;
|
|
1233
|
+
/**
|
|
1234
|
+
* Removes cookies from this attachment's cookie jar, as Playwright's
|
|
1235
|
+
* `browserContext.clearCookies` removes them from a context. With no options it removes every
|
|
1236
|
+
* cookie of the sites this attachment reaches; with options, only the ones that match every option
|
|
1237
|
+
* given (`ClearCookiesOptions`). Each option is a string for now: a RegExp is refused.
|
|
1238
|
+
*
|
|
1239
|
+
* For signing out of a site the user signed in to inside an FKN frame: that session lives in FKN's
|
|
1240
|
+
* jar, never in the app, so the app cannot remove it any other way.
|
|
1241
|
+
*
|
|
1242
|
+
* Which jar: with `cookies: 'persistent'`, the default, the cloud jar of the app's top-level site,
|
|
1243
|
+
* which every app of that site shares (every fkn.app app shares one), so a removal there signs
|
|
1244
|
+
* every one of those apps out of that site. With `'ephemeral'` the attachment's own jar.
|
|
1245
|
+
*
|
|
1246
|
+
* Which cookies: only those of a site this attachment reaches, a site being a host's registered
|
|
1247
|
+
* domain under the Public Suffix List, private section included: the attach url's host (the empty
|
|
1248
|
+
* page's, for `blank`), each goto target's host from the goto's send, and `domains`.
|
|
1249
|
+
* `www.youtube.com` reaches every `*.youtube.com` cookie and no `google.com` one, the rule browsers
|
|
1250
|
+
* follow for `Clear-Site-Data: "cookies"`. A host under the same name is still another site when a
|
|
1251
|
+
* suffix lies between: `amazonaws.com` reaches no `mybucket.s3.amazonaws.com` cookie, since
|
|
1252
|
+
* `s3.amazonaws.com` is a suffix. A host that is itself a public suffix (`com`, `co.uk`,
|
|
1253
|
+
* `github.io`) is no site, and reaches only the cookies set for exactly that host. A Partitioned
|
|
1254
|
+
* cookie matches in every partition.
|
|
1255
|
+
*
|
|
1256
|
+
* Once it resolves: no request a document of this attachment starts carries a removed cookie, its
|
|
1257
|
+
* documents' `document.cookie` lists none, and the removal is committed to the jar, so an
|
|
1258
|
+
* attachment created afterwards never sees one. Another live attachment on the same jar (another
|
|
1259
|
+
* tab, another app's frame) drops them when it hears the commit, normally within milliseconds; a
|
|
1260
|
+
* request it started before then may still carry one. A request already in flight keeps what it
|
|
1261
|
+
* was sent with, and a later response may set cookies again, as in any browser.
|
|
1262
|
+
*
|
|
1263
|
+
* It resolves `undefined` and never says what or how much it removed, so it cannot tell an app
|
|
1264
|
+
* whether the user had a session on a site. It takes the same steps and the same store write
|
|
1265
|
+
* whether or not a cookie matched, so neither how long it takes nor which refusal it meets says so
|
|
1266
|
+
* either. That is why a RegExp is refused before anything is sent: it would be tested in the render
|
|
1267
|
+
* proxy against cookies the app cannot read, and a pattern slow on some of them would make the
|
|
1268
|
+
* call's duration, or a `TimeoutError`, say whether the jar holds one. Calling it again is
|
|
1269
|
+
* harmless. It does not tell the site: the session stays valid there until it lapses, and FKN no
|
|
1270
|
+
* longer holds it.
|
|
1271
|
+
*
|
|
1272
|
+
* No consent card on either jar, and a frame holding no page is served. Cloud only. It runs once,
|
|
1273
|
+
* never inside the locator retry loop, and waits at most 30000 ms.
|
|
1274
|
+
*
|
|
1275
|
+
* Refused:
|
|
1276
|
+
* - TypeError, before anything is sent, in this order: `frame.clearCookies: options must be an
|
|
1277
|
+
* object`; `frame.clearCookies: unknown option "<key>"`; `frame.clearCookies: <key> is a RegExp,
|
|
1278
|
+
* and clearCookies takes strings for name, domain and path for now`; `frame.clearCookies: <key>
|
|
1279
|
+
* must be a string`; `frame.clearCookies: <key> must not be empty; leave it out to match every
|
|
1280
|
+
* <key>`.
|
|
1281
|
+
* - `LocatorDeniedError` `frame.clearCookies: this attachment reaches no site yet; attach a url,
|
|
1282
|
+
* goto one, or declare it in domains`.
|
|
1283
|
+
* - `LocatorDeniedError` `frame.clearCookies: <domain> is not on a site this attachment reaches;
|
|
1284
|
+
* goto it or declare it in domains`, for a string `domain`.
|
|
1285
|
+
* - cloud, `LocatorUnsupportedError` `frame.clearCookies: this FKN page predates clearCookies;
|
|
1286
|
+
* reload the app to load the current one`, with nothing sent.
|
|
1287
|
+
* - cloud, `LocatorUnsupportedError` `frame.clearCookies: this render proxy predates clearCookies;
|
|
1288
|
+
* reload the app`.
|
|
1289
|
+
* - cloud, `Error` `frame.clearCookies: the cookies are gone from this attachment, but its jar did
|
|
1290
|
+
* not take the removal, so other attachments may still send them; call it again`.
|
|
1291
|
+
* - cloud, `TimeoutError` `frame.clearCookies: the render proxy did not answer within 30000ms; the
|
|
1292
|
+
* cookies may or may not be gone, and calling it again is safe`.
|
|
1293
|
+
* - extension, `ExtensionOperationUnsupportedError` (operation `'clearCookies'`)
|
|
1294
|
+
* `frame.clearCookies: an extension frame runs on the browser's own cookies (cookies: 'native'),
|
|
1295
|
+
* which FKN does not clear; attach with cookies: 'persistent' to clear the app's jar`, before
|
|
1296
|
+
* anything is dispatched.
|
|
1297
|
+
* - the terminal detach error once the attachment ended.
|
|
1298
|
+
*/
|
|
1299
|
+
clearCookies(options?: ClearCookiesOptions): Promise<void>;
|
|
1027
1300
|
/**
|
|
1028
1301
|
* Delivers `message` to the page in the frame as a real `message` event, the way
|
|
1029
1302
|
* `iframe.contentWindow.postMessage` would. The page sees a trusted event: `data` is the message,
|
|
@@ -1080,22 +1353,69 @@ type Frame = Omit<FrameLocator<LocatorModules>, 'evaluate'> & {
|
|
|
1080
1353
|
* and not for the document the frame already held when the first listener was added. Extension:
|
|
1081
1354
|
* fires on every load of the frame, with `origin` `''`.
|
|
1082
1355
|
*
|
|
1083
|
-
* Listeners stay on the Frame across navigations and end with the attachment
|
|
1084
|
-
*
|
|
1085
|
-
*
|
|
1356
|
+
* Listeners stay on the Frame across navigations and end with the attachment, or when `signal`
|
|
1357
|
+
* aborts, FKN's addition to Playwright's `on`. A listener added twice is called once, and one whose
|
|
1358
|
+
* signal already aborted is not added. A listener that throws is reported and does not stop the
|
|
1359
|
+
* others. An unknown `type`, or a listener that is not a function, is a `TypeError`. On the cloud
|
|
1360
|
+
* backend, against an FKN page that predates messaging, nothing arrives and the console says so once.
|
|
1086
1361
|
*/
|
|
1087
|
-
|
|
1362
|
+
on<K extends keyof FrameEventMap>(type: K, listener: FrameEventListener<K>, options?: {
|
|
1088
1363
|
signal?: AbortSignal;
|
|
1089
1364
|
}): void;
|
|
1090
|
-
|
|
1365
|
+
/** Removes a listener `on` added; one that is not on the Frame is ignored. An unknown `type` is a `TypeError`. */
|
|
1366
|
+
off<K extends keyof FrameEventMap>(type: K, listener: FrameEventListener<K>): void;
|
|
1091
1367
|
};
|
|
1368
|
+
/**
|
|
1369
|
+
* Which cookie jar an attachment runs on, and with it which backend serves it. One attachment, one
|
|
1370
|
+
* jar: no value unions two jars, so which cookie a request carries always has one answer. HttpOnly
|
|
1371
|
+
* values never reach app code on any value.
|
|
1372
|
+
*
|
|
1373
|
+
* - `'persistent'`, the default: the cloud render proxy's jar of the app's top-level site
|
|
1374
|
+
* (https://fkn.app for every fkn.app app), which every app of that site shares, the same jar its
|
|
1375
|
+
* inline frames and its windows use, kept across visits. Always the cloud backend, whatever is
|
|
1376
|
+
* installed, so `frame.backend()` answers `'cloud'`. Its requests leave through WebVPN, which
|
|
1377
|
+
* keeps the cookies their answers set.
|
|
1378
|
+
* - `'ephemeral'`: a fresh jar of the attachment's own, with site storage under a namespace of its
|
|
1379
|
+
* own, both gone with it. Always the cloud backend: the browser keeps a partition's cookies after
|
|
1380
|
+
* its frame goes, so no extension jar ends with the attachment. Its requests leave through WebVPN.
|
|
1381
|
+
* - `'native'`: the person's own browser cookies for `domains` and every goto's host, copied into
|
|
1382
|
+
* the browser's partition for the app's top-level site on the attach and on every goto. Extension
|
|
1383
|
+
* backend only, so `frame.backend()` answers `'extension'`. Without the extension the top-level
|
|
1384
|
+
* `attachFrame` shows the install prompt, as every extension-only call does; `cloud.attachFrame`
|
|
1385
|
+
* refuses it.
|
|
1386
|
+
*
|
|
1387
|
+
* Refused by name before anything is attached, opened, waited for or dispatched, in this order:
|
|
1388
|
+
* - any `syncCookies` key, true and false alike: TypeError `attachFrame: syncCookies was replaced
|
|
1389
|
+
* by cookies. true is cookies: 'persistent', or 'native' for the person's own browser cookies on
|
|
1390
|
+
* the extension; false is cookies: 'ephemeral'`
|
|
1391
|
+
* - an unknown value: TypeError `attachFrame: cookies must be 'persistent', 'ephemeral' or
|
|
1392
|
+
* 'native', not "<value>"`
|
|
1393
|
+
* - any `storageState` key: TypeError `attachFrame: storageState is not available yet`
|
|
1394
|
+
* - then the shape of the attachment: `iframe` and `window` at once, and `lockdown` or `blank` with
|
|
1395
|
+
* a window, each a TypeError
|
|
1396
|
+
* - `lockdown` with anything but `'native'`: TypeError `attachFrame: lockdown runs on the
|
|
1397
|
+
* extension, which serves only cookies: 'native'`
|
|
1398
|
+
* - `cloud.attachFrame` with `'native'`: TypeError `cloud.attachFrame: cookies: 'native' needs the
|
|
1399
|
+
* FKN browser extension; the cloud render proxy has no browser cookies`
|
|
1400
|
+
* - `extension.attachFrame` with `'persistent'` or `'ephemeral'`, so also with no `cookies` at all:
|
|
1401
|
+
* `ExtensionOperationUnsupportedError` (operation `'cookies'`) `attachFrame: cookies: '<value>'
|
|
1402
|
+
* runs on the cloud render proxy; call cloud.attachFrame or the top-level attachFrame`
|
|
1403
|
+
* - a window on `'native'`, through the top-level `attachFrame` or `extension.attachFrame`:
|
|
1404
|
+
* `ExtensionOperationUnsupportedError` (operation `'attachWindow'`) `attachFrame: a window on
|
|
1405
|
+
* cookies: 'native' is not served yet; a window runs on the cloud render proxy, which has no
|
|
1406
|
+
* browser cookies`, with no install prompt, so the click's activation is left for the app's
|
|
1407
|
+
* fallback
|
|
1408
|
+
*/
|
|
1409
|
+
type AttachCookies = 'persistent' | 'ephemeral' | 'native';
|
|
1092
1410
|
type AttachFrameOptions = {
|
|
1093
1411
|
iframe: HTMLIFrameElement;
|
|
1094
1412
|
domains?: string[];
|
|
1095
|
-
|
|
1413
|
+
/** Which jar, and with it which backend: `'persistent'` when absent. See `AttachCookies`. */
|
|
1414
|
+
cookies?: AttachCookies;
|
|
1096
1415
|
/**
|
|
1097
1416
|
* Replace the embedded site's CSP with a lockdown policy: the frame cannot fetch, connect, or load
|
|
1098
|
-
* any resource. Extension backend only
|
|
1417
|
+
* any resource. Extension backend only, so it takes `cookies: 'native'`; beside any other value it
|
|
1418
|
+
* is a TypeError (see `AttachCookies`). It needs an extension that announces an ABI: an older one
|
|
1099
1419
|
* may not serve it, so the attach is refused with `ExtensionOperationUnsupportedError` (operation
|
|
1100
1420
|
* `'lockdown'`) before anything is attached.
|
|
1101
1421
|
*/
|
|
@@ -1105,6 +1425,67 @@ type AttachFrameOptions = {
|
|
|
1105
1425
|
* refusal does not reject the attach: it surfaces on the first refused operation.
|
|
1106
1426
|
*/
|
|
1107
1427
|
permissions?: CategoryRequest[];
|
|
1428
|
+
/**
|
|
1429
|
+
* Starts the frame on an empty page presented at `blank.url`, with nothing requested from that
|
|
1430
|
+
* site for it. For running the app's own code (an attestation VM, a session client) in the origin
|
|
1431
|
+
* it needs, without loading or running the site's page.
|
|
1432
|
+
*
|
|
1433
|
+
* The document is exactly
|
|
1434
|
+
* `<!doctype html><html><head><meta charset="utf-8"></head><body></body></html>`, served 200 with
|
|
1435
|
+
* `content-type: text/html; charset=utf-8` and `cache-control: no-store`: no content security
|
|
1436
|
+
* policy, no Set-Cookie. Its `location`, `origin`, `document.URL`, `document.domain` and
|
|
1437
|
+
* `baseURI` read `blank.url`, and `document.referrer` reads `''` on the first load (after a reload
|
|
1438
|
+
* it reads the page's own url, as on any proxied page). `url()` returns it. `evaluate`,
|
|
1439
|
+
* `postMessage` and the `message` and `document` events work as on any page. Requests the page's
|
|
1440
|
+
* code makes later go out as that page's would, through WebVPN, on the attachment's jar: with
|
|
1441
|
+
* `cookies: 'persistent'`, the default, the cloud jar of the app's top-level site, which every app
|
|
1442
|
+
* of that site shares (HttpOnly values are never readable in the page); with `'ephemeral'` a jar
|
|
1443
|
+
* of the attachment's own, and site storage under a namespace of its own, both gone with it.
|
|
1444
|
+
*
|
|
1445
|
+
* With `cookies: 'ephemeral'` nothing of the user's is reachable, so calls the Evaluation grant
|
|
1446
|
+
* covers ask no card while the frame shows the empty page: until the attachment's first `goto`,
|
|
1447
|
+
* or until code in the page moves it to another url, even on the same host, after which they ask
|
|
1448
|
+
* as on any page. With `'persistent'` the Evaluation card names the url's host, as for any page.
|
|
1449
|
+
*
|
|
1450
|
+
* The empty page answers its url until the first `goto`: a reload of the page, or a replacement
|
|
1451
|
+
* of the render proxy's own document, brings it back and fires `document`, so an installer must
|
|
1452
|
+
* be idempotent. After the first `goto` the url loads from the site like any other.
|
|
1453
|
+
*
|
|
1454
|
+
* Always the cloud render proxy, with or without the extension: only it can present an origin
|
|
1455
|
+
* without loading it. `frame.backend()` then answers `'cloud'`, and the jar is the cloud's, never
|
|
1456
|
+
* the browser's.
|
|
1457
|
+
*
|
|
1458
|
+
* Refused, in this order, before anything is attached, and after the refusals of `cookies`
|
|
1459
|
+
* (`AttachCookies`), so through `cloud.attachFrame` lockdown and `'native'` meet those first:
|
|
1460
|
+
* - TypeError `attachFrame: blank must be an object { url }` (null, a string)
|
|
1461
|
+
* - TypeError `attachFrame: blank takes { url }, not "<key>"` (an unknown key)
|
|
1462
|
+
* - TypeError `attachFrame: blank.url must be an absolute http or https url, not "<value>"`
|
|
1463
|
+
* - TypeError `attachFrame: blank needs an iframe with no src; this one has "<src>"`
|
|
1464
|
+
* - TypeError `attachFrame: blank does not combine with lockdown`
|
|
1465
|
+
* - TypeError `attachFrame: blank runs on the cloud render proxy, which has no browser cookies;
|
|
1466
|
+
* pass cookies: 'persistent' or 'ephemeral'` (with `cookies: 'native'`)
|
|
1467
|
+
* - Error `attachFrame: refusing to target the extension's own pages or an FKN platform origin`,
|
|
1468
|
+
* the scope check every attach url meets
|
|
1469
|
+
* - Error `attachFrame: a blank page is served by the cloud render proxy, which this build does
|
|
1470
|
+
* not configure`
|
|
1471
|
+
*
|
|
1472
|
+
* After the handshake, with the iframe put back on about:blank and nothing requested from the
|
|
1473
|
+
* site: the terminal `LocatorUnsupportedError` `cloud.attachFrame: this FKN page predates blank
|
|
1474
|
+
* pages; reload the app to load the current one`. The handshake and ready limits are every cloud
|
|
1475
|
+
* attach's, 20000 ms and 65000 ms.
|
|
1476
|
+
*
|
|
1477
|
+
* Also refused, before anything opens or is dispatched: with `window`, the TypeError
|
|
1478
|
+
* `attachFrame: blank does not apply to a window`, since a window opened with no `url` is already
|
|
1479
|
+
* called blank there; and through `extension.attachFrame` with `cookies: 'native'`,
|
|
1480
|
+
* `ExtensionOperationUnsupportedError` (operation `'blank'`) `attachFrame: a blank page is served
|
|
1481
|
+
* by the cloud render proxy only; call cloud.attachFrame`.
|
|
1482
|
+
*/
|
|
1483
|
+
blank?: BlankPage;
|
|
1484
|
+
};
|
|
1485
|
+
/** Where `attachFrame`'s `blank` option presents its empty page. */
|
|
1486
|
+
type BlankPage = {
|
|
1487
|
+
/** Absolute http or https url the empty page is presented at. The fragment is ignored for matching. */
|
|
1488
|
+
url: string;
|
|
1108
1489
|
};
|
|
1109
1490
|
/** Where an attachment's window opens and how big it asks to be. */
|
|
1110
1491
|
type FrameWindowOptions = {
|
|
@@ -1130,12 +1511,14 @@ type AttachWindowOptions = {
|
|
|
1130
1511
|
window: FrameWindowOptions;
|
|
1131
1512
|
domains?: string[];
|
|
1132
1513
|
/**
|
|
1133
|
-
*
|
|
1134
|
-
* as that app's inline frames
|
|
1135
|
-
* those frames
|
|
1136
|
-
*
|
|
1514
|
+
* The window's jar, with an iframe's values (`AttachCookies`). `'persistent'`, the default: the
|
|
1515
|
+
* jar of the app that opened it, the same as that app's inline frames; a window whose app is on
|
|
1516
|
+
* another site shares cookies only with those frames, and its site storage stays its own.
|
|
1517
|
+
* `'ephemeral'`: a jar of the window's own that ends with it. Both run on the cloud backend
|
|
1518
|
+
* whatever is installed. `'native'` is refused by name: a window runs on the cloud render proxy,
|
|
1519
|
+
* and no backend serves a window on the browser's own cookies yet.
|
|
1137
1520
|
*/
|
|
1138
|
-
|
|
1521
|
+
cookies?: AttachCookies;
|
|
1139
1522
|
/** Whole categories asked for once the window has connected, drawn in the window on the cloud backend. */
|
|
1140
1523
|
permissions?: CategoryRequest[];
|
|
1141
1524
|
};
|
|
@@ -1182,15 +1565,41 @@ declare class FrameWindowRefusedError extends Error {
|
|
|
1182
1565
|
type FrameBackend = {
|
|
1183
1566
|
executor: Executor;
|
|
1184
1567
|
gate?: Gate;
|
|
1568
|
+
/**
|
|
1569
|
+
* The backend's name, which `Frame.backend()` answers. Optional so a caller of `createFrame` that
|
|
1570
|
+
* builds its own backend keeps compiling; absent, `Frame.backend()` answers `undefined`.
|
|
1571
|
+
*/
|
|
1572
|
+
backend?: 'cloud' | 'extension';
|
|
1573
|
+
/**
|
|
1574
|
+
* Navigates, `options` already checked by `Frame.goto`: the backend maps `waitUntil: 'commit'` and
|
|
1575
|
+
* `timeout` to its own wire's names, rejects with `TimeoutError` at the deadline, and is never
|
|
1576
|
+
* handed `'documentstart'`.
|
|
1577
|
+
*/
|
|
1185
1578
|
goto(url: string, options?: GotoOptions): Promise<void>;
|
|
1186
1579
|
url(): string;
|
|
1187
|
-
|
|
1580
|
+
requestPermissions?(requests: CategoryRequest[]): Promise<CategoryGrant[]>;
|
|
1188
1581
|
/**
|
|
1189
1582
|
* Runs already-stringified source in the attached site's own realm and answers the cloned result.
|
|
1190
1583
|
* The backend gates it (Evaluation) and runs it where the site's globals live. Optional so a
|
|
1191
1584
|
* backend that cannot run code refuses `Frame.evaluate` by name rather than answering as if it had.
|
|
1192
1585
|
*/
|
|
1193
1586
|
evaluate?(source: string, arg: unknown): Promise<unknown>;
|
|
1587
|
+
/**
|
|
1588
|
+
* Runs `content` as a classic inline script of the attached document and resolves once it ran,
|
|
1589
|
+
* `options` already checked by `Frame.addScriptTag`. The backend gates it (Evaluation), runs it once
|
|
1590
|
+
* and never through the locator retry loop. Optional so a backend that cannot run scripts refuses
|
|
1591
|
+
* `Frame.addScriptTag` by name.
|
|
1592
|
+
*/
|
|
1593
|
+
addScriptTag?(content: string, options: {
|
|
1594
|
+
sourceUrl?: string;
|
|
1595
|
+
}): Promise<void>;
|
|
1596
|
+
/**
|
|
1597
|
+
* Removes the cookies `filter` matches from the attachment's jar, `filter` already checked and
|
|
1598
|
+
* serialized by `Frame.clearCookies`, and resolves `undefined` whatever was removed. Called once,
|
|
1599
|
+
* never through the locator retry loop and never gated. Optional so a backend with no jar of its
|
|
1600
|
+
* own refuses `Frame.clearCookies` by name.
|
|
1601
|
+
*/
|
|
1602
|
+
clearCookies?(filter: ClearCookiesWire): Promise<void>;
|
|
1194
1603
|
/**
|
|
1195
1604
|
* Delivers a message to the page, `targetOrigin` already normalized (`'*'` or a serialized origin)
|
|
1196
1605
|
* and `transfer` an array. Called synchronously by `Frame.postMessage`, so transfers detach at the
|
|
@@ -1224,6 +1633,11 @@ type AttachFrameFunction = {
|
|
|
1224
1633
|
//#endregion
|
|
1225
1634
|
//#region ../web-extension/lib/lib/frame.d.ts
|
|
1226
1635
|
declare const ATTACH_FRAME_EVENT_KEY = "FKN_WEB_EXTENSION_ATTACH_FRAME_EVENT_KEY";
|
|
1636
|
+
/**
|
|
1637
|
+
* Attaches through the extension, on `cookies: 'native'` only: the other values, the default
|
|
1638
|
+
* among them, are the cloud render proxy's, refused here with `ExtensionOperationUnsupportedError`
|
|
1639
|
+
* (operation `'cookies'`) before any exposure wait (`AttachCookies`).
|
|
1640
|
+
*/
|
|
1227
1641
|
declare const attachFrame: AttachFrameFunction;
|
|
1228
1642
|
//#endregion
|
|
1229
|
-
export {
|
|
1643
|
+
export { SelectorPart as $, gotoPermission as A, handleRevivableModules as B, FrameWindowRefusal as C, WindowFrame as D, Locator as E, PermissionRequest as F, createVideoElementHandle as G, RemoteVideoElement as H, permissions as I, type as J, isType as K, CATEGORIES as L, CategoryRequest as M, LegacyPermissionRequest as N, attachFramePermission as O, PermissionGrant as P, OperationRequest as Q, CategoryMeta as R, FrameWindowOptions as S, GotoOptions as T, VideoElementState as U, BoxedVideoElement as V, box as W, Gate as X, Executor as Y, GateTools as Z, FrameEventMap as _, AttachCookies as a, FramePostMessageOptions as b, BlankPage as c, CookieMatchWire as d, Frame as f, FrameEventListener as g, FrameDocumentEvent as h, AddScriptTagOptions as i, CategoryGrant as j, createFrame as k, ClearCookiesOptions as l, FrameBackendEvent as m, attachFrame as n, AttachFrameOptions as o, FrameBackend as p, revive as q, AttachFrameFunction as r, AttachWindowOptions as s, ATTACH_FRAME_EVENT_KEY as t, ClearCookiesWire as u, FrameLocator as v, FrameWindowRefusedError as w, FrameWindowBlockedError as x, FrameMessageEvent as y, PermissionCategory as z };
|