@enricai/barnacle 1.6.1 → 1.6.3
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/README.md +36 -29
- package/dist/api/errors.d.ts +3 -3
- package/dist/api/errors.d.ts.map +1 -1
- package/dist/api/errors.js +4 -4
- package/dist/api/errors.js.map +1 -1
- package/dist/api/helpers/reply.d.ts +1 -1
- package/dist/api/helpers/reply.js +1 -1
- package/dist/cache/keyed-ttl-cache.d.ts +4 -4
- package/dist/cache/keyed-ttl-cache.js +2 -2
- package/dist/lib/applicant-payload.d.ts +4 -4
- package/dist/lib/applicant-payload.js +4 -4
- package/dist/lib/application-address.d.ts +3 -3
- package/dist/lib/application-address.js +5 -5
- package/dist/lib/application-address.js.map +1 -1
- package/dist/lib/application-resume.d.ts +4 -4
- package/dist/lib/application-resume.js +4 -4
- package/dist/lib/dispatch-metrics.js +1 -1
- package/dist/lib/llm/judges/verify-submit.d.ts +1 -1
- package/dist/lib/llm/judges/verify-submit.js +1 -1
- package/dist/lib/llm/schemas.js +3 -3
- package/dist/lib/phone.d.ts +1 -1
- package/dist/lib/phone.js +1 -1
- package/dist/lib/telemetry/call-types.d.ts +1 -1
- package/dist/lib/telemetry/call-types.js +1 -1
- package/dist/lib/tracking-click.d.ts +5 -3
- package/dist/lib/tracking-click.d.ts.map +1 -1
- package/dist/lib/tracking-click.js +5 -3
- package/dist/lib/tracking-click.js.map +1 -1
- package/dist/lib/us-states.d.ts +1 -1
- package/dist/lib/us-states.js +1 -1
- package/dist/plugins/loader.js +2 -2
- package/dist/scraper/cookie-jar.d.ts +2 -2
- package/dist/scraper/cookie-jar.js +2 -2
- package/dist/scraper/deep-query.d.ts +36 -0
- package/dist/scraper/deep-query.d.ts.map +1 -0
- package/dist/scraper/deep-query.js +87 -0
- package/dist/scraper/deep-query.js.map +1 -0
- package/dist/scraper/errors.d.ts +12 -14
- package/dist/scraper/errors.d.ts.map +1 -1
- package/dist/scraper/errors.js +12 -17
- package/dist/scraper/errors.js.map +1 -1
- package/dist/scraper/flow-runner.d.ts +97 -30
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +304 -104
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/http-client.d.ts +11 -1
- package/dist/scraper/http-client.d.ts.map +1 -1
- package/dist/scraper/http-client.js +90 -3
- package/dist/scraper/http-client.js.map +1 -1
- package/dist/scraper/phantom-click.d.ts +45 -0
- package/dist/scraper/phantom-click.d.ts.map +1 -0
- package/dist/scraper/phantom-click.js +37 -0
- package/dist/scraper/phantom-click.js.map +1 -0
- package/dist/scraper/raw-fetch.d.ts +2 -2
- package/dist/scraper/raw-fetch.js +1 -1
- package/dist/scraper/require-response-field.d.ts +1 -1
- package/dist/scraper/require-response-field.js +1 -1
- package/dist/scraper/session-browserbase.d.ts +48 -0
- package/dist/scraper/session-browserbase.d.ts.map +1 -1
- package/dist/scraper/session-browserbase.js +10 -5
- package/dist/scraper/session-browserbase.js.map +1 -1
- package/dist/scraper/session-shared.d.ts +6 -0
- package/dist/scraper/session-shared.d.ts.map +1 -1
- package/dist/scraper/session-shared.js.map +1 -1
- package/dist/scraper/session-warmup.d.ts +1 -1
- package/dist/scraper/session-warmup.js +1 -1
- package/dist/scraper/submit-control.d.ts +51 -0
- package/dist/scraper/submit-control.d.ts.map +1 -0
- package/dist/scraper/submit-control.js +142 -0
- package/dist/scraper/submit-control.js.map +1 -0
- package/dist/scripts/migrate-telemetry-dir-names.d.ts +2 -2
- package/dist/scripts/migrate-telemetry-dir-names.d.ts.map +1 -1
- package/dist/scripts/migrate-telemetry-dir-names.js +1 -1
- package/dist/scripts/recon-browser.d.ts +25 -20
- package/dist/scripts/recon-browser.d.ts.map +1 -1
- package/dist/scripts/recon-browser.js +65 -56
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate.d.ts +52 -7
- package/dist/scripts/recon-generate.d.ts.map +1 -1
- package/dist/scripts/recon-generate.js +73 -31
- package/dist/scripts/recon-generate.js.map +1 -1
- package/dist/scripts/recon-http.d.ts +36 -5
- package/dist/scripts/recon-http.d.ts.map +1 -1
- package/dist/scripts/recon-http.js +77 -47
- package/dist/scripts/recon-http.js.map +1 -1
- package/dist/scripts/recon-replay-jobs.d.ts +32 -3
- package/dist/scripts/recon-replay-jobs.d.ts.map +1 -1
- package/dist/scripts/recon-replay-jobs.js +46 -29
- package/dist/scripts/recon-replay-jobs.js.map +1 -1
- package/dist/scripts/recon-shared.d.ts +45 -0
- package/dist/scripts/recon-shared.d.ts.map +1 -1
- package/dist/scripts/recon-shared.js +117 -0
- package/dist/scripts/recon-shared.js.map +1 -1
- package/dist/scripts/recon-summarize.d.ts +5 -1
- package/dist/scripts/recon-summarize.d.ts.map +1 -1
- package/dist/scripts/recon-summarize.js +19 -7
- package/dist/scripts/recon-summarize.js.map +1 -1
- package/dist/site-plugin.d.ts +4 -4
- package/dist/testing/persona-fixture.d.ts +4 -4
- package/dist/testing/persona-fixture.d.ts.map +1 -1
- package/dist/testing/persona-fixture.js +4 -4
- package/dist/testing/persona-fixture.js.map +1 -1
- package/dist/types/dispatch-metrics.d.ts +1 -1
- package/dist/types/dispatch-metrics.js +1 -1
- package/package.json +1 -1
|
@@ -4,15 +4,19 @@
|
|
|
4
4
|
* coding is required between running recon and registering the plugin.
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* pnpm run recon:generate -- --site-id my-site [--force]
|
|
7
|
+
* pnpm run recon:generate -- --site-id my-site [--run-dir <path>] [--force]
|
|
8
8
|
*
|
|
9
9
|
* --force overwrites an existing src/sites/<siteId>/ directory.
|
|
10
|
+
* --run-dir selects which run root to read; defaults to the most recently
|
|
11
|
+
* modified run root under the recon output base dir (see
|
|
12
|
+
* {@link resolveLatestReconRunRoot}), so the existing two-command
|
|
13
|
+
* "recon, then generate" workflow keeps working unchanged.
|
|
10
14
|
*
|
|
11
|
-
* Reads from:
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* Reads from (under the resolved run root):
|
|
16
|
+
* graphql/*.json — Capture[] from recon-browser.ts
|
|
17
|
+
* replays/*.json — ReplayResult[] from recon-http.ts
|
|
18
|
+
* replays/rate-limit.json
|
|
19
|
+
* aux/*.json — static fixture files
|
|
16
20
|
* src/sites/<siteId>/recon-flow.json — plain-English flow steps
|
|
17
21
|
*/
|
|
18
22
|
import type { ReconFormSchema } from "../recon/form-schema";
|
|
@@ -158,6 +162,21 @@ export declare function detectFormSchemaFieldNames(captures: Capture[], formSche
|
|
|
158
162
|
fieldOptionsMap: FieldOptionsMap;
|
|
159
163
|
allSchemaUuids: Set<string>;
|
|
160
164
|
};
|
|
165
|
+
/**
|
|
166
|
+
* Splits a raw `Set-Cookie` response-header string into `name`/`value` pairs.
|
|
167
|
+
* Captures store `responseHeaders` as a flat `Record<string, string>`
|
|
168
|
+
* (see recon-shared.ts's `Capture`), so multiple `Set-Cookie` headers from the
|
|
169
|
+
* same response are folded by the recon browser's CDP session into one
|
|
170
|
+
* newline-delimited string — each line is one cookie's `name=value; attrs...`.
|
|
171
|
+
* This walks every newline-delimited line and recovers the name/value pair
|
|
172
|
+
* from before that line's first `;`, skipping any line with no `=`.
|
|
173
|
+
*/
|
|
174
|
+
/** Exported for unit testing — lets tests exercise the newline-fold parsing
|
|
175
|
+
* directly against synthetic multi-cookie strings. */
|
|
176
|
+
export declare function walkSetCookiePairs(rawSetCookie: string): Generator<{
|
|
177
|
+
name: string;
|
|
178
|
+
value: string;
|
|
179
|
+
}>;
|
|
161
180
|
/**
|
|
162
181
|
* Walks every capture's response (including GETs — formHistoryId-style values
|
|
163
182
|
* may originate in a state-load GET, not a POST). Indexes every string leaf
|
|
@@ -167,7 +186,9 @@ export declare function detectFormSchemaFieldNames(captures: Capture[], formSche
|
|
|
167
186
|
* Also indexes response-header/cookie-origin values (e.g. a `Set-Cookie`
|
|
168
187
|
* auth token) the same way, tagged with `headerOrigin` instead of a body
|
|
169
188
|
* `path` — this is what lets a stateful API's token-mint response feed a
|
|
170
|
-
* later call's `Cookie` header via `compileActionSteps`.
|
|
189
|
+
* later call's `Cookie` header via `compileActionSteps`. Cookie-origin values
|
|
190
|
+
* are capped by `MAX_COOKIE_STATE_VALUE_LENGTH`, not `MAX_STATE_VALUE_LENGTH`
|
|
191
|
+
* — session JWTs routinely exceed the body-blob cap.
|
|
171
192
|
*
|
|
172
193
|
* The index is intentionally permissive — it doesn't try to shape-match
|
|
173
194
|
* "what looks like a token" because token shapes are an open set across the
|
|
@@ -226,6 +247,30 @@ interface ActionStep {
|
|
|
226
247
|
*/
|
|
227
248
|
/** Exported for unit testing — see `indexStateValues`. */
|
|
228
249
|
export declare function compileActionSteps(actions: ActionCapture[], stateIndex: Map<string, StateValue>): ActionStep[];
|
|
250
|
+
/**
|
|
251
|
+
* Collects every header/cookie-origin produce across an action sequence, in
|
|
252
|
+
* step order — this is what `emitContractTs` renders as `createHttpClient`'s
|
|
253
|
+
* `bind` option so the generated `executeHttp` actually forwards a value like
|
|
254
|
+
* disneycruise's `Set-Cookie: __pa=<jwt>` mint to the stateful call that 401s
|
|
255
|
+
* without it. Deduped by `targetHeader.toLowerCase()` + `cookieName` (HTTP
|
|
256
|
+
* header names are case-insensitive, and compileActionSteps derives
|
|
257
|
+
* `targetHeader` verbatim from observed request-header casing, so the same
|
|
258
|
+
* logical target can show up as e.g. `Cookie` on one step and `cookie` on
|
|
259
|
+
* another): the `Cookie` request header carries many cookies by design, so
|
|
260
|
+
* every distinct cookie-origin produce targeting it must survive (the
|
|
261
|
+
* runtime accumulates them into one `Cookie` header per binding — see
|
|
262
|
+
* http-client.ts); only a produce that re-mints the SAME cookie on a later
|
|
263
|
+
* step collapses to its earliest occurrence. Non-cookie targets (e.g.
|
|
264
|
+
* `X-Conversation-Id`) still keep first-wins, since `HttpResponseBinding` is
|
|
265
|
+
* one binding per target header there and two steps producing the same
|
|
266
|
+
* non-cookie target (even under differing casing) would otherwise race with
|
|
267
|
+
* no defined winner.
|
|
268
|
+
*
|
|
269
|
+
* Exported for unit testing (as `walkSetCookiePairs` is) — lets tests exercise
|
|
270
|
+
* the produce → bind collection step directly against synthetic ActionStep
|
|
271
|
+
* sequences.
|
|
272
|
+
*/
|
|
273
|
+
export declare function collectHeaderBindings(actionSteps: ActionStep[]): HeaderProduce[];
|
|
229
274
|
/**
|
|
230
275
|
* Maps a site's screening-question prompts to the payload field that answers
|
|
231
276
|
* them, as `{ payloadField: [keyword, …] }`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recon-generate.d.ts","sourceRoot":"","sources":["../../src/scripts/recon-generate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"recon-generate.d.ts","sourceRoot":"","sources":["../../src/scripts/recon-generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAiBH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,KAAK,OAAO,EAKb,MAAM,wBAAwB,CAAC;AA2EhC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,OAAO,EACnB,UAAU,GAAE,eAAmD,GAC9D,MAAM,GAAG,IAAI,CAoBf;AAUD,UAAU,SAAS;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,KAAK,SAAI,EACT,MAAM,SAAK,EACX,IAAI,GAAE,SAAc,GACnB,MAAM,CA+DR;AAoCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAqBjG;AA4HD,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAuB3F;AAyBD,UAAU,UAAU;IAClB,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC;IACpB;4DACwD;IACxD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;uEAEmE;IACnE,YAAY,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAmFD,UAAU,YAAY;IACpB;iFAC6E;IAC7E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;uDAEmD;IACnD,gBAAgB,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrE;AAiFD;;;;;GAKG;AACH,KAAK,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAExC;;;;;;;;GAQG;AACH,UAAU,mBAAmB;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AACD,KAAK,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAkDxD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,eAAe,GAAG,IAAI,GACjC;IACD,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC7B,CAYA;AAmbD;;;;;;;;GAQG;AACH;sDACsD;AACtD,wBAAiB,kBAAkB,CACjC,YAAY,EAAE,MAAM,GACnB,SAAS,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAS5C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;8EAC8E;AAC9E,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,aAAa,GAAE,GAAG,CAAC,MAAM,CAAa,EACtC,oBAAoB,GAAE,GAAG,CAAC,MAAM,CAAa,GAC5C,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CA4DzB;AAED;4EAC4E;AAC5E,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;;;;0BAM0B;AAC1B,UAAU,aAAa;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,KAAK,OAAO,GAAG,WAAW,GAAG,aAAa,CAAC;AAE3C,UAAU,UAAU;IAClB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB;;sFAEkF;IAClF,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,aAAa,EAAE,OAAO,CAAC;CACxB;AAmDD;;;;GAIG;AACH,0DAA0D;AAC1D,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,aAAa,EAAE,EACxB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAClC,UAAU,EAAE,CAoGd;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,aAAa,EAAE,CAUhF;AAoJD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CASrE;AAwQD;6DAC6D;AAC7D,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,UAAU,EAAE,EACrB,SAAS,EAAE,OAAO,EAClB,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,EAChC,eAAe,EAAE,eAAe,EAChC,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,EACtC,4BAA4B,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACjD,+BAA+B,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC,EAC7E,OAAO,EAAE,MAAM,EACf,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1C,sBAAsB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3C,mBAAmB,GAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAa,EACpD,UAAU,GAAE,eAAe,GAAG,IAAW,GACxC,MAAM,CA6TR;AAkCD;yEACyE;AACzE,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iGAAiG;IACjG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mGAAmG;IACnG,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;qDAEiD;IACjD,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC;;;oCAGgC;IAChC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;sEACkE;IAClE,sBAAsB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC;;;;sDAIkD;IAClD,yBAAyB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD;;4EAEwE;IACxE,4BAA4B,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC5E;;;+DAG2D;IAC3D,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;sEAGkE;IAClE,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC,GAAG,MAAM,CAmUT;AAED,qFAAqF;AACrF,KAAK,aAAa,GACd,MAAM,GACN;IACE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAyFN;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CA2ET;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,CAiInD;AAED;mEACmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgB5E"}
|
|
@@ -5,15 +5,19 @@
|
|
|
5
5
|
* coding is required between running recon and registering the plugin.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
|
-
* pnpm run recon:generate -- --site-id my-site [--force]
|
|
8
|
+
* pnpm run recon:generate -- --site-id my-site [--run-dir <path>] [--force]
|
|
9
9
|
*
|
|
10
10
|
* --force overwrites an existing src/sites/<siteId>/ directory.
|
|
11
|
+
* --run-dir selects which run root to read; defaults to the most recently
|
|
12
|
+
* modified run root under the recon output base dir (see
|
|
13
|
+
* {@link resolveLatestReconRunRoot}), so the existing two-command
|
|
14
|
+
* "recon, then generate" workflow keeps working unchanged.
|
|
11
15
|
*
|
|
12
|
-
* Reads from:
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* Reads from (under the resolved run root):
|
|
17
|
+
* graphql/*.json — Capture[] from recon-browser.ts
|
|
18
|
+
* replays/*.json — ReplayResult[] from recon-http.ts
|
|
19
|
+
* replays/rate-limit.json
|
|
20
|
+
* aux/*.json — static fixture files
|
|
17
21
|
* src/sites/<siteId>/recon-flow.json — plain-English flow steps
|
|
18
22
|
*/
|
|
19
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -22,8 +26,10 @@ exports.inferZodSchemaFromSamples = inferZodSchemaFromSamples;
|
|
|
22
26
|
exports.selectPayloadAction = selectPayloadAction;
|
|
23
27
|
exports.extractActionSequence = extractActionSequence;
|
|
24
28
|
exports.detectFormSchemaFieldNames = detectFormSchemaFieldNames;
|
|
29
|
+
exports.walkSetCookiePairs = walkSetCookiePairs;
|
|
25
30
|
exports.indexStateValues = indexStateValues;
|
|
26
31
|
exports.compileActionSteps = compileActionSteps;
|
|
32
|
+
exports.collectHeaderBindings = collectHeaderBindings;
|
|
27
33
|
exports.loadQuestionPromptKeywords = loadQuestionPromptKeywords;
|
|
28
34
|
exports.emitMultiStepExecuteHttp = emitMultiStepExecuteHttp;
|
|
29
35
|
exports.emitContractTs = emitContractTs;
|
|
@@ -1070,6 +1076,12 @@ function applyRawOptionIdPayloadSubstitutions(rawBody, fieldNameMap, fieldOption
|
|
|
1070
1076
|
/** Maximum length to guard against indexing massive blobs (HTML fragments,
|
|
1071
1077
|
* embedded base64 images, etc.) that aren't candidates for state threading. */
|
|
1072
1078
|
const MAX_STATE_VALUE_LENGTH = 256;
|
|
1079
|
+
/** Maximum length for `Set-Cookie`-origin values, distinct from
|
|
1080
|
+
* `MAX_STATE_VALUE_LENGTH`. Auth tokens (JWTs) legitimately exceed the
|
|
1081
|
+
* body-blob cap — a 272-char session cookie is normal, not a massive blob —
|
|
1082
|
+
* so cookie origins get their own, more permissive ceiling. Still bounded so
|
|
1083
|
+
* a pathological cookie can't blow up the index. */
|
|
1084
|
+
const MAX_COOKIE_STATE_VALUE_LENGTH = 4096;
|
|
1073
1085
|
/** Canonical "uninitialized" sentinel values that some REST APIs return as
|
|
1074
1086
|
* placeholders before a downstream call populates the real identifier. An ATS
|
|
1075
1087
|
* whose `/user/create` returns these for CandidateId/ApplicationId/
|
|
@@ -1084,19 +1096,24 @@ const PLACEHOLDER_STATE_VALUES = new Set(["00000000-0000-0000-0000-000000000000"
|
|
|
1084
1096
|
* Splits a raw `Set-Cookie` response-header string into `name`/`value` pairs.
|
|
1085
1097
|
* Captures store `responseHeaders` as a flat `Record<string, string>`
|
|
1086
1098
|
* (see recon-shared.ts's `Capture`), so multiple `Set-Cookie` headers from the
|
|
1087
|
-
* same response
|
|
1088
|
-
*
|
|
1089
|
-
*
|
|
1099
|
+
* same response are folded by the recon browser's CDP session into one
|
|
1100
|
+
* newline-delimited string — each line is one cookie's `name=value; attrs...`.
|
|
1101
|
+
* This walks every newline-delimited line and recovers the name/value pair
|
|
1102
|
+
* from before that line's first `;`, skipping any line with no `=`.
|
|
1090
1103
|
*/
|
|
1104
|
+
/** Exported for unit testing — lets tests exercise the newline-fold parsing
|
|
1105
|
+
* directly against synthetic multi-cookie strings. */
|
|
1091
1106
|
function* walkSetCookiePairs(rawSetCookie) {
|
|
1092
|
-
const
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1107
|
+
for (const line of rawSetCookie.split("\n")) {
|
|
1108
|
+
const pair = line.split(";", 1)[0] ?? "";
|
|
1109
|
+
const eq = pair.indexOf("=");
|
|
1110
|
+
if (eq === -1)
|
|
1111
|
+
continue;
|
|
1112
|
+
const name = pair.slice(0, eq).trim();
|
|
1113
|
+
const value = pair.slice(eq + 1).trim();
|
|
1114
|
+
if (name && value)
|
|
1115
|
+
yield { name, value };
|
|
1116
|
+
}
|
|
1100
1117
|
}
|
|
1101
1118
|
/**
|
|
1102
1119
|
* Walks every capture's response (including GETs — formHistoryId-style values
|
|
@@ -1107,7 +1124,9 @@ function* walkSetCookiePairs(rawSetCookie) {
|
|
|
1107
1124
|
* Also indexes response-header/cookie-origin values (e.g. a `Set-Cookie`
|
|
1108
1125
|
* auth token) the same way, tagged with `headerOrigin` instead of a body
|
|
1109
1126
|
* `path` — this is what lets a stateful API's token-mint response feed a
|
|
1110
|
-
* later call's `Cookie` header via `compileActionSteps`.
|
|
1127
|
+
* later call's `Cookie` header via `compileActionSteps`. Cookie-origin values
|
|
1128
|
+
* are capped by `MAX_COOKIE_STATE_VALUE_LENGTH`, not `MAX_STATE_VALUE_LENGTH`
|
|
1129
|
+
* — session JWTs routinely exceed the body-blob cap.
|
|
1111
1130
|
*
|
|
1112
1131
|
* The index is intentionally permissive — it doesn't try to shape-match
|
|
1113
1132
|
* "what looks like a token" because token shapes are an open set across the
|
|
@@ -1143,7 +1162,7 @@ function indexStateValues(captures, shieldedUuids = new Set(), actionCaptureIndi
|
|
|
1143
1162
|
for (const { name, value } of walkSetCookiePairs(rawSetCookie)) {
|
|
1144
1163
|
if (value.length < MIN_STATE_VALUE_LENGTH)
|
|
1145
1164
|
continue;
|
|
1146
|
-
if (value.length >
|
|
1165
|
+
if (value.length > MAX_COOKIE_STATE_VALUE_LENGTH)
|
|
1147
1166
|
continue;
|
|
1148
1167
|
if (PLACEHOLDER_STATE_VALUES.has(value))
|
|
1149
1168
|
continue;
|
|
@@ -1347,21 +1366,36 @@ function compileActionSteps(actions, stateIndex) {
|
|
|
1347
1366
|
* step order — this is what `emitContractTs` renders as `createHttpClient`'s
|
|
1348
1367
|
* `bind` option so the generated `executeHttp` actually forwards a value like
|
|
1349
1368
|
* disneycruise's `Set-Cookie: __pa=<jwt>` mint to the stateful call that 401s
|
|
1350
|
-
* without it. Deduped by `targetHeader
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1369
|
+
* without it. Deduped by `targetHeader.toLowerCase()` + `cookieName` (HTTP
|
|
1370
|
+
* header names are case-insensitive, and compileActionSteps derives
|
|
1371
|
+
* `targetHeader` verbatim from observed request-header casing, so the same
|
|
1372
|
+
* logical target can show up as e.g. `Cookie` on one step and `cookie` on
|
|
1373
|
+
* another): the `Cookie` request header carries many cookies by design, so
|
|
1374
|
+
* every distinct cookie-origin produce targeting it must survive (the
|
|
1375
|
+
* runtime accumulates them into one `Cookie` header per binding — see
|
|
1376
|
+
* http-client.ts); only a produce that re-mints the SAME cookie on a later
|
|
1377
|
+
* step collapses to its earliest occurrence. Non-cookie targets (e.g.
|
|
1378
|
+
* `X-Conversation-Id`) still keep first-wins, since `HttpResponseBinding` is
|
|
1379
|
+
* one binding per target header there and two steps producing the same
|
|
1380
|
+
* non-cookie target (even under differing casing) would otherwise race with
|
|
1381
|
+
* no defined winner.
|
|
1382
|
+
*
|
|
1383
|
+
* Exported for unit testing (as `walkSetCookiePairs` is) — lets tests exercise
|
|
1384
|
+
* the produce → bind collection step directly against synthetic ActionStep
|
|
1385
|
+
* sequences.
|
|
1353
1386
|
*/
|
|
1354
1387
|
function collectHeaderBindings(actionSteps) {
|
|
1355
|
-
const
|
|
1388
|
+
const byKey = new Map();
|
|
1356
1389
|
for (const step of actionSteps) {
|
|
1357
1390
|
for (const p of step.produces) {
|
|
1358
1391
|
if (p.kind !== "header")
|
|
1359
1392
|
continue;
|
|
1360
|
-
|
|
1361
|
-
|
|
1393
|
+
const key = `${p.targetHeader.toLowerCase()}\0${p.cookieName ?? ""}`;
|
|
1394
|
+
if (!byKey.has(key))
|
|
1395
|
+
byKey.set(key, p);
|
|
1362
1396
|
}
|
|
1363
1397
|
}
|
|
1364
|
-
return [...
|
|
1398
|
+
return [...byKey.values()];
|
|
1365
1399
|
}
|
|
1366
1400
|
/**
|
|
1367
1401
|
* Replaces occurrences of state values in `template` with `${varName}`
|
|
@@ -2655,6 +2689,7 @@ async function main() {
|
|
|
2655
2689
|
let emit = "ts";
|
|
2656
2690
|
let vocabularySpecifier = "";
|
|
2657
2691
|
let formSchemaSpecifier = "";
|
|
2692
|
+
let runDir;
|
|
2658
2693
|
for (let i = 0; i < args.length; i++) {
|
|
2659
2694
|
if (args[i] === "--site-id" && args[i + 1])
|
|
2660
2695
|
siteId = args[++i];
|
|
@@ -2662,6 +2697,8 @@ async function main() {
|
|
|
2662
2697
|
vocabularySpecifier = args[++i];
|
|
2663
2698
|
else if (args[i] === "--form-schema" && args[i + 1])
|
|
2664
2699
|
formSchemaSpecifier = args[++i];
|
|
2700
|
+
else if (args[i] === "--run-dir" && args[i + 1])
|
|
2701
|
+
runDir = args[++i];
|
|
2665
2702
|
else if (args[i] === "--force")
|
|
2666
2703
|
force = true;
|
|
2667
2704
|
else if (args[i] === "--emit" && args[i + 1]) {
|
|
@@ -2687,14 +2724,19 @@ async function main() {
|
|
|
2687
2724
|
logger.error(`${manifestPath} already exists — pass --force to overwrite`);
|
|
2688
2725
|
process.exit(1);
|
|
2689
2726
|
}
|
|
2690
|
-
const
|
|
2691
|
-
|
|
2727
|
+
const runRoot = (0, recon_shared_1.resolveLatestReconRunRoot)(runDir);
|
|
2728
|
+
logger.info(`reading recon artifacts from ${runRoot}`);
|
|
2729
|
+
const capturesDir = (0, node_path_1.join)(runRoot, "graphql");
|
|
2730
|
+
const replaysDir = (0, node_path_1.join)(runRoot, "replays");
|
|
2731
|
+
const auxDir = (0, node_path_1.join)(runRoot, "aux");
|
|
2732
|
+
const captures = (0, recon_shared_1.readJsonDir)(capturesDir);
|
|
2733
|
+
const replays = (0, recon_shared_1.readJsonDir)(replaysDir, [
|
|
2692
2734
|
"rate-limit.json",
|
|
2693
2735
|
"introspection-schema.json",
|
|
2694
2736
|
]);
|
|
2695
2737
|
const rateLimits = (() => {
|
|
2696
2738
|
try {
|
|
2697
|
-
return JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(
|
|
2739
|
+
return JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(replaysDir, "rate-limit.json"), "utf8"));
|
|
2698
2740
|
}
|
|
2699
2741
|
catch {
|
|
2700
2742
|
return [];
|
|
@@ -2702,7 +2744,7 @@ async function main() {
|
|
|
2702
2744
|
})();
|
|
2703
2745
|
const auxFiles = (() => {
|
|
2704
2746
|
try {
|
|
2705
|
-
return (0, node_fs_1.readdirSync)(
|
|
2747
|
+
return (0, node_fs_1.readdirSync)(auxDir)
|
|
2706
2748
|
.filter((f) => f.endsWith(".json"))
|
|
2707
2749
|
.sort();
|
|
2708
2750
|
}
|
|
@@ -3017,7 +3059,7 @@ async function main() {
|
|
|
3017
3059
|
if (auxFiles.length > 0) {
|
|
3018
3060
|
(0, node_fs_1.mkdirSync)(`${outDir}/fixtures`, { recursive: true });
|
|
3019
3061
|
for (const f of auxFiles) {
|
|
3020
|
-
(0, node_fs_1.copyFileSync)((0, node_path_1.join)(
|
|
3062
|
+
(0, node_fs_1.copyFileSync)((0, node_path_1.join)(auxDir, f), `${outDir}/fixtures/${f}`);
|
|
3021
3063
|
}
|
|
3022
3064
|
logger.info(`copied ${auxFiles.length} fixture(s) to ${outDir}/fixtures/`);
|
|
3023
3065
|
}
|