@opencraw/studio 0.0.7 → 0.0.8

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 (57) hide show
  1. package/dist/index.esm.js +3239 -901
  2. package/dist/src/document-view/deck-view.mapper.d.ts +70 -0
  3. package/dist/src/document-view/index.d.ts +11 -0
  4. package/dist/src/document-view/pdf-view.mapper.d.ts +47 -0
  5. package/dist/src/document-view/table-preview.use-case.d.ts +152 -0
  6. package/dist/src/document-view/tree-view.mapper.d.ts +47 -0
  7. package/dist/src/document-view/workbook-view.mapper.d.ts +51 -0
  8. package/dist/src/flow-recording/action-to-step.mapper.d.ts +16 -0
  9. package/dist/src/flow-recording/index.d.ts +13 -0
  10. package/dist/src/flow-recording/next-link.policy.d.ts +27 -0
  11. package/dist/src/flow-recording/recorded-action.contract.d.ts +114 -0
  12. package/dist/src/flow-recording/recorder-script.client.d.ts +48 -0
  13. package/dist/src/flow-recording/recorder-session.use-case.d.ts +67 -0
  14. package/dist/src/flow-recording/secret-field.policy.d.ts +33 -0
  15. package/dist/src/flow-recording/wait-insertion.policy.d.ts +26 -0
  16. package/dist/src/index.d.ts +2 -2
  17. package/dist/src/page-inspector/dom-tree.mapper.d.ts +32 -0
  18. package/dist/src/page-inspector/index.d.ts +7 -0
  19. package/dist/src/page-inspector/page-data.algorithm.d.ts +39 -0
  20. package/dist/src/page-inspector/responses-seen.use-case.d.ts +36 -0
  21. package/dist/src/page-snapshot/index.d.ts +3 -0
  22. package/dist/src/page-snapshot/pdf-bytes.use-case.d.ts +16 -0
  23. package/dist/src/page-snapshot/reread-csv.use-case.d.ts +22 -0
  24. package/dist/src/page-snapshot/take-snapshot.use-case.d.ts +26 -1
  25. package/dist/src/studio-api/command.contract.d.ts +300 -0
  26. package/dist/src/studio-api/deck-preview-view.contract.d.ts +28 -0
  27. package/dist/src/studio-api/deck-view.contract.d.ts +127 -0
  28. package/dist/src/studio-api/document-tree-view.contract.d.ts +26 -0
  29. package/dist/src/studio-api/event.contract.d.ts +45 -0
  30. package/dist/src/studio-api/grid-preview-view.contract.d.ts +26 -0
  31. package/dist/src/studio-api/grid-view.contract.d.ts +75 -0
  32. package/dist/src/studio-api/index.d.ts +22 -4
  33. package/dist/src/studio-api/inspect-view.contract.d.ts +62 -0
  34. package/dist/src/studio-api/pdf-view.contract.d.ts +66 -0
  35. package/dist/src/studio-api/responses-seen-view.contract.d.ts +20 -0
  36. package/dist/src/studio-api/snapshot-view.contract.d.ts +22 -1
  37. package/dist/src/studio-api/table-preview-view.contract.d.ts +65 -0
  38. package/dist/src/studio-server/deck-preview.handler.d.ts +17 -0
  39. package/dist/src/studio-server/deck-view.handler.d.ts +15 -0
  40. package/dist/src/studio-server/document-tree.handler.d.ts +14 -0
  41. package/dist/src/studio-server/grid-preview.handler.d.ts +17 -0
  42. package/dist/src/studio-server/grid-view.handler.d.ts +20 -0
  43. package/dist/src/studio-server/inspect-page.handler.d.ts +18 -0
  44. package/dist/src/studio-server/pdf-bytes.handler.d.ts +17 -0
  45. package/dist/src/studio-server/pdf-view.handler.d.ts +14 -0
  46. package/dist/src/studio-server/recording.handler.d.ts +33 -0
  47. package/dist/src/studio-server/responses-seen.handler.d.ts +16 -0
  48. package/dist/src/studio-server/studio-http.use-case.d.ts +3 -1
  49. package/dist/src/studio-server/table-preview.handler.d.ts +16 -0
  50. package/dist/src/studio-server/workspace.store.d.ts +6 -2
  51. package/dist/ui/assets/index-DdiGdaTN.js +13 -0
  52. package/dist/ui/assets/pdf-lqXfRfkR.js +56 -0
  53. package/dist/ui/assets/pdf.worker.min-BmVo14Nb.mjs +28 -0
  54. package/dist/ui/assets/pdf.worker.min-D7i8o3wR.js +1 -0
  55. package/dist/ui/index.html +1 -1
  56. package/package.json +3 -2
  57. package/dist/ui/assets/index-DV8i4Zza.js +0 -13
@@ -0,0 +1,70 @@
1
+ import type { DeckDocument } from '@opencraw/core';
2
+ import type { GridSheetView } from './workbook-view.mapper.js';
3
+ /** One text box on a slide, in points from the slide's top-left corner — mirrors `@opencraw/core`'s `DeckShape`. */
4
+ export interface DeckShapeView {
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ text: string;
10
+ placeholder?: string;
11
+ }
12
+ /** One series of a chart — mirrors `@opencraw/core`'s `DeckChart`'s own series entries. */
13
+ export interface DeckChartSeriesView {
14
+ name: string;
15
+ categories: string[];
16
+ values: (number | null)[];
17
+ }
18
+ /** One chart on a slide — mirrors `@opencraw/core`'s `DeckChart`. */
19
+ export interface DeckChartView {
20
+ type: string;
21
+ title?: string;
22
+ series: DeckChartSeriesView[];
23
+ }
24
+ /** One slide's geometry, tables, charts and notes for the deck canvas (studio plan §3.4, issue #94's 5d). */
25
+ export interface DeckSlideView {
26
+ number: number;
27
+ title?: string;
28
+ hidden: boolean;
29
+ /** Text boxes in reading order, ready to draw as absolutely-positioned boxes. */
30
+ shapes: DeckShapeView[];
31
+ /**
32
+ * `shapes` grouped into visual rows, left to right — indices into
33
+ * `shapes` — the same grouping `findDeckTables`'s `shapes: true` reading
34
+ * groups a slide's text boxes into (`rowsOfCells`, the pure algorithm
35
+ * `@opencraw/core`'s own `deck-table.algorithm.ts`'s `shapeTables` uses).
36
+ * The deck canvas's text-box-grid pick (issue #94's 5d) reads this to find
37
+ * the row a clicked shape sits in, and that row's own leftmost shape's
38
+ * text, without recomputing the grouping client-side or reaching for a
39
+ * core-internal helper: the exact row `findDeckTables` would match a
40
+ * `header`/`until` pattern against at run time.
41
+ */
42
+ shapeRows: number[][];
43
+ /** Native tables, as the grid canvas's own sheet view (`workbook-view.mapper.ts`'s `GridSheetView`) — reused wholesale rather than a parallel shape, since a deck's native table *is* a sheet (`@opencraw/core`'s own `DeckSlide.tables`). */
44
+ tables: GridSheetView[];
45
+ charts: DeckChartView[];
46
+ notes: string;
47
+ }
48
+ /** What `deck-view` answers with (studio plan §3.4, issue #94's 5d): the slide size in points and every slide's shapes, tables, charts and notes, for the deck canvas to draw and pick from. */
49
+ export interface DeckDocumentView {
50
+ width: number;
51
+ height: number;
52
+ slides: DeckSlideView[];
53
+ }
54
+ /**
55
+ * Builds the deck canvas's view model (studio plan §3.4, issue #94's 5d)
56
+ * from an already-read `DeckDocument` (`take-snapshot`'s cached body — no
57
+ * second read of the file): every slide's shapes (with their visual-row
58
+ * grouping, for the text-box-grid pick), native tables (through
59
+ * `workbook-view.mapper.ts`'s own sheet view — a deck table *is* a sheet),
60
+ * charts and notes. Table-specific diagnostics for a `table` extract's own
61
+ * options (the live preview) are not here — they come from
62
+ * `table-preview.use-case.ts`'s `previewDeckTable` instead, computed live as
63
+ * those options change, the same split `pdf-view.mapper.ts`/`workbook-view.mapper.ts`
64
+ * already use.
65
+ *
66
+ * @param document - The read deck.
67
+ * @returns The view.
68
+ */
69
+ export declare function deckDocumentView(document: DeckDocument): DeckDocumentView;
70
+ //# sourceMappingURL=deck-view.mapper.d.ts.map
@@ -0,0 +1,11 @@
1
+ export { deckDocumentView } from './deck-view.mapper.js';
2
+ export type { DeckChartSeriesView, DeckChartView, DeckDocumentView, DeckShapeView, DeckSlideView } from './deck-view.mapper.js';
3
+ export { documentTreeView } from './tree-view.mapper.js';
4
+ export type { DocumentTreeNode, DocumentTreeView, TreeValueType } from './tree-view.mapper.js';
5
+ export { pdfDocumentView } from './pdf-view.mapper.js';
6
+ export type { PdfCellView, PdfDocumentView, PdfPageView, PdfRowView } from './pdf-view.mapper.js';
7
+ export { previewDeckTable, previewGridTable, previewPdfTable } from './table-preview.use-case.js';
8
+ export type { DeckTablePreviewMatch, DeckTablePreviewOptions, DeckTablePreviewResult, GridTablePreviewMatch, GridTablePreviewOptions, GridTablePreviewResult, TablePreviewMatch, TablePreviewOptions, TablePreviewResult } from './table-preview.use-case.js';
9
+ export { workbookDocumentView } from './workbook-view.mapper.js';
10
+ export type { GridCellType, GridCellView, GridMergeView, GridSheetView, WorkbookDocumentView } from './workbook-view.mapper.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,47 @@
1
+ import type { PdfDocument } from '@opencraw/core';
2
+ /** One text cell, in PDF points (y growing upwards from the bottom edge) — mirrors `@opencraw/core`'s `PdfCell`. */
3
+ export interface PdfCellView {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ text: string;
9
+ }
10
+ /** One row of cells, top to bottom. */
11
+ export interface PdfRowView {
12
+ top: number;
13
+ bottom: number;
14
+ cells: PdfCellView[];
15
+ }
16
+ /** One page's geometry and diagnostics for the PDF canvas (studio plan §3.4, issue #94's 5b). */
17
+ export interface PdfPageView {
18
+ number: number;
19
+ /** In PDF points, the size `pdf.js` renders the page at scale 1. */
20
+ width: number;
21
+ height: number;
22
+ rows: PdfRowView[];
23
+ /** `rows.length`, for the diagnostics line ("N rows, M cells"). */
24
+ rowCount: number;
25
+ cellCount: number;
26
+ /** Whether `readPdf` found any text on this page — `false` means a scan: the person sees at once there is nothing here to read (issue #94's 5b). */
27
+ hasTextLayer: boolean;
28
+ }
29
+ /** The PDF canvas's view of a read document: every page's cells and rows, ready to draw over `pdf.js`'s own rendering. */
30
+ export interface PdfDocumentView {
31
+ pages: PdfPageView[];
32
+ }
33
+ /**
34
+ * Builds the PDF canvas's view model (studio plan §3.4, issue #94's 5b) from
35
+ * an already-read `PdfDocument` (`take-snapshot`'s cached body — no second
36
+ * read of the file): every cell and row `readPdf` found, in PDF points, plus
37
+ * per-page counts and whether the page has a text layer at all. Table-specific
38
+ * diagnostics (the header row, the column bands, the wrapped-row regrouping)
39
+ * are not here — they depend on a `table` extract's own options, so they come
40
+ * from `table-preview.use-case.ts` instead, computed live as those options
41
+ * change.
42
+ *
43
+ * @param document - The read PDF.
44
+ * @returns The view.
45
+ */
46
+ export declare function pdfDocumentView(document: PdfDocument): PdfDocumentView;
47
+ //# sourceMappingURL=pdf-view.mapper.d.ts.map
@@ -0,0 +1,152 @@
1
+ import type { DeckDocument, PdfDocument, PdfTable, TableAlign, TableBandDiagnostics, WorkbookCell, WorkbookDocument } from '@opencraw/core';
2
+ /**
3
+ * A `table` extract's own options, as the studio's picks build them: string
4
+ * patterns, not yet compiled — the same shape `ExtractStep`'s `table`-kind
5
+ * fields have, kept separate so this slice does not import the engine's
6
+ * recipe schema for one interface.
7
+ */
8
+ export interface TablePreviewOptions {
9
+ /** Matches the header row (the recipe's `selector`). */
10
+ header: string;
11
+ /** Matches the row that ends the table. */
12
+ until?: string;
13
+ /** Output key -> a pattern for that column's header cell. */
14
+ columns?: Record<string, string>;
15
+ align?: TableAlign;
16
+ }
17
+ /** One matched table, with the exact rows to highlight on the page. */
18
+ export interface TablePreviewMatch {
19
+ page: number;
20
+ /** Index into that page's rows of the header row. */
21
+ headerRowIndex: number;
22
+ /** Every row index (into that page's rows) this match highlights: the header, every regrouped body row, and the `until` row when there is one — sorted, deduplicated. */
23
+ matchedRowIndices: number[];
24
+ /** The column bands the body's cells clustered into, left to right — a column band pick reads its `name` (issue #94's 5b). */
25
+ bands: TableBandDiagnostics[];
26
+ /** The gap (in points) two cell edges may differ by and still share a band — shown while dragging a band edge. */
27
+ bandTolerance: number;
28
+ table: PdfTable;
29
+ }
30
+ /** What `previewPdfTable` answers with: either the matches, or, when a pattern does not compile, why. */
31
+ export interface TablePreviewResult {
32
+ matches: TablePreviewMatch[];
33
+ error?: string;
34
+ }
35
+ /**
36
+ * Runs a `table` extract's options against an already-read PDF (studio plan
37
+ * §3.4, issue #94's 5b: the live preview) — a pure function of the document
38
+ * and the options, so re-running it on every keystroke as the person edits
39
+ * `selector`/`until`/`columns` costs nothing: no re-fetch, no re-parse
40
+ * (`readPdf` already ran once, when `take-snapshot` captured the document).
41
+ *
42
+ * The workbook grid's live preview (issue #94's 5c) is `previewGridTable`,
43
+ * below: the same idea (a pure re-run of the options against the cached
44
+ * document), but its own result shape — a workbook table has no page, no
45
+ * column bands, no wrapped-row regrouping, so folding it into
46
+ * `TablePreviewMatch`/`TablePreviewResult` would leave most of those fields
47
+ * meaningless for a grid pick; a `GridTablePreviewMatch`/`GridTablePreviewResult`
48
+ * sibling reads honestly instead.
49
+ *
50
+ * @param document - The already-read PDF.
51
+ * @param options - The `table` extract's options, not yet compiled to `RegExp`.
52
+ * @returns Every match, each with the exact row indices to highlight — or `error` (and no matches) when a pattern is not a valid regular expression, expected while the person is still typing it.
53
+ */
54
+ export declare function previewPdfTable(document: PdfDocument, options: TablePreviewOptions): TablePreviewResult;
55
+ /**
56
+ * A `table` extract's own options for a workbook (CSV or spreadsheet), as
57
+ * the studio's grid canvas picks build them (issue #94's 5c) — mirrors
58
+ * `@opencraw/core`'s `GridTableQuery`, kept as strings (not yet compiled)
59
+ * the same way `TablePreviewOptions` does for PDF.
60
+ */
61
+ export interface GridTablePreviewOptions {
62
+ /** Matches the names of the sheets to read; default every sheet. */
63
+ sheet?: string;
64
+ /** Matches the header row (the recipe's `selector`). */
65
+ header: string;
66
+ /** Matches the row that ends the table. */
67
+ until?: string;
68
+ /** Output key -> a pattern for that column's header cell. */
69
+ columns?: Record<string, string>;
70
+ /** How many rows the header spans; default 1. */
71
+ headerRows?: number;
72
+ /** Output keys whose empty cells take the value of the row above (a merged-group label pick, issue #94's 5c). */
73
+ fillDown?: string[];
74
+ /** Read hidden sheets and rows too. */
75
+ includeHidden?: boolean;
76
+ }
77
+ /** One table matched by a `table` extract's options against a workbook — mirrors `@opencraw/core`'s `GridTable`. */
78
+ export interface GridTablePreviewMatch {
79
+ sheet: string;
80
+ title: string;
81
+ header: string[];
82
+ rows: Record<string, WorkbookCell>[];
83
+ }
84
+ /** What `previewGridTable` answers with: either the matches, or, when a pattern does not compile, why (mirrors `TablePreviewResult`). */
85
+ export interface GridTablePreviewResult {
86
+ matches: GridTablePreviewMatch[];
87
+ error?: string;
88
+ }
89
+ /**
90
+ * Runs a `table` extract's options against an already-read workbook (studio
91
+ * plan §3.4, issue #94's 5c: the live preview) — a pure function of the
92
+ * document and the options, exactly like `previewPdfTable` above: no
93
+ * re-fetch, no re-parse (`csvWorkbook`/`readXlsxWorkbook` already ran once,
94
+ * when `take-snapshot` captured the document).
95
+ *
96
+ * @param document - The already-read workbook.
97
+ * @param options - The `table` extract's options, not yet compiled to `RegExp`.
98
+ * @returns Every matched table — or `error` (and no matches) when a pattern is not a valid regular expression, expected while the person is still typing it.
99
+ */
100
+ export declare function previewGridTable(document: WorkbookDocument, options: GridTablePreviewOptions): GridTablePreviewResult;
101
+ /**
102
+ * A `table` extract's own options for a deck, as the studio's deck canvas
103
+ * picks build them (issue #94's 5d) — mirrors `@opencraw/core`'s
104
+ * `DeckTableQuery`, kept as strings (not yet compiled) the same way
105
+ * `TablePreviewOptions`/`GridTablePreviewOptions` do for PDF/workbook.
106
+ */
107
+ export interface DeckTablePreviewOptions {
108
+ /** Matches the titles of the slides to read; default every slide. */
109
+ slide?: string;
110
+ /** Read text boxes laid out as a table instead of native tables. */
111
+ shapes?: boolean;
112
+ /** With `shapes`: how a row's values sit against a box wrapped over several lines. */
113
+ align?: TableAlign;
114
+ /** Matches the header row (the recipe's `selector`). */
115
+ header: string;
116
+ /** Matches the row that ends the table. */
117
+ until?: string;
118
+ /** Output key -> a pattern for that column's header cell. */
119
+ columns?: Record<string, string>;
120
+ /** How many rows the header spans; default 1 (native tables only). */
121
+ headerRows?: number;
122
+ /** Output keys whose empty cells take the value of the row above (native tables only). */
123
+ fillDown?: string[];
124
+ /** Read hidden slides too. */
125
+ includeHidden?: boolean;
126
+ }
127
+ /** One table matched by a `table` extract's options against a deck — mirrors `@opencraw/core`'s `DeckTable`. */
128
+ export interface DeckTablePreviewMatch {
129
+ slide: number;
130
+ slideTitle: string;
131
+ title: string;
132
+ header: string[];
133
+ rows: Record<string, WorkbookCell>[];
134
+ }
135
+ /** What `previewDeckTable` answers with: either the matches, or, when a pattern does not compile, why (mirrors `TablePreviewResult`/`GridTablePreviewResult`). */
136
+ export interface DeckTablePreviewResult {
137
+ matches: DeckTablePreviewMatch[];
138
+ error?: string;
139
+ }
140
+ /**
141
+ * Runs a `table` extract's options against an already-read deck (studio plan
142
+ * §3.4, issue #94's 5d: the live preview) — a pure function of the document
143
+ * and the options, exactly like `previewPdfTable`/`previewGridTable` above:
144
+ * no re-fetch, no re-parse (`readPptxDeck` already ran once, when
145
+ * `take-snapshot` captured the document).
146
+ *
147
+ * @param document - The already-read deck.
148
+ * @param options - The `table` extract's options, not yet compiled to `RegExp`.
149
+ * @returns Every matched table — or `error` (and no matches) when a pattern is not a valid regular expression, expected while the person is still typing it.
150
+ */
151
+ export declare function previewDeckTable(document: DeckDocument, options: DeckTablePreviewOptions): DeckTablePreviewResult;
152
+ //# sourceMappingURL=table-preview.use-case.d.ts.map
@@ -0,0 +1,47 @@
1
+ import type { HttpBody } from '@opencraw/core';
2
+ /** A JSON/XML value's shape, for the tree's icon and for deciding whether a node can generalise to a list. */
3
+ export type TreeValueType = 'object' | 'array' | 'string' | 'number' | 'boolean' | 'null' | 'element';
4
+ /** One row of the document tree (studio plan §3.4, issue #94's 5a): a JSON/YAML value or an XML element/attribute. */
5
+ export interface DocumentTreeNode {
6
+ /** A stable key for React lists: the node's own path. */
7
+ id: string;
8
+ /** The property name, array index or element/attribute name to show. */
9
+ label: string;
10
+ valueType: TreeValueType;
11
+ /** A short rendering of a leaf's value; absent for `object`/`array`/`element`. */
12
+ preview?: string;
13
+ /** This exact node's JSONPath (JSON/YAML documents only). */
14
+ jsonpath?: string;
15
+ /** This exact node's XPath (XML documents only). */
16
+ xpath?: string;
17
+ /**
18
+ * Set when this node is one item of an array (JSON) or one of several
19
+ * same-named siblings (XML): the path generalised to every item —
20
+ * `$.results[*]` instead of `$.results[2]` — and how many there are, so a
21
+ * pick can offer "the whole list" per studio plan §3.4.
22
+ */
23
+ listPath?: string;
24
+ listCount?: number;
25
+ /** XML only: the element's own attributes, name -> value (also reachable as child rows). */
26
+ attributes?: Record<string, string>;
27
+ children: DocumentTreeNode[];
28
+ }
29
+ /** What `document-tree` answers with: the parsed document as a tree, and (XML only) the namespace prefixes it declares or that reading synthesised for an unprefixed default namespace, offered so a pick's `extract` can reference them (studio plan §3.4). */
30
+ export interface DocumentTreeView {
31
+ format: 'json' | 'xml';
32
+ root: DocumentTreeNode;
33
+ namespaces?: Record<string, string>;
34
+ }
35
+ /**
36
+ * Builds the document tree for `document-tree` (studio plan §3.4, issue
37
+ * #94's 5a) from the body `page-snapshot`'s `take-snapshot.use-case.ts`
38
+ * already fetched — no second read of the document.
39
+ *
40
+ * @param body - The parsed body (`HttpBody`); YAML and JSON Lines both
41
+ * arrive here already normalised to `{ kind: 'json' }` by `http.client.ts`.
42
+ * @returns The tree.
43
+ * @throws Error when `body`'s kind is not `json` or `xml` (PDF, workbook and
44
+ * deck documents get their own canvases — 5b/5c/5d, not this mapper).
45
+ */
46
+ export declare function documentTreeView(body: HttpBody): DocumentTreeView;
47
+ //# sourceMappingURL=tree-view.mapper.d.ts.map
@@ -0,0 +1,51 @@
1
+ import type { WorkbookCell, WorkbookDocument } from '@opencraw/core';
2
+ /** A cell's type, for the grid to show it as (issue #94's 5c): a number and a boolean keep their runtime type; a date is a string that reads as one of the ISO shapes `read-xlsx.client.ts` writes (a day, a moment, or both) — the workbook model itself has no separate date type (`WorkbookCell` is `string | number | boolean`), so this is the same "does it look like one" a person reading the cell would make. */
3
+ export type GridCellType = 'string' | 'number' | 'boolean' | 'date';
4
+ /** One cell, with the type the grid shows it as. */
5
+ export interface GridCellView {
6
+ value: WorkbookCell;
7
+ type: GridCellType;
8
+ }
9
+ /** One merged range, 0-based and inclusive — mirrors `@opencraw/core`'s A1 references (`Sheet.merges`), already resolved to bounds so the grid can draw it as one cell (`rowSpan`/`colSpan`) instead of parsing `B10:B13` itself. */
10
+ export interface GridMergeView {
11
+ ref: string;
12
+ top: number;
13
+ left: number;
14
+ bottom: number;
15
+ right: number;
16
+ }
17
+ /** One sheet of the grid canvas (issue #94's 5c). */
18
+ export interface GridSheetView {
19
+ name: string;
20
+ hidden: boolean;
21
+ /** 0-based row indices hidden in the sheet. */
22
+ hiddenRows: number[];
23
+ /** The widest row's own length, ragged rows included — for the grid to size its columns. */
24
+ columnCount: number;
25
+ rows: GridCellView[][];
26
+ merges: GridMergeView[];
27
+ }
28
+ /** What `grid-view` answers with (studio plan §3.4, issue #94's 5c): every sheet's cells, typed, with hidden sheets/rows marked and merged ranges resolved — the CSV/workbook grid's own view of the document, structurally the same idea as `pdf-view.mapper.ts`'s `PdfDocumentView`. */
29
+ export interface WorkbookDocumentView {
30
+ sheets: GridSheetView[];
31
+ /** Present when the workbook came from a CSV — the detected (or overridden) delimiter and encoding, shown and overridable (issue #94's 5c). */
32
+ csv?: {
33
+ encoding: string;
34
+ delimiter: string;
35
+ };
36
+ }
37
+ /**
38
+ * Builds the grid canvas's view model (studio plan §3.4, issue #94's 5c) from
39
+ * an already-read `WorkbookDocument` (`take-snapshot`'s cached body — no
40
+ * second read of the file): every sheet's cells, typed, with hidden sheets
41
+ * and rows marked, and merged ranges resolved to bounds so the grid draws
42
+ * them as one cell. Table-specific diagnostics (the matched rows of the
43
+ * current `table` extract's options) are not here — they depend on the
44
+ * picks so far, so they come from `table-preview.use-case.ts`'s
45
+ * `previewGridTable` instead, computed live as those options change.
46
+ *
47
+ * @param document - The read workbook (a spreadsheet or a CSV).
48
+ * @returns The view.
49
+ */
50
+ export declare function workbookDocumentView(document: WorkbookDocument): WorkbookDocumentView;
51
+ //# sourceMappingURL=workbook-view.mapper.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { Step } from '@opencraw/core';
2
+ import type { ResolvedAction } from './recorded-action.contract.js';
3
+ /**
4
+ * Turns one resolved recorded action into the recipe step it reads as
5
+ * (issue #95's card sentences): `Click <selector>`, `Fill <selector> with
6
+ * <value>`, `Select <selector> = <value>`, `Press <key>`, `Scroll to
7
+ * bottom`. Pure: `recorder-session.use-case.ts` has already resolved the
8
+ * selector (`selector-inference`) and, for a secret field, already replaced
9
+ * `value` with its `{{env.NAME}}` placeholder (`secret-field.policy.ts`) —
10
+ * this mapper never sees, and so can never leak, a real secret value.
11
+ *
12
+ * @param action - The resolved action.
13
+ * @returns The step it becomes, or `undefined` for an action this mapper cannot place (a click/fill/select with no verified selector).
14
+ */
15
+ export declare function actionToStep(action: ResolvedAction): Step | undefined;
16
+ //# sourceMappingURL=action-to-step.mapper.d.ts.map
@@ -0,0 +1,13 @@
1
+ export { openRecorderSession } from './recorder-session.use-case.js';
2
+ export type { RecorderCallbacks, RecorderNote, RecorderSessionHandle, RecorderSessionOptions } from './recorder-session.use-case.js';
3
+ export { rawActionSchema, recordedFieldSchema, recordedLinkSchema, RECORDED_ACTION_KINDS, UNSUPPORTED_REASONS } from './recorded-action.contract.js';
4
+ export type { RawAction, RecordedActionKind, RecordedField, RecordedLink, ResolvedAction, UnsupportedReason } from './recorded-action.contract.js';
5
+ export { actionToStep } from './action-to-step.mapper.js';
6
+ export { isSecretField, secretEnvName, secretPlaceholder } from './secret-field.policy.js';
7
+ export { looksLikeNextLink, paginateStepFor } from './next-link.policy.js';
8
+ export type { PaginateStep } from './next-link.policy.js';
9
+ export { insertWaitStep } from './wait-insertion.policy.js';
10
+ export type { WaitContext, WaitStep } from './wait-insertion.policy.js';
11
+ export { recorderScript } from './recorder-script.client.js';
12
+ export type { Page } from 'playwright';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,27 @@
1
+ import type { Step } from '@opencraw/core';
2
+ import type { RecordedLink } from './recorded-action.contract.js';
3
+ /** `paginate`'s own `next` shape, `selector` form only — the only one a recorded click can offer. */
4
+ export type PaginateStep = Extract<Step, {
5
+ type: 'paginate';
6
+ }>;
7
+ /**
8
+ * Whether a clicked, navigating element looks like a "next" link (issue
9
+ * #95's exact heuristics): `rel="next"`, link text matching "next", or the
10
+ * resolved selector itself carrying `li.next a`/`a[aria-label=Next]`. Only
11
+ * meaningful for a click that navigated — the caller checks that first.
12
+ *
13
+ * @param link - The anchor's own `rel`/text/`aria-label`, as reported by `recorder-script.client.ts`.
14
+ * @param selector - The action's resolved selector (`selector-inference`'s own candidate).
15
+ * @returns Whether the studio should offer to turn this click into a `paginate` step.
16
+ */
17
+ export declare function looksLikeNextLink(link: RecordedLink | undefined, selector: string | undefined): boolean;
18
+ /**
19
+ * The `paginate` step a "next" link's selector offers (studio plan §3.1/#95:
20
+ * `For every page — click <selector>`), with an empty body: the studio
21
+ * offers this shape, the person fills in what runs on each page.
22
+ *
23
+ * @param selector - The next link's resolved, verified selector.
24
+ * @returns A `paginate` step, `next.selector` only.
25
+ */
26
+ export declare function paginateStepFor(selector: string): PaginateStep;
27
+ //# sourceMappingURL=next-link.policy.d.ts.map
@@ -0,0 +1,114 @@
1
+ import { z } from 'zod';
2
+ /** The kinds of user action the in-page recorder script (`recorder-script.client.ts`) reports. */
3
+ export declare const RECORDED_ACTION_KINDS: readonly ["click", "fill", "select", "keypress", "scroll"];
4
+ export type RecordedActionKind = typeof RECORDED_ACTION_KINDS[number];
5
+ /** Why a report was refused before it became an action: out of this phase's scope (issue #95). */
6
+ export declare const UNSUPPORTED_REASONS: readonly ["iframe", "shadow-dom"];
7
+ export type UnsupportedReason = typeof UNSUPPORTED_REASONS[number];
8
+ /**
9
+ * The type/name/id of the form field a `fill`/`select` landed on, exactly as
10
+ * the live DOM reports them — `secret-field.policy.ts`'s only input. Never
11
+ * carries the field's value: that travels separately, on the action itself.
12
+ */
13
+ export declare const recordedFieldSchema: z.ZodObject<{
14
+ type: z.ZodOptional<z.ZodString>;
15
+ name: z.ZodOptional<z.ZodString>;
16
+ id: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$strip>;
18
+ export type RecordedField = z.infer<typeof recordedFieldSchema>;
19
+ /** What `next-link.policy.ts` needs off a clicked anchor: never the whole element. */
20
+ export declare const recordedLinkSchema: z.ZodObject<{
21
+ rel: z.ZodOptional<z.ZodString>;
22
+ text: z.ZodOptional<z.ZodString>;
23
+ ariaLabel: z.ZodOptional<z.ZodString>;
24
+ }, z.core.$strip>;
25
+ export type RecordedLink = z.infer<typeof recordedLinkSchema>;
26
+ /**
27
+ * The wire shape of one action as `recorder-script.client.ts` reports it,
28
+ * over the Playwright binding `recorder-session.use-case.ts` exposes: the
29
+ * `data-oc-node` id of the element involved (`selector-inference`'s own
30
+ * marker attribute, `@opencraw/core`'s `NODE_ID_ATTRIBUTE`), never a
31
+ * selector — the studio, not the page, decides that (studio plan §3.2,
32
+ * issue #95). Never the field's real value when it might be a secret: the
33
+ * script itself does not know which fields are secret (`secret-field.policy.ts`
34
+ * runs server-side, once a `RecordedField` is known), but nothing here
35
+ * *requires* a value to be typed out either way — `recorder-session.use-case.ts`
36
+ * discards it the moment a secret is detected.
37
+ *
38
+ * `html` is the document's own markup, captured by the script itself at the
39
+ * moment of the event (`document.documentElement.outerHTML`), not fetched
40
+ * again afterwards: a click that navigates can leave the page before a
41
+ * later `page.content()` call would resolve, reading the *next* page's
42
+ * markup instead of the one the click actually happened on. Capturing it
43
+ * synchronously, in the same event the node id is stamped in, means the
44
+ * selector is always resolved against the exact document the action
45
+ * happened on — still "verified against the page" (issue #95), just without
46
+ * the race a second round trip would risk.
47
+ */
48
+ export declare const rawActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
49
+ kind: z.ZodLiteral<"click">;
50
+ nodeId: z.ZodString;
51
+ html: z.ZodString;
52
+ link: z.ZodOptional<z.ZodObject<{
53
+ rel: z.ZodOptional<z.ZodString>;
54
+ text: z.ZodOptional<z.ZodString>;
55
+ ariaLabel: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strip>>;
57
+ }, z.core.$strip>, z.ZodObject<{
58
+ kind: z.ZodLiteral<"fill">;
59
+ nodeId: z.ZodString;
60
+ html: z.ZodString;
61
+ value: z.ZodString;
62
+ field: z.ZodOptional<z.ZodObject<{
63
+ type: z.ZodOptional<z.ZodString>;
64
+ name: z.ZodOptional<z.ZodString>;
65
+ id: z.ZodOptional<z.ZodString>;
66
+ }, z.core.$strip>>;
67
+ }, z.core.$strip>, z.ZodObject<{
68
+ kind: z.ZodLiteral<"select">;
69
+ nodeId: z.ZodString;
70
+ html: z.ZodString;
71
+ value: z.ZodString;
72
+ field: z.ZodOptional<z.ZodObject<{
73
+ type: z.ZodOptional<z.ZodString>;
74
+ name: z.ZodOptional<z.ZodString>;
75
+ id: z.ZodOptional<z.ZodString>;
76
+ }, z.core.$strip>>;
77
+ }, z.core.$strip>, z.ZodObject<{
78
+ kind: z.ZodLiteral<"keypress">;
79
+ nodeId: z.ZodOptional<z.ZodString>;
80
+ html: z.ZodOptional<z.ZodString>;
81
+ key: z.ZodString;
82
+ }, z.core.$strip>, z.ZodObject<{
83
+ kind: z.ZodLiteral<"scroll">;
84
+ to: z.ZodLiteral<"bottom">;
85
+ }, z.core.$strip>, z.ZodObject<{
86
+ kind: z.ZodLiteral<"unsupported">;
87
+ reason: z.ZodEnum<{
88
+ iframe: "iframe";
89
+ "shadow-dom": "shadow-dom";
90
+ }>;
91
+ }, z.core.$strip>], "kind">;
92
+ export type RawAction = z.infer<typeof rawActionSchema>;
93
+ /**
94
+ * One action once `recorder-session.use-case.ts` has resolved it against the
95
+ * live page: `selector` comes from the phase 2 generator
96
+ * (`selector-inference`'s `candidatesFor`/`rankCandidates`), verified
97
+ * against the page it was recorded on, per issue #95. `value` already holds
98
+ * a `{{env.NAME}}` placeholder, never a real secret, once `secret-field.policy.ts`
99
+ * has flagged the field. `navigated` is set when the action's page changed
100
+ * (a click or a key press that submitted a form/followed a link).
101
+ */
102
+ export interface ResolvedAction {
103
+ kind: RecordedActionKind;
104
+ selector?: string;
105
+ value?: string;
106
+ key?: string;
107
+ field?: RecordedField;
108
+ link?: RecordedLink;
109
+ navigated?: {
110
+ url: string;
111
+ status?: number;
112
+ };
113
+ }
114
+ //# sourceMappingURL=recorded-action.contract.d.ts.map
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The in-page script `recorder-session.use-case.ts` installs on every page
3
+ * of the studio's own headed browser window (`context.addInitScript`),
4
+ * reporting the person's actions to the binding it also exposes on the
5
+ * context (`context.exposeBinding`) — issue #95's "a script injected into
6
+ * every page ... reports the user's actions: click, type, select, key
7
+ * press, scroll".
8
+ *
9
+ * Kept as a plain string, not a TypeScript function passed to
10
+ * `page.evaluate`/`addInitScript`, for the same reason as
11
+ * `page-snapshot/hidden-marks.algorithm.ts`'s `hiddenMarksScript`: it
12
+ * references `window`/`document` as globals, which `AGENTS.md`'s "things
13
+ * that bit before" and the repo's `isolated-functions` lint rule forbid for
14
+ * an in-page TypeScript function.
15
+ *
16
+ * What it reports, and what it deliberately does not:
17
+ *
18
+ * - **click**: the nearest clickable ancestor (`a`, `button`,
19
+ * `input[type=submit|button]`) of the element clicked, or the element
20
+ * itself; for an `<a>`, also its `rel`, text and `aria-label` —
21
+ * `next-link.policy.ts`'s only input.
22
+ * - **fill**: on `blur` of a text-like input/textarea whose value changed
23
+ * since it was focused (never on every keystroke) — the field's `type`,
24
+ * `name` and `id`, and the value *as typed*; whether that value is a
25
+ * secret, and what replaces it, is `secret-field.policy.ts`'s call,
26
+ * server-side, not this script's.
27
+ * - **select**: on `change` of a `<select>`.
28
+ * - **keypress**: `Enter` only (issue #95's own example, "Press Enter");
29
+ * every other key is noise a recipe step has no shape for.
30
+ * - **scroll**: once per "scroll session" (debounced), when the page has
31
+ * been scrolled within `NEAR_BOTTOM_PX` of its bottom.
32
+ * - **unsupported**: once, the first time an event's target sits inside a
33
+ * shadow root, or this script runs in a frame that is not the top window
34
+ * (an iframe) — issue #95's explicit out-of-scope cases, reported instead
35
+ * of attempted.
36
+ *
37
+ * Every reported element is marked with `attribute` (`data-oc-node` by
38
+ * default, `@opencraw/core`'s `NODE_ID_ATTRIBUTE`) if it does not already
39
+ * carry one, the same attribute `selector-inference`'s `pathToNode` reads —
40
+ * so `recorder-session.use-case.ts` can turn a report straight into a
41
+ * verified selector with the phase 2 generator, never inventing its own.
42
+ *
43
+ * @param bindingName - The name Playwright's `exposeBinding` gave the reporting function (`window[bindingName]`).
44
+ * @param attribute - The marker attribute; defaults to `NODE_ID_ATTRIBUTE`.
45
+ * @returns A self-invoking script, ready for `context.addInitScript({ content: recorderScript(...) })`.
46
+ */
47
+ export declare function recorderScript(bindingName: string, attribute?: string): string;
48
+ //# sourceMappingURL=recorder-script.client.d.ts.map