scrapme-flow 0.0.0-stage → 0.2.0
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/LICENSE +21 -0
- package/README.md +126 -2
- package/dist/src/commands/commands.models.d.ts +41 -0
- package/dist/src/commands/commands.models.js +2 -0
- package/dist/src/commands/commands.models.js.map +1 -0
- package/dist/src/commands/save-document.command.d.ts +9 -0
- package/dist/src/commands/save-document.command.js +33 -0
- package/dist/src/commands/save-document.command.js.map +1 -0
- package/dist/src/commands/scrape-page.command.d.ts +20 -0
- package/dist/src/commands/scrape-page.command.js +93 -0
- package/dist/src/commands/scrape-page.command.js.map +1 -0
- package/dist/src/commands/send-mail.command.d.ts +11 -0
- package/dist/src/commands/send-mail.command.js +39 -0
- package/dist/src/commands/send-mail.command.js.map +1 -0
- package/dist/src/config/config-builder.d.ts +24 -0
- package/dist/src/config/config-builder.js +129 -0
- package/dist/src/config/config-builder.js.map +1 -0
- package/dist/src/config/config-loader.d.ts +10 -0
- package/dist/src/config/config-loader.js +79 -0
- package/dist/src/config/config-loader.js.map +1 -0
- package/dist/src/config/config.models.d.ts +144 -0
- package/dist/src/config/config.models.js +2 -0
- package/dist/src/config/config.models.js.map +1 -0
- package/dist/src/config/config.schema.d.ts +75 -0
- package/dist/src/config/config.schema.js +87 -0
- package/dist/src/config/config.schema.js.map +1 -0
- package/dist/src/config/dsn-check.d.ts +5 -0
- package/dist/src/config/dsn-check.js +12 -0
- package/dist/src/config/dsn-check.js.map +1 -0
- package/dist/src/di/container.d.ts +13 -0
- package/dist/src/di/container.js +67 -0
- package/dist/src/di/container.js.map +1 -0
- package/dist/src/di/types.d.ts +27 -0
- package/dist/src/di/types.js +28 -0
- package/dist/src/di/types.js.map +1 -0
- package/dist/src/flow/command-executor.d.ts +18 -0
- package/dist/src/flow/command-executor.js +87 -0
- package/dist/src/flow/command-executor.js.map +1 -0
- package/dist/src/flow/command-resolver.d.ts +11 -0
- package/dist/src/flow/command-resolver.js +35 -0
- package/dist/src/flow/command-resolver.js.map +1 -0
- package/dist/src/flow/flow-catalog.d.ts +12 -0
- package/dist/src/flow/flow-catalog.js +31 -0
- package/dist/src/flow/flow-catalog.js.map +1 -0
- package/dist/src/flow/flow-errors.d.ts +66 -0
- package/dist/src/flow/flow-errors.js +119 -0
- package/dist/src/flow/flow-errors.js.map +1 -0
- package/dist/src/flow/flow-job-processor.d.ts +33 -0
- package/dist/src/flow/flow-job-processor.js +208 -0
- package/dist/src/flow/flow-job-processor.js.map +1 -0
- package/dist/src/flow/flow-params.d.ts +9 -0
- package/dist/src/flow/flow-params.js +52 -0
- package/dist/src/flow/flow-params.js.map +1 -0
- package/dist/src/flow/flow-runner.d.ts +36 -0
- package/dist/src/flow/flow-runner.js +209 -0
- package/dist/src/flow/flow-runner.js.map +1 -0
- package/dist/src/flow/flow-scheduler.d.ts +24 -0
- package/dist/src/flow/flow-scheduler.js +96 -0
- package/dist/src/flow/flow-scheduler.js.map +1 -0
- package/dist/src/flow/flow-validator.d.ts +29 -0
- package/dist/src/flow/flow-validator.js +141 -0
- package/dist/src/flow/flow-validator.js.map +1 -0
- package/dist/src/flow/flow.d.ts +32 -0
- package/dist/src/flow/flow.js +50 -0
- package/dist/src/flow/flow.js.map +1 -0
- package/dist/src/flow/flow.models.d.ts +288 -0
- package/dist/src/flow/flow.models.js +38 -0
- package/dist/src/flow/flow.models.js.map +1 -0
- package/dist/src/flow/retry-policy.d.ts +9 -0
- package/dist/src/flow/retry-policy.js +15 -0
- package/dist/src/flow/retry-policy.js.map +1 -0
- package/dist/src/flow/state-path.d.ts +21 -0
- package/dist/src/flow/state-path.js +37 -0
- package/dist/src/flow/state-path.js.map +1 -0
- package/dist/src/flow/step-input-builder.d.ts +15 -0
- package/dist/src/flow/step-input-builder.js +63 -0
- package/dist/src/flow/step-input-builder.js.map +1 -0
- package/dist/src/flows/scrape.flow.d.ts +6 -0
- package/dist/src/flows/scrape.flow.js +31 -0
- package/dist/src/flows/scrape.flow.js.map +1 -0
- package/dist/src/index.d.ts +57 -0
- package/dist/src/index.js +50 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logging/logger.d.ts +17 -0
- package/dist/src/logging/logger.js +55 -0
- package/dist/src/logging/logger.js.map +1 -0
- package/dist/src/logging/logger.models.d.ts +25 -0
- package/dist/src/logging/logger.models.js +7 -0
- package/dist/src/logging/logger.models.js.map +1 -0
- package/dist/src/mail/mail.models.d.ts +15 -0
- package/dist/src/mail/mail.models.js +2 -0
- package/dist/src/mail/mail.models.js.map +1 -0
- package/dist/src/mail/smtp-mailer.d.ts +13 -0
- package/dist/src/mail/smtp-mailer.js +70 -0
- package/dist/src/mail/smtp-mailer.js.map +1 -0
- package/dist/src/mail/unconfigured-mailer.d.ts +6 -0
- package/dist/src/mail/unconfigured-mailer.js +20 -0
- package/dist/src/mail/unconfigured-mailer.js.map +1 -0
- package/dist/src/models.d.ts +11 -0
- package/dist/src/models.js +10 -0
- package/dist/src/models.js.map +1 -0
- package/dist/src/monitor/monitor-api.d.ts +18 -0
- package/dist/src/monitor/monitor-api.js +62 -0
- package/dist/src/monitor/monitor-api.js.map +1 -0
- package/dist/src/monitor/monitor-server.d.ts +33 -0
- package/dist/src/monitor/monitor-server.js +142 -0
- package/dist/src/monitor/monitor-server.js.map +1 -0
- package/dist/src/monitor/monitor.models.d.ts +27 -0
- package/dist/src/monitor/monitor.models.js +2 -0
- package/dist/src/monitor/monitor.models.js.map +1 -0
- package/dist/src/queue/pg-boss-flow-queue.d.ts +22 -0
- package/dist/src/queue/pg-boss-flow-queue.js +102 -0
- package/dist/src/queue/pg-boss-flow-queue.js.map +1 -0
- package/dist/src/queue/queue.models.d.ts +38 -0
- package/dist/src/queue/queue.models.js +2 -0
- package/dist/src/queue/queue.models.js.map +1 -0
- package/dist/src/reporting/lighty-error-reporter.d.ts +24 -0
- package/dist/src/reporting/lighty-error-reporter.js +96 -0
- package/dist/src/reporting/lighty-error-reporter.js.map +1 -0
- package/dist/src/reporting/log-error-reporter.d.ts +12 -0
- package/dist/src/reporting/log-error-reporter.js +35 -0
- package/dist/src/reporting/log-error-reporter.js.map +1 -0
- package/dist/src/reporting/reporting.models.d.ts +27 -0
- package/dist/src/reporting/reporting.models.js +2 -0
- package/dist/src/reporting/reporting.models.js.map +1 -0
- package/dist/src/scrapme.d.ts +61 -0
- package/dist/src/scrapme.js +133 -0
- package/dist/src/scrapme.js.map +1 -0
- package/dist/src/scrapme.models.d.ts +18 -0
- package/dist/src/scrapme.models.js +2 -0
- package/dist/src/scrapme.models.js.map +1 -0
- package/dist/src/storage/couch-connection.d.ts +19 -0
- package/dist/src/storage/couch-connection.js +67 -0
- package/dist/src/storage/couch-connection.js.map +1 -0
- package/dist/src/storage/couch-database.d.ts +44 -0
- package/dist/src/storage/couch-database.js +118 -0
- package/dist/src/storage/couch-database.js.map +1 -0
- package/dist/src/storage/couch-document-store.d.ts +14 -0
- package/dist/src/storage/couch-document-store.js +36 -0
- package/dist/src/storage/couch-document-store.js.map +1 -0
- package/dist/src/storage/couch-error.d.ts +12 -0
- package/dist/src/storage/couch-error.js +19 -0
- package/dist/src/storage/couch-error.js.map +1 -0
- package/dist/src/storage/couch-flow-run-store.d.ts +24 -0
- package/dist/src/storage/couch-flow-run-store.js +66 -0
- package/dist/src/storage/couch-flow-run-store.js.map +1 -0
- package/dist/src/storage/couch-run-store.d.ts +15 -0
- package/dist/src/storage/couch-run-store.js +52 -0
- package/dist/src/storage/couch-run-store.js.map +1 -0
- package/dist/src/storage/run-doc-ids.d.ts +9 -0
- package/dist/src/storage/run-doc-ids.js +15 -0
- package/dist/src/storage/run-doc-ids.js.map +1 -0
- package/dist/src/storage/storage.models.d.ts +95 -0
- package/dist/src/storage/storage.models.js +5 -0
- package/dist/src/storage/storage.models.js.map +1 -0
- package/dist/src/storage/unconfigured-document-store.d.ts +8 -0
- package/dist/src/storage/unconfigured-document-store.js +26 -0
- package/dist/src/storage/unconfigured-document-store.js.map +1 -0
- package/dist/src/util/preview.d.ts +10 -0
- package/dist/src/util/preview.js +44 -0
- package/dist/src/util/preview.js.map +1 -0
- package/dist/src/util/text.d.ts +8 -0
- package/dist/src/util/text.js +16 -0
- package/dist/src/util/text.js.map +1 -0
- package/dist/src/util/timing.d.ts +10 -0
- package/dist/src/util/timing.js +59 -0
- package/dist/src/util/timing.js.map +1 -0
- package/dist/src/util/url.d.ts +5 -0
- package/dist/src/util/url.js +11 -0
- package/dist/src/util/url.js.map +1 -0
- package/package.json +75 -4
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dotted paths into the flow state: `page.html`, `report.periods`. Only plain property access — no indexes or
|
|
3
|
+
* expressions; anything smarter belongs in a command.
|
|
4
|
+
*/
|
|
5
|
+
export class StatePath {
|
|
6
|
+
static SEPARATOR = '.';
|
|
7
|
+
/** "a.b.c" → ["a","b","c"]; null when a segment is empty ("a..b", ".a", ""). */
|
|
8
|
+
static split(path) {
|
|
9
|
+
const segments = path.split(StatePath.SEPARATOR);
|
|
10
|
+
return segments.every((s) => s.trim() !== '' && s === s.trim()) ? segments : null;
|
|
11
|
+
}
|
|
12
|
+
/** The value at `path`, or `{ found: false }` when some part of it is missing. */
|
|
13
|
+
static get(root, path) {
|
|
14
|
+
let current = root;
|
|
15
|
+
for (const segment of StatePath.split(path) ?? []) {
|
|
16
|
+
if (current === null || typeof current !== 'object' || !Object.hasOwn(current, segment))
|
|
17
|
+
return { found: false };
|
|
18
|
+
current = current[segment];
|
|
19
|
+
}
|
|
20
|
+
return { found: true, value: current };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A copy of `root` with `value` at `path`; objects on the way are copied (never mutated) or created.
|
|
24
|
+
* A non-object in the way is replaced by an object.
|
|
25
|
+
*/
|
|
26
|
+
static set(root, path, value) {
|
|
27
|
+
const [head, ...rest] = StatePath.split(path) ?? [];
|
|
28
|
+
if (head === undefined)
|
|
29
|
+
return root;
|
|
30
|
+
if (rest.length === 0)
|
|
31
|
+
return { ...root, [head]: value };
|
|
32
|
+
const child = root[head];
|
|
33
|
+
const base = child !== null && typeof child === 'object' && !Array.isArray(child) ? child : {};
|
|
34
|
+
return { ...root, [head]: StatePath.set(base, rest.join(StatePath.SEPARATOR), value) };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=state-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-path.js","sourceRoot":"","sources":["../../../src/flow/state-path.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,SAAS;IACb,MAAM,CAAU,SAAS,GAAG,GAAG,CAAC;IAEvC,gFAAgF;IACzE,MAAM,CAAC,KAAK,CAAC,IAAY;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IACpF,CAAC;IAED,kFAAkF;IAC3E,MAAM,CAAC,GAAG,CAAC,IAAa,EAAE,IAAY;QAC3C,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;YACjH,OAAO,GAAI,OAAmC,CAAC,OAAO,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACzC,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,GAAG,CAAC,IAA6B,EAAE,IAAY,EAAE,KAAc;QAC3E,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACpD,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAiC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5H,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;IACzF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type InputSpec } from './flow.models.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a step's input from the state as the step says:
|
|
4
|
+
* neither inputFrom nor input → the whole state
|
|
5
|
+
* inputFrom: 'report' → state.report
|
|
6
|
+
* input: { id: {…}, … } → { id: … } (a copy of inputFrom's object first, when given)
|
|
7
|
+
* Fields: { from: 'path', optional? } · { value: literal } · (state) => value (plain JS, e.g. concatenation).
|
|
8
|
+
* A path the state doesn't have is a PermanentError (MISSING_VALUE): the same state gives the same result.
|
|
9
|
+
*/
|
|
10
|
+
export declare class StepInputBuilder {
|
|
11
|
+
build(spec: InputSpec | undefined, state: Readonly<Record<string, unknown>>, step: string): unknown;
|
|
12
|
+
private value;
|
|
13
|
+
private read;
|
|
14
|
+
private missing;
|
|
15
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { injectable } from 'inversify';
|
|
8
|
+
import { PermanentError } from './flow-errors.js';
|
|
9
|
+
import { ERROR_CODE } from './flow.models.js';
|
|
10
|
+
import { StatePath } from './state-path.js';
|
|
11
|
+
/**
|
|
12
|
+
* Builds a step's input from the state as the step says:
|
|
13
|
+
* neither inputFrom nor input → the whole state
|
|
14
|
+
* inputFrom: 'report' → state.report
|
|
15
|
+
* input: { id: {…}, … } → { id: … } (a copy of inputFrom's object first, when given)
|
|
16
|
+
* Fields: { from: 'path', optional? } · { value: literal } · (state) => value (plain JS, e.g. concatenation).
|
|
17
|
+
* A path the state doesn't have is a PermanentError (MISSING_VALUE): the same state gives the same result.
|
|
18
|
+
*/
|
|
19
|
+
let StepInputBuilder = class StepInputBuilder {
|
|
20
|
+
build(spec, state, step) {
|
|
21
|
+
if (!spec)
|
|
22
|
+
return state;
|
|
23
|
+
const base = spec.from === undefined ? undefined : this.read(state, spec.from, step);
|
|
24
|
+
if (spec.fields.length === 0 && spec.from !== undefined)
|
|
25
|
+
return base;
|
|
26
|
+
if (base !== undefined && (base === null || typeof base !== 'object' || Array.isArray(base))) {
|
|
27
|
+
throw new PermanentError(`step "${step}": inputFrom "${spec.from}" is not an object, so input fields can't be added to it`, { code: ERROR_CODE.BAD_INPUT });
|
|
28
|
+
}
|
|
29
|
+
let input = { ...base };
|
|
30
|
+
for (const field of spec.fields) {
|
|
31
|
+
const value = this.value(field, state, step);
|
|
32
|
+
if (value.present)
|
|
33
|
+
input = StatePath.set(input, field.name, value.value);
|
|
34
|
+
}
|
|
35
|
+
return input;
|
|
36
|
+
}
|
|
37
|
+
value(field, state, step) {
|
|
38
|
+
if ('value' in field)
|
|
39
|
+
return { present: true, value: structuredClone(field.value) };
|
|
40
|
+
if ('compute' in field)
|
|
41
|
+
return { present: true, value: field.compute(state) };
|
|
42
|
+
const found = StatePath.get(state, field.from);
|
|
43
|
+
if (found.found)
|
|
44
|
+
return { present: true, value: found.value };
|
|
45
|
+
if (field.optional)
|
|
46
|
+
return { present: false };
|
|
47
|
+
throw this.missing(field.from, step);
|
|
48
|
+
}
|
|
49
|
+
read(state, path, step) {
|
|
50
|
+
const found = StatePath.get(state, path);
|
|
51
|
+
if (!found.found)
|
|
52
|
+
throw this.missing(path, step);
|
|
53
|
+
return found.value;
|
|
54
|
+
}
|
|
55
|
+
missing(path, step) {
|
|
56
|
+
return new PermanentError(`step "${step}": the state has no "${path}"`, { code: ERROR_CODE.MISSING_VALUE });
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
StepInputBuilder = __decorate([
|
|
60
|
+
injectable()
|
|
61
|
+
], StepInputBuilder);
|
|
62
|
+
export { StepInputBuilder };
|
|
63
|
+
//# sourceMappingURL=step-input-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-input-builder.js","sourceRoot":"","sources":["../../../src/flow/step-input-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ScrapePageCommand } from '../commands/scrape-page.command.js';
|
|
2
|
+
import { Flow } from '../flow/flow.js';
|
|
3
|
+
import { VALUE_TYPE } from '../flow/flow.models.js';
|
|
4
|
+
/**
|
|
5
|
+
* Scrape one page: `Scrapme.create({ flow: scrapeFlow }).runOrThrow({ url })` → state.page (ScrapedPage).
|
|
6
|
+
* Same retries, timeouts, error reports and stored run as any flow.
|
|
7
|
+
*/
|
|
8
|
+
export const scrapeFlow = new Flow({
|
|
9
|
+
name: 'scrape',
|
|
10
|
+
description: 'Render one page with scrap-anything and return it.',
|
|
11
|
+
tags: { kind: 'quick-scrape' },
|
|
12
|
+
params: {
|
|
13
|
+
url: { required: true },
|
|
14
|
+
headers: { type: VALUE_TYPE.JSON },
|
|
15
|
+
priority: { type: VALUE_TYPE.NUMBER },
|
|
16
|
+
allowHttpErrors: { type: VALUE_TYPE.BOOLEAN, default: false },
|
|
17
|
+
},
|
|
18
|
+
steps: [
|
|
19
|
+
{
|
|
20
|
+
key: 'page',
|
|
21
|
+
command: ScrapePageCommand,
|
|
22
|
+
input: {
|
|
23
|
+
url: { from: 'url' },
|
|
24
|
+
headers: { from: 'headers', optional: true },
|
|
25
|
+
priority: { from: 'priority', optional: true },
|
|
26
|
+
allowHttpErrors: { from: 'allowHttpErrors' },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=scrape.flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrape.flow.js","sourceRoot":"","sources":["../../../src/flows/scrape.flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC;IACjC,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,oDAAoD;IACjE,IAAI,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;IAC9B,MAAM,EAAE;QACN,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;QACvB,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE;QAClC,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE;QACrC,eAAe,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;KAC9D;IACD,KAAK,EAAE;QACL;YACE,GAAG,EAAE,MAAM;YACX,OAAO,EAAE,iBAAiB;YAC1B,KAAK,EAAE;gBACL,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;gBACpB,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC5C,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC9C,eAAe,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;aAC7C;SACF;KACF;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scrapme — reliable scraping flows of commands, defined in `*.flow.ts` files and run on a pg-boss queue.
|
|
3
|
+
*
|
|
4
|
+
* import { Scrapme, Flow, ScrapePageCommand, injectable, inject } from 'scrapme-flow';
|
|
5
|
+
*
|
|
6
|
+
* A flow is a list of steps; each step runs one command (an @injectable class; its dependencies come from your
|
|
7
|
+
* app's container). scrapme.flow(flow, input) queues a run; a worker runs it, every command with its own retries
|
|
8
|
+
* and timeout. A failed run is run again by pg-boss; final failures go to LightyErrors. Progress is kept in CouchDB
|
|
9
|
+
* and shown by the scrapme monitor (a separate app, see monitor/ in the repository).
|
|
10
|
+
*/
|
|
11
|
+
import 'reflect-metadata';
|
|
12
|
+
export { Scrapme, RunWaitTimeoutError } from './scrapme.js';
|
|
13
|
+
export type { ScrapmeOptions, StartOptions } from './scrapme.models.js';
|
|
14
|
+
export { Flow, FunctionCommand } from './flow/flow.js';
|
|
15
|
+
export { FlowValidator } from './flow/flow-validator.js';
|
|
16
|
+
export { FlowScheduler } from './flow/flow-scheduler.js';
|
|
17
|
+
export { FlowJobProcessor } from './flow/flow-job-processor.js';
|
|
18
|
+
export { FlowParams } from './flow/flow-params.js';
|
|
19
|
+
export { StepInputBuilder } from './flow/step-input-builder.js';
|
|
20
|
+
export { StatePath } from './flow/state-path.js';
|
|
21
|
+
export { CommandExecutor } from './flow/command-executor.js';
|
|
22
|
+
export { CommandResolver } from './flow/command-resolver.js';
|
|
23
|
+
export { RetryPolicy } from './flow/retry-policy.js';
|
|
24
|
+
export { CommandTimeoutError, FlowCancelledError, FlowDefinitionError, FlowFailedError, FlowInputError, NotConfiguredError, PermanentError, FlowErrors, } from './flow/flow-errors.js';
|
|
25
|
+
export { ATTEMPT_OUTCOME, ERROR_CODE, FINAL_RUN_STATUSES, RUN_STATUS, STEP_STATUS, VALUE_TYPE } from './flow/flow.models.js';
|
|
26
|
+
export type { AttemptOutcome, AttemptReport, Command, CommandClass, CommandContext, CommandOptions, CommandRef, ErrorCode, FieldConfig, FlowConfig, FlowState, ParamConfig, StepConfig, FlowAttemptReport, FlowQueueOptions, FlowDefinition, FlowParam, InputField, InputSpec, ScheduleOptions, WaitOptions, RunStatus, SerializedError, StepDefinition, StepReport, StepStatus, ValueType, } from './flow/flow.models.js';
|
|
27
|
+
export { ScrapePageCommand } from './commands/scrape-page.command.js';
|
|
28
|
+
export { SaveDocumentCommand } from './commands/save-document.command.js';
|
|
29
|
+
export { SendMailCommand } from './commands/send-mail.command.js';
|
|
30
|
+
export type { SaveDocumentInput, ScrapedPage, ScrapePageInput, SendMailInput } from './commands/commands.models.js';
|
|
31
|
+
export { ContainerBuilder } from './di/container.js';
|
|
32
|
+
export { TYPES } from './di/types.js';
|
|
33
|
+
export { ConfigBuilder, ConfigError } from './config/config-builder.js';
|
|
34
|
+
export type { CouchOptions, LightyOptions, MailOptions, PostgresOptions, QueueOptions, ScrapAnythingOptions, ScrapmeConfig, ServiceOptions, StepDefaults, } from './config/config.models.js';
|
|
35
|
+
export { PgBossFlowQueue } from './queue/pg-boss-flow-queue.js';
|
|
36
|
+
export type { FlowJob, FlowJobData, FlowJobOptions, FlowQueue } from './queue/queue.models.js';
|
|
37
|
+
export { Logger } from './logging/logger.js';
|
|
38
|
+
export { LINE_LEVEL, LOG_LEVEL } from './logging/logger.models.js';
|
|
39
|
+
export type { LineLevel, LogLevel, LogSink } from './logging/logger.models.js';
|
|
40
|
+
export type { ErrorReporter, ErrorReportContext } from './reporting/reporting.models.js';
|
|
41
|
+
export { LightyErrorReporter } from './reporting/lighty-error-reporter.js';
|
|
42
|
+
export { LogErrorReporter } from './reporting/log-error-reporter.js';
|
|
43
|
+
export { CREATE_RESULT, DOC_TYPE } from './storage/storage.models.js';
|
|
44
|
+
export type { CouchDoc, DocumentStore, FlowRunDoc, RunStore, SavedDocument } from './storage/storage.models.js';
|
|
45
|
+
export { RunDocIds } from './storage/run-doc-ids.js';
|
|
46
|
+
export { CouchConnection } from './storage/couch-connection.js';
|
|
47
|
+
export { CouchDocumentStore } from './storage/couch-document-store.js';
|
|
48
|
+
export { CouchRunStore } from './storage/couch-run-store.js';
|
|
49
|
+
export { UnconfiguredDocumentStore } from './storage/unconfigured-document-store.js';
|
|
50
|
+
export type { MailMessage, Mailer, SentMail } from './mail/mail.models.js';
|
|
51
|
+
export { SmtpMailer } from './mail/smtp-mailer.js';
|
|
52
|
+
export { UnconfiguredMailer } from './mail/unconfigured-mailer.js';
|
|
53
|
+
export { Preview } from './util/preview.js';
|
|
54
|
+
export { Timing } from './util/timing.js';
|
|
55
|
+
export { Text } from './util/text.js';
|
|
56
|
+
export { Urls } from './util/url.js';
|
|
57
|
+
export { inject, injectable, type Container } from 'inversify';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scrapme — reliable scraping flows of commands, defined in `*.flow.ts` files and run on a pg-boss queue.
|
|
3
|
+
*
|
|
4
|
+
* import { Scrapme, Flow, ScrapePageCommand, injectable, inject } from 'scrapme-flow';
|
|
5
|
+
*
|
|
6
|
+
* A flow is a list of steps; each step runs one command (an @injectable class; its dependencies come from your
|
|
7
|
+
* app's container). scrapme.flow(flow, input) queues a run; a worker runs it, every command with its own retries
|
|
8
|
+
* and timeout. A failed run is run again by pg-boss; final failures go to LightyErrors. Progress is kept in CouchDB
|
|
9
|
+
* and shown by the scrapme monitor (a separate app, see monitor/ in the repository).
|
|
10
|
+
*/
|
|
11
|
+
import 'reflect-metadata';
|
|
12
|
+
export { Scrapme, RunWaitTimeoutError } from './scrapme.js';
|
|
13
|
+
export { Flow, FunctionCommand } from './flow/flow.js';
|
|
14
|
+
export { FlowValidator } from './flow/flow-validator.js';
|
|
15
|
+
export { FlowScheduler } from './flow/flow-scheduler.js';
|
|
16
|
+
export { FlowJobProcessor } from './flow/flow-job-processor.js';
|
|
17
|
+
export { FlowParams } from './flow/flow-params.js';
|
|
18
|
+
export { StepInputBuilder } from './flow/step-input-builder.js';
|
|
19
|
+
export { StatePath } from './flow/state-path.js';
|
|
20
|
+
export { CommandExecutor } from './flow/command-executor.js';
|
|
21
|
+
export { CommandResolver } from './flow/command-resolver.js';
|
|
22
|
+
export { RetryPolicy } from './flow/retry-policy.js';
|
|
23
|
+
export { CommandTimeoutError, FlowCancelledError, FlowDefinitionError, FlowFailedError, FlowInputError, NotConfiguredError, PermanentError, FlowErrors, } from './flow/flow-errors.js';
|
|
24
|
+
export { ATTEMPT_OUTCOME, ERROR_CODE, FINAL_RUN_STATUSES, RUN_STATUS, STEP_STATUS, VALUE_TYPE } from './flow/flow.models.js';
|
|
25
|
+
export { ScrapePageCommand } from './commands/scrape-page.command.js';
|
|
26
|
+
export { SaveDocumentCommand } from './commands/save-document.command.js';
|
|
27
|
+
export { SendMailCommand } from './commands/send-mail.command.js';
|
|
28
|
+
export { ContainerBuilder } from './di/container.js';
|
|
29
|
+
export { TYPES } from './di/types.js';
|
|
30
|
+
export { ConfigBuilder, ConfigError } from './config/config-builder.js';
|
|
31
|
+
export { PgBossFlowQueue } from './queue/pg-boss-flow-queue.js';
|
|
32
|
+
export { Logger } from './logging/logger.js';
|
|
33
|
+
export { LINE_LEVEL, LOG_LEVEL } from './logging/logger.models.js';
|
|
34
|
+
export { LightyErrorReporter } from './reporting/lighty-error-reporter.js';
|
|
35
|
+
export { LogErrorReporter } from './reporting/log-error-reporter.js';
|
|
36
|
+
export { CREATE_RESULT, DOC_TYPE } from './storage/storage.models.js';
|
|
37
|
+
export { RunDocIds } from './storage/run-doc-ids.js';
|
|
38
|
+
export { CouchConnection } from './storage/couch-connection.js';
|
|
39
|
+
export { CouchDocumentStore } from './storage/couch-document-store.js';
|
|
40
|
+
export { CouchRunStore } from './storage/couch-run-store.js';
|
|
41
|
+
export { UnconfiguredDocumentStore } from './storage/unconfigured-document-store.js';
|
|
42
|
+
export { SmtpMailer } from './mail/smtp-mailer.js';
|
|
43
|
+
export { UnconfiguredMailer } from './mail/unconfigured-mailer.js';
|
|
44
|
+
export { Preview } from './util/preview.js';
|
|
45
|
+
export { Timing } from './util/timing.js';
|
|
46
|
+
export { Text } from './util/text.js';
|
|
47
|
+
export { Urls } from './util/url.js';
|
|
48
|
+
// so users build commands with the same inversify as the container
|
|
49
|
+
export { inject, injectable } from 'inversify';
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,UAAU,GACX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AA+B7H,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAGlE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAYxE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAInE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,mEAAmE;AACnE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAkB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type LogFields, type LogLevel, type LogSink } from './logger.models.js';
|
|
2
|
+
/** Structured JSON-lines logger (stdout, warn/error to stderr). Create children for per-component / per-run context. */
|
|
3
|
+
export declare class Logger {
|
|
4
|
+
private readonly level;
|
|
5
|
+
private readonly base;
|
|
6
|
+
private readonly sink;
|
|
7
|
+
static readonly PROCESS_SINK: LogSink;
|
|
8
|
+
private readonly threshold;
|
|
9
|
+
constructor(level: LogLevel, base?: LogFields, sink?: LogSink);
|
|
10
|
+
child(extra: LogFields): Logger;
|
|
11
|
+
debug(msg: string, fields?: LogFields): void;
|
|
12
|
+
info(msg: string, fields?: LogFields): void;
|
|
13
|
+
warn(msg: string, fields?: LogFields): void;
|
|
14
|
+
error(msg: string, fields?: LogFields): void;
|
|
15
|
+
private write;
|
|
16
|
+
private static serialize;
|
|
17
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { LINE_LEVEL, LOG_LEVELS } from './logger.models.js';
|
|
2
|
+
/** Structured JSON-lines logger (stdout, warn/error to stderr). Create children for per-component / per-run context. */
|
|
3
|
+
export class Logger {
|
|
4
|
+
level;
|
|
5
|
+
base;
|
|
6
|
+
sink;
|
|
7
|
+
static PROCESS_SINK = {
|
|
8
|
+
out: (line) => process.stdout.write(line),
|
|
9
|
+
err: (line) => process.stderr.write(line),
|
|
10
|
+
};
|
|
11
|
+
threshold;
|
|
12
|
+
constructor(level, base = {}, sink = Logger.PROCESS_SINK) {
|
|
13
|
+
this.level = level;
|
|
14
|
+
this.base = base;
|
|
15
|
+
this.sink = sink;
|
|
16
|
+
this.threshold = LOG_LEVELS.indexOf(level);
|
|
17
|
+
}
|
|
18
|
+
child(extra) {
|
|
19
|
+
return new Logger(this.level, { ...this.base, ...extra }, this.sink);
|
|
20
|
+
}
|
|
21
|
+
debug(msg, fields) {
|
|
22
|
+
this.write(LINE_LEVEL.DEBUG, msg, fields);
|
|
23
|
+
}
|
|
24
|
+
info(msg, fields) {
|
|
25
|
+
this.write(LINE_LEVEL.INFO, msg, fields);
|
|
26
|
+
}
|
|
27
|
+
warn(msg, fields) {
|
|
28
|
+
this.write(LINE_LEVEL.WARN, msg, fields);
|
|
29
|
+
}
|
|
30
|
+
error(msg, fields) {
|
|
31
|
+
this.write(LINE_LEVEL.ERROR, msg, fields);
|
|
32
|
+
}
|
|
33
|
+
write(level, msg, fields = {}) {
|
|
34
|
+
if (LOG_LEVELS.indexOf(level) < this.threshold)
|
|
35
|
+
return;
|
|
36
|
+
const line = { t: new Date().toISOString(), level, msg };
|
|
37
|
+
for (const [k, v] of Object.entries({ ...this.base, ...fields })) {
|
|
38
|
+
if (v !== undefined)
|
|
39
|
+
line[k] = Logger.serialize(v);
|
|
40
|
+
}
|
|
41
|
+
const text = `${JSON.stringify(line)}\n`;
|
|
42
|
+
if (level === LINE_LEVEL.ERROR || level === LINE_LEVEL.WARN)
|
|
43
|
+
this.sink.err(text);
|
|
44
|
+
else
|
|
45
|
+
this.sink.out(text);
|
|
46
|
+
}
|
|
47
|
+
static serialize(value) {
|
|
48
|
+
if (value instanceof Error) {
|
|
49
|
+
const e = value;
|
|
50
|
+
return { name: e.name, message: e.message, code: e.code, stack: e.stack };
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/logging/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Levels of log lines, in order of importance. */
|
|
2
|
+
export declare const LINE_LEVEL: {
|
|
3
|
+
readonly DEBUG: "debug";
|
|
4
|
+
readonly INFO: "info";
|
|
5
|
+
readonly WARN: "warn";
|
|
6
|
+
readonly ERROR: "error";
|
|
7
|
+
};
|
|
8
|
+
export type LineLevel = (typeof LINE_LEVEL)[keyof typeof LINE_LEVEL];
|
|
9
|
+
/** Thresholds for LOG_LEVEL: a line level, or `silent` (tests). */
|
|
10
|
+
export declare const LOG_LEVEL: {
|
|
11
|
+
readonly SILENT: "silent";
|
|
12
|
+
readonly DEBUG: "debug";
|
|
13
|
+
readonly INFO: "info";
|
|
14
|
+
readonly WARN: "warn";
|
|
15
|
+
readonly ERROR: "error";
|
|
16
|
+
};
|
|
17
|
+
export type LogLevel = (typeof LOG_LEVEL)[keyof typeof LOG_LEVEL];
|
|
18
|
+
/** Lowest to highest; a line is written when its level is at or above the threshold. */
|
|
19
|
+
export declare const LOG_LEVELS: readonly ["debug", "info", "warn", "error", "silent"];
|
|
20
|
+
export type LogFields = Record<string, unknown>;
|
|
21
|
+
/** Where log lines go (process.stdout / process.stderr by default; tests pass their own). */
|
|
22
|
+
export interface LogSink {
|
|
23
|
+
out(line: string): void;
|
|
24
|
+
err(line: string): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Levels of log lines, in order of importance. */
|
|
2
|
+
export const LINE_LEVEL = { DEBUG: 'debug', INFO: 'info', WARN: 'warn', ERROR: 'error' };
|
|
3
|
+
/** Thresholds for LOG_LEVEL: a line level, or `silent` (tests). */
|
|
4
|
+
export const LOG_LEVEL = { ...LINE_LEVEL, SILENT: 'silent' };
|
|
5
|
+
/** Lowest to highest; a line is written when its level is at or above the threshold. */
|
|
6
|
+
export const LOG_LEVELS = [LOG_LEVEL.DEBUG, LOG_LEVEL.INFO, LOG_LEVEL.WARN, LOG_LEVEL.ERROR, LOG_LEVEL.SILENT];
|
|
7
|
+
//# sourceMappingURL=logger.models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.models.js","sourceRoot":"","sources":["../../../src/logging/logger.models.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAW,CAAC;AAGlG,mEAAmE;AACnE,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAW,CAAC;AAGtE,wFAAwF;AACxF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,CAAU,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface MailMessage {
|
|
2
|
+
to: string[];
|
|
3
|
+
subject: string;
|
|
4
|
+
text: string;
|
|
5
|
+
html?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SentMail {
|
|
8
|
+
messageId: string;
|
|
9
|
+
to: string[];
|
|
10
|
+
}
|
|
11
|
+
/** Sends e-mail. SMTP 5xx (address rejected…) = PermanentError, everything else is retryable. */
|
|
12
|
+
export interface Mailer {
|
|
13
|
+
send(message: MailMessage): Promise<SentMail>;
|
|
14
|
+
close(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mail.models.js","sourceRoot":"","sources":["../../../src/mail/mail.models.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MailConfig } from '../config/config.models.js';
|
|
2
|
+
import type { MailMessage, Mailer, SentMail } from './mail.models.js';
|
|
3
|
+
/** SMTP via nodemailer — in dev Mailpit (localhost:1025, UI :8025) catches everything. Connects on the first send. */
|
|
4
|
+
export declare class SmtpMailer implements Mailer {
|
|
5
|
+
private readonly config;
|
|
6
|
+
/** SMTP 5xx = permanent negative reply (RFC 5321) — sending the same message again fails the same way. */
|
|
7
|
+
private static readonly PERMANENT_REPLY_CLASS;
|
|
8
|
+
private transporter;
|
|
9
|
+
constructor(config: MailConfig);
|
|
10
|
+
send(message: MailMessage): Promise<SentMail>;
|
|
11
|
+
close(): void;
|
|
12
|
+
private connection;
|
|
13
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
var SmtpMailer_1;
|
|
11
|
+
import { inject, injectable } from 'inversify';
|
|
12
|
+
import nodemailer, {} from 'nodemailer';
|
|
13
|
+
import { TYPES } from '../di/types.js';
|
|
14
|
+
import { PermanentError } from '../flow/flow-errors.js';
|
|
15
|
+
import { ERROR_CODE } from '../flow/flow.models.js';
|
|
16
|
+
/** SMTP via nodemailer — in dev Mailpit (localhost:1025, UI :8025) catches everything. Connects on the first send. */
|
|
17
|
+
let SmtpMailer = class SmtpMailer {
|
|
18
|
+
static { SmtpMailer_1 = this; }
|
|
19
|
+
config;
|
|
20
|
+
/** SMTP 5xx = permanent negative reply (RFC 5321) — sending the same message again fails the same way. */
|
|
21
|
+
static PERMANENT_REPLY_CLASS = 5;
|
|
22
|
+
transporter = null;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = config;
|
|
25
|
+
}
|
|
26
|
+
async send(message) {
|
|
27
|
+
try {
|
|
28
|
+
const info = await this.connection().sendMail({
|
|
29
|
+
from: this.config.from,
|
|
30
|
+
to: message.to,
|
|
31
|
+
subject: message.subject,
|
|
32
|
+
text: message.text,
|
|
33
|
+
...(message.html ? { html: message.html } : {}),
|
|
34
|
+
});
|
|
35
|
+
return { messageId: String(info.messageId ?? ''), to: message.to };
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const code = err.responseCode;
|
|
39
|
+
if (typeof code === 'number' && Math.floor(code / 100) === SmtpMailer_1.PERMANENT_REPLY_CLASS) {
|
|
40
|
+
throw new PermanentError(`SMTP ${code}: ${err.message}`, { code: ERROR_CODE.MAIL_REJECTED, cause: err });
|
|
41
|
+
}
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
close() {
|
|
46
|
+
this.transporter?.close();
|
|
47
|
+
this.transporter = null;
|
|
48
|
+
}
|
|
49
|
+
connection() {
|
|
50
|
+
if (!this.transporter) {
|
|
51
|
+
const s = this.config;
|
|
52
|
+
this.transporter = nodemailer.createTransport({
|
|
53
|
+
host: s.host,
|
|
54
|
+
port: s.port,
|
|
55
|
+
secure: s.secure,
|
|
56
|
+
...(s.user ? { auth: { user: s.user, pass: s.password ?? '' } } : {}),
|
|
57
|
+
connectionTimeout: s.timeoutMs,
|
|
58
|
+
greetingTimeout: s.timeoutMs,
|
|
59
|
+
socketTimeout: s.timeoutMs,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return this.transporter;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
SmtpMailer = SmtpMailer_1 = __decorate([
|
|
66
|
+
injectable(),
|
|
67
|
+
__param(0, inject(TYPES.MailConfig))
|
|
68
|
+
], SmtpMailer);
|
|
69
|
+
export { SmtpMailer };
|
|
70
|
+
//# sourceMappingURL=smtp-mailer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smtp-mailer.js","sourceRoot":"","sources":["../../../src/mail/smtp-mailer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Mailer, SentMail } from './mail.models.js';
|
|
2
|
+
/** Bound when Scrapme.create got no `mail`: SendMailCommand fails at once with NOT_CONFIGURED. */
|
|
3
|
+
export declare class UnconfiguredMailer implements Mailer {
|
|
4
|
+
send(): Promise<SentMail>;
|
|
5
|
+
close(): void;
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { injectable } from 'inversify';
|
|
8
|
+
import { NotConfiguredError } from '../flow/flow-errors.js';
|
|
9
|
+
/** Bound when Scrapme.create got no `mail`: SendMailCommand fails at once with NOT_CONFIGURED. */
|
|
10
|
+
let UnconfiguredMailer = class UnconfiguredMailer {
|
|
11
|
+
async send() {
|
|
12
|
+
throw new NotConfiguredError('mail', 'SendMailCommand');
|
|
13
|
+
}
|
|
14
|
+
close() { }
|
|
15
|
+
};
|
|
16
|
+
UnconfiguredMailer = __decorate([
|
|
17
|
+
injectable()
|
|
18
|
+
], UnconfiguredMailer);
|
|
19
|
+
export { UnconfiguredMailer };
|
|
20
|
+
//# sourceMappingURL=unconfigured-mailer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unconfigured-mailer.js","sourceRoot":"","sources":["../../../src/mail/unconfigured-mailer.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,kGAAkG;AAE3F,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IACtB,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC1D,CAAC;IAEM,KAAK,KAAU,CAAC;CACxB,CAAA;AANY,kBAAkB;IAD9B,UAAU,EAAE;GACA,kBAAkB,CAM9B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `scrapme-flow/models`: the shapes and constants of what scrapme stores, without the library itself (no Node-only
|
|
3
|
+
* imports) — for apps that only read runs, e.g. the scrapme monitor and its browser dashboard.
|
|
4
|
+
*
|
|
5
|
+
* import { RUN_STATUS, RunDocIds, type FlowRunDoc } from 'scrapme-flow/models';
|
|
6
|
+
*/
|
|
7
|
+
export { ATTEMPT_OUTCOME, ERROR_CODE, FINAL_RUN_STATUSES, RUN_STATUS, STEP_STATUS, VALUE_TYPE } from './flow/flow.models.js';
|
|
8
|
+
export type { AttemptOutcome, AttemptReport, ErrorCode, FlowAttemptReport, RunStatus, SerializedError, StepReport, StepStatus } from './flow/flow.models.js';
|
|
9
|
+
export { DOC_TYPE } from './storage/storage.models.js';
|
|
10
|
+
export type { FlowRunDoc } from './storage/storage.models.js';
|
|
11
|
+
export { RunDocIds } from './storage/run-doc-ids.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `scrapme-flow/models`: the shapes and constants of what scrapme stores, without the library itself (no Node-only
|
|
3
|
+
* imports) — for apps that only read runs, e.g. the scrapme monitor and its browser dashboard.
|
|
4
|
+
*
|
|
5
|
+
* import { RUN_STATUS, RunDocIds, type FlowRunDoc } from 'scrapme-flow/models';
|
|
6
|
+
*/
|
|
7
|
+
export { ATTEMPT_OUTCOME, ERROR_CODE, FINAL_RUN_STATUSES, RUN_STATUS, STEP_STATUS, VALUE_TYPE } from './flow/flow.models.js';
|
|
8
|
+
export { DOC_TYPE } from './storage/storage.models.js';
|
|
9
|
+
export { RunDocIds } from './storage/run-doc-ids.js';
|
|
10
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE7H,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CouchConfig } from '../config/config.models.js';
|
|
2
|
+
import type { FlowRunDoc, RunStore } from '../storage/storage.models.js';
|
|
3
|
+
import type { Overview, RunSummary } from './monitor.models.js';
|
|
4
|
+
/** The data behind the dashboard: the run documents in CouchDB (the monitor only reads them). */
|
|
5
|
+
export declare class MonitorApi {
|
|
6
|
+
private readonly store;
|
|
7
|
+
private readonly couch;
|
|
8
|
+
static readonly MAX_RUNS = 500;
|
|
9
|
+
constructor(store: RunStore, couch: CouchConfig);
|
|
10
|
+
runs(limit: number, filter?: {
|
|
11
|
+
flow?: string;
|
|
12
|
+
status?: string;
|
|
13
|
+
}): Promise<RunSummary[]>;
|
|
14
|
+
run(runId: string): Promise<FlowRunDoc | null>;
|
|
15
|
+
/** Counts per status and the flow names, over the newest MAX_RUNS runs. */
|
|
16
|
+
overview(): Promise<Overview>;
|
|
17
|
+
static summary(d: FlowRunDoc): RunSummary;
|
|
18
|
+
}
|