nothing-browser 0.1.1 → 0.1.3
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/dist/client/index.js +24 -6
- package/dist/piggy/client/index.d.ts +3 -11
- package/dist/piggy/client/index.d.ts.map +1 -1
- package/dist/piggy/expose/index.d.ts +6 -0
- package/dist/piggy/expose/index.d.ts.map +1 -0
- package/dist/piggy/register/index.d.ts.map +1 -1
- package/dist/piggy/tabs/index.d.ts +3 -1
- package/dist/piggy/tabs/index.d.ts.map +1 -1
- package/dist/piggy.d.ts.map +1 -1
- package/dist/piggy.js +640 -501
- package/dist/register/index.js +429 -36
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
- package/piggy/client/index.ts +48 -126
- package/piggy/expose/index.ts +42 -0
- package/piggy/register/index.ts +115 -40
- package/piggy/tabs/index.ts +2 -1
- package/piggy.ts +79 -11
- package/piggy/cache/memory.d.ts +0 -7
- package/piggy/cache/memory.d.ts.map +0 -1
- package/piggy/captcha/index.d.ts +0 -35
- package/piggy/client/index.d.ts +0 -79
- package/piggy/client/index.d.ts.map +0 -1
- package/piggy/dialog/index.d.ts +0 -29
- package/piggy/human/index.d.ts +0 -7
- package/piggy/human/index.d.ts.map +0 -1
- package/piggy/register/index.d.ts +0 -7
- package/piggy/register/index.d.ts.map +0 -1
- package/piggy/server/index.d.ts +0 -58
- package/piggy/server/index.d.ts.map +0 -1
package/dist/piggy.js
CHANGED
|
@@ -7279,6 +7279,24 @@ class PiggyClient {
|
|
|
7279
7279
|
}
|
|
7280
7280
|
}
|
|
7281
7281
|
}
|
|
7282
|
+
if (event.event === "dialog") {
|
|
7283
|
+
const key = `dialog:${event.tabId ?? "default"}`;
|
|
7284
|
+
const handlers = this.globalEventHandlers.get(key);
|
|
7285
|
+
if (handlers) {
|
|
7286
|
+
for (const h of handlers) {
|
|
7287
|
+
try {
|
|
7288
|
+
h({
|
|
7289
|
+
dialogType: event.dialogType,
|
|
7290
|
+
message: event.message,
|
|
7291
|
+
defaultValue: event.defaultValue,
|
|
7292
|
+
tabId: event.tabId
|
|
7293
|
+
});
|
|
7294
|
+
} catch (e) {
|
|
7295
|
+
logger_default.error(`dialog handler error: ${e}`);
|
|
7296
|
+
}
|
|
7297
|
+
}
|
|
7298
|
+
}
|
|
7299
|
+
}
|
|
7282
7300
|
}
|
|
7283
7301
|
onEvent(eventName, tabId, handler) {
|
|
7284
7302
|
const key = `${eventName}:${tabId}`;
|
|
@@ -7426,14 +7444,14 @@ class PiggyClient {
|
|
|
7426
7444
|
async setCookie(name, value, domain, path = "/", tabId = "default") {
|
|
7427
7445
|
await this.send("cookie.set", { name, value, domain, path, tabId });
|
|
7428
7446
|
}
|
|
7429
|
-
async getCookie(name, tabId = "default") {
|
|
7430
|
-
return this.send("cookie.get", { name, tabId });
|
|
7447
|
+
async getCookie(name, domain = "", tabId = "default") {
|
|
7448
|
+
return this.send("cookie.get", { name, domain, tabId });
|
|
7431
7449
|
}
|
|
7432
|
-
async deleteCookie(name, tabId = "default") {
|
|
7433
|
-
await this.send("cookie.delete", { name, tabId });
|
|
7450
|
+
async deleteCookie(name, domain, tabId = "default") {
|
|
7451
|
+
await this.send("cookie.delete", { name, domain, tabId });
|
|
7434
7452
|
}
|
|
7435
|
-
async listCookies(tabId = "default") {
|
|
7436
|
-
return this.send("cookie.list", { tabId });
|
|
7453
|
+
async listCookies(domain = "", tabId = "default") {
|
|
7454
|
+
return this.send("cookie.list", { domain, tabId });
|
|
7437
7455
|
}
|
|
7438
7456
|
async addInterceptRule(action, pattern, options = {}, tabId = "default") {
|
|
7439
7457
|
await this.send("intercept.rule.add", { action, pattern, ...options, tabId });
|
|
@@ -27293,7 +27311,7 @@ function finalize(ctx, schema) {
|
|
|
27293
27311
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
27294
27312
|
} else if (ctx.target === "draft-04") {
|
|
27295
27313
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
27296
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
27314
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
27297
27315
|
if (ctx.external?.uri) {
|
|
27298
27316
|
const id = ctx.external.registry.get(schema)?.id;
|
|
27299
27317
|
if (!id)
|
|
@@ -28617,142 +28635,479 @@ async function storeRecord(storeName, data) {
|
|
|
28617
28635
|
return { stored, skipped };
|
|
28618
28636
|
}
|
|
28619
28637
|
|
|
28620
|
-
// piggy/
|
|
28621
|
-
|
|
28622
|
-
|
|
28623
|
-
|
|
28624
|
-
|
|
28638
|
+
// piggy/find/index.ts
|
|
28639
|
+
class FindClient {
|
|
28640
|
+
client;
|
|
28641
|
+
constructor(client) {
|
|
28642
|
+
this.client = client;
|
|
28643
|
+
}
|
|
28644
|
+
css(selector, tabId = "default") {
|
|
28645
|
+
return this.client.send("find.css", { selector, tabId });
|
|
28646
|
+
}
|
|
28647
|
+
all(selector, tabId = "default") {
|
|
28648
|
+
return this.client.send("find.all", { selector, tabId });
|
|
28649
|
+
}
|
|
28650
|
+
first(selector, tabId = "default") {
|
|
28651
|
+
return this.client.send("find.first", { selector, tabId });
|
|
28652
|
+
}
|
|
28653
|
+
byText(text, tabId = "default") {
|
|
28654
|
+
return this.client.send("find.byText", { text, tabId });
|
|
28655
|
+
}
|
|
28656
|
+
byAttr(attr, value, tabId = "default") {
|
|
28657
|
+
return this.client.send("find.byAttr", { attr, value, tabId });
|
|
28658
|
+
}
|
|
28659
|
+
byTag(tag, tabId = "default") {
|
|
28660
|
+
return this.client.send("find.byTag", { tag, tabId });
|
|
28661
|
+
}
|
|
28662
|
+
byPlaceholder(text, tabId = "default") {
|
|
28663
|
+
return this.client.send("find.byPlaceholder", { text, tabId });
|
|
28664
|
+
}
|
|
28665
|
+
byRole(role, name, tabId = "default") {
|
|
28666
|
+
return this.client.send("find.byRole", { role, name, tabId });
|
|
28667
|
+
}
|
|
28668
|
+
children(selector, tabId = "default") {
|
|
28669
|
+
return this.client.send("find.children", { selector, tabId });
|
|
28670
|
+
}
|
|
28671
|
+
parent(selector, tabId = "default") {
|
|
28672
|
+
return this.client.send("find.parent", { selector, tabId });
|
|
28673
|
+
}
|
|
28674
|
+
closest(selector, ancestor, tabId = "default") {
|
|
28675
|
+
return this.client.send("find.closest", { selector, ancestor, tabId });
|
|
28676
|
+
}
|
|
28677
|
+
count(selector, tabId = "default") {
|
|
28678
|
+
return this.client.send("find.count", { selector, tabId });
|
|
28679
|
+
}
|
|
28680
|
+
exists(selector, tabId = "default") {
|
|
28681
|
+
return this.client.send("find.exists", { selector, tabId });
|
|
28682
|
+
}
|
|
28683
|
+
visible(selector, tabId = "default") {
|
|
28684
|
+
return this.client.send("find.visible", { selector, tabId });
|
|
28685
|
+
}
|
|
28686
|
+
enabled(selector, tabId = "default") {
|
|
28687
|
+
return this.client.send("find.enabled", { selector, tabId });
|
|
28688
|
+
}
|
|
28689
|
+
checked(selector, tabId = "default") {
|
|
28690
|
+
return this.client.send("find.checked", { selector, tabId });
|
|
28691
|
+
}
|
|
28625
28692
|
}
|
|
28626
|
-
function
|
|
28627
|
-
|
|
28693
|
+
function createFindAPI(client) {
|
|
28694
|
+
return new FindClient(client);
|
|
28628
28695
|
}
|
|
28629
|
-
|
|
28630
|
-
|
|
28631
|
-
|
|
28632
|
-
|
|
28633
|
-
|
|
28634
|
-
|
|
28635
|
-
|
|
28636
|
-
|
|
28637
|
-
|
|
28638
|
-
|
|
28639
|
-
|
|
28640
|
-
}
|
|
28696
|
+
|
|
28697
|
+
// piggy/provide/index.ts
|
|
28698
|
+
class ProvideClient {
|
|
28699
|
+
client;
|
|
28700
|
+
constructor(client) {
|
|
28701
|
+
this.client = client;
|
|
28702
|
+
}
|
|
28703
|
+
text(opts, tabId = "default") {
|
|
28704
|
+
return this.client.send("provide.text", { ...opts, tabId });
|
|
28705
|
+
}
|
|
28706
|
+
textAll(opts, tabId = "default") {
|
|
28707
|
+
return this.client.send("provide.textAll", { ...opts, tabId });
|
|
28708
|
+
}
|
|
28709
|
+
attr(opts, tabId = "default") {
|
|
28710
|
+
return this.client.send("provide.attr", { ...opts, tabId });
|
|
28711
|
+
}
|
|
28712
|
+
attrAll(opts, tabId = "default") {
|
|
28713
|
+
return this.client.send("provide.attrAll", { ...opts, tabId });
|
|
28714
|
+
}
|
|
28715
|
+
html(opts, tabId = "default") {
|
|
28716
|
+
return this.client.send("provide.html", { ...opts, tabId });
|
|
28717
|
+
}
|
|
28718
|
+
table(opts, tabId = "default") {
|
|
28719
|
+
return this.client.send("provide.table", { ...opts, tabId });
|
|
28720
|
+
}
|
|
28721
|
+
list(opts, tabId = "default") {
|
|
28722
|
+
return this.client.send("provide.list", { ...opts, tabId });
|
|
28723
|
+
}
|
|
28724
|
+
links(opts, tabId = "default") {
|
|
28725
|
+
return this.client.send("provide.links", { ...opts, tabId });
|
|
28726
|
+
}
|
|
28727
|
+
images(opts, tabId = "default") {
|
|
28728
|
+
return this.client.send("provide.images", { ...opts, tabId });
|
|
28729
|
+
}
|
|
28730
|
+
form(opts, tabId = "default") {
|
|
28731
|
+
return this.client.send("provide.form", { ...opts, tabId });
|
|
28732
|
+
}
|
|
28733
|
+
page(tabId = "default") {
|
|
28734
|
+
return this.client.send("provide.page", { tabId });
|
|
28735
|
+
}
|
|
28736
|
+
div(opts, tabId = "default") {
|
|
28737
|
+
return this.client.send("provide.div", { ...opts, tabId });
|
|
28738
|
+
}
|
|
28739
|
+
meta(tabId = "default") {
|
|
28740
|
+
return this.client.send("provide.meta", { tabId });
|
|
28741
|
+
}
|
|
28742
|
+
select(opts, tabId = "default") {
|
|
28743
|
+
return this.client.send("provide.select", { ...opts, tabId });
|
|
28744
|
+
}
|
|
28745
|
+
json(opts, tabId = "default") {
|
|
28746
|
+
return this.client.send("provide.json", { ...opts, tabId });
|
|
28641
28747
|
}
|
|
28642
|
-
throw last;
|
|
28643
28748
|
}
|
|
28644
|
-
function
|
|
28645
|
-
|
|
28646
|
-
|
|
28647
|
-
|
|
28648
|
-
|
|
28749
|
+
function createProvideAPI(client) {
|
|
28750
|
+
return new ProvideClient(client);
|
|
28751
|
+
}
|
|
28752
|
+
|
|
28753
|
+
// piggy/session/index.ts
|
|
28754
|
+
class SessionClient {
|
|
28755
|
+
client;
|
|
28756
|
+
constructor(client) {
|
|
28757
|
+
this.client = client;
|
|
28649
28758
|
}
|
|
28650
|
-
|
|
28651
|
-
|
|
28652
|
-
|
|
28653
|
-
|
|
28654
|
-
|
|
28655
|
-
|
|
28656
|
-
|
|
28657
|
-
|
|
28658
|
-
|
|
28659
|
-
|
|
28660
|
-
|
|
28661
|
-
|
|
28662
|
-
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
|
|
28668
|
-
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
}
|
|
28678
|
-
|
|
28679
|
-
|
|
28680
|
-
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
28695
|
-
|
|
28696
|
-
|
|
28697
|
-
|
|
28698
|
-
|
|
28699
|
-
|
|
28700
|
-
|
|
28701
|
-
|
|
28702
|
-
|
|
28703
|
-
|
|
28704
|
-
|
|
28705
|
-
}
|
|
28706
|
-
|
|
28707
|
-
|
|
28708
|
-
|
|
28709
|
-
|
|
28710
|
-
|
|
28711
|
-
|
|
28712
|
-
|
|
28713
|
-
|
|
28714
|
-
|
|
28715
|
-
|
|
28716
|
-
|
|
28717
|
-
|
|
28718
|
-
|
|
28719
|
-
|
|
28720
|
-
|
|
28721
|
-
|
|
28722
|
-
|
|
28723
|
-
|
|
28724
|
-
|
|
28725
|
-
|
|
28726
|
-
|
|
28727
|
-
|
|
28728
|
-
|
|
28729
|
-
|
|
28730
|
-
|
|
28731
|
-
|
|
28732
|
-
|
|
28733
|
-
|
|
28734
|
-
|
|
28735
|
-
const
|
|
28736
|
-
|
|
28737
|
-
|
|
28738
|
-
|
|
28739
|
-
|
|
28740
|
-
|
|
28741
|
-
|
|
28742
|
-
|
|
28743
|
-
|
|
28744
|
-
|
|
28745
|
-
})
|
|
28746
|
-
|
|
28747
|
-
|
|
28748
|
-
|
|
28749
|
-
|
|
28750
|
-
|
|
28751
|
-
|
|
28752
|
-
|
|
28753
|
-
|
|
28754
|
-
|
|
28755
|
-
|
|
28759
|
+
reload(tabId = "default") {
|
|
28760
|
+
return this.client.send("session.reload", { tabId });
|
|
28761
|
+
}
|
|
28762
|
+
paths() {
|
|
28763
|
+
return this.client.send("session.paths", {});
|
|
28764
|
+
}
|
|
28765
|
+
cookiesPath() {
|
|
28766
|
+
return this.client.send("session.cookies.path", {});
|
|
28767
|
+
}
|
|
28768
|
+
profilePath() {
|
|
28769
|
+
return this.client.send("session.profile.path", {});
|
|
28770
|
+
}
|
|
28771
|
+
wsPath() {
|
|
28772
|
+
return this.client.send("session.ws.path", {});
|
|
28773
|
+
}
|
|
28774
|
+
pingsPath() {
|
|
28775
|
+
return this.client.send("session.pings.path", {});
|
|
28776
|
+
}
|
|
28777
|
+
setWsSave(enabled) {
|
|
28778
|
+
return this.client.send("session.ws.save", { enabled });
|
|
28779
|
+
}
|
|
28780
|
+
setPingsSave(enabled) {
|
|
28781
|
+
return this.client.send("session.pings.save", { enabled });
|
|
28782
|
+
}
|
|
28783
|
+
async export(tabId = "default") {
|
|
28784
|
+
const raw = await this.client.send("session.export", { tabId });
|
|
28785
|
+
return typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
28786
|
+
}
|
|
28787
|
+
import(data, tabId = "default") {
|
|
28788
|
+
return this.client.send("session.import", {
|
|
28789
|
+
data: JSON.stringify(data),
|
|
28790
|
+
tabId
|
|
28791
|
+
});
|
|
28792
|
+
}
|
|
28793
|
+
setCookie(opts, tabId = "default") {
|
|
28794
|
+
return this.client.send("cookie.set", { ...opts, tabId });
|
|
28795
|
+
}
|
|
28796
|
+
deleteCookie(opts, tabId = "default") {
|
|
28797
|
+
return this.client.send("cookie.delete", { ...opts, tabId });
|
|
28798
|
+
}
|
|
28799
|
+
}
|
|
28800
|
+
function createSessionAPI(client) {
|
|
28801
|
+
return new SessionClient(client);
|
|
28802
|
+
}
|
|
28803
|
+
|
|
28804
|
+
// piggy/dialog/index.ts
|
|
28805
|
+
class DialogClient {
|
|
28806
|
+
client;
|
|
28807
|
+
constructor(client) {
|
|
28808
|
+
this.client = client;
|
|
28809
|
+
}
|
|
28810
|
+
accept(tabId = "default", text) {
|
|
28811
|
+
return this.client.send("dialog.accept", { tabId, ...text !== undefined ? { text } : {} });
|
|
28812
|
+
}
|
|
28813
|
+
dismiss(tabId = "default") {
|
|
28814
|
+
return this.client.send("dialog.dismiss", { tabId });
|
|
28815
|
+
}
|
|
28816
|
+
status(tabId = "default") {
|
|
28817
|
+
return this.client.send("dialog.status", { tabId });
|
|
28818
|
+
}
|
|
28819
|
+
setAutoAction(tabId = "default", action) {
|
|
28820
|
+
return this.client.send("dialog.onDialog", { tabId, action });
|
|
28821
|
+
}
|
|
28822
|
+
upload(selector, filePath, tabId = "default") {
|
|
28823
|
+
return this.client.send("upload", { selector, path: filePath, tabId });
|
|
28824
|
+
}
|
|
28825
|
+
onDialog(tabId, handler) {
|
|
28826
|
+
return this.client.onEvent("dialog", tabId, handler);
|
|
28827
|
+
}
|
|
28828
|
+
waitAndAccept(tabId = "default", text, timeoutMs = 30000) {
|
|
28829
|
+
return new Promise((resolve2, reject) => {
|
|
28830
|
+
const timer = setTimeout(() => {
|
|
28831
|
+
unsub();
|
|
28832
|
+
reject(new Error(`dialog.waitAndAccept: timed out after ${timeoutMs}ms`));
|
|
28833
|
+
}, timeoutMs);
|
|
28834
|
+
const unsub = this.onDialog(tabId, async (data) => {
|
|
28835
|
+
clearTimeout(timer);
|
|
28836
|
+
unsub();
|
|
28837
|
+
await this.accept(tabId, text);
|
|
28838
|
+
resolve2(data);
|
|
28839
|
+
});
|
|
28840
|
+
});
|
|
28841
|
+
}
|
|
28842
|
+
waitAndDismiss(tabId = "default", timeoutMs = 30000) {
|
|
28843
|
+
return new Promise((resolve2, reject) => {
|
|
28844
|
+
const timer = setTimeout(() => {
|
|
28845
|
+
unsub();
|
|
28846
|
+
reject(new Error(`dialog.waitAndDismiss: timed out after ${timeoutMs}ms`));
|
|
28847
|
+
}, timeoutMs);
|
|
28848
|
+
const unsub = this.onDialog(tabId, async (data) => {
|
|
28849
|
+
clearTimeout(timer);
|
|
28850
|
+
unsub();
|
|
28851
|
+
await this.dismiss(tabId);
|
|
28852
|
+
resolve2(data);
|
|
28853
|
+
});
|
|
28854
|
+
});
|
|
28855
|
+
}
|
|
28856
|
+
}
|
|
28857
|
+
function createDialogAPI(client) {
|
|
28858
|
+
return new DialogClient(client);
|
|
28859
|
+
}
|
|
28860
|
+
|
|
28861
|
+
// piggy/iframe/index.ts
|
|
28862
|
+
class IframeClient {
|
|
28863
|
+
client;
|
|
28864
|
+
constructor(client) {
|
|
28865
|
+
this.client = client;
|
|
28866
|
+
}
|
|
28867
|
+
list(tabId = "default") {
|
|
28868
|
+
return this.client.send("iframe.list", { tabId });
|
|
28869
|
+
}
|
|
28870
|
+
evaluate(opts, tabId = "default") {
|
|
28871
|
+
return this.client.send("iframe.evaluate", { ...opts, tabId });
|
|
28872
|
+
}
|
|
28873
|
+
click(opts, tabId = "default") {
|
|
28874
|
+
return this.client.send("iframe.click", { ...opts, tabId });
|
|
28875
|
+
}
|
|
28876
|
+
type(opts, tabId = "default") {
|
|
28877
|
+
return this.client.send("iframe.type", { ...opts, tabId });
|
|
28878
|
+
}
|
|
28879
|
+
text(opts, tabId = "default") {
|
|
28880
|
+
return this.client.send("iframe.text", { ...opts, tabId });
|
|
28881
|
+
}
|
|
28882
|
+
html(opts, tabId = "default") {
|
|
28883
|
+
return this.client.send("iframe.html", { ...opts, tabId });
|
|
28884
|
+
}
|
|
28885
|
+
waitSel(opts, tabId = "default") {
|
|
28886
|
+
return this.client.send("iframe.waitSel", { ...opts, tabId });
|
|
28887
|
+
}
|
|
28888
|
+
}
|
|
28889
|
+
function createIframeAPI(client) {
|
|
28890
|
+
return new IframeClient(client);
|
|
28891
|
+
}
|
|
28892
|
+
|
|
28893
|
+
// piggy/expose/index.ts
|
|
28894
|
+
async function exposeFunction(client, fnName, handler, tabId) {
|
|
28895
|
+
await client.exposeFunction(fnName, handler, tabId);
|
|
28896
|
+
logger_default.success(`[${tabId}] exposed function: ${fnName}`);
|
|
28897
|
+
}
|
|
28898
|
+
async function unexposeFunction(client, fnName, tabId) {
|
|
28899
|
+
await client.unexposeFunction(fnName, tabId);
|
|
28900
|
+
logger_default.info(`[${tabId}] unexposed function: ${fnName}`);
|
|
28901
|
+
}
|
|
28902
|
+
async function clearExposedFunctions(client, tabId) {
|
|
28903
|
+
await client.clearExposedFunctions(tabId);
|
|
28904
|
+
logger_default.info(`[${tabId}] cleared all exposed functions`);
|
|
28905
|
+
}
|
|
28906
|
+
async function exposeAndInject(client, fnName, handler, injectionJs, tabId) {
|
|
28907
|
+
await client.exposeFunction(fnName, handler, tabId);
|
|
28908
|
+
const js = typeof injectionJs === "function" ? injectionJs(fnName) : injectionJs;
|
|
28909
|
+
await client.evaluate(js, tabId);
|
|
28910
|
+
logger_default.success(`[${tabId}] exposed and injected: ${fnName}`);
|
|
28911
|
+
}
|
|
28912
|
+
|
|
28913
|
+
// piggy/captcha/index.ts
|
|
28914
|
+
class CaptchaClient {
|
|
28915
|
+
client;
|
|
28916
|
+
constructor(client) {
|
|
28917
|
+
this.client = client;
|
|
28918
|
+
}
|
|
28919
|
+
status(tabId = "default") {
|
|
28920
|
+
return this.client.send("captcha.status", { tabId });
|
|
28921
|
+
}
|
|
28922
|
+
resolve(tabId = "default") {
|
|
28923
|
+
return this.client.send("captcha.resolve", { tabId });
|
|
28924
|
+
}
|
|
28925
|
+
pause(tabId = "default") {
|
|
28926
|
+
return this.client.send("captcha.pause", { tabId });
|
|
28927
|
+
}
|
|
28928
|
+
check(tabId = "default") {
|
|
28929
|
+
return this.client.send("captcha.check", { tabId });
|
|
28930
|
+
}
|
|
28931
|
+
setAutoRetry(enabled) {
|
|
28932
|
+
return this.client.send("captcha.autoRetry", { enabled });
|
|
28933
|
+
}
|
|
28934
|
+
blockStatus(tabId = "default") {
|
|
28935
|
+
return this.client.send("block.status", { tabId });
|
|
28936
|
+
}
|
|
28937
|
+
blockRetry(tabId = "default") {
|
|
28938
|
+
return this.client.send("block.retry", { tabId });
|
|
28939
|
+
}
|
|
28940
|
+
onCaptcha(tabId, handler) {
|
|
28941
|
+
return this.client.onEvent("captcha", tabId, handler);
|
|
28942
|
+
}
|
|
28943
|
+
onCaptchaResolved(tabId, handler) {
|
|
28944
|
+
return this.client.onEvent("captcha:resolved", tabId, handler);
|
|
28945
|
+
}
|
|
28946
|
+
onBlocked(tabId, handler) {
|
|
28947
|
+
return this.client.onEvent("blocked", tabId, handler);
|
|
28948
|
+
}
|
|
28949
|
+
onBlockRetry(tabId, handler) {
|
|
28950
|
+
return this.client.onEvent("block:retry", tabId, handler);
|
|
28951
|
+
}
|
|
28952
|
+
waitForResolution(tabId = "default", timeoutMs = 300000) {
|
|
28953
|
+
return new Promise((resolve2, reject) => {
|
|
28954
|
+
const timer = setTimeout(() => {
|
|
28955
|
+
unsub();
|
|
28956
|
+
reject(new Error(`captcha.waitForResolution: timed out after ${timeoutMs}ms`));
|
|
28957
|
+
}, timeoutMs);
|
|
28958
|
+
const unsub = this.onCaptchaResolved(tabId, () => {
|
|
28959
|
+
clearTimeout(timer);
|
|
28960
|
+
unsub();
|
|
28961
|
+
resolve2();
|
|
28962
|
+
});
|
|
28963
|
+
logger_default.warn(`[captcha] waiting for manual resolution on tab ${tabId}…`);
|
|
28964
|
+
});
|
|
28965
|
+
}
|
|
28966
|
+
}
|
|
28967
|
+
function createCaptchaAPI(client) {
|
|
28968
|
+
return new CaptchaClient(client);
|
|
28969
|
+
}
|
|
28970
|
+
|
|
28971
|
+
// piggy/register/index.ts
|
|
28972
|
+
var globalClient = null;
|
|
28973
|
+
var humanMode = false;
|
|
28974
|
+
function setClient(c) {
|
|
28975
|
+
globalClient = c;
|
|
28976
|
+
}
|
|
28977
|
+
function setHumanMode(v) {
|
|
28978
|
+
humanMode = v;
|
|
28979
|
+
}
|
|
28980
|
+
async function retry(label, fn, retries = 2, backoff = 150) {
|
|
28981
|
+
let last;
|
|
28982
|
+
for (let i = 0;i <= retries; i++) {
|
|
28983
|
+
try {
|
|
28984
|
+
return await fn();
|
|
28985
|
+
} catch (e) {
|
|
28986
|
+
last = e;
|
|
28987
|
+
if (i < retries) {
|
|
28988
|
+
logger_default.warn(`[${label}] retry ${i + 1}/${retries}: ${e.message}`);
|
|
28989
|
+
await new Promise((r) => setTimeout(r, backoff * (i + 1)));
|
|
28990
|
+
}
|
|
28991
|
+
}
|
|
28992
|
+
}
|
|
28993
|
+
throw last;
|
|
28994
|
+
}
|
|
28995
|
+
function createSiteObject(name, registeredUrl, client, tabId, pool) {
|
|
28996
|
+
let _currentUrl = registeredUrl;
|
|
28997
|
+
let _modifyRuleCounter = 0;
|
|
28998
|
+
function withTab(fn) {
|
|
28999
|
+
return pool ? pool.withTab(fn) : fn(tabId);
|
|
29000
|
+
}
|
|
29001
|
+
const _eventListeners = new Map;
|
|
29002
|
+
const _unsubNavigate = client.onEvent("navigate", tabId, (url2) => {
|
|
29003
|
+
_currentUrl = url2;
|
|
29004
|
+
const handlers = _eventListeners.get("navigate");
|
|
29005
|
+
if (handlers) {
|
|
29006
|
+
for (const h of handlers) {
|
|
29007
|
+
try {
|
|
29008
|
+
h(url2);
|
|
29009
|
+
} catch (e) {
|
|
29010
|
+
logger_default.error(`[${name}] navigate handler error: ${e}`);
|
|
29011
|
+
}
|
|
29012
|
+
}
|
|
29013
|
+
}
|
|
29014
|
+
});
|
|
29015
|
+
const withErrScreen = async (fn, label) => {
|
|
29016
|
+
try {
|
|
29017
|
+
return await fn();
|
|
29018
|
+
} catch (err) {
|
|
29019
|
+
const p = `./error-${name}-${Date.now()}.png`;
|
|
29020
|
+
try {
|
|
29021
|
+
await client.screenshot(p, tabId);
|
|
29022
|
+
logger_default.error(`[${name}] ${label} failed → ${p}`);
|
|
29023
|
+
} catch {
|
|
29024
|
+
logger_default.error(`[${name}] ${label} failed (no screenshot)`);
|
|
29025
|
+
}
|
|
29026
|
+
throw err;
|
|
29027
|
+
}
|
|
29028
|
+
};
|
|
29029
|
+
const site = {
|
|
29030
|
+
_name: name,
|
|
29031
|
+
_tabId: tabId,
|
|
29032
|
+
_pool: pool ?? null,
|
|
29033
|
+
poolStats: () => pool?.stats ?? null,
|
|
29034
|
+
navigate: (url2, opts) => {
|
|
29035
|
+
const target = url2 ?? registeredUrl;
|
|
29036
|
+
return withTab((t2) => retry(name, async () => {
|
|
29037
|
+
logger_default.network(`[${name}] navigating → ${target}`);
|
|
29038
|
+
await client.navigate(target, t2);
|
|
29039
|
+
_currentUrl = target;
|
|
29040
|
+
}, opts?.retries ?? 2));
|
|
29041
|
+
},
|
|
29042
|
+
reload: () => withTab((t2) => client.reload(t2)),
|
|
29043
|
+
goBack: () => withTab((t2) => client.goBack(t2)),
|
|
29044
|
+
goForward: () => withTab((t2) => client.goForward(t2)),
|
|
29045
|
+
waitForNavigation: () => withTab((t2) => client.waitForNavigation(t2)),
|
|
29046
|
+
title: () => withTab(async (t2) => {
|
|
29047
|
+
const title = await client.getTitle(t2);
|
|
29048
|
+
logger_default.info(`[${name}] title: ${title}`);
|
|
29049
|
+
return title;
|
|
29050
|
+
}),
|
|
29051
|
+
url: () => _currentUrl,
|
|
29052
|
+
content: () => withTab((t2) => client.content(t2)),
|
|
29053
|
+
wait: (ms) => {
|
|
29054
|
+
const actual = humanMode ? ms + Math.floor(Math.random() * 600) - 300 : ms;
|
|
29055
|
+
return new Promise((r) => setTimeout(r, Math.max(0, actual)));
|
|
29056
|
+
},
|
|
29057
|
+
waitForSelector: (selector, timeout = 30000) => withTab((t2) => {
|
|
29058
|
+
logger_default.debug(`[${name}] waitForSelector: ${selector}`);
|
|
29059
|
+
return client.waitForSelector(selector, timeout, t2);
|
|
29060
|
+
}),
|
|
29061
|
+
exposeFunction: (fnName, handler) => exposeFunction(client, fnName, handler, tabId).then(() => site),
|
|
29062
|
+
unexposeFunction: (fnName) => unexposeFunction(client, fnName, tabId).then(() => site),
|
|
29063
|
+
clearExposedFunctions: () => clearExposedFunctions(client, tabId).then(() => site),
|
|
29064
|
+
exposeAndInject: (fnName, handler, injectionJs) => exposeAndInject(client, fnName, handler, injectionJs, tabId).then(() => site),
|
|
29065
|
+
waitForVisible: (selector, timeout = 30000) => withTab((t2) => client.waitForSelector(selector, timeout, t2)),
|
|
29066
|
+
waitForResponse: (pattern, timeout = 30000) => withTab((t2) => client.waitForResponse(pattern, timeout, t2)),
|
|
29067
|
+
addInitScript: async (js) => {
|
|
29068
|
+
const code = typeof js === "function" ? `(${js.toString()})();` : js;
|
|
29069
|
+
await withTab((t2) => client.addInitScript(code, t2));
|
|
29070
|
+
logger_default.success(`[${name}] init script added`);
|
|
29071
|
+
return site;
|
|
29072
|
+
},
|
|
29073
|
+
on: (event, handler) => {
|
|
29074
|
+
if (!_eventListeners.has(event))
|
|
29075
|
+
_eventListeners.set(event, new Set);
|
|
29076
|
+
_eventListeners.get(event).add(handler);
|
|
29077
|
+
logger_default.debug(`[${name}] on('${event}') registered`);
|
|
29078
|
+
return () => {
|
|
29079
|
+
_eventListeners.get(event)?.delete(handler);
|
|
29080
|
+
logger_default.debug(`[${name}] on('${event}') unsubscribed`);
|
|
29081
|
+
};
|
|
29082
|
+
},
|
|
29083
|
+
off: (event, handler) => {
|
|
29084
|
+
_eventListeners.get(event)?.delete(handler);
|
|
29085
|
+
},
|
|
29086
|
+
click: (selector, opts) => withErrScreen(() => withTab((t2) => retry(name, async () => {
|
|
29087
|
+
if (humanMode)
|
|
29088
|
+
await new Promise((r) => setTimeout(r, 80 + Math.random() * 140));
|
|
29089
|
+
await client.waitForSelector(selector, opts?.timeout ?? 15000, t2);
|
|
29090
|
+
const ok = await client.click(selector, t2);
|
|
29091
|
+
if (!ok)
|
|
29092
|
+
throw new Error(`click failed: ${selector}`);
|
|
29093
|
+
logger_default.success(`[${name}] clicked: ${selector}`);
|
|
29094
|
+
return ok;
|
|
29095
|
+
}, opts?.retries ?? 2)), `click(${selector})`),
|
|
29096
|
+
doubleClick: (selector) => withErrScreen(() => withTab(async (t2) => {
|
|
29097
|
+
if (humanMode)
|
|
29098
|
+
await new Promise((r) => setTimeout(r, 80 + Math.random() * 120));
|
|
29099
|
+
return client.doubleClick(selector, t2);
|
|
29100
|
+
}), `dblclick(${selector})`),
|
|
29101
|
+
hover: (selector) => withErrScreen(() => withTab(async (t2) => {
|
|
29102
|
+
if (humanMode)
|
|
29103
|
+
await new Promise((r) => setTimeout(r, 50 + Math.random() * 100));
|
|
29104
|
+
return client.hover(selector, t2);
|
|
29105
|
+
}), `hover(${selector})`),
|
|
29106
|
+
type: (selector, text, opts) => withErrScreen(() => withTab(async (t2) => {
|
|
29107
|
+
await client.waitForSelector(selector, 30000, t2);
|
|
29108
|
+
if (humanMode) {
|
|
29109
|
+
const human = new HumanClient(client);
|
|
29110
|
+
await human.type({
|
|
28756
29111
|
selector,
|
|
28757
29112
|
text,
|
|
28758
29113
|
clear: opts?.clear ?? false,
|
|
@@ -28816,6 +29171,68 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
|
|
|
28816
29171
|
css: (query) => withTab((t2) => client.searchCss(query, t2)),
|
|
28817
29172
|
id: (query) => withTab((t2) => client.searchId(query, t2))
|
|
28818
29173
|
},
|
|
29174
|
+
captcha: {
|
|
29175
|
+
status: () => withTab((t2) => createCaptchaAPI(client).status(t2)),
|
|
29176
|
+
resolve: () => withTab((t2) => createCaptchaAPI(client).resolve(t2)),
|
|
29177
|
+
pause: () => withTab((t2) => createCaptchaAPI(client).pause(t2)),
|
|
29178
|
+
check: () => withTab((t2) => createCaptchaAPI(client).check(t2)),
|
|
29179
|
+
autoRetry: (opts) => withTab((t2) => createCaptchaAPI(client).setAutoRetry(opts.enabled)),
|
|
29180
|
+
onCaptcha: (handler) => createCaptchaAPI(client).onCaptcha(tabId, handler),
|
|
29181
|
+
onResolved: (handler) => createCaptchaAPI(client).onCaptchaResolved(tabId, handler)
|
|
29182
|
+
},
|
|
29183
|
+
block: {
|
|
29184
|
+
status: () => withTab((t2) => createCaptchaAPI(client).blockStatus(t2)),
|
|
29185
|
+
retry: () => withTab((t2) => createCaptchaAPI(client).blockRetry(t2)),
|
|
29186
|
+
onBlocked: (handler) => createCaptchaAPI(client).onBlocked(tabId, handler),
|
|
29187
|
+
onRetry: (handler) => createCaptchaAPI(client).onBlockRetry(tabId, handler)
|
|
29188
|
+
},
|
|
29189
|
+
find: {
|
|
29190
|
+
css: (selector) => withTab((t2) => {
|
|
29191
|
+
console.log("[DEBUG] find.css tabId:", t2);
|
|
29192
|
+
return createFindAPI(client).css(selector, t2);
|
|
29193
|
+
}),
|
|
29194
|
+
all: (selector) => withTab((t2) => createFindAPI(client).all(selector, t2)),
|
|
29195
|
+
first: (selector) => withTab((t2) => createFindAPI(client).first(selector, t2)),
|
|
29196
|
+
byText: (text) => withTab((t2) => createFindAPI(client).byText(text, t2)),
|
|
29197
|
+
byAttr: (attr, value) => withTab((t2) => createFindAPI(client).byAttr(attr, value, t2)),
|
|
29198
|
+
byTag: (tag) => withTab((t2) => createFindAPI(client).byTag(tag, t2)),
|
|
29199
|
+
byPlaceholder: (text) => withTab((t2) => createFindAPI(client).byPlaceholder(text, t2)),
|
|
29200
|
+
byRole: (role, name2) => withTab((t2) => createFindAPI(client).byRole(role, name2, t2)),
|
|
29201
|
+
children: (selector) => withTab((t2) => createFindAPI(client).children(selector, t2)),
|
|
29202
|
+
parent: (selector) => withTab((t2) => createFindAPI(client).parent(selector, t2)),
|
|
29203
|
+
closest: (selector, ancestor) => withTab((t2) => createFindAPI(client).closest(selector, ancestor, t2)),
|
|
29204
|
+
count: (selector) => withTab((t2) => createFindAPI(client).count(selector, t2)),
|
|
29205
|
+
exists: (selector) => withTab((t2) => createFindAPI(client).exists(selector, t2)),
|
|
29206
|
+
visible: (selector) => withTab((t2) => createFindAPI(client).visible(selector, t2)),
|
|
29207
|
+
enabled: (selector) => withTab((t2) => createFindAPI(client).enabled(selector, t2)),
|
|
29208
|
+
checked: (selector) => withTab((t2) => createFindAPI(client).checked(selector, t2))
|
|
29209
|
+
},
|
|
29210
|
+
provide: {
|
|
29211
|
+
text: (opts) => withTab((t2) => createProvideAPI(client).text(opts, t2)),
|
|
29212
|
+
textAll: (opts) => withTab((t2) => createProvideAPI(client).textAll(opts, t2)),
|
|
29213
|
+
attr: (opts) => withTab((t2) => createProvideAPI(client).attr(opts, t2)),
|
|
29214
|
+
attrAll: (opts) => withTab((t2) => createProvideAPI(client).attrAll(opts, t2)),
|
|
29215
|
+
html: (opts) => withTab((t2) => createProvideAPI(client).html(opts, t2)),
|
|
29216
|
+
table: (opts) => withTab((t2) => createProvideAPI(client).table(opts, t2)),
|
|
29217
|
+
list: (opts) => withTab((t2) => createProvideAPI(client).list(opts, t2)),
|
|
29218
|
+
links: (opts) => withTab((t2) => createProvideAPI(client).links(opts, t2)),
|
|
29219
|
+
images: (opts) => withTab((t2) => createProvideAPI(client).images(opts, t2)),
|
|
29220
|
+
form: (opts) => withTab((t2) => createProvideAPI(client).form(opts, t2)),
|
|
29221
|
+
page: () => withTab((t2) => createProvideAPI(client).page(t2)),
|
|
29222
|
+
div: (opts) => withTab((t2) => createProvideAPI(client).div(opts, t2)),
|
|
29223
|
+
meta: () => withTab((t2) => createProvideAPI(client).meta(t2)),
|
|
29224
|
+
select: (opts) => withTab((t2) => createProvideAPI(client).select(opts, t2)),
|
|
29225
|
+
json: (opts) => withTab((t2) => createProvideAPI(client).json(opts, t2))
|
|
29226
|
+
},
|
|
29227
|
+
iframe: {
|
|
29228
|
+
list: () => withTab((t2) => createIframeAPI(client).list(t2)),
|
|
29229
|
+
evaluate: (opts) => withTab((t2) => createIframeAPI(client).evaluate(opts, t2)),
|
|
29230
|
+
click: (opts) => withTab((t2) => createIframeAPI(client).click(opts, t2)),
|
|
29231
|
+
type: (opts) => withTab((t2) => createIframeAPI(client).type(opts, t2)),
|
|
29232
|
+
text: (opts) => withTab((t2) => createIframeAPI(client).text(opts, t2)),
|
|
29233
|
+
html: (opts) => withTab((t2) => createIframeAPI(client).html(opts, t2)),
|
|
29234
|
+
waitSel: (opts) => withTab((t2) => createIframeAPI(client).waitSel(opts, t2))
|
|
29235
|
+
},
|
|
28819
29236
|
screenshot: async (filePath) => {
|
|
28820
29237
|
const r = await withTab((t2) => client.screenshot(filePath, t2));
|
|
28821
29238
|
logger_default.success(`[${name}] screenshot → ${filePath ?? "base64"}`);
|
|
@@ -28826,6 +29243,12 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
|
|
|
28826
29243
|
logger_default.success(`[${name}] pdf → ${filePath ?? "base64"}`);
|
|
28827
29244
|
return r;
|
|
28828
29245
|
},
|
|
29246
|
+
human: {
|
|
29247
|
+
set: (opts) => withTab((t2) => createHumanAPI(client).set(opts, t2)),
|
|
29248
|
+
get: () => withTab((t2) => createHumanAPI(client).get(t2)),
|
|
29249
|
+
type: (opts) => withTab((t2) => createHumanAPI(client).type(opts, t2)),
|
|
29250
|
+
click: (opts) => withTab((t2) => createHumanAPI(client).click(opts, t2))
|
|
29251
|
+
},
|
|
28829
29252
|
blockImages: () => withTab(async (t2) => {
|
|
28830
29253
|
await client.blockImages(t2);
|
|
28831
29254
|
logger_default.info(`[${name}] images blocked`);
|
|
@@ -28839,12 +29262,13 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
|
|
|
28839
29262
|
await withTab((t2) => client.setCookie(cookieName, value, domain, path, t2));
|
|
28840
29263
|
logger_default.info(`[${name}] cookie set: ${cookieName} @ ${domain}`);
|
|
28841
29264
|
},
|
|
28842
|
-
get: (cookieName) => withTab((t2) => client.getCookie(cookieName, t2)),
|
|
28843
|
-
delete: async (cookieName) => {
|
|
28844
|
-
|
|
29265
|
+
get: (cookieName, domain = "") => withTab((t2) => client.getCookie(cookieName, domain, t2)),
|
|
29266
|
+
delete: async (cookieName, domain) => {
|
|
29267
|
+
const d = domain ?? new URL(registeredUrl).hostname;
|
|
29268
|
+
await withTab((t2) => client.deleteCookie(cookieName, d, t2));
|
|
28845
29269
|
logger_default.info(`[${name}] cookie deleted: ${cookieName}`);
|
|
28846
29270
|
},
|
|
28847
|
-
list: () => withTab((t2) => client.listCookies(t2))
|
|
29271
|
+
list: (domain = "") => withTab((t2) => client.listCookies(domain, t2))
|
|
28848
29272
|
},
|
|
28849
29273
|
intercept: {
|
|
28850
29274
|
block: async (pattern) => {
|
|
@@ -28931,6 +29355,16 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
|
|
|
28931
29355
|
logger_default.info(`[${name}] intercept rules cleared`);
|
|
28932
29356
|
}
|
|
28933
29357
|
},
|
|
29358
|
+
dialog: {
|
|
29359
|
+
accept: (tabId2 = "default", text) => new DialogClient(client).accept(tabId2, text),
|
|
29360
|
+
dismiss: (tabId2 = "default") => new DialogClient(client).dismiss(tabId2),
|
|
29361
|
+
status: (tabId2 = "default") => new DialogClient(client).status(tabId2),
|
|
29362
|
+
setAutoAction: (tabId2 = "default", action) => new DialogClient(client).setAutoAction(tabId2, action),
|
|
29363
|
+
upload: (selector, filePath, tabId2 = "default") => new DialogClient(client).upload(selector, filePath, tabId2),
|
|
29364
|
+
onDialog: (tabId2, handler) => new DialogClient(client).onDialog(tabId2, handler),
|
|
29365
|
+
waitAndAccept: (tabId2 = "default", text, timeoutMs = 30000) => new DialogClient(client).waitAndAccept(tabId2, text, timeoutMs),
|
|
29366
|
+
waitAndDismiss: (tabId2 = "default", timeoutMs = 30000) => new DialogClient(client).waitAndDismiss(tabId2, timeoutMs)
|
|
29367
|
+
},
|
|
28934
29368
|
capture: {
|
|
28935
29369
|
start: () => withTab(async (t2) => {
|
|
28936
29370
|
await client.captureStart(t2);
|
|
@@ -28950,37 +29384,14 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
|
|
|
28950
29384
|
})
|
|
28951
29385
|
},
|
|
28952
29386
|
session: {
|
|
28953
|
-
export:
|
|
28954
|
-
|
|
28955
|
-
|
|
28956
|
-
|
|
28957
|
-
},
|
|
28958
|
-
|
|
28959
|
-
|
|
28960
|
-
|
|
28961
|
-
}
|
|
28962
|
-
},
|
|
28963
|
-
exposeFunction: async (fnName, handler) => {
|
|
28964
|
-
await client.exposeFunction(fnName, handler, tabId);
|
|
28965
|
-
logger_default.success(`[${name}] exposed function: ${fnName}`);
|
|
28966
|
-
return site;
|
|
28967
|
-
},
|
|
28968
|
-
unexposeFunction: async (fnName) => {
|
|
28969
|
-
await client.unexposeFunction(fnName, tabId);
|
|
28970
|
-
logger_default.info(`[${name}] unexposed function: ${fnName}`);
|
|
28971
|
-
return site;
|
|
28972
|
-
},
|
|
28973
|
-
clearExposedFunctions: async () => {
|
|
28974
|
-
await client.clearExposedFunctions(tabId);
|
|
28975
|
-
logger_default.info(`[${name}] cleared all exposed functions`);
|
|
28976
|
-
return site;
|
|
28977
|
-
},
|
|
28978
|
-
exposeAndInject: async (fnName, handler, injectionJs) => {
|
|
28979
|
-
await client.exposeFunction(fnName, handler, tabId);
|
|
28980
|
-
const js = typeof injectionJs === "function" ? injectionJs(fnName) : injectionJs;
|
|
28981
|
-
await withTab((t2) => client.evaluate(js, t2));
|
|
28982
|
-
logger_default.success(`[${name}] exposed and injected: ${fnName}`);
|
|
28983
|
-
return site;
|
|
29387
|
+
export: () => withTab((t2) => createSessionAPI(client).export(t2)),
|
|
29388
|
+
import: (data) => withTab((t2) => createSessionAPI(client).import(data, t2)),
|
|
29389
|
+
reload: () => withTab((t2) => createSessionAPI(client).reload(t2)),
|
|
29390
|
+
paths: () => createSessionAPI(client).paths(),
|
|
29391
|
+
cookies: { path: () => createSessionAPI(client).cookiesPath() },
|
|
29392
|
+
profile: { path: () => createSessionAPI(client).profilePath() },
|
|
29393
|
+
ws: { save: (opts) => createSessionAPI(client).setWsSave(opts.enabled) },
|
|
29394
|
+
pings: { save: (opts) => createSessionAPI(client).setPingsSave(opts.enabled) }
|
|
28984
29395
|
},
|
|
28985
29396
|
store: async (data, schemaName) => {
|
|
28986
29397
|
const target = schemaName ?? name;
|
|
@@ -29108,139 +29519,24 @@ class CaptureClient {
|
|
|
29108
29519
|
stop(tabId = "default") {
|
|
29109
29520
|
return this.client.send("capture.stop", { tabId });
|
|
29110
29521
|
}
|
|
29111
|
-
requests(tabId = "default") {
|
|
29112
|
-
return this.client.send("capture.requests", { tabId });
|
|
29113
|
-
}
|
|
29114
|
-
ws(tabId = "default") {
|
|
29115
|
-
return this.client.send("capture.ws", { tabId });
|
|
29116
|
-
}
|
|
29117
|
-
cookies(tabId = "default") {
|
|
29118
|
-
return this.client.send("capture.cookies", { tabId });
|
|
29119
|
-
}
|
|
29120
|
-
storage(tabId = "default") {
|
|
29121
|
-
return this.client.send("capture.storage", { tabId });
|
|
29122
|
-
}
|
|
29123
|
-
clear(tabId = "default") {
|
|
29124
|
-
return this.client.send("capture.clear", { tabId });
|
|
29125
|
-
}
|
|
29126
|
-
}
|
|
29127
|
-
function createCaptureAPI(client) {
|
|
29128
|
-
return new CaptureClient(client);
|
|
29129
|
-
}
|
|
29130
|
-
|
|
29131
|
-
// piggy/captcha/index.ts
|
|
29132
|
-
class CaptchaClient {
|
|
29133
|
-
client;
|
|
29134
|
-
constructor(client) {
|
|
29135
|
-
this.client = client;
|
|
29136
|
-
}
|
|
29137
|
-
status(tabId = "default") {
|
|
29138
|
-
return this.client.send("captcha.status", { tabId });
|
|
29139
|
-
}
|
|
29140
|
-
resolve(tabId = "default") {
|
|
29141
|
-
return this.client.send("captcha.resolve", { tabId });
|
|
29142
|
-
}
|
|
29143
|
-
pause(tabId = "default") {
|
|
29144
|
-
return this.client.send("captcha.pause", { tabId });
|
|
29145
|
-
}
|
|
29146
|
-
check(tabId = "default") {
|
|
29147
|
-
return this.client.send("captcha.check", { tabId });
|
|
29148
|
-
}
|
|
29149
|
-
setAutoRetry(enabled) {
|
|
29150
|
-
return this.client.send("captcha.autoRetry", { enabled });
|
|
29151
|
-
}
|
|
29152
|
-
blockStatus(tabId = "default") {
|
|
29153
|
-
return this.client.send("block.status", { tabId });
|
|
29154
|
-
}
|
|
29155
|
-
blockRetry(tabId = "default") {
|
|
29156
|
-
return this.client.send("block.retry", { tabId });
|
|
29157
|
-
}
|
|
29158
|
-
onCaptcha(tabId, handler) {
|
|
29159
|
-
return this.client.onEvent("captcha", tabId, handler);
|
|
29160
|
-
}
|
|
29161
|
-
onCaptchaResolved(tabId, handler) {
|
|
29162
|
-
return this.client.onEvent("captcha:resolved", tabId, handler);
|
|
29163
|
-
}
|
|
29164
|
-
onBlocked(tabId, handler) {
|
|
29165
|
-
return this.client.onEvent("blocked", tabId, handler);
|
|
29166
|
-
}
|
|
29167
|
-
onBlockRetry(tabId, handler) {
|
|
29168
|
-
return this.client.onEvent("block:retry", tabId, handler);
|
|
29169
|
-
}
|
|
29170
|
-
waitForResolution(tabId = "default", timeoutMs = 300000) {
|
|
29171
|
-
return new Promise((resolve2, reject) => {
|
|
29172
|
-
const timer = setTimeout(() => {
|
|
29173
|
-
unsub();
|
|
29174
|
-
reject(new Error(`captcha.waitForResolution: timed out after ${timeoutMs}ms`));
|
|
29175
|
-
}, timeoutMs);
|
|
29176
|
-
const unsub = this.onCaptchaResolved(tabId, () => {
|
|
29177
|
-
clearTimeout(timer);
|
|
29178
|
-
unsub();
|
|
29179
|
-
resolve2();
|
|
29180
|
-
});
|
|
29181
|
-
logger_default.warn(`[captcha] waiting for manual resolution on tab ${tabId}…`);
|
|
29182
|
-
});
|
|
29183
|
-
}
|
|
29184
|
-
}
|
|
29185
|
-
function createCaptchaAPI(client) {
|
|
29186
|
-
return new CaptchaClient(client);
|
|
29187
|
-
}
|
|
29188
|
-
|
|
29189
|
-
// piggy/dialog/index.ts
|
|
29190
|
-
class DialogClient {
|
|
29191
|
-
client;
|
|
29192
|
-
constructor(client) {
|
|
29193
|
-
this.client = client;
|
|
29194
|
-
}
|
|
29195
|
-
accept(tabId = "default", text) {
|
|
29196
|
-
return this.client.send("dialog.accept", { tabId, ...text !== undefined ? { text } : {} });
|
|
29197
|
-
}
|
|
29198
|
-
dismiss(tabId = "default") {
|
|
29199
|
-
return this.client.send("dialog.dismiss", { tabId });
|
|
29200
|
-
}
|
|
29201
|
-
status(tabId = "default") {
|
|
29202
|
-
return this.client.send("dialog.status", { tabId });
|
|
29203
|
-
}
|
|
29204
|
-
setAutoAction(tabId = "default", action) {
|
|
29205
|
-
return this.client.send("dialog.onDialog", { tabId, action });
|
|
29522
|
+
requests(tabId = "default") {
|
|
29523
|
+
return this.client.send("capture.requests", { tabId });
|
|
29206
29524
|
}
|
|
29207
|
-
|
|
29208
|
-
return this.client.send("
|
|
29525
|
+
ws(tabId = "default") {
|
|
29526
|
+
return this.client.send("capture.ws", { tabId });
|
|
29209
29527
|
}
|
|
29210
|
-
|
|
29211
|
-
return this.client.
|
|
29528
|
+
cookies(tabId = "default") {
|
|
29529
|
+
return this.client.send("capture.cookies", { tabId });
|
|
29212
29530
|
}
|
|
29213
|
-
|
|
29214
|
-
return
|
|
29215
|
-
const timer = setTimeout(() => {
|
|
29216
|
-
unsub();
|
|
29217
|
-
reject(new Error(`dialog.waitAndAccept: timed out after ${timeoutMs}ms`));
|
|
29218
|
-
}, timeoutMs);
|
|
29219
|
-
const unsub = this.onDialog(tabId, async (data) => {
|
|
29220
|
-
clearTimeout(timer);
|
|
29221
|
-
unsub();
|
|
29222
|
-
await this.accept(tabId, text);
|
|
29223
|
-
resolve2(data);
|
|
29224
|
-
});
|
|
29225
|
-
});
|
|
29531
|
+
storage(tabId = "default") {
|
|
29532
|
+
return this.client.send("capture.storage", { tabId });
|
|
29226
29533
|
}
|
|
29227
|
-
|
|
29228
|
-
return
|
|
29229
|
-
const timer = setTimeout(() => {
|
|
29230
|
-
unsub();
|
|
29231
|
-
reject(new Error(`dialog.waitAndDismiss: timed out after ${timeoutMs}ms`));
|
|
29232
|
-
}, timeoutMs);
|
|
29233
|
-
const unsub = this.onDialog(tabId, async (data) => {
|
|
29234
|
-
clearTimeout(timer);
|
|
29235
|
-
unsub();
|
|
29236
|
-
await this.dismiss(tabId);
|
|
29237
|
-
resolve2(data);
|
|
29238
|
-
});
|
|
29239
|
-
});
|
|
29534
|
+
clear(tabId = "default") {
|
|
29535
|
+
return this.client.send("capture.clear", { tabId });
|
|
29240
29536
|
}
|
|
29241
29537
|
}
|
|
29242
|
-
function
|
|
29243
|
-
return new
|
|
29538
|
+
function createCaptureAPI(client) {
|
|
29539
|
+
return new CaptureClient(client);
|
|
29244
29540
|
}
|
|
29245
29541
|
|
|
29246
29542
|
// piggy/export/index.ts
|
|
@@ -29318,97 +29614,6 @@ function createExportAPI(client) {
|
|
|
29318
29614
|
return new ExportClient(client);
|
|
29319
29615
|
}
|
|
29320
29616
|
|
|
29321
|
-
// piggy/find/index.ts
|
|
29322
|
-
class FindClient {
|
|
29323
|
-
client;
|
|
29324
|
-
constructor(client) {
|
|
29325
|
-
this.client = client;
|
|
29326
|
-
}
|
|
29327
|
-
css(selector, tabId = "default") {
|
|
29328
|
-
return this.client.send("find.css", { selector, tabId });
|
|
29329
|
-
}
|
|
29330
|
-
all(selector, tabId = "default") {
|
|
29331
|
-
return this.client.send("find.all", { selector, tabId });
|
|
29332
|
-
}
|
|
29333
|
-
first(selector, tabId = "default") {
|
|
29334
|
-
return this.client.send("find.first", { selector, tabId });
|
|
29335
|
-
}
|
|
29336
|
-
byText(text, tabId = "default") {
|
|
29337
|
-
return this.client.send("find.byText", { text, tabId });
|
|
29338
|
-
}
|
|
29339
|
-
byAttr(attr, value, tabId = "default") {
|
|
29340
|
-
return this.client.send("find.byAttr", { attr, value, tabId });
|
|
29341
|
-
}
|
|
29342
|
-
byTag(tag, tabId = "default") {
|
|
29343
|
-
return this.client.send("find.byTag", { tag, tabId });
|
|
29344
|
-
}
|
|
29345
|
-
byPlaceholder(text, tabId = "default") {
|
|
29346
|
-
return this.client.send("find.byPlaceholder", { text, tabId });
|
|
29347
|
-
}
|
|
29348
|
-
byRole(role, name, tabId = "default") {
|
|
29349
|
-
return this.client.send("find.byRole", { role, name, tabId });
|
|
29350
|
-
}
|
|
29351
|
-
children(selector, tabId = "default") {
|
|
29352
|
-
return this.client.send("find.children", { selector, tabId });
|
|
29353
|
-
}
|
|
29354
|
-
parent(selector, tabId = "default") {
|
|
29355
|
-
return this.client.send("find.parent", { selector, tabId });
|
|
29356
|
-
}
|
|
29357
|
-
closest(selector, ancestor, tabId = "default") {
|
|
29358
|
-
return this.client.send("find.closest", { selector, ancestor, tabId });
|
|
29359
|
-
}
|
|
29360
|
-
count(selector, tabId = "default") {
|
|
29361
|
-
return this.client.send("find.count", { selector, tabId });
|
|
29362
|
-
}
|
|
29363
|
-
exists(selector, tabId = "default") {
|
|
29364
|
-
return this.client.send("find.exists", { selector, tabId });
|
|
29365
|
-
}
|
|
29366
|
-
visible(selector, tabId = "default") {
|
|
29367
|
-
return this.client.send("find.visible", { selector, tabId });
|
|
29368
|
-
}
|
|
29369
|
-
enabled(selector, tabId = "default") {
|
|
29370
|
-
return this.client.send("find.enabled", { selector, tabId });
|
|
29371
|
-
}
|
|
29372
|
-
checked(selector, tabId = "default") {
|
|
29373
|
-
return this.client.send("find.checked", { selector, tabId });
|
|
29374
|
-
}
|
|
29375
|
-
}
|
|
29376
|
-
function createFindAPI(client) {
|
|
29377
|
-
return new FindClient(client);
|
|
29378
|
-
}
|
|
29379
|
-
|
|
29380
|
-
// piggy/iframe/index.ts
|
|
29381
|
-
class IframeClient {
|
|
29382
|
-
client;
|
|
29383
|
-
constructor(client) {
|
|
29384
|
-
this.client = client;
|
|
29385
|
-
}
|
|
29386
|
-
list(tabId = "default") {
|
|
29387
|
-
return this.client.send("iframe.list", { tabId });
|
|
29388
|
-
}
|
|
29389
|
-
evaluate(opts, tabId = "default") {
|
|
29390
|
-
return this.client.send("iframe.evaluate", { ...opts, tabId });
|
|
29391
|
-
}
|
|
29392
|
-
click(opts, tabId = "default") {
|
|
29393
|
-
return this.client.send("iframe.click", { ...opts, tabId });
|
|
29394
|
-
}
|
|
29395
|
-
type(opts, tabId = "default") {
|
|
29396
|
-
return this.client.send("iframe.type", { ...opts, tabId });
|
|
29397
|
-
}
|
|
29398
|
-
text(opts, tabId = "default") {
|
|
29399
|
-
return this.client.send("iframe.text", { ...opts, tabId });
|
|
29400
|
-
}
|
|
29401
|
-
html(opts, tabId = "default") {
|
|
29402
|
-
return this.client.send("iframe.html", { ...opts, tabId });
|
|
29403
|
-
}
|
|
29404
|
-
waitSel(opts, tabId = "default") {
|
|
29405
|
-
return this.client.send("iframe.waitSel", { ...opts, tabId });
|
|
29406
|
-
}
|
|
29407
|
-
}
|
|
29408
|
-
function createIframeAPI(client) {
|
|
29409
|
-
return new IframeClient(client);
|
|
29410
|
-
}
|
|
29411
|
-
|
|
29412
29617
|
// piggy/interactions/index.ts
|
|
29413
29618
|
class InteractionsClient {
|
|
29414
29619
|
client;
|
|
@@ -29535,62 +29740,6 @@ function createNavigationAPI(client) {
|
|
|
29535
29740
|
return new NavigationClient(client);
|
|
29536
29741
|
}
|
|
29537
29742
|
|
|
29538
|
-
// piggy/provide/index.ts
|
|
29539
|
-
class ProvideClient {
|
|
29540
|
-
client;
|
|
29541
|
-
constructor(client) {
|
|
29542
|
-
this.client = client;
|
|
29543
|
-
}
|
|
29544
|
-
text(opts, tabId = "default") {
|
|
29545
|
-
return this.client.send("provide.text", { ...opts, tabId });
|
|
29546
|
-
}
|
|
29547
|
-
textAll(opts, tabId = "default") {
|
|
29548
|
-
return this.client.send("provide.textAll", { ...opts, tabId });
|
|
29549
|
-
}
|
|
29550
|
-
attr(opts, tabId = "default") {
|
|
29551
|
-
return this.client.send("provide.attr", { ...opts, tabId });
|
|
29552
|
-
}
|
|
29553
|
-
attrAll(opts, tabId = "default") {
|
|
29554
|
-
return this.client.send("provide.attrAll", { ...opts, tabId });
|
|
29555
|
-
}
|
|
29556
|
-
html(opts, tabId = "default") {
|
|
29557
|
-
return this.client.send("provide.html", { ...opts, tabId });
|
|
29558
|
-
}
|
|
29559
|
-
table(opts, tabId = "default") {
|
|
29560
|
-
return this.client.send("provide.table", { ...opts, tabId });
|
|
29561
|
-
}
|
|
29562
|
-
list(opts, tabId = "default") {
|
|
29563
|
-
return this.client.send("provide.list", { ...opts, tabId });
|
|
29564
|
-
}
|
|
29565
|
-
links(opts, tabId = "default") {
|
|
29566
|
-
return this.client.send("provide.links", { ...opts, tabId });
|
|
29567
|
-
}
|
|
29568
|
-
images(opts, tabId = "default") {
|
|
29569
|
-
return this.client.send("provide.images", { ...opts, tabId });
|
|
29570
|
-
}
|
|
29571
|
-
form(opts, tabId = "default") {
|
|
29572
|
-
return this.client.send("provide.form", { ...opts, tabId });
|
|
29573
|
-
}
|
|
29574
|
-
page(tabId = "default") {
|
|
29575
|
-
return this.client.send("provide.page", { tabId });
|
|
29576
|
-
}
|
|
29577
|
-
div(opts, tabId = "default") {
|
|
29578
|
-
return this.client.send("provide.div", { ...opts, tabId });
|
|
29579
|
-
}
|
|
29580
|
-
meta(tabId = "default") {
|
|
29581
|
-
return this.client.send("provide.meta", { tabId });
|
|
29582
|
-
}
|
|
29583
|
-
select(opts, tabId = "default") {
|
|
29584
|
-
return this.client.send("provide.select", { ...opts, tabId });
|
|
29585
|
-
}
|
|
29586
|
-
json(opts, tabId = "default") {
|
|
29587
|
-
return this.client.send("provide.json", { ...opts, tabId });
|
|
29588
|
-
}
|
|
29589
|
-
}
|
|
29590
|
-
function createProvideAPI(client) {
|
|
29591
|
-
return new ProvideClient(client);
|
|
29592
|
-
}
|
|
29593
|
-
|
|
29594
29743
|
// piggy/proxy/index.ts
|
|
29595
29744
|
class ProxyClient {
|
|
29596
29745
|
client;
|
|
@@ -29650,57 +29799,6 @@ function createProxyAPI(client) {
|
|
|
29650
29799
|
return new ProxyClient(client);
|
|
29651
29800
|
}
|
|
29652
29801
|
|
|
29653
|
-
// piggy/session/index.ts
|
|
29654
|
-
class SessionClient {
|
|
29655
|
-
client;
|
|
29656
|
-
constructor(client) {
|
|
29657
|
-
this.client = client;
|
|
29658
|
-
}
|
|
29659
|
-
reload(tabId = "default") {
|
|
29660
|
-
return this.client.send("session.reload", { tabId });
|
|
29661
|
-
}
|
|
29662
|
-
paths() {
|
|
29663
|
-
return this.client.send("session.paths", {});
|
|
29664
|
-
}
|
|
29665
|
-
cookiesPath() {
|
|
29666
|
-
return this.client.send("session.cookies.path", {});
|
|
29667
|
-
}
|
|
29668
|
-
profilePath() {
|
|
29669
|
-
return this.client.send("session.profile.path", {});
|
|
29670
|
-
}
|
|
29671
|
-
wsPath() {
|
|
29672
|
-
return this.client.send("session.ws.path", {});
|
|
29673
|
-
}
|
|
29674
|
-
pingsPath() {
|
|
29675
|
-
return this.client.send("session.pings.path", {});
|
|
29676
|
-
}
|
|
29677
|
-
setWsSave(enabled) {
|
|
29678
|
-
return this.client.send("session.ws.save", { enabled });
|
|
29679
|
-
}
|
|
29680
|
-
setPingsSave(enabled) {
|
|
29681
|
-
return this.client.send("session.pings.save", { enabled });
|
|
29682
|
-
}
|
|
29683
|
-
async export(tabId = "default") {
|
|
29684
|
-
const raw = await this.client.send("session.export", { tabId });
|
|
29685
|
-
return typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
29686
|
-
}
|
|
29687
|
-
import(data, tabId = "default") {
|
|
29688
|
-
return this.client.send("session.import", {
|
|
29689
|
-
data: JSON.stringify(data),
|
|
29690
|
-
tabId
|
|
29691
|
-
});
|
|
29692
|
-
}
|
|
29693
|
-
setCookie(opts, tabId = "default") {
|
|
29694
|
-
return this.client.send("cookie.set", { ...opts, tabId });
|
|
29695
|
-
}
|
|
29696
|
-
deleteCookie(opts, tabId = "default") {
|
|
29697
|
-
return this.client.send("cookie.delete", { ...opts, tabId });
|
|
29698
|
-
}
|
|
29699
|
-
}
|
|
29700
|
-
function createSessionAPI(client) {
|
|
29701
|
-
return new SessionClient(client);
|
|
29702
|
-
}
|
|
29703
|
-
|
|
29704
29802
|
// piggy/tabs/index.ts
|
|
29705
29803
|
class TabsClient {
|
|
29706
29804
|
client;
|
|
@@ -29710,7 +29808,8 @@ class TabsClient {
|
|
|
29710
29808
|
new() {
|
|
29711
29809
|
return this.client.send("tab.new", {});
|
|
29712
29810
|
}
|
|
29713
|
-
close(
|
|
29811
|
+
close(opts) {
|
|
29812
|
+
const tabId = typeof opts === "string" ? opts : opts.tabId;
|
|
29714
29813
|
return this.client.send("tab.close", { tabId });
|
|
29715
29814
|
}
|
|
29716
29815
|
list() {
|
|
@@ -29867,6 +29966,7 @@ var _router = null;
|
|
|
29867
29966
|
var _tabMode = "tab";
|
|
29868
29967
|
var _extraProcs = [];
|
|
29869
29968
|
var _sites = {};
|
|
29969
|
+
var _singleSiteName = null;
|
|
29870
29970
|
function guardClient() {
|
|
29871
29971
|
if (!_client)
|
|
29872
29972
|
throw new Error("No client. Call piggy.launch() or piggy.connect() first.");
|
|
@@ -29903,9 +30003,15 @@ var piggy = {
|
|
|
29903
30003
|
throw new Error(`No URL for site "${name}"`);
|
|
29904
30004
|
const binaryMode = opts?.binary ?? "headless";
|
|
29905
30005
|
const poolSize = opts?.pool ?? 0;
|
|
30006
|
+
const isSingle = opts?.single === true;
|
|
30007
|
+
if (isSingle && _singleSiteName && _singleSiteName !== name) {
|
|
30008
|
+
throw new Error(`piggy: site "${_singleSiteName}" is already registered as single. ` + `Only one site may use { single: true } at a time.`);
|
|
30009
|
+
}
|
|
29906
30010
|
if (_tabMode === "tab") {
|
|
29907
30011
|
const client = guardClient();
|
|
29908
30012
|
if (poolSize > 1) {
|
|
30013
|
+
if (isSingle)
|
|
30014
|
+
throw new Error("piggy: { single: true } is incompatible with pool > 1");
|
|
29909
30015
|
const pool = new TabPool(client, poolSize, url2, name);
|
|
29910
30016
|
await pool.init();
|
|
29911
30017
|
const siteObj = createSiteObject(name, url2, client, "default", pool);
|
|
@@ -29913,13 +30019,20 @@ var piggy = {
|
|
|
29913
30019
|
piggy[name] = siteObj;
|
|
29914
30020
|
logger_default.success(`[${name}] registered with pool of ${poolSize} tabs`);
|
|
29915
30021
|
} else {
|
|
29916
|
-
const tabId = await client.newTab();
|
|
30022
|
+
const tabId = isSingle ? "default" : await client.newTab();
|
|
29917
30023
|
const siteObj = createSiteObject(name, url2, client, tabId);
|
|
29918
30024
|
_sites[name] = siteObj;
|
|
29919
30025
|
piggy[name] = siteObj;
|
|
29920
|
-
|
|
30026
|
+
if (isSingle) {
|
|
30027
|
+
_singleSiteName = name;
|
|
30028
|
+
logger_default.success(`[${name}] registered as single-tab site (default tab)`);
|
|
30029
|
+
} else {
|
|
30030
|
+
logger_default.success(`[${name}] registered as tab ${tabId}`);
|
|
30031
|
+
}
|
|
29921
30032
|
}
|
|
29922
30033
|
} else {
|
|
30034
|
+
if (isSingle)
|
|
30035
|
+
throw new Error("piggy: { single: true } is only supported in tab mode");
|
|
29923
30036
|
const socketName = `piggy_${name}`;
|
|
29924
30037
|
await spawnBrowserOnSocket(socketName, binaryMode);
|
|
29925
30038
|
await new Promise((r) => setTimeout(r, 500));
|
|
@@ -29933,9 +30046,34 @@ var piggy = {
|
|
|
29933
30046
|
}
|
|
29934
30047
|
return piggy;
|
|
29935
30048
|
},
|
|
30049
|
+
extend: async (...installers) => {
|
|
30050
|
+
if (!_singleSiteName) {
|
|
30051
|
+
throw new Error(`piggy.extend() requires a site registered with { single: true }.
|
|
30052
|
+
` + 'Example: await piggy.register("mysite", url, { single: true })');
|
|
30053
|
+
}
|
|
30054
|
+
if (installers.length === 0) {
|
|
30055
|
+
logger_default.warn("[piggy] extend() called with no plugins — nothing to do");
|
|
30056
|
+
return piggy;
|
|
30057
|
+
}
|
|
30058
|
+
const site = _sites[_singleSiteName];
|
|
30059
|
+
if (!site) {
|
|
30060
|
+
throw new Error(`piggy.extend(): site "${_singleSiteName}" not found — register it first`);
|
|
30061
|
+
}
|
|
30062
|
+
for (const installer of installers) {
|
|
30063
|
+
if (typeof installer !== "function") {
|
|
30064
|
+
throw new Error("piggy.extend(): each argument must be a plugin installer function");
|
|
30065
|
+
}
|
|
30066
|
+
await installer(site);
|
|
30067
|
+
}
|
|
30068
|
+
logger_default.success(`[piggy] ${installers.length} plugin(s) installed on "${_singleSiteName}"`);
|
|
30069
|
+
return piggy;
|
|
30070
|
+
},
|
|
29936
30071
|
get tabs() {
|
|
29937
30072
|
return _router?.tabs ?? createTabsAPI(guardClient());
|
|
29938
30073
|
},
|
|
30074
|
+
get tab() {
|
|
30075
|
+
return _router?.tabs ?? createTabsAPI(guardClient());
|
|
30076
|
+
},
|
|
29939
30077
|
get navigation() {
|
|
29940
30078
|
return _router?.navigation ?? createNavigationAPI(guardClient());
|
|
29941
30079
|
},
|
|
@@ -30045,6 +30183,7 @@ var piggy = {
|
|
|
30045
30183
|
}),
|
|
30046
30184
|
close: async (opts) => {
|
|
30047
30185
|
stopServer();
|
|
30186
|
+
_singleSiteName = null;
|
|
30048
30187
|
if (opts?.force) {
|
|
30049
30188
|
for (const { client: c } of _extraProcs)
|
|
30050
30189
|
c.disconnect();
|