scrapely 1.2.3 → 1.2.4
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 +119 -1
- package/dist/actor.d.ts +703 -0
- package/dist/actor.js +1441 -0
- package/dist/browser-configuration.d.ts +58 -0
- package/dist/browser-configuration.js +128 -0
- package/dist/browser-locations.d.ts +5 -0
- package/dist/browser-locations.js +5469 -0
- package/dist/charging.d.ts +153 -0
- package/dist/charging.js +782 -0
- package/dist/charging_client.d.ts +18 -0
- package/dist/charging_client.js +49 -0
- package/dist/configuration.d.ts +121 -0
- package/dist/configuration.js +128 -0
- package/dist/crypto/secrets.d.ts +44 -0
- package/dist/crypto/secrets.js +164 -0
- package/dist/events/events-client.d.ts +59 -0
- package/dist/events/events-client.js +120 -0
- package/dist/events/scrapely-event-manager.d.ts +13 -0
- package/dist/events/scrapely-event-manager.js +61 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +95 -0
- package/dist/log-env.d.ts +1 -0
- package/dist/log-env.js +12 -0
- package/dist/manifest.d.ts +30 -0
- package/dist/manifest.js +47 -0
- package/dist/patch-browser-pool.d.ts +66 -0
- package/dist/patch-browser-pool.js +827 -0
- package/dist/proxy-configuration.d.ts +118 -0
- package/dist/proxy-configuration.js +88 -0
- package/dist/request-list.d.ts +57 -0
- package/dist/request-list.js +79 -0
- package/dist/runner/docker-manager.d.ts +88 -0
- package/dist/runner/docker-manager.js +283 -0
- package/dist/runner/index.d.ts +2 -0
- package/dist/runner/index.js +7 -0
- package/dist/runner/timeout-manager.d.ts +43 -0
- package/dist/runner/timeout-manager.js +90 -0
- package/dist/scrapely-proxy-configuration.d.ts +99 -0
- package/dist/scrapely-proxy-configuration.js +559 -0
- package/dist/storage/api-storage-client.d.ts +199 -0
- package/dist/storage/api-storage-client.js +910 -0
- package/dist/storage/billing-tracker.d.ts +163 -0
- package/dist/storage/billing-tracker.js +260 -0
- package/dist/storage/dataset-client.d.ts +43 -0
- package/dist/storage/dataset-client.js +232 -0
- package/dist/storage/dataset-collection-client.d.ts +8 -0
- package/dist/storage/dataset-collection-client.js +75 -0
- package/dist/storage/dataset-push-script.d.ts +18 -0
- package/dist/storage/dataset-push-script.js +38 -0
- package/dist/storage/dragonfly-client.d.ts +94 -0
- package/dist/storage/dragonfly-client.js +167 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.js +25 -0
- package/dist/storage/key-value-store-client.d.ts +61 -0
- package/dist/storage/key-value-store-client.js +306 -0
- package/dist/storage/kv-store-collection-client.d.ts +8 -0
- package/dist/storage/kv-store-collection-client.js +76 -0
- package/dist/storage/kvs-iteration.d.ts +17 -0
- package/dist/storage/kvs-iteration.js +126 -0
- package/dist/storage/log-manager.d.ts +114 -0
- package/dist/storage/log-manager.js +244 -0
- package/dist/storage/patch-storage.d.ts +11 -0
- package/dist/storage/patch-storage.js +177 -0
- package/dist/storage/request-queue-client.d.ts +93 -0
- package/dist/storage/request-queue-client.js +522 -0
- package/dist/storage/rq-collection-client.d.ts +8 -0
- package/dist/storage/rq-collection-client.js +89 -0
- package/dist/storage/rq-list-requests.d.ts +59 -0
- package/dist/storage/rq-list-requests.js +114 -0
- package/dist/storage/rq-lock-script.d.ts +56 -0
- package/dist/storage/rq-lock-script.js +127 -0
- package/dist/storage/run-metadata.d.ts +98 -0
- package/dist/storage/run-metadata.js +256 -0
- package/dist/storage/s3-client.d.ts +103 -0
- package/dist/storage/s3-client.js +302 -0
- package/dist/storage/ttl-manager.d.ts +70 -0
- package/dist/storage/ttl-manager.js +115 -0
- package/dist/storage/utils.d.ts +3 -0
- package/dist/storage/utils.js +19 -0
- package/dist/storage-identifiers.d.ts +20 -0
- package/dist/storage-identifiers.js +6 -0
- package/dist/utils.d.ts +54 -0
- package/dist/utils.js +63 -0
- package/dist/validator.d.ts +24 -0
- package/dist/validator.js +158 -0
- package/package.json +90 -9
package/dist/utils.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.utils = void 0;
|
|
4
|
+
exports.enqueueLinks = enqueueLinks;
|
|
5
|
+
/**
|
|
6
|
+
* Enqueues links found on the page using a CSS selector.
|
|
7
|
+
*
|
|
8
|
+
* This is an Apify v2-compatible implementation that adapts to Crawlee v3 internally.
|
|
9
|
+
* It extracts URLs from the page using cheerio and adds them to the request queue.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Inside a CheerioCrawler requestHandler:
|
|
14
|
+
* await Apify.utils.enqueueLinks({
|
|
15
|
+
* $,
|
|
16
|
+
* requestQueue,
|
|
17
|
+
* selector: 'a[href*="/app/"]',
|
|
18
|
+
* baseUrl: new URL(request.url).origin,
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
async function enqueueLinks(options) {
|
|
23
|
+
const { $, requestQueue, selector = 'a[href]', baseUrl, userData = {}, transformRequestFunction } = options;
|
|
24
|
+
// Collect all matching URLs
|
|
25
|
+
const urls = [];
|
|
26
|
+
$(selector).each((_, element) => {
|
|
27
|
+
const href = $(element).attr('href');
|
|
28
|
+
if (href) {
|
|
29
|
+
// Resolve relative URLs if baseUrl is provided
|
|
30
|
+
let fullUrl;
|
|
31
|
+
try {
|
|
32
|
+
fullUrl = baseUrl ? new URL(href, baseUrl).href : href;
|
|
33
|
+
urls.push(fullUrl);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Skip invalid URLs
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// Deduplicate URLs
|
|
41
|
+
const uniqueUrls = [...new Set(urls)];
|
|
42
|
+
// Add each URL to the request queue
|
|
43
|
+
for (const url of uniqueUrls) {
|
|
44
|
+
const request = {
|
|
45
|
+
url,
|
|
46
|
+
userData: { ...userData },
|
|
47
|
+
};
|
|
48
|
+
// Apply transformation if provided
|
|
49
|
+
const transformed = transformRequestFunction
|
|
50
|
+
? transformRequestFunction(request)
|
|
51
|
+
: request;
|
|
52
|
+
if (transformed) {
|
|
53
|
+
await requestQueue.addRequest(transformed);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Utility namespace providing Apify v2-compatible helper functions.
|
|
59
|
+
* These adapt to Crawlee v3 APIs internally.
|
|
60
|
+
*/
|
|
61
|
+
exports.utils = {
|
|
62
|
+
enqueueLinks,
|
|
63
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scrapely Actor Package Validator
|
|
3
|
+
* Validates actor package format
|
|
4
|
+
*/
|
|
5
|
+
import { ScrapelyManifest } from './manifest.js';
|
|
6
|
+
export interface ValidationResult {
|
|
7
|
+
valid: boolean;
|
|
8
|
+
errors: string[];
|
|
9
|
+
manifest?: ScrapelyManifest;
|
|
10
|
+
packageJson?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Validate an actor package directory
|
|
14
|
+
* Checks for: package.json, package.json, entrypoint file
|
|
15
|
+
*/
|
|
16
|
+
export declare function validatePackage(packageDir: string): ValidationResult;
|
|
17
|
+
/**
|
|
18
|
+
* Get normalized manifest with defaults applied
|
|
19
|
+
*/
|
|
20
|
+
export declare function getNormalizedManifest(manifest: ScrapelyManifest): Required<Pick<ScrapelyManifest, 'name' | 'version' | 'entrypoint' | 'maxMemory' | 'maxTimeout'>> & Omit<ScrapelyManifest, 'maxMemory' | 'maxTimeout'>;
|
|
21
|
+
/**
|
|
22
|
+
* CLI entry point for validation
|
|
23
|
+
*/
|
|
24
|
+
export declare function runValidator(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Scrapely Actor Package Validator
|
|
4
|
+
* Validates actor package format
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.validatePackage = validatePackage;
|
|
41
|
+
exports.getNormalizedManifest = getNormalizedManifest;
|
|
42
|
+
exports.runValidator = runValidator;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const manifest_js_1 = require("./manifest.js");
|
|
46
|
+
/**
|
|
47
|
+
* Validate an actor package directory
|
|
48
|
+
* Checks for: package.json, package.json, entrypoint file
|
|
49
|
+
*/
|
|
50
|
+
function validatePackage(packageDir) {
|
|
51
|
+
const errors = [];
|
|
52
|
+
let manifest;
|
|
53
|
+
let packageJson;
|
|
54
|
+
// Check directory exists
|
|
55
|
+
if (!fs.existsSync(packageDir)) {
|
|
56
|
+
return { valid: false, errors: [`Directory not found: ${packageDir}`] };
|
|
57
|
+
}
|
|
58
|
+
if (!fs.statSync(packageDir).isDirectory()) {
|
|
59
|
+
return { valid: false, errors: [`Not a directory: ${packageDir}`] };
|
|
60
|
+
}
|
|
61
|
+
// Check package.json
|
|
62
|
+
const manifestPath = path.join(packageDir, 'package.json');
|
|
63
|
+
if (!fs.existsSync(manifestPath)) {
|
|
64
|
+
errors.push('Missing package.json');
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
try {
|
|
68
|
+
const content = fs.readFileSync(manifestPath, 'utf-8');
|
|
69
|
+
const parsed = JSON.parse(content);
|
|
70
|
+
const manifestErrors = (0, manifest_js_1.validateManifest)(parsed);
|
|
71
|
+
if (manifestErrors.length > 0) {
|
|
72
|
+
errors.push(...manifestErrors.map(e => `package.json: ${e}`));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
manifest = parsed;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
errors.push(`package.json: Invalid JSON - ${err.message}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Check package.json
|
|
83
|
+
const packageJsonPath = path.join(packageDir, 'package.json');
|
|
84
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
85
|
+
errors.push('Missing package.json');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
try {
|
|
89
|
+
const content = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
90
|
+
packageJson = JSON.parse(content);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
errors.push(`package.json: Invalid JSON - ${err.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Check entrypoint file exists
|
|
97
|
+
if (manifest?.entrypoint) {
|
|
98
|
+
const entrypointPath = path.join(packageDir, manifest.entrypoint);
|
|
99
|
+
if (!fs.existsSync(entrypointPath)) {
|
|
100
|
+
errors.push(`Entrypoint not found: ${manifest.entrypoint}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
valid: errors.length === 0,
|
|
105
|
+
errors,
|
|
106
|
+
manifest,
|
|
107
|
+
packageJson,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get normalized manifest with defaults applied
|
|
112
|
+
*/
|
|
113
|
+
function getNormalizedManifest(manifest) {
|
|
114
|
+
return {
|
|
115
|
+
...manifest,
|
|
116
|
+
maxMemory: manifest.maxMemory ?? manifest_js_1.DEFAULT_MAX_MEMORY,
|
|
117
|
+
maxTimeout: manifest.maxTimeout ?? manifest_js_1.DEFAULT_MAX_TIMEOUT,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* CLI entry point for validation
|
|
122
|
+
*/
|
|
123
|
+
async function runValidator(args) {
|
|
124
|
+
const packageDir = args[0] || process.cwd();
|
|
125
|
+
console.log(`[Scrapely] Validating package: ${packageDir}\n`);
|
|
126
|
+
const result = validatePackage(packageDir);
|
|
127
|
+
if (result.valid) {
|
|
128
|
+
console.log('✓ Package is valid\n');
|
|
129
|
+
if (result.manifest) {
|
|
130
|
+
const normalized = getNormalizedManifest(result.manifest);
|
|
131
|
+
console.log('Manifest:');
|
|
132
|
+
console.log(` Name: ${normalized.name}`);
|
|
133
|
+
console.log(` Version: ${normalized.version}`);
|
|
134
|
+
console.log(` Entrypoint: ${normalized.entrypoint}`);
|
|
135
|
+
console.log(` Max Memory: ${normalized.maxMemory} MB`);
|
|
136
|
+
console.log(` Max Timeout: ${normalized.maxTimeout} seconds`);
|
|
137
|
+
if (normalized.description) {
|
|
138
|
+
console.log(` Description: ${normalized.description}`);
|
|
139
|
+
}
|
|
140
|
+
if (normalized.author) {
|
|
141
|
+
console.log(` Author: ${normalized.author}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
process.exit(0);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
console.log('✗ Package validation failed\n');
|
|
148
|
+
console.log('Errors:');
|
|
149
|
+
for (const error of result.errors) {
|
|
150
|
+
console.log(` - ${error}`);
|
|
151
|
+
}
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Run if called directly (CommonJS compatible)
|
|
156
|
+
if (require.main === module) {
|
|
157
|
+
runValidator(process.argv.slice(2));
|
|
158
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,92 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
"name": "scrapely",
|
|
3
|
+
"version": "1.2.4",
|
|
4
|
+
"description": "Apify-like scraping platform using Evomi browser infrastructure",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"private": false,
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/SandeepDev1/scrapely.git"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"registry": "https://registry.npmjs.org",
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "npx tsx tests/test-mvp.ts",
|
|
21
|
+
"test:charging": "npx tsx --test tests/charging-pending.test.ts",
|
|
22
|
+
"test:charging-client": "npx tsx --test tests/charging-client.test.ts",
|
|
23
|
+
"test:proxy": "npx tsx --test tests/proxy-configuration.test.ts",
|
|
24
|
+
"test:browser-pool": "npx tsx --test tests/patch-browser-pool.test.ts",
|
|
25
|
+
"test:browser-config": "npx tsx --test tests/browser-configuration.test.ts",
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"setup:gvisor": "bash scripts/setup-gvisor.sh",
|
|
28
|
+
"setup:server": "bash scripts/setup-server.sh",
|
|
29
|
+
"prod": "bash scripts/deploy-prod.sh",
|
|
30
|
+
"prod:update": "bash scripts/deploy-prod.sh --update-only",
|
|
31
|
+
"migrate": "npx tsx scripts/run-migration.ts",
|
|
32
|
+
"test:local-run": "npx tsx --test tests/local-run.test.ts",
|
|
33
|
+
"test:init-rollback": "npx tsx --test tests/init-rollback.test.ts",
|
|
34
|
+
"test:apify-parity": "npx tsx --test tests/apify-parity.test.ts",
|
|
35
|
+
"test:run-control": "npx tsx --test tests/run-control.test.ts",
|
|
36
|
+
"test:rq-list": "npx tsx --test tests/rq-list-requests.test.ts"
|
|
37
|
+
},
|
|
38
|
+
"author": "SandeepDev1",
|
|
39
|
+
"license": "ISC",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@aws-sdk/client-s3": "^3.700.0",
|
|
42
|
+
"@crawlee/browser": "^3.16.0",
|
|
43
|
+
"@crawlee/browser-pool": "^3.16.0",
|
|
44
|
+
"@crawlee/playwright": "^3.16.0",
|
|
45
|
+
"basic-ftp": "^6.0.1",
|
|
46
|
+
"crawlee": "^3.16.0",
|
|
47
|
+
"dockerode": "^4.0.9",
|
|
48
|
+
"ioredis": "^6.0.0",
|
|
49
|
+
"ip-address": "10.3.1",
|
|
50
|
+
"lodash": "^4.18.1",
|
|
51
|
+
"mysql2": "^3.23.1",
|
|
52
|
+
"playwright": "^1.58.2",
|
|
53
|
+
"scrapely-client": "^2.25.2",
|
|
54
|
+
"tar-fs": "2.1.5",
|
|
55
|
+
"ws": "^8.18.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/dockerode": "^4.0.1",
|
|
59
|
+
"@types/node": "^25.5.0",
|
|
60
|
+
"@types/ws": "^8.5.10",
|
|
61
|
+
"dotenv": "^17.3.1",
|
|
62
|
+
"puppeteer-core": "^24.43.1",
|
|
63
|
+
"tsx": "^4.21.0",
|
|
64
|
+
"typescript": "^5.7.0"
|
|
65
|
+
},
|
|
66
|
+
"overrides": {
|
|
67
|
+
"adm-zip": "^0.6.0",
|
|
68
|
+
"tar-fs": "2.1.5",
|
|
69
|
+
"yargs": "18.1.0",
|
|
70
|
+
"axios": "^1.18.0",
|
|
71
|
+
"brace-expansion": "5.0.9",
|
|
72
|
+
"fast-xml-builder": "^1.2.1",
|
|
73
|
+
"file-type": "^21.3.3",
|
|
74
|
+
"follow-redirects": "^1.16.0",
|
|
75
|
+
"@crawlee/core": {
|
|
76
|
+
"ow": "0.28.2"
|
|
77
|
+
},
|
|
78
|
+
"@crawlee/utils": {
|
|
79
|
+
"ow": "0.28.2"
|
|
80
|
+
},
|
|
81
|
+
"header-generator": {
|
|
82
|
+
"ow": "0.28.2"
|
|
83
|
+
},
|
|
84
|
+
"scrapely-client": {
|
|
85
|
+
"ow": "0.28.2"
|
|
86
|
+
},
|
|
87
|
+
"uuid": "^11.1.1",
|
|
88
|
+
"@inquirer/external-editor": "3.0.3",
|
|
89
|
+
"nanoid": "5.1.16",
|
|
90
|
+
"browserslist": "4.28.7"
|
|
91
|
+
}
|
|
11
92
|
}
|