@opencraw/core 0.1.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.
Files changed (114) hide show
  1. package/README.md +67 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.esm.js +5302 -0
  4. package/dist/src/access/access-broker.use-case.d.ts +43 -0
  5. package/dist/src/access/access-config.error.d.ts +5 -0
  6. package/dist/src/access/access-config.repository.d.ts +11 -0
  7. package/dist/src/access/access-json-schema.mapper.d.ts +8 -0
  8. package/dist/src/access/access-plugin.contract.d.ts +48 -0
  9. package/dist/src/access/access-preset.store.d.ts +19 -0
  10. package/dist/src/access/access-profile.contract.d.ts +91 -0
  11. package/dist/src/access/index.d.ts +11 -0
  12. package/dist/src/access/render-access.mapper.d.ts +41 -0
  13. package/dist/src/access/session-id.algorithm.d.ts +8 -0
  14. package/dist/src/api-steps/extract-from-document.use-case.d.ts +27 -0
  15. package/dist/src/api-steps/index.d.ts +4 -0
  16. package/dist/src/api-steps/run-api-step.use-case.d.ts +20 -0
  17. package/dist/src/api-steps/send-request.use-case.d.ts +22 -0
  18. package/dist/src/browser-session/browser-session.config.d.ts +21 -0
  19. package/dist/src/browser-session/browser.client.d.ts +67 -0
  20. package/dist/src/browser-session/index.d.ts +5 -0
  21. package/dist/src/crawl-events/crawl-event.contract.d.ts +120 -0
  22. package/dist/src/crawl-events/event-bus.store.d.ts +10 -0
  23. package/dist/src/crawl-events/index.d.ts +4 -0
  24. package/dist/src/crawl-events/trace-line.mapper.d.ts +14 -0
  25. package/dist/src/crawl-execution/bootstrap-session.use-case.d.ts +55 -0
  26. package/dist/src/crawl-execution/crawl-options.config.d.ts +37 -0
  27. package/dist/src/crawl-execution/crawl-report.model.d.ts +25 -0
  28. package/dist/src/crawl-execution/create-crawler.use-case.d.ts +19 -0
  29. package/dist/src/crawl-execution/index.d.ts +8 -0
  30. package/dist/src/crawl-execution/rotating-runner.use-case.d.ts +57 -0
  31. package/dist/src/crawl-execution/run-crawl.use-case.d.ts +13 -0
  32. package/dist/src/crawl-execution/run-input-recipe.use-case.d.ts +40 -0
  33. package/dist/src/extraction-scope/extraction-scope.model.d.ts +73 -0
  34. package/dist/src/extraction-scope/index.d.ts +5 -0
  35. package/dist/src/extraction-scope/live-element.model.d.ts +28 -0
  36. package/dist/src/hooks/hook-registry.store.d.ts +16 -0
  37. package/dist/src/hooks/hook.contract.d.ts +17 -0
  38. package/dist/src/hooks/hook.error.d.ts +7 -0
  39. package/dist/src/hooks/index.d.ts +4 -0
  40. package/dist/src/http-session/http-response.contract.d.ts +44 -0
  41. package/dist/src/http-session/http.client.d.ts +42 -0
  42. package/dist/src/http-session/index.d.ts +5 -0
  43. package/dist/src/index.d.ts +24 -0
  44. package/dist/src/output-mapping/coerce-field.mapper.d.ts +19 -0
  45. package/dist/src/output-mapping/generated-field.mapper.d.ts +16 -0
  46. package/dist/src/output-mapping/index.d.ts +9 -0
  47. package/dist/src/output-mapping/map-record.use-case.d.ts +27 -0
  48. package/dist/src/output-mapping/mapping.error.d.ts +17 -0
  49. package/dist/src/output-mapping/missing-value.policy.d.ts +14 -0
  50. package/dist/src/output-mapping/output-field.validator.d.ts +10 -0
  51. package/dist/src/output-mapping/output-record.model.d.ts +20 -0
  52. package/dist/src/recipe-loading/index.d.ts +9 -0
  53. package/dist/src/recipe-loading/load-recipe-set.use-case.d.ts +45 -0
  54. package/dist/src/recipe-loading/read-recipe-source.use-case.d.ts +14 -0
  55. package/dist/src/recipe-loading/recipe-binding.error.d.ts +14 -0
  56. package/dist/src/recipe-loading/recipe-binding.validator.d.ts +32 -0
  57. package/dist/src/recipe-loading/recipe-file.repository.d.ts +11 -0
  58. package/dist/src/recipe-loading/recipe-set.model.d.ts +12 -0
  59. package/dist/src/recipe-loading/recipe-source.contract.d.ts +28 -0
  60. package/dist/src/recipe-loading/recipe-text.mapper.d.ts +14 -0
  61. package/dist/src/recipe-schema/index.d.ts +15 -0
  62. package/dist/src/recipe-schema/input-recipe.contract.d.ts +103 -0
  63. package/dist/src/recipe-schema/json-schema.mapper.d.ts +15 -0
  64. package/dist/src/recipe-schema/output-recipe.contract.d.ts +47 -0
  65. package/dist/src/recipe-schema/recipe-kind.enum.d.ts +31 -0
  66. package/dist/src/recipe-schema/recipe-validation.error.d.ts +17 -0
  67. package/dist/src/recipe-schema/recipe.validator.d.ts +28 -0
  68. package/dist/src/recipe-schema/step.contract.d.ts +152 -0
  69. package/dist/src/recipe-schema/transform-rule.contract.d.ts +120 -0
  70. package/dist/src/record-sink/dedupe.policy.d.ts +17 -0
  71. package/dist/src/record-sink/index.d.ts +8 -0
  72. package/dist/src/record-sink/json-lines-sink.repository.d.ts +19 -0
  73. package/dist/src/record-sink/memory-sink.repository.d.ts +9 -0
  74. package/dist/src/record-sink/record-sink.contract.d.ts +17 -0
  75. package/dist/src/selection/html-selector.algorithm.d.ts +18 -0
  76. package/dist/src/selection/index.d.ts +8 -0
  77. package/dist/src/selection/json-path.algorithm.d.ts +9 -0
  78. package/dist/src/selection/json-text.algorithm.d.ts +31 -0
  79. package/dist/src/selection/regex.algorithm.d.ts +12 -0
  80. package/dist/src/selection/take-value.mapper.d.ts +27 -0
  81. package/dist/src/step-flow/block-rule.policy.d.ts +21 -0
  82. package/dist/src/step-flow/blocked.error.d.ts +9 -0
  83. package/dist/src/step-flow/for-each.use-case.d.ts +18 -0
  84. package/dist/src/step-flow/index.d.ts +10 -0
  85. package/dist/src/step-flow/paginate.use-case.d.ts +17 -0
  86. package/dist/src/step-flow/retry.policy.d.ts +21 -0
  87. package/dist/src/step-flow/run-gate.policy.d.ts +39 -0
  88. package/dist/src/step-flow/run-steps.use-case.d.ts +39 -0
  89. package/dist/src/step-flow/step-failure.error.d.ts +14 -0
  90. package/dist/src/step-flow/step-runner.contract.d.ts +39 -0
  91. package/dist/src/template/expression.algorithm.d.ts +53 -0
  92. package/dist/src/template/index.d.ts +7 -0
  93. package/dist/src/template/template.algorithm.d.ts +53 -0
  94. package/dist/src/template/value-path.algorithm.d.ts +29 -0
  95. package/dist/src/template/value-text.algorithm.d.ts +18 -0
  96. package/dist/src/transformation/apply-transform-chain.use-case.d.ts +17 -0
  97. package/dist/src/transformation/collection.algorithm.d.ts +15 -0
  98. package/dist/src/transformation/currency.algorithm.d.ts +15 -0
  99. package/dist/src/transformation/date.algorithm.d.ts +13 -0
  100. package/dist/src/transformation/index.d.ts +10 -0
  101. package/dist/src/transformation/lookup.algorithm.d.ts +24 -0
  102. package/dist/src/transformation/number.algorithm.d.ts +30 -0
  103. package/dist/src/transformation/string.algorithm.d.ts +18 -0
  104. package/dist/src/transformation/transform-registry.store.d.ts +36 -0
  105. package/dist/src/transformation/transform.error.d.ts +8 -0
  106. package/dist/src/transformation/url.algorithm.d.ts +20 -0
  107. package/dist/src/web-steps/evaluate-script.use-case.d.ts +10 -0
  108. package/dist/src/web-steps/extract-from-page.use-case.d.ts +10 -0
  109. package/dist/src/web-steps/index.d.ts +2 -0
  110. package/dist/src/web-steps/interact.use-case.d.ts +36 -0
  111. package/dist/src/web-steps/navigate.use-case.d.ts +14 -0
  112. package/dist/src/web-steps/run-web-step.use-case.d.ts +22 -0
  113. package/dist/src/web-steps/snapshot-elements.use-case.d.ts +13 -0
  114. package/package.json +75 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `{{ }}` interpolation for recipe strings. A placeholder is a dotted path
3
+ * resolved through the lookup the caller provides, or an expression over such
4
+ * paths (see `expression.algorithm`). No code is ever executed.
5
+ */
6
+ import type { Lookup } from './value-text.algorithm.js';
7
+ /**
8
+ * Whether a string contains at least one placeholder.
9
+ *
10
+ * @param text - The string.
11
+ * @returns `true` when it has a `{{ }}`.
12
+ */
13
+ export declare function hasPlaceholder(text: string): boolean;
14
+ /**
15
+ * Renders a template. When the template is exactly one placeholder the resolved
16
+ * value is returned as is (so a list or a number survives); otherwise every
17
+ * placeholder is stringified into the text, `undefined`/`null` as `''`.
18
+ *
19
+ * @param template - The string to render.
20
+ * @param lookup - Resolves a path.
21
+ * @returns The rendered value.
22
+ */
23
+ export declare function render(template: string, lookup: Lookup): unknown;
24
+ /**
25
+ * The value of one placeholder: a plain path is looked up as is; anything else
26
+ * is parsed and evaluated as an expression.
27
+ *
28
+ * @param inner - The trimmed text between the braces.
29
+ * @param lookup - Resolves a path.
30
+ * @returns The value.
31
+ * @throws Error when an expression does not parse.
32
+ */
33
+ export declare function resolve(inner: string, lookup: Lookup): unknown;
34
+ /**
35
+ * Renders every string inside a JSON-shaped value (an object, an array, or a
36
+ * string) with {@link render}, so a lone placeholder keeps its type
37
+ * (`"{{vars.limit}}"` becomes the number) and anything else becomes text.
38
+ * Numbers, booleans and `null` pass through untouched.
39
+ *
40
+ * @param value - The value.
41
+ * @param lookup - Resolves a path.
42
+ * @returns A new value with every string rendered.
43
+ */
44
+ export declare function renderDeep(value: unknown, lookup: Lookup): unknown;
45
+ /**
46
+ * Renders a template that must produce text.
47
+ *
48
+ * @param template - The string to render.
49
+ * @param lookup - Resolves a path.
50
+ * @returns The rendered text; a non-string single value is stringified.
51
+ */
52
+ export declare function renderText(template: string, lookup: Lookup): string;
53
+ //# sourceMappingURL=template.algorithm.d.ts.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Reads and writes values by dotted path (`seller.name`, `items.0.url`, `items[0].url`).
3
+ * Pure: the read never throws on a missing segment, the write creates what is missing.
4
+ */
5
+ /**
6
+ * Splits a path into its segments; `a.b[0].c` and `a.b.0.c` are the same path.
7
+ *
8
+ * @param path - The dotted path.
9
+ * @returns Its segments, `[]` for an empty path or `.`.
10
+ */
11
+ export declare function segmentsOf(path: string): string[];
12
+ /**
13
+ * Reads a value by path. Only own properties are read, so `constructor`,
14
+ * `__proto__`, `toString` and the like resolve to `undefined` whatever the data.
15
+ *
16
+ * @param source - Where to read from.
17
+ * @param path - The dotted path; `.` or `''` returns the source itself.
18
+ * @returns The value, or `undefined` when any segment is missing.
19
+ */
20
+ export declare function getPath(source: unknown, path: string): unknown;
21
+ /**
22
+ * Writes a value by path, creating intermediate objects (or arrays for numeric segments).
23
+ *
24
+ * @param target - The object to write into. Mutated.
25
+ * @param path - The dotted path.
26
+ * @param value - The value to store.
27
+ */
28
+ export declare function setPath(target: Record<string, unknown>, path: string, value: unknown): void;
29
+ //# sourceMappingURL=value-path.algorithm.d.ts.map
@@ -0,0 +1,18 @@
1
+ /** How recipes read a value: as text for interpolation, as a truth for conditions. Shared by templates and expressions. */
2
+ /** Resolves a dotted path to a value; `undefined` when unknown. */
3
+ export type Lookup = (path: string) => unknown;
4
+ /**
5
+ * Truthiness as recipes mean it: `when` and `until` conditions.
6
+ *
7
+ * @param value - Any rendered value.
8
+ * @returns `false` for `undefined`, `null`, `''`, `0`, `false`, `'false'`, `'0'`, `'null'` and an empty list.
9
+ */
10
+ export declare function isTruthy(value: unknown): boolean;
11
+ /**
12
+ * The text form of a value for interpolation.
13
+ *
14
+ * @param value - Any value.
15
+ * @returns A string; objects and arrays as JSON.
16
+ */
17
+ export declare function stringify(value: unknown): string;
18
+ //# sourceMappingURL=value-text.algorithm.d.ts.map
@@ -0,0 +1,17 @@
1
+ import type { TransformRule } from '../recipe-schema/index.js';
2
+ import type { TransformContext } from './transform-registry.store.js';
3
+ /**
4
+ * Applies a chain of transforms in order. A scalar op applied to a list runs
5
+ * on every item; a list op runs on the list itself. A missing value (`undefined`
6
+ * or `null`) passes through every op except `default`, `template` and `hook`,
7
+ * so a missing source reaches the missing-value policy untouched. Async because
8
+ * a `hook` may be.
9
+ *
10
+ * @param value - The resolved source value(s).
11
+ * @param rules - The chain.
12
+ * @param context - Lookup, hooks and the base URL.
13
+ * @returns The transformed value.
14
+ * @throws TransformError (or whatever a hook throws) when a step cannot apply.
15
+ */
16
+ export declare function applyTransformChain(value: unknown, rules: readonly TransformRule[], context: TransformContext): Promise<unknown>;
17
+ //# sourceMappingURL=apply-transform-chain.use-case.d.ts.map
@@ -0,0 +1,15 @@
1
+ /** The input as a list: a list as is, a missing value as empty; anything else fails the op. */
2
+ export declare function asList(op: string, value: unknown): unknown[];
3
+ export declare function first(value: unknown): unknown;
4
+ export declare function last(value: unknown): unknown;
5
+ export declare function nth(value: unknown, index: number): unknown;
6
+ export declare function slice(value: unknown, start: number, end?: number): unknown[];
7
+ export declare function join(value: unknown, separator: string): string;
8
+ export declare function concat(value: unknown, separator?: string): string;
9
+ /** The first value that is not `undefined`, `null` or blank text. */
10
+ export declare function coalesce(value: unknown): unknown;
11
+ export declare function flatten(value: unknown): unknown[];
12
+ export declare function unique(value: unknown): unknown[];
13
+ export declare function sum(value: unknown): number;
14
+ export declare function count(value: unknown): number;
15
+ //# sourceMappingURL=collection.algorithm.d.ts.map
@@ -0,0 +1,15 @@
1
+ /** A money amount with its ISO 4217 code, when known. */
2
+ export interface Money {
3
+ amount: number;
4
+ currency?: string;
5
+ }
6
+ /**
7
+ * Parses a price. The currency comes from the explicit code, else a code or symbol in the text.
8
+ *
9
+ * @param value - Text such as `1.299,00 €` or a number.
10
+ * @param locale - The locale the text is written in.
11
+ * @param currency - An explicit ISO 4217 code that wins over anything in the text.
12
+ * @returns The money value.
13
+ */
14
+ export declare function parseCurrency(value: unknown, locale?: string, currency?: string): Money;
15
+ //# sourceMappingURL=currency.algorithm.d.ts.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Parses a date or instant.
3
+ *
4
+ * @param value - Text, a number (epoch milliseconds) or a Date.
5
+ * @param format - Tokens `YYYY MM DD HH mm ss`, e.g. `DD/MM/YYYY`; without one the text must be ISO 8601 or otherwise `Date.parse`-able.
6
+ * @param timezone - An IANA zone the text is written in when it carries no offset; default UTC.
7
+ * @returns The instant.
8
+ * @throws TransformError when the text cannot be read.
9
+ */
10
+ export declare function parseDate(value: unknown, format?: string, timezone?: string): Date;
11
+ /** `YYYY-MM-DD` of an instant, in UTC. */
12
+ export declare function toIsoDate(date: Date): string;
13
+ //# sourceMappingURL=date.algorithm.d.ts.map
@@ -0,0 +1,10 @@
1
+ export { applyTransformChain } from './apply-transform-chain.use-case.js';
2
+ export { BUILT_IN_TRANSFORMS } from './transform-registry.store.js';
3
+ export type { TransformContext } from './transform-registry.store.js';
4
+ export { TransformError } from './transform.error.js';
5
+ export { parseNumber, parseInteger, parseBoolean } from './number.algorithm.js';
6
+ export { parseCurrency } from './currency.algorithm.js';
7
+ export type { Money } from './currency.algorithm.js';
8
+ export { parseDate, toIsoDate } from './date.algorithm.js';
9
+ export { absoluteUrl } from './url.algorithm.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The first item of a table whose `key` path equals a value, compared as text
3
+ * so `"3"` finds `3`. The table is whatever a bound id holds: data, JSON text
4
+ * or a list of JSON texts (a `data-*` attribute per element).
5
+ *
6
+ * @param value - The value to find.
7
+ * @param table - The table, as bound in scope.
8
+ * @param key - A dotted path inside each item.
9
+ * @param pick - A dotted path to return from the item; the item itself when omitted.
10
+ * @returns The picked value, or `undefined` when nothing matches.
11
+ */
12
+ export declare function lookup(value: unknown, table: unknown, key: string, pick?: string): unknown;
13
+ /**
14
+ * Groups a list by a path, keeping first-seen order.
15
+ *
16
+ * @param items - The list.
17
+ * @param by - A dotted path inside each item; items without one group under `null`.
18
+ * @returns One `{ key, items }` per distinct key.
19
+ */
20
+ export declare function group(items: unknown[], by: string): {
21
+ key: unknown;
22
+ items: unknown[];
23
+ }[];
24
+ //# sourceMappingURL=lookup.algorithm.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The decimal and group separators a locale uses.
3
+ *
4
+ * @param locale - A BCP 47 tag; `undefined` means "guess from the text".
5
+ * @returns The two separators.
6
+ */
7
+ export declare function separatorsOf(locale: string): {
8
+ decimal: string;
9
+ group: string;
10
+ };
11
+ /**
12
+ * Parses a number from text, tolerating currency symbols, spaces and locale separators.
13
+ *
14
+ * @param value - Text or a number.
15
+ * @param locale - The locale the text is written in. Without one, the last separator is the decimal one when
16
+ * it is followed by 1 or 2 digits, otherwise it is a group separator.
17
+ * @returns The number.
18
+ * @throws TransformError when no number can be read.
19
+ */
20
+ export declare function parseNumber(value: unknown, locale?: string): number;
21
+ export declare function parseInteger(value: unknown, locale?: string): number;
22
+ /**
23
+ * Reads a boolean the way a recipe means it.
24
+ *
25
+ * @param value - Any value.
26
+ * @param truthy - Phrases that mean `true` (case-insensitive, matched as a substring); default: yes/true/1/on/in stock/available.
27
+ * @returns The boolean.
28
+ */
29
+ export declare function parseBoolean(value: unknown, truthy?: readonly string[]): boolean;
30
+ //# sourceMappingURL=number.algorithm.d.ts.map
@@ -0,0 +1,18 @@
1
+ /** A short description of a value for error messages. */
2
+ export declare function describe(value: unknown): string;
3
+ export declare function trim(value: unknown): string;
4
+ export declare function lowercase(value: unknown): string;
5
+ export declare function uppercase(value: unknown): string;
6
+ export declare function replace(value: unknown, pattern: string, replacement: string, flags?: string): string;
7
+ /**
8
+ * The first match of a pattern.
9
+ *
10
+ * @param value - The text.
11
+ * @param pattern - A regular expression source.
12
+ * @param group - The capture group to return; default: group 1 when the pattern has one, else the whole match.
13
+ * @param flags - Regular expression flags.
14
+ * @returns The captured text, or `undefined` when nothing matches.
15
+ */
16
+ export declare function regex(value: unknown, pattern: string, group?: number, flags?: string): string | undefined;
17
+ export declare function split(value: unknown, separator: string): string[];
18
+ //# sourceMappingURL=string.algorithm.d.ts.map
@@ -0,0 +1,36 @@
1
+ import type { HookRegistry } from '../hooks/index.js';
2
+ import type { TransformOp, TransformRule } from '../recipe-schema/index.js';
3
+ import type { Lookup } from '../template/index.js';
4
+ /** What a transform may need besides its input. */
5
+ export interface TransformContext {
6
+ recipeId: string;
7
+ /** Resolves template paths against the current scope. */
8
+ lookup: Lookup;
9
+ /** The scope snapshot, for hooks. */
10
+ scope: Record<string, unknown>;
11
+ hooks: HookRegistry;
12
+ /** The current page URL; `absoluteUrl` resolves against it by default. */
13
+ baseUrl?: string;
14
+ log: (level: 'debug' | 'info' | 'warn' | 'error', message: string, meta?: Record<string, unknown>) => void;
15
+ }
16
+ type RuleOf<Op extends TransformOp> = Extract<TransformRule, {
17
+ op: Op;
18
+ }>;
19
+ /** One registered operation. `elementwise` ops apply to each item when the input is a list. */
20
+ interface Registered<Op extends TransformOp = TransformOp> {
21
+ elementwise: boolean;
22
+ apply: (value: unknown, rule: RuleOf<Op>, context: TransformContext) => unknown;
23
+ }
24
+ /** The closed set of built-in transforms, one per `TransformRule` op. */
25
+ export declare const BUILT_IN_TRANSFORMS: {
26
+ [Op in TransformOp]: Registered<Op>;
27
+ };
28
+ /**
29
+ * Looks up the implementation of a rule.
30
+ *
31
+ * @param rule - A transform rule from a recipe.
32
+ * @returns The registered operation.
33
+ */
34
+ export declare function transformFor(rule: TransformRule): Registered;
35
+ export {};
36
+ //# sourceMappingURL=transform-registry.store.d.ts.map
@@ -0,0 +1,8 @@
1
+ /** A transform that could not be applied to its input. */
2
+ export declare class TransformError extends Error {
3
+ readonly op: string;
4
+ readonly input?: unknown | undefined;
5
+ readonly name = "TransformError";
6
+ constructor(op: string, reason: string, input?: unknown | undefined);
7
+ }
8
+ //# sourceMappingURL=transform.error.d.ts.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Percent-encodes a value for one URL component (a path segment, a query
3
+ * value), with `encodeURIComponent`'s rules: everything but letters, digits
4
+ * and `-_.!~*'()` is encoded, non-ASCII as UTF-8.
5
+ *
6
+ * @param value - Text, a number or a boolean.
7
+ * @returns The encoded text.
8
+ * @throws TransformError for anything else.
9
+ */
10
+ export declare function urlEncode(value: unknown): string;
11
+ /**
12
+ * Resolves a possibly relative URL.
13
+ *
14
+ * @param value - The URL text.
15
+ * @param base - What relative URLs resolve against; usually the page URL.
16
+ * @returns The absolute URL.
17
+ * @throws TransformError when the result is not a valid URL.
18
+ */
19
+ export declare function absoluteUrl(value: unknown, base?: string): string;
20
+ //# sourceMappingURL=url.algorithm.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { Page } from 'playwright';
2
+ import type { ExtractionScope } from '../extraction-scope/index.js';
3
+ import type { EvaluateStep } from '../recipe-schema/index.js';
4
+ /**
5
+ * Runs an `evaluate` step: the script is evaluated in the page as an expression
6
+ * (a function expression is called), and its JSON-serialisable result is bound
7
+ * under the step id. Trusted recipes only: this is arbitrary code in the page.
8
+ */
9
+ export declare function evaluateScript(step: EvaluateStep, page: Page, scope: ExtractionScope): Promise<void>;
10
+ //# sourceMappingURL=evaluate-script.use-case.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { Page } from 'playwright';
2
+ import type { ExtractionScope } from '../extraction-scope/index.js';
3
+ import type { ExtractStep } from '../recipe-schema/index.js';
4
+ /**
5
+ * Runs an `extract` step on the live page (css or xpath through locators, one
6
+ * round trip for all matches). With `from`, it reads a fragment bound earlier
7
+ * instead, the same way api mode reads a fetched document.
8
+ */
9
+ export declare function extractFromPage(step: ExtractStep, page: Page, scope: ExtractionScope): Promise<void>;
10
+ //# sourceMappingURL=extract-from-page.use-case.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { WebStepRunner } from './run-web-step.use-case.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,36 @@
1
+ import type { Locator, Page } from 'playwright';
2
+ import type { ExtractionScope } from '../extraction-scope/index.js';
3
+ import type { ClickStep, FillStep, PressStep, ScreenshotStep, ScrollStep, SelectStep, TargetFields, WaitStep } from '../recipe-schema/index.js';
4
+ /**
5
+ * The element an interaction lands on: the first match of `selector`, or what
6
+ * `target` renders to - a live element (re-resolved by selector and index, so a
7
+ * re-render since the loop started does not matter) or a selector string.
8
+ *
9
+ * @param step - A step with `selector` or `target`.
10
+ * @param page - The page.
11
+ * @param scope - Where `target` is resolved.
12
+ * @returns The locator.
13
+ * @throws Error when `target` renders to something that is neither.
14
+ */
15
+ export declare function targetOf(step: TargetFields, page: Page, scope: ExtractionScope): Locator;
16
+ export declare function click(step: ClickStep, page: Page, scope: ExtractionScope): Promise<void>;
17
+ export declare function fill(step: FillStep, page: Page, scope: ExtractionScope): Promise<void>;
18
+ export declare function press(step: PressStep, page: Page, scope: ExtractionScope): Promise<void>;
19
+ /** Picks an option of a `<select>` by value, label or index; each is a template. */
20
+ export declare function select(step: SelectStep, page: Page, scope: ExtractionScope): Promise<void>;
21
+ /**
22
+ * Scrolls to the bottom (or to an element) `times` times; with `untilStable`
23
+ * it keeps going until the page stops growing, which is how infinite lists end.
24
+ */
25
+ export declare function scroll(step: ScrollStep, page: Page): Promise<void>;
26
+ export declare function wait(step: WaitStep, page: Page): Promise<void>;
27
+ /**
28
+ * Whether a locator becomes visible within a timeout. Never throws.
29
+ *
30
+ * @param target - The locator.
31
+ * @param timeout - Milliseconds to wait.
32
+ * @returns `true` when visible in time.
33
+ */
34
+ export declare function appears(target: Locator, timeout: number): Promise<boolean>;
35
+ export declare function screenshot(step: ScreenshotStep, page: Page, scope: ExtractionScope): Promise<void>;
36
+ //# sourceMappingURL=interact.use-case.d.ts.map
@@ -0,0 +1,14 @@
1
+ import type { Page } from 'playwright';
2
+ import type { EventBus } from '../crawl-events/index.js';
3
+ import type { ExtractionScope } from '../extraction-scope/index.js';
4
+ import type { GotoStep, InputRecipe } from '../recipe-schema/index.js';
5
+ import type { RunGate } from '../step-flow/index.js';
6
+ /**
7
+ * Runs a `goto` step: renders the URL (relative to the current page), waits for
8
+ * the gate's throttle (`delayMs`), navigates, records the page's real URL in the
9
+ * scope, and checks the response against the recipe's block rule.
10
+ *
11
+ * @throws BlockedError when the response is a block.
12
+ */
13
+ export declare function navigate(step: GotoStep, page: Page, scope: ExtractionScope, recipe: InputRecipe, gate: RunGate, events: EventBus): Promise<void>;
14
+ //# sourceMappingURL=navigate.use-case.d.ts.map
@@ -0,0 +1,22 @@
1
+ import type { BrowserSession } from '../browser-session/index.js';
2
+ import type { EventBus } from '../crawl-events/index.js';
3
+ import type { ExtractionScope, LiveElement } from '../extraction-scope/index.js';
4
+ import type { InputRecipe, PaginateNext, Step } from '../recipe-schema/index.js';
5
+ import { RunGate } from '../step-flow/index.js';
6
+ import type { NextPageResult, StepRunner } from '../step-flow/index.js';
7
+ /** Runs web-mode leaf steps on a browser page. */
8
+ export declare class WebStepRunner implements StepRunner {
9
+ private readonly session;
10
+ private readonly recipe;
11
+ private readonly events;
12
+ private readonly gate;
13
+ private readonly page;
14
+ constructor(session: BrowserSession, recipe: InputRecipe, events: EventBus, gate?: RunGate);
15
+ /** Clicks and key presses can navigate; keep `page.url` honest after every leaf step. */
16
+ private trackUrl;
17
+ runLeaf(step: Step, scope: ExtractionScope): Promise<void>;
18
+ nextPage(next: PaginateNext, scope: ExtractionScope): Promise<NextPageResult>;
19
+ elements(selector: string): Promise<LiveElement[]>;
20
+ dispose(): Promise<void>;
21
+ }
22
+ //# sourceMappingURL=run-web-step.use-case.d.ts.map
@@ -0,0 +1,13 @@
1
+ import type { Page } from 'playwright';
2
+ import type { LiveElement } from '../extraction-scope/index.js';
3
+ /**
4
+ * Snapshots every element a selector matches, in one round trip, for a
5
+ * `forEach` over `selector`. Each snapshot carries the selector and its index
6
+ * so a later `target` can find the element again, even after a re-render.
7
+ *
8
+ * @param selector - A css selector (or `xpath=...`), already rendered.
9
+ * @param page - The page.
10
+ * @returns One snapshot per match, in document order.
11
+ */
12
+ export declare function snapshotElements(selector: string, page: Page): Promise<LiveElement[]>;
13
+ //# sourceMappingURL=snapshot-elements.use-case.d.ts.map
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@opencraw/core",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.esm.js",
6
+ "module": "./dist/index.esm.js",
7
+ "types": "./dist/src/index.d.ts",
8
+ "exports": {
9
+ "./package.json": "./package.json",
10
+ ".": {
11
+ "types": "./dist/src/index.d.ts",
12
+ "import": "./dist/index.esm.js",
13
+ "default": "./dist/index.esm.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "!**/*.tsbuildinfo",
19
+ "!**/*.d.ts.map",
20
+ "!**/*.js.map"
21
+ ],
22
+ "dependencies": {
23
+ "cheerio": "^1.2.0",
24
+ "domhandler": "^6.0.1",
25
+ "jsonpath-plus": "^10.4.0",
26
+ "playwright": "^1.63.0",
27
+ "zod": "^4.6.5"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "description": "Recipe-driven crawler engine: JSON input recipes (Playwright browser or HTTP API steps) mapped through transforms to JSON output schemas.",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/russoedu/open.craw.git",
37
+ "directory": "packages/core"
38
+ },
39
+ "keywords": [
40
+ "crawler",
41
+ "scraper",
42
+ "playwright",
43
+ "recipe",
44
+ "data-driven",
45
+ "json"
46
+ ],
47
+ "engines": {
48
+ "node": ">=22"
49
+ },
50
+ "sideEffects": false,
51
+ "nx": {
52
+ "targets": {
53
+ "e2e": {
54
+ "executor": "nx:run-commands",
55
+ "dependsOn": [
56
+ "build"
57
+ ],
58
+ "options": {
59
+ "command": "tsc -p tsconfig.e2e.json && jest --config jest.e2e.config.cts",
60
+ "cwd": "packages/core"
61
+ }
62
+ },
63
+ "schemas": {
64
+ "executor": "nx:run-commands",
65
+ "dependsOn": [
66
+ "build"
67
+ ],
68
+ "options": {
69
+ "command": "node tools/emit-json-schemas.mjs",
70
+ "cwd": "packages/core"
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }