Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20,008 changes: 3,391 additions & 16,617 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"lint:fix": "eslint \"packages/**/src/**/*\" test --fix"
},
"devDependencies": {
"@apify/consts": "^2.4.1",
"@apify/consts": "^2.20.0",
"@apify/eslint-config-ts": "^0.3.0",
"@apify/input_secrets": "^1.1.1",
"@apify/tsconfig": "^0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ export class CrawlerSetup implements CrawlerSetupOptions {
}

const devToolsServer = new DevToolsServer({
containerHost: new URL(process.env.APIFY_CONTAINER_URL!).host,
devToolsServerPort: process.env.APIFY_CONTAINER_PORT,
containerHost: new URL(process.env.ACTOR_WEB_SERVER_URL!).host,
devToolsServerPort: process.env.ACTOR_WEB_SERVER_PORT,
chromeRemoteDebuggingPort: CHROME_DEBUGGER_PORT,
});
await devToolsServer.start();
Expand Down
52 changes: 35 additions & 17 deletions packages/apify/src/actor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ow from 'ow';
import { createPrivateKey } from 'node:crypto';
import { decryptInputSecrets } from '@apify/input_secrets';
import { ENV_VARS, INTEGER_ENV_VARS } from '@apify/consts';
import { ACTOR_ENV_VARS, APIFY_ENV_VARS, INTEGER_ENV_VARS } from '@apify/consts';
import { addTimeoutToPromise } from '@apify/timeout';
import log, { LogLevel } from '@apify/log';
import type {
Expand Down Expand Up @@ -485,7 +485,7 @@ export class Actor<Data extends Dictionary = Dictionary> {

const runId = this.config.get('actorRunId')!;
if (!runId) {
throw new Error(`Environment variable ${ENV_VARS.ACTOR_RUN_ID} is not set!`);
throw new Error(`Environment variable ${ACTOR_ENV_VARS.RUN_ID} is not set!`);
}

return this.apifyClient.webhooks().create({
Expand Down Expand Up @@ -846,9 +846,27 @@ export class Actor<Data extends Dictionary = Dictionary> {
}

/**
* Returns a new {@apilink ApifyEnv} object which contains information parsed from all the `APIFY_XXX` environment variables.
* Modifies Actor env vars so parsing respects the structure of {@apilink ApifyEnv} interface.
*/
private getModifiedActorEnvVars() {
const modifiedActorEnvVars: Record<string, string> = {};

Object.entries(ACTOR_ENV_VARS).forEach(([k, v]) => {
// Prepend `ACTOR_` to env vars so ApifyEnv structure is preserved
if (['ID', 'RUN_ID', 'TASK_ID'].includes(k)) {
modifiedActorEnvVars[`ACTOR_${k}`] = v;
} else {
modifiedActorEnvVars[k] = v;
}
});

return modifiedActorEnvVars;
}

/**
* Returns a new {@apilink ApifyEnv} object which contains information parsed from all the Apify environment variables.
*
* For the list of the `APIFY_XXX` environment variables, see
* For the list of the Apify environment variables, see
* [Actor documentation](https://docs.apify.com/actor/run#environment-variables).
* If some variables are not defined or are invalid, the corresponding value in the resulting object will be null.
* @ignore
Expand All @@ -858,7 +876,7 @@ export class Actor<Data extends Dictionary = Dictionary> {
const env = process.env || {};
const envVars = {} as ApifyEnv;

for (const [shortName, fullName] of Object.entries(ENV_VARS)) {
for (const [shortName, fullName] of Object.entries({ ...APIFY_ENV_VARS, ...this.getModifiedActorEnvVars() })) {
const camelCaseName = snakeCaseToCamelCase(shortName) as keyof ApifyEnv;
let value: string | number | Date | undefined = env[fullName];

Expand Down Expand Up @@ -899,7 +917,7 @@ export class Actor<Data extends Dictionary = Dictionary> {
* @ignore
*/
isAtHome(): boolean {
return !!process.env[ENV_VARS.IS_AT_HOME];
return !!process.env[APIFY_ENV_VARS.IS_AT_HOME];
}

/**
Expand Down Expand Up @@ -1421,9 +1439,9 @@ export class Actor<Data extends Dictionary = Dictionary> {
}

/**
* Returns a new {@apilink ApifyEnv} object which contains information parsed from all the `APIFY_XXX` environment variables.
* Returns a new {@apilink ApifyEnv} object which contains information parsed from all the Apify environment variables.
*
* For the list of the `APIFY_XXX` environment variables, see
* For the list of the Apify environment variables, see
* [Actor documentation](https://docs.apify.com/actor/run#environment-variables).
* If some of the variables are not defined or are invalid, the corresponding value in the resulting object will be null.
*/
Expand Down Expand Up @@ -1496,22 +1514,22 @@ export interface InitOptions {
export interface MainOptions extends ExitOptions, InitOptions {}

/**
* Parsed representation of the `APIFY_XXX` environmental variables.
* Parsed representation of the Apify environment variables.
* This object is returned by the {@apilink Actor.getEnv} function.
*/
export interface ApifyEnv {
/**
* ID of the actor (APIFY_ACTOR_ID)
* ID of the actor (ACTOR_ID)
*/
actorId: string | null;

/**
* ID of the actor run (APIFY_ACTOR_RUN_ID)
* ID of the actor run (ACTOR_RUN_ID)
*/
actorRunId: string | null;

/**
* ID of the actor task (APIFY_ACTOR_TASK_ID)
* ID of the actor task (ACTOR_TASK_ID)
*/
actorTaskId: string | null;

Expand All @@ -1528,30 +1546,30 @@ export interface ApifyEnv {
token: string | null;

/**
* Date when the actor was started (APIFY_STARTED_AT)
* Date when the actor was started (ACTOR_STARTED_AT)
*/
startedAt: Date | null;

/**
* Date when the actor will time out (APIFY_TIMEOUT_AT)
* Date when the actor will time out (ACTOR_TIMEOUT_AT)
*/
timeoutAt: Date | null;

/**
* ID of the key-value store where input and output data of this
* actor is stored (APIFY_DEFAULT_KEY_VALUE_STORE_ID)
* actor is stored (ACTOR_DEFAULT_KEY_VALUE_STORE_ID)
*/
defaultKeyValueStoreId: string | null;

/**
* ID of the dataset where input and output data of this
* actor is stored (APIFY_DEFAULT_DATASET_ID)
* actor is stored (ACTOR_DEFAULT_DATASET_ID)
*/
defaultDatasetId: string | null;

/**
* Amount of memory allocated for the actor,
* in megabytes (APIFY_MEMORY_MBYTES)
* in megabytes (ACTOR_MEMORY_MBYTES)
*/
memoryMbytes: number | null;
}
Expand Down
56 changes: 37 additions & 19 deletions packages/apify/src/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ENV_VARS, LOCAL_ENV_VARS } from '@apify/consts';
import {
ACTOR_ENV_VARS,
APIFY_ENV_VARS,
LOCAL_ACTOR_ENV_VARS,
LOCAL_APIFY_ENV_VARS,
} from '@apify/consts';
import { Configuration as CoreConfiguration } from '@crawlee/core';
import type { ConfigurationOptions as CoreConfigurationOptions } from '@crawlee/core';

Expand Down Expand Up @@ -59,27 +64,27 @@ export interface ConfigurationOptions extends CoreConfigurationOptions {
*
* Key | Environment Variable | Default Value
* ---|---|---
* `memoryMbytes` | `APIFY_MEMORY_MBYTES` | -
* `memoryMbytes` | `ACTOR_MEMORY_MBYTES` | -
* `headless` | `APIFY_HEADLESS` | -
* `persistStateIntervalMillis` | `APIFY_PERSIST_STATE_INTERVAL_MILLIS` | `60e3`
* `token` | `APIFY_TOKEN` | -
* `isAtHome` | `APIFY_IS_AT_HOME` | -
* `defaultDatasetId` | `APIFY_DEFAULT_DATASET_ID` | `'default'`
* `defaultKeyValueStoreId` | `APIFY_DEFAULT_KEY_VALUE_STORE_ID` | `'default'`
* `defaultRequestQueueId` | `APIFY_DEFAULT_REQUEST_QUEUE_ID` | `'default'`
* `defaultDatasetId` | `ACTOR_DEFAULT_DATASET_ID` | `'default'`
* `defaultKeyValueStoreId` | `ACTOR_DEFAULT_KEY_VALUE_STORE_ID` | `'default'`
* `defaultRequestQueueId` | `ACTOR_DEFAULT_REQUEST_QUEUE_ID` | `'default'`
*
* ## Advanced Configuration Options
*
* Key | Environment Variable | Default Value
* ---|---|---
* `actorEventsWsUrl` | `APIFY_ACTOR_EVENTS_WS_URL` | -
* `actorId` | `APIFY_ACTOR_ID` | -
* `actorRunId` | `APIFY_ACTOR_RUN_ID` | -
* `actorTaskId` | `APIFY_ACTOR_TASK_ID` | -
* `actorEventsWsUrl` | `ACTOR_EVENTS_WEBSOCKET_URL` | -
* `actorId` | `ACTOR_ID` | -
* `actorRunId` | `ACTOR_RUN_ID` | -
* `actorTaskId` | `ACTOR_TASK_ID` | -
* `apiBaseUrl` | `APIFY_API_BASE_URL` | `'https://api.apify.com'`
* `containerPort` | `APIFY_CONTAINER_PORT` | `4321`
* `containerUrl` | `APIFY_CONTAINER_URL` | `'http://localhost:4321'`
* `inputKey` | `APIFY_INPUT_KEY` | `'INPUT'`
* `containerPort` | `ACTOR_WEB_SERVER_PORT` | `4321`
* `containerUrl` | `ACTOR_WEB_SERVER_URL` | `'http://localhost:4321'`
* `inputKey` | `ACTOR_INPUT_KEY` | `'INPUT'`
* `metamorphAfterSleepMillis` | `APIFY_METAMORPH_AFTER_SLEEP_MILLIS` | `300e3`
* `proxyHostname` | `APIFY_PROXY_HOSTNAME` | `'proxy.apify.com'`
* `proxyPassword` | `APIFY_PROXY_PASSWORD` | -
Expand Down Expand Up @@ -133,6 +138,19 @@ export class Configuration extends CoreConfiguration {
APIFY_PROXY_PORT: 'proxyPort',
APIFY_INPUT_SECRETS_PRIVATE_KEY_FILE: 'inputSecretsPrivateKeyFile',
APIFY_INPUT_SECRETS_PRIVATE_KEY_PASSPHRASE: 'inputSecretsPrivateKeyPassphrase',

// Actor env vars
ACTOR_DEFAULT_DATASET_ID: 'defaultDatasetId',
ACTOR_DEFAULT_KEY_VALUE_STORE_ID: 'defaultKeyValueStoreId',
ACTOR_DEFAULT_REQUEST_QUEUE_ID: 'defaultRequestQueueId',
ACTOR_EVENTS_WEBSOCKET_URL: 'actorEventsWsUrl',
ACTOR_ID: 'actorId',
ACTOR_INPUT_KEY: 'inputKey',
ACTOR_MEMORY_MBYTES: 'memoryMbytes',
ACTOR_RUN_ID: 'actorRunId',
ACTOR_TASK_ID: 'actorTaskId',
ACTOR_WEB_SERVER_PORT: 'containerPort',
ACTOR_WEB_SERVER_URL: 'containerUrl',
};

protected static override INTEGER_VARS = [...super.INTEGER_VARS, 'proxyPort', 'containerPort', 'metamorphAfterSleepMillis'];
Expand All @@ -141,16 +159,16 @@ export class Configuration extends CoreConfiguration {

protected static override DEFAULTS = {
...super.DEFAULTS,
defaultKeyValueStoreId: LOCAL_ENV_VARS[ENV_VARS.DEFAULT_KEY_VALUE_STORE_ID],
defaultDatasetId: LOCAL_ENV_VARS[ENV_VARS.DEFAULT_DATASET_ID],
defaultRequestQueueId: LOCAL_ENV_VARS[ENV_VARS.DEFAULT_REQUEST_QUEUE_ID],
defaultKeyValueStoreId: LOCAL_ACTOR_ENV_VARS[ACTOR_ENV_VARS.DEFAULT_KEY_VALUE_STORE_ID],
defaultDatasetId: LOCAL_ACTOR_ENV_VARS[ACTOR_ENV_VARS.DEFAULT_DATASET_ID],
defaultRequestQueueId: LOCAL_ACTOR_ENV_VARS[ACTOR_ENV_VARS.DEFAULT_REQUEST_QUEUE_ID],
inputKey: 'INPUT',
apiBaseUrl: 'https://api.apify.com',
proxyStatusUrl: 'http://proxy.apify.com',
proxyHostname: LOCAL_ENV_VARS[ENV_VARS.PROXY_HOSTNAME],
proxyPort: +LOCAL_ENV_VARS[ENV_VARS.PROXY_PORT],
containerPort: +LOCAL_ENV_VARS[ENV_VARS.CONTAINER_PORT],
containerUrl: LOCAL_ENV_VARS[ENV_VARS.CONTAINER_URL],
proxyHostname: LOCAL_APIFY_ENV_VARS[APIFY_ENV_VARS.PROXY_HOSTNAME],
proxyPort: +LOCAL_APIFY_ENV_VARS[APIFY_ENV_VARS.PROXY_PORT],
containerPort: +LOCAL_ACTOR_ENV_VARS[ACTOR_ENV_VARS.WEB_SERVER_PORT],
containerUrl: LOCAL_ACTOR_ENV_VARS[ACTOR_ENV_VARS.WEB_SERVER_URL],
metamorphAfterSleepMillis: 300e3,
persistStateIntervalMillis: 60e3, // This value is mentioned in jsdoc in `events.js`, if you update it here, update it there too.
};
Expand Down
4 changes: 2 additions & 2 deletions packages/apify/src/platform_event_manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ACTOR_EVENT_NAMES, ENV_VARS } from '@apify/consts';
import { ACTOR_EVENT_NAMES, ACTOR_ENV_VARS } from '@apify/consts';
import WebSocket from 'ws';
import { EventType, EventManager } from '@crawlee/core';
import { betterClearInterval } from '@apify/utilities';
Expand Down Expand Up @@ -64,7 +64,7 @@ export class PlatformEventManager extends EventManager {

// Locally there is no web socket to connect, so just print a log message.
if (!eventsWsUrl) {
this.log.debug(`Environment variable ${ENV_VARS.ACTOR_EVENTS_WS_URL} is not set, no events from Apify platform will be emitted.`);
this.log.debug(`Environment variable ${ACTOR_ENV_VARS.EVENTS_WEBSOCKET_URL} is not set, no events from Apify platform will be emitted.`);
return;
}

Expand Down
6 changes: 3 additions & 3 deletions packages/apify/src/proxy_configuration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ow from 'ow';
import { APIFY_PROXY_VALUE_REGEX, ENV_VARS } from '@apify/consts';
import { APIFY_PROXY_VALUE_REGEX, APIFY_ENV_VARS } from '@apify/consts';
import type {
ProxyConfigurationOptions as CoreProxyConfigurationOptions,
ProxyInfo as CoreProxyInfo,
Expand Down Expand Up @@ -328,8 +328,8 @@ export class ProxyConfiguration extends CoreProxyConfiguration {
}

if (!this.password) {
throw new Error(`Apify Proxy password must be provided using options.password or the "${ENV_VARS.PROXY_PASSWORD}" environment variable. `
+ `If you add the "${ENV_VARS.TOKEN}" environment variable, the password will be automatically inferred.`);
throw new Error(`Apify Proxy password must be provided using options.password or the "${APIFY_ENV_VARS.PROXY_PASSWORD}" environment variable. `
+ `If you add the "${APIFY_ENV_VARS.TOKEN}" environment variable, the password will be automatically inferred.`);
}
}

Expand Down
6 changes: 3 additions & 3 deletions packages/apify/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import log from '@apify/log';
import { ENV_VARS } from '@apify/consts';
import { APIFY_ENV_VARS } from '@apify/consts';
import { type } from 'node:os';
import semver from 'semver';

Expand Down Expand Up @@ -29,8 +29,8 @@ export function logSystemInfo() {
* @ignore
*/
export function printOutdatedSdkWarning() {
if (process.env[ENV_VARS.DISABLE_OUTDATED_WARNING]) return;
const latestApifyVersion = process.env[ENV_VARS.SDK_LATEST_VERSION];
if (process.env[APIFY_ENV_VARS.DISABLE_OUTDATED_WARNING]) return;
const latestApifyVersion = process.env[APIFY_ENV_VARS.SDK_LATEST_VERSION];
if (!latestApifyVersion || !semver.lt(apifyVersion, latestApifyVersion)) return;

log.warning(`You are using an outdated version (${apifyVersion}) of Apify SDK. We recommend you to update to the latest version (${latestApifyVersion}).
Expand Down
Loading