Skip to content

Commit ecdcdab

Browse files
committed
feat: validate crawlee versions in Actor.init
The SDK depends on `@crawlee/core`, but if the user installs an incompatible version of crawlee, they might end up with two installations of the `@crawlee/core` which means multiple static registers like the one for the global configuration, which breaks the integration, since the SDK will only touch the global config it sees, but it's a different one than the explicitly installed package. Closes #237
1 parent f499ed2 commit ecdcdab

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

packages/apify/src/actor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import { KeyValueStore } from './key_value_store';
4141
import { PlatformEventManager } from './platform_event_manager';
4242
import type { ProxyConfigurationOptions } from './proxy_configuration';
4343
import { ProxyConfiguration } from './proxy_configuration';
44-
import { logSystemInfo, printOutdatedSdkWarning } from './utils';
44+
import { checkCrawleeVersion, logSystemInfo, printOutdatedSdkWarning } from './utils';
4545

4646
/**
4747
* `Actor` class serves as an alternative approach to the static helpers exported from the package. It allows to pass configuration
@@ -193,6 +193,7 @@ export class Actor<Data extends Dictionary = Dictionary> {
193193

194194
this.initialized = true;
195195

196+
checkCrawleeVersion();
196197
logSystemInfo();
197198
printOutdatedSdkWarning();
198199

packages/apify/src/utils.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import log from '@apify/log';
66
import { version as crawleeVersion } from '@crawlee/core/package.json';
77
// @ts-expect-error if we enable resolveJsonModule, we end up with `src` folder in `dist`
88
import { version as apifyClientVersion } from 'apify-client/package.json';
9+
import { pathExistsSync, readJSONSync } from 'fs-extra';
910
import semver from 'semver';
1011

1112
// @ts-expect-error if we enable resolveJsonModule, we end up with `src` folder in `dist`
@@ -25,6 +26,37 @@ export function logSystemInfo() {
2526
});
2627
}
2728

29+
/**
30+
* Logs info about system, node version and apify package version.
31+
* @internal
32+
*/
33+
export function checkCrawleeVersion() {
34+
const paths = [
35+
// when users install `crawlee` package, we need to check its core dependency
36+
`${process.cwd()}/node_modules/crawlee/node_modules/@crawlee/core/package.json`,
37+
// when users install `@crawlee/cheerio` or other crawler package, we need to check the dependency under basic crawler package
38+
`${process.cwd()}/node_modules/@crawlee/basic/node_modules/@crawlee/core/package.json`,
39+
];
40+
41+
for (const path of paths) {
42+
if (!pathExistsSync(path)) {
43+
continue;
44+
}
45+
46+
let version;
47+
48+
try {
49+
version = readJSONSync(path).version;
50+
} catch {
51+
//
52+
}
53+
54+
if (version != null && version !== crawleeVersion) {
55+
throw new Error(`Detected incompatible Crawlee version used by the SDK. User installed ${version} but the SDK uses ${crawleeVersion}.`);
56+
}
57+
}
58+
}
59+
2860
/**
2961
* Prints a warning if this version of Apify SDK is outdated.
3062
* @ignore

0 commit comments

Comments
 (0)