@enricai/barnacle 1.12.7 → 1.12.9
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/plugins/config-plugin.d.ts.map +1 -1
- package/dist/plugins/config-plugin.js +2 -1
- package/dist/plugins/config-plugin.js.map +1 -1
- package/dist/scraper/cdp-heartbeat.d.ts +34 -0
- package/dist/scraper/cdp-heartbeat.d.ts.map +1 -0
- package/dist/scraper/cdp-heartbeat.js +30 -0
- package/dist/scraper/cdp-heartbeat.js.map +1 -0
- package/dist/scraper/errors.d.ts +15 -1
- package/dist/scraper/errors.d.ts.map +1 -1
- package/dist/scraper/errors.js +24 -2
- package/dist/scraper/errors.js.map +1 -1
- package/dist/scraper/flow-runner.d.ts +10 -0
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +5 -1
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/session-browserbase.d.ts.map +1 -1
- package/dist/scraper/session-browserbase.js +27 -1
- package/dist/scraper/session-browserbase.js.map +1 -1
- package/dist/scraper/session-shared.d.ts +18 -0
- package/dist/scraper/session-shared.d.ts.map +1 -1
- package/dist/scraper/session-shared.js.map +1 -1
- package/dist/scraper/session-steel.d.ts +9 -0
- package/dist/scraper/session-steel.d.ts.map +1 -1
- package/dist/scraper/session-steel.js +53 -0
- package/dist/scraper/session-steel.js.map +1 -1
- package/dist/scraper/session-teardown.d.ts +22 -0
- package/dist/scraper/session-teardown.d.ts.map +1 -0
- package/dist/scraper/session-teardown.js +54 -0
- package/dist/scraper/session-teardown.js.map +1 -0
- package/dist/scripts/recon-browser.d.ts.map +1 -1
- package/dist/scripts/recon-browser.js +23 -1
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate-multicall-fixture.d.ts +26 -0
- package/dist/scripts/recon-generate-multicall-fixture.d.ts.map +1 -1
- package/dist/scripts/recon-generate-multicall-fixture.js +47 -0
- package/dist/scripts/recon-generate-multicall-fixture.js.map +1 -1
- package/dist/scripts/recon-generate-multiendpoint-fixture.d.ts +12 -0
- package/dist/scripts/recon-generate-multiendpoint-fixture.d.ts.map +1 -0
- package/dist/scripts/recon-generate-multiendpoint-fixture.js +108 -0
- package/dist/scripts/recon-generate-multiendpoint-fixture.js.map +1 -0
- package/dist/scripts/recon-generate-repeated-section-fixture.d.ts +14 -0
- package/dist/scripts/recon-generate-repeated-section-fixture.d.ts.map +1 -0
- package/dist/scripts/recon-generate-repeated-section-fixture.js +52 -0
- package/dist/scripts/recon-generate-repeated-section-fixture.js.map +1 -0
- package/dist/scripts/recon-generate.d.ts +19 -6
- package/dist/scripts/recon-generate.d.ts.map +1 -1
- package/dist/scripts/recon-generate.js +207 -115
- package/dist/scripts/recon-generate.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recon-generate-repeated-section-fixture.js","sourceRoot":"","sources":["../../src/scripts/recon-generate-repeated-section-fixture.ts"],"names":[],"mappings":";;;AAAA,iGAA0E;AAG1E,MAAM,IAAI,GAAG,yBAAyB,CAAC;AACvC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC;;;;;;;;;;GAUG;AACH;IACE,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,IAA6B,EAAW,EAAE,CACtF,IAAA,+CAAY,EAAC;QACX,GAAG,EAAE,GAAG,IAAI,iBAAiB,iBAAiB,IAAI,IAAI,EAAE;QACxD,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QACrC,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE;QAC9E,SAAS,EAAE,oBAAoB,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG;KACjE,CAAC,CAAC;IAEL,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,QAAgB,EAAW,EAAE,CAAC,CAAC;QAC9D,GAAG,IAAA,+CAAY,EAAC;YACd,GAAG,EAAE,GAAG,IAAI,iBAAiB,iBAAiB,WAAW;YACzD,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,QAAQ,EAAE,EAAE,CAAC;YAC1E,YAAY,EAAE,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE;YACrD,SAAS,EAAE,oBAAoB,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG;SACjE,CAAC;QACF,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;IAEH,OAAO;QACL,IAAA,+CAAY,EAAC;YACX,GAAG,EAAE,GAAG,IAAI,eAAe;YAC3B,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;YACzD,YAAY,EAAE,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE;YACnE,SAAS,EAAE,sBAAsB;SAClC,CAAC;QACF,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC7D,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QAC7C,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAClD,OAAO,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAC9C,OAAO,CAAC,aAAa,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;QACpD,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;QACd,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;QACd,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;QACd,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;KACf,CAAC;AACJ,CAAC"}
|
|
@@ -193,6 +193,7 @@ interface PrimaryGraphQLOperation {
|
|
|
193
193
|
* combined into one composite score.
|
|
194
194
|
*/
|
|
195
195
|
export declare function selectPrimaryGraphQLOperation(captures: Capture[], flowSteps: FlowStepInput[], vocabulary: ReconVocabulary): PrimaryGraphQLOperation | null;
|
|
196
|
+
export declare function firstEndpointPath(captures: Capture[]): string;
|
|
196
197
|
interface ActionCapture {
|
|
197
198
|
capture: Capture;
|
|
198
199
|
index: number;
|
|
@@ -224,19 +225,23 @@ export interface SubmitPatterns {
|
|
|
224
225
|
export declare function resolveManifestActionSequence(runRoot: string, captures: Capture[]): ActionCapture[] | null;
|
|
225
226
|
/**
|
|
226
227
|
* Extracts the ordered sequence of meaningful POSTs that represent the
|
|
227
|
-
* transactional flow:
|
|
228
|
-
* sinks. Assets need no filter of their own — they arrive as GETs.
|
|
228
|
+
* transactional flow: non-noise 2xx POSTs, minus telemetry and error-reporting
|
|
229
|
+
* sinks. Assets need no filter of their own — they arrive as GETs. Host is
|
|
230
|
+
* NOT a filter criterion — a multi-step submission routinely bounces to a
|
|
231
|
+
* different host mid-flow (an account-creation redirect, a tenant API
|
|
232
|
+
* subdomain distinct from the landing page's host), so `isNoiseUrl` alone
|
|
233
|
+
* decides what counts as site traffic vs. third-party noise.
|
|
229
234
|
*
|
|
230
235
|
* When the flow declares submit patterns, only POSTs matching them survive —
|
|
231
236
|
* this isolates the submission from same-origin page chrome (bootstrap, chatbot,
|
|
232
237
|
* JWT refresh, reference-lookup) that a browser fires incidentally. Absent
|
|
233
|
-
* patterns preserve the
|
|
238
|
+
* patterns preserve the noise heuristic exactly.
|
|
234
239
|
*
|
|
235
240
|
* Exported for tests: this predicate decides what a generated plugin will POST
|
|
236
241
|
* at a live site, and it is the only gate between a browser's incidental
|
|
237
242
|
* chatter and the emitted hot path.
|
|
238
243
|
*/
|
|
239
|
-
export declare function extractActionSequence(captures: Capture[],
|
|
244
|
+
export declare function extractActionSequence(captures: Capture[], submitPatterns?: SubmitPatterns | null): ActionCapture[];
|
|
240
245
|
/**
|
|
241
246
|
* GraphQL-aware analog of {@link extractActionSequence}: REST's URL/method
|
|
242
247
|
* shape doesn't apply when every operation POSTs to the same endpoint, so
|
|
@@ -245,12 +250,13 @@ export declare function extractActionSequence(captures: Capture[], baseUrl: stri
|
|
|
245
250
|
* make up a transactional flow (`UpsertSavedApplication`, `SubmitForm`, ...)
|
|
246
251
|
* — and drops `query` operations, which are read/bootstrap calls (e.g. a
|
|
247
252
|
* page-load `ListForms`) that carry no state-threading value and are exactly
|
|
248
|
-
* what let a chronologically-first fallback pick an unrelated query.
|
|
253
|
+
* what let a chronologically-first fallback pick an unrelated query. Host is
|
|
254
|
+
* NOT a filter criterion, matching {@link extractActionSequence}.
|
|
249
255
|
*
|
|
250
256
|
* Exported for tests: this predicate decides what a generated GraphQL plugin
|
|
251
257
|
* will send at a live site.
|
|
252
258
|
*/
|
|
253
|
-
export declare function extractGraphQLActionSequence(captures: Capture[],
|
|
259
|
+
export declare function extractGraphQLActionSequence(captures: Capture[], submitPatterns?: SubmitPatterns | null): ActionCapture[];
|
|
254
260
|
interface StateValue {
|
|
255
261
|
/** The raw string that appears in some response and is reused downstream. */
|
|
256
262
|
value: string;
|
|
@@ -590,6 +596,13 @@ export declare function emitContractTs(opts: {
|
|
|
590
596
|
auxFiles: string[];
|
|
591
597
|
/** Multi-step submission flow body — when set, replaces the default single-endpoint hot path. */
|
|
592
598
|
multiStepBody?: string;
|
|
599
|
+
/** Browser-flow-only fallback: a multi-action flow whose captured sequence
|
|
600
|
+
* couldn't be synthesized into a trustworthy `executeHttp` (a required
|
|
601
|
+
* value never resolved via state-threading, a payload field, or a
|
|
602
|
+
* generator). When true, `executeHttp` is omitted entirely — the plugin
|
|
603
|
+
* ships browser-only with the standard candidate payload schema — rather
|
|
604
|
+
* than emitting a fabricated single-call HTTP stub. */
|
|
605
|
+
omitExecuteHttp?: boolean;
|
|
593
606
|
/** First action capture's request body — used to infer the payload schema for submission flows. */
|
|
594
607
|
inputBody?: unknown;
|
|
595
608
|
/** Whether the flow has a multipart upload step — derived from actionSteps at the call site. */
|
|
@@ -1 +1 @@
|
|
|
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;AA2BhC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,OAAO,EACnB,UAAU,GAAE,eAAkC,GAC7C,MAAM,GAAG,IAAI,CAoBf;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,MAAM,GAAG,IAAI,CAsBf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,aAAa,EAAE,EAC1B,UAAU,EAAE,eAAe,EAC3B,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BrB;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;AA8DD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAMjG;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAMhG;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,EACxE,gBAAgB,EAAE,OAAO,EACzB,WAAW,EAAE,SAAS,CAAC,EAAE,EACzB,kBAAkB,EAAE,OAAO,GAC1B,OAAO,CAGT;AAcD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAe3E;
|
|
1
|
+
{"version":3,"file":"recon-generate.d.ts","sourceRoot":"","sources":["../../src/scripts/recon-generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,6 +31,7 @@ exports.selectReturnAction = selectReturnAction;
|
|
|
31
31
|
exports.selectEffectiveResponseBody = selectEffectiveResponseBody;
|
|
32
32
|
exports.extractEntryUrlParams = extractEntryUrlParams;
|
|
33
33
|
exports.selectPrimaryGraphQLOperation = selectPrimaryGraphQLOperation;
|
|
34
|
+
exports.firstEndpointPath = firstEndpointPath;
|
|
34
35
|
exports.resolveManifestActionSequence = resolveManifestActionSequence;
|
|
35
36
|
exports.extractActionSequence = extractActionSequence;
|
|
36
37
|
exports.extractGraphQLActionSequence = extractGraphQLActionSequence;
|
|
@@ -505,14 +506,14 @@ const IGNORE_REQUEST_HEADERS = new Set([
|
|
|
505
506
|
*/
|
|
506
507
|
function deriveRequestHeaders(captures, replays, baseUrl, submitPatterns = null) {
|
|
507
508
|
const successfulUrls = new Set(replays.filter((r) => r.success).map((r) => endpointKey(r.url)));
|
|
508
|
-
// Prefer ACTION captures (non-GET 2xx
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
//
|
|
512
|
-
//
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
const actionCaptures = extractActionSequence(captures,
|
|
509
|
+
// Prefer ACTION captures (non-GET 2xx, non-noise) as the authoritative
|
|
510
|
+
// header source. Replay-matched static-asset GETs lack the API-specific
|
|
511
|
+
// headers that REST endpoints require, so falling back to those produces
|
|
512
|
+
// a degenerate baseline-only header set. When action captures exist
|
|
513
|
+
// (multi-step submission flows), use them. For sites where the flow is a
|
|
514
|
+
// single REST call (no detectable action sequence), fall back to the
|
|
515
|
+
// replay-matched captures.
|
|
516
|
+
const actionCaptures = extractActionSequence(captures, submitPatterns).map((a) => a.capture);
|
|
516
517
|
const replayMatchedCaptures = captures.filter((c) => successfulUrls.has(endpointKey(c.url)));
|
|
517
518
|
const relevantCaptures = actionCaptures.length > 0 ? actionCaptures : replayMatchedCaptures;
|
|
518
519
|
const counts = new Map();
|
|
@@ -631,10 +632,18 @@ function selectPrimaryGraphQLOperation(captures, flowSteps, vocabulary) {
|
|
|
631
632
|
return { capture: winner.capture, endpointPath };
|
|
632
633
|
}
|
|
633
634
|
function firstEndpointPath(captures) {
|
|
635
|
+
const nonGetCaptures = captures.filter((c) => c.method !== "GET");
|
|
636
|
+
for (const c of nonGetCaptures) {
|
|
637
|
+
try {
|
|
638
|
+
return new URL(c.url).pathname;
|
|
639
|
+
}
|
|
640
|
+
catch {
|
|
641
|
+
// skip
|
|
642
|
+
}
|
|
643
|
+
}
|
|
634
644
|
for (const c of captures) {
|
|
635
645
|
try {
|
|
636
|
-
|
|
637
|
-
return u.pathname;
|
|
646
|
+
return new URL(c.url).pathname;
|
|
638
647
|
}
|
|
639
648
|
catch {
|
|
640
649
|
// skip
|
|
@@ -698,26 +707,23 @@ function resolveManifestActionSequence(runRoot, captures) {
|
|
|
698
707
|
}
|
|
699
708
|
/**
|
|
700
709
|
* Extracts the ordered sequence of meaningful POSTs that represent the
|
|
701
|
-
* transactional flow:
|
|
702
|
-
* sinks. Assets need no filter of their own — they arrive as GETs.
|
|
710
|
+
* transactional flow: non-noise 2xx POSTs, minus telemetry and error-reporting
|
|
711
|
+
* sinks. Assets need no filter of their own — they arrive as GETs. Host is
|
|
712
|
+
* NOT a filter criterion — a multi-step submission routinely bounces to a
|
|
713
|
+
* different host mid-flow (an account-creation redirect, a tenant API
|
|
714
|
+
* subdomain distinct from the landing page's host), so `isNoiseUrl` alone
|
|
715
|
+
* decides what counts as site traffic vs. third-party noise.
|
|
703
716
|
*
|
|
704
717
|
* When the flow declares submit patterns, only POSTs matching them survive —
|
|
705
718
|
* this isolates the submission from same-origin page chrome (bootstrap, chatbot,
|
|
706
719
|
* JWT refresh, reference-lookup) that a browser fires incidentally. Absent
|
|
707
|
-
* patterns preserve the
|
|
720
|
+
* patterns preserve the noise heuristic exactly.
|
|
708
721
|
*
|
|
709
722
|
* Exported for tests: this predicate decides what a generated plugin will POST
|
|
710
723
|
* at a live site, and it is the only gate between a browser's incidental
|
|
711
724
|
* chatter and the emitted hot path.
|
|
712
725
|
*/
|
|
713
|
-
function extractActionSequence(captures,
|
|
714
|
-
let host;
|
|
715
|
-
try {
|
|
716
|
-
host = new URL(baseUrl).host;
|
|
717
|
-
}
|
|
718
|
-
catch {
|
|
719
|
-
host = "";
|
|
720
|
-
}
|
|
726
|
+
function extractActionSequence(captures, submitPatterns = null) {
|
|
721
727
|
const matchesSubmit = compileSubmitMatcher(submitPatterns);
|
|
722
728
|
return captures
|
|
723
729
|
.map((capture, index) => ({ capture, index }))
|
|
@@ -726,15 +732,6 @@ function extractActionSequence(captures, baseUrl, submitPatterns = null) {
|
|
|
726
732
|
return false;
|
|
727
733
|
if (capture.status < 200 || capture.status >= 300)
|
|
728
734
|
return false;
|
|
729
|
-
let captureHost;
|
|
730
|
-
try {
|
|
731
|
-
captureHost = new URL(capture.url).host;
|
|
732
|
-
}
|
|
733
|
-
catch {
|
|
734
|
-
return false;
|
|
735
|
-
}
|
|
736
|
-
if (captureHost !== host)
|
|
737
|
-
return false;
|
|
738
735
|
if ((0, capture_filters_1.isNoiseUrl)(capture.url))
|
|
739
736
|
return false;
|
|
740
737
|
if (!matchesSubmit(capture))
|
|
@@ -750,19 +747,13 @@ function extractActionSequence(captures, baseUrl, submitPatterns = null) {
|
|
|
750
747
|
* make up a transactional flow (`UpsertSavedApplication`, `SubmitForm`, ...)
|
|
751
748
|
* — and drops `query` operations, which are read/bootstrap calls (e.g. a
|
|
752
749
|
* page-load `ListForms`) that carry no state-threading value and are exactly
|
|
753
|
-
* what let a chronologically-first fallback pick an unrelated query.
|
|
750
|
+
* what let a chronologically-first fallback pick an unrelated query. Host is
|
|
751
|
+
* NOT a filter criterion, matching {@link extractActionSequence}.
|
|
754
752
|
*
|
|
755
753
|
* Exported for tests: this predicate decides what a generated GraphQL plugin
|
|
756
754
|
* will send at a live site.
|
|
757
755
|
*/
|
|
758
|
-
function extractGraphQLActionSequence(captures,
|
|
759
|
-
let host;
|
|
760
|
-
try {
|
|
761
|
-
host = new URL(baseUrl).host;
|
|
762
|
-
}
|
|
763
|
-
catch {
|
|
764
|
-
host = "";
|
|
765
|
-
}
|
|
756
|
+
function extractGraphQLActionSequence(captures, submitPatterns = null) {
|
|
766
757
|
const matchesSubmit = compileSubmitMatcher(submitPatterns);
|
|
767
758
|
return captures
|
|
768
759
|
.map((capture, index) => ({ capture, index }))
|
|
@@ -771,15 +762,6 @@ function extractGraphQLActionSequence(captures, baseUrl, submitPatterns = null)
|
|
|
771
762
|
return false;
|
|
772
763
|
if (capture.status < 200 || capture.status >= 300)
|
|
773
764
|
return false;
|
|
774
|
-
let captureHost;
|
|
775
|
-
try {
|
|
776
|
-
captureHost = new URL(capture.url).host;
|
|
777
|
-
}
|
|
778
|
-
catch {
|
|
779
|
-
return false;
|
|
780
|
-
}
|
|
781
|
-
if (captureHost !== host)
|
|
782
|
-
return false;
|
|
783
765
|
if ((0, capture_filters_1.isNoiseUrl)(capture.url))
|
|
784
766
|
return false;
|
|
785
767
|
if (!matchesSubmit(capture))
|
|
@@ -3280,7 +3262,7 @@ function renderGqlVariablesExpr(variables, payloadFieldNames) {
|
|
|
3280
3262
|
return entries.length > 0 ? `{ ${entries.join(", ")} }` : "{}";
|
|
3281
3263
|
}
|
|
3282
3264
|
function emitContractTs(opts) {
|
|
3283
|
-
const { siteId, pascal, baseUrl, baseHeaders, minTime, safeRps, responseBody, gql, gqlQuery, endpointPath, gqlOperationName, gqlVariables, auxFiles, multiStepBody, inputBody, hasMultipartStep = false, discoveredFormFields, fieldOptionsMap, discoveredOptionFields, discoveredRawOptionFields, discoveredAdditionalBodyKeys, discoveredStructuredKeys, payloadFieldNames, headerBindings = [], } = opts;
|
|
3265
|
+
const { siteId, pascal, baseUrl, baseHeaders, minTime, safeRps, responseBody, gql, gqlQuery, endpointPath, gqlOperationName, gqlVariables, auxFiles, multiStepBody, omitExecuteHttp = false, inputBody, hasMultipartStep = false, discoveredFormFields, fieldOptionsMap, discoveredOptionFields, discoveredRawOptionFields, discoveredAdditionalBodyKeys, discoveredStructuredKeys, payloadFieldNames, headerBindings = [], } = opts;
|
|
3284
3266
|
// This is the CLIENT-level schema — createHttpClient's default, and the
|
|
3285
3267
|
// plugin's caller-facing contract (what executeHttp's return value promises
|
|
3286
3268
|
// its own caller). It does NOT validate any individual call in a multi-step
|
|
@@ -3289,18 +3271,18 @@ function emitContractTs(opts) {
|
|
|
3289
3271
|
// invocation, so heterogeneous per-call shapes are each checked against
|
|
3290
3272
|
// their own inferred schema regardless of what this client-level schema is.
|
|
3291
3273
|
//
|
|
3292
|
-
// For multi-step flows
|
|
3293
|
-
//
|
|
3294
|
-
//
|
|
3295
|
-
//
|
|
3296
|
-
//
|
|
3297
|
-
//
|
|
3298
|
-
//
|
|
3299
|
-
//
|
|
3300
|
-
//
|
|
3301
|
-
//
|
|
3302
|
-
//
|
|
3303
|
-
const responseSchemaExpr =
|
|
3274
|
+
// For multi-step flows, `responseBody` here is already
|
|
3275
|
+
// `selectEffectiveResponseBody`'s pick — the SAME call `selectReturnAction`
|
|
3276
|
+
// returns from `executeHttp` (`return { data: r9 }` below, r9 being that
|
|
3277
|
+
// call's own already-validated result). Inferring the client-level schema
|
|
3278
|
+
// from it is therefore not a guess about a field the captures never showed:
|
|
3279
|
+
// it's the literal shape of the value the client hands back, captured by
|
|
3280
|
+
// its own success response (e.g. a `valid`/`errors`-shaped terminal body).
|
|
3281
|
+
// Single-endpoint plugins keep the same inferred-schema treatment, since
|
|
3282
|
+
// there both roles (client default and sole call) coincide.
|
|
3283
|
+
// Browser-flow-only plugins have no HTTP call to infer a shape from —
|
|
3284
|
+
// z.unknown() there is the honest gap, not a narrowing shortcut.
|
|
3285
|
+
const responseSchemaExpr = omitExecuteHttp ? `z.unknown()` : inferZodSchema(responseBody);
|
|
3304
3286
|
// Multi-step flows that include a multipart upload need the binary asset
|
|
3305
3287
|
// on the payload. ApplicantContactSchema (via ApplicantResumeSchema) already
|
|
3306
3288
|
// declares Resume/ResumeContentType/ResumeFilename, so submission flows
|
|
@@ -3485,14 +3467,22 @@ function emitContractTs(opts) {
|
|
|
3485
3467
|
.map(([k, v]) => ` ${isValidJsIdentifier(k) ? k : JSON.stringify(k)}: ${JSON.stringify(v)}`)
|
|
3486
3468
|
.join(",\n");
|
|
3487
3469
|
const fixtureImport = auxFiles.length > 0 ? `// import { loadFixture } from "${ENGINE_PKG}/scraper/fixtures";\n` : "";
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3470
|
+
// Browser-flow-only plugins have no direct-HTTP hot path, so none of the
|
|
3471
|
+
// client-construction machinery below (import, rate limiter, cache/client
|
|
3472
|
+
// const) is emitted — it would sit unreferenced and trip Biome's
|
|
3473
|
+
// `noUnusedVariables`.
|
|
3474
|
+
const clientImport = omitExecuteHttp
|
|
3475
|
+
? ""
|
|
3476
|
+
: gql
|
|
3477
|
+
? `import { createGraphqlClient } from "${ENGINE_PKG}/scraper/graphql-client";`
|
|
3478
|
+
: `import { createHttpClient } from "${ENGINE_PKG}/scraper/http-client";`;
|
|
3479
|
+
const queryConst = !omitExecuteHttp && gql && gqlQuery
|
|
3492
3480
|
? `\n// Lifted verbatim from recon capture — trim UI-only fields before shipping.\nconst ${pascal.toUpperCase()}_QUERY = \`${gqlQuery.trim()}\`;\n`
|
|
3493
3481
|
: "";
|
|
3494
|
-
const gqlCacheBlock =
|
|
3495
|
-
?
|
|
3482
|
+
const gqlCacheBlock = omitExecuteHttp
|
|
3483
|
+
? ""
|
|
3484
|
+
: gql
|
|
3485
|
+
? `
|
|
3496
3486
|
type GqlFn = (operationName: string, query: string, variables: Record<string, unknown>) => Promise<${pascal}Response>;
|
|
3497
3487
|
|
|
3498
3488
|
const gqlCache = new Map<string, GqlFn>();
|
|
@@ -3511,7 +3501,7 @@ function getGql(baseUrl: string): GqlFn {
|
|
|
3511
3501
|
return client;
|
|
3512
3502
|
}
|
|
3513
3503
|
`
|
|
3514
|
-
|
|
3504
|
+
: `
|
|
3515
3505
|
const httpClient = createHttpClient({ schema: ${pascal}ResponseSchema, bottleneck: limiter, baseHeaders: BASE_HEADERS${bindOptionLiteral(headerBindings)} });
|
|
3516
3506
|
`;
|
|
3517
3507
|
const gqlOperationNameExpr = gqlOperationName
|
|
@@ -3556,7 +3546,7 @@ const httpClient = createHttpClient({ schema: ${pascal}ResponseSchema, bottlenec
|
|
|
3556
3546
|
export const ${pascal}InternalRequestReference = ${internalRequestReferenceExpr};
|
|
3557
3547
|
`
|
|
3558
3548
|
: "";
|
|
3559
|
-
const queryChecklistLine = gql
|
|
3549
|
+
const queryChecklistLine = !omitExecuteHttp && gql
|
|
3560
3550
|
? `\n * [ ] Trim UI-only fields from ${pascal.toUpperCase()}_QUERY (keep only fields you need)`
|
|
3561
3551
|
: "";
|
|
3562
3552
|
// Multi-step flows validate each call against its own per-call inferred
|
|
@@ -3564,37 +3554,73 @@ export const ${pascal}InternalRequestReference = ${internalRequestReferenceExpr}
|
|
|
3564
3554
|
// what executeHttp promises ITS OWN caller, never a per-call validator, so
|
|
3565
3555
|
// the checklist item must say that explicitly. Single-endpoint plugins have
|
|
3566
3556
|
// exactly one call, so the client schema and that call's validator are the
|
|
3567
|
-
// same schema and the shorter wording stays accurate.
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3557
|
+
// same schema and the shorter wording stays accurate. Browser-flow-only
|
|
3558
|
+
// plugins have no executeHttp at all, so ResponseSchema is only ever the
|
|
3559
|
+
// browser flow's own return-value contract.
|
|
3560
|
+
const narrowSchemaChecklistLine = omitExecuteHttp
|
|
3561
|
+
? `\n * [ ] Narrow ${pascal}ResponseSchema to match what the browser flow should promise ITS CALLER — this flow could not synthesize a trustworthy executeHttp (a required value from the captured sequence never resolved), so it ships browser-only`
|
|
3562
|
+
: multiStepBody
|
|
3563
|
+
? `\n * [ ] Narrow ${pascal}ResponseSchema to match what executeHttp should promise ITS CALLER — this is the plugin's own return-value contract, not a per-call validator (each call in the flow is already checked against its own inferred schema)`
|
|
3564
|
+
: `\n * [ ] Narrow ${pascal}ResponseSchema to match the real response shape`;
|
|
3571
3565
|
const camel = siteId.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
3566
|
+
// Browser-flow-only plugins need neither Bottleneck (no rate-limited HTTP
|
|
3567
|
+
// client) nor BASE_HEADERS (no per-call headers to bake in) — both would
|
|
3568
|
+
// sit unreferenced and trip Biome's `noUnusedVariables`.
|
|
3569
|
+
const bottleneckImport = omitExecuteHttp ? "" : `import Bottleneck from "bottleneck";\n`;
|
|
3570
|
+
const baseHeadersBlock = omitExecuteHttp
|
|
3571
|
+
? ""
|
|
3572
|
+
: `
|
|
3573
|
+
const BASE_HEADERS: Record<string, string> = {
|
|
3574
|
+
${headersLiteral},
|
|
3575
|
+
};
|
|
3576
|
+
`;
|
|
3577
|
+
const limiterBlock = omitExecuteHttp
|
|
3578
|
+
? ""
|
|
3579
|
+
: `
|
|
3580
|
+
// Safe ceiling: ${safeRps} rps — from recon rate-limit probe.
|
|
3581
|
+
const limiter = new Bottleneck({ minTime: ${minTime} });
|
|
3582
|
+
`;
|
|
3583
|
+
const executeHttpMethodBlock = omitExecuteHttp
|
|
3584
|
+
? ""
|
|
3585
|
+
: `
|
|
3586
|
+
/** Hot path: direct HTTP — no browser, no LLM tokens. */
|
|
3587
|
+
async executeHttp(
|
|
3588
|
+
payload: ${pascal}Payload,
|
|
3589
|
+
${executeHttpBody.includes("context.") ? "context" : "_context"}: SitePluginContext
|
|
3590
|
+
): Promise<SitePluginResult<${pascal}Response>> {
|
|
3591
|
+
${executeHttpBody}
|
|
3592
|
+
},
|
|
3593
|
+
`;
|
|
3594
|
+
const pluginDocComment = omitExecuteHttp
|
|
3595
|
+
? `/**
|
|
3596
|
+
* Plugin for ${siteId}. Browser-flow-only: the captured multi-step submission
|
|
3597
|
+
* sequence could not be synthesized into a trustworthy direct-HTTP hot path
|
|
3598
|
+
* (see the checklist above), so this always runs via Stagehand.
|
|
3599
|
+
*/`
|
|
3600
|
+
: `/**
|
|
3601
|
+
* Plugin for ${siteId}. Tries the direct-HTTP hot path first; falls back to
|
|
3602
|
+
* Stagehand automatically on schema drift or bot challenge.
|
|
3603
|
+
*/`;
|
|
3604
|
+
const baseHeadersChecklistLine = omitExecuteHttp
|
|
3605
|
+
? ""
|
|
3606
|
+
: `\n * [ ] Verify BASE_HEADERS — remove any that aren't load-bearing`;
|
|
3607
|
+
const outOfTreeChecklistLine = omitExecuteHttp
|
|
3608
|
+
? `\n * [ ] Out-of-tree: \`pnpm add zod\` — this file imports it directly, and a\n * strict node_modules layout (pnpm) won't resolve it as a transitive\n * dep of @enricai/barnacle alone`
|
|
3609
|
+
: `\n * [ ] Out-of-tree: \`pnpm add bottleneck zod\` — this file imports both\n * directly, and a strict node_modules layout (pnpm) won't resolve\n * them as transitive deps of @enricai/barnacle alone`;
|
|
3572
3610
|
return `/**
|
|
3573
3611
|
* Generated by recon-generate.ts — review before shipping.
|
|
3574
3612
|
*
|
|
3575
3613
|
* Checklist:${queryChecklistLine}${narrowSchemaChecklistLine}
|
|
3576
|
-
* [ ] Adjust ${pascal}PayloadSchema to your actual request parameters
|
|
3577
|
-
* [ ] Verify BASE_HEADERS — remove any that aren't load-bearing
|
|
3578
|
-
* [ ] Out-of-tree: \`pnpm add bottleneck zod\` — this file imports both
|
|
3579
|
-
* directly, and a strict node_modules layout (pnpm) won't resolve
|
|
3580
|
-
* them as transitive deps of @enricai/barnacle alone
|
|
3614
|
+
* [ ] Adjust ${pascal}PayloadSchema to your actual request parameters${baseHeadersChecklistLine}${outOfTreeChecklistLine}
|
|
3581
3615
|
*/
|
|
3582
3616
|
|
|
3583
|
-
import
|
|
3584
|
-
import { z } from "zod/v4";
|
|
3617
|
+
${bottleneckImport}import { z } from "zod/v4";
|
|
3585
3618
|
|
|
3586
3619
|
${fixtureImport}${applicantContactImport}${caseInsensitiveHeadersImport}${multipartBoolImport}${clientImport}
|
|
3587
3620
|
import type { BrowserSession } from "${ENGINE_PKG}/scraper/session";
|
|
3588
3621
|
import type { SitePlugin, SitePluginContext, SitePluginResult } from "${ENGINE_PKG}/site-plugin";
|
|
3589
3622
|
import { run${pascal}BrowserFlow } from "@/sites/${siteId}/flows/browser-flow";
|
|
3590
|
-
|
|
3591
|
-
const BASE_HEADERS: Record<string, string> = {
|
|
3592
|
-
${headersLiteral},
|
|
3593
|
-
};
|
|
3594
|
-
|
|
3595
|
-
// Safe ceiling: ${safeRps} rps — from recon rate-limit probe.
|
|
3596
|
-
const limiter = new Bottleneck({ minTime: ${minTime} });
|
|
3597
|
-
|
|
3623
|
+
${baseHeadersBlock}${limiterBlock}
|
|
3598
3624
|
const ${pascal}ResponseSchema = ${responseSchemaExpr};
|
|
3599
3625
|
|
|
3600
3626
|
export type ${pascal}Response = z.infer<typeof ${pascal}ResponseSchema>;
|
|
@@ -3605,10 +3631,7 @@ const ${pascal}PayloadSchema = ${payloadSchemaExpr};
|
|
|
3605
3631
|
|
|
3606
3632
|
export type ${pascal}Payload = z.infer<typeof ${pascal}PayloadSchema>;
|
|
3607
3633
|
${internalRequestReferenceBlock}${queryConst}${gqlCacheBlock}${fixtureComments}
|
|
3608
|
-
|
|
3609
|
-
* Plugin for ${siteId}. Tries the direct-HTTP hot path first; falls back to
|
|
3610
|
-
* Stagehand automatically on schema drift or bot challenge.
|
|
3611
|
-
*/
|
|
3634
|
+
${pluginDocComment}
|
|
3612
3635
|
export const ${camel}Plugin: SitePlugin<${pascal}Payload, ${pascal}Response> = {
|
|
3613
3636
|
meta: {
|
|
3614
3637
|
siteId: ${JSON.stringify(siteId)},
|
|
@@ -3626,15 +3649,7 @@ export const ${camel}Plugin: SitePlugin<${pascal}Payload, ${pascal}Response> = {
|
|
|
3626
3649
|
// encoding parseable.
|
|
3627
3650
|
apiVersion: ${JSON.stringify(plugin_api_version_1.PLUGIN_API_VERSION)},${payloadNeedsMultipart || inputBody ? "\n multipart: true," : ""}
|
|
3628
3651
|
},
|
|
3629
|
-
|
|
3630
|
-
/** Hot path: direct HTTP — no browser, no LLM tokens. */
|
|
3631
|
-
async executeHttp(
|
|
3632
|
-
payload: ${pascal}Payload,
|
|
3633
|
-
${executeHttpBody.includes("context.") ? "context" : "_context"}: SitePluginContext
|
|
3634
|
-
): Promise<SitePluginResult<${pascal}Response>> {
|
|
3635
|
-
${executeHttpBody}
|
|
3636
|
-
},
|
|
3637
|
-
|
|
3652
|
+
${executeHttpMethodBlock}
|
|
3638
3653
|
/** Browser fallback: Stagehand + Steel — invoked only when hot path fails. */
|
|
3639
3654
|
async execute(
|
|
3640
3655
|
payload: ${pascal}Payload,
|
|
@@ -4134,9 +4149,7 @@ async function main() {
|
|
|
4134
4149
|
// Hoisted so both the primary-operation gate below and rawActionCaptures
|
|
4135
4150
|
// (further down) read the same computed sequence instead of calling the
|
|
4136
4151
|
// extractor twice.
|
|
4137
|
-
const graphqlActionSequence = gql
|
|
4138
|
-
? extractGraphQLActionSequence(captures, baseUrl, submitPatterns)
|
|
4139
|
-
: [];
|
|
4152
|
+
const graphqlActionSequence = gql ? extractGraphQLActionSequence(captures, submitPatterns) : [];
|
|
4140
4153
|
const isReadOnlyFlow = !flowSteps.some((step) => typeof step !== "string" && step.submitStep === true);
|
|
4141
4154
|
const primaryGraphQLOperation = gql && isReadOnlyFlow && graphqlActionSequence.length === 0
|
|
4142
4155
|
? selectPrimaryGraphQLOperation(captures, flowSteps, vocabulary)
|
|
@@ -4150,15 +4163,60 @@ async function main() {
|
|
|
4150
4163
|
// Selection precedence: (A) the authoritative submit-manifest recon-browser
|
|
4151
4164
|
// wrote from the verified submission; else (B/C) pattern/heuristic extraction.
|
|
4152
4165
|
// The manifest is the only signal that separates a submission POST from a
|
|
4153
|
-
// page-chrome POST sharing its URL, so it wins when present
|
|
4166
|
+
// page-chrome POST sharing its URL, so it normally wins when present — but
|
|
4167
|
+
// a manifest built from a single flow-declared submit step cannot represent
|
|
4168
|
+
// a wizard whose every section saves independently, so it is only trusted
|
|
4169
|
+
// when it isn't a strict undercount of what the same captures' own
|
|
4170
|
+
// heuristic extraction finds.
|
|
4171
|
+
const patternedHeuristicActionCaptures = gql
|
|
4172
|
+
? graphqlActionSequence
|
|
4173
|
+
: collapseRedundantPatches(extractActionSequence(captures, submitPatterns));
|
|
4174
|
+
// The same undercount hazard applies one layer below the manifest: a
|
|
4175
|
+
// flow-declared submitEndpointPattern that matches only one section's URL
|
|
4176
|
+
// (the natural way to describe "the button that finishes the wizard")
|
|
4177
|
+
// filters the heuristic sequence down to that one capture even though the
|
|
4178
|
+
// same captures, read without the pattern, show every section saving
|
|
4179
|
+
// independently. A pattern that undercounts what the unfiltered heuristic
|
|
4180
|
+
// finds is therefore not trusted either — it falls back to the richer,
|
|
4181
|
+
// unfiltered sequence instead of collapsing a real multi-call flow into
|
|
4182
|
+
// the generic single-endpoint fallback.
|
|
4183
|
+
const unfilteredHeuristicActionCaptures = submitPatterns.endpoint === null && submitPatterns.body === null
|
|
4184
|
+
? patternedHeuristicActionCaptures
|
|
4185
|
+
: gql
|
|
4186
|
+
? extractGraphQLActionSequence(captures, null)
|
|
4187
|
+
: collapseRedundantPatches(extractActionSequence(captures, null));
|
|
4188
|
+
const patternUndercounts = patternedHeuristicActionCaptures.length < unfilteredHeuristicActionCaptures.length;
|
|
4189
|
+
if (patternUndercounts) {
|
|
4190
|
+
logger.info(`submission selection: ignoring submitEndpointPattern/submitBodyPattern (${patternedHeuristicActionCaptures.length} capture(s)) as an undercount of the unfiltered heuristic action sequence (${unfilteredHeuristicActionCaptures.length} capture(s))`);
|
|
4191
|
+
}
|
|
4192
|
+
const heuristicActionCaptures = patternUndercounts
|
|
4193
|
+
? unfilteredHeuristicActionCaptures
|
|
4194
|
+
: patternedHeuristicActionCaptures;
|
|
4154
4195
|
const manifestActionCaptures = resolveManifestActionSequence(runRoot, captures);
|
|
4155
|
-
|
|
4196
|
+
const manifestUndercounts = manifestActionCaptures !== null &&
|
|
4197
|
+
manifestActionCaptures.length < heuristicActionCaptures.length;
|
|
4198
|
+
if (manifestActionCaptures !== null && manifestUndercounts) {
|
|
4199
|
+
logger.info(`submission selection: ignoring submit-manifest.json (${manifestActionCaptures.length} capture(s)) as an undercount of the heuristic action sequence (${heuristicActionCaptures.length} capture(s))`);
|
|
4200
|
+
}
|
|
4201
|
+
else if (manifestActionCaptures !== null) {
|
|
4156
4202
|
logger.info(`submission selection: using submit-manifest.json (${manifestActionCaptures.length} authoritative capture(s))`);
|
|
4157
4203
|
}
|
|
4158
|
-
const rawActionCaptures = manifestActionCaptures
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4204
|
+
const rawActionCaptures = manifestActionCaptures !== null && !manifestUndercounts
|
|
4205
|
+
? manifestActionCaptures
|
|
4206
|
+
: heuristicActionCaptures;
|
|
4207
|
+
// The declared submitEndpointPattern's own under-match: unlike manifestUndercounts
|
|
4208
|
+
// (which compares an authoritative submit-manifest.json against the heuristic
|
|
4209
|
+
// sequence), this compares the pattern-filtered heuristic sequence against the SAME
|
|
4210
|
+
// captures with no submitPatterns filter at all — the true raw non-GET 2xx non-noise
|
|
4211
|
+
// action set. A pattern that matches conspicuously fewer calls than that raw set is a
|
|
4212
|
+
// detection failure (the pattern is too narrow), not evidence the flow is read-only,
|
|
4213
|
+
// and per the no-silent-fallback rule must not be allowed to quietly collapse into the
|
|
4214
|
+
// generic single-endpoint {query} template below.
|
|
4215
|
+
const rawUnfilteredActionCaptures = submitEndpointPattern === null
|
|
4216
|
+
? null
|
|
4217
|
+
: gql
|
|
4218
|
+
? extractGraphQLActionSequence(captures, null)
|
|
4219
|
+
: collapseRedundantPatches(extractActionSequence(captures, null));
|
|
4162
4220
|
// Form-schema detection runs BEFORE state-indexing so the field-id/option-id
|
|
4163
4221
|
// UUIDs can be shielded from indexing — those UUIDs are stable schema
|
|
4164
4222
|
// anchors that T2/T3 substitution depends on remaining literal in body
|
|
@@ -4211,6 +4269,19 @@ async function main() {
|
|
|
4211
4269
|
: new Map();
|
|
4212
4270
|
const actionSteps = actionCaptures.length > 1 ? compileActionSteps(actionCaptures, stateIndex) : [];
|
|
4213
4271
|
const isSubmissionFlow = actionSteps.length > 1;
|
|
4272
|
+
// Loud failure for a submitEndpointPattern that under-matches the raw traffic badly
|
|
4273
|
+
// enough to collapse the flow to the single-endpoint fallback: heuristicActionCaptures
|
|
4274
|
+
// is the pattern-filtered sequence (used both directly and as rawActionCaptures' floor
|
|
4275
|
+
// via manifestUndercounts above), so if it's this thin ONLY because the pattern itself
|
|
4276
|
+
// excluded real action captures the unfiltered raw set still has, emitting the generic
|
|
4277
|
+
// {query} template would misrepresent a genuine multi-call flow as read-only. Exit
|
|
4278
|
+
// rather than degrade quietly, per the no-defensive/no-silent-fallback rule.
|
|
4279
|
+
if (rawUnfilteredActionCaptures !== null &&
|
|
4280
|
+
!isSubmissionFlow &&
|
|
4281
|
+
rawUnfilteredActionCaptures.length > heuristicActionCaptures.length) {
|
|
4282
|
+
logger.error(`ERROR declared submitEndpointPattern ${JSON.stringify(submitEndpointPattern)} matched only ${heuristicActionCaptures.length} of ${rawUnfilteredActionCaptures.length} raw non-GET 2xx non-noise action capture(s) — this under-match looks like a detection failure, not a read-only flow; refusing to fall back to the generic single-endpoint {query} template. Fix submitEndpointPattern in recon-flow.json to cover the real submission calls.`);
|
|
4283
|
+
process.exit(1);
|
|
4284
|
+
}
|
|
4214
4285
|
// Diagnostic for the FAILURE-3 shape (a flowless recon capture): a "submission flow"
|
|
4215
4286
|
// whose every action capture is landing-phase is almost certainly page-chrome
|
|
4216
4287
|
// bootstrap (e.g. page-chrome `POST /widgets`) misread as an apply flow, not a walked
|
|
@@ -4287,15 +4358,33 @@ async function main() {
|
|
|
4287
4358
|
staticBaseHeaders[k] = v;
|
|
4288
4359
|
}
|
|
4289
4360
|
}
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4361
|
+
// Third branch (browser-flow-only): a multi-action flow (isSubmissionFlow)
|
|
4362
|
+
// that crosses hosts mid-sequence (compileActionSteps' isCrossDomain — a
|
|
4363
|
+
// captured redirect off the original domain, e.g. an auth bounce or a
|
|
4364
|
+
// vendor-hosted submission step). A bare `fetch`-based executeHttp can't
|
|
4365
|
+
// reliably replay that: cookies/CSRF/session state minted for one origin
|
|
4366
|
+
// don't automatically carry to the next the way a real browser's redirect
|
|
4367
|
+
// handling does, so synthesizing a same-shape HTTP sequence would silently
|
|
4368
|
+
// drop the session boundary the recon actually walked. Per-step, this
|
|
4369
|
+
// already surfaces as the "cross-domain redirect detected ... likely needs
|
|
4370
|
+
// browser fallback for this step" TODO (see emitMultiStepExecuteHttp); at
|
|
4371
|
+
// the whole-flow level the honest emit is no executeHttp at all — never a
|
|
4372
|
+
// same-host multi-step body that quietly drops the hop, and never a
|
|
4373
|
+
// downgrade to the single-endpoint `{query}` branch either, since that's a
|
|
4374
|
+
// fabrication of its own kind for a flow that isn't a single-action
|
|
4375
|
+
// query/search to begin with.
|
|
4376
|
+
const browserFlowOnly = isSubmissionFlow && actionSteps.some((s) => s.isCrossDomain);
|
|
4377
|
+
const multiStepBody = browserFlowOnly
|
|
4378
|
+
? undefined
|
|
4379
|
+
: isSubmissionFlow
|
|
4380
|
+
? emitMultiStepExecuteHttp(actionSteps, inputBody, errorSignals, fieldNameMap, discoveredFormFields, fieldOptionsMap, discoveredOptionFields, discoveredRawOptionFields, discoveredAdditionalBodyKeys, baseUrl, baseUrlDerivedHeaders, tenantSubdomainHeaders, formSchema, personaBindings, entryUrlParams, shieldedUuids, selectResolutions, discoveredStructuredKeys, rawCodeFields)
|
|
4381
|
+
: undefined;
|
|
4293
4382
|
const hasMultipartStep = actionSteps.some((s) => s.isMultipart);
|
|
4294
4383
|
const headerBindings = collectHeaderBindings(actionSteps);
|
|
4295
4384
|
// Shape inference targets the SAME call executeHttp returns — see
|
|
4296
4385
|
// selectEffectiveResponseBody — so the two surfaces can't describe different calls.
|
|
4297
4386
|
const effectiveResponseBody = selectEffectiveResponseBody(isSubmissionFlow, actionSteps, responseBody);
|
|
4298
|
-
logger.info(`generating plugin for ${siteId} (${gql ? "GraphQL" : isSubmissionFlow ? `submission flow, ${actionSteps.length} steps` : "single-endpoint REST"}, baseUrl: ${baseUrl})`);
|
|
4387
|
+
logger.info(`generating plugin for ${siteId} (${gql ? "GraphQL" : browserFlowOnly ? `submission flow, ${actionSteps.length} steps, browser-flow-only (cross-domain hop detected)` : isSubmissionFlow ? `submission flow, ${actionSteps.length} steps` : "single-endpoint REST"}, baseUrl: ${baseUrl})`);
|
|
4299
4388
|
if (emit === "config") {
|
|
4300
4389
|
(0, node_fs_1.mkdirSync)(outDir, { recursive: true });
|
|
4301
4390
|
(0, node_fs_1.writeFileSync)(manifestPath, emitConfigManifest({
|
|
@@ -4309,7 +4398,9 @@ async function main() {
|
|
|
4309
4398
|
// A submission flow is the case where the `.ts` emit carries an
|
|
4310
4399
|
// executeHttp hot path; point the manifest at where the operator drops
|
|
4311
4400
|
// the compiled module rather than silently dropping the direct path.
|
|
4312
|
-
|
|
4401
|
+
// Not set for the browser-flow-only branch — there is no hot path to
|
|
4402
|
+
// compile a module for.
|
|
4403
|
+
httpModulePath: isSubmissionFlow && !browserFlowOnly ? `./${siteId}.http.js` : undefined,
|
|
4313
4404
|
}));
|
|
4314
4405
|
logger.info(`wrote ${manifestPath}`);
|
|
4315
4406
|
logger.info(`done — review ${manifestPath}, fill in response/extract schemas, then load via BARNACLE_PLUGINS or BARNACLE_PLUGINS_CONFIG_DIR (no compile step)`);
|
|
@@ -4346,6 +4437,7 @@ async function main() {
|
|
|
4346
4437
|
gqlVariables: primaryGraphQLOperation?.capture.variables ?? null,
|
|
4347
4438
|
auxFiles,
|
|
4348
4439
|
multiStepBody,
|
|
4440
|
+
omitExecuteHttp: browserFlowOnly,
|
|
4349
4441
|
inputBody,
|
|
4350
4442
|
hasMultipartStep,
|
|
4351
4443
|
discoveredFormFields,
|