@opencraw/core 0.1.3 → 0.1.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 (170) hide show
  1. package/dist/access/access-broker.use-case.d.ts +43 -0
  2. package/dist/access/access-config.error.d.ts +5 -0
  3. package/dist/access/access-config.repository.d.ts +11 -0
  4. package/dist/access/access-json-schema.mapper.d.ts +8 -0
  5. package/dist/access/access-plugin.contract.d.ts +48 -0
  6. package/dist/access/access-preset.store.d.ts +19 -0
  7. package/dist/access/access-profile.contract.d.ts +95 -0
  8. package/dist/access/index.d.ts +11 -0
  9. package/dist/access/render-access.mapper.d.ts +41 -0
  10. package/dist/access/session-id.algorithm.d.ts +8 -0
  11. package/dist/api-steps/extract-from-document.use-case.d.ts +41 -0
  12. package/dist/api-steps/index.d.ts +4 -0
  13. package/dist/api-steps/run-api-step.use-case.d.ts +20 -0
  14. package/dist/api-steps/send-request.use-case.d.ts +23 -0
  15. package/dist/browser-session/browser-profile.store.d.ts +52 -0
  16. package/dist/browser-session/browser-session.config.d.ts +21 -0
  17. package/dist/browser-session/browser.client.d.ts +75 -0
  18. package/dist/browser-session/index.d.ts +6 -0
  19. package/dist/captcha/captcha-budget.model.d.ts +21 -0
  20. package/dist/captcha/captcha-detection.client.d.ts +28 -0
  21. package/dist/captcha/captcha-guard.use-case.d.ts +64 -0
  22. package/dist/captcha/captcha-solver-registry.store.d.ts +19 -0
  23. package/dist/captcha/captcha-solver.contract.d.ts +47 -0
  24. package/dist/captcha/captcha.error.d.ts +13 -0
  25. package/dist/captcha/index.d.ts +10 -0
  26. package/dist/captcha/resolve-captcha.use-case.d.ts +40 -0
  27. package/dist/crawl-events/crawl-event.contract.d.ts +169 -0
  28. package/dist/crawl-events/event-bus.store.d.ts +10 -0
  29. package/dist/crawl-events/index.d.ts +4 -0
  30. package/dist/crawl-events/trace-line.mapper.d.ts +14 -0
  31. package/dist/crawl-execution/bootstrap-session.use-case.d.ts +79 -0
  32. package/dist/crawl-execution/crawl-options.config.d.ts +67 -0
  33. package/dist/crawl-execution/crawl-report.model.d.ts +33 -0
  34. package/dist/crawl-execution/create-crawler.use-case.d.ts +20 -0
  35. package/dist/crawl-execution/index.d.ts +8 -0
  36. package/dist/crawl-execution/rotating-runner.use-case.d.ts +66 -0
  37. package/dist/crawl-execution/run-crawl.use-case.d.ts +17 -0
  38. package/dist/crawl-execution/run-input-recipe.use-case.d.ts +51 -0
  39. package/dist/deck-document/deck-document.model.d.ts +58 -0
  40. package/dist/deck-document/deck-table.algorithm.d.ts +35 -0
  41. package/dist/deck-document/index.d.ts +6 -0
  42. package/dist/deck-document/read-pptx.client.d.ts +16 -0
  43. package/dist/docx-document/index.d.ts +2 -0
  44. package/dist/docx-document/read-docx-html.client.d.ts +23 -0
  45. package/dist/extraction-scope/extraction-scope.model.d.ts +77 -0
  46. package/dist/extraction-scope/index.d.ts +5 -0
  47. package/dist/extraction-scope/live-element.model.d.ts +28 -0
  48. package/dist/hooks/hook-registry.store.d.ts +16 -0
  49. package/dist/hooks/hook.contract.d.ts +17 -0
  50. package/dist/hooks/hook.error.d.ts +7 -0
  51. package/dist/hooks/index.d.ts +4 -0
  52. package/dist/http-session/http-response.contract.d.ts +58 -0
  53. package/dist/http-session/http.client.d.ts +42 -0
  54. package/dist/http-session/index.d.ts +5 -0
  55. package/dist/http-session/text-decoding.algorithm.d.ts +35 -0
  56. package/dist/index.esm.js +649 -25
  57. package/dist/markdown-document/index.d.ts +3 -0
  58. package/dist/markdown-document/read-markdown.client.d.ts +39 -0
  59. package/dist/output-mapping/coerce-field.mapper.d.ts +19 -0
  60. package/dist/output-mapping/generated-field.mapper.d.ts +16 -0
  61. package/dist/output-mapping/index.d.ts +9 -0
  62. package/dist/output-mapping/map-record.use-case.d.ts +27 -0
  63. package/dist/output-mapping/mapping.error.d.ts +17 -0
  64. package/dist/output-mapping/missing-value.policy.d.ts +14 -0
  65. package/dist/output-mapping/output-field.validator.d.ts +10 -0
  66. package/dist/output-mapping/output-record.model.d.ts +20 -0
  67. package/dist/pdf-document/index.d.ts +7 -0
  68. package/dist/pdf-document/pdf-document.model.d.ts +51 -0
  69. package/dist/pdf-document/pdf-table.algorithm.d.ts +43 -0
  70. package/dist/pdf-document/read-pdf.client.d.ts +18 -0
  71. package/dist/pdf-document/row-assembly.algorithm.d.ts +26 -0
  72. package/dist/recipe-loading/index.d.ts +9 -0
  73. package/dist/recipe-loading/load-recipe-set.use-case.d.ts +45 -0
  74. package/dist/recipe-loading/read-recipe-source.use-case.d.ts +14 -0
  75. package/dist/recipe-loading/recipe-binding.error.d.ts +14 -0
  76. package/dist/recipe-loading/recipe-binding.validator.d.ts +34 -0
  77. package/dist/recipe-loading/recipe-file.repository.d.ts +11 -0
  78. package/dist/recipe-loading/recipe-set.model.d.ts +12 -0
  79. package/dist/recipe-loading/recipe-source.contract.d.ts +28 -0
  80. package/dist/recipe-loading/recipe-text.mapper.d.ts +14 -0
  81. package/dist/recipe-schema/index.d.ts +15 -0
  82. package/dist/recipe-schema/input-recipe.contract.d.ts +156 -0
  83. package/dist/recipe-schema/json-schema.mapper.d.ts +15 -0
  84. package/dist/recipe-schema/output-recipe.contract.d.ts +47 -0
  85. package/dist/recipe-schema/recipe-kind.enum.d.ts +35 -0
  86. package/dist/recipe-schema/recipe-validation.error.d.ts +17 -0
  87. package/dist/recipe-schema/recipe.validator.d.ts +28 -0
  88. package/dist/recipe-schema/step.contract.d.ts +206 -0
  89. package/dist/recipe-schema/transform-rule.contract.d.ts +120 -0
  90. package/dist/record-diff/index.d.ts +4 -0
  91. package/dist/record-diff/record-diff.algorithm.d.ts +82 -0
  92. package/dist/record-diff/records-file.repository.d.ts +10 -0
  93. package/dist/record-sink/dedupe.policy.d.ts +29 -0
  94. package/dist/record-sink/index.d.ts +9 -0
  95. package/dist/record-sink/json-lines-sink.repository.d.ts +19 -0
  96. package/dist/record-sink/memory-sink.repository.d.ts +9 -0
  97. package/dist/record-sink/record-sink.contract.d.ts +17 -0
  98. package/dist/selection/html-selector.algorithm.d.ts +19 -0
  99. package/dist/selection/index.d.ts +8 -0
  100. package/dist/selection/json-path.algorithm.d.ts +9 -0
  101. package/dist/selection/json-text.algorithm.d.ts +58 -0
  102. package/dist/selection/regex.algorithm.d.ts +12 -0
  103. package/dist/selection/take-value.mapper.d.ts +27 -0
  104. package/dist/src/api-steps/extract-from-document.use-case.d.ts +5 -5
  105. package/dist/src/docx-document/index.d.ts +2 -0
  106. package/dist/src/docx-document/read-docx-html.client.d.ts +23 -0
  107. package/dist/src/extraction-scope/extraction-scope.model.d.ts +2 -1
  108. package/dist/src/http-session/http-response.contract.d.ts +2 -1
  109. package/dist/src/index.d.ts +4 -0
  110. package/dist/src/markdown-document/index.d.ts +1 -1
  111. package/dist/src/markdown-document/read-markdown.client.d.ts +10 -0
  112. package/dist/src/recipe-schema/recipe-kind.enum.d.ts +1 -1
  113. package/dist/src/recipe-schema/step.contract.d.ts +4 -0
  114. package/dist/src/record-diff/index.d.ts +4 -0
  115. package/dist/src/record-diff/record-diff.algorithm.d.ts +82 -0
  116. package/dist/src/record-diff/records-file.repository.d.ts +10 -0
  117. package/dist/src/selection/html-selector.algorithm.d.ts +2 -1
  118. package/dist/src/xml-document/index.d.ts +6 -0
  119. package/dist/src/xml-document/xml-document.model.d.ts +13 -0
  120. package/dist/src/xml-document/xml-parser.client.d.ts +49 -0
  121. package/dist/src/xml-document/xpath.algorithm.d.ts +30 -0
  122. package/dist/step-flow/block-rule.policy.d.ts +21 -0
  123. package/dist/step-flow/blocked.error.d.ts +9 -0
  124. package/dist/step-flow/for-each.use-case.d.ts +20 -0
  125. package/dist/step-flow/host-throttle.policy.d.ts +49 -0
  126. package/dist/step-flow/index.d.ts +15 -0
  127. package/dist/step-flow/paginate.use-case.d.ts +17 -0
  128. package/dist/step-flow/retry.policy.d.ts +21 -0
  129. package/dist/step-flow/run-gate.policy.d.ts +50 -0
  130. package/dist/step-flow/run-steps.use-case.d.ts +39 -0
  131. package/dist/step-flow/step-failure.error.d.ts +14 -0
  132. package/dist/step-flow/step-runner.contract.d.ts +52 -0
  133. package/dist/step-flow/transport-retry.policy.d.ts +76 -0
  134. package/dist/template/expression.algorithm.d.ts +53 -0
  135. package/dist/template/index.d.ts +7 -0
  136. package/dist/template/template.algorithm.d.ts +53 -0
  137. package/dist/template/value-path.algorithm.d.ts +29 -0
  138. package/dist/template/value-text.algorithm.d.ts +18 -0
  139. package/dist/transformation/apply-transform-chain.use-case.d.ts +17 -0
  140. package/dist/transformation/collection.algorithm.d.ts +15 -0
  141. package/dist/transformation/currency.algorithm.d.ts +15 -0
  142. package/dist/transformation/date.algorithm.d.ts +13 -0
  143. package/dist/transformation/index.d.ts +10 -0
  144. package/dist/transformation/lookup.algorithm.d.ts +24 -0
  145. package/dist/transformation/number.algorithm.d.ts +30 -0
  146. package/dist/transformation/string.algorithm.d.ts +18 -0
  147. package/dist/transformation/transform-registry.store.d.ts +36 -0
  148. package/dist/transformation/transform.error.d.ts +8 -0
  149. package/dist/transformation/url.algorithm.d.ts +20 -0
  150. package/dist/web-steps/evaluate-script.use-case.d.ts +10 -0
  151. package/dist/web-steps/extract-from-page.use-case.d.ts +10 -0
  152. package/dist/web-steps/index.d.ts +2 -0
  153. package/dist/web-steps/interact.use-case.d.ts +36 -0
  154. package/dist/web-steps/navigate.use-case.d.ts +15 -0
  155. package/dist/web-steps/run-web-step.use-case.d.ts +37 -0
  156. package/dist/web-steps/snapshot-elements.use-case.d.ts +13 -0
  157. package/dist/workbook-document/csv-parser.algorithm.d.ts +26 -0
  158. package/dist/workbook-document/csv-workbook.mapper.d.ts +24 -0
  159. package/dist/workbook-document/grid-table.algorithm.d.ts +53 -0
  160. package/dist/workbook-document/html-tables.mapper.d.ts +14 -0
  161. package/dist/workbook-document/index.d.ts +9 -0
  162. package/dist/workbook-document/read-xlsx.client.d.ts +18 -0
  163. package/dist/workbook-document/workbook-document.model.d.ts +51 -0
  164. package/dist/xml-document/index.d.ts +6 -0
  165. package/dist/xml-document/xml-document.model.d.ts +13 -0
  166. package/dist/xml-document/xml-parser.client.d.ts +49 -0
  167. package/dist/xml-document/xpath.algorithm.d.ts +30 -0
  168. package/dist/yaml-document/index.d.ts +3 -0
  169. package/dist/yaml-document/read-yaml.client.d.ts +25 -0
  170. package/package.json +4 -2
@@ -0,0 +1,66 @@
1
+ import type { AccessLease } from '../access/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 { BlockedError } from '../step-flow/index.js';
6
+ import type { NextPageResult, StepRunner } from '../step-flow/index.js';
7
+ /** A runner and the access lease it was opened with. */
8
+ export interface LeasedRunner {
9
+ runner: StepRunner;
10
+ lease: AccessLease;
11
+ }
12
+ export interface RotatingRunnerOptions {
13
+ recipe: InputRecipe;
14
+ events: EventBus;
15
+ /** How many rotations the run may use; 0 disables rotation. */
16
+ maxRotations: number;
17
+ /** Opens a runner on a fresh lease: attempt 1 first, then 2, 3... */
18
+ open: (attempt: number) => Promise<LeasedRunner>;
19
+ }
20
+ /**
21
+ * The runner a recipe run uses. It delegates to a runner opened on an access
22
+ * lease, reports every block as an `access:blocked` event and, when the recipe
23
+ * allows it, rotates: takes a new lease, opens a new runner on it (re-running
24
+ * the bootstrap) and tells the step walk to retry the blocked step.
25
+ *
26
+ * Under concurrency several iterations can be blocked by the same lease at
27
+ * once. Each block remembers the generation of runner that produced it, so
28
+ * only the first one rotates; the rest just retry on the new runner. Replaced
29
+ * runners are kept until the run ends, because other iterations may still have
30
+ * requests in flight on them.
31
+ */
32
+ export declare class RotatingRunner implements StepRunner {
33
+ private readonly options;
34
+ /**
35
+ * Opens the first runner.
36
+ *
37
+ * @param options - The recipe, events, rotation budget and how to open a runner.
38
+ * @returns The rotating runner.
39
+ */
40
+ static open(options: RotatingRunnerOptions): Promise<RotatingRunner>;
41
+ private current;
42
+ private readonly retired;
43
+ private readonly blockedAt;
44
+ private generation;
45
+ private rotations;
46
+ private rotating;
47
+ private constructor();
48
+ private get inner();
49
+ private swap;
50
+ private note;
51
+ runLeaf(step: Step, scope: ExtractionScope): Promise<void>;
52
+ nextPage(next: PaginateNext, scope: ExtractionScope): Promise<NextPageResult>;
53
+ /**
54
+ * A runner for one parallel iteration, forked from whichever runner is
55
+ * current when it runs a step: after a rotation it forks again from the new
56
+ * one, since the old context is gone (or going). Blocks are noted and
57
+ * rotated like the main runner's.
58
+ *
59
+ * @returns The iteration's runner.
60
+ */
61
+ fork(): Promise<StepRunner>;
62
+ elements(selector: string, scope: ExtractionScope): Promise<LiveElement[]>;
63
+ rotate(error: BlockedError): Promise<boolean>;
64
+ dispose(): Promise<void>;
65
+ }
66
+ //# sourceMappingURL=rotating-runner.use-case.d.ts.map
@@ -0,0 +1,17 @@
1
+ import type { RecipeSet } from '../recipe-loading/index.js';
2
+ import type { CrawlReport } from './crawl-report.model.js';
3
+ import type { RecipeRunDependencies } from './run-input-recipe.use-case.js';
4
+ /**
5
+ * Runs every input recipe of a set into one sink, `parallel` at a time
6
+ * (default one after another). Reports come back in the set's order whatever
7
+ * order the recipes finish in. Under `onRecipeError: 'stop'`, a failed recipe
8
+ * stops the ones not started yet; those already running finish.
9
+ *
10
+ * @param set - The bound recipes.
11
+ * @param deps - Shared browser, hooks, events, sink and de-duplication.
12
+ * @param onRecipeError - Whether a failed recipe stops the run.
13
+ * @param parallel - How many input recipes run at once.
14
+ * @returns The report.
15
+ */
16
+ export declare function runCrawl(set: RecipeSet, deps: RecipeRunDependencies, onRecipeError: 'continue' | 'stop', parallel?: number): Promise<CrawlReport>;
17
+ //# sourceMappingURL=run-crawl.use-case.d.ts.map
@@ -0,0 +1,51 @@
1
+ import type { AccessBroker } from '../access/index.js';
2
+ import { BrowserClient } from '../browser-session/index.js';
3
+ import type { BrowserProfiles } from '../browser-session/index.js';
4
+ import { CaptchaSolverRegistry } from '../captcha/index.js';
5
+ import type { EventBus } from '../crawl-events/index.js';
6
+ import type { HookRegistry } from '../hooks/index.js';
7
+ import type { InputRecipe, OutputRecipe, RetryRule } from '../recipe-schema/index.js';
8
+ import type { DedupePolicy, RecordSink } from '../record-sink/index.js';
9
+ import type { HostThrottle } from '../step-flow/index.js';
10
+ import type { RecipeReport } from './crawl-report.model.js';
11
+ export interface RecipeRunDependencies {
12
+ browser: () => Promise<BrowserClient>;
13
+ hooks: HookRegistry;
14
+ events: EventBus;
15
+ sink: RecordSink;
16
+ dedupe: DedupePolicy;
17
+ storageStateDir?: string;
18
+ /** Accept invalid TLS certificates in api mode too (sandbox proxies); mirrors `browser.ignoreHTTPSErrors`. */
19
+ ignoreHTTPSErrors?: boolean;
20
+ /** Skip records the sink already has (`sink.has`). */
21
+ resume?: boolean;
22
+ /** Attach the scope snapshot to record events. */
23
+ debug?: boolean;
24
+ /** Leases each recipe run its network access. */
25
+ access: AccessBroker;
26
+ /** The solvers recipes name; none when omitted. */
27
+ captchaSolvers?: CaptchaSolverRegistry;
28
+ /** The crawler's per-site throttle, shared by every recipe. */
29
+ hosts?: HostThrottle;
30
+ /** The runner's persistent browser profiles, for `session.browserProfile`. */
31
+ profiles?: BrowserProfiles;
32
+ /** The crawler's retry rule, under each recipe's `limits.retry`. */
33
+ retry?: RetryRule;
34
+ }
35
+ /**
36
+ * Runs one input recipe end to end: session, runner, the step walk, and for
37
+ * every emitted scope the mapping, de-duplication and the sink. A step or
38
+ * mapping failure under the `fail` policy ends the recipe and is reported,
39
+ * never thrown: the caller decides whether the run goes on.
40
+ *
41
+ * Emits are serialised through one promise chain whatever the concurrency, so
42
+ * the sink sees one record at a time and `maxRecords` is exact: once reached,
43
+ * every later emit returns `stop` before mapping.
44
+ *
45
+ * @param recipe - The input recipe.
46
+ * @param output - The output recipe it feeds.
47
+ * @param deps - Shared browser, hooks, events, sink and de-duplication.
48
+ * @returns What happened.
49
+ */
50
+ export declare function runInputRecipe(recipe: InputRecipe, output: OutputRecipe, deps: RecipeRunDependencies): Promise<RecipeReport>;
51
+ //# sourceMappingURL=run-input-recipe.use-case.d.ts.map
@@ -0,0 +1,58 @@
1
+ import type { Sheet } from '../workbook-document/index.js';
2
+ /** A text box on a slide, in points from the slide's top-left corner. */
3
+ export interface DeckShape {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ text: string;
9
+ /** The placeholder it fills (`title`, `body`…). */
10
+ placeholder?: string;
11
+ }
12
+ /** A chart's data, from the values the chart caches. */
13
+ export interface DeckChart {
14
+ type: string;
15
+ title?: string;
16
+ series: {
17
+ name: string;
18
+ categories: string[];
19
+ values: (number | null)[];
20
+ }[];
21
+ }
22
+ /** One slide. */
23
+ export interface DeckSlide {
24
+ number: number;
25
+ title?: string;
26
+ hidden: boolean;
27
+ /** Text boxes in reading order. */
28
+ shapes: DeckShape[];
29
+ /** Native tables, as sheets (`table 1`…) with their merged cells. */
30
+ tables: Sheet[];
31
+ charts: DeckChart[];
32
+ notes: string;
33
+ }
34
+ /** A presentation read into slides: what `extract` works on. */
35
+ export interface DeckDocument {
36
+ kind: 'deck';
37
+ /** The slide size, in points. */
38
+ width: number;
39
+ height: number;
40
+ slides: DeckSlide[];
41
+ }
42
+ /**
43
+ * The text a `regex` extract reads: per visible slide, its title, its text
44
+ * boxes in reading order, its tables' rows (cells separated by a tab) and its
45
+ * notes after `Notes:`; slides separated by a blank line.
46
+ *
47
+ * @param document - The deck.
48
+ * @returns The text.
49
+ */
50
+ export declare function deckText(document: DeckDocument): string;
51
+ /**
52
+ * Whether a value bound in scope is a read deck (so `extract … from` can take it).
53
+ *
54
+ * @param value - Anything.
55
+ * @returns Whether it is a {@link DeckDocument}.
56
+ */
57
+ export declare function isDeckDocument(value: unknown): value is DeckDocument;
58
+ //# sourceMappingURL=deck-document.model.d.ts.map
@@ -0,0 +1,35 @@
1
+ import type { TableAlign } from '../pdf-document/index.js';
2
+ import type { GridTableQuery, WorkbookCell } from '../workbook-document/index.js';
3
+ import type { DeckDocument } from './deck-document.model.js';
4
+ /** What a table extract looks for in a deck. */
5
+ export interface DeckTableQuery extends Omit<GridTableQuery, 'sheet'> {
6
+ /** Matches the titles of the slides to read; default every slide. */
7
+ slide?: RegExp;
8
+ /** Read text boxes laid out as a table instead of native tables. */
9
+ shapes?: boolean;
10
+ /** With `shapes`: how a row's values sit against a box wrapped over several lines. */
11
+ align?: TableAlign;
12
+ }
13
+ /** One table found in a deck. */
14
+ export interface DeckTable {
15
+ /** The slide's number, from 1. */
16
+ slide: number;
17
+ slideTitle: string;
18
+ /** The first header cell. */
19
+ title: string;
20
+ header: string[];
21
+ rows: Record<string, WorkbookCell>[];
22
+ }
23
+ /**
24
+ * Finds tables in a deck: native tables through the workbook table reader
25
+ * (merged cells filled, a header over several rows joined), or, with
26
+ * `shapes`, text boxes laid out as a table through the PDF table reader (a box
27
+ * is a cell, boxes whose heights overlap a row, columns from where the body's
28
+ * boxes start). Hidden slides are skipped unless `includeHidden`.
29
+ *
30
+ * @param document - The deck.
31
+ * @param query - Which tables, on which slides, and how to name their columns.
32
+ * @returns The tables, slide by slide.
33
+ */
34
+ export declare function findDeckTables(document: DeckDocument, query: DeckTableQuery): DeckTable[];
35
+ //# sourceMappingURL=deck-table.algorithm.d.ts.map
@@ -0,0 +1,6 @@
1
+ export { deckText, isDeckDocument } from './deck-document.model.js';
2
+ export type { DeckDocument, DeckSlide, DeckShape, DeckChart } from './deck-document.model.js';
3
+ export { readPptxDeck } from './read-pptx.client.js';
4
+ export { findDeckTables } from './deck-table.algorithm.js';
5
+ export type { DeckTable, DeckTableQuery } from './deck-table.algorithm.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { DeckDocument } from './deck-document.model.js';
2
+ /**
3
+ * Reads a `.pptx` presentation into a deck document, through
4
+ * `@opencraw/office-reader`: every slide's text boxes with their positions,
5
+ * its tables with their merged cells, its charts' cached data and its notes.
6
+ * The reader is imported on first use, so recipes that never read a
7
+ * presentation never load it.
8
+ *
9
+ * @param bytes - The file.
10
+ * @param source - Where it came from, for messages.
11
+ * @returns The deck.
12
+ * @throws Error naming the source, and saying what to do, for a file that is
13
+ * not a readable presentation (a legacy `.ppt`, a password-protected file, an `.odp`…).
14
+ */
15
+ export declare function readPptxDeck(bytes: Uint8Array, source: string): Promise<DeckDocument>;
16
+ //# sourceMappingURL=read-pptx.client.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { readDocxHtml } from './read-docx-html.client.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Reads a `.docx` Word document into HTML, through `@opencraw/office-reader`,
3
+ * so every selector that reads a page reads a Word document too:
4
+ *
5
+ * - headings become `<h1>`…`<h6>` inside `<section data-heading="…">`, as in
6
+ * rendered Markdown;
7
+ * - list items become nested `<ul>` / `<ol>`;
8
+ * - tables become `<table>`s with their merged cells as `colspan` / `rowspan`,
9
+ * so a `table` extract reads them like any HTML table;
10
+ * - a paragraph keeps its style as `data-style` and its links as `<a href>`;
11
+ * - headers, footers and notes follow the body, in `<header>`, `<footer>`
12
+ * and `<aside data-part="notes">`; the title goes to `<title>`.
13
+ *
14
+ * The reader is imported on first use.
15
+ *
16
+ * @param bytes - The file.
17
+ * @param source - Where it came from, for messages.
18
+ * @returns The HTML document.
19
+ * @throws Error naming the source, and saying what to do, for a file that is
20
+ * not a readable Word document (a legacy `.doc`, a password-protected file, an `.odt`…).
21
+ */
22
+ export declare function readDocxHtml(bytes: Uint8Array, source: string): Promise<string>;
23
+ //# sourceMappingURL=read-docx-html.client.d.ts.map
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The values a recipe has extracted so far, by id, with the lexical nesting the
3
+ * steps create: `forEach` and `paginate` open a child scope per iteration or page
4
+ * and drop it afterwards, so nothing from one page leaks into the next. A read
5
+ * walks up the chain; a write lands in the scope it is made on.
6
+ *
7
+ * Page state (the current URL, page number and the document `extract` reads by
8
+ * default) is scope state too, bound in the innermost scope that navigated.
9
+ */
10
+ import type { XmlDocument } from '../xml-document/index.js';
11
+ import type { DeckDocument } from '../deck-document/index.js';
12
+ import type { PdfDocument } from '../pdf-document/index.js';
13
+ import type { WorkbookDocument } from '../workbook-document/index.js';
14
+ /** A fetched or rendered document a later `extract` can read. */
15
+ export type ScopeDocument = PdfDocument | WorkbookDocument | DeckDocument | XmlDocument | {
16
+ kind: 'json';
17
+ data: unknown;
18
+ } | {
19
+ kind: 'html';
20
+ html: string;
21
+ } | {
22
+ kind: 'text';
23
+ text: string;
24
+ };
25
+ /** Where the crawl is: bound by whichever scope last navigated. */
26
+ export interface PageState {
27
+ url: string;
28
+ number: number;
29
+ document?: ScopeDocument;
30
+ }
31
+ /** Paths a template can read besides ids: `page.url`, `page.number`, `start.url`, `vars.*`. */
32
+ export declare const RESERVED_ROOTS: readonly ['page', 'start', 'vars'];
33
+ export declare class ExtractionScope {
34
+ private readonly parent?;
35
+ private readonly values;
36
+ private page;
37
+ constructor(parent?: ExtractionScope | undefined);
38
+ /** Opens a nested scope; reads fall through to this one. */
39
+ child(): ExtractionScope;
40
+ /** Binds a value in this scope, shadowing any parent binding of the same id. */
41
+ set(id: string, value: unknown): void;
42
+ /**
43
+ * Appends to the list the id is bound to, in whichever scope binds it (this
44
+ * one or a parent), as a new list: a snapshot emitted earlier keeps what it saw.
45
+ *
46
+ * @param id - The id of a list bound in this scope or a parent.
47
+ * @param items - What to add, in order.
48
+ * @throws Error when no scope binds the id, or it holds something other than a list.
49
+ */
50
+ append(id: string, items: readonly unknown[]): void;
51
+ /** Whether the id is bound here or in a parent. */
52
+ has(id: string): boolean;
53
+ /** The nearest binding of the id; `undefined` when unbound. */
54
+ get(id: string): unknown;
55
+ /** Records a navigation in this scope. Missing fields inherit from the nearest page state. */
56
+ setPage(state: Partial<PageState>): void;
57
+ /** Replaces only the current document, keeping URL and number. */
58
+ setDocument(document: ScopeDocument): void;
59
+ /** The nearest page state up the chain, if any scope navigated. */
60
+ get pageState(): PageState | undefined;
61
+ /** The document `extract` reads when no `from` is given. */
62
+ get document(): ScopeDocument | undefined;
63
+ /**
64
+ * Every binding visible from here, child shadowing parent, plus `page` as
65
+ * `{ url, number }`. This is what `emit` hands to the mapping.
66
+ */
67
+ snapshot(): Record<string, unknown>;
68
+ /**
69
+ * Resolves a dotted path the way templates do: the first segment is an id (or
70
+ * `page`), the rest walks into the value.
71
+ *
72
+ * @param path - A dotted path such as `item.href` or `page.url`.
73
+ * @returns The value, or `undefined`.
74
+ */
75
+ lookup(path: string): unknown;
76
+ }
77
+ //# sourceMappingURL=extraction-scope.model.d.ts.map
@@ -0,0 +1,5 @@
1
+ export { ExtractionScope, RESERVED_ROOTS } from './extraction-scope.model.js';
2
+ export type { PageState, ScopeDocument } from './extraction-scope.model.js';
3
+ export { isLiveElement } from './live-element.model.js';
4
+ export type { LiveElement } from './live-element.model.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A snapshot of one element a `forEach` over `selector` iterates: what it held
3
+ * when the loop started, plus where to find it again. The engine never keeps a
4
+ * handle to the element itself: `selector` and `index` re-resolve it on every
5
+ * use, so a re-render between iterations does not break the loop.
6
+ */
7
+ export interface LiveElement {
8
+ /** The selector the loop matched, already rendered. */
9
+ selector: string;
10
+ /** Position among the matches, from 0. */
11
+ index: number;
12
+ /** Text content, whitespace collapsed. */
13
+ text: string;
14
+ /** Inner HTML. */
15
+ html: string;
16
+ /** Every attribute, by name. */
17
+ attrs: Record<string, string>;
18
+ /** The `value` of an input, option or select; absent otherwise. */
19
+ value?: string;
20
+ }
21
+ /**
22
+ * Whether a value is a live element snapshot (a `target` template rendered to one).
23
+ *
24
+ * @param value - Anything a template rendered.
25
+ * @returns `true` for an object with a `selector` string and an `index` number.
26
+ */
27
+ export declare function isLiveElement(value: unknown): value is LiveElement;
28
+ //# sourceMappingURL=live-element.model.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { Hook, HookMap } from './hook.contract.js';
2
+ /** The hooks a crawler was created with, resolved by name at run time. */
3
+ export declare class HookRegistry {
4
+ private readonly hooks;
5
+ constructor(hooks?: HookMap);
6
+ register(name: string, hook: Hook): void;
7
+ has(name: string): boolean;
8
+ names(): string[];
9
+ /**
10
+ * @param name - The name a recipe used.
11
+ * @returns The hook.
12
+ * @throws UnknownHookError when nothing was registered under that name.
13
+ */
14
+ resolve(name: string): Hook;
15
+ }
16
+ //# sourceMappingURL=hook-registry.store.d.ts.map
@@ -0,0 +1,17 @@
1
+ /** Severity of a message a hook logs. Typed here so hooks stay a leaf slice. */
2
+ export type HookLogLevel = 'debug' | 'info' | 'warn' | 'error';
3
+ /** What a hook knows about where it runs. */
4
+ export interface HookContext {
5
+ recipeId: string;
6
+ /** The extracted values visible at the call site, child scopes shadowing parents. */
7
+ scope: Record<string, unknown>;
8
+ log: (level: HookLogLevel, message: string, meta?: Record<string, unknown>) => void;
9
+ }
10
+ /**
11
+ * A programmatic handler a recipe references by name, from a `hook` step
12
+ * (`input` is `undefined`) or a `hook` transform (`input` is the value so far).
13
+ */
14
+ export type Hook = (input: unknown, args: Record<string, unknown>, context: HookContext) => unknown;
15
+ /** Hooks by the name recipes use. */
16
+ export type HookMap = Record<string, Hook>;
17
+ //# sourceMappingURL=hook.contract.d.ts.map
@@ -0,0 +1,7 @@
1
+ /** A recipe named a hook nothing registered. */
2
+ export declare class UnknownHookError extends Error {
3
+ readonly hookName: string;
4
+ readonly name = "UnknownHookError";
5
+ constructor(hookName: string, known: readonly string[]);
6
+ }
7
+ //# sourceMappingURL=hook.error.d.ts.map
@@ -0,0 +1,4 @@
1
+ export type { Hook, HookMap, HookContext, HookLogLevel } from './hook.contract.js';
2
+ export { HookRegistry } from './hook-registry.store.js';
3
+ export { UnknownHookError } from './hook.error.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,58 @@
1
+ import type { DeckDocument } from '../deck-document/index.js';
2
+ import type { PdfDocument } from '../pdf-document/index.js';
3
+ import type { WorkbookDocument } from '../workbook-document/index.js';
4
+ import type { XmlDocument } from '../xml-document/index.js';
5
+ import type { BodyKind, HttpMethod } from '../recipe-schema/index.js';
6
+ /** One HTTP request as the api runner sends it, templates already rendered. */
7
+ export interface HttpRequest {
8
+ method?: HttpMethod;
9
+ url: string;
10
+ query?: Record<string, string>;
11
+ headers?: Record<string, string>;
12
+ body?: unknown;
13
+ /** How to read the body; default: from the response content type. */
14
+ as?: BodyKind;
15
+ /** The encoding of a text body (a WHATWG label); default: the BOM, the declared charset, UTF-8, else Windows-1252. */
16
+ encoding?: string;
17
+ /** A CSV body's delimiter (one character); default: detected. */
18
+ delimiter?: string;
19
+ /** A YAML body's scalars: `typed` (default) or `text`. */
20
+ scalars?: 'typed' | 'text';
21
+ timeoutMs?: number;
22
+ }
23
+ /** A parsed response body. Structurally the same as a scope document, on purpose. */
24
+ export type HttpBody = PdfDocument | WorkbookDocument | DeckDocument | XmlDocument | {
25
+ kind: 'json';
26
+ data: unknown;
27
+ } | {
28
+ kind: 'html';
29
+ html: string;
30
+ } | {
31
+ kind: 'text';
32
+ text: string;
33
+ };
34
+ export interface HttpResponse {
35
+ status: number;
36
+ /** The final URL after redirects. */
37
+ url: string;
38
+ headers: Record<string, string>;
39
+ body: HttpBody;
40
+ /** What reading the body noticed but read anyway (an unknown YAML tag…). */
41
+ warnings?: string[];
42
+ /** The format the body was read as (`yaml` and `jsonl` both give JSON data). */
43
+ format?: BodyKind;
44
+ }
45
+ /** The part of the client the api runner needs; tests fake it. */
46
+ export interface HttpSender {
47
+ send: (request: HttpRequest) => Promise<HttpResponse>;
48
+ }
49
+ /** A response with a 4xx or 5xx status. */
50
+ export declare class HttpError extends Error {
51
+ readonly status: number;
52
+ readonly url: string;
53
+ readonly body: HttpBody;
54
+ readonly headers: Record<string, string>;
55
+ readonly name = "HttpError";
56
+ constructor(status: number, url: string, body: HttpBody, headers?: Record<string, string>);
57
+ }
58
+ //# sourceMappingURL=http-response.contract.d.ts.map
@@ -0,0 +1,42 @@
1
+ import type { APIRequestContext } from 'playwright';
2
+ import type { HttpRequest, HttpResponse, HttpSender } from './http-response.contract.js';
3
+ /** Playwright's storage state: cookies plus per-origin local storage. */
4
+ export type StorageState = Awaited<ReturnType<APIRequestContext['storageState']>>;
5
+ export interface HttpClientOptions {
6
+ /** Cookies and storage captured by a browser session, or loaded from a file. */
7
+ storageState?: StorageState;
8
+ headers?: Record<string, string>;
9
+ userAgent?: string;
10
+ timeoutMs?: number;
11
+ ignoreHTTPSErrors?: boolean;
12
+ /** Send every request through this proxy. */
13
+ proxy?: {
14
+ server: string;
15
+ username?: string;
16
+ password?: string;
17
+ bypass?: string;
18
+ };
19
+ }
20
+ /**
21
+ * HTTP through Playwright's request context: cookies, redirects and storage
22
+ * state behave exactly as they do in the browser, so a session captured by a
23
+ * browser bootstrap can be reused without translation. No browser is launched.
24
+ */
25
+ export declare class HttpClient implements HttpSender {
26
+ private readonly context;
27
+ private readonly timeoutMs;
28
+ static open(options?: HttpClientOptions): Promise<HttpClient>;
29
+ private constructor();
30
+ /**
31
+ * Sends a request and parses the body.
32
+ *
33
+ * @param httpRequest - What to send.
34
+ * @returns The response.
35
+ * @throws HttpError for a 4xx or 5xx status.
36
+ */
37
+ send(httpRequest: HttpRequest): Promise<HttpResponse>;
38
+ /** The cookies and storage this context holds now. */
39
+ storageState(): Promise<StorageState>;
40
+ dispose(): Promise<void>;
41
+ }
42
+ //# sourceMappingURL=http.client.d.ts.map
@@ -0,0 +1,5 @@
1
+ export { HttpClient } from './http.client.js';
2
+ export type { HttpClientOptions, StorageState } from './http.client.js';
3
+ export { HttpError } from './http-response.contract.js';
4
+ export type { HttpRequest, HttpResponse, HttpBody, HttpSender } from './http-response.contract.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,35 @@
1
+ /** Decoded text and the encoding it was read as. */
2
+ export interface DecodedText {
3
+ text: string;
4
+ encoding: string;
5
+ }
6
+ /**
7
+ * Decodes a body, in this order: a byte-order mark (UTF-8, UTF-16 LE/BE; Excel's
8
+ * "Unicode text" export is UTF-16 LE), the encoding a recipe asks for, the
9
+ * charset the server declares, strict UTF-8, and Windows-1252 (a superset of
10
+ * Latin-1) for text that is not UTF-8.
11
+ *
12
+ * The Windows-1252 fallback is only taken when the text holds no valid UTF-8
13
+ * beyond ASCII: a UTF-8 page with one stray byte keeps its accents, with a
14
+ * replacement character for the stray byte, instead of turning every accent
15
+ * into mojibake.
16
+ *
17
+ * @param bytes - The body.
18
+ * @param options - `encoding`: the recipe's choice, a WHATWG label (wins over
19
+ * the charset, not over a BOM); `charset`: from the content type (ignored when
20
+ * not a known label).
21
+ * @returns The text, without its BOM, and the encoding used.
22
+ * @throws Error when `encoding` is not a known label.
23
+ */
24
+ export declare function decodeText(bytes: Uint8Array, options?: {
25
+ encoding?: string;
26
+ charset?: string;
27
+ }): DecodedText;
28
+ /**
29
+ * The charset a content type declares (`text/csv; charset=ISO-8859-1`).
30
+ *
31
+ * @param contentType - The header value.
32
+ * @returns The charset, or `undefined`.
33
+ */
34
+ export declare function charsetOf(contentType: string): string | undefined;
35
+ //# sourceMappingURL=text-decoding.algorithm.d.ts.map