@opencraw/studio 0.0.18 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-provisioning/ensure-browser-launch.use-case.d.ts +12 -0
- package/dist/browser-provisioning/index.d.ts +2 -0
- package/dist/browser-provisioning/install-chromium.use-case.d.ts +2 -0
- package/dist/browser-provisioning/missing-browser.policy.d.ts +3 -0
- package/dist/document-view/deck-view.mapper.d.ts +70 -0
- package/dist/document-view/index.d.ts +13 -0
- package/dist/document-view/pdf-view.mapper.d.ts +47 -0
- package/dist/document-view/region-preview.use-case.d.ts +30 -0
- package/dist/document-view/table-preview.use-case.d.ts +152 -0
- package/dist/document-view/tree-view.mapper.d.ts +47 -0
- package/dist/document-view/workbook-view.mapper.d.ts +51 -0
- package/dist/explain-why/index.d.ts +5 -0
- package/dist/explain-why/item-hint.algorithm.d.ts +13 -0
- package/dist/explain-why/why-sentence.mapper.d.ts +48 -0
- package/dist/explain-why/why.use-case.d.ts +26 -0
- package/dist/flow-recording/action-to-step.mapper.d.ts +16 -0
- package/dist/flow-recording/index.d.ts +13 -0
- package/dist/flow-recording/next-link.policy.d.ts +27 -0
- package/dist/flow-recording/recorded-action.contract.d.ts +114 -0
- package/dist/flow-recording/recorder-script.client.d.ts +48 -0
- package/dist/flow-recording/recorder-session.use-case.d.ts +67 -0
- package/dist/flow-recording/secret-field.policy.d.ts +33 -0
- package/dist/flow-recording/wait-insertion.policy.d.ts +26 -0
- package/dist/index.d.ts +14 -1
- package/dist/main.d.ts +18 -0
- package/dist/page-inspector/dom-tree.mapper.d.ts +32 -0
- package/dist/page-inspector/index.d.ts +7 -0
- package/dist/page-inspector/page-data.algorithm.d.ts +39 -0
- package/dist/page-inspector/responses-seen.use-case.d.ts +36 -0
- package/dist/page-snapshot/fetch-start-page.use-case.d.ts +20 -0
- package/dist/page-snapshot/hidden-marks.algorithm.d.ts +23 -0
- package/dist/page-snapshot/index.d.ts +13 -0
- package/dist/page-snapshot/invalidate-stale-snapshot.use-case.d.ts +12 -0
- package/dist/page-snapshot/pdf-bytes.use-case.d.ts +16 -0
- package/dist/page-snapshot/reread-csv.use-case.d.ts +22 -0
- package/dist/page-snapshot/rewrite-document.mapper.d.ts +27 -0
- package/dist/page-snapshot/snapshot.store.d.ts +14 -0
- package/dist/page-snapshot/start-point.policy.d.ts +12 -0
- package/dist/page-snapshot/take-snapshot.use-case.d.ts +60 -0
- package/dist/recipe-workspace/import-document.use-case.d.ts +22 -0
- package/dist/recipe-workspace/index.d.ts +5 -0
- package/dist/recipe-workspace/open-workspace.use-case.d.ts +15 -0
- package/dist/recipe-workspace/save-recipe.use-case.d.ts +21 -0
- package/dist/sample-run/index.d.ts +8 -0
- package/dist/sample-run/last-run.store.d.ts +17 -0
- package/dist/sample-run/load-recipe-pair.use-case.d.ts +18 -0
- package/dist/sample-run/run-sample.use-case.d.ts +40 -0
- package/dist/sample-run/sample-run-record.contract.d.ts +48 -0
- package/dist/scope-outline/card-sentence.mapper.d.ts +18 -0
- package/dist/scope-outline/index.d.ts +8 -0
- package/dist/scope-outline/outline-to-recipe.mapper.d.ts +17 -0
- package/dist/scope-outline/outline.model.d.ts +57 -0
- package/dist/scope-outline/recipe-to-outline.mapper.d.ts +14 -0
- package/dist/scope-outline/scope-at-path.algorithm.d.ts +19 -0
- package/dist/selector-inference/class-token.policy.d.ts +35 -0
- package/dist/selector-inference/dom-path.model.d.ts +73 -0
- package/dist/selector-inference/index.d.ts +12 -0
- package/dist/selector-inference/list-inference.algorithm.d.ts +43 -0
- package/dist/selector-inference/selector-candidates.algorithm.d.ts +22 -0
- package/dist/selector-inference/selector-ranking.policy.d.ts +27 -0
- package/dist/selector-inference/shadow-dom.error.d.ts +11 -0
- package/dist/selector-inference/take-kind.policy.d.ts +12 -0
- package/dist/studio-api/command.contract.d.ts +531 -0
- package/dist/studio-api/deck-preview-view.contract.d.ts +28 -0
- package/dist/studio-api/deck-view.contract.d.ts +127 -0
- package/dist/studio-api/document-tree-view.contract.d.ts +26 -0
- package/dist/studio-api/event.contract.d.ts +155 -0
- package/dist/studio-api/grid-preview-view.contract.d.ts +26 -0
- package/dist/studio-api/grid-view.contract.d.ts +75 -0
- package/dist/studio-api/import-document-view.contract.d.ts +8 -0
- package/dist/studio-api/index.d.ts +43 -0
- package/dist/studio-api/infer-selector-view.contract.d.ts +68 -0
- package/dist/studio-api/inspect-view.contract.d.ts +62 -0
- package/dist/studio-api/outline-view.contract.d.ts +37 -0
- package/dist/studio-api/pdf-view.contract.d.ts +66 -0
- package/dist/studio-api/region-preview-view.contract.d.ts +53 -0
- package/dist/studio-api/responses-seen-view.contract.d.ts +20 -0
- package/dist/studio-api/sample-run-view.contract.d.ts +28 -0
- package/dist/studio-api/snapshot-view.contract.d.ts +30 -0
- package/dist/studio-api/start-page-view.contract.d.ts +7 -0
- package/dist/studio-api/table-preview-view.contract.d.ts +65 -0
- package/dist/studio-api/verify-selector-view.contract.d.ts +18 -0
- package/dist/studio-api/why-view.contract.d.ts +16 -0
- package/dist/studio-api/workspace-view.contract.d.ts +67 -0
- package/dist/studio-server/access-token.policy.d.ts +26 -0
- package/dist/studio-server/deck-preview.handler.d.ts +17 -0
- package/dist/studio-server/deck-view.handler.d.ts +15 -0
- package/dist/studio-server/document-tree.handler.d.ts +14 -0
- package/dist/studio-server/explain-why.handler.d.ts +14 -0
- package/dist/studio-server/fetch-start-page.handler.d.ts +14 -0
- package/dist/studio-server/grid-preview.handler.d.ts +17 -0
- package/dist/studio-server/grid-view.handler.d.ts +20 -0
- package/dist/studio-server/import-document.handler.d.ts +14 -0
- package/dist/studio-server/index.d.ts +3 -0
- package/dist/studio-server/infer-selector.handler.d.ts +18 -0
- package/dist/studio-server/inspect-page.handler.d.ts +18 -0
- package/dist/studio-server/open-workspace.handler.d.ts +20 -0
- package/dist/studio-server/pdf-bytes.handler.d.ts +17 -0
- package/dist/studio-server/pdf-view.handler.d.ts +14 -0
- package/dist/studio-server/recording.handler.d.ts +36 -0
- package/dist/studio-server/region-preview.handler.d.ts +17 -0
- package/dist/studio-server/responses-seen.handler.d.ts +16 -0
- package/dist/studio-server/run-sample.handler.d.ts +28 -0
- package/dist/studio-server/save-outline.handler.d.ts +18 -0
- package/dist/studio-server/save-recipe.handler.d.ts +15 -0
- package/dist/studio-server/static-file.handler.d.ts +14 -0
- package/dist/studio-server/studio-http.use-case.d.ts +40 -0
- package/dist/studio-server/table-preview.handler.d.ts +16 -0
- package/dist/studio-server/take-snapshot.handler.d.ts +16 -0
- package/dist/studio-server/verify-selector.handler.d.ts +18 -0
- package/dist/studio-server/websocket.client.d.ts +22 -0
- package/dist/studio-server/workspace.store.d.ts +36 -0
- package/dist/trusted-plugins/index.d.ts +2 -0
- package/dist/trusted-plugins/trusted-plugins.contract.d.ts +14 -0
- package/package.json +3 -3
|
@@ -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
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Page } from 'playwright';
|
|
2
|
+
import type { BrowserSessionConfig } from '@opencraw/core';
|
|
3
|
+
import type { OutlineNode } from '../studio-api';
|
|
4
|
+
export interface RecorderNote {
|
|
5
|
+
kind: 'next-link' | 'unsupported' | 'info';
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
/** Where recorded actions and notices go as a recording proceeds. */
|
|
9
|
+
export interface RecorderCallbacks {
|
|
10
|
+
onCard: (node: OutlineNode, secret: boolean) => void;
|
|
11
|
+
onNote: (note: RecorderNote) => void;
|
|
12
|
+
}
|
|
13
|
+
export interface RecorderSessionOptions {
|
|
14
|
+
/** The page the headed window opens on. */
|
|
15
|
+
startUrl: string;
|
|
16
|
+
/** Where the studio's own recorder profiles live — see `BrowserProfiles`; never the folder a crawl's own `session.browserProfile` uses. */
|
|
17
|
+
profileDir: string;
|
|
18
|
+
/** Browser launch settings; `headless` is always forced `false` — a recording is, by definition, a window the person watches and drives. */
|
|
19
|
+
browser?: BrowserSessionConfig;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A recording in progress: `stop` closes the window and hands back every
|
|
23
|
+
* step recorded, in order. `page` is the window's own live Playwright page
|
|
24
|
+
* — public the same way `BrowserSession.page` already is, for a caller (a
|
|
25
|
+
* future embedded view, this phase's own e2e test driving the window "as
|
|
26
|
+
* the person would") that needs to reach the live window itself, not just
|
|
27
|
+
* the reported actions.
|
|
28
|
+
*/
|
|
29
|
+
export interface RecorderSessionHandle {
|
|
30
|
+
page: Page;
|
|
31
|
+
stop: () => Promise<{
|
|
32
|
+
steps: Record<string, unknown>[];
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Opens the headed browser window a flow is recorded in (issue #95, studio
|
|
37
|
+
* plan §3.1's last paragraph / phase 6): a Playwright persistent context, in
|
|
38
|
+
* the studio's own profile (`BrowserProfiles`, `headless: false` — the only
|
|
39
|
+
* precedent this codebase already has for a headed launch,
|
|
40
|
+
* `packages/core/src/browser-session/browser-profile.store.ts`), with
|
|
41
|
+
* `recorder-script.client.ts` installed on every page
|
|
42
|
+
* (`context.addInitScript`) and reporting through a context-wide binding
|
|
43
|
+
* (`context.exposeBinding`, so a page opened mid-recording — a link with
|
|
44
|
+
* `target=_blank`, say — is covered too, not only the first page).
|
|
45
|
+
*
|
|
46
|
+
* Each reported action is resolved into a verified selector
|
|
47
|
+
* (`selector-inference`, against the page's own current markup — issue
|
|
48
|
+
* #95's "verified against the page"), turned into a step
|
|
49
|
+
* (`action-to-step.mapper.ts`), and broadcast as an outline card built by
|
|
50
|
+
* `scope-outline`'s own `recipeToOutline` — the same sentence/bracket logic
|
|
51
|
+
* every other phase's cards already go through, never a second card format.
|
|
52
|
+
* A secret field's value is replaced by its `{{env.NAME}}` placeholder
|
|
53
|
+
* before it reaches a step, a card, or this function's return value: the
|
|
54
|
+
* real value is discarded the instant `secret-field.policy.ts` flags the
|
|
55
|
+
* field, never logged, never kept.
|
|
56
|
+
*
|
|
57
|
+
* Recording inside an iframe or shadow DOM is out of this phase's scope
|
|
58
|
+
* (issue #95): `recorder-script.client.ts` detects both and reports them as
|
|
59
|
+
* `unsupported` notes instead of guessing at a selector that would not
|
|
60
|
+
* verify.
|
|
61
|
+
*
|
|
62
|
+
* @param options - The start URL, the profile directory, and browser launch settings.
|
|
63
|
+
* @param callbacks - Where cards and notices go as they happen.
|
|
64
|
+
* @returns A handle: `stop` closes the window and returns every step recorded.
|
|
65
|
+
*/
|
|
66
|
+
export declare function openRecorderSession(options: RecorderSessionOptions, callbacks: RecorderCallbacks): Promise<RecorderSessionHandle>;
|
|
67
|
+
//# sourceMappingURL=recorder-session.use-case.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { RecordedField } from './recorded-action.contract';
|
|
2
|
+
/**
|
|
3
|
+
* Whether a recorded `fill`/`select` field's typed value is a secret: a
|
|
4
|
+
* `type="password"` input, or a field the person explicitly marked (`marked`,
|
|
5
|
+
* a future "mark as secret" UI action — not built by this phase, but the
|
|
6
|
+
* flag is honoured wherever it comes from), or a name/id matching `token`,
|
|
7
|
+
* `secret` or `api[-_]?key` (issue #95's exact wording).
|
|
8
|
+
*
|
|
9
|
+
* @param field - The field's type/name/id, as reported by `recorder-script.client.ts`.
|
|
10
|
+
* @param marked - The person explicitly marked this field as secret; default `false`.
|
|
11
|
+
* @returns Whether the field's value must become `{{env.NAME}}` instead of the real text.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isSecretField(field: RecordedField, marked?: boolean): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The `{{env.NAME}}` variable name a secret field suggests, from its own
|
|
16
|
+
* name/id (falling back to `PASSWORD` for a bare `type="password"` field
|
|
17
|
+
* with neither): `camelCase`/`kebab-case`/`snake_case` all become
|
|
18
|
+
* `SCREAMING_SNAKE_CASE`, punctuation dropped, so `user-pass`, `userPass`
|
|
19
|
+
* and `user_pass` all suggest `USER_PASS`.
|
|
20
|
+
*
|
|
21
|
+
* @param field - The field's type/name/id.
|
|
22
|
+
* @returns A valid env-var-shaped name (letters, digits, underscores, not starting with a digit).
|
|
23
|
+
*/
|
|
24
|
+
export declare function secretEnvName(field: RecordedField): string;
|
|
25
|
+
/**
|
|
26
|
+
* The placeholder a secret field's value becomes in the recorded recipe:
|
|
27
|
+
* never the real text, in the recipe JSON or anywhere the studio logs.
|
|
28
|
+
*
|
|
29
|
+
* @param field - The field's type/name/id.
|
|
30
|
+
* @returns `{{env.NAME}}`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function secretPlaceholder(field: RecordedField): string;
|
|
33
|
+
//# sourceMappingURL=secret-field.policy.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Step } from '@opencraw/core';
|
|
2
|
+
export type WaitStep = Extract<Step, {
|
|
3
|
+
type: 'wait';
|
|
4
|
+
}>;
|
|
5
|
+
/** What happened right after the previous recorded action, before this one. */
|
|
6
|
+
export interface WaitContext {
|
|
7
|
+
/** The previous action's click/key press changed the page. */
|
|
8
|
+
navigated: boolean;
|
|
9
|
+
/** The page fetched something (XHR/`fetch`) since the previous action, without necessarily navigating. */
|
|
10
|
+
xhr: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Whether a `Wait for <selector>` step belongs between the action that just
|
|
14
|
+
* happened and the next one (issue #95): after a navigation or an XHR, the
|
|
15
|
+
* recorder inserts a wait for the element the person interacts with next, so
|
|
16
|
+
* a replayed recipe does not race the page's own load. Nothing to wait for
|
|
17
|
+
* without a next selector (a page-level key press, a scroll) — and no
|
|
18
|
+
* navigation or fetch either: a recording of a page that never moves should
|
|
19
|
+
* not fill up with waits nobody asked for.
|
|
20
|
+
*
|
|
21
|
+
* @param context - What happened since the previous action.
|
|
22
|
+
* @param nextSelector - The next action's own resolved selector, when it has one.
|
|
23
|
+
* @returns The wait step to insert before the next action's own step, or `undefined`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function insertWaitStep(context: WaitContext, nextSelector: string | undefined): WaitStep | undefined;
|
|
26
|
+
//# sourceMappingURL=wait-insertion.policy.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,14 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { main } from './main';
|
|
2
|
+
export type { StudioMainOptions } from './main';
|
|
3
|
+
export type { TrustedPlugins } from './trusted-plugins';
|
|
4
|
+
export { startStudioServer } from './studio-server';
|
|
5
|
+
export type { StudioServer, StudioServerOptions } from './studio-server';
|
|
6
|
+
export { openWorkspace, saveRecipe, importDocument } from './recipe-workspace';
|
|
7
|
+
export type { ImportedDocument } from './recipe-workspace';
|
|
8
|
+
export { runSample, loadRecipePair } from './sample-run';
|
|
9
|
+
export type { RecipePair, SampleRunCallbacks, SampleRunHandle, SampleRunRecord, SampleRunRejected, SampleRunResult, SampleStepSummary, SampleStoppedBy } from './sample-run';
|
|
10
|
+
export { fetchStartPage } from './page-snapshot';
|
|
11
|
+
export type { WhyFacts, WhyStepFact } from './explain-why';
|
|
12
|
+
export { sampleBudgetSchema, openWorkspaceCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, missingWhyTargetSchema, rejectedWhyTargetSchema, whyTargetSchema, explainWhyCommandSchema, studioCommandSchema, importDocumentViewSchema, stoppedBySchema, fieldTraceSchema, traceLineEventSchema, recordEventSchema, recordRejectedEventSchema, runFinishedEventSchema, workspaceChangedEventSchema, studioEventSchema, loadedHooksSchema, recipeIssueSchema, recipeListingSchema, workspaceViewSchema, sampleRunRecordSchema, sampleRunViewSchema, startPageViewSchema, snapshotViewSchema, verifySelectorViewSchema, fieldPickSchema, inferSelectorViewSchema, sentencePartSchema, outlineCardSchema, outlineBracketSchema, outlineNodeSchema, outlineViewSchema, whyViewSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewOptionsSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, regionPreviewMatchSchema, regionPreviewViewSchema, gridViewCommandSchema, gridPreviewOptionsSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewOptionsSchema, deckPreviewCommandSchema, domTreeNodeViewSchema, pageDataFindingSchema, inspectViewSchema, observedResponseSchema, responsesSeenViewSchema, documentTreeNodeViewSchema, documentTreeViewSchema, pdfCellViewSchema, pdfRowViewSchema, pdfPageViewSchema, pdfDocumentViewSchema, tablePreviewTableSchema, tablePreviewBandSchema, tablePreviewMatchSchema, tablePreviewViewSchema, gridCellViewSchema, gridMergeViewSchema, gridSheetViewSchema, workbookDocumentViewSchema, gridTablePreviewMatchSchema, gridTablePreviewViewSchema, deckShapeViewSchema, deckChartSeriesViewSchema, deckChartViewSchema, deckSlideViewSchema, deckDocumentViewSchema, deckTablePreviewMatchSchema, deckTablePreviewViewSchema, startRecordingCommandSchema, stopRecordingCommandSchema, recordingCardEventSchema, recordingNoteEventSchema, recordingStoppedEventSchema, } from './studio-api';
|
|
13
|
+
export type { SampleBudget, OpenWorkspaceCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StudioCommand, ImportDocumentView, RegionPreviewMatchView, RegionPreviewView, StoppedBy, FieldTraceView, TraceLineEvent, RecordEvent, RecordRejectedEvent, RunFinishedEvent, WorkspaceChangedEvent, StudioEvent, LoadedHooks, RecipeIssue, RecipeListing, WorkspaceView, SampleRunView, StartPageView, SnapshotView, VerifySelectorView, FieldPick, InferSelectorView, SentencePart, OutlineCard, OutlineBracket, OutlineNode, OutlineView, WhyView, DomTreeNodeView, PageDataKind, PageDataFindingView, InspectView, ObservedResponseView, ResponsesSeenView, DocumentTreeNodeView, DocumentTreeView, PdfCellView, PdfRowView, PdfPageView, PdfDocumentView, TablePreviewTableView, TablePreviewBandView, TablePreviewMatchView, TablePreviewView, GridCellView, GridMergeView, GridSheetView, WorkbookDocumentView, GridTablePreviewMatchView, GridTablePreviewView, DeckShapeView, DeckChartSeriesView, DeckChartView, DeckSlideView, DeckDocumentView, DeckTablePreviewMatchView, DeckTablePreviewView, StartRecordingCommand, StopRecordingCommand, RecordingCardEvent, RecordingNoteEvent, RecordingStoppedEvent, } from './studio-api';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TrustedPlugins } from './trusted-plugins';
|
|
2
|
+
/** What the caller of `main` decided beyond the command-line arguments. */
|
|
3
|
+
export interface StudioMainOptions {
|
|
4
|
+
/** Hooks and plugins loaded from a file the person named at launch (`opencraw studio --hooks <file>`, issue #150). `main` never loads code itself. */
|
|
5
|
+
plugins?: TrustedPlugins;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Runs `opencraw-studio`: starts the server, opens `folder` (if given) as
|
|
9
|
+
* the workspace right away, and prints the URL with the token, the way
|
|
10
|
+
* `docs/research/recipe-studio.md` §2 shows it: `http://127.0.0.1:<port>/?token=…`.
|
|
11
|
+
* The process stays up (the server keeps the event loop alive) until it is
|
|
12
|
+
* interrupted (Ctrl+C).
|
|
13
|
+
*
|
|
14
|
+
* @param argv - Arguments after the program name: an optional recipe folder, `.` when omitted.
|
|
15
|
+
* @param options - What the caller loaded beforehand: the trusted plugins, if any.
|
|
16
|
+
*/
|
|
17
|
+
export declare function main(argv: readonly string[], options?: StudioMainOptions): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** One row of the Inspect panel's DOM tree (studio plan §3.3, issue #93): a snapshot element, or a collapsed run of identical siblings. */
|
|
2
|
+
export interface DomTreeNode {
|
|
3
|
+
/** The snapshot's own `data-oc-node` id — what a pick addresses. Present on every real element; absent only on the synthetic wrapper a collapsed run never needs (a run always keeps its first member's id here). */
|
|
4
|
+
nodeId: string;
|
|
5
|
+
tag: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
classes?: string[];
|
|
8
|
+
/** Every other attribute (the internal `data-oc-node`/`data-oc-hidden` marks stripped). */
|
|
9
|
+
attributes: Record<string, string>;
|
|
10
|
+
/** This element's own text, trimmed and cut to `TEXT_LIMIT`, when it has no element children (mixed element+text content shows only the element children — see this file's `buildNode`). */
|
|
11
|
+
text?: string;
|
|
12
|
+
/** From the snapshot's `data-oc-hidden` mark (`hidden-marks.algorithm.ts`, phase 2). */
|
|
13
|
+
hidden: boolean;
|
|
14
|
+
children: DomTreeNode[];
|
|
15
|
+
/** Set when this row stands for a run of `repeatCount` structurally identical consecutive siblings (same tag, attributes and subtree — ids aside): the issue's `×20`. `repeatNodeIds` carries every collapsed sibling's own id, so a pick still knows every node the row represents. */
|
|
16
|
+
repeatCount?: number;
|
|
17
|
+
repeatNodeIds?: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds the Inspect panel's DOM tree from a captured snapshot (studio plan
|
|
21
|
+
* §3.3, issue #93): the same rewritten, marked-up document the content pane's
|
|
22
|
+
* iframe shows (`page-snapshot`'s `take-snapshot.use-case.ts`), so a tree
|
|
23
|
+
* row's `nodeId` addresses exactly the element the iframe would highlight —
|
|
24
|
+
* no separate capture, per issue #93's scope note to reuse phase 2's
|
|
25
|
+
* snapshot rather than recapture.
|
|
26
|
+
*
|
|
27
|
+
* @param snapshotHtml - The cached, rewritten snapshot (`SnapshotResult.html`).
|
|
28
|
+
* @returns The tree's root (the document's `<html>` element).
|
|
29
|
+
* @throws Error when the document has no `<html>` element (should not happen: `rewriteDocument` always produces one).
|
|
30
|
+
*/
|
|
31
|
+
export declare function domTree(snapshotHtml: string): DomTreeNode;
|
|
32
|
+
//# sourceMappingURL=dom-tree.mapper.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { domTree } from './dom-tree.mapper';
|
|
2
|
+
export type { DomTreeNode } from './dom-tree.mapper';
|
|
3
|
+
export { pageData } from './page-data.algorithm';
|
|
4
|
+
export type { PageDataFinding, PageDataKind } from './page-data.algorithm';
|
|
5
|
+
export { responsesSeen } from './responses-seen.use-case';
|
|
6
|
+
export type { ObservedResponse } from './responses-seen.use-case';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type PageDataKind = 'ld-json' | 'json-script' | 'inline-state' | 'meta' | 'link';
|
|
2
|
+
/** One pickable value in "data in the page" (studio plan §3.3, issue #93): a `<script type="application/ld+json">`/`"application/json">` block, an inline state assignment, a `<meta>`, or a `<link rel>`. */
|
|
3
|
+
export interface PageDataFinding {
|
|
4
|
+
kind: PageDataKind;
|
|
5
|
+
/** What the UI shows for this row: the JSON-LD `@type`, the global name assigned (`__NEXT_DATA__`), or `meta:`/`link:` and its name/rel. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** A selector verified against the real page (never the sanitised snapshot: `ld-json`/`json-script`/`inline-state` live inside a `<script>`, which the snapshot's `rewriteDocument` strips for the sandboxed iframe — see this file's own doc comment). */
|
|
8
|
+
selector: string;
|
|
9
|
+
selectorKind: 'css';
|
|
10
|
+
/** How many elements this selector reaches on the real page — always 1 by construction (`structuralSelector` is a full ancestor path), kept as a field so the UI's "N matches" confidence reads the same as a tree pick's. */
|
|
11
|
+
matches: number;
|
|
12
|
+
/** The parsed value's top-level keys, each pickable as its own `$.<key>` `jsonpath` card — absent when the value is not a JSON object (an array, a scalar, or text that did not parse). */
|
|
13
|
+
keys?: string[];
|
|
14
|
+
/** `meta`/`link` only: which attribute holds the pickable value (`content`/`href`). */
|
|
15
|
+
attribute?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Finds the data-in-the-page findings the Inspect panel lists apart from the
|
|
19
|
+
* DOM tree (studio plan §3.3, issue #93): JSON-LD and `application/json`
|
|
20
|
+
* script blocks, inline state assignments, `<meta>` name/property values and
|
|
21
|
+
* `<link rel>`s — reusing `@opencraw/probe`'s `describeJson` for a found
|
|
22
|
+
* value's shape (its own `find-data.algorithm.ts`/`html-findings.mapper.ts`
|
|
23
|
+
* scan a page's raw text for *reporting*, with no element to point a pick at;
|
|
24
|
+
* this function's own job — locating each finding's element so a pick can
|
|
25
|
+
* reach it — is new).
|
|
26
|
+
*
|
|
27
|
+
* Takes the **raw** captured document, not the display snapshot
|
|
28
|
+
* (`page-snapshot`'s `SnapshotResult.html`): `rewriteDocument` strips every
|
|
29
|
+
* `<script>` for the sandboxed iframe, which would make JSON-LD, inline
|
|
30
|
+
* state and other script-tag data invisible here. `<meta>`/`<link>` survive
|
|
31
|
+
* rewriting untouched, so using the raw document for every kind (rather than
|
|
32
|
+
* mixing two documents) keeps this function simple and its selectors
|
|
33
|
+
* verified against what the engine will actually crawl.
|
|
34
|
+
*
|
|
35
|
+
* @param rawHtml - The document as fetched/rendered, before `rewriteDocument` strips scripts.
|
|
36
|
+
* @returns The findings, in document order.
|
|
37
|
+
*/
|
|
38
|
+
export declare function pageData(rawHtml: string): PageDataFinding[];
|
|
39
|
+
//# sourceMappingURL=page-data.algorithm.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BrowserSessionConfig, InputRecipe } from '@opencraw/core';
|
|
2
|
+
/** One JSON response the page fetched while it rendered (studio plan §3.3, issue #93): what "responses seen" lists, and what picking one switches the recipe to api mode on. */
|
|
3
|
+
export interface ObservedResponse {
|
|
4
|
+
url: string;
|
|
5
|
+
status: number;
|
|
6
|
+
/** The response body's size in bytes (its UTF-8 text length). */
|
|
7
|
+
size: number;
|
|
8
|
+
/** The top-level shape (`describeJson`'s own `type`: `"object"`, `"array (12) of object"`…), or `"text"` when the body did not parse as JSON despite its content type. */
|
|
9
|
+
shape: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Records the JSON responses seen while an input recipe's start page
|
|
13
|
+
* rendered (studio plan §3.3, issue #93): the same technique `packages/cli`'s
|
|
14
|
+
* `probe --browser` uses (`observeBrowserJson`) — render the page, listen for
|
|
15
|
+
* `response` events whose content type is JSON, give it a few seconds to
|
|
16
|
+
* settle. Kept as its own capture, independent of `page-snapshot`'s
|
|
17
|
+
* `take-snapshot.use-case.ts`: that capture reads `page.content()` right
|
|
18
|
+
* after `goto` resolves, with no observation window, and changing its shape
|
|
19
|
+
* to also collect responses was a larger, riskier change to already-shipped,
|
|
20
|
+
* tested code than this phase's budget allowed (see this phase's final
|
|
21
|
+
* report) — so this opens its own short-lived browser session instead of
|
|
22
|
+
* piggy-backing on the cached snapshot.
|
|
23
|
+
*
|
|
24
|
+
* Only `"start"` is supported, mirroring `take-snapshot.use-case.ts`'s own
|
|
25
|
+
* reach; api-mode recipes have no page load to observe, so they always
|
|
26
|
+
* answer with an empty list rather than an error (there is nothing wrong
|
|
27
|
+
* with asking, the answer is just "none").
|
|
28
|
+
*
|
|
29
|
+
* @param input - The input recipe; only `mode` and the first `start` point are used.
|
|
30
|
+
* @param stepPath - The step to observe after, e.g. `"start"`.
|
|
31
|
+
* @param browser - Browser launch settings, shared with `take-snapshot`/`verify-selector`/`run-sample`.
|
|
32
|
+
* @returns The distinct JSON responses observed, at most `RESPONSE_LIMIT`.
|
|
33
|
+
* @throws Error when the recipe has no start point, or `stepPath` is not `"start"`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function responsesSeen(input: InputRecipe, stepPath: string, browser?: BrowserSessionConfig): Promise<ObservedResponse[]>;
|
|
36
|
+
//# sourceMappingURL=responses-seen.use-case.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BrowserSessionConfig, InputRecipe } from '@opencraw/core';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches an input recipe's start page as the engine would see it: a fresh
|
|
4
|
+
* Playwright page in web mode, core's HTTP client in api mode. Returns plain
|
|
5
|
+
* text: the page's HTML, or a readable rendering of a non-HTML api response.
|
|
6
|
+
* No rewriting, no script stripping, no node ids yet: that is phase 2's
|
|
7
|
+
* `page-snapshot` proper (studio plan, #91). Provisional for phase 0 in two
|
|
8
|
+
* ways, both worth knowing before relying on it: it opens a bare page
|
|
9
|
+
* without running the recipe's own steps first, so a start point behind a
|
|
10
|
+
* `session.bootstrap` login shows what an anonymous visitor sees; and it
|
|
11
|
+
* launches a fresh browser or HTTP context per call, one page then closes
|
|
12
|
+
* it, rather than reusing whatever the last sample run had open.
|
|
13
|
+
*
|
|
14
|
+
* @param input - The input recipe; only `mode` and the first `start` point are used.
|
|
15
|
+
* @param browser - Browser launch settings for web mode (an executable path override, headless…).
|
|
16
|
+
* @returns The page's content as plain text.
|
|
17
|
+
* @throws Error when the recipe has no start point.
|
|
18
|
+
*/
|
|
19
|
+
export declare function fetchStartPage(input: InputRecipe, browser?: BrowserSessionConfig): Promise<string>;
|
|
20
|
+
//# sourceMappingURL=fetch-start-page.use-case.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** The attribute `hiddenMarksScript` stamps on an element hidden on the live page. */
|
|
2
|
+
export declare const HIDDEN_ATTRIBUTE = "data-oc-hidden";
|
|
3
|
+
/**
|
|
4
|
+
* The in-page script `take-snapshot.use-case.ts` runs with `page.evaluate`
|
|
5
|
+
* *before* `page.content()`, so a `display: none`/`visibility: hidden`/
|
|
6
|
+
* zero-size element carries `data-oc-hidden="1"` into the captured markup
|
|
7
|
+
* (studio plan §3.1, issue #91) — the only way to know an element was
|
|
8
|
+
* hidden on the live page, since a static parse of the HTML afterwards has
|
|
9
|
+
* no computed style to ask.
|
|
10
|
+
*
|
|
11
|
+
* Kept as a plain string, not a TypeScript function passed to
|
|
12
|
+
* `page.evaluate`, because it references `window`/`document` as globals: `AGENTS.md`'s
|
|
13
|
+
* "things that bit before" calls out that in-page functions must not do
|
|
14
|
+
* that (the repo's `isolated-functions` lint rule), and every existing
|
|
15
|
+
* `page.evaluate` call with real DOM logic in this codebase (see
|
|
16
|
+
* `packages/core/src/captcha/resolve-captcha.use-case.ts`) already uses
|
|
17
|
+
* this same string-template shape.
|
|
18
|
+
*
|
|
19
|
+
* @param attribute - The attribute to stamp; defaults to `HIDDEN_ATTRIBUTE` (parameterised for tests and for a future caller that wants a different name).
|
|
20
|
+
* @returns A self-invoking script, ready for `page.evaluate(hiddenMarksScript())`.
|
|
21
|
+
*/
|
|
22
|
+
export declare function hiddenMarksScript(attribute?: string): string;
|
|
23
|
+
//# sourceMappingURL=hidden-marks.algorithm.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { fetchStartPage } from './fetch-start-page.use-case';
|
|
2
|
+
export { takeSnapshot } from './take-snapshot.use-case';
|
|
3
|
+
export type { SnapshotResult } from './take-snapshot.use-case';
|
|
4
|
+
export { rewriteDocument } from './rewrite-document.mapper';
|
|
5
|
+
export type { RewrittenDocument } from './rewrite-document.mapper';
|
|
6
|
+
export { hiddenMarksScript, HIDDEN_ATTRIBUTE } from './hidden-marks.algorithm';
|
|
7
|
+
export { createSnapshotCache, cachedSnapshot, putSnapshot, invalidateRecipe } from './snapshot.store';
|
|
8
|
+
export type { SnapshotCache } from './snapshot.store';
|
|
9
|
+
export { pdfBytes } from './pdf-bytes.use-case';
|
|
10
|
+
export { rereadCsv } from './reread-csv.use-case';
|
|
11
|
+
export type { CsvOverride } from './reread-csv.use-case';
|
|
12
|
+
export { invalidateStaleSnapshot } from './invalidate-stale-snapshot.use-case';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SnapshotCache } from './snapshot.store';
|
|
2
|
+
/**
|
|
3
|
+
* Drops a recipe's cached snapshots when the edit about to be saved changes
|
|
4
|
+
* its start point (issue #159). Call it before the file is written: it reads
|
|
5
|
+
* the recipe as it is on disk now to compare.
|
|
6
|
+
*
|
|
7
|
+
* @param cache - The workspace's snapshot cache.
|
|
8
|
+
* @param file - The recipe file being saved.
|
|
9
|
+
* @param next - The recipe being saved.
|
|
10
|
+
*/
|
|
11
|
+
export declare function invalidateStaleSnapshot(cache: SnapshotCache, file: string, next: unknown): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=invalidate-stale-snapshot.use-case.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches a PDF's raw bytes for the PDF canvas's `pdf.js` to render in the
|
|
3
|
+
* browser (studio plan §3.4, issue #94's 5b: "the PDF bytes served by the
|
|
4
|
+
* studio"). `take-snapshot` already read this same document with
|
|
5
|
+
* `@opencraw/core`'s `readPdf` for the cells/rows `document-view` maps, but
|
|
6
|
+
* `HttpClient`/`readPdf` parse the bytes and keep only the result — pdf.js
|
|
7
|
+
* needs the file itself, so this re-fetches it from the same URL a cached
|
|
8
|
+
* snapshot's own `SnapshotResult.baseUrl` gives, the way `HttpClient`'s own
|
|
9
|
+
* `file:` branch (`readLocalFile`) and its HTTP fetch do.
|
|
10
|
+
*
|
|
11
|
+
* @param url - The document's URL — a `file:` URL or an `http(s):` URL.
|
|
12
|
+
* @returns The raw bytes.
|
|
13
|
+
* @throws Error when a `file:` URL cannot be read, or the fetch does not succeed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function pdfBytes(url: string): Promise<Uint8Array>;
|
|
16
|
+
//# sourceMappingURL=pdf-bytes.use-case.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { WorkbookDocument } from '@opencraw/core';
|
|
2
|
+
/** `delimiter`/`encoding` on a `grid-view` request overriding what was auto-detected (issue #94's 5c: "the detected delimiter and encoding shown and overridable"); either, both, or neither. */
|
|
3
|
+
export interface CsvOverride {
|
|
4
|
+
delimiter?: string;
|
|
5
|
+
encoding?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Re-reads a CSV document with an overridden delimiter and/or encoding
|
|
9
|
+
* (studio plan §3.4, issue #94's 5c). `take-snapshot` already read this same
|
|
10
|
+
* document once with auto-detection (`http.client.ts`'s own `csvWorkbook`
|
|
11
|
+
* call); it keeps only the parsed result, not the raw bytes, so re-reading
|
|
12
|
+
* the file/URL is the only way to apply a different choice — the same
|
|
13
|
+
* "the studio re-fetches, the reader keeps no bytes around" tradeoff
|
|
14
|
+
* `pdf-bytes.use-case.ts` documents for pdf.js.
|
|
15
|
+
*
|
|
16
|
+
* @param url - The document's URL — a `file:` URL or an `http(s):` URL (`page-snapshot`'s cached `SnapshotResult.baseUrl`).
|
|
17
|
+
* @param override - The delimiter and/or encoding to force; `HttpClient` still detects whichever one is left out.
|
|
18
|
+
* @returns The freshly read workbook.
|
|
19
|
+
* @throws Error when the URL cannot be read, or it no longer reads back as a workbook.
|
|
20
|
+
*/
|
|
21
|
+
export declare function rereadCsv(url: string, override: CsvOverride): Promise<WorkbookDocument>;
|
|
22
|
+
//# sourceMappingURL=reread-csv.use-case.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface RewrittenDocument {
|
|
2
|
+
/** The document, ready for the sandboxed iframe: absolute URLs, a `<base>`, no `<script>`, forms disabled, `<meta http-equiv="refresh">` stripped, every element carrying a `data-oc-node` id. */
|
|
3
|
+
html: string;
|
|
4
|
+
/** How many elements were stamped with a node id — the same count `page-inspector` (phase 4) and the picker's match counts can be checked against. */
|
|
5
|
+
nodeCount: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Rewrites captured HTML into what the content pane's sandboxed iframe shows
|
|
9
|
+
* (studio plan §3.1, issue #91): every URL made absolute against `baseUrl`,
|
|
10
|
+
* a `<base>` injected, every `<script>` removed, forms disabled (`onsubmit`
|
|
11
|
+
* stripped, fields made read-only), `<meta http-equiv="refresh">` stripped
|
|
12
|
+
* (it would otherwise navigate the sandboxed frame on its own), and every
|
|
13
|
+
* element given a stable `data-oc-node` id, in document order, for the
|
|
14
|
+
* picker overlay and `selector-inference` to address specific nodes by.
|
|
15
|
+
*
|
|
16
|
+
* Purely a markup transform: it does not know whether an element is hidden
|
|
17
|
+
* on the live page (`display: none`, `visibility: hidden`, zero size) — in
|
|
18
|
+
* web mode that is `hidden-marks.algorithm.ts`'s job, run against the live
|
|
19
|
+
* page *before* this function ever sees the markup, so a `data-oc-hidden`
|
|
20
|
+
* attribute it wrote just survives serialisation untouched here.
|
|
21
|
+
*
|
|
22
|
+
* @param html - The captured document (`page.content()` in web mode, the fetched body in api mode).
|
|
23
|
+
* @param baseUrl - The page's own URL, for resolving relative links and as the `<base>`.
|
|
24
|
+
* @returns The rewritten document and how many elements it stamped.
|
|
25
|
+
*/
|
|
26
|
+
export declare function rewriteDocument(html: string, baseUrl: string): RewrittenDocument;
|
|
27
|
+
//# sourceMappingURL=rewrite-document.mapper.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SnapshotResult } from './take-snapshot.use-case';
|
|
2
|
+
/** A cache of the last snapshot taken per step path, so switching the selected step in the Steps outline does not always re-run the recipe (studio plan §3.1, issue #91). One per open recipe: key by `${recipeId}:${path}`. */
|
|
3
|
+
export interface SnapshotCache {
|
|
4
|
+
entries: Map<string, SnapshotResult>;
|
|
5
|
+
}
|
|
6
|
+
/** @returns An empty cache, for a freshly opened workspace. */
|
|
7
|
+
export declare function createSnapshotCache(): SnapshotCache;
|
|
8
|
+
/** @returns The cached snapshot for `recipeId`/`path`, or `undefined` when none was taken yet. */
|
|
9
|
+
export declare function cachedSnapshot(cache: SnapshotCache, recipeId: string, path: string): SnapshotResult | undefined;
|
|
10
|
+
/** Records a freshly taken snapshot, replacing whatever was cached for the same recipe and step path. */
|
|
11
|
+
export declare function putSnapshot(cache: SnapshotCache, recipeId: string, path: string, snapshot: SnapshotResult): void;
|
|
12
|
+
/** Drops every cached snapshot of one recipe — called after a save, since the steps up to any path may now capture something different. */
|
|
13
|
+
export declare function invalidateRecipe(cache: SnapshotCache, recipeId: string): void;
|
|
14
|
+
//# sourceMappingURL=snapshot.store.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether an edit changes the page a recipe's start snapshot shows (issue
|
|
3
|
+
* #159): its start URLs, mode, session, vars, headers… anything but the steps
|
|
4
|
+
* and mapping that run after it. A pick only adds steps, so it keeps the
|
|
5
|
+
* snapshot already taken instead of fetching the page again.
|
|
6
|
+
*
|
|
7
|
+
* @param before - The recipe as last saved (`undefined` when there was none).
|
|
8
|
+
* @param after - The recipe being saved.
|
|
9
|
+
* @returns `true` when the cached start snapshot may now be out of date.
|
|
10
|
+
*/
|
|
11
|
+
export declare function startPointChanged(before: unknown, after: unknown): boolean;
|
|
12
|
+
//# sourceMappingURL=start-point.policy.d.ts.map
|