publishport-opencli 1.0.7 → 1.0.9

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/cli-manifest.json CHANGED
@@ -15215,7 +15215,7 @@
15215
15215
  "type": "js",
15216
15216
  "modulePath": "facebook/search.js",
15217
15217
  "sourceFile": "facebook/search.js",
15218
- "navigateBefore": "https://www.facebook.com"
15218
+ "navigateBefore": false
15219
15219
  },
15220
15220
  {
15221
15221
  "site": "facebook",
@@ -47183,6 +47183,125 @@
47183
47183
  "sourceFile": "xianyu/chat.js",
47184
47184
  "navigateBefore": false
47185
47185
  },
47186
+ {
47187
+ "site": "xianyu",
47188
+ "name": "collect",
47189
+ "description": "列出我收藏的商品(分页)",
47190
+ "access": "read",
47191
+ "domain": "www.goofish.com",
47192
+ "strategy": "cookie",
47193
+ "browser": true,
47194
+ "args": [
47195
+ {
47196
+ "name": "page",
47197
+ "type": "int",
47198
+ "default": 1,
47199
+ "required": false,
47200
+ "help": "页码,从 1 开始"
47201
+ },
47202
+ {
47203
+ "name": "page_size",
47204
+ "type": "int",
47205
+ "default": 20,
47206
+ "required": false,
47207
+ "help": "每页条数"
47208
+ }
47209
+ ],
47210
+ "columns": [
47211
+ "item_id",
47212
+ "title",
47213
+ "price",
47214
+ "seller_nick",
47215
+ "want_cnt",
47216
+ "status_str"
47217
+ ],
47218
+ "type": "js",
47219
+ "modulePath": "xianyu/collect.js",
47220
+ "sourceFile": "xianyu/collect.js",
47221
+ "navigateBefore": false
47222
+ },
47223
+ {
47224
+ "site": "xianyu",
47225
+ "name": "delete",
47226
+ "description": "下架/删除商品",
47227
+ "access": "write",
47228
+ "domain": "www.goofish.com",
47229
+ "strategy": "cookie",
47230
+ "browser": true,
47231
+ "args": [
47232
+ {
47233
+ "name": "item_id",
47234
+ "type": "str",
47235
+ "required": true,
47236
+ "positional": true,
47237
+ "help": "商品 itemId"
47238
+ }
47239
+ ],
47240
+ "columns": [
47241
+ "item_id",
47242
+ "ok"
47243
+ ],
47244
+ "type": "js",
47245
+ "modulePath": "xianyu/manage.js",
47246
+ "sourceFile": "xianyu/manage.js",
47247
+ "navigateBefore": false
47248
+ },
47249
+ {
47250
+ "site": "xianyu",
47251
+ "name": "edit",
47252
+ "description": "编辑商品(标题/详情/价格/划线价/库存,按需传)",
47253
+ "access": "write",
47254
+ "domain": "www.goofish.com",
47255
+ "strategy": "cookie",
47256
+ "browser": true,
47257
+ "args": [
47258
+ {
47259
+ "name": "item_id",
47260
+ "type": "str",
47261
+ "required": true,
47262
+ "positional": true,
47263
+ "help": "商品 itemId"
47264
+ },
47265
+ {
47266
+ "name": "title",
47267
+ "type": "str",
47268
+ "required": false,
47269
+ "help": "新标题"
47270
+ },
47271
+ {
47272
+ "name": "desc",
47273
+ "type": "str",
47274
+ "required": false,
47275
+ "help": "新详情描述"
47276
+ },
47277
+ {
47278
+ "name": "price",
47279
+ "type": "float",
47280
+ "required": false,
47281
+ "help": "新价格(元)"
47282
+ },
47283
+ {
47284
+ "name": "original_price",
47285
+ "type": "float",
47286
+ "required": false,
47287
+ "help": "新划线价(元),传 0 清除"
47288
+ },
47289
+ {
47290
+ "name": "quantity",
47291
+ "type": "int",
47292
+ "required": false,
47293
+ "help": "新库存数量"
47294
+ }
47295
+ ],
47296
+ "columns": [
47297
+ "item_id",
47298
+ "ok"
47299
+ ],
47300
+ "type": "js",
47301
+ "modulePath": "xianyu/manage.js",
47302
+ "sourceFile": "xianyu/manage.js",
47303
+ "navigateBefore": false
47304
+ },
47186
47305
  {
47187
47306
  "site": "xianyu",
47188
47307
  "name": "inbox",
@@ -47263,6 +47382,42 @@
47263
47382
  "sourceFile": "xianyu/item.js",
47264
47383
  "navigateBefore": false
47265
47384
  },
47385
+ {
47386
+ "site": "xianyu",
47387
+ "name": "location",
47388
+ "description": "获取账号默认发布地址",
47389
+ "access": "read",
47390
+ "domain": "www.goofish.com",
47391
+ "strategy": "cookie",
47392
+ "browser": true,
47393
+ "args": [
47394
+ {
47395
+ "name": "longitude",
47396
+ "type": "float",
47397
+ "default": 121.4737,
47398
+ "required": false,
47399
+ "help": "经度(默认上海)"
47400
+ },
47401
+ {
47402
+ "name": "latitude",
47403
+ "type": "float",
47404
+ "default": 31.2304,
47405
+ "required": false,
47406
+ "help": "纬度(默认上海)"
47407
+ }
47408
+ ],
47409
+ "columns": [
47410
+ "prov",
47411
+ "city",
47412
+ "area",
47413
+ "poi",
47414
+ "division_id"
47415
+ ],
47416
+ "type": "js",
47417
+ "modulePath": "xianyu/location.js",
47418
+ "sourceFile": "xianyu/location.js",
47419
+ "navigateBefore": false
47420
+ },
47266
47421
  {
47267
47422
  "site": "xianyu",
47268
47423
  "name": "login",
@@ -47346,6 +47501,220 @@
47346
47501
  "sourceFile": "xianyu/messages.js",
47347
47502
  "navigateBefore": false
47348
47503
  },
47504
+ {
47505
+ "site": "xianyu",
47506
+ "name": "mine",
47507
+ "description": "列出当前账号在售/已发布商品(分页)",
47508
+ "access": "read",
47509
+ "domain": "www.goofish.com",
47510
+ "strategy": "cookie",
47511
+ "browser": true,
47512
+ "args": [
47513
+ {
47514
+ "name": "page",
47515
+ "type": "int",
47516
+ "default": 1,
47517
+ "required": false,
47518
+ "help": "页码,从 1 开始"
47519
+ },
47520
+ {
47521
+ "name": "page_size",
47522
+ "type": "int",
47523
+ "default": 20,
47524
+ "required": false,
47525
+ "help": "每页条数"
47526
+ }
47527
+ ],
47528
+ "columns": [
47529
+ "item_id",
47530
+ "title",
47531
+ "price",
47532
+ "status",
47533
+ "main_pic"
47534
+ ],
47535
+ "type": "js",
47536
+ "modulePath": "xianyu/manage.js",
47537
+ "sourceFile": "xianyu/manage.js",
47538
+ "navigateBefore": false
47539
+ },
47540
+ {
47541
+ "site": "xianyu",
47542
+ "name": "order",
47543
+ "description": "列出卖家已售订单(可按状态筛选)",
47544
+ "access": "read",
47545
+ "domain": "www.goofish.com",
47546
+ "strategy": "cookie",
47547
+ "browser": true,
47548
+ "args": [
47549
+ {
47550
+ "name": "page",
47551
+ "type": "int",
47552
+ "default": 1,
47553
+ "required": false,
47554
+ "help": "页码,从 1 开始"
47555
+ },
47556
+ {
47557
+ "name": "page_size",
47558
+ "type": "int",
47559
+ "default": 20,
47560
+ "required": false,
47561
+ "help": "每页条数"
47562
+ },
47563
+ {
47564
+ "name": "status",
47565
+ "type": "str",
47566
+ "default": "ALL",
47567
+ "required": false,
47568
+ "help": "订单状态筛选:ALL / WAITING_PAY / WAITING_SEND / WAITING_RECEIVE / WAITING_RATE / SUCCESS / REFUND"
47569
+ }
47570
+ ],
47571
+ "columns": [
47572
+ "order_id",
47573
+ "item_id",
47574
+ "buyer_nick",
47575
+ "status_str",
47576
+ "total_price",
47577
+ "create_time"
47578
+ ],
47579
+ "type": "js",
47580
+ "modulePath": "xianyu/order.js",
47581
+ "sourceFile": "xianyu/order.js",
47582
+ "navigateBefore": false
47583
+ },
47584
+ {
47585
+ "site": "xianyu",
47586
+ "name": "order-get",
47587
+ "description": "查询单个闲鱼订单详情",
47588
+ "access": "read",
47589
+ "domain": "www.goofish.com",
47590
+ "strategy": "cookie",
47591
+ "browser": true,
47592
+ "args": [
47593
+ {
47594
+ "name": "order_id",
47595
+ "type": "str",
47596
+ "required": true,
47597
+ "positional": true,
47598
+ "help": "订单号 orderId"
47599
+ },
47600
+ {
47601
+ "name": "role",
47602
+ "type": "str",
47603
+ "default": "seller",
47604
+ "required": false,
47605
+ "help": "视角:seller / buyer"
47606
+ }
47607
+ ],
47608
+ "columns": [
47609
+ "order_id",
47610
+ "item_id",
47611
+ "status_str",
47612
+ "total_price",
47613
+ "buyer_nick"
47614
+ ],
47615
+ "type": "js",
47616
+ "modulePath": "xianyu/order.js",
47617
+ "sourceFile": "xianyu/order.js",
47618
+ "navigateBefore": false
47619
+ },
47620
+ {
47621
+ "site": "xianyu",
47622
+ "name": "order-ship-dummy",
47623
+ "description": "虚拟发货(仅虚拟商品,无需物流单号)",
47624
+ "access": "write",
47625
+ "domain": "www.goofish.com",
47626
+ "strategy": "cookie",
47627
+ "browser": true,
47628
+ "args": [
47629
+ {
47630
+ "name": "order_id",
47631
+ "type": "str",
47632
+ "required": true,
47633
+ "positional": true,
47634
+ "help": "订单号 orderId"
47635
+ },
47636
+ {
47637
+ "name": "text",
47638
+ "type": "str",
47639
+ "default": "",
47640
+ "required": false,
47641
+ "help": "发货附言(可选)"
47642
+ }
47643
+ ],
47644
+ "columns": [
47645
+ "order_id",
47646
+ "ok"
47647
+ ],
47648
+ "type": "js",
47649
+ "modulePath": "xianyu/order.js",
47650
+ "sourceFile": "xianyu/order.js",
47651
+ "navigateBefore": false
47652
+ },
47653
+ {
47654
+ "site": "xianyu",
47655
+ "name": "order-ship-freeshipping",
47656
+ "description": "包邮发货(拼团活动专用)",
47657
+ "access": "write",
47658
+ "domain": "www.goofish.com",
47659
+ "strategy": "cookie",
47660
+ "browser": true,
47661
+ "args": [
47662
+ {
47663
+ "name": "order_id",
47664
+ "type": "str",
47665
+ "required": true,
47666
+ "positional": true,
47667
+ "help": "订单号 bizOrderId"
47668
+ },
47669
+ {
47670
+ "name": "item_id",
47671
+ "type": "str",
47672
+ "required": true,
47673
+ "help": "商品 itemId"
47674
+ },
47675
+ {
47676
+ "name": "buyer_id",
47677
+ "type": "str",
47678
+ "required": true,
47679
+ "help": "买家 userId"
47680
+ }
47681
+ ],
47682
+ "columns": [
47683
+ "order_id",
47684
+ "ok"
47685
+ ],
47686
+ "type": "js",
47687
+ "modulePath": "xianyu/order.js",
47688
+ "sourceFile": "xianyu/order.js",
47689
+ "navigateBefore": false
47690
+ },
47691
+ {
47692
+ "site": "xianyu",
47693
+ "name": "polish",
47694
+ "description": "擦亮商品(刷新曝光排序,不改内容)",
47695
+ "access": "write",
47696
+ "domain": "www.goofish.com",
47697
+ "strategy": "cookie",
47698
+ "browser": true,
47699
+ "args": [
47700
+ {
47701
+ "name": "item_id",
47702
+ "type": "str",
47703
+ "required": true,
47704
+ "positional": true,
47705
+ "help": "商品 itemId"
47706
+ }
47707
+ ],
47708
+ "columns": [
47709
+ "item_id",
47710
+ "ok",
47711
+ "already_polished"
47712
+ ],
47713
+ "type": "js",
47714
+ "modulePath": "xianyu/manage.js",
47715
+ "sourceFile": "xianyu/manage.js",
47716
+ "navigateBefore": false
47717
+ },
47349
47718
  {
47350
47719
  "site": "xianyu",
47351
47720
  "name": "publish",
@@ -47423,6 +47792,48 @@
47423
47792
  "sourceFile": "xianyu/publish.js",
47424
47793
  "navigateBefore": false
47425
47794
  },
47795
+ {
47796
+ "site": "xianyu",
47797
+ "name": "rate",
47798
+ "description": "拉某用户收到的信用评价列表",
47799
+ "access": "read",
47800
+ "domain": "www.goofish.com",
47801
+ "strategy": "cookie",
47802
+ "browser": true,
47803
+ "args": [
47804
+ {
47805
+ "name": "user_id",
47806
+ "type": "str",
47807
+ "required": true,
47808
+ "positional": true,
47809
+ "help": "被评价用户 userId(明文数字 uid)"
47810
+ },
47811
+ {
47812
+ "name": "page",
47813
+ "type": "int",
47814
+ "default": 1,
47815
+ "required": false,
47816
+ "help": "页码,从 1 开始"
47817
+ },
47818
+ {
47819
+ "name": "page_size",
47820
+ "type": "int",
47821
+ "default": 20,
47822
+ "required": false,
47823
+ "help": "每页条数"
47824
+ }
47825
+ ],
47826
+ "columns": [
47827
+ "rate_id",
47828
+ "rater_nick",
47829
+ "rate_content",
47830
+ "create_time"
47831
+ ],
47832
+ "type": "js",
47833
+ "modulePath": "xianyu/rate.js",
47834
+ "sourceFile": "xianyu/rate.js",
47835
+ "navigateBefore": false
47836
+ },
47426
47837
  {
47427
47838
  "site": "xianyu",
47428
47839
  "name": "reply",
@@ -47538,6 +47949,36 @@
47538
47949
  "sourceFile": "xianyu/search.js",
47539
47950
  "navigateBefore": false
47540
47951
  },
47952
+ {
47953
+ "site": "xianyu",
47954
+ "name": "user",
47955
+ "description": "查询闲鱼用户主页信息(不传 user_id 看自己)",
47956
+ "access": "read",
47957
+ "domain": "www.goofish.com",
47958
+ "strategy": "cookie",
47959
+ "browser": true,
47960
+ "args": [
47961
+ {
47962
+ "name": "user_id",
47963
+ "type": "str",
47964
+ "required": false,
47965
+ "positional": true,
47966
+ "help": "目标用户 userId;留空看自己"
47967
+ }
47968
+ ],
47969
+ "columns": [
47970
+ "user_id",
47971
+ "nick",
47972
+ "city",
47973
+ "credit_level",
47974
+ "fans_count",
47975
+ "follow_count"
47976
+ ],
47977
+ "type": "js",
47978
+ "modulePath": "xianyu/user.js",
47979
+ "sourceFile": "xianyu/user.js",
47980
+ "navigateBefore": false
47981
+ },
47541
47982
  {
47542
47983
  "site": "xianyu",
47543
47984
  "name": "whoami",
@@ -48449,7 +48890,7 @@
48449
48890
  "name": "topics",
48450
48891
  "type": "str",
48451
48892
  "required": false,
48452
- "help": "话题标签,逗号分隔,不含 # "
48893
+ "help": "话题标签,逗号分隔,不含 # 号。平台话题库匹配不上的会自动跳过并在结果中提示,不影响发布"
48453
48894
  },
48454
48895
  {
48455
48896
  "name": "draft",
@@ -48461,7 +48902,8 @@
48461
48902
  ],
48462
48903
  "columns": [
48463
48904
  "status",
48464
- "detail"
48905
+ "detail",
48906
+ "url"
48465
48907
  ],
48466
48908
  "type": "js",
48467
48909
  "modulePath": "xiaohongshu/publish.js",
@@ -1,8 +1,27 @@
1
- import{ArgumentError as m,AuthRequiredError as h,CommandExecutionError as s,EmptyResultError as i}from"@jackwener/opencli/errors";import{cli as b,Strategy as k}from"@jackwener/opencli/registry";const x="https://www.facebook.com/",a=50;function c(t){const n=Number(t);if(!Number.isInteger(n)||n<1||n>a)throw new m(`facebook feed --limit must be an integer between 1 and ${a}`);return n}function p(t){if(t&&typeof t==="object"&&"data"in t)return t.data;return t}function l(t){return`(() => {
2
- const limit = ${t};
1
+ import{ArgumentError as K,AuthRequiredError as P,CommandExecutionError as Q,EmptyResultError as U}from"@jackwener/opencli/errors";import{cli as h,Strategy as j}from"@jackwener/opencli/registry";const T="https://www.facebook.com/",V=50;function W(f){const J=Number(f);if(!Number.isInteger(J)||J<1||J>V)throw new K(`facebook feed --limit must be an integer between 1 and ${V}`);return J}function Y(f){if(f&&typeof f==="object"&&"data"in f)return f.data;return f}function Z(f){return`(() => {
2
+ const limit = ${f};
3
3
 
4
4
  function clean(value) {
5
- return String(value || '').replace(/\\s+/g, ' ').trim();
5
+ // Strip zero-width / bidi control chars first: Facebook injects them into
6
+ // decoy nodes to poison scrapers. See issue #2089.
7
+ return String(value || '')
8
+ .replace(/[\\u200b-\\u200f\\u202a-\\u202e\\u2060\\ufeff]/g, '')
9
+ .replace(/\\s+/g, ' ')
10
+ .trim();
11
+ }
12
+
13
+ // FB anti-scrape decoys: long spaceless digit runs, spaced single-char
14
+ // strings ("a b c d e"), and hidden-domain .com spam. Real author/content
15
+ // text never looks like this.
16
+ function isDecoyText(text) {
17
+ if (!text) return true;
18
+ if (/^\\d{8,}$/.test(text)) return true;
19
+ if (/^(?:\\S ){4,}\\S$/.test(text) && text.replace(/\\s/g, '').length <= 12) return true;
20
+ return false;
21
+ }
22
+
23
+ function isReelsOrCarouselChrome(text) {
24
+ return /^(Reels|Reels and short videos|Reels 和短视频|快拍|短视频|People you may know)/i.test(text);
6
25
  }
7
26
 
8
27
  function textOf(el) {
@@ -94,6 +113,8 @@ import{ArgumentError as m,AuthRequiredError as h,CommandExecutionError as s,Empt
94
113
  && !isActionText(text)
95
114
  && !isMetricText(text)
96
115
  && !isTimestampText(text)
116
+ && !isDecoyText(text)
117
+ && !/^[\\d\\s.,-]+$/.test(text) // reject all-digit decoy names, but keep "Class of 2024" (#2089)
97
118
  && !/\\/groups\\/|\\/watch\\/|\\/reel\\/|\\/events\\/|\\/friends\\//i.test(href)) {
98
119
  return text;
99
120
  }
@@ -107,6 +128,7 @@ import{ArgumentError as m,AuthRequiredError as h,CommandExecutionError as s,Empt
107
128
  if (text.length <= 10) return false;
108
129
  if (isSuggestionOrChrome(text) || isSponsored(text)) return false;
109
130
  if (isActionText(text) || isMetricText(text) || isTimestampText(text)) return false;
131
+ if (isDecoyText(text) || isReelsOrCarouselChrome(text)) return false;
110
132
  if (/^(See more|查看更多|更多)$/i.test(text)) return false;
111
133
  return true;
112
134
  });
@@ -148,6 +170,47 @@ import{ArgumentError as m,AuthRequiredError as h,CommandExecutionError as s,Empt
148
170
  .filter((el) => textOf(el).length > 30);
149
171
  }
150
172
 
173
+ // Modern Facebook no longer wraps posts in [role="article"] nor exposes the
174
+ // Like/Comment/Share aria-labels the fallback keyed on. Every post still
175
+ // carries one "Actions for this post" control (the ⋯ menu). Anchor on it and
176
+ // walk up to the HIGHEST ancestor that still contains exactly one such
177
+ // control — that bounds the node to a single post. See issue #2089.
178
+ function actionMenuAnchors() {
179
+ // Post menus only — NOT "Actions for this comment", so the anchor set,
180
+ // countMenus, and loadFeedPosts all key on the same thing (#2089).
181
+ return Array.from(document.querySelectorAll('[aria-label]')).filter((el) =>
182
+ /^(Actions for this post|此帖子的操作|针对此帖子的操作|贴文的操作)$/i.test(labelOf(el)));
183
+ }
184
+
185
+ function actionAnchoredContainers() {
186
+ const menus = actionMenuAnchors();
187
+ const seen = new WeakSet();
188
+ const containers = [];
189
+ const countMenus = (node) => {
190
+ let n = 0;
191
+ for (const el of node.querySelectorAll('[aria-label]')) {
192
+ if (/^(Actions for this post|此帖子的操作|针对此帖子的操作|贴文的操作)$/i.test(labelOf(el))) n += 1;
193
+ }
194
+ return n;
195
+ };
196
+ const LANDMARK_ROLES = new Set(['main', 'feed', 'banner', 'navigation', 'complementary', 'contentinfo', 'region']);
197
+ for (const menu of menus) {
198
+ let node = menu.parentElement;
199
+ let best = null;
200
+ for (let depth = 0; depth < 22 && node && node !== document.body && node !== document.documentElement; depth += 1, node = node.parentElement) {
201
+ // Never let a single-post page climb the container up to a page
202
+ // landmark (role=main/feed/...) and emit the whole region as a post.
203
+ if (LANDMARK_ROLES.has(node.getAttribute('role') || '')) break;
204
+ if (countMenus(node) === 1) best = node; else break;
205
+ }
206
+ if (best && !seen.has(best) && textOf(best).length > 30) {
207
+ seen.add(best);
208
+ containers.push(best);
209
+ }
210
+ }
211
+ return containers;
212
+ }
213
+
151
214
  function fallbackContainers() {
152
215
  const main = document.querySelector('[role="main"]');
153
216
  if (!main) return [];
@@ -188,7 +251,8 @@ import{ArgumentError as m,AuthRequiredError as h,CommandExecutionError as s,Empt
188
251
  if (isAuthPage()) return { status: 'auth', rows: [], diagnostics: {} };
189
252
 
190
253
  const primary = primaryContainers();
191
- const combined = dedupe([...primary, ...fallbackContainers()]);
254
+ const actionAnchored = actionAnchoredContainers();
255
+ const combined = dedupe([...primary, ...actionAnchored, ...fallbackContainers()]);
192
256
  const rows = [];
193
257
  for (const container of combined) {
194
258
  const row = extractPost(container, rows.length + 1);
@@ -202,8 +266,17 @@ import{ArgumentError as m,AuthRequiredError as h,CommandExecutionError as s,Empt
202
266
  diagnostics: {
203
267
  articleCount: document.querySelectorAll('[role="article"]').length,
204
268
  primaryCount: primary.length,
269
+ actionMenuCount: actionMenuAnchors().length,
205
270
  fallbackActionCount: document.querySelectorAll('[role="main"] [aria-label="Like"], [role="main"] [aria-label="赞"], [role="main"] [aria-label="Comment"], [role="main"] [aria-label="评论"]').length,
206
271
  mainTextLength: textOf(document.querySelector('[role="main"]')).length,
207
272
  },
208
273
  };
209
- })()`}async function u(t,n){const d=c(n.limit??10);try{await t.goto(x,{settleMs:4000})}catch(o){throw new s(`Failed to navigate to facebook feed: ${o instanceof Error?o.message:o}`,"Check that facebook.com is reachable and the browser extension is connected.")}let e;try{e=p(await t.evaluate(l(d)))}catch(o){throw new s(`Failed to read facebook feed: ${o instanceof Error?o.message:o}`,"Facebook may not have rendered or the feed markup may have changed.")}if(!e||typeof e!=="object"||!Array.isArray(e.rows))throw new s("facebook feed returned malformed extraction payload");if(e.status==="auth")throw new h("www.facebook.com","Open Chrome and log in to Facebook before retrying.");if(e.rows.length>0)return e.rows;if(e.status==="empty")throw new i("facebook feed","Facebook did not show any feed posts for this account.");const r=e.diagnostics||{};if(r.articleCount||r.fallbackActionCount||r.mainTextLength>200)throw new s("facebook feed page rendered but no feed rows could be extracted",`Diagnostics: articles=${r.articleCount||0}, actions=${r.fallbackActionCount||0}, mainTextLength=${r.mainTextLength||0}.`);throw new i("facebook feed","No Facebook feed content was visible in the current browser session.")}const f={site:"facebook",name:"feed",access:"read",description:"Get your Facebook news feed",domain:"www.facebook.com",strategy:k.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"limit",type:"int",default:10,help:"Number of posts"}],columns:["index","author","content","likes","comments","shares"],func:u};b(f);export const __test__={buildFeedExtractScript:l,command:f,getFacebookFeed:u,requireLimit:c};
274
+ })()`}async function X(f,J){const N=`(async () => {
275
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
276
+ window.scrollTo(0, document.body.scrollHeight);
277
+ await sleep(800);
278
+ return document.querySelectorAll('[aria-label]').length
279
+ ? document.querySelectorAll('[role="article"]').length
280
+ + Array.from(document.querySelectorAll('[aria-label]')).filter((el) => /^(Actions for this post|此帖子的操作|针对此帖子的操作|贴文的操作)$/i.test((el.getAttribute('aria-label') || '').trim())).length
281
+ : 0;
282
+ })()`;let z=-1;for(let G=0;G<8;G+=1){let D=0;try{D=Number(Y(await f.evaluate(N)))||0}catch{break}if(D>=J||D===z)break;z=D}}async function $(f,J){const N=W(J.limit??10);try{await f.goto(T,{settleMs:4000})}catch(D){throw new Q(`Failed to navigate to facebook feed: ${D instanceof Error?D.message:D}`,"Check that facebook.com is reachable and the browser extension is connected.")}await X(f,N);let z;try{z=Y(await f.evaluate(Z(N)))}catch(D){throw new Q(`Failed to read facebook feed: ${D instanceof Error?D.message:D}`,"Facebook may not have rendered or the feed markup may have changed.")}if(!z||typeof z!=="object"||!Array.isArray(z.rows))throw new Q("facebook feed returned malformed extraction payload");if(z.status==="auth")throw new P("www.facebook.com","Open Chrome and log in to Facebook before retrying.");if(z.rows.length>0)return z.rows;if(z.status==="empty")throw new U("facebook feed","Facebook did not show any feed posts for this account.");const G=z.diagnostics||{};if(G.articleCount||G.actionMenuCount||G.fallbackActionCount||G.mainTextLength>200)throw new Q("facebook feed page rendered but no feed rows could be extracted",`Diagnostics: articles=${G.articleCount||0}, actions=${G.fallbackActionCount||0}, mainTextLength=${G.mainTextLength||0}.`);throw new U("facebook feed","No Facebook feed content was visible in the current browser session.")}const H={site:"facebook",name:"feed",access:"read",description:"Get your Facebook news feed",domain:"www.facebook.com",strategy:j.COOKIE,browser:!0,navigateBefore:!1,args:[{name:"limit",type:"int",default:10,help:"Number of posts"}],columns:["index","author","content","likes","comments","shares"],func:$};h(H);export const __test__={buildFeedExtractScript:Z,command:H,getFacebookFeed:$,requireLimit:W};