mx-cloud 0.0.18 → 0.0.20
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/build/interpret.d.ts +3 -0
- package/build/interpret.js +109 -7
- package/build/preprocessor.js +2 -0
- package/build/types/workflow.d.ts +2 -0
- package/package.json +1 -1
package/build/interpret.d.ts
CHANGED
|
@@ -59,6 +59,9 @@ export default class Interpreter extends EventEmitter {
|
|
|
59
59
|
private blocker;
|
|
60
60
|
private cumulativeResults;
|
|
61
61
|
private autohealFailures;
|
|
62
|
+
private namedResults;
|
|
63
|
+
private screenshotCounter;
|
|
64
|
+
private serializableDataByType;
|
|
62
65
|
constructor(workflow: WorkflowFile, options?: Partial<InterpreterOptions>);
|
|
63
66
|
trackAutohealFailure(error: string): void;
|
|
64
67
|
private applyAdBlocker;
|
package/build/interpret.js
CHANGED
|
@@ -67,6 +67,12 @@ class Interpreter extends events_1.EventEmitter {
|
|
|
67
67
|
this.blocker = null;
|
|
68
68
|
this.cumulativeResults = [];
|
|
69
69
|
this.autohealFailures = [];
|
|
70
|
+
this.namedResults = {};
|
|
71
|
+
this.screenshotCounter = 0;
|
|
72
|
+
this.serializableDataByType = {
|
|
73
|
+
scrapeList: {},
|
|
74
|
+
scrapeSchema: {}
|
|
75
|
+
};
|
|
70
76
|
this.workflow = workflow.workflow;
|
|
71
77
|
this.initializedWorkflow = null;
|
|
72
78
|
this.options = Object.assign({ maxRepeats: 5, maxConcurrency: 5, serializableCallback: (data) => {
|
|
@@ -348,13 +354,31 @@ class Interpreter extends events_1.EventEmitter {
|
|
|
348
354
|
* Beware of false linter errors - here, we know better!
|
|
349
355
|
*/
|
|
350
356
|
const wawActions = {
|
|
351
|
-
screenshot: (params) => __awaiter(this, void 0, void 0, function* () {
|
|
357
|
+
screenshot: (params, nameOverride) => __awaiter(this, void 0, void 0, function* () {
|
|
352
358
|
var _a;
|
|
353
359
|
if ((_a = this.options.debugChannel) === null || _a === void 0 ? void 0 : _a.setActionType) {
|
|
354
|
-
this.options.debugChannel.setActionType(
|
|
360
|
+
this.options.debugChannel.setActionType("screenshot");
|
|
355
361
|
}
|
|
356
362
|
const screenshotBuffer = yield page.screenshot(Object.assign(Object.assign({}, params), { path: undefined }));
|
|
357
|
-
|
|
363
|
+
// Prefer explicit nameOverride (from workflow step.name or computed action name)
|
|
364
|
+
// If nameOverride is provided (non-empty) use it *as-is*.
|
|
365
|
+
// Only use counter-appended name when no nameOverride is available.
|
|
366
|
+
const explicitName = (typeof nameOverride === 'string' && nameOverride.trim().length > 0) ? nameOverride.trim() : null;
|
|
367
|
+
let screenshotName;
|
|
368
|
+
if (explicitName) {
|
|
369
|
+
screenshotName = explicitName;
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
// If no explicit name, produce a readable generated name with a counter
|
|
373
|
+
this.screenshotCounter += 1;
|
|
374
|
+
screenshotName = `Screenshot ${this.screenshotCounter}`;
|
|
375
|
+
}
|
|
376
|
+
// Pass structured metadata (name included) to binaryCallback
|
|
377
|
+
yield this.options.binaryCallback({
|
|
378
|
+
name: screenshotName,
|
|
379
|
+
data: screenshotBuffer,
|
|
380
|
+
mimeType: "image/png",
|
|
381
|
+
}, "image/png");
|
|
358
382
|
}),
|
|
359
383
|
enqueueLinks: (selector) => __awaiter(this, void 0, void 0, function* () {
|
|
360
384
|
var _a;
|
|
@@ -450,7 +474,24 @@ class Interpreter extends events_1.EventEmitter {
|
|
|
450
474
|
}
|
|
451
475
|
console.log("Total accumulated rows:", this.cumulativeResults.length);
|
|
452
476
|
console.log("Current results:", this.cumulativeResults);
|
|
453
|
-
|
|
477
|
+
// ✅ Append schema results under "scrapeSchema" → name
|
|
478
|
+
const actionType = "scrapeSchema";
|
|
479
|
+
const actionName = schema.__name || "Texts";
|
|
480
|
+
if (!this.namedResults[actionType])
|
|
481
|
+
this.namedResults[actionType] = {};
|
|
482
|
+
this.namedResults[actionType][actionName] = this.cumulativeResults;
|
|
483
|
+
if (!this.serializableDataByType[actionType])
|
|
484
|
+
this.serializableDataByType[actionType] = {};
|
|
485
|
+
if (!this.serializableDataByType[actionType][actionName]) {
|
|
486
|
+
this.serializableDataByType[actionType][actionName] = [];
|
|
487
|
+
}
|
|
488
|
+
// Store as array (matching cumulativeResults structure)
|
|
489
|
+
this.serializableDataByType[actionType][actionName] = [...this.cumulativeResults];
|
|
490
|
+
// now emit full structured object
|
|
491
|
+
yield this.options.serializableCallback({
|
|
492
|
+
scrapeList: this.serializableDataByType.scrapeList,
|
|
493
|
+
scrapeSchema: this.serializableDataByType.scrapeSchema
|
|
494
|
+
});
|
|
454
495
|
}),
|
|
455
496
|
scrapeList: (config) => __awaiter(this, void 0, void 0, function* () {
|
|
456
497
|
var _a, _b;
|
|
@@ -491,12 +532,35 @@ class Interpreter extends events_1.EventEmitter {
|
|
|
491
532
|
scrapeResults = [];
|
|
492
533
|
}
|
|
493
534
|
console.log(`ScrapeList completed with ${scrapeResults.length} results`);
|
|
494
|
-
|
|
535
|
+
// ✅ Append list results under "scrapeList" → name
|
|
536
|
+
const actionType = "scrapeList";
|
|
537
|
+
const actionName = config.__name || "List";
|
|
538
|
+
if (!this.serializableDataByType[actionType])
|
|
539
|
+
this.serializableDataByType[actionType] = {};
|
|
540
|
+
if (!this.serializableDataByType[actionType][actionName]) {
|
|
541
|
+
this.serializableDataByType[actionType][actionName] = [];
|
|
542
|
+
}
|
|
543
|
+
this.serializableDataByType[actionType][actionName].push(...scrapeResults);
|
|
544
|
+
yield this.options.serializableCallback({
|
|
545
|
+
scrapeList: this.serializableDataByType.scrapeList,
|
|
546
|
+
scrapeSchema: this.serializableDataByType.scrapeSchema
|
|
547
|
+
});
|
|
495
548
|
}
|
|
496
549
|
catch (error) {
|
|
497
550
|
console.error('ScrapeList action failed completely:', error.message);
|
|
498
551
|
// Don't throw error, just return empty array
|
|
499
|
-
|
|
552
|
+
const actionType = "scrapeList";
|
|
553
|
+
const actionName = config.__name || "List";
|
|
554
|
+
if (!this.namedResults[actionType])
|
|
555
|
+
this.namedResults[actionType] = {};
|
|
556
|
+
this.namedResults[actionType][actionName] = [];
|
|
557
|
+
if (!this.serializableDataByType[actionType])
|
|
558
|
+
this.serializableDataByType[actionType] = {};
|
|
559
|
+
this.serializableDataByType[actionType][actionName] = [];
|
|
560
|
+
yield this.options.serializableCallback({
|
|
561
|
+
scrapeList: this.serializableDataByType.scrapeList,
|
|
562
|
+
scrapeSchema: this.serializableDataByType.scrapeSchema
|
|
563
|
+
});
|
|
500
564
|
}
|
|
501
565
|
}),
|
|
502
566
|
scrapeListAuto: (config) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -569,11 +633,49 @@ class Interpreter extends events_1.EventEmitter {
|
|
|
569
633
|
return;
|
|
570
634
|
}
|
|
571
635
|
this.log(`Launching ${String(step.action)}`, logger_1.Level.LOG);
|
|
636
|
+
let stepName = null;
|
|
637
|
+
try {
|
|
638
|
+
const debug = this.options.debugChannel;
|
|
639
|
+
if (debug === null || debug === void 0 ? void 0 : debug.setActionType) {
|
|
640
|
+
debug.setActionType(String(step.action));
|
|
641
|
+
}
|
|
642
|
+
// Safely extract name for this step
|
|
643
|
+
if (step === null || step === void 0 ? void 0 : step.name) {
|
|
644
|
+
stepName = step.name;
|
|
645
|
+
}
|
|
646
|
+
else if (Array.isArray(step === null || step === void 0 ? void 0 : step.args) &&
|
|
647
|
+
step.args.length > 0 &&
|
|
648
|
+
typeof step.args[0] === "object" &&
|
|
649
|
+
"__name" in step.args[0]) {
|
|
650
|
+
stepName = step.args[0].__name;
|
|
651
|
+
}
|
|
652
|
+
else if (typeof (step === null || step === void 0 ? void 0 : step.args) === "object" &&
|
|
653
|
+
(step === null || step === void 0 ? void 0 : step.args) !== null &&
|
|
654
|
+
"__name" in step.args) {
|
|
655
|
+
stepName = step.args.__name;
|
|
656
|
+
}
|
|
657
|
+
// Default fallback
|
|
658
|
+
if (!stepName) {
|
|
659
|
+
stepName = String(step.action);
|
|
660
|
+
}
|
|
661
|
+
if (debug && typeof debug.setActionName === "function") {
|
|
662
|
+
debug.setActionName(stepName);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
catch (err) {
|
|
666
|
+
this.log(`Failed to set action name/type: ${err.message}`, logger_1.Level.WARN);
|
|
667
|
+
}
|
|
572
668
|
try {
|
|
573
669
|
if (step.action in wawActions) {
|
|
574
670
|
// "Arrayifying" here should not be needed (TS + syntax checker - only arrays; but why not)
|
|
575
671
|
const params = !step.args || Array.isArray(step.args) ? step.args : [step.args];
|
|
576
|
-
|
|
672
|
+
if (step.action === 'screenshot') {
|
|
673
|
+
// call the screenshot handler directly to allow the extra name parameter
|
|
674
|
+
yield wawActions.screenshot(...(params !== null && params !== void 0 ? params : []), stepName !== null && stepName !== void 0 ? stepName : undefined);
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
yield wawActions[step.action](...(params !== null && params !== void 0 ? params : []));
|
|
678
|
+
}
|
|
577
679
|
}
|
|
578
680
|
else {
|
|
579
681
|
if ((_a = this.options.debugChannel) === null || _a === void 0 ? void 0 : _a.setActionType) {
|
package/build/preprocessor.js
CHANGED
|
@@ -34,6 +34,8 @@ class Preprocessor {
|
|
|
34
34
|
what: joi_1.default.array().items({
|
|
35
35
|
action: joi_1.default.string().required(),
|
|
36
36
|
args: joi_1.default.array().items(joi_1.default.any()),
|
|
37
|
+
name: joi_1.default.string(),
|
|
38
|
+
actionId: joi_1.default.string()
|
|
37
39
|
}).required(),
|
|
38
40
|
})).required(),
|
|
39
41
|
});
|
|
@@ -27,6 +27,8 @@ export type CustomFunctions = 'scrape' | 'scrapeSchema' | 'scroll' | 'screenshot
|
|
|
27
27
|
export type What = {
|
|
28
28
|
action: MethodNames<Page> | CustomFunctions;
|
|
29
29
|
args?: any[];
|
|
30
|
+
name?: string;
|
|
31
|
+
actionId?: string;
|
|
30
32
|
};
|
|
31
33
|
export type PageState = Partial<BaseConditions>;
|
|
32
34
|
export type ParamType = Record<string, any>;
|