apify 3.7.3-beta.5 → 3.7.3-beta.50

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/README.md CHANGED
@@ -5,6 +5,8 @@
5
5
  [![Chat on discord](https://img.shields.io/discord/801163717915574323?label=discord)](https://discord.gg/jyEM2PRvMU)
6
6
  [![Build Status](https://github.com/apify/apify-sdk-js/actions/workflows/test-and-release.yaml/badge.svg?branch=master)](https://github.com/apify/apify-sdk-js/actions/workflows/test-and-release.yaml)
7
7
 
8
+ `apify` is the official SDK for building [Apify Actors](https://docs.apify.com/platform/actors) in JavaScript and TypeScript. It handles the Actor lifecycle, storage access, platform events, proxy configuration, and more.
9
+
8
10
  ## Quick Start
9
11
 
10
12
  This short tutorial will set you up to start using Apify SDK in a minute or two.
@@ -33,7 +35,27 @@ await Actor.setValue('OUTPUT', {
33
35
  await Actor.exit();
34
36
  ```
35
37
 
36
- > You can also install the [`crawlee`](https://npmjs.org/crawlee) module, as it now provides the crawlers that were previously exported by Apify SDK. If you don't plan to use crawlers in your Actors, then you don't need to install it. Keep in mind that neither `playwright` nor `puppeteer` are bundled with `crawlee` in order to reduce install size and allow greater flexibility. That's why we manually install it with NPM. You can choose one, both, or neither. For more information and example please check [`documentation.`](https://docs.apify.com/sdk/js/docs/concepts/actor-lifecycle#running-crawlee-code-as-an-actor)
38
+ > You can also install the [`crawlee`](https://www.npmjs.com/package/crawlee) module, as it now provides the crawlers that were previously exported by Apify SDK. If you don't plan to use crawlers in your Actors, then you don't need to install it. Keep in mind that neither `playwright` nor `puppeteer` are bundled with `crawlee` in order to reduce install size and allow greater flexibility. That's why we manually install it with NPM. You can choose one, both, or neither. For more information and example please check [`documentation.`](https://docs.apify.com/sdk/js/docs/concepts/actor-lifecycle#running-crawlee-code-as-an-actor)
39
+
40
+ ## What are Actors?
41
+
42
+ Actors are serverless programs that can do almost anything. From simple scripts and web scrapers to complex automation workflows, AI agents, or even always-on services that expose HTTP endpoints.
43
+
44
+ They can run either locally or on the Apify platform, where you can scale their execution, monitor runs, schedule tasks, integrate them with other services, or even publish and monetize them. If you're new to Apify, learn more about the platform in the [Apify documentation](https://docs.apify.com/platform/about).
45
+
46
+ For more context, read the [Actor whitepaper](https://whitepaper.actor/).
47
+
48
+ ## What you can build
49
+
50
+ Almost any Node.js project can become an Actor, including projects for:
51
+
52
+ - **Web scraping and crawling** - The SDK works seamlessly with [Crawlee](https://crawlee.dev), which makes Apify a natural place to deploy and scale your crawlers. Start from a ready-made [Cheerio](https://apify.com/templates/js-crawlee-cheerio) template.
53
+ - **Browser automation** - Drive a real browser with [Playwright](https://playwright.dev), [Puppeteer](https://pptr.dev), or [Selenium](https://apify.com/apify/example-selenium) to automate tasks, fill in forms, or test web apps.
54
+ - **AI agents** - Host agents built with your framework of choice. Ready-made Actor templates cover [LangChain](https://apify.com/templates/js-langchain), [LangGraph](https://apify.com/templates/js-langgraph-agent), [BeeAI](https://apify.com/templates/ts-beeai-agent), and [Mastra](https://apify.com/templates/ts-mastraai).
55
+ - **MCP servers** - Deploy an MCP server as an Actor and make its tools available to any MCP client. See the [MCP server](https://apify.com/templates/ts-mcp-empty) and [MCP proxy](https://apify.com/templates/ts-mcp-proxy) templates.
56
+ - **Web servers and APIs** - Run a web server inside an Actor to serve HTTP requests, for example to expose your scraper as a live API. See the [Standby](https://apify.com/templates/js-standby) templates.
57
+
58
+ Whatever you build, the Apify SDK doesn't lock you into a particular framework. Bring the libraries you already use, and let Apify run your project in the cloud.
37
59
 
38
60
  ## Support
39
61
 
package/dist/actor.d.ts CHANGED
@@ -145,7 +145,7 @@ export interface ApifyEnv {
145
145
  logLevel: string | null;
146
146
  logFormat: string | null;
147
147
  /**
148
- * Origin for the Actor run, i.e. how it was started. See [here](https://docs.apify.com/sdk/python/reference/enum/MetaOrigin)
148
+ * Origin for the Actor run, i.e. how it was started. See [here](https://docs.apify.com/platform/actors/running/runs-and-builds#origin)
149
149
  * for more details. (APIFY_META_ORIGIN)
150
150
  */
151
151
  metaOrigin: string | null;
@@ -1361,9 +1361,12 @@ export declare class Actor<Data extends Dictionary = Dictionary> {
1361
1361
  private _openStorage;
1362
1362
  private _ensureActorInit;
1363
1363
  /**
1364
- * Get time remaining from the Actor run timeout. Returns `undefined` if not on an Apify platform or the current
1365
- * run was started without a timeout.
1364
+ * Get time remaining from the Actor run timeout in seconds, rounded up to whole seconds with minimum value of 1 second.
1365
+ *
1366
+ * The API treats a 0 second timeout as no timeout, the minimum acceptable timeout is 1 second.
1367
+ *
1368
+ * Returns `undefined` if not on the Apify platform or the current run was started without a timeout.
1366
1369
  */
1367
- private getRemainingTime;
1370
+ private getRemainingTimeSecs;
1368
1371
  private inferDefaultsFromInputSchema;
1369
1372
  }
package/dist/actor.js CHANGED
@@ -399,7 +399,7 @@ class Actor {
399
399
  * @ignore
400
400
  */
401
401
  async call(actorId, input, options = {}) {
402
- const timeout = options.timeout === 'inherit' ? this.getRemainingTime() : options.timeout;
402
+ const timeout = options.timeout === 'inherit' ? this.getRemainingTimeSecs() : options.timeout;
403
403
  const { token, ...rest } = options;
404
404
  const client = token ? this.newClient({ token }) : this.apifyClient;
405
405
  return client.actor(actorId).call(input, { ...rest, timeout });
@@ -429,7 +429,7 @@ class Actor {
429
429
  * @ignore
430
430
  */
431
431
  async start(actorId, input, options = {}) {
432
- const timeout = options.timeout === 'inherit' ? this.getRemainingTime() : options.timeout;
432
+ const timeout = options.timeout === 'inherit' ? this.getRemainingTimeSecs() : options.timeout;
433
433
  const { token, ...rest } = options;
434
434
  const client = token ? this.newClient({ token }) : this.apifyClient;
435
435
  return client.actor(actorId).start(input, { ...rest, timeout });
@@ -486,7 +486,7 @@ class Actor {
486
486
  * @ignore
487
487
  */
488
488
  async callTask(taskId, input, options = {}) {
489
- const timeout = options.timeout === 'inherit' ? this.getRemainingTime() : options.timeout;
489
+ const timeout = options.timeout === 'inherit' ? this.getRemainingTimeSecs() : options.timeout;
490
490
  const { token, ...rest } = options;
491
491
  const client = token ? this.newClient({ token }) : this.apifyClient;
492
492
  return client.task(taskId).call(input, { ...rest, timeout });
@@ -1031,7 +1031,12 @@ class Actor {
1031
1031
  userAgentSuffix: [`SDK/${apifyVersion}`, `Crawlee/${crawleeVersion}`],
1032
1032
  ...storageClientOptions,
1033
1033
  ...options, // allow overriding the instance configuration
1034
- }, this);
1034
+ }, {
1035
+ config: this.config,
1036
+ // Hand over the raw manager rather than the public getChargingManager(), which
1037
+ // warns about a missing init() — a standalone client is a supported use case.
1038
+ getChargingManager: () => this.chargingManager,
1039
+ });
1035
1040
  }
1036
1041
  /**
1037
1042
  * Returns `true` when code is running on Apify platform and `false` otherwise (for example locally).
@@ -1685,13 +1690,17 @@ class Actor {
1685
1690
  ].join('\n'));
1686
1691
  }
1687
1692
  /**
1688
- * Get time remaining from the Actor run timeout. Returns `undefined` if not on an Apify platform or the current
1689
- * run was started without a timeout.
1693
+ * Get time remaining from the Actor run timeout in seconds, rounded up to whole seconds with minimum value of 1 second.
1694
+ *
1695
+ * The API treats a 0 second timeout as no timeout, the minimum acceptable timeout is 1 second.
1696
+ *
1697
+ * Returns `undefined` if not on the Apify platform or the current run was started without a timeout.
1690
1698
  */
1691
- getRemainingTime() {
1699
+ getRemainingTimeSecs() {
1692
1700
  const env = this.getEnv();
1701
+ const MINIMUM_API_TIMEOUT_SECS = 1;
1693
1702
  if (this.isAtHome() && env.timeoutAt !== null) {
1694
- return env.timeoutAt.getTime() - Date.now();
1703
+ return Math.max(Math.ceil((env.timeoutAt.getTime() - Date.now()) / 1000), MINIMUM_API_TIMEOUT_SECS);
1695
1704
  }
1696
1705
  log_1.default.warning('Using `inherit` argument is only possible when the Actor is running on the Apify platform and when the ' +
1697
1706
  'timeout for the Actor run is set.');
@@ -76,6 +76,11 @@ export declare class ChargingManager {
76
76
  */
77
77
  init(): Promise<void>;
78
78
  private ensureChargingLogDatasetOnPlatform;
79
+ /**
80
+ * Whether {@link ChargingManager.init} has run. All charging operations (including
81
+ * {@link ChargingManager.getPricingInfo}) require an initialized manager.
82
+ */
83
+ get isInitialized(): boolean;
79
84
  /**
80
85
  * Get information about the pricing for this Actor.
81
86
  */
package/dist/charging.js CHANGED
@@ -208,6 +208,13 @@ class ChargingManager {
208
208
  await defaultStore.setValue(this.PLATFORM_CHARGING_LOG_DATASET_ID_KEY, dataset.id);
209
209
  return dataset.id;
210
210
  }
211
+ /**
212
+ * Whether {@link ChargingManager.init} has run. All charging operations (including
213
+ * {@link ChargingManager.getPricingInfo}) require an initialized manager.
214
+ */
215
+ get isInitialized() {
216
+ return this.chargingState !== undefined;
217
+ }
211
218
  /**
212
219
  * Get information about the pricing for this Actor.
213
220
  */
@@ -88,7 +88,7 @@ export interface ConfigurationOptions extends CoreConfigurationOptions {
88
88
  * `actorPermissionLevel` | `ACTOR_PERMISSION_LEVEL` | -
89
89
  * `actorRunId` | `ACTOR_RUN_ID` | -
90
90
  * `actorTaskId` | `ACTOR_TASK_ID` | -
91
- * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com'`
91
+ * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com/'`
92
92
  * `containerPort` | `ACTOR_WEB_SERVER_PORT` | `4321`
93
93
  * `containerUrl` | `ACTOR_WEB_SERVER_URL` | `'http://localhost:4321'`
94
94
  * `inputKey` | `ACTOR_INPUT_KEY` | `'INPUT'`
@@ -58,7 +58,7 @@ const consts_1 = require("@apify/consts");
58
58
  * `actorPermissionLevel` | `ACTOR_PERMISSION_LEVEL` | -
59
59
  * `actorRunId` | `ACTOR_RUN_ID` | -
60
60
  * `actorTaskId` | `ACTOR_TASK_ID` | -
61
- * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com'`
61
+ * `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com/'`
62
62
  * `containerPort` | `ACTOR_WEB_SERVER_PORT` | `4321`
63
63
  * `containerUrl` | `ACTOR_WEB_SERVER_URL` | `'http://localhost:4321'`
64
64
  * `inputKey` | `ACTOR_INPUT_KEY` | `'INPUT'`
@@ -208,7 +208,7 @@ Object.defineProperty(Configuration, "DEFAULTS", {
208
208
  defaultDatasetId: consts_1.LOCAL_ACTOR_ENV_VARS[consts_1.ACTOR_ENV_VARS.DEFAULT_DATASET_ID],
209
209
  defaultRequestQueueId: consts_1.LOCAL_ACTOR_ENV_VARS[consts_1.ACTOR_ENV_VARS.DEFAULT_REQUEST_QUEUE_ID],
210
210
  inputKey: 'INPUT',
211
- apiBaseUrl: 'https://api.apify.com',
211
+ apiBaseUrl: 'https://api.apify.com/',
212
212
  apiPublicBaseUrl: 'https://api.apify.com',
213
213
  proxyStatusUrl: 'http://proxy.apify.com',
214
214
  proxyHostname: consts_1.LOCAL_APIFY_ENV_VARS[consts_1.APIFY_ENV_VARS.PROXY_HOSTNAME],
@@ -55,7 +55,12 @@ function createPatchedApifyClient(options, actor) {
55
55
  apifyClient: this,
56
56
  httpClient: this.httpClient,
57
57
  };
58
- const hasDefaultDatasetItemEvent = charging_js_1.DEFAULT_DATASET_ITEM_EVENT in actor.getChargingManager().getPricingInfo().perEventPrices;
58
+ // Charging is only configured for an initialized Actor (a platform run). A
59
+ // standalone client from `Actor.newClient()` without `Actor.init()` has no
60
+ // charging state, so skip interception rather than letting getPricingInfo() throw.
61
+ const chargingManager = actor.getChargingManager();
62
+ const hasDefaultDatasetItemEvent = chargingManager.isInitialized &&
63
+ charging_js_1.DEFAULT_DATASET_ITEM_EVENT in chargingManager.getPricingInfo().perEventPrices;
59
64
  if (!isDefaultDataset || !hasDefaultDatasetItemEvent) {
60
65
  return new apify_client_1.DatasetClient(datasetOptions);
61
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apify",
3
- "version": "3.7.3-beta.5",
3
+ "version": "3.7.3-beta.50",
4
4
  "description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
5
5
  "engines": {
6
6
  "node": ">=16.0.0"
@@ -57,7 +57,7 @@
57
57
  "@apify/consts": "^2.51.0",
58
58
  "@apify/input_secrets": "^1.2.0",
59
59
  "@apify/log": "^2.4.3",
60
- "@apify/timeout": "^0.3.0",
60
+ "@apify/timeout": "^0.4.0",
61
61
  "@apify/utilities": "^2.13.0",
62
62
  "@crawlee/core": "^3.14.1",
63
63
  "@crawlee/types": "^3.14.1",
@@ -70,10 +70,10 @@
70
70
  "ws": "^8.18.0"
71
71
  },
72
72
  "devDependencies": {
73
- "@apify/oxlint-config": "^0.2.5",
74
- "@apify/tsconfig": "^0.1.2",
73
+ "@apify/oxlint-config": "^0.3.0",
74
+ "@apify/tsconfig": "^0.2.0",
75
75
  "@commitlint/config-conventional": "^21.0.0",
76
- "@playwright/browser-chromium": "^1.46.0",
76
+ "@playwright/browser-chromium": "^1.60.0",
77
77
  "@types/content-type": "^1.1.8",
78
78
  "@types/fs-extra": "^11.0.4",
79
79
  "@types/node": "^24.0.0",
@@ -86,16 +86,16 @@
86
86
  "globby": "^16.0.0",
87
87
  "husky": "^9.1.7",
88
88
  "lint-staged": "^17.0.0",
89
- "oxfmt": "0.46.0",
90
- "oxlint": "1.67.0",
89
+ "oxfmt": "0.60.0",
90
+ "oxlint": "1.75.0",
91
91
  "oxlint-tsgolint": "0.22.0",
92
- "playwright": "^1.46.0",
93
- "puppeteer": "^24.0.0",
92
+ "playwright": "^1.60.0",
93
+ "puppeteer": "^25.0.0",
94
94
  "rimraf": "^6.0.1",
95
95
  "tsx": "^4.16.5",
96
- "typescript": "~5.9.0",
96
+ "typescript": "~6.0.0",
97
97
  "vite-tsconfig-paths": "^6.0.0",
98
- "vitest": "^3.0.0"
98
+ "vitest": "^4.0.0"
99
99
  },
100
100
  "devEngines": {
101
101
  "packageManager": {