From 31313c69ac1efbdbf1cf7b276c15f0e5bde3dfb3 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Sat, 7 Feb 2026 17:16:04 -0800 Subject: [PATCH] v2.1: Bundle Bird X search - no external CLI needed Vendor Bird's Twitter GraphQL search client directly into /last30days, eliminating the dependency on `npm install -g @steipete/bird`. X search now works out of the box with just Node.js 22+ and browser cookies. - Add vendored bird-search.mjs wrapper (search-only subset of Bird v0.8.0) - Vendor @steipete/sweet-cookie for browser cookie extraction - Update bird_x.py to call vendored Node.js module instead of `bird` binary - Update README.md and SKILL.md for v2.1 (remove Bird CLI install steps) - Include Bird's MIT LICENSE in vendor directory The fallback chain is: vendored search -> xAI API key -> web-only mode. Co-Authored-By: Claude Opus 4.6 --- README.md | 35 +- SKILL.md | 5 +- ...26-02-07-feat-bundle-bird-x-search-plan.md | 208 +++++++ scripts/lib/bird_x.py | 76 ++- scripts/lib/vendor/bird-search/LICENSE | 21 + .../lib/vendor/bird-search/bird-search.mjs | 134 +++++ scripts/lib/vendor/bird-search/lib/cookies.js | 173 ++++++ .../lib/vendor/bird-search/lib/features.json | 17 + .../vendor/bird-search/lib/paginate-cursor.js | 37 ++ .../lib/vendor/bird-search/lib/query-ids.json | 20 + .../bird-search/lib/runtime-features.js | 151 ++++++ .../bird-search/lib/runtime-query-ids.js | 264 +++++++++ .../bird-search/lib/twitter-client-base.js | 129 +++++ .../lib/twitter-client-constants.js | 50 ++ .../lib/twitter-client-features.js | 347 ++++++++++++ .../bird-search/lib/twitter-client-search.js | 157 ++++++ .../bird-search/lib/twitter-client-types.js | 2 + .../bird-search/lib/twitter-client-utils.js | 511 ++++++++++++++++++ .../@steipete/sweet-cookie/LICENSE | 22 + .../@steipete/sweet-cookie/README.md | 29 + .../@steipete/sweet-cookie/dist/index.d.ts | 3 + .../sweet-cookie/dist/index.d.ts.map | 1 + .../@steipete/sweet-cookie/dist/index.js | 2 + .../@steipete/sweet-cookie/dist/index.js.map | 1 + .../sweet-cookie/dist/providers/chrome.d.ts | 8 + .../dist/providers/chrome.d.ts.map | 1 + .../sweet-cookie/dist/providers/chrome.js | 27 + .../sweet-cookie/dist/providers/chrome.js.map | 1 + .../dist/providers/chromeSqlite/crypto.d.ts | 11 + .../providers/chromeSqlite/crypto.d.ts.map | 1 + .../dist/providers/chromeSqlite/crypto.js | 100 ++++ .../dist/providers/chromeSqlite/crypto.js.map | 1 + .../providers/chromeSqlite/linuxKeyring.d.ts | 25 + .../chromeSqlite/linuxKeyring.d.ts.map | 1 + .../providers/chromeSqlite/linuxKeyring.js | 104 ++++ .../chromeSqlite/linuxKeyring.js.map | 1 + .../dist/providers/chromeSqlite/shared.d.ts | 10 + .../providers/chromeSqlite/shared.d.ts.map | 1 + .../dist/providers/chromeSqlite/shared.js | 293 ++++++++++ .../dist/providers/chromeSqlite/shared.js.map | 1 + .../providers/chromeSqlite/windowsDpapi.d.ts | 10 + .../chromeSqlite/windowsDpapi.d.ts.map | 1 + .../providers/chromeSqlite/windowsDpapi.js | 26 + .../chromeSqlite/windowsDpapi.js.map | 1 + .../dist/providers/chromeSqliteLinux.d.ts | 7 + .../dist/providers/chromeSqliteLinux.d.ts.map | 1 + .../dist/providers/chromeSqliteLinux.js | 51 ++ .../dist/providers/chromeSqliteLinux.js.map | 1 + .../dist/providers/chromeSqliteMac.d.ts | 7 + .../dist/providers/chromeSqliteMac.d.ts.map | 1 + .../dist/providers/chromeSqliteMac.js | 60 ++ .../dist/providers/chromeSqliteMac.js.map | 1 + .../dist/providers/chromeSqliteWindows.d.ts | 7 + .../providers/chromeSqliteWindows.d.ts.map | 1 + .../dist/providers/chromeSqliteWindows.js | 38 ++ .../dist/providers/chromeSqliteWindows.js.map | 1 + .../dist/providers/chromium/linuxPaths.d.ts | 5 + .../providers/chromium/linuxPaths.d.ts.map | 1 + .../dist/providers/chromium/linuxPaths.js | 33 ++ .../dist/providers/chromium/linuxPaths.js.map | 1 + .../providers/chromium/macosKeychain.d.ts | 24 + .../providers/chromium/macosKeychain.d.ts.map | 1 + .../dist/providers/chromium/macosKeychain.js | 30 + .../providers/chromium/macosKeychain.js.map | 1 + .../dist/providers/chromium/paths.d.ts | 11 + .../dist/providers/chromium/paths.d.ts.map | 1 + .../dist/providers/chromium/paths.js | 43 ++ .../dist/providers/chromium/paths.js.map | 1 + .../providers/chromium/windowsMasterKey.d.ts | 8 + .../chromium/windowsMasterKey.d.ts.map | 1 + .../providers/chromium/windowsMasterKey.js | 41 ++ .../chromium/windowsMasterKey.js.map | 1 + .../dist/providers/chromium/windowsPaths.d.ts | 8 + .../providers/chromium/windowsPaths.d.ts.map | 1 + .../dist/providers/chromium/windowsPaths.js | 53 ++ .../providers/chromium/windowsPaths.js.map | 1 + .../sweet-cookie/dist/providers/edge.d.ts | 8 + .../sweet-cookie/dist/providers/edge.d.ts.map | 1 + .../sweet-cookie/dist/providers/edge.js | 27 + .../sweet-cookie/dist/providers/edge.js.map | 1 + .../dist/providers/edgeSqliteLinux.d.ts | 7 + .../dist/providers/edgeSqliteLinux.d.ts.map | 1 + .../dist/providers/edgeSqliteLinux.js | 53 ++ .../dist/providers/edgeSqliteLinux.js.map | 1 + .../dist/providers/edgeSqliteMac.d.ts | 8 + .../dist/providers/edgeSqliteMac.d.ts.map | 1 + .../dist/providers/edgeSqliteMac.js | 60 ++ .../dist/providers/edgeSqliteMac.js.map | 1 + .../dist/providers/edgeSqliteWindows.d.ts | 7 + .../dist/providers/edgeSqliteWindows.d.ts.map | 1 + .../dist/providers/edgeSqliteWindows.js | 38 ++ .../dist/providers/edgeSqliteWindows.js.map | 1 + .../dist/providers/firefoxSqlite.d.ts | 6 + .../dist/providers/firefoxSqlite.d.ts.map | 1 + .../dist/providers/firefoxSqlite.js | 257 +++++++++ .../dist/providers/firefoxSqlite.js.map | 1 + .../sweet-cookie/dist/providers/inline.d.ts | 8 + .../dist/providers/inline.d.ts.map | 1 + .../sweet-cookie/dist/providers/inline.js | 71 +++ .../sweet-cookie/dist/providers/inline.js.map | 1 + .../dist/providers/safariBinaryCookies.d.ts | 6 + .../providers/safariBinaryCookies.d.ts.map | 1 + .../dist/providers/safariBinaryCookies.js | 173 ++++++ .../dist/providers/safariBinaryCookies.js.map | 1 + .../@steipete/sweet-cookie/dist/public.d.ts | 26 + .../sweet-cookie/dist/public.d.ts.map | 1 + .../@steipete/sweet-cookie/dist/public.js | 195 +++++++ .../@steipete/sweet-cookie/dist/public.js.map | 1 + .../@steipete/sweet-cookie/dist/types.d.ts | 121 +++++ .../sweet-cookie/dist/types.d.ts.map | 1 + .../@steipete/sweet-cookie/dist/types.js | 2 + .../@steipete/sweet-cookie/dist/types.js.map | 1 + .../sweet-cookie/dist/util/base64.d.ts | 2 + .../sweet-cookie/dist/util/base64.d.ts.map | 1 + .../sweet-cookie/dist/util/base64.js | 18 + .../sweet-cookie/dist/util/base64.js.map | 1 + .../sweet-cookie/dist/util/exec.d.ts | 8 + .../sweet-cookie/dist/util/exec.d.ts.map | 1 + .../@steipete/sweet-cookie/dist/util/exec.js | 110 ++++ .../sweet-cookie/dist/util/exec.js.map | 1 + .../sweet-cookie/dist/util/expire.d.ts | 2 + .../sweet-cookie/dist/util/expire.d.ts.map | 1 + .../sweet-cookie/dist/util/expire.js | 32 ++ .../sweet-cookie/dist/util/expire.js.map | 1 + .../@steipete/sweet-cookie/dist/util/fs.d.ts | 2 + .../sweet-cookie/dist/util/fs.d.ts.map | 1 + .../@steipete/sweet-cookie/dist/util/fs.js | 13 + .../sweet-cookie/dist/util/fs.js.map | 1 + .../sweet-cookie/dist/util/hostMatch.d.ts | 2 + .../sweet-cookie/dist/util/hostMatch.d.ts.map | 1 + .../sweet-cookie/dist/util/hostMatch.js | 7 + .../sweet-cookie/dist/util/hostMatch.js.map | 1 + .../sweet-cookie/dist/util/nodeSqlite.d.ts | 5 + .../dist/util/nodeSqlite.d.ts.map | 1 + .../sweet-cookie/dist/util/nodeSqlite.js | 58 ++ .../sweet-cookie/dist/util/nodeSqlite.js.map | 1 + .../sweet-cookie/dist/util/origins.d.ts | 2 + .../sweet-cookie/dist/util/origins.d.ts.map | 1 + .../sweet-cookie/dist/util/origins.js | 27 + .../sweet-cookie/dist/util/origins.js.map | 1 + .../sweet-cookie/dist/util/runtime.d.ts | 2 + .../sweet-cookie/dist/util/runtime.d.ts.map | 1 + .../sweet-cookie/dist/util/runtime.js | 8 + .../sweet-cookie/dist/util/runtime.js.map | 1 + .../@steipete/sweet-cookie/package.json | 40 ++ scripts/lib/vendor/bird-search/package.json | 13 + 146 files changed, 4860 insertions(+), 59 deletions(-) create mode 100644 docs/plans/2026-02-07-feat-bundle-bird-x-search-plan.md create mode 100644 scripts/lib/vendor/bird-search/LICENSE create mode 100644 scripts/lib/vendor/bird-search/bird-search.mjs create mode 100644 scripts/lib/vendor/bird-search/lib/cookies.js create mode 100644 scripts/lib/vendor/bird-search/lib/features.json create mode 100644 scripts/lib/vendor/bird-search/lib/paginate-cursor.js create mode 100644 scripts/lib/vendor/bird-search/lib/query-ids.json create mode 100644 scripts/lib/vendor/bird-search/lib/runtime-features.js create mode 100644 scripts/lib/vendor/bird-search/lib/runtime-query-ids.js create mode 100644 scripts/lib/vendor/bird-search/lib/twitter-client-base.js create mode 100644 scripts/lib/vendor/bird-search/lib/twitter-client-constants.js create mode 100644 scripts/lib/vendor/bird-search/lib/twitter-client-features.js create mode 100644 scripts/lib/vendor/bird-search/lib/twitter-client-search.js create mode 100644 scripts/lib/vendor/bird-search/lib/twitter-client-types.js create mode 100644 scripts/lib/vendor/bird-search/lib/twitter-client-utils.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/LICENSE create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/README.md create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js.map create mode 100644 scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/package.json create mode 100644 scripts/lib/vendor/bird-search/package.json diff --git a/README.md b/README.md index 23571ca..e524a27 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ -# /last30days v2 +# /last30days v2.1 **The AI world reinvents itself every month. This Claude Code skill keeps you current.** /last30days researches your topic across Reddit, X, and the web from the last 30 days, finds what the community is actually upvoting and sharing, and writes you a prompt that works today, not six months ago. Whether it's Ralph Wiggum loops, Suno music prompts, or the latest Midjourney techniques, you'll prompt like someone who's been paying attention. -**New in V2:** Dramatically better search results. Smarter query construction finds posts that V1 missed entirely, and a new two-phase search automatically discovers key @handles and subreddits from initial results, then drills deeper. Also: free X search via [Bird CLI](https://github.com/steipete/bird) (no xAI key needed), `--days=N` for flexible lookback, and automatic model fallback. [Full changelog below.](#whats-new-in-v2) +**New in V2.1:** X search is now fully bundled - no external `bird` CLI or xAI API key needed for X. Just have Node.js 22+ installed. Uses a vendored subset of Bird's Twitter GraphQL client (MIT licensed, originally by [@steipete](https://x.com/steipete)). -**The tradeoff:** V2 finds way more content but takes longer — typically 2-8 minutes depending on how niche your topic is. The old V1 was faster but regularly missed results (like returning 0 X posts on trending topics). We think the depth is worth the wait, but if you'd use a faster "quick mode" that trades some depth for speed, let us know: [@mvanhorn](https://x.com/mvanhorn) / [@slashlast30days](https://x.com/slashlast30days). +**New in V2:** Dramatically better search results. Smarter query construction finds posts that V1 missed entirely, and a new two-phase search automatically discovers key @handles and subreddits from initial results, then drills deeper. Free X search (no xAI key needed), `--days=N` for flexible lookback, and automatic model fallback. [Full changelog below.](#whats-new-in-v2) + +**The tradeoff:** V2 finds way more content but takes longer - typically 2-8 minutes depending on how niche your topic is. The old V1 was faster but regularly missed results (like returning 0 X posts on trending topics). We think the depth is worth the wait, but if you'd use a faster "quick mode" that trades some depth for speed, let us know: [@mvanhorn](https://x.com/mvanhorn) / [@slashlast30days](https://x.com/slashlast30days). **Best for prompt research**: discover what prompting techniques actually work for any tool (ChatGPT, Midjourney, Claude, Figma AI, etc.) by learning from real community discussions and best practices. @@ -20,21 +22,22 @@ git clone https://github.com/mvanhorn/last30days-skill.git ~/.claude/skills/last mkdir -p ~/.config/last30days cat > ~/.config/last30days/.env << 'EOF' OPENAI_API_KEY=sk-... -XAI_API_KEY=xai-... # optional if using Bird CLI +XAI_API_KEY=xai-... # optional - not needed for X search in v2.1 EOF chmod 600 ~/.config/last30days/.env ``` -### Optional: Bird CLI for free X search +### X Search Authentication -[Bird CLI](https://github.com/steipete/bird) lets you search X without an xAI API key. If installed and authenticated, /last30days uses it automatically. +V2.1 bundles X search directly - no external tools needed. Just be logged into x.com in Safari, Chrome, or Firefox and it auto-detects your session cookies. +Alternatively, set environment variables: ```bash -npm install -g @steipete/bird -bird login +export AUTH_TOKEN=your_auth_token # from x.com cookies +export CT0=your_ct0_token # from x.com cookies ``` -Bird is free and doesn't require an xAI key. If both Bird and an xAI key are available, Bird is preferred. +**Requirements:** Node.js 22+ (for the vendored Twitter GraphQL client). ## Usage @@ -780,11 +783,11 @@ This example shows /last30days discovering **emerging developer workflows** - re ## Requirements - **OpenAI API key** - For Reddit research (uses web search via Responses API) -- **X search** (one of): - - **Bird CLI** (free) - `npm install -g @steipete/bird && bird login` - - **xAI API key** - Paid, uses Grok's live X search +- **Node.js 22+** - For X search (bundled Twitter GraphQL client) +- **X session** - Be logged into x.com in your browser, or set `AUTH_TOKEN`/`CT0` env vars +- **xAI API key** (optional fallback) - If the bundled search can't authenticate, falls back to xAI's Grok API -At least one API key is required. Bird CLI is recommended for X search since it's free. +At least one API key is required. X search works automatically if you're logged into x.com in your browser. ## How It Works @@ -792,7 +795,7 @@ At least one API key is required. Bird CLI is recommended for X search since it' **Phase 1: Broad discovery** - OpenAI Responses API with `web_search` tool scoped to reddit.com -- Bird CLI (or xAI API) for X/Twitter search +- Vendored Twitter GraphQL search (or xAI API fallback) for X search - WebSearch for blogs, news, docs, tutorials - Reddit JSON enrichment for real engagement metrics (upvotes, comments) - Scoring algorithm weighing recency, relevance, and engagement @@ -825,9 +828,9 @@ V2 finds significantly more content than V1. Two major improvements: **Reddit JSON enrichment** - Fetches real upvote and comment counts from Reddit's free API for every thread, giving you actual engagement signals instead of estimates. -### Free X search via Bird CLI +### Bundled X search (v2.1) -**Bird CLI integration** - Search X without an xAI API key. Just `npm install -g @steipete/bird && bird login`. Auto-detected at runtime — if Bird is installed, it's used automatically. If both Bird and an xAI key are available, Bird is preferred. +**X search is fully self-contained** - No external `bird` CLI or xAI API key needed. /last30days bundles a vendored subset of Bird's Twitter GraphQL client (MIT licensed, by Peter Steinberger). Just be logged into x.com in your browser and it auto-detects your session. Falls back to xAI API if bundled search can't authenticate. ### Everything else diff --git a/SKILL.md b/SKILL.md index bd750be..ea1a9d0 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,11 +1,12 @@ --- name: last30days +version: "2.1" description: Research a topic from the last 30 days on Reddit + X + Web, become an expert, and write copy-paste-ready prompts for the user's target tool. argument-hint: 'nano banana pro prompts, NVIDIA news, best AI video tools' allowed-tools: Bash, Read, Write, AskUserQuestion, WebSearch --- -# last30days: Research Any Topic from the Last 30 Days +# last30days v2.1: Research Any Topic from the Last 30 Days Research ANY topic across Reddit, X, and the web. Surface what people are actually discussing, recommending, and debating right now. @@ -251,7 +252,7 @@ KEY PATTERNS from the research: --- ✅ All agents reported back! ├─ 🟠 Reddit: {N} threads │ {N} upvotes │ {N} comments -├─ 🔵 X: {N} posts │ {N} likes │ {N} reposts (via Bird/xAI) +├─ 🔵 X: {N} posts │ {N} likes │ {N} reposts ├─ 🌐 Web: {N} pages (supplementary) └─ 🗣️ Top voices: @{handle1} ({N} likes), @{handle2} │ r/{sub1}, r/{sub2} --- diff --git a/docs/plans/2026-02-07-feat-bundle-bird-x-search-plan.md b/docs/plans/2026-02-07-feat-bundle-bird-x-search-plan.md new file mode 100644 index 0000000..ae5d179 --- /dev/null +++ b/docs/plans/2026-02-07-feat-bundle-bird-x-search-plan.md @@ -0,0 +1,208 @@ +--- +title: "feat: Bundle Bird X search client to eliminate npm dependency" +type: feat +date: 2026-02-07 +--- + +# feat: Bundle Bird X search client to eliminate npm dependency + +## Overview + +Replace the `subprocess.run(["bird", "search", ...])` dependency in `bird_x.py` with a vendored Node.js module that calls Twitter's GraphQL search API directly. This eliminates the need for users to `npm install -g @steipete/bird` and protects against the package being removed from npm. + +Bird is MIT-licensed. We have the full compiled package archived at `vendor/steipete-bird-0.8.0.tgz` and forked to `github.com/mvanhorn/bird-cli-archive`. + +## Problem Statement + +@steipete deleted Bird's GitHub repo on 2026-02-07. The npm package still works today, but if he unpublishes it from npm: +- New users can't `npm install -g @steipete/bird` +- The `bird` binary disappears from PATH on fresh installs +- `bird_x.py` returns 0 X results for everyone without an xAI API key +- /last30days V2's headline feature ("free X search") stops working for new users + +## Proposed Solution + +**Vendor Bird's search-only subset as a Node.js module inside /last30days, called from Python via `subprocess.run(["node", ...])`.** + +This is the minimal-change approach: +- Keep Python as the orchestrator (bird_x.py stays mostly the same) +- Replace `subprocess.run(["bird", "search", ...])` with `subprocess.run(["node", "vendor/bird-search.mjs", ...])` +- Extract only the search-related code from Bird (not posting, bookmarks, lists, etc.) +- Cookie auth stays the same (environment variables or browser extraction) + +### Why not rewrite in pure Python? + +Bird's search client uses Twitter's internal GraphQL API with: +- Rotating QueryIDs (hardcoded + runtime refresh from x.com) +- Specific request header construction (bearer token, csrf, client UUIDs) +- Cursor-based pagination with Twitter-specific response parsing +- The `@steipete/sweet-cookie` dependency for browser cookie extraction + +Porting all of this to Python is ~1000 lines of fragile reverse-engineering. Vendoring the working JS code is faster, safer, and easier to maintain since the archive includes source maps for debugging. + +## Technical Approach + +### What we need from Bird + +Only 8 files from `dist/lib/` (out of 30+): + +1. `twitter-client-base.js` - HTTP client, auth headers, rate limiting +2. `twitter-client-search.js` - Search mixin (the core feature) +3. `twitter-client-utils.js` - Tweet parsing, cursor extraction +4. `twitter-client-constants.js` - API endpoints, QueryIDs +5. `twitter-client-types.js` - TypeScript type stubs +6. `cookies.js` - Cookie resolution (env vars, browser extraction) +7. `runtime-query-ids.js` - QueryID refresh from x.com +8. `paginate-cursor.js` - Cursor pagination helper + +Plus: +- `features.json` - GraphQL feature flags +- `query-ids.json` - Hardcoded QueryID fallbacks + +### What we DON'T need + +Posting, bookmarks, lists, timelines, engagement, follow, media, news, user lookup, user tweets - all the non-search mixins. This cuts the vendored code roughly in half. + +### Architecture + +``` +scripts/ + lib/ + bird_x.py # MODIFIED - calls node instead of bird binary + vendor/ + bird-search/ + bird-search.mjs # NEW - thin CLI wrapper, ~40 lines + lib/ # VENDORED - subset of Bird's dist/lib/ + twitter-client-base.js + twitter-client-search.js + twitter-client-utils.js + twitter-client-constants.js + twitter-client-types.js + cookies.js + runtime-query-ids.js + paginate-cursor.js + features.json + query-ids.json + node_modules/ # VENDORED - sweet-cookie only + @steipete/ + sweet-cookie/ + package.json # Minimal, points to bird-search.mjs + LICENSE # Bird's MIT license (required by MIT terms) +``` + +### Implementation + +#### 1. Create `bird-search.mjs` wrapper (~40 lines) + +A minimal Node.js script that: +- Accepts: `node bird-search.mjs --count --json` +- Creates a TwitterClient with search mixin only +- Resolves cookies (env vars first, then browser extraction) +- Calls `client.search(query, count)` +- Outputs JSON to stdout +- Exits with code 0 on success, 1 on error + +This replaces the full `bird` CLI binary. Same interface, fraction of the code. + +#### 2. Modify `bird_x.py` - change subprocess target + +```python +# BEFORE (current) +cmd = ["bird", "search", query, "-n", str(count), "--json"] + +# AFTER (vendored) +bird_search = Path(__file__).parent / "vendor" / "bird-search" / "bird-search.mjs" +cmd = ["node", bird_search, query, "--count", str(count), "--json"] +``` + +Same subprocess pattern. Same JSON output format. Minimal diff. + +#### 3. Update auth check functions + +```python +# BEFORE +def is_bird_installed() -> bool: + return shutil.which("bird") is not None + +# AFTER +def is_bird_installed() -> bool: + bird_search = Path(__file__).parent / "vendor" / "bird-search" / "bird-search.mjs" + return bird_search.exists() and shutil.which("node") is not None +``` + +`is_bird_authenticated()` changes from `bird whoami` to a quick Node.js cookie check or environment variable check. + +`install_bird()` becomes a no-op (already vendored) or removes itself entirely. + +#### 4. Vendor sweet-cookie + +`@steipete/sweet-cookie` is the only runtime dependency. It handles browser cookie extraction on macOS/Linux. Options: + +**Option A (recommended):** Vendor sweet-cookie into `vendor/bird-search/node_modules/`. It's small (one file). This makes the skill fully self-contained with zero npm installs. + +**Option B:** Fall back to environment variables only (no browser cookie extraction). Users would need to manually set `AUTH_TOKEN` and `CT0` env vars. Simpler but worse UX. + +Recommend Option A - vendor it. + +#### 5. Update user-facing docs + +- `README.md` - Remove "Install Bird CLI" section, replace with "Requires Node.js 22+" +- `SKILL.md` - Remove Bird CLI installation instructions +- Keep the fallback chain: vendored Bird search -> xAI API key -> web-only + +## Acceptance Criteria + +- [ ] `bird_x.py` calls vendored Node.js module instead of `bird` binary +- [ ] `search_x()` returns identical JSON format (no downstream changes needed) +- [ ] `search_handles()` works with vendored module +- [ ] Cookie auth works via environment variables (`AUTH_TOKEN`, `CT0`) +- [ ] Cookie auth works via browser extraction (sweet-cookie) +- [ ] `is_bird_installed()` checks for vendored module + Node.js +- [ ] `install_bird()` removed or returns success immediately +- [ ] No `npm install -g @steipete/bird` required anywhere +- [ ] Bird's MIT LICENSE included in vendor directory +- [ ] README updated to remove Bird CLI install steps +- [ ] SKILL.md updated to remove Bird CLI references +- [ ] Works on macOS (primary) and Linux +- [ ] Fallback to xAI API key still works if vendored search fails + +## Files Changed + +| File | Action | Description | +|------|--------|-------------| +| `scripts/lib/bird_x.py` | MODIFY | Replace `["bird", ...]` subprocess calls with `["node", "vendor/bird-search/bird-search.mjs", ...]` | +| `scripts/lib/vendor/bird-search/bird-search.mjs` | CREATE | Thin Node.js wrapper that imports Bird's search client and outputs JSON | +| `scripts/lib/vendor/bird-search/lib/*.js` | VENDOR | 8 files from Bird's dist/lib/ (search subset only) | +| `scripts/lib/vendor/bird-search/lib/features.json` | VENDOR | GraphQL feature flags | +| `scripts/lib/vendor/bird-search/lib/query-ids.json` | VENDOR | Hardcoded QueryID fallbacks | +| `scripts/lib/vendor/bird-search/node_modules/` | VENDOR | sweet-cookie package | +| `scripts/lib/vendor/bird-search/package.json` | CREATE | Minimal package.json for module resolution | +| `scripts/lib/vendor/bird-search/LICENSE` | COPY | Bird's MIT license | +| `README.md` | MODIFY | Remove Bird CLI install section, add Node.js 22+ requirement | +| `SKILL.md` | MODIFY | Remove Bird CLI references | + +## Dependencies & Risks + +**Node.js 22+ required** - Users who had Bird CLI already have Node.js. This is not a new dependency, just a version requirement. Claude Code environments typically have Node.js. + +**Twitter API changes** - The GraphQL QueryIDs may rotate. Bird includes a runtime refresh mechanism (`runtime-query-ids.js`) that fetches new IDs from x.com. This is vendored and will continue working. + +**sweet-cookie platform support** - Browser cookie extraction only works on macOS (Safari, Chrome, Firefox) and Linux (Chrome, Firefox). Windows users need manual env vars. This matches Bird CLI's existing behavior. + +**Legal** - Bird is MIT licensed. MIT requires including the license notice in copies. We include `LICENSE` in the vendor directory. Using Twitter's internal API is the same legal gray area Bird always operated in - user accepted this when they used Bird. + +## What This Does NOT Change + +- Python remains the orchestrator - bird_x.py still does query construction, retry logic, response parsing +- The fallback chain stays: vendored search -> xAI API -> web-only +- Cookie auth mechanism is identical (env vars or browser extraction) +- JSON output format is identical - no changes needed in score.py or format.py +- xai_x.py is completely untouched + +## References + +- Bird CLI archive: `github.com/mvanhorn/bird-cli-archive` +- Local vendor tarball: `vendor/steipete-bird-0.8.0.tgz` +- Bird search implementation: `bird-cli-archive/dist/lib/twitter-client-search.js` +- Current bird_x.py: `scripts/lib/bird_x.py` +- Fallback chain: `scripts/lib/env.py:get_x_source()` diff --git a/scripts/lib/bird_x.py b/scripts/lib/bird_x.py index 507454d..8d67bd5 100644 --- a/scripts/lib/bird_x.py +++ b/scripts/lib/bird_x.py @@ -1,12 +1,20 @@ -"""Bird CLI client for X (Twitter) search.""" +"""Bird X search client - vendored Twitter GraphQL search for /last30days v2.1. + +Uses a vendored subset of @steipete/bird v0.8.0 (MIT License) to search X +via Twitter's GraphQL API. No external `bird` CLI binary needed - just Node.js 22+. +""" import json import shutil import subprocess import sys +from pathlib import Path from datetime import datetime from typing import Any, Dict, List, Optional, Tuple +# Path to the vendored bird-search wrapper +_BIRD_SEARCH_MJS = Path(__file__).parent / "vendor" / "bird-search" / "bird-search.mjs" + # Depth configurations: number of results to request DEPTH_CONFIG = { "quick": 12, @@ -77,32 +85,33 @@ def _extract_core_subject(topic: str) -> str: def is_bird_installed() -> bool: - """Check if Bird CLI is installed. + """Check if vendored Bird search module is available. Returns: - True if 'bird' command is available in PATH, False otherwise. + True if bird-search.mjs exists and Node.js 22+ is in PATH. """ - return shutil.which("bird") is not None + if not _BIRD_SEARCH_MJS.exists(): + return False + return shutil.which("node") is not None def is_bird_authenticated() -> Optional[str]: - """Check if Bird is authenticated by running 'bird whoami'. + """Check if X credentials are available (env vars or browser cookies). Returns: - Username if authenticated, None otherwise. + Auth source string if authenticated, None otherwise. """ if not is_bird_installed(): return None try: result = subprocess.run( - ["bird", "whoami"], + ["node", str(_BIRD_SEARCH_MJS), "--whoami"], capture_output=True, text=True, - timeout=10, + timeout=15, ) if result.returncode == 0 and result.stdout.strip(): - # Output is typically the username return result.stdout.strip().split('\n')[0] return None except (subprocess.TimeoutExpired, FileNotFoundError, subprocess.SubprocessError): @@ -110,7 +119,7 @@ def is_bird_authenticated() -> Optional[str]: def check_npm_available() -> bool: - """Check if npm is available for installation. + """Check if npm is available (kept for API compatibility). Returns: True if 'npm' command is available in PATH, False otherwise. @@ -119,52 +128,37 @@ def check_npm_available() -> bool: def install_bird() -> Tuple[bool, str]: - """Install Bird CLI via npm. + """No-op - Bird search is vendored in v2.1, no installation needed. Returns: Tuple of (success, message). """ - if not check_npm_available(): - return False, "npm not found. Install Node.js first, or install Bird manually: https://github.com/steipete/bird" - - try: - _log("Installing Bird CLI...") - result = subprocess.run( - ["npm", "install", "-g", "@steipete/bird"], - capture_output=True, - text=True, - timeout=120, - ) - if result.returncode == 0: - return True, "Bird CLI installed successfully!" - else: - error = result.stderr.strip() or result.stdout.strip() or "Unknown error" - return False, f"Installation failed: {error}" - except subprocess.TimeoutExpired: - return False, "Installation timed out" - except Exception as e: - return False, f"Installation error: {e}" + if is_bird_installed(): + return True, "Bird search is bundled with /last30days v2.1 - no installation needed." + if not shutil.which("node"): + return False, "Node.js 22+ is required for X search. Install Node.js first." + return False, f"Vendored bird-search.mjs not found at {_BIRD_SEARCH_MJS}" def get_bird_status() -> Dict[str, Any]: - """Get comprehensive Bird status. + """Get comprehensive Bird search status. Returns: Dict with keys: installed, authenticated, username, can_install """ installed = is_bird_installed() - username = is_bird_authenticated() if installed else None + auth_source = is_bird_authenticated() if installed else None return { "installed": installed, - "authenticated": username is not None, - "username": username, - "can_install": check_npm_available(), + "authenticated": auth_source is not None, + "username": auth_source, # Now returns auth source (e.g., "Safari", "env AUTH_TOKEN") + "can_install": True, # Always vendored in v2.1 } def _run_bird_search(query: str, count: int, timeout: int) -> Dict[str, Any]: - """Run a single Bird CLI search and return raw response. + """Run a search using the vendored bird-search.mjs module. Args: query: Full search query string (including since: filter) @@ -175,9 +169,9 @@ def _run_bird_search(query: str, count: int, timeout: int) -> Dict[str, Any]: Raw Bird JSON response or error dict. """ cmd = [ - "bird", "search", + "node", str(_BIRD_SEARCH_MJS), query, - "-n", str(count), + "--count", str(count), "--json", ] @@ -276,9 +270,9 @@ def search_handles( query = f"from:{handle} {core_topic} since:{from_date}" cmd = [ - "bird", "search", + "node", str(_BIRD_SEARCH_MJS), query, - "-n", str(count_per), + "--count", str(count_per), "--json", ] diff --git a/scripts/lib/vendor/bird-search/LICENSE b/scripts/lib/vendor/bird-search/LICENSE new file mode 100644 index 0000000..f7b5266 --- /dev/null +++ b/scripts/lib/vendor/bird-search/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Peter Steinberger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/scripts/lib/vendor/bird-search/bird-search.mjs b/scripts/lib/vendor/bird-search/bird-search.mjs new file mode 100644 index 0000000..2f96c52 --- /dev/null +++ b/scripts/lib/vendor/bird-search/bird-search.mjs @@ -0,0 +1,134 @@ +#!/usr/bin/env node +/** + * bird-search.mjs - Vendored Bird CLI search wrapper for /last30days. + * Subset of @steipete/bird v0.8.0 (MIT License, Peter Steinberger). + * + * Usage: + * node bird-search.mjs [--count N] [--json] + * node bird-search.mjs --whoami + * node bird-search.mjs --check + */ + +import { resolveCredentials } from './lib/cookies.js'; +import { TwitterClientBase } from './lib/twitter-client-base.js'; +import { withSearch } from './lib/twitter-client-search.js'; + +// Build a search-only client (no posting, bookmarks, etc.) +const SearchClient = withSearch(TwitterClientBase); + +const args = process.argv.slice(2); + +// --check: verify that credentials can be resolved +if (args.includes('--check')) { + try { + const { cookies, warnings } = await resolveCredentials({}); + if (cookies.authToken && cookies.ct0) { + process.stdout.write(JSON.stringify({ authenticated: true, source: cookies.source })); + process.exit(0); + } else { + process.stdout.write(JSON.stringify({ authenticated: false, warnings })); + process.exit(1); + } + } catch (err) { + process.stdout.write(JSON.stringify({ authenticated: false, error: err.message })); + process.exit(1); + } +} + +// --whoami: check auth and output source +if (args.includes('--whoami')) { + try { + const { cookies } = await resolveCredentials({}); + if (cookies.authToken && cookies.ct0) { + process.stdout.write(cookies.source || 'authenticated'); + process.exit(0); + } else { + process.stderr.write('Not authenticated\n'); + process.exit(1); + } + } catch (err) { + process.stderr.write(`Auth check failed: ${err.message}\n`); + process.exit(1); + } +} + +// Parse search args +let query = null; +let count = 20; +let jsonOutput = false; + +for (let i = 0; i < args.length; i++) { + if (args[i] === '--count' && args[i + 1]) { + count = parseInt(args[i + 1], 10); + i++; + } else if (args[i] === '-n' && args[i + 1]) { + count = parseInt(args[i + 1], 10); + i++; + } else if (args[i] === '--json') { + jsonOutput = true; + } else if (!args[i].startsWith('-')) { + query = args[i]; + } +} + +if (!query) { + process.stderr.write('Usage: node bird-search.mjs [--count N] [--json]\n'); + process.exit(1); +} + +try { + // Resolve credentials (env vars, then browser cookies) + const { cookies, warnings } = await resolveCredentials({}); + + if (!cookies.authToken || !cookies.ct0) { + const msg = warnings.length > 0 ? warnings.join('; ') : 'No Twitter credentials found'; + if (jsonOutput) { + process.stdout.write(JSON.stringify({ error: msg, items: [] })); + } else { + process.stderr.write(`Error: ${msg}\n`); + } + process.exit(1); + } + + // Create search client + const client = new SearchClient({ + cookies: { + authToken: cookies.authToken, + ct0: cookies.ct0, + cookieHeader: cookies.cookieHeader, + }, + timeoutMs: 30000, + }); + + // Run search + const result = await client.search(query, count); + + if (!result.success) { + if (jsonOutput) { + process.stdout.write(JSON.stringify({ error: result.error, items: [] })); + } else { + process.stderr.write(`Search failed: ${result.error}\n`); + } + process.exit(1); + } + + // Output results + const tweets = result.tweets || []; + if (jsonOutput) { + process.stdout.write(JSON.stringify(tweets)); + } else { + for (const tweet of tweets) { + const author = tweet.author?.username || 'unknown'; + process.stdout.write(`@${author}: ${tweet.text?.slice(0, 200)}\n\n`); + } + } + + process.exit(0); +} catch (err) { + if (jsonOutput) { + process.stdout.write(JSON.stringify({ error: err.message, items: [] })); + } else { + process.stderr.write(`Error: ${err.message}\n`); + } + process.exit(1); +} diff --git a/scripts/lib/vendor/bird-search/lib/cookies.js b/scripts/lib/vendor/bird-search/lib/cookies.js new file mode 100644 index 0000000..83ca799 --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/cookies.js @@ -0,0 +1,173 @@ +/** + * Browser cookie extraction for Twitter authentication. + * Delegates to @steipete/sweet-cookie for Safari/Chrome/Firefox reads. + */ +import { getCookies } from '@steipete/sweet-cookie'; +const TWITTER_COOKIE_NAMES = ['auth_token', 'ct0']; +const TWITTER_URL = 'https://x.com/'; +const TWITTER_ORIGINS = ['https://x.com/', 'https://twitter.com/']; +const DEFAULT_COOKIE_TIMEOUT_MS = 30_000; +function normalizeValue(value) { + if (typeof value !== 'string') { + return null; + } + const trimmed = value.trim(); + return trimmed.length > 0 ? trimmed : null; +} +function cookieHeader(authToken, ct0) { + return `auth_token=${authToken}; ct0=${ct0}`; +} +function buildEmpty() { + return { authToken: null, ct0: null, cookieHeader: null, source: null }; +} +function readEnvCookie(cookies, keys, field) { + if (cookies[field]) { + return; + } + for (const key of keys) { + const value = normalizeValue(process.env[key]); + if (!value) { + continue; + } + cookies[field] = value; + if (!cookies.source) { + cookies.source = `env ${key}`; + } + break; + } +} +function resolveSources(cookieSource) { + if (Array.isArray(cookieSource)) { + return cookieSource; + } + if (cookieSource) { + return [cookieSource]; + } + return ['safari', 'chrome', 'firefox']; +} +function labelForSource(source, profile) { + if (source === 'safari') { + return 'Safari'; + } + if (source === 'chrome') { + return profile ? `Chrome profile "${profile}"` : 'Chrome default profile'; + } + return profile ? `Firefox profile "${profile}"` : 'Firefox default profile'; +} +function pickCookieValue(cookies, name) { + const matches = cookies.filter((c) => c?.name === name && typeof c.value === 'string'); + if (matches.length === 0) { + return null; + } + const preferred = matches.find((c) => (c.domain ?? '').endsWith('x.com')); + if (preferred?.value) { + return preferred.value; + } + const twitter = matches.find((c) => (c.domain ?? '').endsWith('twitter.com')); + if (twitter?.value) { + return twitter.value; + } + return matches[0]?.value ?? null; +} +async function readTwitterCookiesFromBrowser(options) { + const warnings = []; + const out = buildEmpty(); + const { cookies, warnings: providerWarnings } = await getCookies({ + url: TWITTER_URL, + origins: TWITTER_ORIGINS, + names: [...TWITTER_COOKIE_NAMES], + browsers: [options.source], + mode: 'merge', + chromeProfile: options.chromeProfile, + firefoxProfile: options.firefoxProfile, + timeoutMs: options.cookieTimeoutMs, + }); + warnings.push(...providerWarnings); + const authToken = pickCookieValue(cookies, 'auth_token'); + const ct0 = pickCookieValue(cookies, 'ct0'); + if (authToken) { + out.authToken = authToken; + } + if (ct0) { + out.ct0 = ct0; + } + if (out.authToken && out.ct0) { + out.cookieHeader = cookieHeader(out.authToken, out.ct0); + out.source = labelForSource(options.source, options.source === 'chrome' ? options.chromeProfile : options.firefoxProfile); + return { cookies: out, warnings }; + } + if (options.source === 'safari') { + warnings.push('No Twitter cookies found in Safari. Make sure you are logged into x.com in Safari.'); + } + else if (options.source === 'chrome') { + warnings.push('No Twitter cookies found in Chrome. Make sure you are logged into x.com in Chrome.'); + } + else { + warnings.push('No Twitter cookies found in Firefox. Make sure you are logged into x.com in Firefox and the profile exists.'); + } + return { cookies: out, warnings }; +} +export async function extractCookiesFromSafari() { + return readTwitterCookiesFromBrowser({ source: 'safari' }); +} +export async function extractCookiesFromChrome(profile) { + return readTwitterCookiesFromBrowser({ source: 'chrome', chromeProfile: profile }); +} +export async function extractCookiesFromFirefox(profile) { + return readTwitterCookiesFromBrowser({ source: 'firefox', firefoxProfile: profile }); +} +/** + * Resolve Twitter credentials from multiple sources. + * Priority: CLI args > environment variables > browsers (ordered). + */ +export async function resolveCredentials(options) { + const warnings = []; + const cookies = buildEmpty(); + const cookieTimeoutMs = typeof options.cookieTimeoutMs === 'number' && + Number.isFinite(options.cookieTimeoutMs) && + options.cookieTimeoutMs > 0 + ? options.cookieTimeoutMs + : process.platform === 'darwin' + ? DEFAULT_COOKIE_TIMEOUT_MS + : undefined; + if (options.authToken) { + cookies.authToken = options.authToken; + cookies.source = 'CLI argument'; + } + if (options.ct0) { + cookies.ct0 = options.ct0; + if (!cookies.source) { + cookies.source = 'CLI argument'; + } + } + readEnvCookie(cookies, ['AUTH_TOKEN', 'TWITTER_AUTH_TOKEN'], 'authToken'); + readEnvCookie(cookies, ['CT0', 'TWITTER_CT0'], 'ct0'); + if (cookies.authToken && cookies.ct0) { + cookies.cookieHeader = cookieHeader(cookies.authToken, cookies.ct0); + return { cookies, warnings }; + } + const sourcesToTry = resolveSources(options.cookieSource); + for (const source of sourcesToTry) { + const res = await readTwitterCookiesFromBrowser({ + source, + chromeProfile: options.chromeProfile, + firefoxProfile: options.firefoxProfile, + cookieTimeoutMs, + }); + warnings.push(...res.warnings); + if (res.cookies.authToken && res.cookies.ct0) { + return { cookies: res.cookies, warnings }; + } + } + if (!cookies.authToken) { + warnings.push('Missing auth_token - provide via --auth-token, AUTH_TOKEN env var, or login to x.com in Safari/Chrome/Firefox'); + } + if (!cookies.ct0) { + warnings.push('Missing ct0 - provide via --ct0, CT0 env var, or login to x.com in Safari/Chrome/Firefox'); + } + if (cookies.authToken && cookies.ct0) { + cookies.cookieHeader = cookieHeader(cookies.authToken, cookies.ct0); + } + return { cookies, warnings }; +} +//# sourceMappingURL=cookies.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/features.json b/scripts/lib/vendor/bird-search/lib/features.json new file mode 100644 index 0000000..c43e03c --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/features.json @@ -0,0 +1,17 @@ +{ + "global": { + "responsive_web_grok_annotations_enabled": false, + "post_ctas_fetch_enabled": true, + "responsive_web_graphql_exclude_directive_enabled": true + }, + "sets": { + "lists": { + "blue_business_profile_image_shape_enabled": true, + "tweetypie_unmention_optimization_enabled": true, + "responsive_web_text_conversations_enabled": false, + "interactive_text_enabled": true, + "vibe_api_enabled": true, + "responsive_web_twitter_blue_verified_badge_is_enabled": true + } + } +} diff --git a/scripts/lib/vendor/bird-search/lib/paginate-cursor.js b/scripts/lib/vendor/bird-search/lib/paginate-cursor.js new file mode 100644 index 0000000..6c061fe --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/paginate-cursor.js @@ -0,0 +1,37 @@ +export async function paginateCursor(opts) { + const { maxPages, pageDelayMs = 1000 } = opts; + const seen = new Set(); + const items = []; + let cursor = opts.cursor; + let pagesFetched = 0; + while (true) { + if (pagesFetched > 0 && pageDelayMs > 0) { + await opts.sleep(pageDelayMs); + } + const page = await opts.fetchPage(cursor); + if (!page.success) { + if (items.length > 0) { + return { success: false, error: page.error, items, nextCursor: cursor }; + } + return page; + } + pagesFetched += 1; + for (const item of page.items) { + const key = opts.getKey(item); + if (seen.has(key)) { + continue; + } + seen.add(key); + items.push(item); + } + const pageCursor = page.cursor; + if (!pageCursor || pageCursor === cursor) { + return { success: true, items, nextCursor: undefined }; + } + if (maxPages !== undefined && pagesFetched >= maxPages) { + return { success: true, items, nextCursor: pageCursor }; + } + cursor = pageCursor; + } +} +//# sourceMappingURL=paginate-cursor.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/query-ids.json b/scripts/lib/vendor/bird-search/lib/query-ids.json new file mode 100644 index 0000000..6033f31 --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/query-ids.json @@ -0,0 +1,20 @@ +{ + "CreateTweet": "nmdAQXJDxw6-0KKF2on7eA", + "CreateRetweet": "LFho5rIi4xcKO90p9jwG7A", + "CreateFriendship": "8h9JVdV8dlSyqyRDJEPCsA", + "DestroyFriendship": "ppXWuagMNXgvzx6WoXBW0Q", + "FavoriteTweet": "lI07N6Otwv1PhnEgXILM7A", + "DeleteBookmark": "Wlmlj2-xzyS1GN3a6cj-mQ", + "TweetDetail": "_NvJCnIjOW__EP5-RF197A", + "SearchTimeline": "6AAys3t42mosm_yTI_QENg", + "Bookmarks": "RV1g3b8n_SGOHwkqKYSCFw", + "BookmarkFolderTimeline": "KJIQpsvxrTfRIlbaRIySHQ", + "Following": "mWYeougg_ocJS2Vr1Vt28w", + "Followers": "SFYY3WsgwjlXSLlfnEUE4A", + "Likes": "ETJflBunfqNa1uE1mBPCaw", + "ExploreSidebar": "lpSN4M6qpimkF4nRFPE3nQ", + "ExplorePage": "kheAINB_4pzRDqkzG3K-ng", + "GenericTimelineById": "uGSr7alSjR9v6QJAIaqSKQ", + "TrendHistory": "Sj4T-jSB9pr0Mxtsc1UKZQ", + "AboutAccountQuery": "zs_jFPFT78rBpXv9Z3U2YQ" +} diff --git a/scripts/lib/vendor/bird-search/lib/runtime-features.js b/scripts/lib/vendor/bird-search/lib/runtime-features.js new file mode 100644 index 0000000..6910e9d --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/runtime-features.js @@ -0,0 +1,151 @@ +import { existsSync, readFileSync } from 'node:fs'; +import { mkdir, writeFile } from 'node:fs/promises'; +import { homedir } from 'node:os'; +import path from 'node:path'; +// biome-ignore lint/correctness/useImportExtensions: JSON module import doesn't use .js extension. +import defaultOverrides from './features.json' with { type: 'json' }; +const DEFAULT_CACHE_FILENAME = 'features.json'; +let cachedOverrides = null; +function normalizeFeatureMap(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) { + return {}; + } + const result = {}; + for (const [key, entry] of Object.entries(value)) { + if (typeof entry === 'boolean') { + result[key] = entry; + } + } + return result; +} +function normalizeOverrides(value) { + if (!value || typeof value !== 'object' || Array.isArray(value)) { + return { global: {}, sets: {} }; + } + const record = value; + const global = normalizeFeatureMap(record.global); + const sets = {}; + const rawSets = record.sets && typeof record.sets === 'object' && !Array.isArray(record.sets) + ? record.sets + : {}; + for (const [setName, setValue] of Object.entries(rawSets)) { + const normalized = normalizeFeatureMap(setValue); + if (Object.keys(normalized).length > 0) { + sets[setName] = normalized; + } + } + return { global, sets }; +} +function mergeOverrides(base, next) { + const sets = { ...base.sets }; + for (const [setName, overrides] of Object.entries(next.sets)) { + const existing = sets[setName]; + sets[setName] = existing ? { ...existing, ...overrides } : { ...overrides }; + } + return { + global: { ...base.global, ...next.global }, + sets, + }; +} +function toFeatureOverrides(overrides) { + const result = {}; + if (Object.keys(overrides.global).length > 0) { + result.global = overrides.global; + } + const setEntries = Object.entries(overrides.sets).filter(([, value]) => Object.keys(value).length > 0); + if (setEntries.length > 0) { + result.sets = Object.fromEntries(setEntries); + } + return result; +} +function resolveFeaturesCachePath() { + const override = process.env.BIRD_FEATURES_CACHE ?? process.env.BIRD_FEATURES_PATH; + if (override && override.trim().length > 0) { + return path.resolve(override.trim()); + } + return path.join(homedir(), '.config', 'bird', DEFAULT_CACHE_FILENAME); +} +function readOverridesFromFile(cachePath) { + if (!existsSync(cachePath)) { + return null; + } + try { + const raw = readFileSync(cachePath, 'utf8'); + return normalizeOverrides(JSON.parse(raw)); + } + catch { + return null; + } +} +function readOverridesFromEnv() { + const raw = process.env.BIRD_FEATURES_JSON; + if (!raw || raw.trim().length === 0) { + return null; + } + try { + return normalizeOverrides(JSON.parse(raw)); + } + catch { + return null; + } +} +function writeOverridesToDisk(cachePath, overrides) { + const payload = toFeatureOverrides(overrides); + return mkdir(path.dirname(cachePath), { recursive: true }).then(() => writeFile(cachePath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8')); +} +export function loadFeatureOverrides() { + if (cachedOverrides) { + return cachedOverrides; + } + const base = normalizeOverrides(defaultOverrides); + const fromFile = readOverridesFromFile(resolveFeaturesCachePath()); + const fromEnv = readOverridesFromEnv(); + let merged = base; + if (fromFile) { + merged = mergeOverrides(merged, fromFile); + } + if (fromEnv) { + merged = mergeOverrides(merged, fromEnv); + } + cachedOverrides = merged; + return merged; +} +export function getFeatureOverridesSnapshot() { + const overrides = toFeatureOverrides(loadFeatureOverrides()); + return { + cachePath: resolveFeaturesCachePath(), + overrides, + }; +} +export function applyFeatureOverrides(setName, base) { + const overrides = loadFeatureOverrides(); + const globalOverrides = overrides.global; + const setOverrides = overrides.sets[setName]; + if (Object.keys(globalOverrides).length === 0 && (!setOverrides || Object.keys(setOverrides).length === 0)) { + return base; + } + if (setOverrides) { + return { + ...base, + ...globalOverrides, + ...setOverrides, + }; + } + return { + ...base, + ...globalOverrides, + }; +} +export async function refreshFeatureOverridesCache() { + const cachePath = resolveFeaturesCachePath(); + const base = normalizeOverrides(defaultOverrides); + const fromFile = readOverridesFromFile(cachePath); + const merged = mergeOverrides(base, fromFile ?? { global: {}, sets: {} }); + await writeOverridesToDisk(cachePath, merged); + cachedOverrides = null; + return { cachePath, overrides: toFeatureOverrides(merged) }; +} +export function clearFeatureOverridesCache() { + cachedOverrides = null; +} +//# sourceMappingURL=runtime-features.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/runtime-query-ids.js b/scripts/lib/vendor/bird-search/lib/runtime-query-ids.js new file mode 100644 index 0000000..c09fe62 --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/runtime-query-ids.js @@ -0,0 +1,264 @@ +import { mkdir, readFile, writeFile } from 'node:fs/promises'; +import { homedir } from 'node:os'; +import path from 'node:path'; +const DEFAULT_CACHE_FILENAME = 'query-ids-cache.json'; +const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000; +const DISCOVERY_PAGES = [ + 'https://x.com/?lang=en', + 'https://x.com/explore', + 'https://x.com/notifications', + 'https://x.com/settings/profile', +]; +const BUNDLE_URL_REGEX = /https:\/\/abs\.twimg\.com\/responsive-web\/client-web(?:-legacy)?\/[A-Za-z0-9.-]+\.js/g; +const QUERY_ID_REGEX = /^[a-zA-Z0-9_-]+$/; +const OPERATION_PATTERNS = [ + { + regex: /e\.exports=\{queryId\s*:\s*["']([^"']+)["']\s*,\s*operationName\s*:\s*["']([^"']+)["']/gs, + operationGroup: 2, + queryIdGroup: 1, + }, + { + regex: /e\.exports=\{operationName\s*:\s*["']([^"']+)["']\s*,\s*queryId\s*:\s*["']([^"']+)["']/gs, + operationGroup: 1, + queryIdGroup: 2, + }, + { + regex: /operationName\s*[:=]\s*["']([^"']+)["'](.{0,4000}?)queryId\s*[:=]\s*["']([^"']+)["']/gs, + operationGroup: 1, + queryIdGroup: 3, + }, + { + regex: /queryId\s*[:=]\s*["']([^"']+)["'](.{0,4000}?)operationName\s*[:=]\s*["']([^"']+)["']/gs, + operationGroup: 3, + queryIdGroup: 1, + }, +]; +const HEADERS = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36', + Accept: 'text/html,application/json;q=0.9,*/*;q=0.8', + 'Accept-Language': 'en-US,en;q=0.9', +}; +async function fetchText(fetchImpl, url) { + const response = await fetchImpl(url, { headers: HEADERS }); + if (!response.ok) { + const body = await response.text().catch(() => ''); + throw new Error(`HTTP ${response.status} for ${url}: ${body.slice(0, 120)}`); + } + return response.text(); +} +function resolveDefaultCachePath() { + const override = process.env.BIRD_QUERY_IDS_CACHE; + if (override && override.trim().length > 0) { + return path.resolve(override.trim()); + } + return path.join(homedir(), '.config', 'bird', DEFAULT_CACHE_FILENAME); +} +function parseSnapshot(raw) { + if (!raw || typeof raw !== 'object') { + return null; + } + const record = raw; + const fetchedAt = typeof record.fetchedAt === 'string' ? record.fetchedAt : null; + const ttlMs = typeof record.ttlMs === 'number' && Number.isFinite(record.ttlMs) ? record.ttlMs : null; + const ids = record.ids && typeof record.ids === 'object' ? record.ids : null; + const discovery = record.discovery && typeof record.discovery === 'object' ? record.discovery : null; + if (!fetchedAt || !ttlMs || !ids || !discovery) { + return null; + } + const pages = Array.isArray(discovery.pages) ? discovery.pages : null; + const bundles = Array.isArray(discovery.bundles) ? discovery.bundles : null; + if (!pages || !bundles) { + return null; + } + const normalizedIds = {}; + for (const [key, value] of Object.entries(ids)) { + if (typeof value === 'string' && value.trim().length > 0) { + normalizedIds[key] = value.trim(); + } + } + return { + fetchedAt, + ttlMs, + ids: normalizedIds, + discovery: { + pages: pages.filter((p) => typeof p === 'string'), + bundles: bundles.filter((b) => typeof b === 'string'), + }, + }; +} +async function readSnapshotFromDisk(cachePath) { + try { + const raw = await readFile(cachePath, 'utf8'); + return parseSnapshot(JSON.parse(raw)); + } + catch { + return null; + } +} +async function writeSnapshotToDisk(cachePath, snapshot) { + await mkdir(path.dirname(cachePath), { recursive: true }); + await writeFile(cachePath, `${JSON.stringify(snapshot, null, 2)}\n`, 'utf8'); +} +async function discoverBundles(fetchImpl) { + const bundles = new Set(); + for (const page of DISCOVERY_PAGES) { + try { + const html = await fetchText(fetchImpl, page); + for (const match of html.matchAll(BUNDLE_URL_REGEX)) { + bundles.add(match[0]); + } + } + catch { + // ignore discovery page failures; other pages often work + } + } + const discovered = [...bundles]; + if (discovered.length === 0) { + throw new Error('No client bundles discovered; x.com layout may have changed.'); + } + return discovered; +} +function extractOperations(bundleContents, bundleLabel, targets, discovered) { + for (const pattern of OPERATION_PATTERNS) { + pattern.regex.lastIndex = 0; + while (true) { + const match = pattern.regex.exec(bundleContents); + if (match === null) { + break; + } + const operationName = match[pattern.operationGroup]; + const queryId = match[pattern.queryIdGroup]; + if (!operationName || !queryId) { + continue; + } + if (!targets.has(operationName)) { + continue; + } + if (!QUERY_ID_REGEX.test(queryId)) { + continue; + } + if (discovered.has(operationName)) { + continue; + } + discovered.set(operationName, { queryId, bundle: bundleLabel }); + if (discovered.size === targets.size) { + return; + } + } + } +} +async function fetchAndExtract(fetchImpl, bundleUrls, targets) { + const discovered = new Map(); + const CONCURRENCY = 6; + for (let i = 0; i < bundleUrls.length; i += CONCURRENCY) { + const chunk = bundleUrls.slice(i, i + CONCURRENCY); + await Promise.all(chunk.map(async (url) => { + if (discovered.size === targets.size) { + return; + } + const label = url.split('/').at(-1) ?? url; + try { + const js = await fetchText(fetchImpl, url); + extractOperations(js, label, targets, discovered); + } + catch { + // ignore failed bundles + } + })); + if (discovered.size === targets.size) { + break; + } + } + return discovered; +} +export function createRuntimeQueryIdStore(options = {}) { + const fetchImpl = options.fetchImpl ?? fetch; + const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS; + const cachePath = options.cachePath ? path.resolve(options.cachePath) : resolveDefaultCachePath(); + let memorySnapshot = null; + let loadOnce = null; + let refreshInFlight = null; + const loadSnapshot = async () => { + if (memorySnapshot) { + return memorySnapshot; + } + if (!loadOnce) { + loadOnce = (async () => { + const fromDisk = await readSnapshotFromDisk(cachePath); + memorySnapshot = fromDisk; + return fromDisk; + })(); + } + return loadOnce; + }; + const getSnapshotInfo = async () => { + const snapshot = await loadSnapshot(); + if (!snapshot) { + return null; + } + const fetchedAtMs = new Date(snapshot.fetchedAt).getTime(); + const ageMs = Number.isFinite(fetchedAtMs) ? Math.max(0, Date.now() - fetchedAtMs) : Number.POSITIVE_INFINITY; + const effectiveTtl = Number.isFinite(snapshot.ttlMs) ? snapshot.ttlMs : ttlMs; + const isFresh = ageMs <= effectiveTtl; + return { snapshot, cachePath, ageMs, isFresh }; + }; + const getQueryId = async (operationName) => { + const info = await getSnapshotInfo(); + if (!info) { + return null; + } + return info.snapshot.ids[operationName] ?? null; + }; + const refresh = async (operationNames, opts = {}) => { + if (refreshInFlight) { + return refreshInFlight; + } + refreshInFlight = (async () => { + const current = await getSnapshotInfo(); + if (!opts.force && current?.isFresh) { + return current; + } + const targets = new Set(operationNames); + const bundleUrls = await discoverBundles(fetchImpl); + const discovered = await fetchAndExtract(fetchImpl, bundleUrls, targets); + if (discovered.size === 0) { + return current ?? null; + } + const ids = {}; + for (const name of operationNames) { + const entry = discovered.get(name); + if (entry?.queryId) { + ids[name] = entry.queryId; + } + } + const snapshot = { + fetchedAt: new Date().toISOString(), + ttlMs, + ids, + discovery: { + pages: [...DISCOVERY_PAGES], + bundles: bundleUrls.map((url) => url.split('/').at(-1) ?? url), + }, + }; + await writeSnapshotToDisk(cachePath, snapshot); + memorySnapshot = snapshot; + return getSnapshotInfo(); + })().finally(() => { + refreshInFlight = null; + }); + return refreshInFlight; + }; + return { + cachePath, + ttlMs, + getSnapshotInfo, + getQueryId, + refresh, + clearMemory() { + memorySnapshot = null; + loadOnce = null; + }, + }; +} +export const runtimeQueryIds = createRuntimeQueryIdStore(); +//# sourceMappingURL=runtime-query-ids.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/twitter-client-base.js b/scripts/lib/vendor/bird-search/lib/twitter-client-base.js new file mode 100644 index 0000000..8b7e969 --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/twitter-client-base.js @@ -0,0 +1,129 @@ +import { randomBytes, randomUUID } from 'node:crypto'; +import { runtimeQueryIds } from './runtime-query-ids.js'; +import { QUERY_IDS, TARGET_QUERY_ID_OPERATIONS } from './twitter-client-constants.js'; +import { normalizeQuoteDepth } from './twitter-client-utils.js'; +export class TwitterClientBase { + authToken; + ct0; + cookieHeader; + userAgent; + timeoutMs; + quoteDepth; + clientUuid; + clientDeviceId; + clientUserId; + constructor(options) { + if (!options.cookies.authToken || !options.cookies.ct0) { + throw new Error('Both authToken and ct0 cookies are required'); + } + this.authToken = options.cookies.authToken; + this.ct0 = options.cookies.ct0; + this.cookieHeader = options.cookies.cookieHeader || `auth_token=${this.authToken}; ct0=${this.ct0}`; + this.userAgent = + options.userAgent || + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'; + this.timeoutMs = options.timeoutMs; + this.quoteDepth = normalizeQuoteDepth(options.quoteDepth); + this.clientUuid = randomUUID(); + this.clientDeviceId = randomUUID(); + } + async sleep(ms) { + await new Promise((resolve) => setTimeout(resolve, ms)); + } + async getQueryId(operationName) { + const cached = await runtimeQueryIds.getQueryId(operationName); + return cached ?? QUERY_IDS[operationName]; + } + async refreshQueryIds() { + if (process.env.NODE_ENV === 'test') { + return; + } + try { + await runtimeQueryIds.refresh(TARGET_QUERY_ID_OPERATIONS, { force: true }); + } + catch { + // ignore refresh failures; callers will fall back to baked-in IDs + } + } + async withRefreshedQueryIdsOn404(attempt) { + const firstAttempt = await attempt(); + if (firstAttempt.success || !firstAttempt.had404) { + return { result: firstAttempt, refreshed: false }; + } + await this.refreshQueryIds(); + const secondAttempt = await attempt(); + return { result: secondAttempt, refreshed: true }; + } + async getTweetDetailQueryIds() { + const primary = await this.getQueryId('TweetDetail'); + return Array.from(new Set([primary, '97JF30KziU00483E_8elBA', 'aFvUsJm2c-oDkJV75blV6g'])); + } + async getSearchTimelineQueryIds() { + const primary = await this.getQueryId('SearchTimeline'); + return Array.from(new Set([primary, 'M1jEez78PEfVfbQLvlWMvQ', '5h0kNbk3ii97rmfY6CdgAA', 'Tp1sewRU1AsZpBWhqCZicQ'])); + } + async fetchWithTimeout(url, init) { + if (!this.timeoutMs || this.timeoutMs <= 0) { + return fetch(url, init); + } + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs); + try { + return await fetch(url, { ...init, signal: controller.signal }); + } + finally { + clearTimeout(timeoutId); + } + } + getHeaders() { + return this.getJsonHeaders(); + } + createTransactionId() { + return randomBytes(16).toString('hex'); + } + getBaseHeaders() { + const headers = { + accept: '*/*', + 'accept-language': 'en-US,en;q=0.9', + authorization: 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA', + 'x-csrf-token': this.ct0, + 'x-twitter-auth-type': 'OAuth2Session', + 'x-twitter-active-user': 'yes', + 'x-twitter-client-language': 'en', + 'x-client-uuid': this.clientUuid, + 'x-twitter-client-deviceid': this.clientDeviceId, + 'x-client-transaction-id': this.createTransactionId(), + cookie: this.cookieHeader, + 'user-agent': this.userAgent, + origin: 'https://x.com', + referer: 'https://x.com/', + }; + if (this.clientUserId) { + headers['x-twitter-client-user-id'] = this.clientUserId; + } + return headers; + } + getJsonHeaders() { + return { + ...this.getBaseHeaders(), + 'content-type': 'application/json', + }; + } + getUploadHeaders() { + // Note: do not set content-type; URLSearchParams/FormData need to set it (incl boundary) themselves. + return this.getBaseHeaders(); + } + async ensureClientUserId() { + if (process.env.NODE_ENV === 'test') { + return; + } + if (this.clientUserId) { + return; + } + const result = await this.getCurrentUser(); + if (result.success && result.user?.id) { + this.clientUserId = result.user.id; + } + } +} +//# sourceMappingURL=twitter-client-base.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/twitter-client-constants.js b/scripts/lib/vendor/bird-search/lib/twitter-client-constants.js new file mode 100644 index 0000000..a9fcde3 --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/twitter-client-constants.js @@ -0,0 +1,50 @@ +// biome-ignore lint/correctness/useImportExtensions: JSON module import doesn't use .js extension. +import queryIds from './query-ids.json' with { type: 'json' }; +export const TWITTER_API_BASE = 'https://x.com/i/api/graphql'; +export const TWITTER_GRAPHQL_POST_URL = 'https://x.com/i/api/graphql'; +export const TWITTER_UPLOAD_URL = 'https://upload.twitter.com/i/media/upload.json'; +export const TWITTER_MEDIA_METADATA_URL = 'https://x.com/i/api/1.1/media/metadata/create.json'; +export const TWITTER_STATUS_UPDATE_URL = 'https://x.com/i/api/1.1/statuses/update.json'; +export const SETTINGS_SCREEN_NAME_REGEX = /"screen_name":"([^"]+)"/; +export const SETTINGS_USER_ID_REGEX = /"user_id"\s*:\s*"(\d+)"/; +export const SETTINGS_NAME_REGEX = /"name":"([^"\\]*(?:\\.[^"\\]*)*)"/; +// Query IDs rotate frequently; the values in query-ids.json are refreshed by +// scripts/update-query-ids.ts. The fallback values keep the client usable if +// the file is missing or incomplete. +export const FALLBACK_QUERY_IDS = { + CreateTweet: 'TAJw1rBsjAtdNgTdlo2oeg', + CreateRetweet: 'ojPdsZsimiJrUGLR1sjUtA', + DeleteRetweet: 'iQtK4dl5hBmXewYZuEOKVw', + CreateFriendship: '8h9JVdV8dlSyqyRDJEPCsA', + DestroyFriendship: 'ppXWuagMNXgvzx6WoXBW0Q', + FavoriteTweet: 'lI07N6Otwv1PhnEgXILM7A', + UnfavoriteTweet: 'ZYKSe-w7KEslx3JhSIk5LA', + CreateBookmark: 'aoDbu3RHznuiSkQ9aNM67Q', + DeleteBookmark: 'Wlmlj2-xzyS1GN3a6cj-mQ', + TweetDetail: '97JF30KziU00483E_8elBA', + SearchTimeline: 'M1jEez78PEfVfbQLvlWMvQ', + UserArticlesTweets: '8zBy9h4L90aDL02RsBcCFg', + UserTweets: 'Wms1GvIiHXAPBaCr9KblaA', + Bookmarks: 'RV1g3b8n_SGOHwkqKYSCFw', + Following: 'BEkNpEt5pNETESoqMsTEGA', + Followers: 'kuFUYP9eV1FPoEy4N-pi7w', + Likes: 'JR2gceKucIKcVNB_9JkhsA', + BookmarkFolderTimeline: 'KJIQpsvxrTfRIlbaRIySHQ', + ListOwnerships: 'wQcOSjSQ8NtgxIwvYl1lMg', + ListMemberships: 'BlEXXdARdSeL_0KyKHHvvg', + ListLatestTweetsTimeline: '2TemLyqrMpTeAmysdbnVqw', + ListByRestId: 'wXzyA5vM_aVkBL9G8Vp3kw', + HomeTimeline: 'edseUwk9sP5Phz__9TIRnA', + HomeLatestTimeline: 'iOEZpOdfekFsxSlPQCQtPg', + ExploreSidebar: 'lpSN4M6qpimkF4nRFPE3nQ', + ExplorePage: 'kheAINB_4pzRDqkzG3K-ng', + GenericTimelineById: 'uGSr7alSjR9v6QJAIaqSKQ', + TrendHistory: 'Sj4T-jSB9pr0Mxtsc1UKZQ', + AboutAccountQuery: 'zs_jFPFT78rBpXv9Z3U2YQ', +}; +export const QUERY_IDS = { + ...FALLBACK_QUERY_IDS, + ...queryIds, +}; +export const TARGET_QUERY_ID_OPERATIONS = Object.keys(FALLBACK_QUERY_IDS); +//# sourceMappingURL=twitter-client-constants.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/twitter-client-features.js b/scripts/lib/vendor/bird-search/lib/twitter-client-features.js new file mode 100644 index 0000000..6083861 --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/twitter-client-features.js @@ -0,0 +1,347 @@ +import { applyFeatureOverrides } from './runtime-features.js'; +export function buildArticleFeatures() { + return applyFeatureOverrides('article', { + rweb_video_screen_enabled: true, + profile_label_improvements_pcf_label_in_post_enabled: true, + responsive_web_profile_redirect_enabled: true, + rweb_tipjar_consumption_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + premium_content_api_read_enabled: false, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: false, + responsive_web_grok_analyze_post_followups_enabled: false, + responsive_web_grok_annotations_enabled: false, + responsive_web_jetfuel_frame: true, + post_ctas_fetch_enabled: true, + responsive_web_grok_share_attachment_enabled: true, + articles_preview_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + responsive_web_grok_show_grok_translated_post: false, + responsive_web_grok_analysis_button_from_backend: true, + creator_subscriptions_quote_tweet_preview_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_grok_image_annotation_enabled: true, + responsive_web_grok_imagine_annotation_enabled: true, + responsive_web_grok_community_note_auto_translation_is_enabled: false, + responsive_web_enhance_cards_enabled: false, + }); +} +export function buildTweetDetailFeatures() { + return applyFeatureOverrides('tweetDetail', { + ...buildArticleFeatures(), + responsive_web_graphql_exclude_directive_enabled: true, + communities_web_enable_tweet_community_results_fetch: true, + responsive_web_twitter_article_plain_text_enabled: true, + responsive_web_twitter_article_seed_tweet_detail_enabled: true, + responsive_web_twitter_article_seed_tweet_summary_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + tweet_awards_web_tipping_enabled: false, + creator_subscriptions_quote_tweet_preview_enabled: false, + verified_phone_label_enabled: false, + }); +} +export function buildArticleFieldToggles() { + return { + withPayments: false, + withAuxiliaryUserLabels: false, + withArticleRichContentState: true, + withArticlePlainText: true, + withGrokAnalyze: false, + withDisallowedReplyControls: false, + }; +} +export function buildSearchFeatures() { + return applyFeatureOverrides('search', { + rweb_video_screen_enabled: true, + profile_label_improvements_pcf_label_in_post_enabled: true, + responsive_web_profile_redirect_enabled: true, + rweb_tipjar_consumption_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + premium_content_api_read_enabled: false, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: false, + responsive_web_grok_analyze_post_followups_enabled: false, + responsive_web_grok_annotations_enabled: false, + responsive_web_jetfuel_frame: true, + post_ctas_fetch_enabled: true, + responsive_web_grok_share_attachment_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + responsive_web_grok_show_grok_translated_post: false, + responsive_web_grok_analysis_button_from_backend: true, + creator_subscriptions_quote_tweet_preview_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_grok_image_annotation_enabled: true, + responsive_web_grok_imagine_annotation_enabled: true, + responsive_web_grok_community_note_auto_translation_is_enabled: false, + articles_preview_enabled: true, + responsive_web_enhance_cards_enabled: false, + }); +} +export function buildTweetCreateFeatures() { + return applyFeatureOverrides('tweetCreate', { + rweb_video_screen_enabled: true, + creator_subscriptions_tweet_preview_api_enabled: true, + premium_content_api_read_enabled: false, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: false, + responsive_web_grok_analyze_post_followups_enabled: false, + responsive_web_grok_annotations_enabled: false, + responsive_web_jetfuel_frame: true, + post_ctas_fetch_enabled: true, + responsive_web_grok_share_attachment_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + responsive_web_grok_show_grok_translated_post: false, + responsive_web_grok_analysis_button_from_backend: true, + creator_subscriptions_quote_tweet_preview_enabled: false, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + profile_label_improvements_pcf_label_in_post_enabled: true, + responsive_web_profile_redirect_enabled: false, + rweb_tipjar_consumption_enabled: true, + verified_phone_label_enabled: false, + articles_preview_enabled: true, + responsive_web_grok_community_note_auto_translation_is_enabled: false, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + responsive_web_grok_image_annotation_enabled: true, + responsive_web_grok_imagine_annotation_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_enhance_cards_enabled: false, + }); +} +export function buildTimelineFeatures() { + return applyFeatureOverrides('timeline', { + ...buildSearchFeatures(), + blue_business_profile_image_shape_enabled: true, + responsive_web_text_conversations_enabled: false, + tweetypie_unmention_optimization_enabled: true, + vibe_api_enabled: true, + responsive_web_twitter_blue_verified_badge_is_enabled: true, + interactive_text_enabled: true, + longform_notetweets_richtext_consumption_enabled: true, + responsive_web_media_download_video_enabled: false, + }); +} +export function buildBookmarksFeatures() { + return applyFeatureOverrides('bookmarks', { + ...buildTimelineFeatures(), + graphql_timeline_v2_bookmark_timeline: true, + }); +} +export function buildLikesFeatures() { + return applyFeatureOverrides('likes', buildTimelineFeatures()); +} +export function buildListsFeatures() { + return applyFeatureOverrides('lists', { + rweb_video_screen_enabled: true, + profile_label_improvements_pcf_label_in_post_enabled: true, + responsive_web_profile_redirect_enabled: true, + rweb_tipjar_consumption_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + premium_content_api_read_enabled: false, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: false, + responsive_web_grok_analyze_post_followups_enabled: false, + responsive_web_grok_annotations_enabled: false, + responsive_web_jetfuel_frame: true, + post_ctas_fetch_enabled: true, + responsive_web_grok_share_attachment_enabled: true, + articles_preview_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + responsive_web_grok_show_grok_translated_post: false, + responsive_web_grok_analysis_button_from_backend: true, + creator_subscriptions_quote_tweet_preview_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_grok_image_annotation_enabled: true, + responsive_web_grok_imagine_annotation_enabled: true, + responsive_web_grok_community_note_auto_translation_is_enabled: false, + responsive_web_enhance_cards_enabled: false, + blue_business_profile_image_shape_enabled: false, + responsive_web_text_conversations_enabled: false, + tweetypie_unmention_optimization_enabled: true, + vibe_api_enabled: false, + interactive_text_enabled: false, + }); +} +export function buildHomeTimelineFeatures() { + return applyFeatureOverrides('homeTimeline', { + ...buildTimelineFeatures(), + }); +} +export function buildUserTweetsFeatures() { + return applyFeatureOverrides('userTweets', { + rweb_video_screen_enabled: false, + profile_label_improvements_pcf_label_in_post_enabled: true, + responsive_web_profile_redirect_enabled: false, + rweb_tipjar_consumption_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + premium_content_api_read_enabled: false, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: false, + responsive_web_grok_analyze_post_followups_enabled: true, + responsive_web_jetfuel_frame: true, + post_ctas_fetch_enabled: true, + responsive_web_grok_share_attachment_enabled: true, + responsive_web_grok_annotations_enabled: false, + articles_preview_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + responsive_web_grok_show_grok_translated_post: true, + responsive_web_grok_analysis_button_from_backend: true, + creator_subscriptions_quote_tweet_preview_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_grok_image_annotation_enabled: true, + responsive_web_grok_imagine_annotation_enabled: true, + responsive_web_grok_community_note_auto_translation_is_enabled: false, + responsive_web_enhance_cards_enabled: false, + }); +} +export function buildFollowingFeatures() { + return applyFeatureOverrides('following', { + rweb_video_screen_enabled: true, + profile_label_improvements_pcf_label_in_post_enabled: false, + responsive_web_profile_redirect_enabled: true, + rweb_tipjar_consumption_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + premium_content_api_read_enabled: true, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: false, + responsive_web_grok_analyze_post_followups_enabled: false, + responsive_web_grok_annotations_enabled: false, + responsive_web_jetfuel_frame: false, + post_ctas_fetch_enabled: true, + responsive_web_grok_share_attachment_enabled: false, + articles_preview_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: true, + responsive_web_grok_show_grok_translated_post: false, + responsive_web_grok_analysis_button_from_backend: false, + creator_subscriptions_quote_tweet_preview_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_grok_image_annotation_enabled: false, + responsive_web_grok_imagine_annotation_enabled: false, + responsive_web_grok_community_note_auto_translation_is_enabled: false, + responsive_web_enhance_cards_enabled: false, + }); +} +export function buildExploreFeatures() { + return applyFeatureOverrides('explore', { + rweb_video_screen_enabled: true, + profile_label_improvements_pcf_label_in_post_enabled: true, + responsive_web_profile_redirect_enabled: true, + rweb_tipjar_consumption_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, + premium_content_api_read_enabled: false, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: true, + responsive_web_grok_analyze_post_followups_enabled: true, + responsive_web_grok_annotations_enabled: true, + responsive_web_jetfuel_frame: true, + responsive_web_grok_share_attachment_enabled: true, + articles_preview_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + responsive_web_grok_show_grok_translated_post: true, + responsive_web_grok_analysis_button_from_backend: true, + creator_subscriptions_quote_tweet_preview_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_grok_image_annotation_enabled: true, + responsive_web_grok_imagine_annotation_enabled: true, + responsive_web_grok_community_note_auto_translation_is_enabled: true, + responsive_web_enhance_cards_enabled: false, + // Additional features required for ExploreSidebar + post_ctas_fetch_enabled: true, + rweb_video_timestamps_enabled: true, + }); +} +//# sourceMappingURL=twitter-client-features.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/twitter-client-search.js b/scripts/lib/vendor/bird-search/lib/twitter-client-search.js new file mode 100644 index 0000000..64d1fdb --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/twitter-client-search.js @@ -0,0 +1,157 @@ +import { TWITTER_API_BASE } from './twitter-client-constants.js'; +import { buildSearchFeatures } from './twitter-client-features.js'; +import { extractCursorFromInstructions, parseTweetsFromInstructions } from './twitter-client-utils.js'; +const RAW_QUERY_MISSING_REGEX = /must be defined/i; +function isQueryIdMismatch(payload) { + try { + const parsed = JSON.parse(payload); + return (parsed.errors?.some((error) => { + if (error?.extensions?.code === 'GRAPHQL_VALIDATION_FAILED') { + return true; + } + if (error?.path?.includes('rawQuery') && RAW_QUERY_MISSING_REGEX.test(error.message ?? '')) { + return true; + } + return false; + }) ?? false); + } + catch { + return false; + } +} +export function withSearch(Base) { + class TwitterClientSearch extends Base { + // biome-ignore lint/complexity/noUselessConstructor lint/suspicious/noExplicitAny: TS mixin constructor requirement. + constructor(...args) { + super(...args); + } + /** + * Search for tweets matching a query + */ + async search(query, count = 20, options = {}) { + return this.searchPaged(query, count, options); + } + /** + * Get all search results (paged) + */ + async getAllSearchResults(query, options) { + return this.searchPaged(query, Number.POSITIVE_INFINITY, options); + } + async searchPaged(query, limit, options = {}) { + const features = buildSearchFeatures(); + const pageSize = 20; + const seen = new Set(); + const tweets = []; + let cursor = options.cursor; + let nextCursor; + let pagesFetched = 0; + const { includeRaw = false, maxPages } = options; + const fetchPage = async (pageCount, pageCursor) => { + let lastError; + let had404 = false; + const queryIds = await this.getSearchTimelineQueryIds(); + for (const queryId of queryIds) { + const variables = { + rawQuery: query, + count: pageCount, + querySource: 'typed_query', + product: 'Latest', + ...(pageCursor ? { cursor: pageCursor } : {}), + }; + const params = new URLSearchParams({ + variables: JSON.stringify(variables), + }); + const url = `${TWITTER_API_BASE}/${queryId}/SearchTimeline?${params.toString()}`; + try { + const response = await this.fetchWithTimeout(url, { + method: 'POST', + headers: this.getHeaders(), + body: JSON.stringify({ features, queryId }), + }); + if (response.status === 404) { + had404 = true; + lastError = `HTTP ${response.status}`; + continue; + } + if (!response.ok) { + const text = await response.text(); + const shouldRefreshQueryIds = (response.status === 400 || response.status === 422) && isQueryIdMismatch(text); + return { + success: false, + error: `HTTP ${response.status}: ${text.slice(0, 200)}`, + had404: had404 || shouldRefreshQueryIds, + }; + } + const data = (await response.json()); + if (data.errors && data.errors.length > 0) { + const shouldRefreshQueryIds = data.errors.some((error) => error?.extensions?.code === 'GRAPHQL_VALIDATION_FAILED'); + return { + success: false, + error: data.errors.map((e) => e.message).join(', '), + had404: had404 || shouldRefreshQueryIds, + }; + } + const instructions = data.data?.search_by_raw_query?.search_timeline?.timeline?.instructions; + const pageTweets = parseTweetsFromInstructions(instructions, { quoteDepth: this.quoteDepth, includeRaw }); + const nextCursor = extractCursorFromInstructions(instructions); + return { success: true, tweets: pageTweets, cursor: nextCursor, had404 }; + } + catch (error) { + lastError = error instanceof Error ? error.message : String(error); + } + } + return { success: false, error: lastError ?? 'Unknown error fetching search results', had404 }; + }; + const fetchWithRefresh = async (pageCount, pageCursor) => { + const firstAttempt = await fetchPage(pageCount, pageCursor); + if (firstAttempt.success) { + return firstAttempt; + } + if (firstAttempt.had404) { + await this.refreshQueryIds(); + const secondAttempt = await fetchPage(pageCount, pageCursor); + if (secondAttempt.success) { + return secondAttempt; + } + return { success: false, error: secondAttempt.error }; + } + return { success: false, error: firstAttempt.error }; + }; + const unlimited = limit === Number.POSITIVE_INFINITY; + while (unlimited || tweets.length < limit) { + const pageCount = unlimited ? pageSize : Math.min(pageSize, limit - tweets.length); + const page = await fetchWithRefresh(pageCount, cursor); + if (!page.success) { + return { success: false, error: page.error }; + } + pagesFetched += 1; + let added = 0; + for (const tweet of page.tweets) { + if (seen.has(tweet.id)) { + continue; + } + seen.add(tweet.id); + tweets.push(tweet); + added += 1; + if (!unlimited && tweets.length >= limit) { + break; + } + } + const pageCursor = page.cursor; + if (!pageCursor || pageCursor === cursor || page.tweets.length === 0 || added === 0) { + nextCursor = undefined; + break; + } + if (maxPages && pagesFetched >= maxPages) { + nextCursor = pageCursor; + break; + } + cursor = pageCursor; + nextCursor = pageCursor; + } + return { success: true, tweets, nextCursor }; + } + } + return TwitterClientSearch; +} +//# sourceMappingURL=twitter-client-search.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/twitter-client-types.js b/scripts/lib/vendor/bird-search/lib/twitter-client-types.js new file mode 100644 index 0000000..3277c71 --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/twitter-client-types.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=twitter-client-types.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/lib/twitter-client-utils.js b/scripts/lib/vendor/bird-search/lib/twitter-client-utils.js new file mode 100644 index 0000000..b6e869d --- /dev/null +++ b/scripts/lib/vendor/bird-search/lib/twitter-client-utils.js @@ -0,0 +1,511 @@ +export function normalizeQuoteDepth(value) { + if (value === undefined || value === null) { + return 1; + } + if (!Number.isFinite(value)) { + return 1; + } + return Math.max(0, Math.floor(value)); +} +export function firstText(...values) { + for (const value of values) { + if (typeof value === 'string') { + const trimmed = value.trim(); + if (trimmed) { + return trimmed; + } + } + } + return undefined; +} +export function collectTextFields(value, keys, output) { + if (!value) { + return; + } + if (typeof value === 'string') { + return; + } + if (Array.isArray(value)) { + for (const item of value) { + collectTextFields(item, keys, output); + } + return; + } + if (typeof value === 'object') { + for (const [key, nested] of Object.entries(value)) { + if (keys.has(key)) { + if (typeof nested === 'string') { + const trimmed = nested.trim(); + if (trimmed) { + output.push(trimmed); + } + continue; + } + } + collectTextFields(nested, keys, output); + } + } +} +export function uniqueOrdered(values) { + const seen = new Set(); + const result = []; + for (const value of values) { + if (seen.has(value)) { + continue; + } + seen.add(value); + result.push(value); + } + return result; +} +/** + * Renders a Draft.js content_state into readable markdown/text format. + * Handles blocks (paragraphs, headers, lists) and entities (code blocks, links, tweets, dividers). + */ +export function renderContentState(contentState) { + if (!contentState?.blocks || contentState.blocks.length === 0) { + return undefined; + } + // Build entity lookup map from array/object formats + const entityMap = new Map(); + const rawEntityMap = contentState.entityMap ?? []; + if (Array.isArray(rawEntityMap)) { + for (const entry of rawEntityMap) { + const key = Number.parseInt(entry.key, 10); + if (!Number.isNaN(key)) { + entityMap.set(key, entry.value); + } + } + } + else { + for (const [key, value] of Object.entries(rawEntityMap)) { + const keyNumber = Number.parseInt(key, 10); + if (!Number.isNaN(keyNumber)) { + entityMap.set(keyNumber, value); + } + } + } + const outputLines = []; + let orderedListCounter = 0; + let previousBlockType; + for (const block of contentState.blocks) { + // Reset ordered list counter when leaving ordered list context + if (block.type !== 'ordered-list-item' && previousBlockType === 'ordered-list-item') { + orderedListCounter = 0; + } + switch (block.type) { + case 'unstyled': { + // Plain paragraph - just output text with any inline formatting + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(text); + } + break; + } + case 'header-one': { + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(`# ${text}`); + } + break; + } + case 'header-two': { + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(`## ${text}`); + } + break; + } + case 'header-three': { + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(`### ${text}`); + } + break; + } + case 'unordered-list-item': { + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(`- ${text}`); + } + break; + } + case 'ordered-list-item': { + orderedListCounter++; + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(`${orderedListCounter}. ${text}`); + } + break; + } + case 'blockquote': { + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(`> ${text}`); + } + break; + } + case 'atomic': { + // Atomic blocks are placeholders for embedded entities + const entityContent = renderAtomicBlock(block, entityMap); + if (entityContent) { + outputLines.push(entityContent); + } + break; + } + default: { + // Fallback: just output the text + const text = renderBlockText(block, entityMap); + if (text) { + outputLines.push(text); + } + } + } + previousBlockType = block.type; + } + const result = outputLines.join('\n\n'); + return result.trim() || undefined; +} +/** + * Renders text content of a block, applying inline link entities. + */ +function renderBlockText(block, entityMap) { + let text = block.text; + // Handle LINK entities by appending URL in markdown format + // Process in reverse order to not mess up offsets + const linkRanges = (block.entityRanges ?? []) + .filter((range) => { + const entity = entityMap.get(range.key); + return entity?.type === 'LINK' && entity.data.url; + }) + .sort((a, b) => b.offset - a.offset); + for (const range of linkRanges) { + const entity = entityMap.get(range.key); + if (entity?.data.url) { + const linkText = text.slice(range.offset, range.offset + range.length); + const markdownLink = `[${linkText}](${entity.data.url})`; + text = text.slice(0, range.offset) + markdownLink + text.slice(range.offset + range.length); + } + } + return text.trim(); +} +/** + * Renders an atomic block by looking up its entity and returning appropriate content. + */ +function renderAtomicBlock(block, entityMap) { + const entityRanges = block.entityRanges ?? []; + if (entityRanges.length === 0) { + return undefined; + } + const entityKey = entityRanges[0].key; + const entity = entityMap.get(entityKey); + if (!entity) { + return undefined; + } + switch (entity.type) { + case 'MARKDOWN': + // Code blocks and other markdown content - output as-is + return entity.data.markdown?.trim(); + case 'DIVIDER': + return '---'; + case 'TWEET': + if (entity.data.tweetId) { + return `[Embedded Tweet: https://x.com/i/status/${entity.data.tweetId}]`; + } + return undefined; + case 'LINK': + if (entity.data.url) { + return `[Link: ${entity.data.url}]`; + } + return undefined; + case 'IMAGE': + // Images in atomic blocks - could extract URL if available + return '[Image]'; + default: + return undefined; + } +} +export function extractArticleText(result) { + const article = result?.article; + if (!article) { + return undefined; + } + const articleResult = article.article_results?.result ?? article; + if (process.env.BIRD_DEBUG_ARTICLE === '1') { + console.error('[bird][debug][article] payload:', JSON.stringify({ + rest_id: result?.rest_id, + article: articleResult, + note_tweet: result?.note_tweet?.note_tweet_results?.result ?? null, + }, null, 2)); + } + const title = firstText(articleResult.title, article.title); + // Try to render from rich content_state first (Draft.js format with blocks + entityMap) + // This preserves code blocks, embedded tweets, markdown, etc. + const contentState = article.article_results?.result?.content_state; + const richBody = renderContentState(contentState); + if (richBody) { + // Rich content found - prepend title if not already included + if (title) { + const normalizedTitle = title.trim(); + const trimmedBody = richBody.trimStart(); + const headingMatches = [`# ${normalizedTitle}`, `## ${normalizedTitle}`, `### ${normalizedTitle}`]; + const hasTitle = trimmedBody === normalizedTitle || + trimmedBody.startsWith(`${normalizedTitle}\n`) || + headingMatches.some((heading) => trimmedBody.startsWith(heading)); + if (!hasTitle) { + return `${title}\n\n${richBody}`; + } + } + return richBody; + } + // Fallback to plain text extraction for articles without rich content_state + let body = firstText(articleResult.plain_text, article.plain_text, articleResult.body?.text, articleResult.body?.richtext?.text, articleResult.body?.rich_text?.text, articleResult.content?.text, articleResult.content?.richtext?.text, articleResult.content?.rich_text?.text, articleResult.text, articleResult.richtext?.text, articleResult.rich_text?.text, article.body?.text, article.body?.richtext?.text, article.body?.rich_text?.text, article.content?.text, article.content?.richtext?.text, article.content?.rich_text?.text, article.text, article.richtext?.text, article.rich_text?.text); + if (body && title && body.trim() === title.trim()) { + body = undefined; + } + if (!body) { + const collected = []; + collectTextFields(articleResult, new Set(['text', 'title']), collected); + collectTextFields(article, new Set(['text', 'title']), collected); + const unique = uniqueOrdered(collected); + const filtered = title ? unique.filter((value) => value !== title) : unique; + if (filtered.length > 0) { + body = filtered.join('\n\n'); + } + } + if (title && body && !body.startsWith(title)) { + return `${title}\n\n${body}`; + } + return body ?? title; +} +export function extractNoteTweetText(result) { + const note = result?.note_tweet?.note_tweet_results?.result; + if (!note) { + return undefined; + } + return firstText(note.text, note.richtext?.text, note.rich_text?.text, note.content?.text, note.content?.richtext?.text, note.content?.rich_text?.text); +} +export function extractTweetText(result) { + return extractArticleText(result) ?? extractNoteTweetText(result) ?? firstText(result?.legacy?.full_text); +} +export function extractArticleMetadata(result) { + const article = result?.article; + if (!article) { + return undefined; + } + const articleResult = article.article_results?.result ?? article; + const title = firstText(articleResult.title, article.title); + if (!title) { + return undefined; + } + // preview_text is available in home timeline responses + const previewText = firstText(articleResult.preview_text, article.preview_text); + return { title, previewText }; +} +export function extractMedia(result) { + // Prefer extended_entities (has video info), fall back to entities + const rawMedia = result?.legacy?.extended_entities?.media ?? result?.legacy?.entities?.media; + if (!rawMedia || rawMedia.length === 0) { + return undefined; + } + const media = []; + for (const item of rawMedia) { + if (!item.type || !item.media_url_https) { + continue; + } + const mediaItem = { + type: item.type, + url: item.media_url_https, + }; + // Get dimensions from largest available size + const sizes = item.sizes; + if (sizes?.large) { + mediaItem.width = sizes.large.w; + mediaItem.height = sizes.large.h; + } + else if (sizes?.medium) { + mediaItem.width = sizes.medium.w; + mediaItem.height = sizes.medium.h; + } + // For thumbnails/previews + if (sizes?.small) { + mediaItem.previewUrl = `${item.media_url_https}:small`; + } + // Extract video URL for video/animated_gif + if ((item.type === 'video' || item.type === 'animated_gif') && item.video_info?.variants) { + // Prefer highest bitrate MP4, fall back to first MP4 when bitrate is missing. + const mp4Variants = item.video_info.variants.filter((v) => v.content_type === 'video/mp4' && typeof v.url === 'string'); + const mp4WithBitrate = mp4Variants + .filter((v) => typeof v.bitrate === 'number') + .sort((a, b) => b.bitrate - a.bitrate); + const selectedVariant = mp4WithBitrate[0] ?? mp4Variants[0]; + if (selectedVariant) { + mediaItem.videoUrl = selectedVariant.url; + } + if (typeof item.video_info.duration_millis === 'number') { + mediaItem.durationMs = item.video_info.duration_millis; + } + } + media.push(mediaItem); + } + return media.length > 0 ? media : undefined; +} +export function unwrapTweetResult(result) { + if (!result) { + return undefined; + } + if (result.tweet) { + return result.tweet; + } + return result; +} +export function mapTweetResult(result, quoteDepthOrOptions) { + const options = typeof quoteDepthOrOptions === 'number' ? { quoteDepth: quoteDepthOrOptions } : quoteDepthOrOptions; + const { quoteDepth, includeRaw = false } = options; + const userResult = result?.core?.user_results?.result; + const userLegacy = userResult?.legacy; + const userCore = userResult?.core; + const username = userLegacy?.screen_name ?? userCore?.screen_name; + const name = userLegacy?.name ?? userCore?.name ?? username; + const userId = userResult?.rest_id; + if (!result?.rest_id || !username) { + return undefined; + } + const text = extractTweetText(result); + if (!text) { + return undefined; + } + let quotedTweet; + if (quoteDepth > 0) { + const quotedResult = unwrapTweetResult(result.quoted_status_result?.result); + if (quotedResult) { + quotedTweet = mapTweetResult(quotedResult, { quoteDepth: quoteDepth - 1, includeRaw }); + } + } + const media = extractMedia(result); + const article = extractArticleMetadata(result); + const tweetData = { + id: result.rest_id, + text, + createdAt: result.legacy?.created_at, + replyCount: result.legacy?.reply_count, + retweetCount: result.legacy?.retweet_count, + likeCount: result.legacy?.favorite_count, + conversationId: result.legacy?.conversation_id_str, + inReplyToStatusId: result.legacy?.in_reply_to_status_id_str ?? undefined, + author: { + username, + name: name || username, + }, + authorId: userId, + quotedTweet, + media, + article, + }; + if (includeRaw) { + tweetData._raw = result; + } + return tweetData; +} +export function findTweetInInstructions(instructions, tweetId) { + if (!instructions) { + return undefined; + } + for (const instruction of instructions) { + for (const entry of instruction.entries || []) { + const result = entry.content?.itemContent?.tweet_results?.result; + if (result?.rest_id === tweetId) { + return result; + } + } + } + return undefined; +} +export function collectTweetResultsFromEntry(entry) { + const results = []; + const pushResult = (result) => { + if (result?.rest_id) { + results.push(result); + } + }; + const content = entry.content; + pushResult(content?.itemContent?.tweet_results?.result); + pushResult(content?.item?.itemContent?.tweet_results?.result); + for (const item of content?.items ?? []) { + pushResult(item?.item?.itemContent?.tweet_results?.result); + pushResult(item?.itemContent?.tweet_results?.result); + pushResult(item?.content?.itemContent?.tweet_results?.result); + } + return results; +} +export function parseTweetsFromInstructions(instructions, quoteDepthOrOptions) { + const options = typeof quoteDepthOrOptions === 'number' ? { quoteDepth: quoteDepthOrOptions } : quoteDepthOrOptions; + const { quoteDepth, includeRaw = false } = options; + const tweets = []; + const seen = new Set(); + for (const instruction of instructions ?? []) { + for (const entry of instruction.entries ?? []) { + const results = collectTweetResultsFromEntry(entry); + for (const result of results) { + const mapped = mapTweetResult(result, { quoteDepth, includeRaw }); + if (!mapped || seen.has(mapped.id)) { + continue; + } + seen.add(mapped.id); + tweets.push(mapped); + } + } + } + return tweets; +} +export function extractCursorFromInstructions(instructions, cursorType = 'Bottom') { + for (const instruction of instructions ?? []) { + for (const entry of instruction.entries ?? []) { + const content = entry.content; + if (content?.cursorType === cursorType && typeof content.value === 'string' && content.value.length > 0) { + return content.value; + } + } + } + return undefined; +} +export function parseUsersFromInstructions(instructions) { + if (!instructions) { + return []; + } + const users = []; + for (const instruction of instructions) { + if (!instruction.entries) { + continue; + } + for (const entry of instruction.entries) { + const content = entry?.content; + const rawUserResult = content?.itemContent?.user_results?.result; + const userResult = rawUserResult?.__typename === 'UserWithVisibilityResults' && rawUserResult.user + ? rawUserResult.user + : rawUserResult; + if (!userResult || userResult.__typename !== 'User') { + continue; + } + const legacy = userResult.legacy; + const core = userResult.core; + const username = legacy?.screen_name ?? core?.screen_name; + if (!userResult.rest_id || !username) { + continue; + } + users.push({ + id: userResult.rest_id, + username, + name: legacy?.name ?? core?.name ?? username, + description: legacy?.description, + followersCount: legacy?.followers_count, + followingCount: legacy?.friends_count, + isBlueVerified: userResult.is_blue_verified, + profileImageUrl: legacy?.profile_image_url_https ?? userResult.avatar?.image_url, + createdAt: legacy?.created_at ?? core?.created_at, + }); + } + } + return users; +} +//# sourceMappingURL=twitter-client-utils.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/LICENSE b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/LICENSE new file mode 100644 index 0000000..382d7b0 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2025 Peter Steinberger + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/README.md b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/README.md new file mode 100644 index 0000000..e6926e7 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/README.md @@ -0,0 +1,29 @@ +# @steipete/sweet-cookie + +Inline-first browser cookie extraction for local tooling (no native addons). + +Supports: +- Inline payloads (JSON / base64 / file) — most reliable path. +- Local browser reads (best effort): Chrome, Edge, Firefox, Safari (macOS). + +Install: +```bash +npm i @steipete/sweet-cookie +``` + +Usage: +```ts +import { getCookies, toCookieHeader } from '@steipete/sweet-cookie'; + +const { cookies, warnings } = await getCookies({ + url: 'https://example.com/', + names: ['session', 'csrf'], + browsers: ['chrome', 'edge', 'firefox', 'safari'], +}); + +for (const w of warnings) console.warn(w); +const cookieHeader = toCookieHeader(cookies, { dedupeByName: true }); +``` + +Docs + extension exporter: see the repo root README. + diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts new file mode 100644 index 0000000..6b4855d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts @@ -0,0 +1,3 @@ +export { getCookies, toCookieHeader } from './public.js'; +export type { BrowserName, Cookie, CookieHeaderOptions, CookieMode, CookieSameSite, GetCookiesOptions, GetCookiesResult, } from './types.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts.map new file mode 100644 index 0000000..e0f5600 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EACX,WAAW,EACX,MAAM,EACN,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,YAAY,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js new file mode 100644 index 0000000..dca6064 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js @@ -0,0 +1,2 @@ +export { getCookies, toCookieHeader } from './public.js'; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js.map new file mode 100644 index 0000000..8621620 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts new file mode 100644 index 0000000..e6b93f5 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts @@ -0,0 +1,8 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromChrome(options: { + profile?: string; + timeoutMs?: number; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=chrome.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts.map new file mode 100644 index 0000000..89e5eb8 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../src/providers/chrome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK5D,wBAAsB,oBAAoB,CACzC,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5F,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CA0B3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js new file mode 100644 index 0000000..5e4f315 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js @@ -0,0 +1,27 @@ +import { getCookiesFromChromeSqliteLinux } from './chromeSqliteLinux.js'; +import { getCookiesFromChromeSqliteMac } from './chromeSqliteMac.js'; +import { getCookiesFromChromeSqliteWindows } from './chromeSqliteWindows.js'; +export async function getCookiesFromChrome(options, origins, allowlistNames) { + const warnings = []; + // Platform dispatch only. All real logic lives in the per-OS providers. + if (process.platform === 'darwin') { + const r = await getCookiesFromChromeSqliteMac(options, origins, allowlistNames); + warnings.push(...r.warnings); + const cookies = r.cookies; + return { cookies, warnings }; + } + if (process.platform === 'linux') { + const r = await getCookiesFromChromeSqliteLinux(options, origins, allowlistNames); + warnings.push(...r.warnings); + const cookies = r.cookies; + return { cookies, warnings }; + } + if (process.platform === 'win32') { + const r = await getCookiesFromChromeSqliteWindows(options, origins, allowlistNames); + warnings.push(...r.warnings); + const cookies = r.cookies; + return { cookies, warnings }; + } + return { cookies: [], warnings }; +} +//# sourceMappingURL=chrome.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js.map new file mode 100644 index 0000000..b3b112a --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chrome.js.map @@ -0,0 +1 @@ +{"version":3,"file":"chrome.js","sourceRoot":"","sources":["../../src/providers/chrome.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAE7E,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACzC,OAA4F,EAC5F,OAAiB,EACjB,cAAkC;IAElC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,wEAAwE;IACxE,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,MAAM,6BAA6B,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QAChF,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAa,CAAC,CAAC,OAAO,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,MAAM,+BAA+B,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QAClF,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAa,CAAC,CAAC,OAAO,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,MAAM,iCAAiC,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QACpF,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAa,CAAC,CAAC,OAAO,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts new file mode 100644 index 0000000..e432ae0 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts @@ -0,0 +1,11 @@ +export declare function deriveAes128CbcKeyFromPassword(password: string, options: { + iterations: number; +}): Buffer; +export declare function decryptChromiumAes128CbcCookieValue(encryptedValue: Uint8Array, keyCandidates: readonly Buffer[], options: { + stripHashPrefix: boolean; + treatUnknownPrefixAsPlaintext?: boolean; +}): string | null; +export declare function decryptChromiumAes256GcmCookieValue(encryptedValue: Uint8Array, key: Buffer, options: { + stripHashPrefix: boolean; +}): string | null; +//# sourceMappingURL=crypto.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts.map new file mode 100644 index 0000000..ad07eaa --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/crypto.ts"],"names":[],"mappings":"AAIA,wBAAgB,8BAA8B,CAC7C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAC7B,MAAM,CAIR;AAED,wBAAgB,mCAAmC,CAClD,cAAc,EAAE,UAAU,EAC1B,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,OAAO,EAAE;IAAE,eAAe,EAAE,OAAO,CAAC;IAAC,6BAA6B,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5E,MAAM,GAAG,IAAI,CA2Bf;AAED,wBAAgB,mCAAmC,CAClD,cAAc,EAAE,UAAU,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,GACnC,MAAM,GAAG,IAAI,CAyBf"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js new file mode 100644 index 0000000..b0b77a5 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js @@ -0,0 +1,100 @@ +import { createDecipheriv, pbkdf2Sync } from 'node:crypto'; +const UTF8_DECODER = new TextDecoder('utf-8', { fatal: true }); +export function deriveAes128CbcKeyFromPassword(password, options) { + // Chromium derives the AES-128-CBC key from "Chrome Safe Storage" using PBKDF2. + // The salt/length/digest are fixed by Chromium ("saltysalt", 16 bytes, sha1). + return pbkdf2Sync(password, 'saltysalt', options.iterations, 16, 'sha1'); +} +export function decryptChromiumAes128CbcCookieValue(encryptedValue, keyCandidates, options) { + const buf = Buffer.from(encryptedValue); + if (buf.length < 3) + return null; + // Chromium prefixes encrypted cookies with `v10`, `v11`, ... (three bytes). + const prefix = buf.subarray(0, 3).toString('utf8'); + const hasVersionPrefix = /^v\d\d$/.test(prefix); + if (!hasVersionPrefix) { + // Some platforms (notably macOS) can store plaintext values in `encrypted_value`. + // Callers decide whether unknown prefixes should be treated as plaintext. + if (options.treatUnknownPrefixAsPlaintext === false) + return null; + return decodeCookieValueBytes(buf, false); + } + const ciphertext = buf.subarray(3); + if (!ciphertext.length) + return ''; + for (const key of keyCandidates) { + // Try multiple candidates because Linux may fall back to empty passwords depending on keyring state. + const decrypted = tryDecryptAes128Cbc(ciphertext, key); + if (!decrypted) + continue; + const decoded = decodeCookieValueBytes(decrypted, options.stripHashPrefix); + if (decoded !== null) + return decoded; + } + return null; +} +export function decryptChromiumAes256GcmCookieValue(encryptedValue, key, options) { + const buf = Buffer.from(encryptedValue); + if (buf.length < 3) + return null; + const prefix = buf.subarray(0, 3).toString('utf8'); + if (!/^v\d\d$/.test(prefix)) + return null; + // AES-256-GCM layout: + // - 12-byte nonce + // - ciphertext + // - 16-byte authentication tag + const payload = buf.subarray(3); + if (payload.length < 12 + 16) + return null; + const nonce = payload.subarray(0, 12); + const authenticationTag = payload.subarray(payload.length - 16); + const ciphertext = payload.subarray(12, payload.length - 16); + try { + const decipher = createDecipheriv('aes-256-gcm', key, nonce); + decipher.setAuthTag(authenticationTag); + const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]); + return decodeCookieValueBytes(plaintext, options.stripHashPrefix); + } + catch { + return null; + } +} +function tryDecryptAes128Cbc(ciphertext, key) { + try { + // Chromium's legacy AES-128-CBC uses an IV of 16 spaces. + const iv = Buffer.alloc(16, 0x20); + const decipher = createDecipheriv('aes-128-cbc', key, iv); + decipher.setAutoPadding(false); + const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]); + return removePkcs7Padding(plaintext); + } + catch { + return null; + } +} +function removePkcs7Padding(value) { + if (!value.length) + return value; + const padding = value[value.length - 1]; + if (!padding || padding > 16) + return value; + return value.subarray(0, value.length - padding); +} +function decodeCookieValueBytes(value, stripHashPrefix) { + // Chromium >= 24 prepends a 32-byte hash to cookie values. + const bytes = stripHashPrefix && value.length >= 32 ? value.subarray(32) : value; + try { + return stripLeadingControlChars(UTF8_DECODER.decode(bytes)); + } + catch { + return null; + } +} +function stripLeadingControlChars(value) { + let i = 0; + while (i < value.length && value.charCodeAt(i) < 0x20) + i += 1; + return value.slice(i); +} +//# sourceMappingURL=crypto.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js.map new file mode 100644 index 0000000..890f3a4 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/crypto.js.map @@ -0,0 +1 @@ +{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/crypto.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts new file mode 100644 index 0000000..f664ab0 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts @@ -0,0 +1,25 @@ +export type LinuxKeyringBackend = 'gnome' | 'kwallet' | 'basic'; +/** + * Read the "Safe Storage" password from a Linux keyring. + * + * Chromium browsers typically store their cookie encryption password under: + * - service: " Safe Storage" + * - account: "" + * + * We keep this logic in JS (no native deps) and return an empty password on failure + * (Chromium may still have v10 cookies, and callers can use inline/export escape hatches). + */ +export declare function getLinuxChromiumSafeStoragePassword(options: { + backend?: LinuxKeyringBackend; + app: 'chrome' | 'edge'; +}): Promise<{ + password: string; + warnings: string[]; +}>; +export declare function getLinuxChromeSafeStoragePassword(options?: { + backend?: LinuxKeyringBackend; +}): Promise<{ + password: string; + warnings: string[]; +}>; +//# sourceMappingURL=linuxKeyring.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts.map new file mode 100644 index 0000000..fd958e9 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"linuxKeyring.d.ts","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/linuxKeyring.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAEhE;;;;;;;;;GASG;AACH,wBAAsB,mCAAmC,CAAC,OAAO,EAAE;IAClE,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA8DpD;AAED,wBAAsB,iCAAiC,CACtD,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAAO,GAC7C,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAInD"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js new file mode 100644 index 0000000..bb113a5 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js @@ -0,0 +1,104 @@ +import { execCapture } from '../../util/exec.js'; +/** + * Read the "Safe Storage" password from a Linux keyring. + * + * Chromium browsers typically store their cookie encryption password under: + * - service: " Safe Storage" + * - account: "" + * + * We keep this logic in JS (no native deps) and return an empty password on failure + * (Chromium may still have v10 cookies, and callers can use inline/export escape hatches). + */ +export async function getLinuxChromiumSafeStoragePassword(options) { + const warnings = []; + // Escape hatch: if callers already know the password (or want deterministic CI behavior), + // they can bypass keyring probing entirely. + const overrideKey = options.app === 'edge' + ? 'SWEET_COOKIE_EDGE_SAFE_STORAGE_PASSWORD' + : 'SWEET_COOKIE_CHROME_SAFE_STORAGE_PASSWORD'; + const override = readEnv(overrideKey); + if (override !== undefined) + return { password: override, warnings }; + const backend = options.backend ?? parseLinuxKeyringBackend() ?? chooseLinuxKeyringBackend(); + // `basic` means "don't try keyrings" (Chrome will fall back to older/less-secure schemes on some setups). + if (backend === 'basic') + return { password: '', warnings }; + const service = options.app === 'edge' ? 'Microsoft Edge Safe Storage' : 'Chrome Safe Storage'; + const account = options.app === 'edge' ? 'Microsoft Edge' : 'Chrome'; + const folder = `${account} Keys`; + if (backend === 'gnome') { + // GNOME keyring: `secret-tool` is the simplest way to read libsecret entries. + const res = await execCapture('secret-tool', ['lookup', 'service', service, 'account', account], { timeoutMs: 3_000 }); + if (res.code === 0) + return { password: res.stdout.trim(), warnings }; + warnings.push('Failed to read Linux keyring via secret-tool; v11 cookies may be unavailable.'); + return { password: '', warnings }; + } + // KDE keyring: query KWallet via `kwallet-query`, but the wallet name differs across KDE versions. + const kdeVersion = (readEnv('KDE_SESSION_VERSION') ?? '').trim(); + const serviceName = kdeVersion === '6' + ? 'org.kde.kwalletd6' + : kdeVersion === '5' + ? 'org.kde.kwalletd5' + : 'org.kde.kwalletd'; + const walletPath = kdeVersion === '6' + ? '/modules/kwalletd6' + : kdeVersion === '5' + ? '/modules/kwalletd5' + : '/modules/kwalletd'; + const wallet = await getKWalletNetworkWallet(serviceName, walletPath); + const passwordRes = await execCapture('kwallet-query', ['--read-password', service, '--folder', folder, wallet], { timeoutMs: 3_000 }); + if (passwordRes.code !== 0) { + warnings.push('Failed to read Linux keyring via kwallet-query; v11 cookies may be unavailable.'); + return { password: '', warnings }; + } + if (passwordRes.stdout.toLowerCase().startsWith('failed to read')) + return { password: '', warnings }; + return { password: passwordRes.stdout.trim(), warnings }; +} +export async function getLinuxChromeSafeStoragePassword(options = {}) { + const args = { app: 'chrome' }; + if (options.backend !== undefined) + args.backend = options.backend; + return await getLinuxChromiumSafeStoragePassword(args); +} +function parseLinuxKeyringBackend() { + const raw = readEnv('SWEET_COOKIE_LINUX_KEYRING'); + if (!raw) + return undefined; + const normalized = raw.toLowerCase(); + if (normalized === 'gnome') + return 'gnome'; + if (normalized === 'kwallet') + return 'kwallet'; + if (normalized === 'basic') + return 'basic'; + return undefined; +} +function chooseLinuxKeyringBackend() { + const xdg = readEnv('XDG_CURRENT_DESKTOP') ?? ''; + const isKde = xdg.split(':').some((p) => p.trim().toLowerCase() === 'kde') || !!readEnv('KDE_FULL_SESSION'); + return isKde ? 'kwallet' : 'gnome'; +} +async function getKWalletNetworkWallet(serviceName, walletPath) { + const res = await execCapture('dbus-send', [ + '--session', + '--print-reply=literal', + `--dest=${serviceName}`, + walletPath, + 'org.kde.KWallet.networkWallet', + ], { timeoutMs: 3_000 }); + const fallback = 'kdewallet'; + if (res.code !== 0) + return fallback; + const raw = res.stdout.trim(); + if (!raw) + return fallback; + return raw.replaceAll('"', '').trim() || fallback; +} +function readEnv(key) { + const value = process.env[key]; + const trimmed = typeof value === 'string' ? value.trim() : ''; + return trimmed.length ? trimmed : undefined; +} +//# sourceMappingURL=linuxKeyring.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js.map new file mode 100644 index 0000000..e0b6a4b --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/linuxKeyring.js.map @@ -0,0 +1 @@ +{"version":3,"file":"linuxKeyring.js","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/linuxKeyring.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts new file mode 100644 index 0000000..3e6205f --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts @@ -0,0 +1,10 @@ +import type { GetCookiesResult } from '../../types.js'; +export declare function getCookiesFromChromeSqliteDb(options: { + dbPath: string; + profile?: string; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null, decrypt: (encryptedValue: Uint8Array, options: { + stripHashPrefix: boolean; +}) => string | null): Promise; +//# sourceMappingURL=shared.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts.map new file mode 100644 index 0000000..dccba66 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/shared.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAA0B,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAkB/E,wBAAsB,4BAA4B,CACjD,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACxF,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAClC,OAAO,EAAE,CAAC,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,KAAK,MAAM,GAAG,IAAI,GAC3F,OAAO,CAAC,gBAAgB,CAAC,CAsD3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js new file mode 100644 index 0000000..59ef6e4 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js @@ -0,0 +1,293 @@ +import { copyFileSync, existsSync, mkdtempSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import path from 'node:path'; +import { normalizeExpiration } from '../../util/expire.js'; +import { hostMatchesCookieDomain } from '../../util/hostMatch.js'; +import { importNodeSqlite, supportsReadBigInts } from '../../util/nodeSqlite.js'; +import { isBunRuntime } from '../../util/runtime.js'; +export async function getCookiesFromChromeSqliteDb(options, origins, allowlistNames, decrypt) { + const warnings = []; + // Chrome can keep its cookie DB locked and/or rely on WAL sidecars. + // Copying to a temp dir gives us a stable snapshot that both node:sqlite and bun:sqlite can open. + const tempDir = mkdtempSync(path.join(tmpdir(), 'sweet-cookie-chrome-')); + const tempDbPath = path.join(tempDir, 'Cookies'); + try { + copyFileSync(options.dbPath, tempDbPath); + // If WAL is enabled, the latest writes might live in `Cookies-wal`/`Cookies-shm`. + // Copy them too when present so our snapshot reflects the current browser state. + copySidecar(options.dbPath, `${tempDbPath}-wal`, '-wal'); + copySidecar(options.dbPath, `${tempDbPath}-shm`, '-shm'); + } + catch (error) { + rmSync(tempDir, { recursive: true, force: true }); + warnings.push(`Failed to copy Chrome cookie DB: ${error instanceof Error ? error.message : String(error)}`); + return { cookies: [], warnings }; + } + try { + const hosts = origins.map((o) => new URL(o).hostname); + const where = buildHostWhereClause(hosts, 'host_key'); + const metaVersion = await readChromiumMetaVersion(tempDbPath); + // Chromium >= 24 stores a 32-byte hash prefix in decrypted cookie values. + // We detect this via the `meta` table version and strip it when present. + const stripHashPrefix = metaVersion >= 24; + const rowsResult = await readChromeRows(tempDbPath, where); + if (!rowsResult.ok) { + warnings.push(rowsResult.error); + return { cookies: [], warnings }; + } + const collectOptions = {}; + if (options.profile) + collectOptions.profile = options.profile; + if (options.includeExpired !== undefined) + collectOptions.includeExpired = options.includeExpired; + const cookies = collectChromeCookiesFromRows(rowsResult.rows, collectOptions, hosts, allowlistNames, (encryptedValue) => decrypt(encryptedValue, { stripHashPrefix }), warnings); + return { cookies: dedupeCookies(cookies), warnings }; + } + finally { + rmSync(tempDir, { recursive: true, force: true }); + } +} +function collectChromeCookiesFromRows(rows, options, hosts, allowlistNames, decrypt, warnings) { + const cookies = []; + const now = Math.floor(Date.now() / 1000); + let warnedEncryptedType = false; + for (const row of rows) { + const name = typeof row.name === 'string' ? row.name : null; + if (!name) + continue; + if (allowlistNames && allowlistNames.size > 0 && !allowlistNames.has(name)) + continue; + const hostKey = typeof row.host_key === 'string' ? row.host_key : null; + if (!hostKey) + continue; + if (!hostMatchesAny(hosts, hostKey)) + continue; + const rowPath = typeof row.path === 'string' ? row.path : ''; + const valueString = typeof row.value === 'string' ? row.value : null; + let value = valueString; + if (value === null || value.length === 0) { + // Many modern Chromium cookies keep `value` empty and only store `encrypted_value`. + // We decrypt on demand and drop rows we can't interpret. + const encryptedBytes = getEncryptedBytes(row); + if (!encryptedBytes) { + if (!warnedEncryptedType && row.encrypted_value !== undefined) { + warnings.push('Chrome cookie encrypted_value is in an unsupported type.'); + warnedEncryptedType = true; + } + continue; + } + value = decrypt(encryptedBytes); + } + if (value === null) + continue; + const expiresRaw = typeof row.expires_utc === 'number' || typeof row.expires_utc === 'bigint' + ? row.expires_utc + : tryParseInt(row.expires_utc); + const expires = normalizeExpiration(expiresRaw ?? undefined); + if (!options.includeExpired) { + if (expires && expires < now) + continue; + } + const secure = row.is_secure === 1 || + row.is_secure === 1n || + row.is_secure === '1' || + row.is_secure === true; + const httpOnly = row.is_httponly === 1 || + row.is_httponly === 1n || + row.is_httponly === '1' || + row.is_httponly === true; + const sameSite = normalizeChromiumSameSite(row.samesite); + const source = { browser: 'chrome' }; + if (options.profile) + source.profile = options.profile; + const cookie = { + name, + value, + domain: hostKey.startsWith('.') ? hostKey.slice(1) : hostKey, + path: rowPath || '/', + secure, + httpOnly, + source, + }; + if (expires !== undefined) + cookie.expires = expires; + if (sameSite !== undefined) + cookie.sameSite = sameSite; + cookies.push(cookie); + } + return cookies; +} +function tryParseInt(value) { + if (typeof value === 'bigint') { + const parsed = Number(value); + return Number.isFinite(parsed) ? parsed : null; + } + if (typeof value !== 'string') + return null; + const parsed = Number.parseInt(value, 10); + return Number.isFinite(parsed) ? parsed : null; +} +function normalizeChromiumSameSite(value) { + if (typeof value === 'bigint') { + const parsed = Number(value); + return Number.isFinite(parsed) ? normalizeChromiumSameSite(parsed) : undefined; + } + if (typeof value === 'number') { + if (value === 2) + return 'Strict'; + if (value === 1) + return 'Lax'; + if (value === 0) + return 'None'; + return undefined; + } + if (typeof value === 'string') { + const parsed = Number.parseInt(value, 10); + if (Number.isFinite(parsed)) + return normalizeChromiumSameSite(parsed); + const normalized = value.toLowerCase(); + if (normalized === 'strict') + return 'Strict'; + if (normalized === 'lax') + return 'Lax'; + if (normalized === 'none' || normalized === 'no_restriction') + return 'None'; + } + return undefined; +} +function getEncryptedBytes(row) { + const raw = row.encrypted_value; + if (raw instanceof Uint8Array) + return raw; + return null; +} +async function readChromiumMetaVersion(dbPath) { + const sql = `SELECT value FROM meta WHERE key = 'version'`; + const result = isBunRuntime() + ? await queryNodeOrBun({ kind: 'bun', dbPath, sql }) + : await queryNodeOrBun({ kind: 'node', dbPath, sql }); + if (!result.ok) + return 0; + const first = result.rows[0]; + const value = first?.value; + if (typeof value === 'number') + return Math.floor(value); + if (typeof value === 'bigint') { + const parsed = Number(value); + return Number.isFinite(parsed) ? Math.floor(parsed) : 0; + } + if (typeof value === 'string') { + const parsed = Number.parseInt(value, 10); + return Number.isFinite(parsed) ? parsed : 0; + } + return 0; +} +async function readChromeRows(dbPath, where) { + const sqliteKind = isBunRuntime() ? 'bun' : 'node'; + const sqliteLabel = sqliteKind === 'bun' ? 'bun:sqlite' : 'node:sqlite'; + const sql = `SELECT name, value, host_key, path, expires_utc, samesite, encrypted_value, ` + + `is_secure AS is_secure, is_httponly AS is_httponly ` + + `FROM cookies WHERE (${where}) ORDER BY expires_utc DESC;`; + const result = await queryNodeOrBun({ kind: sqliteKind, dbPath, sql }); + if (result.ok) + return { ok: true, rows: result.rows }; + // Intentionally strict: only support modern Chromium cookie DB schemas. + // If this fails, assume the local Chrome/Chromium is too old or uses a non-standard schema. + return { + ok: false, + error: `${sqliteLabel} failed reading Chrome cookies (requires modern Chromium, e.g. Chrome >= 100): ${result.error}`, + }; +} +async function queryNodeOrBun(options) { + try { + if (options.kind === 'node') { + // Node's `node:sqlite` is synchronous and returns plain JS values. Keep it boxed in a + // small scope so callers don't need to care about runtime differences. + const { DatabaseSync } = await importNodeSqlite(); + const dbOptions = { readOnly: true }; + if (supportsReadBigInts()) { + dbOptions.readBigInts = true; + } + const db = new DatabaseSync(options.dbPath, dbOptions); + try { + const rows = db.prepare(options.sql).all(); + return { ok: true, rows }; + } + finally { + db.close(); + } + } + // Bun's sqlite API has a different surface (`Database` + `.query().all()`). + const { Database } = await import('bun:sqlite'); + const db = new Database(options.dbPath, { readonly: true }); + try { + const rows = db.query(options.sql).all(); + return { ok: true, rows }; + } + finally { + db.close(); + } + } + catch (error) { + return { ok: false, error: error instanceof Error ? error.message : String(error) }; + } +} +function copySidecar(sourceDbPath, target, suffix) { + const sidecar = `${sourceDbPath}${suffix}`; + if (!existsSync(sidecar)) + return; + try { + copyFileSync(sidecar, target); + } + catch { + // ignore + } +} +function buildHostWhereClause(hosts, column) { + const clauses = []; + for (const host of hosts) { + // Chrome cookies often live on parent domains (e.g. .google.com for gemini.google.com). + // Include parent domains so the SQL filter doesn't drop valid session cookies. + for (const candidate of expandHostCandidates(host)) { + const escaped = sqlLiteral(candidate); + const escapedDot = sqlLiteral(`.${candidate}`); + const escapedLike = sqlLiteral(`%.${candidate}`); + clauses.push(`${column} = ${escaped}`); + clauses.push(`${column} = ${escapedDot}`); + clauses.push(`${column} LIKE ${escapedLike}`); + } + } + return clauses.length ? clauses.join(' OR ') : '1=0'; +} +function sqlLiteral(value) { + const escaped = value.replaceAll("'", "''"); + return `'${escaped}'`; +} +function expandHostCandidates(host) { + const parts = host.split('.').filter(Boolean); + if (parts.length <= 1) + return [host]; + const candidates = new Set(); + candidates.add(host); + // Include parent domains down to two labels (avoid TLD-only fragments). + for (let i = 1; i <= parts.length - 2; i += 1) { + const candidate = parts.slice(i).join('.'); + if (candidate) + candidates.add(candidate); + } + return Array.from(candidates); +} +function hostMatchesAny(hosts, cookieHost) { + const cookieDomain = cookieHost.startsWith('.') ? cookieHost.slice(1) : cookieHost; + return hosts.some((host) => hostMatchesCookieDomain(host, cookieDomain)); +} +function dedupeCookies(cookies) { + const merged = new Map(); + for (const cookie of cookies) { + const key = `${cookie.name}|${cookie.domain ?? ''}|${cookie.path ?? ''}`; + if (!merged.has(key)) + merged.set(key, cookie); + } + return Array.from(merged.values()); +} +//# sourceMappingURL=shared.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js.map new file mode 100644 index 0000000..261d801 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/shared.js.map @@ -0,0 +1 @@ +{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAcrD,MAAM,CAAC,KAAK,UAAU,4BAA4B,CACjD,OAAwF,EACxF,OAAiB,EACjB,cAAkC,EAClC,OAA6F;IAE7F,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,oEAAoE;IACpE,kGAAkG;IAClG,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC,CAAC;IACzE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,CAAC;QACJ,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACzC,kFAAkF;QAClF,iFAAiF;QACjF,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,UAAU,MAAM,EAAE,MAAM,CAAC,CAAC;QACzD,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,UAAU,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,QAAQ,CAAC,IAAI,CACZ,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5F,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;IAClC,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAEtD,MAAM,WAAW,GAAG,MAAM,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC9D,0EAA0E;QAC1E,yEAAyE;QACzE,MAAM,eAAe,GAAG,WAAW,IAAI,EAAE,CAAC;QAE1C,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;QAClC,CAAC;QAED,MAAM,cAAc,GAAmD,EAAE,CAAC;QAC1E,IAAI,OAAO,CAAC,OAAO;YAAE,cAAc,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC9D,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;YACvC,cAAc,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;QAExD,MAAM,OAAO,GAAG,4BAA4B,CAC3C,UAAU,CAAC,IAAI,EACf,cAAc,EACd,KAAK,EACL,cAAc,EACd,CAAC,cAAc,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,eAAe,EAAE,CAAC,EAChE,QAAQ,CACR,CAAC;QAEF,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;IACtD,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACF,CAAC;AAED,SAAS,4BAA4B,CACpC,IAAiB,EACjB,OAAuD,EACvD,KAAe,EACf,cAAkC,EAClC,OAAsD,EACtD,QAAkB;IAElB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAEhC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5D,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,IAAI,cAAc,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAErF,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QACvE,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC;YAAE,SAAS;QAE9C,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAE7D,MAAM,WAAW,GAAG,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,IAAI,KAAK,GAAkB,WAAW,CAAC;QACvC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1C,oFAAoF;YACpF,yDAAyD;YACzD,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrB,IAAI,CAAC,mBAAmB,IAAI,GAAG,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;oBAC/D,QAAQ,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;oBAC1E,mBAAmB,GAAG,IAAI,CAAC;gBAC5B,CAAC;gBACD,SAAS;YACV,CAAC;YACD,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QAE7B,MAAM,UAAU,GACf,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ;YACzE,CAAC,CAAC,GAAG,CAAC,WAAW;YACjB,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,mBAAmB,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;QAE7D,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;YAC7B,IAAI,OAAO,IAAI,OAAO,GAAG,GAAG;gBAAE,SAAS;QACxC,CAAC;QAED,MAAM,MAAM,GACX,GAAG,CAAC,SAAS,KAAK,CAAC;YACnB,GAAG,CAAC,SAAS,KAAK,EAAE;YACpB,GAAG,CAAC,SAAS,KAAK,GAAG;YACrB,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC;QACxB,MAAM,QAAQ,GACb,GAAG,CAAC,WAAW,KAAK,CAAC;YACrB,GAAG,CAAC,WAAW,KAAK,EAAE;YACtB,GAAG,CAAC,WAAW,KAAK,GAAG;YACvB,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC;QAE1B,MAAM,QAAQ,GAAG,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAkC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QACpE,IAAI,OAAO,CAAC,OAAO;YAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAEtD,MAAM,MAAM,GAAW;YACtB,IAAI;YACJ,KAAK;YACL,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;YAC5D,IAAI,EAAE,OAAO,IAAI,GAAG;YACpB,MAAM;YACN,QAAQ;YACR,MAAM;SACN,CAAC;QACF,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;QACpD,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEvD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAc;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QACjC,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC9B,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QAC/B,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,yBAAyB,CAAC,MAAM,CAAC,CAAC;QACtE,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,UAAU,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC7C,IAAI,UAAU,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QACvC,IAAI,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,gBAAgB;YAAE,OAAO,MAAM,CAAC;IAC7E,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAc;IACxC,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC;IAChC,IAAI,GAAG,YAAY,UAAU;QAAE,OAAO,GAAG,CAAC;IAC1C,OAAO,IAAI,CAAC;AACb,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,MAAc;IACpD,MAAM,GAAG,GAAG,8CAA8C,CAAC;IAC3D,MAAM,MAAM,GAAG,YAAY,EAAE;QAC5B,CAAC,CAAC,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACpD,CAAC,CAAC,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAoC,CAAC;IAChE,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,CAAC;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC;AAED,KAAK,UAAU,cAAc,CAC5B,MAAc,EACd,KAAa;IAEb,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IACnD,MAAM,WAAW,GAAG,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC;IAExE,MAAM,GAAG,GACR,8EAA8E;QAC9E,qDAAqD;QACrD,uBAAuB,KAAK,8BAA8B,CAAC;IAE5D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvE,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAmB,EAAE,CAAC;IAErE,wEAAwE;IACxE,4FAA4F;IAC5F,OAAO;QACN,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,GAAG,WAAW,kFAAkF,MAAM,CAAC,KAAK,EAAE;KACrH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,OAI7B;IACA,IAAI,CAAC;QACJ,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7B,sFAAsF;YACtF,uEAAuE;YACvE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,gBAAgB,EAAE,CAAC;YAClD,MAAM,SAAS,GAAiD,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACnF,IAAI,mBAAmB,EAAE,EAAE,CAAC;gBAC3B,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC;YAC9B,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YACvD,IAAI,CAAC;gBACJ,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAoC,CAAC;gBAC7E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;oBAAS,CAAC;gBACV,EAAE,CAAC,KAAK,EAAE,CAAC;YACZ,CAAC;QACF,CAAC;QACD,4EAA4E;QAC5E,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAoC,CAAC;YAC3E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACV,EAAE,CAAC,KAAK,EAAE,CAAC;QACZ,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IACrF,CAAC;AACF,CAAC;AAED,SAAS,WAAW,CAAC,YAAoB,EAAE,MAAc,EAAE,MAAuB;IACjF,MAAM,OAAO,GAAG,GAAG,YAAY,GAAG,MAAM,EAAE,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO;IACjC,IAAI,CAAC;QACJ,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACR,SAAS;IACV,CAAC;AACF,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAe,EAAE,MAAkB;IAChE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,wFAAwF;QACxF,+EAA+E;QAC/E,KAAK,MAAM,SAAS,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;YACtC,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;YAC/C,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,SAAS,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,MAAM,OAAO,EAAE,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,MAAM,UAAU,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,SAAS,WAAW,EAAE,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACtD,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAChC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,OAAO,IAAI,OAAO,GAAG,CAAC;AACvB,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,wEAAwE;IACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,SAAS;YAAE,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,cAAc,CAAC,KAAe,EAAE,UAAkB;IAC1D,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACnF,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAuB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,aAAa,CAAC,OAAiB;IACvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;QACzE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACpC,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts new file mode 100644 index 0000000..9da1305 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts @@ -0,0 +1,10 @@ +export declare function dpapiUnprotect(data: Buffer, options?: { + timeoutMs?: number; +}): Promise<{ + ok: true; + value: Buffer; +} | { + ok: false; + error: string; +}>; +//# sourceMappingURL=windowsDpapi.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts.map new file mode 100644 index 0000000..cd94668 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"windowsDpapi.d.ts","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/windowsDpapi.ts"],"names":[],"mappings":"AAEA,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA+BrE"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js new file mode 100644 index 0000000..d0915bf --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js @@ -0,0 +1,26 @@ +import { execCapture } from '../../util/exec.js'; +export async function dpapiUnprotect(data, options = {}) { + const timeoutMs = options.timeoutMs ?? 5_000; + // There is no cross-platform JS API for Windows DPAPI, and we explicitly avoid native addons. + // PowerShell can call ProtectedData.Unprotect for the current user, which matches Chrome's behavior. + const inputB64 = data.toString('base64'); + const prelude = 'try { Add-Type -AssemblyName System.Security.Cryptography.ProtectedData -ErrorAction Stop } catch { try { Add-Type -AssemblyName System.Security -ErrorAction Stop } catch {} };'; + const script = prelude + + `$in=[Convert]::FromBase64String('${inputB64}');` + + `$out=[System.Security.Cryptography.ProtectedData]::Unprotect($in,$null,[System.Security.Cryptography.DataProtectionScope]::CurrentUser);` + + `[Convert]::ToBase64String($out)`; + const res = await execCapture('powershell', ['-NoProfile', '-NonInteractive', '-Command', script], { + timeoutMs, + }); + if (res.code !== 0) { + return { ok: false, error: res.stderr.trim() || `powershell exit ${res.code}` }; + } + try { + const out = Buffer.from(res.stdout.trim(), 'base64'); + return { ok: true, value: out }; + } + catch (error) { + return { ok: false, error: error instanceof Error ? error.message : String(error) }; + } +} +//# sourceMappingURL=windowsDpapi.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js.map new file mode 100644 index 0000000..f915def --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqlite/windowsDpapi.js.map @@ -0,0 +1 @@ +{"version":3,"file":"windowsDpapi.js","sourceRoot":"","sources":["../../../src/providers/chromeSqlite/windowsDpapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,IAAY,EACZ,UAAkC,EAAE;IAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAE7C,8FAA8F;IAC9F,qGAAqG;IACrG,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,OAAO,GACZ,kLAAkL,CAAC;IACpL,MAAM,MAAM,GACX,OAAO;QACP,oCAAoC,QAAQ,KAAK;QACjD,0IAA0I;QAC1I,iCAAiC,CAAC;IAEnC,MAAM,GAAG,GAAG,MAAM,WAAW,CAC5B,YAAY,EACZ,CAAC,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,CAAC,EACrD;QACC,SAAS;KACT,CACD,CAAC;IACF,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,mBAAmB,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;IACjF,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;QACrD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IACrF,CAAC;AACF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts new file mode 100644 index 0000000..354f277 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts @@ -0,0 +1,7 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromChromeSqliteLinux(options: { + profile?: string; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=chromeSqliteLinux.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts.map new file mode 100644 index 0000000..c2a7162 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"chromeSqliteLinux.d.ts","sourceRoot":"","sources":["../../src/providers/chromeSqliteLinux.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASpD,wBAAsB,+BAA+B,CACpD,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACxE,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAkD3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js new file mode 100644 index 0000000..620e7ef --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js @@ -0,0 +1,51 @@ +import { decryptChromiumAes128CbcCookieValue, deriveAes128CbcKeyFromPassword, } from './chromeSqlite/crypto.js'; +import { getLinuxChromeSafeStoragePassword } from './chromeSqlite/linuxKeyring.js'; +import { getCookiesFromChromeSqliteDb } from './chromeSqlite/shared.js'; +import { resolveChromiumCookiesDbLinux } from './chromium/linuxPaths.js'; +export async function getCookiesFromChromeSqliteLinux(options, origins, allowlistNames) { + const args = { + configDirName: 'google-chrome', + }; + if (options.profile !== undefined) + args.profile = options.profile; + const dbPath = resolveChromiumCookiesDbLinux(args); + if (!dbPath) { + return { cookies: [], warnings: ['Chrome cookies database not found.'] }; + } + const { password, warnings: keyringWarnings } = await getLinuxChromeSafeStoragePassword(); + // Linux uses multiple schemes depending on distro/keyring availability. + // - v10 often uses the hard-coded "peanuts" password + // - v11 uses "Chrome Safe Storage" from the keyring (may be empty/unavailable) + const v10Key = deriveAes128CbcKeyFromPassword('peanuts', { iterations: 1 }); + const emptyKey = deriveAes128CbcKeyFromPassword('', { iterations: 1 }); + const v11Key = deriveAes128CbcKeyFromPassword(password, { iterations: 1 }); + const decrypt = (encryptedValue, opts) => { + const prefix = Buffer.from(encryptedValue).subarray(0, 3).toString('utf8'); + if (prefix === 'v10') { + return decryptChromiumAes128CbcCookieValue(encryptedValue, [v10Key, emptyKey], { + stripHashPrefix: opts.stripHashPrefix, + treatUnknownPrefixAsPlaintext: false, + }); + } + if (prefix === 'v11') { + return decryptChromiumAes128CbcCookieValue(encryptedValue, [v11Key, emptyKey], { + stripHashPrefix: opts.stripHashPrefix, + treatUnknownPrefixAsPlaintext: false, + }); + } + return null; + }; + const dbOptions = { + dbPath, + }; + if (options.profile) + dbOptions.profile = options.profile; + if (options.includeExpired !== undefined) + dbOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + dbOptions.debug = options.debug; + const result = await getCookiesFromChromeSqliteDb(dbOptions, origins, allowlistNames, decrypt); + result.warnings.unshift(...keyringWarnings); + return result; +} +//# sourceMappingURL=chromeSqliteLinux.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js.map new file mode 100644 index 0000000..8878b98 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteLinux.js.map @@ -0,0 +1 @@ +{"version":3,"file":"chromeSqliteLinux.js","sourceRoot":"","sources":["../../src/providers/chromeSqliteLinux.ts"],"names":[],"mappings":"AACA,OAAO,EACN,mCAAmC,EACnC,8BAA8B,GAC9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACpD,OAAwE,EACxE,OAAiB,EACjB,cAAkC;IAElC,MAAM,IAAI,GAAwD;QACjE,aAAa,EAAE,eAAe;KAC9B,CAAC;IACF,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAClE,MAAM,MAAM,GAAG,6BAA6B,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,oCAAoC,CAAC,EAAE,CAAC;IAC1E,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,MAAM,iCAAiC,EAAE,CAAC;IAE1F,wEAAwE;IACxE,qDAAqD;IACrD,+EAA+E;IAC/E,MAAM,MAAM,GAAG,8BAA8B,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,8BAA8B,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,8BAA8B,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAE3E,MAAM,OAAO,GAAG,CACf,cAA0B,EAC1B,IAAkC,EAClB,EAAE;QAClB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3E,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACtB,OAAO,mCAAmC,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;gBAC9E,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,6BAA6B,EAAE,KAAK;aACpC,CAAC,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACtB,OAAO,mCAAmC,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;gBAC9E,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,6BAA6B,EAAE,KAAK;aACpC,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;IAEF,MAAM,SAAS,GACd;QACC,MAAM;KACN,CAAC;IACH,IAAI,OAAO,CAAC,OAAO;QAAE,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACzD,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;QAAE,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAC5F,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAEjE,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAC/F,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC;AACf,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts new file mode 100644 index 0000000..da0e8aa --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts @@ -0,0 +1,7 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromChromeSqliteMac(options: { + profile?: string; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=chromeSqliteMac.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts.map new file mode 100644 index 0000000..1801b1a --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"chromeSqliteMac.d.ts","sourceRoot":"","sources":["../../src/providers/chromeSqliteMac.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASpD,wBAAsB,6BAA6B,CAClD,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACxE,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CA6C3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js new file mode 100644 index 0000000..71c815f --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js @@ -0,0 +1,60 @@ +import { homedir } from 'node:os'; +import path from 'node:path'; +import { decryptChromiumAes128CbcCookieValue, deriveAes128CbcKeyFromPassword, } from './chromeSqlite/crypto.js'; +import { getCookiesFromChromeSqliteDb } from './chromeSqlite/shared.js'; +import { readKeychainGenericPasswordFirst } from './chromium/macosKeychain.js'; +import { resolveCookiesDbFromProfileOrRoots } from './chromium/paths.js'; +export async function getCookiesFromChromeSqliteMac(options, origins, allowlistNames) { + const dbPath = resolveChromeCookiesDb(options.profile); + if (!dbPath) { + return { cookies: [], warnings: ['Chrome cookies database not found.'] }; + } + const warnings = []; + // On macOS, Chrome stores its "Safe Storage" secret in Keychain. + // `security find-generic-password` is stable and avoids any native Node keychain modules. + const passwordResult = await readKeychainGenericPasswordFirst({ + account: 'Chrome', + services: ['Chrome Safe Storage'], + timeoutMs: 3_000, + label: 'Chrome Safe Storage', + }); + if (!passwordResult.ok) { + warnings.push(passwordResult.error); + return { cookies: [], warnings }; + } + const chromePassword = passwordResult.password.trim(); + if (!chromePassword) { + warnings.push('macOS Keychain returned an empty Chrome Safe Storage password.'); + return { cookies: [], warnings }; + } + // Chromium uses PBKDF2(password, "saltysalt", 1003, 16, sha1) for AES-128-CBC cookie values on macOS. + const key = deriveAes128CbcKeyFromPassword(chromePassword, { iterations: 1003 }); + const decrypt = (encryptedValue, opts) => decryptChromiumAes128CbcCookieValue(encryptedValue, [key], { + stripHashPrefix: opts.stripHashPrefix, + treatUnknownPrefixAsPlaintext: true, + }); + const dbOptions = { + dbPath, + }; + if (options.profile) + dbOptions.profile = options.profile; + if (options.includeExpired !== undefined) + dbOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + dbOptions.debug = options.debug; + const result = await getCookiesFromChromeSqliteDb(dbOptions, origins, allowlistNames, decrypt); + result.warnings.unshift(...warnings); + return result; +} +function resolveChromeCookiesDb(profile) { + const home = homedir(); + /* c8 ignore next */ + const roots = process.platform === 'darwin' + ? [path.join(home, 'Library', 'Application Support', 'Google', 'Chrome')] + : []; + const args = { roots }; + if (profile !== undefined) + args.profile = profile; + return resolveCookiesDbFromProfileOrRoots(args); +} +//# sourceMappingURL=chromeSqliteMac.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js.map new file mode 100644 index 0000000..0b73d5d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteMac.js.map @@ -0,0 +1 @@ +{"version":3,"file":"chromeSqliteMac.js","sourceRoot":"","sources":["../../src/providers/chromeSqliteMac.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts new file mode 100644 index 0000000..b9a9d95 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts @@ -0,0 +1,7 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromChromeSqliteWindows(options: { + profile?: string; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=chromeSqliteWindows.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts.map new file mode 100644 index 0000000..0c61b9b --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"chromeSqliteWindows.d.ts","sourceRoot":"","sources":["../../src/providers/chromeSqliteWindows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD,wBAAsB,iCAAiC,CACtD,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACxE,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAmC3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js new file mode 100644 index 0000000..576d365 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js @@ -0,0 +1,38 @@ +import path from 'node:path'; +import { decryptChromiumAes256GcmCookieValue } from './chromeSqlite/crypto.js'; +import { getCookiesFromChromeSqliteDb } from './chromeSqlite/shared.js'; +import { getWindowsChromiumMasterKey } from './chromium/windowsMasterKey.js'; +import { resolveChromiumPathsWindows } from './chromium/windowsPaths.js'; +export async function getCookiesFromChromeSqliteWindows(options, origins, allowlistNames) { + const resolveArgs = { + localAppDataVendorPath: path.join('Google', 'Chrome', 'User Data'), + }; + if (options.profile !== undefined) + resolveArgs.profile = options.profile; + const { dbPath, userDataDir } = resolveChromiumPathsWindows(resolveArgs); + if (!dbPath || !userDataDir) { + return { cookies: [], warnings: ['Chrome cookies database not found.'] }; + } + // On Windows, Chrome stores an AES key in `Local State` encrypted with DPAPI (CurrentUser). + // That master key is then used for AES-256-GCM cookie values (`v10`/`v11`/`v20` prefixes). + const masterKey = await getWindowsChromiumMasterKey(userDataDir, 'Chrome'); + if (!masterKey.ok) { + return { cookies: [], warnings: [masterKey.error] }; + } + const decrypt = (encryptedValue, opts) => { + return decryptChromiumAes256GcmCookieValue(encryptedValue, masterKey.value, { + stripHashPrefix: opts.stripHashPrefix, + }); + }; + const dbOptions = { + dbPath, + }; + if (options.profile) + dbOptions.profile = options.profile; + if (options.includeExpired !== undefined) + dbOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + dbOptions.debug = options.debug; + return await getCookiesFromChromeSqliteDb(dbOptions, origins, allowlistNames, decrypt); +} +//# sourceMappingURL=chromeSqliteWindows.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js.map new file mode 100644 index 0000000..b99dfe2 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromeSqliteWindows.js.map @@ -0,0 +1 @@ +{"version":3,"file":"chromeSqliteWindows.js","sourceRoot":"","sources":["../../src/providers/chromeSqliteWindows.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,mCAAmC,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACtD,OAAwE,EACxE,OAAiB,EACjB,cAAkC;IAElC,MAAM,WAAW,GAAsD;QACtE,sBAAsB,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC;KAClE,CAAC;IACF,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACzE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;IACzE,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,oCAAoC,CAAC,EAAE,CAAC;IAC1E,CAAC;IAED,4FAA4F;IAC5F,2FAA2F;IAC3F,MAAM,SAAS,GAAG,MAAM,2BAA2B,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC3E,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IACrD,CAAC;IAED,MAAM,OAAO,GAAG,CACf,cAA0B,EAC1B,IAAkC,EAClB,EAAE;QAClB,OAAO,mCAAmC,CAAC,cAAc,EAAE,SAAS,CAAC,KAAK,EAAE;YAC3E,eAAe,EAAE,IAAI,CAAC,eAAe;SACrC,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,SAAS,GACd;QACC,MAAM;KACN,CAAC;IACH,IAAI,OAAO,CAAC,OAAO;QAAE,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACzD,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;QAAE,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAC5F,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAEjE,OAAO,MAAM,4BAA4B,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AACxF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts new file mode 100644 index 0000000..010ddea --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts @@ -0,0 +1,5 @@ +export declare function resolveChromiumCookiesDbLinux(options: { + configDirName: string; + profile?: string; +}): string | null; +//# sourceMappingURL=linuxPaths.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts.map new file mode 100644 index 0000000..eaf0cb5 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"linuxPaths.d.ts","sourceRoot":"","sources":["../../../src/providers/chromium/linuxPaths.ts"],"names":[],"mappings":"AAMA,wBAAgB,6BAA6B,CAAC,OAAO,EAAE;IACtD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,GAAG,IAAI,CA0BhB"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js new file mode 100644 index 0000000..5aa9d40 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js @@ -0,0 +1,33 @@ +import { existsSync } from 'node:fs'; +import { homedir } from 'node:os'; +import path from 'node:path'; +import { expandPath, looksLikePath } from './paths.js'; +export function resolveChromiumCookiesDbLinux(options) { + const home = homedir(); + // biome-ignore lint/complexity/useLiteralKeys: process.env is an index signature under strict TS. + const configHome = process.env['XDG_CONFIG_HOME']?.trim() || path.join(home, '.config'); + const root = path.join(configHome, options.configDirName); + if (options.profile && looksLikePath(options.profile)) { + const candidate = expandPath(options.profile); + if (candidate.endsWith('Cookies') && existsSync(candidate)) + return candidate; + const direct = path.join(candidate, 'Cookies'); + if (existsSync(direct)) + return direct; + const network = path.join(candidate, 'Network', 'Cookies'); + if (existsSync(network)) + return network; + return null; + } + const profileDir = options.profile && options.profile.trim().length > 0 ? options.profile.trim() : 'Default'; + const candidates = [ + path.join(root, profileDir, 'Cookies'), + path.join(root, profileDir, 'Network', 'Cookies'), + ]; + for (const candidate of candidates) { + if (existsSync(candidate)) + return candidate; + } + return null; +} +//# sourceMappingURL=linuxPaths.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js.map new file mode 100644 index 0000000..0c3503b --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/linuxPaths.js.map @@ -0,0 +1 @@ +{"version":3,"file":"linuxPaths.js","sourceRoot":"","sources":["../../../src/providers/chromium/linuxPaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,UAAU,6BAA6B,CAAC,OAG7C;IACA,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,kGAAkG;IAClG,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1D,IAAI,OAAO,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC/C,IAAI,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3D,IAAI,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QACxC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,UAAU,GACf,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3F,MAAM,UAAU,GAAG;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC;KACjD,CAAC;IACF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts new file mode 100644 index 0000000..ed5ea8a --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts @@ -0,0 +1,24 @@ +export declare function readKeychainGenericPassword(options: { + account: string; + service: string; + timeoutMs: number; +}): Promise<{ + ok: true; + password: string; +} | { + ok: false; + error: string; +}>; +export declare function readKeychainGenericPasswordFirst(options: { + account: string; + services: string[]; + timeoutMs: number; + label: string; +}): Promise<{ + ok: true; + password: string; +} | { + ok: false; + error: string; +}>; +//# sourceMappingURL=macosKeychain.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts.map new file mode 100644 index 0000000..a0a20b3 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"macosKeychain.d.ts","sourceRoot":"","sources":["../../../src/providers/chromium/macosKeychain.ts"],"names":[],"mappings":"AAEA,wBAAsB,2BAA2B,CAAC,OAAO,EAAE;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAczE;AAED,wBAAsB,gCAAgC,CAAC,OAAO,EAAE;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBzE"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js new file mode 100644 index 0000000..275a157 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js @@ -0,0 +1,30 @@ +import { execCapture } from '../../util/exec.js'; +export async function readKeychainGenericPassword(options) { + const res = await execCapture('security', ['find-generic-password', '-w', '-a', options.account, '-s', options.service], { timeoutMs: options.timeoutMs }); + if (res.code === 0) { + const password = res.stdout.trim(); + return { ok: true, password }; + } + return { + ok: false, + error: `${res.stderr.trim() || `exit ${res.code}`}`, + }; +} +export async function readKeychainGenericPasswordFirst(options) { + let lastError = null; + for (const service of options.services) { + const r = await readKeychainGenericPassword({ + account: options.account, + service, + timeoutMs: options.timeoutMs, + }); + if (r.ok) + return r; + lastError = r.error; + } + return { + ok: false, + error: `Failed to read macOS Keychain (${options.label}): ${lastError ?? 'permission denied / keychain locked / entry missing.'}`, + }; +} +//# sourceMappingURL=macosKeychain.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js.map new file mode 100644 index 0000000..be7edb8 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/macosKeychain.js.map @@ -0,0 +1 @@ +{"version":3,"file":"macosKeychain.js","sourceRoot":"","sources":["../../../src/providers/chromium/macosKeychain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,OAIjD;IACA,MAAM,GAAG,GAAG,MAAM,WAAW,CAC5B,UAAU,EACV,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EAC7E,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAChC,CAAC;IACF,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO;QACN,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,QAAQ,GAAG,CAAC,IAAI,EAAE,EAAE;KACnD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gCAAgC,CAAC,OAKtD;IACA,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,MAAM,2BAA2B,CAAC;YAC3C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO;YACP,SAAS,EAAE,OAAO,CAAC,SAAS;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC;QACnB,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC;IACrB,CAAC;IAED,OAAO;QACN,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,kCAAkC,OAAO,CAAC,KAAK,MAAM,SAAS,IAAI,sDAAsD,EAAE;KACjI,CAAC;AACH,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts new file mode 100644 index 0000000..8782384 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts @@ -0,0 +1,11 @@ +export declare function looksLikePath(value: string): boolean; +export declare function expandPath(input: string): string; +export declare function safeStat(candidate: string): { + isFile: () => boolean; + isDirectory: () => boolean; +} | null; +export declare function resolveCookiesDbFromProfileOrRoots(options: { + profile?: string; + roots: string[]; +}): string | null; +//# sourceMappingURL=paths.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts.map new file mode 100644 index 0000000..2142f97 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/providers/chromium/paths.ts"],"names":[],"mappings":"AAIA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wBAAgB,QAAQ,CACvB,SAAS,EAAE,MAAM,GACf;IAAE,MAAM,EAAE,MAAM,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,OAAO,CAAA;CAAE,GAAG,IAAI,CAM9D;AAED,wBAAgB,kCAAkC,CAAC,OAAO,EAAE;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CAChB,GAAG,MAAM,GAAG,IAAI,CAuBhB"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js new file mode 100644 index 0000000..97e9c69 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js @@ -0,0 +1,43 @@ +import { existsSync, statSync } from 'node:fs'; +import { homedir } from 'node:os'; +import path from 'node:path'; +export function looksLikePath(value) { + return value.includes('/') || value.includes('\\'); +} +export function expandPath(input) { + if (input.startsWith('~/')) + return path.join(homedir(), input.slice(2)); + return path.isAbsolute(input) ? input : path.resolve(process.cwd(), input); +} +export function safeStat(candidate) { + try { + return statSync(candidate); + } + catch { + return null; + } +} +export function resolveCookiesDbFromProfileOrRoots(options) { + const candidates = []; + if (options.profile && looksLikePath(options.profile)) { + const expanded = expandPath(options.profile); + const stat = safeStat(expanded); + if (stat?.isFile()) + return expanded; + candidates.push(path.join(expanded, 'Cookies')); + candidates.push(path.join(expanded, 'Network', 'Cookies')); + } + else { + const profileDir = options.profile && options.profile.trim().length > 0 ? options.profile.trim() : 'Default'; + for (const root of options.roots) { + candidates.push(path.join(root, profileDir, 'Cookies')); + candidates.push(path.join(root, profileDir, 'Network', 'Cookies')); + } + } + for (const candidate of candidates) { + if (existsSync(candidate)) + return candidate; + } + return null; +} +//# sourceMappingURL=paths.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js.map new file mode 100644 index 0000000..91745ce --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/paths.js.map @@ -0,0 +1 @@ +{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/providers/chromium/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,aAAa,CAAC,KAAa;IAC1C,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,QAAQ,CACvB,SAAiB;IAEjB,IAAI,CAAC;QACJ,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,OAGlD;IACA,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,IAAI,OAAO,CAAC,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,IAAI,EAAE,MAAM,EAAE;YAAE,OAAO,QAAQ,CAAC;QACpC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;QAChD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACP,MAAM,UAAU,GACf,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3F,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;YACxD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;QACpE,CAAC;IACF,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC7C,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts new file mode 100644 index 0000000..e69729d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts @@ -0,0 +1,8 @@ +export declare function getWindowsChromiumMasterKey(userDataDir: string, label: string): Promise<{ + ok: true; + value: Buffer; +} | { + ok: false; + error: string; +}>; +//# sourceMappingURL=windowsMasterKey.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts.map new file mode 100644 index 0000000..df19c35 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"windowsMasterKey.d.ts","sourceRoot":"","sources":["../../../src/providers/chromium/windowsMasterKey.ts"],"names":[],"mappings":"AAKA,wBAAsB,2BAA2B,CAChD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GACX,OAAO,CACP;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3B;IACA,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACb,CACH,CAsCA"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js new file mode 100644 index 0000000..33453b1 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js @@ -0,0 +1,41 @@ +import { existsSync, readFileSync } from 'node:fs'; +import path from 'node:path'; +import { dpapiUnprotect } from '../chromeSqlite/windowsDpapi.js'; +export async function getWindowsChromiumMasterKey(userDataDir, label) { + const localStatePath = path.join(userDataDir, 'Local State'); + if (!existsSync(localStatePath)) { + return { ok: false, error: `${label} Local State file not found.` }; + } + let encryptedKeyB64 = null; + try { + const raw = readFileSync(localStatePath, 'utf8'); + const parsed = JSON.parse(raw); + encryptedKeyB64 = + typeof parsed.os_crypt?.encrypted_key === 'string' ? parsed.os_crypt.encrypted_key : null; + } + catch (error) { + return { + ok: false, + error: `Failed to parse ${label} Local State: ${error instanceof Error ? error.message : String(error)}`, + }; + } + if (!encryptedKeyB64) + return { ok: false, error: `${label} Local State missing os_crypt.encrypted_key.` }; + let encryptedKey; + try { + encryptedKey = Buffer.from(encryptedKeyB64, 'base64'); + } + catch { + return { ok: false, error: `${label} Local State contains an invalid encrypted_key.` }; + } + const prefix = Buffer.from('DPAPI', 'utf8'); + if (!encryptedKey.subarray(0, prefix.length).equals(prefix)) { + return { ok: false, error: `${label} encrypted_key does not start with DPAPI prefix.` }; + } + const unprotected = await dpapiUnprotect(encryptedKey.subarray(prefix.length)); + if (!unprotected.ok) { + return { ok: false, error: `DPAPI decrypt failed: ${unprotected.error}` }; + } + return { ok: true, value: unprotected.value }; +} +//# sourceMappingURL=windowsMasterKey.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js.map new file mode 100644 index 0000000..3a43096 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsMasterKey.js.map @@ -0,0 +1 @@ +{"version":3,"file":"windowsMasterKey.js","sourceRoot":"","sources":["../../../src/providers/chromium/windowsMasterKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAChD,WAAmB,EACnB,KAAa;IAQb,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,8BAA8B,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA+C,CAAC;QAC7E,eAAe;YACd,OAAO,MAAM,CAAC,QAAQ,EAAE,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO;YACN,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,mBAAmB,KAAK,iBAAiB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SACxG,CAAC;IACH,CAAC;IAED,IAAI,CAAC,eAAe;QACnB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,8CAA8C,EAAE,CAAC;IAErF,IAAI,YAAoB,CAAC;IACzB,IAAI,CAAC;QACJ,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,iDAAiD,EAAE,CAAC;IACxF,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,kDAAkD,EAAE,CAAC;IACzF,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC;AAC/C,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts new file mode 100644 index 0000000..66b0d07 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts @@ -0,0 +1,8 @@ +export declare function resolveChromiumPathsWindows(options: { + localAppDataVendorPath: string; + profile?: string; +}): { + dbPath: string | null; + userDataDir: string | null; +}; +//# sourceMappingURL=windowsPaths.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts.map new file mode 100644 index 0000000..52d69d9 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"windowsPaths.d.ts","sourceRoot":"","sources":["../../../src/providers/chromium/windowsPaths.ts"],"names":[],"mappings":"AAKA,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACpD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAmCxD"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js new file mode 100644 index 0000000..c073461 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js @@ -0,0 +1,53 @@ +import { existsSync } from 'node:fs'; +import path from 'node:path'; +import { expandPath, looksLikePath } from './paths.js'; +export function resolveChromiumPathsWindows(options) { + // biome-ignore lint/complexity/useLiteralKeys: process.env is an index signature under strict TS. + const localAppData = process.env['LOCALAPPDATA']; + const root = localAppData ? path.join(localAppData, options.localAppDataVendorPath) : null; + if (options.profile && looksLikePath(options.profile)) { + const expanded = expandPath(options.profile); + const candidates = expanded.endsWith('Cookies') + ? [expanded] + : [ + path.join(expanded, 'Network', 'Cookies'), + path.join(expanded, 'Cookies'), + path.join(expanded, 'Default', 'Network', 'Cookies'), + ]; + for (const candidate of candidates) { + if (!existsSync(candidate)) + continue; + const userDataDir = findUserDataDir(candidate); + return { dbPath: candidate, userDataDir }; + } + if (existsSync(path.join(expanded, 'Local State'))) { + return { dbPath: null, userDataDir: expanded }; + } + } + const profileDir = options.profile && options.profile.trim().length > 0 ? options.profile.trim() : 'Default'; + if (!root) + return { dbPath: null, userDataDir: null }; + const candidates = [ + path.join(root, profileDir, 'Network', 'Cookies'), + path.join(root, profileDir, 'Cookies'), + ]; + for (const candidate of candidates) { + if (existsSync(candidate)) + return { dbPath: candidate, userDataDir: root }; + } + return { dbPath: null, userDataDir: root }; +} +function findUserDataDir(cookiesDbPath) { + let current = path.dirname(cookiesDbPath); + for (let i = 0; i < 6; i += 1) { + const localState = path.join(current, 'Local State'); + if (existsSync(localState)) + return current; + const next = path.dirname(current); + if (next === current) + break; + current = next; + } + return null; +} +//# sourceMappingURL=windowsPaths.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js.map new file mode 100644 index 0000000..c526c58 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/chromium/windowsPaths.js.map @@ -0,0 +1 @@ +{"version":3,"file":"windowsPaths.js","sourceRoot":"","sources":["../../../src/providers/chromium/windowsPaths.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts new file mode 100644 index 0000000..ea43447 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts @@ -0,0 +1,8 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromEdge(options: { + profile?: string; + timeoutMs?: number; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=edge.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts.map new file mode 100644 index 0000000..7d5e0f9 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"edge.d.ts","sourceRoot":"","sources":["../../src/providers/edge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK5D,wBAAsB,kBAAkB,CACvC,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5F,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CA0B3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js new file mode 100644 index 0000000..c0f84c5 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js @@ -0,0 +1,27 @@ +import { getCookiesFromEdgeSqliteLinux } from './edgeSqliteLinux.js'; +import { getCookiesFromEdgeSqliteMac } from './edgeSqliteMac.js'; +import { getCookiesFromEdgeSqliteWindows } from './edgeSqliteWindows.js'; +export async function getCookiesFromEdge(options, origins, allowlistNames) { + const warnings = []; + // Platform dispatch only. All real logic lives in the per-OS providers. + if (process.platform === 'darwin') { + const r = await getCookiesFromEdgeSqliteMac(options, origins, allowlistNames); + warnings.push(...r.warnings); + const cookies = r.cookies; + return { cookies, warnings }; + } + if (process.platform === 'linux') { + const r = await getCookiesFromEdgeSqliteLinux(options, origins, allowlistNames); + warnings.push(...r.warnings); + const cookies = r.cookies; + return { cookies, warnings }; + } + if (process.platform === 'win32') { + const r = await getCookiesFromEdgeSqliteWindows(options, origins, allowlistNames); + warnings.push(...r.warnings); + const cookies = r.cookies; + return { cookies, warnings }; + } + return { cookies: [], warnings }; +} +//# sourceMappingURL=edge.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js.map new file mode 100644 index 0000000..d5dc206 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edge.js.map @@ -0,0 +1 @@ +{"version":3,"file":"edge.js","sourceRoot":"","sources":["../../src/providers/edge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,OAA4F,EAC5F,OAAiB,EACjB,cAAkC;IAElC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,wEAAwE;IACxE,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,MAAM,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QAC9E,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAa,CAAC,CAAC,OAAO,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,MAAM,6BAA6B,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QAChF,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAa,CAAC,CAAC,OAAO,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,MAAM,+BAA+B,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QAClF,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAa,CAAC,CAAC,OAAO,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts new file mode 100644 index 0000000..b5ec216 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts @@ -0,0 +1,7 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromEdgeSqliteLinux(options: { + profile?: string; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=edgeSqliteLinux.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts.map new file mode 100644 index 0000000..09b6e0f --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"edgeSqliteLinux.d.ts","sourceRoot":"","sources":["../../src/providers/edgeSqliteLinux.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASpD,wBAAsB,6BAA6B,CAClD,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACxE,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAoD3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js new file mode 100644 index 0000000..5f42452 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js @@ -0,0 +1,53 @@ +import { decryptChromiumAes128CbcCookieValue, deriveAes128CbcKeyFromPassword, } from './chromeSqlite/crypto.js'; +import { getLinuxChromiumSafeStoragePassword } from './chromeSqlite/linuxKeyring.js'; +import { getCookiesFromChromeSqliteDb } from './chromeSqlite/shared.js'; +import { resolveChromiumCookiesDbLinux } from './chromium/linuxPaths.js'; +export async function getCookiesFromEdgeSqliteLinux(options, origins, allowlistNames) { + const args = { + configDirName: 'microsoft-edge', + }; + if (options.profile !== undefined) + args.profile = options.profile; + const dbPath = resolveChromiumCookiesDbLinux(args); + if (!dbPath) { + return { cookies: [], warnings: ['Edge cookies database not found.'] }; + } + const { password, warnings: keyringWarnings } = await getLinuxChromiumSafeStoragePassword({ + app: 'edge', + }); + // Linux uses multiple schemes depending on distro/keyring availability. + // - v10 often uses the hard-coded "peanuts" password + // - v11 uses " Safe Storage" from the keyring (may be empty/unavailable) + const v10Key = deriveAes128CbcKeyFromPassword('peanuts', { iterations: 1 }); + const emptyKey = deriveAes128CbcKeyFromPassword('', { iterations: 1 }); + const v11Key = deriveAes128CbcKeyFromPassword(password, { iterations: 1 }); + const decrypt = (encryptedValue, opts) => { + const prefix = Buffer.from(encryptedValue).subarray(0, 3).toString('utf8'); + if (prefix === 'v10') { + return decryptChromiumAes128CbcCookieValue(encryptedValue, [v10Key, emptyKey], { + stripHashPrefix: opts.stripHashPrefix, + treatUnknownPrefixAsPlaintext: false, + }); + } + if (prefix === 'v11') { + return decryptChromiumAes128CbcCookieValue(encryptedValue, [v11Key, emptyKey], { + stripHashPrefix: opts.stripHashPrefix, + treatUnknownPrefixAsPlaintext: false, + }); + } + return null; + }; + const dbOptions = { + dbPath, + }; + if (options.profile) + dbOptions.profile = options.profile; + if (options.includeExpired !== undefined) + dbOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + dbOptions.debug = options.debug; + const result = await getCookiesFromChromeSqliteDb(dbOptions, origins, allowlistNames, decrypt); + result.warnings.unshift(...keyringWarnings); + return result; +} +//# sourceMappingURL=edgeSqliteLinux.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js.map new file mode 100644 index 0000000..37a33a2 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteLinux.js.map @@ -0,0 +1 @@ +{"version":3,"file":"edgeSqliteLinux.js","sourceRoot":"","sources":["../../src/providers/edgeSqliteLinux.ts"],"names":[],"mappings":"AACA,OAAO,EACN,mCAAmC,EACnC,8BAA8B,GAC9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAClD,OAAwE,EACxE,OAAiB,EACjB,cAAkC;IAElC,MAAM,IAAI,GAAwD;QACjE,aAAa,EAAE,gBAAgB;KAC/B,CAAC;IACF,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAClE,MAAM,MAAM,GAAG,6BAA6B,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,kCAAkC,CAAC,EAAE,CAAC;IACxE,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,MAAM,mCAAmC,CAAC;QACzF,GAAG,EAAE,MAAM;KACX,CAAC,CAAC;IAEH,wEAAwE;IACxE,qDAAqD;IACrD,kFAAkF;IAClF,MAAM,MAAM,GAAG,8BAA8B,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,8BAA8B,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,8BAA8B,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAE3E,MAAM,OAAO,GAAG,CACf,cAA0B,EAC1B,IAAkC,EAClB,EAAE;QAClB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3E,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACtB,OAAO,mCAAmC,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;gBAC9E,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,6BAA6B,EAAE,KAAK;aACpC,CAAC,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACtB,OAAO,mCAAmC,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;gBAC9E,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,6BAA6B,EAAE,KAAK;aACpC,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;IAEF,MAAM,SAAS,GACd;QACC,MAAM;KACN,CAAC;IACH,IAAI,OAAO,CAAC,OAAO;QAAE,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACzD,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;QAAE,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAC5F,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAEjE,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAC/F,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC;AACf,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts new file mode 100644 index 0000000..4ae4074 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts @@ -0,0 +1,8 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromEdgeSqliteMac(options: { + profile?: string; + includeExpired?: boolean; + debug?: boolean; + timeoutMs?: number; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=edgeSqliteMac.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts.map new file mode 100644 index 0000000..0d8809d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"edgeSqliteMac.d.ts","sourceRoot":"","sources":["../../src/providers/edgeSqliteMac.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASpD,wBAAsB,2BAA2B,CAChD,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5F,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CA8C3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js new file mode 100644 index 0000000..5876aee --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js @@ -0,0 +1,60 @@ +import { homedir } from 'node:os'; +import path from 'node:path'; +import { decryptChromiumAes128CbcCookieValue, deriveAes128CbcKeyFromPassword, } from './chromeSqlite/crypto.js'; +import { getCookiesFromChromeSqliteDb } from './chromeSqlite/shared.js'; +import { readKeychainGenericPasswordFirst } from './chromium/macosKeychain.js'; +import { resolveCookiesDbFromProfileOrRoots } from './chromium/paths.js'; +export async function getCookiesFromEdgeSqliteMac(options, origins, allowlistNames) { + const dbPath = resolveEdgeCookiesDb(options.profile); + if (!dbPath) { + return { cookies: [], warnings: ['Edge cookies database not found.'] }; + } + const warnings = []; + // On macOS, Edge stores its "Safe Storage" secret in Keychain (same scheme as Chrome). + // `security find-generic-password` is stable and avoids any native Node keychain modules. + const passwordResult = await readKeychainGenericPasswordFirst({ + account: 'Microsoft Edge', + services: ['Microsoft Edge Safe Storage', 'Microsoft Edge'], + timeoutMs: options.timeoutMs ?? 3_000, + label: 'Microsoft Edge Safe Storage', + }); + if (!passwordResult.ok) { + warnings.push(passwordResult.error); + return { cookies: [], warnings }; + } + const edgePassword = passwordResult.password.trim(); + if (!edgePassword) { + warnings.push('macOS Keychain returned an empty Microsoft Edge Safe Storage password.'); + return { cookies: [], warnings }; + } + // Chromium uses PBKDF2(password, "saltysalt", 1003, 16, sha1) for AES-128-CBC cookie values on macOS. + const key = deriveAes128CbcKeyFromPassword(edgePassword, { iterations: 1003 }); + const decrypt = (encryptedValue, opts) => decryptChromiumAes128CbcCookieValue(encryptedValue, [key], { + stripHashPrefix: opts.stripHashPrefix, + treatUnknownPrefixAsPlaintext: true, + }); + const dbOptions = { + dbPath, + }; + if (options.profile) + dbOptions.profile = options.profile; + if (options.includeExpired !== undefined) + dbOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + dbOptions.debug = options.debug; + const result = await getCookiesFromChromeSqliteDb(dbOptions, origins, allowlistNames, decrypt); + result.warnings.unshift(...warnings); + return result; +} +function resolveEdgeCookiesDb(profile) { + const home = homedir(); + /* c8 ignore next */ + const roots = process.platform === 'darwin' + ? [path.join(home, 'Library', 'Application Support', 'Microsoft Edge')] + : []; + const args = { roots }; + if (profile !== undefined) + args.profile = profile; + return resolveCookiesDbFromProfileOrRoots(args); +} +//# sourceMappingURL=edgeSqliteMac.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js.map new file mode 100644 index 0000000..f363f01 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteMac.js.map @@ -0,0 +1 @@ +{"version":3,"file":"edgeSqliteMac.js","sourceRoot":"","sources":["../../src/providers/edgeSqliteMac.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts new file mode 100644 index 0000000..3e06bd9 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts @@ -0,0 +1,7 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromEdgeSqliteWindows(options: { + profile?: string; + includeExpired?: boolean; + debug?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=edgeSqliteWindows.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts.map new file mode 100644 index 0000000..3751b35 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"edgeSqliteWindows.d.ts","sourceRoot":"","sources":["../../src/providers/edgeSqliteWindows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD,wBAAsB,+BAA+B,CACpD,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACxE,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAmC3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js new file mode 100644 index 0000000..bdf7284 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js @@ -0,0 +1,38 @@ +import path from 'node:path'; +import { decryptChromiumAes256GcmCookieValue } from './chromeSqlite/crypto.js'; +import { getCookiesFromChromeSqliteDb } from './chromeSqlite/shared.js'; +import { getWindowsChromiumMasterKey } from './chromium/windowsMasterKey.js'; +import { resolveChromiumPathsWindows } from './chromium/windowsPaths.js'; +export async function getCookiesFromEdgeSqliteWindows(options, origins, allowlistNames) { + const resolveArgs = { + localAppDataVendorPath: path.join('Microsoft', 'Edge', 'User Data'), + }; + if (options.profile !== undefined) + resolveArgs.profile = options.profile; + const { dbPath, userDataDir } = resolveChromiumPathsWindows(resolveArgs); + if (!dbPath || !userDataDir) { + return { cookies: [], warnings: ['Edge cookies database not found.'] }; + } + // On Windows, Edge stores an AES key in `Local State` encrypted with DPAPI (CurrentUser). + // That master key is then used for AES-256-GCM cookie values (`v10`/`v11`/`v20` prefixes). + const masterKey = await getWindowsChromiumMasterKey(userDataDir, 'Edge'); + if (!masterKey.ok) { + return { cookies: [], warnings: [masterKey.error] }; + } + const decrypt = (encryptedValue, opts) => { + return decryptChromiumAes256GcmCookieValue(encryptedValue, masterKey.value, { + stripHashPrefix: opts.stripHashPrefix, + }); + }; + const dbOptions = { + dbPath, + }; + if (options.profile) + dbOptions.profile = options.profile; + if (options.includeExpired !== undefined) + dbOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + dbOptions.debug = options.debug; + return await getCookiesFromChromeSqliteDb(dbOptions, origins, allowlistNames, decrypt); +} +//# sourceMappingURL=edgeSqliteWindows.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js.map new file mode 100644 index 0000000..3e63db4 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/edgeSqliteWindows.js.map @@ -0,0 +1 @@ +{"version":3,"file":"edgeSqliteWindows.js","sourceRoot":"","sources":["../../src/providers/edgeSqliteWindows.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,mCAAmC,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACpD,OAAwE,EACxE,OAAiB,EACjB,cAAkC;IAElC,MAAM,WAAW,GAAsD;QACtE,sBAAsB,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC;KACnE,CAAC;IACF,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACzE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,2BAA2B,CAAC,WAAW,CAAC,CAAC;IACzE,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,kCAAkC,CAAC,EAAE,CAAC;IACxE,CAAC;IAED,0FAA0F;IAC1F,2FAA2F;IAC3F,MAAM,SAAS,GAAG,MAAM,2BAA2B,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACzE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;IACrD,CAAC;IAED,MAAM,OAAO,GAAG,CACf,cAA0B,EAC1B,IAAkC,EAClB,EAAE;QAClB,OAAO,mCAAmC,CAAC,cAAc,EAAE,SAAS,CAAC,KAAK,EAAE;YAC3E,eAAe,EAAE,IAAI,CAAC,eAAe;SACrC,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,SAAS,GACd;QACC,MAAM;KACN,CAAC;IACH,IAAI,OAAO,CAAC,OAAO;QAAE,SAAS,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACzD,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;QAAE,SAAS,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAC5F,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAEjE,OAAO,MAAM,4BAA4B,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AACxF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts new file mode 100644 index 0000000..4b1c6c8 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts @@ -0,0 +1,6 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromFirefox(options: { + profile?: string; + includeExpired?: boolean; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=firefoxSqlite.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts.map new file mode 100644 index 0000000..9a51b2d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"firefoxSqlite.d.ts","sourceRoot":"","sources":["../../src/providers/firefoxSqlite.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAA0B,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK5E,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,EACvD,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAmD3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js new file mode 100644 index 0000000..6370263 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js @@ -0,0 +1,257 @@ +import { copyFileSync, existsSync, mkdtempSync, readdirSync, rmSync } from 'node:fs'; +import { homedir, tmpdir } from 'node:os'; +import path from 'node:path'; +import { hostMatchesCookieDomain } from '../util/hostMatch.js'; +import { importNodeSqlite } from '../util/nodeSqlite.js'; +import { isBunRuntime } from '../util/runtime.js'; +export async function getCookiesFromFirefox(options, origins, allowlistNames) { + const warnings = []; + const dbPath = resolveFirefoxCookiesDb(options.profile); + if (!dbPath) { + warnings.push('Firefox cookies database not found.'); + return { cookies: [], warnings }; + } + const tempDir = mkdtempSync(path.join(tmpdir(), 'sweet-cookie-firefox-')); + const tempDbPath = path.join(tempDir, 'cookies.sqlite'); + try { + copyFileSync(dbPath, tempDbPath); + copySidecar(dbPath, `${tempDbPath}-wal`, '-wal'); + copySidecar(dbPath, `${tempDbPath}-shm`, '-shm'); + } + catch (error) { + rmSync(tempDir, { recursive: true, force: true }); + warnings.push(`Failed to copy Firefox cookie DB: ${error instanceof Error ? error.message : String(error)}`); + return { cookies: [], warnings }; + } + const hosts = origins.map((o) => new URL(o).hostname); + const now = Math.floor(Date.now() / 1000); + const where = buildHostWhereClause(hosts); + const expiryClause = options.includeExpired ? '' : ` AND (expiry = 0 OR expiry > ${now})`; + const sql = `SELECT name, value, host, path, expiry, isSecure, isHttpOnly, sameSite ` + + `FROM moz_cookies WHERE (${where})${expiryClause} ORDER BY expiry DESC;`; + try { + if (isBunRuntime()) { + const bunResult = await queryFirefoxCookiesWithBunSqlite(tempDbPath, sql); + if (!bunResult.ok) { + warnings.push(`bun:sqlite failed reading Firefox cookies: ${bunResult.error}`); + return { cookies: [], warnings }; + } + const cookies = collectFirefoxCookiesFromRows(bunResult.rows, options, hosts, allowlistNames); + return { cookies: dedupeCookies(cookies), warnings }; + } + const nodeResult = await queryFirefoxCookiesWithNodeSqlite(tempDbPath, sql); + if (!nodeResult.ok) { + warnings.push(`node:sqlite failed reading Firefox cookies: ${nodeResult.error}`); + return { cookies: [], warnings }; + } + const cookies = collectFirefoxCookiesFromRows(nodeResult.rows, options, hosts, allowlistNames); + return { cookies: dedupeCookies(cookies), warnings }; + } + finally { + rmSync(tempDir, { recursive: true, force: true }); + } +} +async function queryFirefoxCookiesWithNodeSqlite(dbPath, sql) { + try { + const { DatabaseSync } = await importNodeSqlite(); + const db = new DatabaseSync(dbPath, { readOnly: true }); + try { + const rows = db.prepare(sql).all(); + return { ok: true, rows }; + } + finally { + db.close(); + } + } + catch (error) { + return { ok: false, error: error instanceof Error ? error.message : String(error) }; + } +} +async function queryFirefoxCookiesWithBunSqlite(dbPath, sql) { + try { + const { Database } = await import('bun:sqlite'); + const db = new Database(dbPath, { readonly: true }); + try { + const rows = db.query(sql).all(); + return { ok: true, rows }; + } + finally { + db.close(); + } + } + catch (error) { + return { ok: false, error: error instanceof Error ? error.message : String(error) }; + } +} +function collectFirefoxCookiesFromRows(rows, options, hosts, allowlistNames) { + const now = Math.floor(Date.now() / 1000); + const cookies = []; + for (const row of rows) { + const name = typeof row.name === 'string' ? row.name : null; + const value = typeof row.value === 'string' ? row.value : null; + const host = typeof row.host === 'string' ? row.host : null; + const cookiePath = typeof row.path === 'string' ? row.path : ''; + if (!name || value === null || !host) + continue; + if (allowlistNames && allowlistNames.size > 0 && !allowlistNames.has(name)) + continue; + if (!hostMatchesAny(hosts, host)) + continue; + const expiryText = typeof row.expiry === 'number' + ? String(row.expiry) + : typeof row.expiry === 'string' + ? row.expiry + : undefined; + const expires = normalizeFirefoxExpiry(expiryText); + if (!options.includeExpired && expires && expires < now) + continue; + const isSecure = row.isSecure === 1 || row.isSecure === '1' || row.isSecure === true; + const isHttpOnly = row.isHttpOnly === 1 || row.isHttpOnly === '1' || row.isHttpOnly === true; + const cookie = { + name, + value, + domain: host.startsWith('.') ? host.slice(1) : host, + path: cookiePath || '/', + secure: isSecure, + httpOnly: isHttpOnly, + }; + if (expires !== undefined) + cookie.expires = expires; + const normalizedSameSite = normalizeFirefoxSameSite(typeof row.sameSite === 'number' + ? String(row.sameSite) + : typeof row.sameSite === 'string' + ? row.sameSite + : undefined); + if (normalizedSameSite !== undefined) + cookie.sameSite = normalizedSameSite; + const source = { browser: 'firefox' }; + if (options.profile) + source.profile = options.profile; + cookie.source = source; + cookies.push(cookie); + } + return cookies; +} +function resolveFirefoxCookiesDb(profile) { + const home = homedir(); + // biome-ignore lint/complexity/useLiteralKeys: process.env is an index signature under strict TS. + const appData = process.env['APPDATA']; + /* c8 ignore next 10 */ + const roots = process.platform === 'darwin' + ? [path.join(home, 'Library', 'Application Support', 'Firefox', 'Profiles')] + : process.platform === 'linux' + ? [path.join(home, '.mozilla', 'firefox')] + : process.platform === 'win32' + ? appData + ? [path.join(appData, 'Mozilla', 'Firefox', 'Profiles')] + : [] + : []; + if (profile && looksLikePath(profile)) { + const candidate = profile.endsWith('cookies.sqlite') + ? profile + : path.join(profile, 'cookies.sqlite'); + return existsSync(candidate) ? candidate : null; + } + for (const root of roots) { + if (!root || !existsSync(root)) + continue; + if (profile) { + const candidate = path.join(root, profile, 'cookies.sqlite'); + if (existsSync(candidate)) + return candidate; + continue; + } + const entries = safeReaddir(root); + const defaultRelease = entries.find((e) => e.includes('default-release')); + const picked = defaultRelease ?? entries[0]; + if (!picked) + continue; + const candidate = path.join(root, picked, 'cookies.sqlite'); + if (existsSync(candidate)) + return candidate; + } + return null; +} +function safeReaddir(dir) { + try { + return readdirSync(dir, { withFileTypes: true }) + .filter((e) => e.isDirectory()) + .map((e) => e.name); + } + catch { + return []; + } +} +function looksLikePath(value) { + return value.includes('/') || value.includes('\\'); +} +function copySidecar(sourceDbPath, target, suffix) { + const sidecar = `${sourceDbPath}${suffix}`; + if (!existsSync(sidecar)) + return; + try { + copyFileSync(sidecar, target); + } + catch { + // ignore + } +} +function buildHostWhereClause(hosts) { + const clauses = []; + for (const host of hosts) { + const escaped = sqlLiteral(host); + const escapedDot = sqlLiteral(`.${host}`); + const escapedLike = sqlLiteral(`%.${host}`); + clauses.push(`host = ${escaped}`); + clauses.push(`host = ${escapedDot}`); + clauses.push(`host LIKE ${escapedLike}`); + } + return clauses.length ? clauses.join(' OR ') : '1=0'; +} +function sqlLiteral(value) { + const escaped = value.replaceAll("'", "''"); + return `'${escaped}'`; +} +function normalizeFirefoxExpiry(expiry) { + if (!expiry) + return undefined; + const value = Number.parseInt(expiry, 10); + if (!Number.isFinite(value) || value <= 0) + return undefined; + return value; +} +function normalizeFirefoxSameSite(raw) { + if (!raw) + return undefined; + const value = Number.parseInt(raw, 10); + if (Number.isFinite(value)) { + if (value === 2) + return 'Strict'; + if (value === 1) + return 'Lax'; + if (value === 0) + return 'None'; + } + const normalized = raw.toLowerCase(); + if (normalized === 'strict') + return 'Strict'; + if (normalized === 'lax') + return 'Lax'; + if (normalized === 'none') + return 'None'; + return undefined; +} +function hostMatchesAny(hosts, cookieHost) { + const cookieDomain = cookieHost.startsWith('.') ? cookieHost.slice(1) : cookieHost; + return hosts.some((host) => hostMatchesCookieDomain(host, cookieDomain)); +} +function dedupeCookies(cookies) { + const merged = new Map(); + for (const cookie of cookies) { + const key = `${cookie.name}|${cookie.domain ?? ''}|${cookie.path ?? ''}`; + if (!merged.has(key)) + merged.set(key, cookie); + } + return Array.from(merged.values()); +} +//# sourceMappingURL=firefoxSqlite.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js.map new file mode 100644 index 0000000..35d1c54 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/firefoxSqlite.js.map @@ -0,0 +1 @@ +{"version":3,"file":"firefoxSqlite.js","sourceRoot":"","sources":["../../src/providers/firefoxSqlite.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts new file mode 100644 index 0000000..6799b13 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts @@ -0,0 +1,8 @@ +import type { GetCookiesResult } from '../types.js'; +type InlineSource = { + source: string; + payload: string; +}; +export declare function getCookiesFromInline(inline: InlineSource, origins: string[], allowlistNames: Set | null): Promise; +export {}; +//# sourceMappingURL=inline.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts.map new file mode 100644 index 0000000..4f00506 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../../src/providers/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK5D,KAAK,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,wBAAsB,oBAAoB,CACzC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAkC3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js new file mode 100644 index 0000000..2070fc6 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js @@ -0,0 +1,71 @@ +import { tryDecodeBase64Json } from '../util/base64.js'; +import { readTextFileIfExists } from '../util/fs.js'; +import { hostMatchesCookieDomain } from '../util/hostMatch.js'; +export async function getCookiesFromInline(inline, origins, allowlistNames) { + const warnings = []; + // Inline sources can be: + // - the payload itself (JSON or base64) + // - a file path that contains JSON/base64 + // + // We do a small heuristic: treat `*.json`/`*.base64` and explicit "file" sources as file paths first. + const rawPayload = inline.source.endsWith('file') || + inline.payload.endsWith('.json') || + inline.payload.endsWith('.base64') + ? ((await readTextFileIfExists(inline.payload)) ?? inline.payload) + : inline.payload; + // If it looks like base64, decode it to JSON. Otherwise use it as-is. + const decoded = tryDecodeBase64Json(rawPayload) ?? rawPayload; + const parsed = tryParseCookiePayload(decoded); + if (!parsed) { + return { cookies: [], warnings }; + } + const hostAllow = new Set(origins.map((o) => new URL(o).hostname)); + const cookies = []; + for (const cookie of parsed.cookies) { + if (!cookie?.name) + continue; + if (allowlistNames && allowlistNames.size > 0 && !allowlistNames.has(cookie.name)) + continue; + const domain = cookie.domain ?? (cookie.url ? safeHostnameFromUrl(cookie.url) : undefined); + if (domain && hostAllow.size > 0 && !matchesAnyHost(hostAllow, domain)) + continue; + cookies.push(cookie); + } + return { cookies, warnings }; +} +function tryParseCookiePayload(input) { + const trimmed = input.trim(); + if (!trimmed) + return null; + try { + const parsed = JSON.parse(trimmed); + if (Array.isArray(parsed)) { + return { cookies: parsed }; + } + if (parsed && + typeof parsed === 'object' && + Array.isArray(parsed.cookies)) { + return { cookies: parsed.cookies }; + } + return null; + } + catch { + return null; + } +} +function matchesAnyHost(hosts, cookieDomain) { + for (const host of hosts) { + if (hostMatchesCookieDomain(host, cookieDomain)) + return true; + } + return false; +} +function safeHostnameFromUrl(url) { + try { + return new URL(url).hostname; + } + catch { + return undefined; + } +} +//# sourceMappingURL=inline.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js.map new file mode 100644 index 0000000..80278a8 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/inline.js.map @@ -0,0 +1 @@ +{"version":3,"file":"inline.js","sourceRoot":"","sources":["../../src/providers/inline.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts new file mode 100644 index 0000000..b117cde --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts @@ -0,0 +1,6 @@ +import type { GetCookiesResult } from '../types.js'; +export declare function getCookiesFromSafari(options: { + includeExpired?: boolean; + file?: string; +}, origins: string[], allowlistNames: Set | null): Promise; +//# sourceMappingURL=safariBinaryCookies.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts.map new file mode 100644 index 0000000..14c76c1 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"safariBinaryCookies.d.ts","sourceRoot":"","sources":["../../src/providers/safariBinaryCookies.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAU,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK5D,wBAAsB,oBAAoB,CACzC,OAAO,EAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACpD,OAAO,EAAE,MAAM,EAAE,EACjB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAqC3B"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js new file mode 100644 index 0000000..45602b6 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js @@ -0,0 +1,173 @@ +import { existsSync, readFileSync } from 'node:fs'; +import { homedir } from 'node:os'; +import path from 'node:path'; +import { hostMatchesCookieDomain } from '../util/hostMatch.js'; +const MAC_EPOCH_DELTA_SECONDS = 978_307_200; +export async function getCookiesFromSafari(options, origins, allowlistNames) { + const warnings = []; + if (process.platform !== 'darwin') { + return { cookies: [], warnings }; + } + const cookieFile = options.file ?? resolveSafariBinaryCookiesPath(); + if (!cookieFile) { + warnings.push('Safari Cookies.binarycookies not found.'); + return { cookies: [], warnings }; + } + const hosts = origins.map((o) => new URL(o).hostname); + const now = Math.floor(Date.now() / 1000); + try { + const data = readFileSync(cookieFile); + // Safari's `Cookies.binarycookies` is a small binary container with multiple "pages". + // We decode only the fields we need (name/value/domain/path/flags/expiry). + const parsed = decodeBinaryCookies(data); + const cookies = []; + for (const cookie of parsed) { + if (!cookie.name) + continue; + if (allowlistNames && allowlistNames.size > 0 && !allowlistNames.has(cookie.name)) + continue; + const domain = cookie.domain; + if (!domain) + continue; + if (!hosts.some((h) => hostMatchesCookieDomain(h, domain))) + continue; + if (!options.includeExpired && cookie.expires && cookie.expires < now) + continue; + cookies.push(cookie); + } + return { cookies: dedupeCookies(cookies), warnings }; + } + catch (error) { + warnings.push(`Failed to read Safari cookies: ${error instanceof Error ? error.message : String(error)}`); + return { cookies: [], warnings }; + } +} +function resolveSafariBinaryCookiesPath() { + const home = homedir(); + const candidates = [ + path.join(home, 'Library', 'Cookies', 'Cookies.binarycookies'), + path.join(home, 'Library', 'Containers', 'com.apple.Safari', 'Data', 'Library', 'Cookies', 'Cookies.binarycookies'), + ]; + for (const candidate of candidates) { + if (existsSync(candidate)) + return candidate; + } + return null; +} +function decodeBinaryCookies(buffer) { + if (buffer.length < 8) + return []; + if (buffer.subarray(0, 4).toString('utf8') !== 'cook') + return []; + const pageCount = buffer.readUInt32BE(4); + let cursor = 8; + const pageSizes = []; + for (let i = 0; i < pageCount; i += 1) { + pageSizes.push(buffer.readUInt32BE(cursor)); + cursor += 4; + } + const cookies = []; + for (const pageSize of pageSizes) { + const page = buffer.subarray(cursor, cursor + pageSize); + cursor += pageSize; + cookies.push(...decodePage(page)); + } + return cookies; +} +function decodePage(page) { + if (page.length < 16) + return []; + const header = page.readUInt32BE(0); + if (header !== 0x00000100) + return []; + const cookieCount = page.readUInt32LE(4); + const offsets = []; + let cursor = 8; + for (let i = 0; i < cookieCount; i += 1) { + offsets.push(page.readUInt32LE(cursor)); + cursor += 4; + } + const cookies = []; + for (const offset of offsets) { + const cookie = decodeCookie(page.subarray(offset)); + if (cookie) + cookies.push(cookie); + } + return cookies; +} +function decodeCookie(cookieBuffer) { + if (cookieBuffer.length < 48) + return null; + const size = cookieBuffer.readUInt32LE(0); + if (size < 48 || size > cookieBuffer.length) + return null; + const flagsValue = cookieBuffer.readUInt32LE(8); + const isSecure = (flagsValue & 1) !== 0; + const isHttpOnly = (flagsValue & 4) !== 0; + const urlOffset = cookieBuffer.readUInt32LE(16); + const nameOffset = cookieBuffer.readUInt32LE(20); + const pathOffset = cookieBuffer.readUInt32LE(24); + const valueOffset = cookieBuffer.readUInt32LE(28); + // Safari stores dates as "Mac absolute time" (seconds since 2001-01-01). + const expiration = readDoubleLE(cookieBuffer, 40); + const rawUrl = readCString(cookieBuffer, urlOffset, size); + const name = readCString(cookieBuffer, nameOffset, size); + const cookiePath = readCString(cookieBuffer, pathOffset, size) ?? '/'; + const value = readCString(cookieBuffer, valueOffset, size) ?? ''; + if (!name) + return null; + const domain = rawUrl ? safeHostnameFromUrl(rawUrl) : undefined; + const expires = expiration && expiration > 0 ? Math.round(expiration + MAC_EPOCH_DELTA_SECONDS) : undefined; + const decoded = { + name, + value, + path: cookiePath, + secure: isSecure, + httpOnly: isHttpOnly, + source: { browser: 'safari' }, + }; + if (domain) + decoded.domain = domain; + if (expires !== undefined) + decoded.expires = expires; + return decoded; +} +function readDoubleLE(buffer, offset) { + if (offset + 8 > buffer.length) + return 0; + const slice = buffer.subarray(offset, offset + 8); + return slice.readDoubleLE(0); +} +function readCString(buffer, offset, end) { + if (offset <= 0 || offset >= end) + return null; + let cursor = offset; + while (cursor < end && buffer[cursor] !== 0) + cursor += 1; + if (cursor >= end) + return null; + return buffer.toString('utf8', offset, cursor); +} +function safeHostnameFromUrl(raw) { + try { + const url = raw.includes('://') ? raw : `https://${raw}`; + const parsed = new URL(url); + return parsed.hostname.startsWith('.') ? parsed.hostname.slice(1) : parsed.hostname; + } + catch { + const cleaned = raw.trim(); + if (!cleaned) + return undefined; + return cleaned.startsWith('.') ? cleaned.slice(1) : cleaned; + } +} +function dedupeCookies(cookies) { + const merged = new Map(); + for (const cookie of cookies) { + const key = `${cookie.name}|${cookie.domain ?? ''}|${cookie.path ?? ''}`; + if (!merged.has(key)) + merged.set(key, cookie); + } + return Array.from(merged.values()); +} +//# sourceMappingURL=safariBinaryCookies.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js.map new file mode 100644 index 0000000..b1458b1 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/providers/safariBinaryCookies.js.map @@ -0,0 +1 @@ +{"version":3,"file":"safariBinaryCookies.js","sourceRoot":"","sources":["../../src/providers/safariBinaryCookies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,uBAAuB,GAAG,WAAW,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACzC,OAAoD,EACpD,OAAiB,EACjB,cAAkC;IAElC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,IAAI,8BAA8B,EAAE,CAAC;IACpE,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACzD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE1C,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;QACtC,sFAAsF;QACtF,2EAA2E;QAC3E,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,SAAS;YAC3B,IAAI,cAAc,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC5F,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC7B,IAAI,CAAC,MAAM;gBAAE,SAAS;YACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;gBAAE,SAAS;YACrE,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,GAAG,GAAG;gBAAE,SAAS;YAChF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,QAAQ,CAAC,IAAI,CACZ,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC1F,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;IAClC,CAAC;AACF,CAAC;AAED,SAAS,8BAA8B;IACtC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,UAAU,GAAG;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,uBAAuB,CAAC;QAC9D,IAAI,CAAC,IAAI,CACR,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,MAAM,EACN,SAAS,EACT,SAAS,EACT,uBAAuB,CACvB;KACD,CAAC;IACF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IAC1C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC;IACjE,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,CAAC;IACb,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC;QACxD,MAAM,IAAI,QAAQ,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC/B,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,CAAC;IACb,CAAC;IAED,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,IAAI,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,YAAoB;IACzC,IAAI,YAAY,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,IAAI,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,IAAI,GAAG,EAAE,IAAI,IAAI,GAAG,YAAY,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzD,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAElD,yEAAyE;IACzE,MAAM,UAAU,GAAG,YAAY,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAElD,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC;IACtE,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAEjE,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEhE,MAAM,OAAO,GACZ,UAAU,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE7F,MAAM,OAAO,GAAW;QACvB,IAAI;QACJ,KAAK;QACL,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,MAAM,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE;KAC7B,CAAC;IAEF,IAAI,MAAM;QAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IACpC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;IAErD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,MAAc,EAAE,MAAc;IACnD,IAAI,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,MAAc,EAAE,GAAW;IAC/D,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,MAAM,GAAG,MAAM,CAAC;IACpB,OAAO,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,CAAC,CAAC;IACzD,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAW;IACvC,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO;YAAE,OAAO,SAAS,CAAC;QAC/B,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC7D,CAAC;AACF,CAAC;AAED,SAAS,aAAa,CAAC,OAAiB;IACvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;QACzE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACpC,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts new file mode 100644 index 0000000..f3b0144 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts @@ -0,0 +1,26 @@ +import type { Cookie, CookieHeaderOptions, GetCookiesOptions, GetCookiesResult } from './types.js'; +/** + * Read cookies for a URL from one or more browser backends (and/or inline payloads). + * + * Supported backends: + * - `chrome`: macOS / Windows / Linux (Chromium-based; default discovery targets Google Chrome paths) + * - `edge`: macOS / Windows / Linux (Chromium-based; default discovery targets Microsoft Edge paths) + * - `firefox`: macOS / Windows / Linux + * - `safari`: macOS only (`Cookies.binarycookies`) + * + * Runtime requirements: + * - Node >= 22 (uses `node:sqlite`) or Bun (uses `bun:sqlite`) + * + * The function returns `{ cookies, warnings }`: + * - `cookies`: best-effort results, filtered by `url`/`origins` and optional `names` allowlist + * - `warnings`: non-fatal diagnostics (no raw cookie values) + */ +export declare function getCookies(options: GetCookiesOptions): Promise; +/** + * Convert cookies to an HTTP `Cookie` header value. + * + * This is a helper for typical Node fetch clients / HTTP libraries. + * It does not validate cookie RFC edge cases; it simply joins `name=value` pairs. + */ +export declare function toCookieHeader(cookies: readonly Cookie[], options?: CookieHeaderOptions): string; +//# sourceMappingURL=public.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts.map new file mode 100644 index 0000000..8151fd4 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEX,MAAM,EACN,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAKpB;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2FtF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,GAAE,mBAAwB,GAC/B,MAAM,CAyBR"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js new file mode 100644 index 0000000..716b4ce --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js @@ -0,0 +1,195 @@ +import { getCookiesFromChrome } from './providers/chrome.js'; +import { getCookiesFromEdge } from './providers/edge.js'; +import { getCookiesFromFirefox } from './providers/firefoxSqlite.js'; +import { getCookiesFromInline } from './providers/inline.js'; +import { getCookiesFromSafari } from './providers/safariBinaryCookies.js'; +import { normalizeOrigins } from './util/origins.js'; +const DEFAULT_BROWSERS = ['chrome', 'safari', 'firefox']; +/** + * Read cookies for a URL from one or more browser backends (and/or inline payloads). + * + * Supported backends: + * - `chrome`: macOS / Windows / Linux (Chromium-based; default discovery targets Google Chrome paths) + * - `edge`: macOS / Windows / Linux (Chromium-based; default discovery targets Microsoft Edge paths) + * - `firefox`: macOS / Windows / Linux + * - `safari`: macOS only (`Cookies.binarycookies`) + * + * Runtime requirements: + * - Node >= 22 (uses `node:sqlite`) or Bun (uses `bun:sqlite`) + * + * The function returns `{ cookies, warnings }`: + * - `cookies`: best-effort results, filtered by `url`/`origins` and optional `names` allowlist + * - `warnings`: non-fatal diagnostics (no raw cookie values) + */ +export async function getCookies(options) { + const warnings = []; + const url = options.url; + const origins = normalizeOrigins(url, options.origins); + const names = normalizeNames(options.names); + let browsers; + if (Array.isArray(options.browsers) && options.browsers.length > 0) { + browsers = options.browsers; + } + else { + browsers = parseBrowsersEnv() ?? DEFAULT_BROWSERS; + } + const mode = options.mode ?? parseModeEnv() ?? 'merge'; + const inlineSources = await resolveInlineSources(options); + // Inline sources are the most reliable path (they bypass DB locks + keychain prompts). + // We short-circuit on the first inline source that yields any cookies. + for (const source of inlineSources) { + const inlineResult = await getCookiesFromInline(source, origins, names); + warnings.push(...inlineResult.warnings); + if (inlineResult.cookies.length) { + return { cookies: inlineResult.cookies, warnings }; + } + } + const merged = new Map(); + const tryAdd = (cookie) => { + // Dedupe by name+domain+path (a common stable identity for HTTP cookies). + const domain = cookie.domain ?? ''; + const pathValue = cookie.path ?? ''; + const key = `${cookie.name}|${domain}|${pathValue}`; + if (!merged.has(key)) { + merged.set(key, cookie); + } + }; + for (const browser of browsers) { + let result; + if (browser === 'chrome') { + const chromeOptions = {}; + const chromeProfile = options.chromeProfile ?? options.profile ?? readEnv('SWEET_COOKIE_CHROME_PROFILE'); + if (chromeProfile) + chromeOptions.profile = chromeProfile; + if (options.timeoutMs !== undefined) + chromeOptions.timeoutMs = options.timeoutMs; + if (options.includeExpired !== undefined) + chromeOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + chromeOptions.debug = options.debug; + result = await getCookiesFromChrome(chromeOptions, origins, names); + } + else if (browser === 'edge') { + const edgeOptions = {}; + const edgeProfile = options.edgeProfile ?? + options.profile ?? + readEnv('SWEET_COOKIE_EDGE_PROFILE') ?? + readEnv('SWEET_COOKIE_CHROME_PROFILE'); + if (edgeProfile) + edgeOptions.profile = edgeProfile; + if (options.timeoutMs !== undefined) + edgeOptions.timeoutMs = options.timeoutMs; + if (options.includeExpired !== undefined) + edgeOptions.includeExpired = options.includeExpired; + if (options.debug !== undefined) + edgeOptions.debug = options.debug; + result = await getCookiesFromEdge(edgeOptions, origins, names); + } + else if (browser === 'firefox') { + const firefoxOptions = {}; + const firefoxProfile = options.firefoxProfile ?? readEnv('SWEET_COOKIE_FIREFOX_PROFILE'); + if (firefoxProfile) + firefoxOptions.profile = firefoxProfile; + if (options.includeExpired !== undefined) + firefoxOptions.includeExpired = options.includeExpired; + result = await getCookiesFromFirefox(firefoxOptions, origins, names); + } + else { + const safariOptions = {}; + if (options.includeExpired !== undefined) + safariOptions.includeExpired = options.includeExpired; + if (options.safariCookiesFile) + safariOptions.file = options.safariCookiesFile; + result = await getCookiesFromSafari(safariOptions, origins, names); + } + warnings.push(...result.warnings); + if (mode === 'first' && result.cookies.length) { + // "first" returns the first backend that produced anything (plus accumulated warnings). + return { cookies: result.cookies, warnings }; + } + for (const cookie of result.cookies) { + tryAdd(cookie); + } + } + return { cookies: Array.from(merged.values()), warnings }; +} +/** + * Convert cookies to an HTTP `Cookie` header value. + * + * This is a helper for typical Node fetch clients / HTTP libraries. + * It does not validate cookie RFC edge cases; it simply joins `name=value` pairs. + */ +export function toCookieHeader(cookies, options = {}) { + const sort = options.sort ?? 'name'; + const dedupeByName = options.dedupeByName ?? false; + const items = cookies + .filter((cookie) => cookie?.name && typeof cookie.value === 'string') + .map((cookie) => ({ name: cookie.name, value: cookie.value })); + const ordered = sort === 'name' ? items.slice().sort((a, b) => a.name.localeCompare(b.name)) : items; + if (!dedupeByName) { + return ordered.map((cookie) => `${cookie.name}=${cookie.value}`).join('; '); + } + const seen = new Set(); + const deduped = []; + for (const cookie of ordered) { + const key = cookie.name; + if (seen.has(key)) + continue; + seen.add(key); + deduped.push(cookie); + } + return deduped.map((cookie) => `${cookie.name}=${cookie.value}`).join('; '); +} +function normalizeNames(names) { + if (!names?.length) + return null; + const cleaned = names.map((n) => n.trim()).filter(Boolean); + if (!cleaned.length) + return null; + return new Set(cleaned); +} +async function resolveInlineSources(options) { + const sources = []; + if (options.inlineCookiesJson) { + sources.push({ source: 'inline-json', payload: options.inlineCookiesJson }); + } + if (options.inlineCookiesBase64) { + sources.push({ source: 'inline-base64', payload: options.inlineCookiesBase64 }); + } + if (options.inlineCookiesFile) { + sources.push({ source: 'inline-file', payload: options.inlineCookiesFile }); + } + return sources; +} +function parseBrowsersEnv() { + const raw = readEnv('SWEET_COOKIE_BROWSERS') ?? readEnv('SWEET_COOKIE_SOURCES'); + if (!raw) + return undefined; + const tokens = raw + .split(/[,\s]+/) + .map((t) => t.trim().toLowerCase()) + .filter(Boolean); + const out = []; + for (const token of tokens) { + if (token === 'chrome' || token === 'edge' || token === 'firefox' || token === 'safari') { + if (!out.includes(token)) + out.push(token); + } + } + return out.length ? out : undefined; +} +function parseModeEnv() { + const raw = readEnv('SWEET_COOKIE_MODE'); + if (!raw) + return undefined; + const normalized = raw.trim().toLowerCase(); + if (normalized === 'merge' || normalized === 'first') + return normalized; + return undefined; +} +function readEnv(key) { + const value = process.env[key]; + const trimmed = typeof value === 'string' ? value.trim() : ''; + return trimmed.length ? trimmed : undefined; +} +//# sourceMappingURL=public.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js.map new file mode 100644 index 0000000..7a360e3 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/public.js.map @@ -0,0 +1 @@ +{"version":3,"file":"public.js","sourceRoot":"","sources":["../src/public.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts new file mode 100644 index 0000000..03c76a0 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts @@ -0,0 +1,121 @@ +/** + * Supported browser backends. + * + * Notes: + * - `safari` is macOS-only. + * - `chrome` targets Google Chrome paths by default. + * - `edge` targets Microsoft Edge paths by default. + * - Other Chromium browsers often work by passing an explicit cookie DB path via `chromeProfile` + * (or `edgeProfile` if you want to keep sources separate). + * - Only modern Chromium cookie DB schemas are supported (roughly Chrome >= 100). + */ +export type BrowserName = 'chrome' | 'edge' | 'firefox' | 'safari'; +export type CookieSameSite = 'Strict' | 'Lax' | 'None'; +export interface Cookie { + /** Cookie name (required). */ + name: string; + /** Cookie value (required; may be empty string). */ + value: string; + /** Hostname without leading dot (e.g. `example.com`). */ + domain?: string; + /** Path (defaults to `/` when omitted). */ + path?: string; + /** + * Optional URL form. Useful when a cookie is host-only or when `domain` is not known. + * If present, it should be a valid origin URL like `https://example.com`. + */ + url?: string; + /** Unix timestamp in seconds. Omit for session cookies. */ + expires?: number; + secure?: boolean; + httpOnly?: boolean; + sameSite?: CookieSameSite; + source?: { + browser: BrowserName; + /** Optional profile identifier when resolved from a profile. */ + profile?: string; + /** Optional origin that produced this cookie (implementation detail). */ + origin?: string; + /** Optional store identifier (implementation detail; e.g. extension cookie store). */ + storeId?: string; + }; +} +export type CookieMode = 'merge' | 'first'; +export interface GetCookiesOptions { + /** + * Primary URL used to derive default origin filtering. + * Must include a protocol (e.g. `https://example.com/`). + */ + url: string; + /** + * Additional origins to include when filtering cookies. + * Useful for OAuth/SSO flows where cookies are set on multiple domains. + */ + origins?: string[]; + /** Allowlist of cookie names. When omitted, all matching cookies are returned. */ + names?: string[]; + /** + * Which browser backends to try, in order. + * Defaults to `chrome`, `safari`, `firefox` (and is also configurable via env). + */ + browsers?: BrowserName[]; + /** Alias for chromeProfile (common case). */ + profile?: string; + /** + * Chrome/Chromium profile selector. + * + * Accepted values: + * - profile directory name like `Default` / `Profile 2` + * - a path to a profile directory + * - a path to a cookie DB file (`.../Network/Cookies` or `.../Cookies`) + */ + chromeProfile?: string; + /** + * Microsoft Edge profile selector. + * + * Accepted values: + * - profile directory name like `Default` / `Profile 2` + * - a path to a profile directory + * - a path to a cookie DB file (`.../Network/Cookies` or `.../Cookies`) + */ + edgeProfile?: string; + /** + * Firefox profile selector (profile name or filesystem path). + * If a directory is provided, `cookies.sqlite` is resolved within it. + */ + firefoxProfile?: string; + /** Override path to Safari Cookies.binarycookies (for tests / debugging). */ + safariCookiesFile?: string; + /** Include expired cookies (default: false). */ + includeExpired?: boolean; + /** Timeout for OS helper calls (keychain/keyring/DPAPI). */ + timeoutMs?: number; + /** Emit extra provider warnings (no raw cookie values). */ + debug?: boolean; + /** Merge cookies across backends (`merge`) or return first successful backend (`first`). */ + mode?: CookieMode; + /** + * Inline cookie payload source. Commonly a file path exported by the extension. + * If it looks like a file path, Sweet Cookie will attempt to read it. + */ + inlineCookiesFile?: string; + /** Inline cookie payload as JSON string (either `Cookie[]` or `{ cookies: Cookie[] }`). */ + inlineCookiesJson?: string; + /** Inline cookie payload as base64-encoded JSON. */ + inlineCookiesBase64?: string; +} +export interface GetCookiesResult { + cookies: Cookie[]; + /** + * Non-fatal warnings from providers (missing keyring tools, schema drift, unsupported cookies, etc). + * Never includes raw cookie values. + */ + warnings: string[]; +} +export interface CookieHeaderOptions { + /** If true, keeps the first cookie value per name and drops duplicates. */ + dedupeByName?: boolean; + /** Sorting strategy for the emitted header. */ + sort?: 'name' | 'none'; +} +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts.map new file mode 100644 index 0000000..f44e1aa --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,MAAM;IACtB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE;QACR,OAAO,EAAE,WAAW,CAAC;QACrB,gEAAgE;QAChE,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,yEAAyE;QACzE,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,sFAAsF;QACtF,OAAO,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACF;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAE3C,MAAM,WAAW,iBAAiB;IACjC;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gDAAgD;IAChD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IACnC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js new file mode 100644 index 0000000..718fd38 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js.map new file mode 100644 index 0000000..c768b79 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/types.js.map @@ -0,0 +1 @@ +{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts new file mode 100644 index 0000000..de5dc28 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts @@ -0,0 +1,2 @@ +export declare function tryDecodeBase64Json(input: string): string | null; +//# sourceMappingURL=base64.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts.map new file mode 100644 index 0000000..b8dbc1d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../../src/util/base64.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAahE"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js new file mode 100644 index 0000000..c1e470b --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js @@ -0,0 +1,18 @@ +export function tryDecodeBase64Json(input) { + const trimmed = input.trim(); + if (!trimmed) + return null; + try { + const encoding = /[-_]/.test(trimmed) ? 'base64url' : 'base64'; + const buf = Buffer.from(trimmed, encoding); + const decoded = buf.toString('utf8').trim(); + if (!decoded) + return null; + JSON.parse(decoded); + return decoded; + } + catch { + return null; + } +} +//# sourceMappingURL=base64.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js.map new file mode 100644 index 0000000..efef5e3 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/base64.js.map @@ -0,0 +1 @@ +{"version":3,"file":"base64.js","sourceRoot":"","sources":["../../src/util/base64.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAmB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC/E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,OAAO,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts new file mode 100644 index 0000000..03d671f --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts @@ -0,0 +1,8 @@ +export declare function execCapture(file: string, args: string[], options?: { + timeoutMs?: number; +}): Promise<{ + code: number; + stdout: string; + stderr: string; +}>; +//# sourceMappingURL=exec.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts.map new file mode 100644 index 0000000..97b044a --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/util/exec.ts"],"names":[],"mappings":"AAEA,wBAAsB,WAAW,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA8G3D"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js new file mode 100644 index 0000000..044cb3e --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js @@ -0,0 +1,110 @@ +import { spawn } from 'node:child_process'; +export async function execCapture(file, args, options = {}) { + const timeoutMs = options.timeoutMs ?? 10_000; + const runOnce = (executable) => new Promise((resolve) => { + // Keep this very small + predictable: + // - no shell by default (avoid quoting differences) + // - capture stdout/stderr for diagnostics + // - hard timeout so keychain/keyring calls can't hang forever in CI/SSH sessions + const child = spawn(executable, args, { stdio: ['ignore', 'pipe', 'pipe'] }); + let stdout = ''; + let stderr = ''; + child.stdout.setEncoding('utf8'); + child.stderr.setEncoding('utf8'); + child.stdout.on('data', (chunk) => { + stdout += chunk; + }); + child.stderr.on('data', (chunk) => { + stderr += chunk; + }); + const timer = setTimeout(() => { + try { + child.kill('SIGKILL'); + } + catch { + // ignore + } + resolve({ code: 124, stdout, stderr: `${stderr}\nTimed out after ${timeoutMs}ms` }); + }, timeoutMs); + timer.unref?.(); + child.on('error', (error) => { + clearTimeout(timer); + resolve({ + code: 127, + stdout, + stderr: `${stderr}\n${error instanceof Error ? error.message : String(error)}`, + }); + }); + child.on('close', (code) => { + clearTimeout(timer); + resolve({ code: code ?? 0, stdout, stderr }); + }); + }); + const result = await runOnce(file); + if (process.platform !== 'win32') + return result; + /* c8 ignore start */ + const runOnceCmd = (cmd) => { + // On Windows, some tools are `.cmd`/`.bat` wrappers and won't exec directly. + // We fall back to `cmd.exe /c` and quote args ourselves. + const quoted = [cmd, ...args.map(cmdQuote)].join(' '); + return new Promise((resolve) => { + const child = spawn('cmd.exe', ['/d', '/s', '/c', quoted], { + stdio: ['ignore', 'pipe', 'pipe'], + }); + let stdout = ''; + let stderr = ''; + child.stdout.setEncoding('utf8'); + child.stderr.setEncoding('utf8'); + child.stdout.on('data', (chunk) => { + stdout += chunk; + }); + child.stderr.on('data', (chunk) => { + stderr += chunk; + }); + const timer = setTimeout(() => { + try { + child.kill('SIGKILL'); + } + catch { + // ignore + } + resolve({ code: 124, stdout, stderr: `${stderr}\nTimed out after ${timeoutMs}ms` }); + }, timeoutMs); + timer.unref?.(); + child.on('error', (error) => { + clearTimeout(timer); + resolve({ + code: 127, + stdout, + stderr: `${stderr}\n${error instanceof Error ? error.message : String(error)}`, + }); + }); + child.on('close', (code) => { + clearTimeout(timer); + resolve({ code: code ?? 0, stdout, stderr }); + }); + }); + }; + const stderr = result.stderr.toLowerCase(); + if (result.code === 127 && stderr.includes('enoent') && !file.toLowerCase().endsWith('.cmd')) { + const cmdResult = await runOnceCmd(`${file}.cmd`); + if (!(cmdResult.code === 127 && cmdResult.stderr.toLowerCase().includes('enoent'))) + return cmdResult; + } + if (result.code === 127 && stderr.includes('enoent') && !file.toLowerCase().endsWith('.bat')) { + const batResult = await runOnceCmd(`${file}.bat`); + if (!(batResult.code === 127 && batResult.stderr.toLowerCase().includes('enoent'))) + return batResult; + } + /* c8 ignore stop */ + return result; +} +function cmdQuote(value) { + if (!value) + return '""'; + if (!/[\t\s"&|<>^]/.test(value)) + return value; + return `"${value.replaceAll('"', '""')}"`; +} +//# sourceMappingURL=exec.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js.map new file mode 100644 index 0000000..abcca00 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/exec.js.map @@ -0,0 +1 @@ +{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/util/exec.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts new file mode 100644 index 0000000..19ae6d2 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts @@ -0,0 +1,2 @@ +export declare function normalizeExpiration(expires?: number | bigint): number | undefined; +//# sourceMappingURL=expire.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts.map new file mode 100644 index 0000000..0b36a1d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"expire.d.ts","sourceRoot":"","sources":["../../src/util/expire.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CA6BjF"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js new file mode 100644 index 0000000..9b9e38d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js @@ -0,0 +1,32 @@ +export function normalizeExpiration(expires) { + if (expires === undefined || expires === null) + return undefined; + if (typeof expires === 'bigint') { + if (expires <= 0n) + return undefined; + if (expires > 10000000000000n) { + return Number(expires / 1000000n - 11644473600n); + } + if (expires > 10000000000n) { + return Number(expires / 1000n); + } + return Number(expires); + } + if (!expires || Number.isNaN(expires)) + return undefined; + const value = Number(expires); + if (value <= 0) + return undefined; + // Chromium can use microseconds since 1601 (Windows epoch) in sqlite stores. + if (value > 10_000_000_000_000) { + return Math.round(value / 1_000_000 - 11_644_473_600); + } + // milliseconds epoch + // (seconds epoch is already ~1.7e9, so the cutoff must be much higher than 1e9) + if (value > 10_000_000_000) { + return Math.round(value / 1000); + } + // seconds epoch + return Math.round(value); +} +//# sourceMappingURL=expire.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js.map new file mode 100644 index 0000000..480ee94 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/expire.js.map @@ -0,0 +1 @@ +{"version":3,"file":"expire.js","sourceRoot":"","sources":["../../src/util/expire.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,mBAAmB,CAAC,OAAyB;IAC5D,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAChE,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,OAAO,IAAI,EAAE;YAAE,OAAO,SAAS,CAAC;QACpC,IAAI,OAAO,GAAG,eAAmB,EAAE,CAAC;YACnC,OAAO,MAAM,CAAC,OAAO,GAAG,QAAU,GAAG,YAAe,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,OAAO,GAAG,YAAe,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAEjC,6EAA6E;IAC7E,IAAI,KAAK,GAAG,kBAAkB,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC;IACvD,CAAC;IAED,qBAAqB;IACrB,gFAAgF;IAChF,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,gBAAgB;IAChB,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts new file mode 100644 index 0000000..e6e1322 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts @@ -0,0 +1,2 @@ +export declare function readTextFileIfExists(filePath: string): Promise; +//# sourceMappingURL=fs.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts.map new file mode 100644 index 0000000..a6a44bb --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/util/fs.ts"],"names":[],"mappings":"AAEA,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnF"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js new file mode 100644 index 0000000..d9f5469 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js @@ -0,0 +1,13 @@ +import fs from 'node:fs/promises'; +export async function readTextFileIfExists(filePath) { + try { + const stat = await fs.stat(filePath); + if (!stat.isFile()) + return null; + return await fs.readFile(filePath, 'utf8'); + } + catch { + return null; + } +} +//# sourceMappingURL=fs.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js.map new file mode 100644 index 0000000..26ecdb6 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/fs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/util/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IAC1D,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts new file mode 100644 index 0000000..5f51d7c --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts @@ -0,0 +1,2 @@ +export declare function hostMatchesCookieDomain(host: string, cookieDomain: string): boolean; +//# sourceMappingURL=hostMatch.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts.map new file mode 100644 index 0000000..e64a4e2 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"hostMatch.d.ts","sourceRoot":"","sources":["../../src/util/hostMatch.ts"],"names":[],"mappings":"AAAA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAKnF"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js new file mode 100644 index 0000000..9f221ba --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js @@ -0,0 +1,7 @@ +export function hostMatchesCookieDomain(host, cookieDomain) { + const normalizedHost = host.toLowerCase(); + const normalizedDomain = cookieDomain.startsWith('.') ? cookieDomain.slice(1) : cookieDomain; + const domainLower = normalizedDomain.toLowerCase(); + return normalizedHost === domainLower || normalizedHost.endsWith(`.${domainLower}`); +} +//# sourceMappingURL=hostMatch.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js.map new file mode 100644 index 0000000..a8c5c4e --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/hostMatch.js.map @@ -0,0 +1 @@ +{"version":3,"file":"hostMatch.js","sourceRoot":"","sources":["../../src/util/hostMatch.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,YAAoB;IACzE,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,gBAAgB,GAAG,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IAC7F,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC;IACnD,OAAO,cAAc,KAAK,WAAW,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC;AACrF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts new file mode 100644 index 0000000..f15eed5 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts @@ -0,0 +1,5 @@ +type NodeSqliteModule = typeof import('node:sqlite'); +export declare function supportsReadBigInts(): boolean; +export declare function importNodeSqlite(): Promise; +export {}; +//# sourceMappingURL=nodeSqlite.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts.map new file mode 100644 index 0000000..45e57aa --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"nodeSqlite.d.ts","sourceRoot":"","sources":["../../src/util/nodeSqlite.ts"],"names":[],"mappings":"AAAA,KAAK,gBAAgB,GAAG,cAAc,aAAa,CAAC,CAAC;AAIrD,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C;AA4BD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAmBlE"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js new file mode 100644 index 0000000..68c344e --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js @@ -0,0 +1,58 @@ +let cached = null; +export function supportsReadBigInts() { + const [majorRaw, minorRaw] = process.versions.node.split('.'); + const major = Number.parseInt(majorRaw ?? '', 10); + const minor = Number.parseInt(minorRaw ?? '', 10); + if (!Number.isFinite(major) || !Number.isFinite(minor)) + return false; + if (major > 24) + return true; + if (major < 24) + return false; + return minor >= 4; +} +function shouldSuppressSqliteExperimentalWarning(warning, args) { + const message = typeof warning === 'string' + ? warning + : warning instanceof Error + ? warning.message + : typeof warning?.message === 'string' + ? warning.message + : null; + if (!message || !message.includes('SQLite is an experimental feature')) + return false; + // Best-effort: only swallow the one noisy warning that Node emits when loading `node:sqlite`. + // We do *not* suppress arbitrary warnings, and we restore the original handler immediately. + const firstArg = args[0]; + if (firstArg === 'ExperimentalWarning') + return true; + if (typeof firstArg === 'object' && firstArg) { + const type = firstArg.type; + if (type === 'ExperimentalWarning') + return true; + } + if (warning instanceof Error && warning.name === 'ExperimentalWarning') + return true; + return false; +} +export async function importNodeSqlite() { + if (cached) + return cached; + // Node currently emits an ExperimentalWarning when importing `node:sqlite`. + // This is harmless noise for consumers of this library, so we silence only that specific warning. + const originalEmitWarning = process.emitWarning.bind(process); + process.emitWarning = ((warning, ...args) => { + if (shouldSuppressSqliteExperimentalWarning(warning, args)) + return; + // @ts-expect-error - Node's overloads are awkward; preserve runtime behavior. + return originalEmitWarning(warning, ...args); + }); + try { + cached = await import('node:sqlite'); + return cached; + } + finally { + process.emitWarning = originalEmitWarning; + } +} +//# sourceMappingURL=nodeSqlite.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js.map new file mode 100644 index 0000000..627007d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/nodeSqlite.js.map @@ -0,0 +1 @@ +{"version":3,"file":"nodeSqlite.js","sourceRoot":"","sources":["../../src/util/nodeSqlite.ts"],"names":[],"mappings":"AAEA,IAAI,MAAM,GAA4B,IAAI,CAAC;AAE3C,MAAM,UAAU,mBAAmB;IAClC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrE,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAC5B,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAC7B,OAAO,KAAK,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,uCAAuC,CAAC,OAAgB,EAAE,IAAe;IACjF,MAAM,OAAO,GACZ,OAAO,OAAO,KAAK,QAAQ;QAC1B,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,YAAY,KAAK;YACzB,CAAC,CAAC,OAAO,CAAC,OAAO;YACjB,CAAC,CAAC,OAAQ,OAAwC,EAAE,OAAO,KAAK,QAAQ;gBACvE,CAAC,CAAE,OAA+B,CAAC,OAAO;gBAC1C,CAAC,CAAC,IAAI,CAAC;IAEX,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,mCAAmC,CAAC;QAAE,OAAO,KAAK,CAAC;IAErF,8FAA8F;IAC9F,4FAA4F;IAC5F,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,QAAQ,KAAK,qBAAqB;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAI,QAA+B,CAAC,IAAI,CAAC;QACnD,IAAI,IAAI,KAAK,qBAAqB;YAAE,OAAO,IAAI,CAAC;IACjD,CAAC;IACD,IAAI,OAAO,YAAY,KAAK,IAAK,OAA8B,CAAC,IAAI,KAAK,qBAAqB;QAC7F,OAAO,IAAI,CAAC;IAEb,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACrC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,4EAA4E;IAC5E,kGAAkG;IAClG,MAAM,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE9D,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC,OAAgB,EAAE,GAAG,IAAe,EAAE,EAAE;QAC/D,IAAI,uCAAuC,CAAC,OAAO,EAAE,IAAI,CAAC;YAAE,OAAO;QACnE,8EAA8E;QAC9E,OAAO,mBAAmB,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9C,CAAC,CAA+B,CAAC;IAEjC,IAAI,CAAC;QACJ,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC;IACf,CAAC;YAAS,CAAC;QACV,OAAO,CAAC,WAAW,GAAG,mBAAmB,CAAC;IAC3C,CAAC;AACF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts new file mode 100644 index 0000000..8a61f62 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts @@ -0,0 +1,2 @@ +export declare function normalizeOrigins(url: string, extraOrigins?: string[]): string[]; +//# sourceMappingURL=origins.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts.map new file mode 100644 index 0000000..a94554c --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"origins.d.ts","sourceRoot":"","sources":["../../src/util/origins.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAqB/E"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js new file mode 100644 index 0000000..f325dbe --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js @@ -0,0 +1,27 @@ +export function normalizeOrigins(url, extraOrigins) { + const origins = []; + try { + const parsed = new URL(url); + origins.push(ensureTrailingSlash(parsed.origin)); + } + catch { + // ignore + } + for (const raw of extraOrigins ?? []) { + const trimmed = raw.trim(); + if (!trimmed) + continue; + try { + const parsed = new URL(trimmed); + origins.push(ensureTrailingSlash(parsed.origin)); + } + catch { + // ignore malformed extras + } + } + return Array.from(new Set(origins)); +} +function ensureTrailingSlash(origin) { + return origin.endsWith('/') ? origin : `${origin}/`; +} +//# sourceMappingURL=origins.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js.map new file mode 100644 index 0000000..f30490d --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/origins.js.map @@ -0,0 +1 @@ +{"version":3,"file":"origins.js","sourceRoot":"","sources":["../../src/util/origins.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAAC,GAAW,EAAE,YAAuB;IACpE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACR,SAAS;IACV,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,YAAY,IAAI,EAAE,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACR,0BAA0B;QAC3B,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC;AACrD,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts new file mode 100644 index 0000000..0effb84 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts @@ -0,0 +1,2 @@ +export declare function isBunRuntime(): boolean; +//# sourceMappingURL=runtime.d.ts.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts.map new file mode 100644 index 0000000..e79fd7b --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/util/runtime.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,IAAI,OAAO,CAKtC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js new file mode 100644 index 0000000..c0f48b4 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js @@ -0,0 +1,8 @@ +export function isBunRuntime() { + // Bun: https://bun.sh/docs/runtime/environment-variables#bun-specific + if (typeof process === 'undefined') + return false; + const bunVersion = process.versions.bun; + return Boolean(typeof process.versions === 'object' && typeof bunVersion === 'string'); +} +//# sourceMappingURL=runtime.js.map \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js.map b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js.map new file mode 100644 index 0000000..4c02d7a --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/dist/util/runtime.js.map @@ -0,0 +1 @@ +{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/util/runtime.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY;IAC3B,sEAAsE;IACtE,IAAI,OAAO,OAAO,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,UAAU,GAAI,OAAO,CAAC,QAAyC,CAAC,GAAG,CAAC;IAC1E,OAAO,OAAO,CAAC,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC;AACxF,CAAC"} \ No newline at end of file diff --git a/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/package.json b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/package.json new file mode 100644 index 0000000..ffef682 --- /dev/null +++ b/scripts/lib/vendor/bird-search/node_modules/@steipete/sweet-cookie/package.json @@ -0,0 +1,40 @@ +{ + "name": "@steipete/sweet-cookie", + "version": "0.1.0", + "description": "Inline-first browser cookie extraction for local tooling (no native addons).", + "license": "MIT", + "author": "Peter Steinberger", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "README.md", + "LICENSE" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/steipete/sweet-cookie.git", + "directory": "packages/core" + }, + "bugs": { + "url": "https://github.com/steipete/sweet-cookie/issues" + }, + "homepage": "https://github.com/steipete/sweet-cookie#readme", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + } + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "engines": { + "node": ">=22" + } +} diff --git a/scripts/lib/vendor/bird-search/package.json b/scripts/lib/vendor/bird-search/package.json new file mode 100644 index 0000000..9446bb3 --- /dev/null +++ b/scripts/lib/vendor/bird-search/package.json @@ -0,0 +1,13 @@ +{ + "name": "bird-search", + "version": "0.8.0", + "description": "Vendored Bird CLI search subset for /last30days", + "type": "module", + "main": "bird-search.mjs", + "private": true, + "engines": { + "node": ">=22" + }, + "license": "MIT", + "attribution": "Based on @steipete/bird v0.8.0 by Peter Steinberger (MIT License)" +}