notte-sdk 1.9.0 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var SDK_VERSION = true ? "1.9.0" : "dev";
2
+ var SDK_VERSION = true ? "1.9.2" : "dev";
3
3
  var SDK_PACKAGE_NAME = true ? "notte-sdk" : "notte-sdk";
4
4
 
5
5
  // src/version-check.ts
@@ -932,6 +932,11 @@ var createClient = (config = {}) => {
932
932
  var client = createClient(createConfig({ baseUrl: "https://api.notte.cc" }));
933
933
 
934
934
  // src/lib/client/sdk.gen.ts
935
+ var sessionAuthReadiness = (options) => (options.client ?? client).get({
936
+ security: [{ scheme: "bearer", type: "http" }],
937
+ url: "/sessions/{session_id}/auth",
938
+ ...options
939
+ });
935
940
  var listSessions = (options) => (options?.client ?? client).get({
936
941
  security: [{ scheme: "bearer", type: "http" }],
937
942
  url: "/sessions",
@@ -951,6 +956,11 @@ var sessionStatus = (options) => (options.client ?? client).get({
951
956
  url: "/sessions/{session_id}",
952
957
  ...options
953
958
  });
959
+ var sessionProfilePreview = (options) => (options.client ?? client).get({
960
+ security: [{ scheme: "bearer", type: "http" }],
961
+ url: "/sessions/{session_id}/profile-preview",
962
+ ...options
963
+ });
954
964
  var getSessionScript = (options) => (options.client ?? client).get({
955
965
  security: [{ scheme: "bearer", type: "http" }],
956
966
  url: "/sessions/{session_id}/workflow/code",
@@ -1262,6 +1272,38 @@ var listVaults = (options) => (options?.client ?? client).get({
1262
1272
  url: "/vaults",
1263
1273
  ...options
1264
1274
  });
1275
+ var connectPaymentWallet = (options) => (options.client ?? client).post({
1276
+ security: [{ scheme: "bearer", type: "http" }],
1277
+ url: "/payments/connect",
1278
+ ...options,
1279
+ headers: {
1280
+ "Content-Type": "application/json",
1281
+ ...options.headers
1282
+ }
1283
+ });
1284
+ var disconnectPaymentWallet = (options) => (options.client ?? client).post({
1285
+ security: [{ scheme: "bearer", type: "http" }],
1286
+ url: "/payments/disconnect",
1287
+ ...options,
1288
+ headers: {
1289
+ "Content-Type": "application/json",
1290
+ ...options.headers
1291
+ }
1292
+ });
1293
+ var createPayment = (options) => (options.client ?? client).post({
1294
+ security: [{ scheme: "bearer", type: "http" }],
1295
+ url: "/sessions/{session_id}/payments",
1296
+ ...options,
1297
+ headers: {
1298
+ "Content-Type": "application/json",
1299
+ ...options.headers
1300
+ }
1301
+ });
1302
+ var getPayment = (options) => (options.client ?? client).get({
1303
+ security: [{ scheme: "bearer", type: "http" }],
1304
+ url: "/payments/{payment_id}",
1305
+ ...options
1306
+ });
1265
1307
  var profileCreate = (options) => (options.client ?? client).post({
1266
1308
  security: [{ scheme: "bearer", type: "http" }],
1267
1309
  url: "/profiles/create",
@@ -1519,10 +1561,8 @@ var scrapeFromHtml = (options) => (options.client ?? client).post({
1519
1561
  }
1520
1562
  });
1521
1563
 
1522
- // src/session.ts
1523
- import { existsSync } from "fs";
1524
- import { writeFile as writeFile2 } from "fs/promises";
1525
- import { resolve as resolve2 } from "path";
1564
+ // src/managed-auth.ts
1565
+ import { setTimeout as delay } from "timers/promises";
1526
1566
 
1527
1567
  // src/errors.ts
1528
1568
  var NotteError = class extends Error {
@@ -1676,70 +1716,544 @@ function sleep(ms) {
1676
1716
  return new Promise((resolve3) => setTimeout(resolve3, ms));
1677
1717
  }
1678
1718
 
1679
- // src/actions.ts
1680
- function builder(type) {
1681
- return (...[input]) => ({ ...input ?? {}, type });
1719
+ // src/managed-auth.ts
1720
+ var ManagedAuthError = class extends NotteError {
1721
+ };
1722
+ function validateAuthRetry(value) {
1723
+ if (!Number.isInteger(value) || value < 0 || value > 2) {
1724
+ throw new InvalidRequestError("auth_retry must be an integer between 0 and 2");
1725
+ }
1682
1726
  }
1683
- var goto = builder("goto");
1684
- var gotoNewTab = builder("goto_new_tab");
1685
- var closeTab = builder("close_tab");
1686
- var switchTab = builder("switch_tab");
1687
- var goBack = builder("go_back");
1688
- var goForward = builder("go_forward");
1689
- var reload = builder("reload");
1690
- var wait = builder("wait");
1691
- var pressKey = builder("press_key");
1692
- var scrollUp = builder("scroll_up");
1693
- var scrollDown = builder("scroll_down");
1694
- var captchaSolve = builder("captcha_solve");
1695
- var help = builder("help");
1696
- var completion = builder("completion");
1697
- var scrape = builder("scrape");
1698
- var emailRead = builder("email_read");
1699
- var emailVerificationRead = builder("email_verification_read");
1700
- var smsRead = builder("sms_read");
1701
- var evaluateJs = builder("evaluate_js");
1702
- var formFill = builder("form_fill");
1703
- var click = builder("click");
1704
- var fill = builder("fill");
1705
- var multiFactorFill = builder("multi_factor_fill");
1706
- var fallbackFill = builder("fallback_fill");
1707
- var check = builder("check");
1708
- var selectDropdownOption = builder("select_dropdown_option");
1709
- var uploadFile = builder("upload_file");
1710
- var downloadFile = builder("download_file");
1711
- var actions = {
1712
- goto,
1713
- gotoNewTab,
1714
- closeTab,
1715
- switchTab,
1716
- goBack,
1717
- goForward,
1718
- reload,
1719
- wait,
1720
- pressKey,
1721
- scrollUp,
1722
- scrollDown,
1723
- captchaSolve,
1724
- help,
1725
- completion,
1726
- scrape,
1727
- emailRead,
1728
- emailVerificationRead,
1729
- smsRead,
1730
- evaluateJs,
1731
- formFill,
1732
- click,
1733
- fill,
1734
- multiFactorFill,
1735
- fallbackFill,
1736
- check,
1737
- selectDropdownOption,
1738
- uploadFile,
1739
- downloadFile
1727
+ async function pollAuth(read, options) {
1728
+ const timeoutMs = options.timeoutMs ?? 615e3;
1729
+ const interval = options.pollIntervalMs ?? 1e3;
1730
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || !Number.isFinite(interval) || interval <= 0) {
1731
+ throw new InvalidRequestError("timeoutMs and pollIntervalMs must be positive finite numbers");
1732
+ }
1733
+ const deadline = new AbortController();
1734
+ const timer = setTimeout(() => deadline.abort(new NotteTimeoutError("Timed out waiting for authentication")), timeoutMs);
1735
+ const cancel = () => deadline.abort(options.signal?.reason);
1736
+ if (options.signal?.aborted) cancel();
1737
+ else options.signal?.addEventListener("abort", cancel, { once: true });
1738
+ const signal = deadline.signal;
1739
+ let errors = 0;
1740
+ try {
1741
+ while (true) {
1742
+ signal.throwIfAborted();
1743
+ try {
1744
+ const value = await read(signal);
1745
+ signal.throwIfAborted();
1746
+ if (value !== void 0) return value;
1747
+ errors = 0;
1748
+ } catch (error) {
1749
+ signal.throwIfAborted();
1750
+ const retryable = error instanceof NotteAPIError ? error.statusCode >= 500 : error instanceof TypeError || error instanceof NotteTimeoutError;
1751
+ if (!retryable || ++errors >= 3) throw error;
1752
+ }
1753
+ await delay(interval, void 0, { signal });
1754
+ }
1755
+ } catch (error) {
1756
+ signal.throwIfAborted();
1757
+ throw error;
1758
+ } finally {
1759
+ clearTimeout(timer);
1760
+ options.signal?.removeEventListener("abort", cancel);
1761
+ }
1762
+ }
1763
+ var NotteManagedAuth = class {
1764
+ constructor(client2) {
1765
+ this.client = client2;
1766
+ }
1767
+ /** Run only the verifier; this does not submit login credentials. */
1768
+ async checkConnection(connectionId) {
1769
+ const response = await this.client.getClient().post({
1770
+ url: `/managed-auth/connections/${encodeURIComponent(connectionId)}/check`,
1771
+ body: {},
1772
+ headers: { "Content-Type": "application/json" },
1773
+ throwOnError: true
1774
+ });
1775
+ return response.data;
1776
+ }
1777
+ async getOperation(operationId, options = {}) {
1778
+ const response = await this.client.getClient().get({
1779
+ url: `/managed-auth/operations/${encodeURIComponent(operationId)}`,
1780
+ headers: { [TIMEOUT_HEADER]: "10000" },
1781
+ signal: options.signal,
1782
+ throwOnError: true
1783
+ });
1784
+ return response.data;
1785
+ }
1786
+ /** Wait for an accepted operation. Aborting this wait does not cancel the server operation. */
1787
+ async waitForAuth(operation, options = {}) {
1788
+ const completed = (value) => {
1789
+ if (value.status === "succeeded") return value;
1790
+ if (value.status === "pending" || value.status === "running") return void 0;
1791
+ throw new ManagedAuthError(value.error || "Connection authentication failed");
1792
+ };
1793
+ options.signal?.throwIfAborted();
1794
+ const result = completed(operation);
1795
+ if (result) return result;
1796
+ return pollAuth(async (signal) => completed(await this.getOperation(operation.id, { signal })), options);
1797
+ }
1798
+ /** Verify first, logging in only when required and automatic recovery is allowed. */
1799
+ async refreshConnection(connectionId, options = {}) {
1800
+ return this.run(connectionId, "refresh", options);
1801
+ }
1802
+ /** Explicitly request a new login. Conflicting operations remain HTTP 409 errors. */
1803
+ async reauthenticateConnection(connectionId, options = {}) {
1804
+ return this.run(connectionId, "reauthenticate", options);
1805
+ }
1806
+ async run(connectionId, action, options) {
1807
+ const authRetry = options.auth_retry ?? 0;
1808
+ validateAuthRetry(authRetry);
1809
+ options.signal?.throwIfAborted();
1810
+ const response = await this.client.getClient().post({
1811
+ url: `/managed-auth/connections/${encodeURIComponent(connectionId)}/${action}`,
1812
+ body: { auth_retry: authRetry },
1813
+ headers: { "Content-Type": "application/json" },
1814
+ signal: options.signal,
1815
+ throwOnError: true
1816
+ });
1817
+ return options.wait === false ? response.data : this.waitForAuth(response.data, options);
1818
+ }
1740
1819
  };
1741
- function isCaptchaSolveAction(action) {
1742
- return action.type === "captcha_solve";
1820
+
1821
+ // src/resources.gen.ts
1822
+ function createResources(client2, getApiKey) {
1823
+ return {
1824
+ sessions: {
1825
+ /** sessionAuthReadiness: /sessions/{session_id}/auth. Returns the API response body. */
1826
+ authReadiness: async (sessionId, requestOptions = {}) => {
1827
+ const response = await sessionAuthReadiness({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId } });
1828
+ return response.data;
1829
+ },
1830
+ /** createPayment: /sessions/{session_id}/payments. Returns the API response body. */
1831
+ createPayment: async (sessionId, body, query = void 0, requestOptions) => {
1832
+ const response = await createPayment({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, body, query });
1833
+ return response.data;
1834
+ },
1835
+ /** sessionDebugInfo: /sessions/{session_id}/debug. Returns the API response body. */
1836
+ debugInfo: async (sessionId, query = void 0, requestOptions = {}) => {
1837
+ const response = await sessionDebugInfo({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1838
+ return response.data;
1839
+ },
1840
+ /** deleteSessionFile: /sessions/{session_id}/files/{file_id}. Returns the API response body. */
1841
+ deleteSessionFile: async (sessionId, fileId, requestOptions = {}) => {
1842
+ const response = await deleteSessionFile({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId, "file_id": fileId } });
1843
+ return response.data;
1844
+ },
1845
+ /** downloadSessionFile: /sessions/{session_id}/files/{file_id}. Returns the API response body. */
1846
+ downloadSessionFile: async (sessionId, fileId, requestOptions = {}) => {
1847
+ const response = await downloadSessionFile({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId, "file_id": fileId } });
1848
+ return response.data;
1849
+ },
1850
+ /** pageExecute: /sessions/{session_id}/page/execute. Returns the API response body. */
1851
+ execute: async (sessionId, body, query = void 0, requestOptions = {}) => {
1852
+ const response = await pageExecute({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, body, query });
1853
+ return response.data;
1854
+ },
1855
+ /** sessionCookiesGet: /sessions/{session_id}/cookies. Returns the API response body. */
1856
+ getCookies: async (sessionId, query = void 0, requestOptions = {}) => {
1857
+ const response = await sessionCookiesGet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1858
+ return response.data;
1859
+ },
1860
+ /** getSessionScript: /sessions/{session_id}/workflow/code. Returns the API response body. */
1861
+ getSessionScript: async (sessionId, query, requestOptions = {}) => {
1862
+ const response = await getSessionScript({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1863
+ return response.data;
1864
+ },
1865
+ /** listSessions: /sessions. Returns the API response body. */
1866
+ list: async (query = void 0, requestOptions = {}) => {
1867
+ const response = await listSessions({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, query });
1868
+ return response.data;
1869
+ },
1870
+ /** listSessionFiles: /sessions/{session_id}/files. Returns the API response body. */
1871
+ listSessionFiles: async (sessionId, query = void 0, requestOptions = {}) => {
1872
+ const response = await listSessionFiles({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1873
+ return response.data;
1874
+ },
1875
+ /** sessionNetworkLogs: /sessions/{session_id}/network/logs. Returns the API response body. */
1876
+ networkLogs: async (sessionId, query = void 0, requestOptions = {}) => {
1877
+ const response = await sessionNetworkLogs({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1878
+ return response.data;
1879
+ },
1880
+ /** pageObserve: /sessions/{session_id}/page/observe. Returns the API response body. */
1881
+ observe: async (sessionId, body, query = void 0, requestOptions = {}) => {
1882
+ const response = await pageObserve({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, body, query });
1883
+ return response.data;
1884
+ },
1885
+ /** sessionOffset: /sessions/{session_id}/offset. Returns the API response body. */
1886
+ offset: async (sessionId, requestOptions = {}) => {
1887
+ const response = await sessionOffset({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId } });
1888
+ return response.data;
1889
+ },
1890
+ /** pageScreenshot: /sessions/{session_id}/page/screenshot. Returns the API response body. */
1891
+ pageScreenshot: async (sessionId, query = void 0, requestOptions = {}) => {
1892
+ const response = await pageScreenshot({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1893
+ return response.data;
1894
+ },
1895
+ /** sessionProfilePreview: /sessions/{session_id}/profile-preview. Returns the API response body. */
1896
+ profilePreview: async (sessionId, query = void 0, requestOptions = {}) => {
1897
+ const response = await sessionProfilePreview({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1898
+ return response.data;
1899
+ },
1900
+ /** sessionReplay: /sessions/{session_id}/replay. Returns the API response body. */
1901
+ replay: async (sessionId, requestOptions = {}) => {
1902
+ const response = await sessionReplay({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId } });
1903
+ return response.data;
1904
+ },
1905
+ /** pageScrape: /sessions/{session_id}/page/scrape. Returns the API response body. */
1906
+ scrape: async (sessionId, body, query = void 0, requestOptions = {}) => {
1907
+ const response = await pageScrape({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, body, query });
1908
+ return response.data;
1909
+ },
1910
+ /** sessionCookiesSet: /sessions/{session_id}/cookies. Returns the API response body. */
1911
+ setCookies: async (sessionId, body, query = void 0, requestOptions = {}) => {
1912
+ const response = await sessionCookiesSet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, body, query });
1913
+ return response.data;
1914
+ },
1915
+ /** sessionStart: /sessions/start. Returns the API response body. */
1916
+ start: async (body, requestOptions = {}) => {
1917
+ const response = await sessionStart({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, body });
1918
+ return response.data;
1919
+ },
1920
+ /** sessionStatus: /sessions/{session_id}. Returns the API response body. */
1921
+ status: async (sessionId, requestOptions = {}) => {
1922
+ const response = await sessionStatus({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId } });
1923
+ return response.data;
1924
+ },
1925
+ /** sessionStop: /sessions/{session_id}/stop. Returns the API response body. */
1926
+ stop: async (sessionId, query = void 0, requestOptions = {}) => {
1927
+ const response = await sessionStop({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, query });
1928
+ return response.data;
1929
+ },
1930
+ /** uploadSessionFile: /sessions/{session_id}/files. Returns the API response body. */
1931
+ uploadSessionFile: async (sessionId, body, requestOptions = {}) => {
1932
+ const response = await uploadSessionFile({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "session_id": sessionId }, body });
1933
+ return response.data;
1934
+ }
1935
+ },
1936
+ agents: {
1937
+ /** getScript: /agents/{agent_id}/workflow/code. Returns the API response body. */
1938
+ getScript: async (agentId, query, requestOptions = {}) => {
1939
+ const response = await getScript({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "agent_id": agentId }, query });
1940
+ return response.data;
1941
+ },
1942
+ /** listAgents: /agents. Returns the API response body. */
1943
+ list: async (query = void 0, requestOptions = {}) => {
1944
+ const response = await listAgents({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, query });
1945
+ return response.data;
1946
+ },
1947
+ /** agentStart: /agents/start. Returns the API response body. */
1948
+ start: async (body, requestOptions = {}) => {
1949
+ const response = await agentStart({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, body });
1950
+ return response.data;
1951
+ },
1952
+ /** agentStatus: /agents/{agent_id}. Returns the API response body. */
1953
+ status: async (agentId, requestOptions = {}) => {
1954
+ const response = await agentStatus({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "agent_id": agentId } });
1955
+ return response.data;
1956
+ },
1957
+ /** agentStop: /agents/{agent_id}/stop. Returns the API response body. */
1958
+ stop: async (agentId, query, requestOptions = {}) => {
1959
+ const response = await agentStop({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "agent_id": agentId }, query });
1960
+ return response.data;
1961
+ }
1962
+ },
1963
+ functions: {
1964
+ /** functionCreate: /functions. Returns the API response body. */
1965
+ create: async (body, query = void 0, requestOptions = {}) => {
1966
+ const response = await functionCreate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, body, query });
1967
+ return response.data;
1968
+ },
1969
+ /** functionDelete: /functions/{function_id}. Returns the API response body. */
1970
+ delete: async (functionId, requestOptions = {}) => {
1971
+ const response = await functionDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId } });
1972
+ return response.data;
1973
+ },
1974
+ /** functionScheduleDelete: /functions/{function_id}/schedule. Returns the API response body. */
1975
+ deleteSchedule: async (functionId, requestOptions = {}) => {
1976
+ const response = await functionScheduleDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId } });
1977
+ return response.data;
1978
+ },
1979
+ /** functionDownloadUrl: /functions/{function_id}. Returns the API response body. */
1980
+ downloadUrl: async (functionId, query = void 0, requestOptions = {}) => {
1981
+ const response = await functionDownloadUrl({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, query });
1982
+ return response.data;
1983
+ },
1984
+ /** functionFork: /functions/{function_id}/fork. Returns the API response body. */
1985
+ fork: async (functionId, requestOptions = {}) => {
1986
+ const response = await functionFork({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId } });
1987
+ return response.data;
1988
+ },
1989
+ /** listFunctions: /functions. Returns the API response body. */
1990
+ list: async (query = void 0, requestOptions = {}) => {
1991
+ const response = await listFunctions({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, query });
1992
+ return response.data;
1993
+ },
1994
+ /** listFunctionRunsByFunctionId: /functions/{function_id}/runs. Returns the API response body. */
1995
+ listRuns: async (functionId, query = void 0, requestOptions = {}) => {
1996
+ const response = await listFunctionRunsByFunctionId({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, query });
1997
+ return response.data;
1998
+ },
1999
+ /** functionMetadataUpdate: /functions/{function_id}. Returns the API response body. */
2000
+ metadataUpdate: async (functionId, body, requestOptions = {}) => {
2001
+ const response = await functionMetadataUpdate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, body });
2002
+ return response.data;
2003
+ },
2004
+ /** functionRollback: /functions/{function_id}/rollback. Returns the API response body. */
2005
+ rollback: async (functionId, body, query = void 0, requestOptions = {}) => {
2006
+ const response = await functionRollback({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, body, query });
2007
+ return response.data;
2008
+ },
2009
+ /** functionRunGetMetadata: /functions/{function_id}/runs/{run_id}. Returns the API response body. */
2010
+ runGetMetadata: async (functionId, runId, requestOptions = {}) => {
2011
+ const response = await functionRunGetMetadata({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId, "run_id": runId } });
2012
+ return response.data;
2013
+ },
2014
+ /** functionRunStart: /functions/{function_id}/runs/start. Returns the API response body. */
2015
+ runStart: async (functionId, body, requestOptions = {}) => {
2016
+ const response = await functionRunStart({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers, "x-notte-api-key": getApiKey() }, path: { "function_id": functionId }, body });
2017
+ return response.data;
2018
+ },
2019
+ /** functionRunStop: /functions/{function_id}/runs/{run_id}. Returns the API response body. */
2020
+ runStop: async (functionId, runId, requestOptions = {}) => {
2021
+ const response = await functionRunStop({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId, "run_id": runId } });
2022
+ return response.data;
2023
+ },
2024
+ /** functionRunUpdateMetadata: /functions/{function_id}/runs/{run_id}. Returns the API response body. */
2025
+ runUpdateMetadata: async (functionId, runId, body, requestOptions = {}) => {
2026
+ const response = await functionRunUpdateMetadata({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId, "run_id": runId }, body });
2027
+ return response.data;
2028
+ },
2029
+ /** functionRuntimeHealth: /functions/health. Returns the API response body. */
2030
+ runtimeHealth: async (requestOptions = {}) => {
2031
+ const response = await functionRuntimeHealth({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers } });
2032
+ return response.data;
2033
+ },
2034
+ /** functionScheduleSet: /functions/{function_id}/schedule. Returns the API response body. */
2035
+ setSchedule: async (functionId, body, requestOptions = {}) => {
2036
+ const response = await functionScheduleSet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, body });
2037
+ return response.data;
2038
+ },
2039
+ /** functionUpdate: /functions/{function_id}. Returns the API response body. */
2040
+ update: async (functionId, body, query = void 0, requestOptions = {}) => {
2041
+ const response = await functionUpdate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "function_id": functionId }, body, query });
2042
+ return response.data;
2043
+ }
2044
+ },
2045
+ vaults: {
2046
+ /** vaultCreate: /vaults/create. Returns the API response body. */
2047
+ create: async (body, requestOptions = {}) => {
2048
+ const response = await vaultCreate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, body });
2049
+ return response.data;
2050
+ },
2051
+ /** vaultCredentialsAdd: /vaults/{vault_id}/credentials. Returns the API response body. */
2052
+ credentialsAdd: async (vaultId, body, requestOptions = {}) => {
2053
+ const response = await vaultCredentialsAdd({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId }, body });
2054
+ return response.data;
2055
+ },
2056
+ /** vaultCredentialsDelete: /vaults/{vault_id}/credentials. Returns the API response body. */
2057
+ credentialsDelete: async (vaultId, query, requestOptions = {}) => {
2058
+ const response = await vaultCredentialsDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId }, query });
2059
+ return response.data;
2060
+ },
2061
+ /** vaultCredentialsGet: /vaults/{vault_id}/credentials. Returns the API response body. */
2062
+ credentialsGet: async (vaultId, query, requestOptions = {}) => {
2063
+ const response = await vaultCredentialsGet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId }, query });
2064
+ return response.data;
2065
+ },
2066
+ /** vaultCredentialsList: /vaults/{vault_id}. Returns the API response body. */
2067
+ credentialsList: async (vaultId, requestOptions = {}) => {
2068
+ const response = await vaultCredentialsList({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId } });
2069
+ return response.data;
2070
+ },
2071
+ /** vaultCreditCardDelete: /vaults/{vault_id}/card. Returns the API response body. */
2072
+ creditCardDelete: async (vaultId, requestOptions = {}) => {
2073
+ const response = await vaultCreditCardDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId } });
2074
+ return response.data;
2075
+ },
2076
+ /** vaultCreditCardGet: /vaults/{vault_id}/card. Returns the API response body. */
2077
+ creditCardGet: async (vaultId, requestOptions = {}) => {
2078
+ const response = await vaultCreditCardGet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId } });
2079
+ return response.data;
2080
+ },
2081
+ /** vaultCreditCardSet: /vaults/{vault_id}/card. Returns the API response body. */
2082
+ creditCardSet: async (vaultId, body, requestOptions = {}) => {
2083
+ const response = await vaultCreditCardSet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId }, body });
2084
+ return response.data;
2085
+ },
2086
+ /** vaultDelete: /vaults/{vault_id}. Returns the API response body. */
2087
+ delete: async (vaultId, requestOptions = {}) => {
2088
+ const response = await vaultDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId } });
2089
+ return response.data;
2090
+ },
2091
+ /** listVaults: /vaults. Returns the API response body. */
2092
+ list: async (query = void 0, requestOptions = {}) => {
2093
+ const response = await listVaults({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, query });
2094
+ return response.data;
2095
+ },
2096
+ /** vaultUpdate: /vaults/{vault_id}. Returns the API response body. */
2097
+ update: async (vaultId, body, requestOptions = {}) => {
2098
+ const response = await vaultUpdate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "vault_id": vaultId }, body });
2099
+ return response.data;
2100
+ }
2101
+ },
2102
+ personas: {
2103
+ /** personaCreate: /personas/create. Returns the API response body. */
2104
+ create: async (body, requestOptions = {}) => {
2105
+ const response = await personaCreate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, body });
2106
+ return response.data;
2107
+ },
2108
+ /** personaDelete: /personas/{persona_id}. Returns the API response body. */
2109
+ delete: async (personaId, requestOptions = {}) => {
2110
+ const response = await personaDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "persona_id": personaId } });
2111
+ return response.data;
2112
+ },
2113
+ /** personaEmailsList: /personas/{persona_id}/emails. Returns the API response body. */
2114
+ emailsList: async (personaId, query = void 0, requestOptions = {}) => {
2115
+ const response = await personaEmailsList({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "persona_id": personaId }, query });
2116
+ return response.data;
2117
+ },
2118
+ /** personaGet: /personas/{persona_id}. Returns the API response body. */
2119
+ get: async (personaId, requestOptions = {}) => {
2120
+ const response = await personaGet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "persona_id": personaId } });
2121
+ return response.data;
2122
+ },
2123
+ /** listPersonas: /personas. Returns the API response body. */
2124
+ list: async (query = void 0, requestOptions = {}) => {
2125
+ const response = await listPersonas({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, query });
2126
+ return response.data;
2127
+ },
2128
+ /** personaSmsList: /personas/{persona_id}/sms. Returns the API response body. */
2129
+ smsList: async (personaId, query = void 0, requestOptions = {}) => {
2130
+ const response = await personaSmsList({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "persona_id": personaId }, query });
2131
+ return response.data;
2132
+ },
2133
+ /** personaUpdate: /personas/{persona_id}. Returns the API response body. */
2134
+ update: async (personaId, body, requestOptions = {}) => {
2135
+ const response = await personaUpdate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "persona_id": personaId }, body });
2136
+ return response.data;
2137
+ }
2138
+ },
2139
+ profiles: {
2140
+ /** profileCookiesGet: /profiles/{profile_id}/cookies. Returns the API response body. */
2141
+ cookiesGet: async (profileId, requestOptions = {}) => {
2142
+ const response = await profileCookiesGet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "profile_id": profileId } });
2143
+ return response.data;
2144
+ },
2145
+ /** profileCookiesSet: /profiles/{profile_id}/cookies. Returns the API response body. */
2146
+ cookiesSet: async (profileId, body, requestOptions = {}) => {
2147
+ const response = await profileCookiesSet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "profile_id": profileId }, body });
2148
+ return response.data;
2149
+ },
2150
+ /** profileCreate: /profiles/create. Returns the API response body. */
2151
+ create: async (body, requestOptions = {}) => {
2152
+ const response = await profileCreate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, body });
2153
+ return response.data;
2154
+ },
2155
+ /** profileDelete: /profiles/{profile_id}. Returns the API response body. */
2156
+ delete: async (profileId, requestOptions = {}) => {
2157
+ const response = await profileDelete({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "profile_id": profileId } });
2158
+ return response.data;
2159
+ },
2160
+ /** profileDuplicate: /profiles/{profile_id}/duplicate. Returns the API response body. */
2161
+ duplicate: async (profileId, body, requestOptions = {}) => {
2162
+ const response = await profileDuplicate({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "profile_id": profileId }, body });
2163
+ return response.data;
2164
+ },
2165
+ /** profileGet: /profiles/{profile_id}. Returns the API response body. */
2166
+ get: async (profileId, requestOptions = {}) => {
2167
+ const response = await profileGet({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, path: { "profile_id": profileId } });
2168
+ return response.data;
2169
+ },
2170
+ /** profileList: /profiles. Returns the API response body. */
2171
+ list: async (query = void 0, requestOptions = {}) => {
2172
+ const response = await profileList({ client: client2, throwOnError: true, signal: requestOptions.signal, headers: { ...requestOptions.headers }, query });
2173
+ return response.data;
2174
+ }
2175
+ }
2176
+ };
2177
+ }
2178
+
2179
+ // src/session.ts
2180
+ import { existsSync } from "fs";
2181
+ import { writeFile as writeFile2 } from "fs/promises";
2182
+ import { resolve as resolve2 } from "path";
2183
+ import { setTimeout as delay2 } from "timers/promises";
2184
+
2185
+ // src/captcha.ts
2186
+ async function executeWithCaptcha(action, budgetSeconds, request) {
2187
+ const explicit = action.type === "captcha_solve";
2188
+ let deadline = explicit ? performance.now() + budgetSeconds * 1e3 : void 0;
2189
+ let params = { captcha_timeout_seconds: budgetSeconds };
2190
+ let requestAction = action;
2191
+ let original;
2192
+ let last;
2193
+ const remaining = () => deadline === void 0 ? budgetSeconds : (deadline - performance.now()) / 1e3;
2194
+ const pause = (ms = 1e3) => sleep(Math.max(0, Math.min(ms, remaining() * 1e3)));
2195
+ const failure = (message, code) => ({
2196
+ started_at: (/* @__PURE__ */ new Date()).toISOString(),
2197
+ ended_at: (/* @__PURE__ */ new Date()).toISOString(),
2198
+ ...original ?? last,
2199
+ action,
2200
+ success: false,
2201
+ message,
2202
+ code,
2203
+ exception: message,
2204
+ exception_detail: null,
2205
+ captcha: last?.captcha
2206
+ });
2207
+ while (true) {
2208
+ const left = remaining();
2209
+ if (left <= 0) return failure("CAPTCHA wait deadline exceeded", "captcha_timeout");
2210
+ params.captcha_timeout_seconds = left;
2211
+ const polling = requestAction.type === "captcha_solve";
2212
+ let result;
2213
+ try {
2214
+ result = await request(requestAction, { ...params }, polling ? Math.min(1e4, left * 1e3) : void 0);
2215
+ } catch (error) {
2216
+ const transport = error instanceof NotteTimeoutError || error instanceof TypeError || error instanceof SyntaxError;
2217
+ const transient = params.captcha_id !== void 0 && error instanceof NotteAPIError && [408, 429, 502, 503, 504].includes(error.statusCode);
2218
+ if (!polling || params.captcha_id === void 0 || !transport && !transient) throw error;
2219
+ await pause();
2220
+ continue;
2221
+ }
2222
+ last = result;
2223
+ const status = result.captcha;
2224
+ if (!status) {
2225
+ return params.captcha_id ? failure("Server omitted CAPTCHA polling status", "captcha_protocol_error") : result;
2226
+ }
2227
+ if (params.captcha_id && status.captcha_id !== params.captcha_id) {
2228
+ return failure("Server returned a different CAPTCHA solve", "captcha_protocol_error");
2229
+ }
2230
+ deadline ??= performance.now() + budgetSeconds * 1e3;
2231
+ if (!original && !explicit && result.action_executed === true) original = result;
2232
+ if (status.state === "cancelled" && status.cancel_reason === "navigation" && original) {
2233
+ return { ...original, captcha: status };
2234
+ }
2235
+ if (status.state === "failed" || status.state === "cancelled") {
2236
+ return failure(status.message || `CAPTCHA ${status.state}`, `captcha_${status.state}`);
2237
+ }
2238
+ if (status.state === "solved") {
2239
+ if (explicit) return result;
2240
+ if (original) return { ...original, captcha: status };
2241
+ if (!params.captcha_id && result.action_executed !== false) return result;
2242
+ params = {
2243
+ captcha_timeout_seconds: remaining(),
2244
+ target_page_id: status.page_id,
2245
+ target_generation: status.generation
2246
+ };
2247
+ requestAction = action;
2248
+ continue;
2249
+ }
2250
+ if (!explicit && !original && !params.captcha_id && result.action_executed !== false) {
2251
+ return failure("Server did not confirm whether the action executed", "captcha_execution_unknown");
2252
+ }
2253
+ params.captcha_id = status.captcha_id;
2254
+ requestAction = { type: "captcha_solve" };
2255
+ await pause(Math.min(1e3, Math.max(100, status.retry_after_ms ?? 1e3)));
2256
+ }
1743
2257
  }
1744
2258
 
1745
2259
  // src/page-fetch.ts
@@ -2140,7 +2654,6 @@ function openBrowser(url) {
2140
2654
  var SESSION_START_TRIES = 3;
2141
2655
  var CLUSTER_OVERLOAD_RETRY_DELAY_MS = 3e4;
2142
2656
  var CAPTCHA_SOLVE_TIMEOUT_MS = 1e5;
2143
- var CAPTCHA_SOLVE_TRIES = 3;
2144
2657
  function observeServerOwnedDialog(_dialog) {
2145
2658
  }
2146
2659
  function installServerOwnedDialogPolicy(browser) {
@@ -2156,6 +2669,9 @@ var Session = class {
2156
2669
  defaultRaiseOnFailure;
2157
2670
  defaultPerceptionType;
2158
2671
  cookieFile;
2672
+ cookiesLoaded = false;
2673
+ cookieLoadPromise;
2674
+ authenticationReady = false;
2159
2675
  fileStorage;
2160
2676
  sessionId = null;
2161
2677
  isActive = false;
@@ -2191,12 +2707,17 @@ var Session = class {
2191
2707
  * `CLUSTER_OVERLOAD_RETRY_DELAY_MS` on HTTP 529 (cluster overload). 4xx
2192
2708
  * errors are never retried.
2193
2709
  *
2710
+ * Managed-auth sessions wait for readiness by default. Pass
2711
+ * `{ wait_for_authentication: false }` for an explicit nonblocking start,
2712
+ * then call `waitForAuth()` before executing actions or connecting over CDP.
2713
+ * Cancellation during creation waits for its response so the new session can
2714
+ * be closed. Cancellation or failure during the startup wait also closes it.
2194
2715
  * Prefer `session.use(async session => { ... })`, which also stops the session.
2195
2716
  * @example
2196
2717
  * const session = client.Session();
2197
2718
  * await session.start();
2198
2719
  */
2199
- async start() {
2720
+ async start(options = {}) {
2200
2721
  if (this.legacyHeadless === false) {
2201
2722
  throw new Error(
2202
2723
  "Remote `headless: false` is no longer supported. `headless: true` sessions still include session replays and access to the live viewer."
@@ -2209,11 +2730,19 @@ var Session = class {
2209
2730
  if (this.isActive) {
2210
2731
  throw new Error("Session is already active");
2211
2732
  }
2212
- const body = this.options;
2733
+ options.signal?.throwIfAborted();
2734
+ validateAuthRetry(this.options.auth_retry ?? 0);
2735
+ const { auth_retry, wait_for_authentication, ...request } = this.options;
2736
+ const body = {
2737
+ ...request,
2738
+ ...request.auth_ids?.length ? { auth_retry: auth_retry ?? 0, wait_for_authentication: false } : {}
2739
+ };
2740
+ const shouldWait = options.wait_for_authentication ?? wait_for_authentication ?? true;
2213
2741
  let tries = SESSION_START_TRIES;
2214
2742
  const origTries = tries;
2215
2743
  let sessionData;
2216
2744
  while (tries > 0) {
2745
+ options.signal?.throwIfAborted();
2217
2746
  tries -= 1;
2218
2747
  try {
2219
2748
  const response = await sessionStart({ client: this.client.getClient(), body, throwOnError: true });
@@ -2228,7 +2757,16 @@ var Session = class {
2228
2757
  console.warn(
2229
2758
  `Failed to start session due to cluster overload, retrying in ${CLUSTER_OVERLOAD_RETRY_DELAY_MS / 1e3} seconds (${retryStr})...`
2230
2759
  );
2231
- await sleep(CLUSTER_OVERLOAD_RETRY_DELAY_MS);
2760
+ if (options.signal) {
2761
+ try {
2762
+ await delay2(CLUSTER_OVERLOAD_RETRY_DELAY_MS, void 0, { signal: options.signal });
2763
+ } catch (error2) {
2764
+ options.signal.throwIfAborted();
2765
+ throw error2;
2766
+ }
2767
+ } else {
2768
+ await sleep(CLUSTER_OVERLOAD_RETRY_DELAY_MS);
2769
+ }
2232
2770
  } else {
2233
2771
  console.warn(`Failed to start session: retrying (${retryStr})`);
2234
2772
  }
@@ -2240,19 +2778,17 @@ var Session = class {
2240
2778
  this.sessionId = sessionData.session_id;
2241
2779
  this.isActive = true;
2242
2780
  this.response = sessionData;
2781
+ this.cookiesLoaded = false;
2782
+ this.cookieLoadPromise = void 0;
2783
+ this.authenticationReady = false;
2243
2784
  this.fileStorage = this.fileStorage?.forSession(sessionData.session_id);
2244
2785
  try {
2786
+ options.signal?.throwIfAborted();
2787
+ if (shouldWait) await this.waitForAuth(options);
2245
2788
  if (this.openViewer) {
2246
2789
  this.openViewerInBrowser();
2247
2790
  }
2248
- if (this.cookieFile !== void 0) {
2249
- if (existsSync(this.cookieFile)) {
2250
- console.info(`\u{1F36A} Automatically loading cookies from ${this.cookieFile}`);
2251
- await this.setCookiesFromFile(this.cookieFile);
2252
- } else {
2253
- console.warn(`\u{1F36A} Cookie file ${this.cookieFile} not found, skipping cookie loading`);
2254
- }
2255
- }
2791
+ if (this.response?.status === "active") await this.loadInitialCookies();
2256
2792
  } catch (error) {
2257
2793
  try {
2258
2794
  await this.stop("error");
@@ -2262,6 +2798,65 @@ var Session = class {
2262
2798
  throw error;
2263
2799
  }
2264
2800
  }
2801
+ /**
2802
+ * Wait for this session to become usable without creating a session or submitting another login.
2803
+ * A standalone wait leaves session ownership with the caller, including on timeout or cancellation.
2804
+ */
2805
+ async waitForAuth(options = {}) {
2806
+ options.signal?.throwIfAborted();
2807
+ if (!this.response) throw new Error("Session has not started");
2808
+ if (this.response.status === "active") {
2809
+ await this.loadInitialCookies();
2810
+ return;
2811
+ }
2812
+ const sessionId = this.lastSessionId();
2813
+ this.response = await pollAuth(async (signal) => {
2814
+ const response = await sessionAuthReadiness({
2815
+ client: this.client.getClient(),
2816
+ path: { session_id: sessionId },
2817
+ headers: { [TIMEOUT_HEADER]: "10000" },
2818
+ signal,
2819
+ throwOnError: true
2820
+ });
2821
+ let result = response.data;
2822
+ if (result.status === "active") {
2823
+ this.authenticationReady = true;
2824
+ result = (await sessionStatus({
2825
+ client: this.client.getClient(),
2826
+ path: { session_id: sessionId },
2827
+ headers: { [TIMEOUT_HEADER]: "10000" },
2828
+ signal,
2829
+ throwOnError: true
2830
+ })).data;
2831
+ this.authenticationReady = result.status === "active";
2832
+ if (this.authenticationReady) return result;
2833
+ }
2834
+ if (result.status !== "authenticating") throw new ManagedAuthError(result.error || "Session authentication failed");
2835
+ return void 0;
2836
+ }, options);
2837
+ await this.loadInitialCookies();
2838
+ }
2839
+ async loadInitialCookies() {
2840
+ if (this.cookiesLoaded || this.cookieFile === void 0) return;
2841
+ if (!this.cookieLoadPromise) {
2842
+ const cookieFile = this.cookieFile;
2843
+ this.cookieLoadPromise = (async () => {
2844
+ if (existsSync(cookieFile)) {
2845
+ console.info(`\u{1F36A} Automatically loading cookies from ${cookieFile}`);
2846
+ await this.setCookiesFromFile(cookieFile);
2847
+ } else {
2848
+ console.warn(`\u{1F36A} Cookie file ${cookieFile} not found, skipping cookie loading`);
2849
+ }
2850
+ this.cookiesLoaded = true;
2851
+ })();
2852
+ }
2853
+ const pending = this.cookieLoadPromise;
2854
+ try {
2855
+ await pending;
2856
+ } finally {
2857
+ if (this.cookieLoadPromise === pending) this.cookieLoadPromise = void 0;
2858
+ }
2859
+ }
2265
2860
  /**
2266
2861
  * Stop the session and clean up resources (including any Playwright
2267
2862
  * connection opened with `page()`). When a `cookie_file` was given, the
@@ -2277,7 +2872,7 @@ var Session = class {
2277
2872
  }
2278
2873
  const sessionId = this.sessionId;
2279
2874
  await this.closePlaywright();
2280
- if (this.cookieFile !== void 0) {
2875
+ if (this.cookieFile !== void 0 && (this.authenticationReady || this.response?.status === "active")) {
2281
2876
  try {
2282
2877
  const cookies = await this.getCookies();
2283
2878
  await createOrAppendCookiesToFile(this.cookieFile, cookies);
@@ -2638,32 +3233,22 @@ var Session = class {
2638
3233
  async execute(action, options = {}) {
2639
3234
  const sessionId = this.requireSessionId();
2640
3235
  const raiseOnFailure = typeof options === "boolean" ? options : options.raiseOnFailure ?? this.defaultRaiseOnFailure;
2641
- const isCaptcha = isCaptchaSolveAction(action);
2642
- let result;
2643
- let lastError;
2644
- for (let attempt = 0; attempt < CAPTCHA_SOLVE_TRIES; attempt += 1) {
2645
- try {
3236
+ const result = await executeWithCaptcha(
3237
+ action,
3238
+ this.client.getConfig().captchaTimeoutSeconds ?? 180,
3239
+ async (requestAction, params, timeoutMs) => {
3240
+ const query = params;
2646
3241
  const response = await pageExecute({
2647
3242
  client: this.client.getClient(),
2648
3243
  path: { session_id: sessionId },
2649
- body: action,
2650
- headers: isCaptcha ? { [TIMEOUT_HEADER]: String(CAPTCHA_SOLVE_TIMEOUT_MS) } : void 0,
3244
+ body: requestAction,
3245
+ query,
3246
+ headers: timeoutMs === void 0 ? void 0 : { [TIMEOUT_HEADER]: String(timeoutMs) },
2651
3247
  throwOnError: true
2652
3248
  });
2653
- result = response.data;
2654
- break;
2655
- } catch (error) {
2656
- if (isCaptcha && error instanceof NotteAPIError && error.statusCode === 408) {
2657
- lastError = error;
2658
- console.warn("Solve captcha action timed out. This can happen for long and complex captchas. Retrying...");
2659
- continue;
2660
- }
2661
- throw error;
3249
+ return response.data;
2662
3250
  }
2663
- }
2664
- if (!result) {
2665
- throw lastError ?? new Error(`Failed to execute action '${action.type}'. This should not happen. Please report this issue.`);
2666
- }
3251
+ );
2667
3252
  if (raiseOnFailure && !result.success) {
2668
3253
  console.error(`\u{1F6A8} Execution failed with message: '${result.message}'`);
2669
3254
  if (result.exception_detail) {
@@ -2757,7 +3342,10 @@ var Session = class {
2757
3342
  * Context manager pattern: start the session, run the callback and stop the
2758
3343
  * session, with close reason `error` when the callback throws.
2759
3344
  *
2760
- * @param callback - Async work to perform with the started session.
3345
+ * Always waits for Managed Auth readiness before invoking the callback.
3346
+ *
3347
+ * @param callback - Async work to perform with the ready session.
3348
+ * @param options - Controls the Managed Auth readiness wait, including timeout and cancellation.
2761
3349
  * @returns The callback's return value after session cleanup has been attempted.
2762
3350
  * @throws Error if startup fails, the callback throws, or cleanup fails after a successful callback.
2763
3351
  * @example
@@ -2765,8 +3353,8 @@ var Session = class {
2765
3353
  * await session.execute({ type: 'goto', url: 'https://www.notte.cc' });
2766
3354
  * });
2767
3355
  */
2768
- async use(callback) {
2769
- await this.start();
3356
+ async use(callback, options = {}) {
3357
+ await this.start({ ...options, wait_for_authentication: true });
2770
3358
  let callbackFailed = false;
2771
3359
  try {
2772
3360
  return await callback(this);
@@ -4891,11 +5479,16 @@ function isRelativeProxyUrl(baseUrl) {
4891
5479
  var NotteClient3 = class {
4892
5480
  config;
4893
5481
  client = createClient();
5482
+ resources = createResources(this.client, () => this.config.apiKey ?? "");
4894
5483
  constructor(config = {}) {
4895
5484
  const apiKey = config.apiKey || process.env.NOTTE_API_KEY;
4896
5485
  const baseUrl = config.baseUrl || process.env.NOTTE_API_URL || DEFAULT_NOTTE_API_URL;
4897
5486
  const dbPreview = config.dbPreview || process.env[DB_PREVIEW_ENV] || void 0;
4898
5487
  const timeoutMs = config.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
5488
+ const captchaTimeoutSeconds = config.captchaTimeoutSeconds ?? 180;
5489
+ if (!Number.isFinite(captchaTimeoutSeconds) || captchaTimeoutSeconds <= 0) {
5490
+ throw new InvalidRequestError("captchaTimeoutSeconds must be positive and finite");
5491
+ }
4899
5492
  if (!(timeoutMs >= 0)) {
4900
5493
  throw new InvalidRequestError("timeoutMs must be a non-negative number");
4901
5494
  }
@@ -4914,7 +5507,7 @@ var NotteClient3 = class {
4914
5507
  "NOTTE_API_KEY needs to be provided. Pass config.apiKey or set the NOTTE_API_KEY environment variable."
4915
5508
  );
4916
5509
  }
4917
- this.config = { baseUrl, apiKey, timeoutMs, dbPreview, verbose: config.verbose ?? false };
5510
+ this.config = { baseUrl, apiKey, timeoutMs, captchaTimeoutSeconds, dbPreview, verbose: config.verbose ?? false };
4918
5511
  if (baseUrl !== DEFAULT_NOTTE_API_URL && !isProxyMode) {
4919
5512
  console.warn(`NOTTE_API_URL is set to: ${baseUrl}`);
4920
5513
  }
@@ -5129,36 +5722,40 @@ var NotteClient3 = class {
5129
5722
  Function(options) {
5130
5723
  return this.NotteFunction(options);
5131
5724
  }
5132
- /** Sessions listing, the counterpart of `client.sessions.list()`. */
5725
+ /** Client-bound session API operations. `list()` retains its array return value. */
5133
5726
  get sessions() {
5134
5727
  return {
5728
+ ...this.resources.sessions,
5135
5729
  list: async (options = {}) => {
5136
5730
  const response = await listSessions({ client: this.getClient(), query: options });
5137
5731
  return response.data?.items ?? [];
5138
5732
  }
5139
5733
  };
5140
5734
  }
5141
- /** Agents listing, the counterpart of `client.agents.list()`. */
5735
+ /** Client-bound agent API operations. `list()` retains its array return value. */
5142
5736
  get agents() {
5143
5737
  return {
5738
+ ...this.resources.agents,
5144
5739
  list: async (options = {}) => {
5145
5740
  const response = await listAgents({ client: this.getClient(), query: options });
5146
5741
  return response.data?.items ?? [];
5147
5742
  }
5148
5743
  };
5149
5744
  }
5150
- /** Vaults listing, the counterpart of `client.vaults.list()`. */
5745
+ /** Client-bound vault API operations. `list()` retains its array return value. */
5151
5746
  get vaults() {
5152
5747
  return {
5748
+ ...this.resources.vaults,
5153
5749
  list: async (options = {}) => {
5154
5750
  const response = await listVaults({ client: this.getClient(), query: options });
5155
5751
  return response.data?.items ?? [];
5156
5752
  }
5157
5753
  };
5158
5754
  }
5159
- /** Functions listing, the counterpart of `client.functions.list()`. */
5755
+ /** Client-bound function API operations. `list()` retains its array return value. */
5160
5756
  get functions() {
5161
5757
  return {
5758
+ ...this.resources.functions,
5162
5759
  list: async (options = {}) => {
5163
5760
  const response = await listFunctions({ client: this.getClient(), query: options });
5164
5761
  return response.data?.items ?? [];
@@ -5181,6 +5778,10 @@ var NotteClient3 = class {
5181
5778
  get secrets() {
5182
5779
  return new NotteSecrets(this);
5183
5780
  }
5781
+ /** Managed authentication: verify connections, request login, and wait for readiness. */
5782
+ get managedAuth() {
5783
+ return new NotteManagedAuth(this);
5784
+ }
5184
5785
  /** Usage and billing (`/usage`, `/usage/logs`). */
5185
5786
  get usage() {
5186
5787
  return new NotteUsage(this);
@@ -5190,6 +5791,7 @@ var NotteClient3 = class {
5190
5791
  */
5191
5792
  get personas() {
5192
5793
  return {
5794
+ ...this.resources.personas,
5193
5795
  list: async (options) => {
5194
5796
  const response = await listPersonas({
5195
5797
  client: this.getClient(),
@@ -5205,6 +5807,10 @@ var NotteClient3 = class {
5205
5807
  getClient() {
5206
5808
  return this.client;
5207
5809
  }
5810
+ /** Client-bound profile API operations, generated from OpenAPI. */
5811
+ get profiles() {
5812
+ return this.resources.profiles;
5813
+ }
5208
5814
  async scrape(url, options = {}) {
5209
5815
  const body = await buildScrapeBody(options);
5210
5816
  const response = await scrapeWebpage({
@@ -5278,6 +5884,72 @@ function withTimeout(signal, timeoutMs) {
5278
5884
  return { signal: composite, release };
5279
5885
  }
5280
5886
 
5887
+ // src/actions.ts
5888
+ function builder(type) {
5889
+ return (...[input]) => ({ ...input ?? {}, type });
5890
+ }
5891
+ var goto = builder("goto");
5892
+ var gotoNewTab = builder("goto_new_tab");
5893
+ var closeTab = builder("close_tab");
5894
+ var switchTab = builder("switch_tab");
5895
+ var goBack = builder("go_back");
5896
+ var goForward = builder("go_forward");
5897
+ var reload = builder("reload");
5898
+ var wait = builder("wait");
5899
+ var pressKey = builder("press_key");
5900
+ var scrollUp = builder("scroll_up");
5901
+ var scrollDown = builder("scroll_down");
5902
+ var captchaSolve = builder("captcha_solve");
5903
+ var help = builder("help");
5904
+ var completion = builder("completion");
5905
+ var scrape = builder("scrape");
5906
+ var emailRead = builder("email_read");
5907
+ var emailVerificationRead = builder("email_verification_read");
5908
+ var smsRead = builder("sms_read");
5909
+ var evaluateJs = builder("evaluate_js");
5910
+ var formFill = builder("form_fill");
5911
+ var click = builder("click");
5912
+ var fill = builder("fill");
5913
+ var multiFactorFill = builder("multi_factor_fill");
5914
+ var fallbackFill = builder("fallback_fill");
5915
+ var check = builder("check");
5916
+ var selectDropdownOption = builder("select_dropdown_option");
5917
+ var uploadFile = builder("upload_file");
5918
+ var downloadFile = builder("download_file");
5919
+ var actions = {
5920
+ goto,
5921
+ gotoNewTab,
5922
+ closeTab,
5923
+ switchTab,
5924
+ goBack,
5925
+ goForward,
5926
+ reload,
5927
+ wait,
5928
+ pressKey,
5929
+ scrollUp,
5930
+ scrollDown,
5931
+ captchaSolve,
5932
+ help,
5933
+ completion,
5934
+ scrape,
5935
+ emailRead,
5936
+ emailVerificationRead,
5937
+ smsRead,
5938
+ evaluateJs,
5939
+ formFill,
5940
+ click,
5941
+ fill,
5942
+ multiFactorFill,
5943
+ fallbackFill,
5944
+ check,
5945
+ selectDropdownOption,
5946
+ uploadFile,
5947
+ downloadFile
5948
+ };
5949
+ function isCaptchaSolveAction(action) {
5950
+ return action.type === "captcha_solve";
5951
+ }
5952
+
5281
5953
  // src/proxy/types.ts
5282
5954
  var NotteProxyAuthError = class extends Error {
5283
5955
  constructor(message = "Unauthorized") {
@@ -5318,12 +5990,14 @@ export {
5318
5990
  FileExistsError,
5319
5991
  FileNotFoundError,
5320
5992
  InvalidRequestError,
5993
+ ManagedAuthError,
5321
5994
  NotteAPIError,
5322
5995
  NotteAPIExecutionError,
5323
5996
  NotteAnything,
5324
5997
  NotteClient3 as NotteClient,
5325
5998
  NotteError,
5326
5999
  NotteFunction,
6000
+ NotteManagedAuth,
5327
6001
  NottePersona,
5328
6002
  NotteProxyAuthError,
5329
6003
  NotteSecrets,
@@ -5353,11 +6027,14 @@ export {
5353
6027
  connectLinkMailboxes,
5354
6028
  connectLinkStatus,
5355
6029
  connectLinkSubmit,
6030
+ connectPaymentWallet,
5356
6031
  createClient2 as createClient,
5357
6032
  createOrAppendCookiesToFile,
6033
+ createPayment,
5358
6034
  NotteClient3 as default,
5359
6035
  deleteSecret,
5360
6036
  deleteSessionFile,
6037
+ disconnectPaymentWallet,
5361
6038
  downloadSessionFile,
5362
6039
  functionCreate,
5363
6040
  functionDelete,
@@ -5373,6 +6050,7 @@ export {
5373
6050
  functionScheduleDelete,
5374
6051
  functionScheduleSet,
5375
6052
  functionUpdate,
6053
+ getPayment,
5376
6054
  getRootDomain,
5377
6055
  getScript,
5378
6056
  getSecret,
@@ -5429,11 +6107,13 @@ export {
5429
6107
  scrapeFromHtml,
5430
6108
  scrapeWebpage,
5431
6109
  searchWeb,
6110
+ sessionAuthReadiness,
5432
6111
  sessionCookiesGet,
5433
6112
  sessionCookiesSet,
5434
6113
  sessionDebugInfo,
5435
6114
  sessionNetworkLogs,
5436
6115
  sessionOffset,
6116
+ sessionProfilePreview,
5437
6117
  sessionReplay,
5438
6118
  sessionStart,
5439
6119
  sessionStatus,