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.
Files changed (86) hide show
  1. package/README.md +119 -1
  2. package/dist/actor.d.ts +703 -0
  3. package/dist/actor.js +1441 -0
  4. package/dist/browser-configuration.d.ts +58 -0
  5. package/dist/browser-configuration.js +128 -0
  6. package/dist/browser-locations.d.ts +5 -0
  7. package/dist/browser-locations.js +5469 -0
  8. package/dist/charging.d.ts +153 -0
  9. package/dist/charging.js +782 -0
  10. package/dist/charging_client.d.ts +18 -0
  11. package/dist/charging_client.js +49 -0
  12. package/dist/configuration.d.ts +121 -0
  13. package/dist/configuration.js +128 -0
  14. package/dist/crypto/secrets.d.ts +44 -0
  15. package/dist/crypto/secrets.js +164 -0
  16. package/dist/events/events-client.d.ts +59 -0
  17. package/dist/events/events-client.js +120 -0
  18. package/dist/events/scrapely-event-manager.d.ts +13 -0
  19. package/dist/events/scrapely-event-manager.js +61 -0
  20. package/dist/index.d.ts +29 -0
  21. package/dist/index.js +95 -0
  22. package/dist/log-env.d.ts +1 -0
  23. package/dist/log-env.js +12 -0
  24. package/dist/manifest.d.ts +30 -0
  25. package/dist/manifest.js +47 -0
  26. package/dist/patch-browser-pool.d.ts +66 -0
  27. package/dist/patch-browser-pool.js +827 -0
  28. package/dist/proxy-configuration.d.ts +118 -0
  29. package/dist/proxy-configuration.js +88 -0
  30. package/dist/request-list.d.ts +57 -0
  31. package/dist/request-list.js +79 -0
  32. package/dist/runner/docker-manager.d.ts +88 -0
  33. package/dist/runner/docker-manager.js +283 -0
  34. package/dist/runner/index.d.ts +2 -0
  35. package/dist/runner/index.js +7 -0
  36. package/dist/runner/timeout-manager.d.ts +43 -0
  37. package/dist/runner/timeout-manager.js +90 -0
  38. package/dist/scrapely-proxy-configuration.d.ts +99 -0
  39. package/dist/scrapely-proxy-configuration.js +559 -0
  40. package/dist/storage/api-storage-client.d.ts +199 -0
  41. package/dist/storage/api-storage-client.js +910 -0
  42. package/dist/storage/billing-tracker.d.ts +163 -0
  43. package/dist/storage/billing-tracker.js +260 -0
  44. package/dist/storage/dataset-client.d.ts +43 -0
  45. package/dist/storage/dataset-client.js +232 -0
  46. package/dist/storage/dataset-collection-client.d.ts +8 -0
  47. package/dist/storage/dataset-collection-client.js +75 -0
  48. package/dist/storage/dataset-push-script.d.ts +18 -0
  49. package/dist/storage/dataset-push-script.js +38 -0
  50. package/dist/storage/dragonfly-client.d.ts +94 -0
  51. package/dist/storage/dragonfly-client.js +167 -0
  52. package/dist/storage/index.d.ts +11 -0
  53. package/dist/storage/index.js +25 -0
  54. package/dist/storage/key-value-store-client.d.ts +61 -0
  55. package/dist/storage/key-value-store-client.js +306 -0
  56. package/dist/storage/kv-store-collection-client.d.ts +8 -0
  57. package/dist/storage/kv-store-collection-client.js +76 -0
  58. package/dist/storage/kvs-iteration.d.ts +17 -0
  59. package/dist/storage/kvs-iteration.js +126 -0
  60. package/dist/storage/log-manager.d.ts +114 -0
  61. package/dist/storage/log-manager.js +244 -0
  62. package/dist/storage/patch-storage.d.ts +11 -0
  63. package/dist/storage/patch-storage.js +177 -0
  64. package/dist/storage/request-queue-client.d.ts +93 -0
  65. package/dist/storage/request-queue-client.js +522 -0
  66. package/dist/storage/rq-collection-client.d.ts +8 -0
  67. package/dist/storage/rq-collection-client.js +89 -0
  68. package/dist/storage/rq-list-requests.d.ts +59 -0
  69. package/dist/storage/rq-list-requests.js +114 -0
  70. package/dist/storage/rq-lock-script.d.ts +56 -0
  71. package/dist/storage/rq-lock-script.js +127 -0
  72. package/dist/storage/run-metadata.d.ts +98 -0
  73. package/dist/storage/run-metadata.js +256 -0
  74. package/dist/storage/s3-client.d.ts +103 -0
  75. package/dist/storage/s3-client.js +302 -0
  76. package/dist/storage/ttl-manager.d.ts +70 -0
  77. package/dist/storage/ttl-manager.js +115 -0
  78. package/dist/storage/utils.d.ts +3 -0
  79. package/dist/storage/utils.js +19 -0
  80. package/dist/storage-identifiers.d.ts +20 -0
  81. package/dist/storage-identifiers.js +6 -0
  82. package/dist/utils.d.ts +54 -0
  83. package/dist/utils.js +63 -0
  84. package/dist/validator.d.ts +24 -0
  85. package/dist/validator.js +158 -0
  86. 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
- "name": "scrapely",
3
- "version": "1.2.3",
4
- "description": "Reserved package name.",
5
- "license": "UNLICENSED",
6
- "private": false,
7
- "files": [],
8
- "publishConfig": {
9
- "access": "public"
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
  }