@enricai/barnacle 1.12.44 → 1.12.45
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/scripts/recon-generate-multicall-fixture.d.ts +14 -0
- package/dist/scripts/recon-generate-multicall-fixture.d.ts.map +1 -1
- package/dist/scripts/recon-generate-multicall-fixture.js +72 -0
- package/dist/scripts/recon-generate-multicall-fixture.js.map +1 -1
- package/dist/scripts/recon-generate.d.ts.map +1 -1
- package/dist/scripts/recon-generate.js +66 -59
- package/dist/scripts/recon-generate.js.map +1 -1
- package/package.json +1 -1
|
@@ -7078,19 +7078,46 @@ function emitContractTs(opts) {
|
|
|
7078
7078
|
//
|
|
7079
7079
|
// The captured request body (inputBody) is the SITE's internal request
|
|
7080
7080
|
// shape (a vendor's ddoKey/formData, a GraphQL worklet's variables, …) — not
|
|
7081
|
-
//
|
|
7082
|
-
//
|
|
7083
|
-
//
|
|
7084
|
-
//
|
|
7085
|
-
//
|
|
7086
|
-
//
|
|
7087
|
-
//
|
|
7088
|
-
//
|
|
7089
|
-
//
|
|
7090
|
-
|
|
7091
|
-
|
|
7081
|
+
// necessarily the real caller's shape. ApplicantContactSchema (the job-
|
|
7082
|
+
// application template: identity/address/resume fields + Email + a JSON
|
|
7083
|
+
// Answers block) only belongs on flows that are actually job/benefits
|
|
7084
|
+
// applications — selecting it purely because SOME body was captured picks
|
|
7085
|
+
// it for unrelated submission flows too. usesApplicantContactSchema is the
|
|
7086
|
+
// real-evidence gate: it requires the captured inputBody to itself carry
|
|
7087
|
+
// one of ApplicantContactSchema's own field names (case-insensitively,
|
|
7088
|
+
// checked at any depth via walkAllPrimitiveLeaves) before the template
|
|
7089
|
+
// applies (see recon-generate-payload-schema-mismatch.md).
|
|
7090
|
+
const applicantContactFieldNames = new Set([
|
|
7091
|
+
"FirstName",
|
|
7092
|
+
"LastName",
|
|
7093
|
+
"Phone",
|
|
7094
|
+
"AddressLine",
|
|
7095
|
+
"City",
|
|
7096
|
+
"State",
|
|
7097
|
+
"PostalCode",
|
|
7098
|
+
"Country",
|
|
7099
|
+
"County",
|
|
7100
|
+
"Resume",
|
|
7101
|
+
"ResumeContentType",
|
|
7102
|
+
"ResumeFilename",
|
|
7103
|
+
"ResumeBase64",
|
|
7104
|
+
]);
|
|
7105
|
+
const baseContractFieldNames = new Set(["Email", "ClickUrl", "Answers"]);
|
|
7106
|
+
const applicantContactEvidenceFieldNamesLower = new Set([...applicantContactFieldNames, ...baseContractFieldNames].map((name) => name.toLowerCase()));
|
|
7107
|
+
const usesApplicantContactSchema = inputBody != null &&
|
|
7108
|
+
[...walkAllPrimitiveLeaves(inputBody)].some(({ path }) => path.some((segment) => applicantContactEvidenceFieldNamesLower.has(segment.toLowerCase())));
|
|
7109
|
+
const isReservedByApplicantContactSchema = (name) => usesApplicantContactSchema && applicantContactFieldNames.has(name);
|
|
7110
|
+
// A missing inputBody, or one with no ApplicantContactSchema evidence,
|
|
7111
|
+
// means this is not a job-application submission flow. The former keeps
|
|
7112
|
+
// its own read-flow `{ query }` contract untouched; the latter (a body WAS
|
|
7113
|
+
// captured, it just isn't an application) gets a plain empty base instead
|
|
7114
|
+
// — extend() below still layers on every genuinely-discovered field from
|
|
7115
|
+
// the other sources unchanged.
|
|
7116
|
+
const basePayloadSchemaExpr = usesApplicantContactSchema
|
|
7092
7117
|
? `ApplicantContactSchema`
|
|
7093
|
-
:
|
|
7118
|
+
: inputBody
|
|
7119
|
+
? `z.object({})`
|
|
7120
|
+
: `z.object({\n query: z.string().min(1),\n})`;
|
|
7094
7121
|
// Only the single-endpoint GraphQL read path (a real primary operation, no
|
|
7095
7122
|
// multi-step flow) is a candidate for a paging signal — multiStepBody
|
|
7096
7123
|
// already owns its own per-call semantics.
|
|
@@ -7153,34 +7180,12 @@ function emitContractTs(opts) {
|
|
|
7153
7180
|
if (paginationSignal) {
|
|
7154
7181
|
addExtendField("maxPages", " maxPages: z.number().int().positive().optional(),");
|
|
7155
7182
|
}
|
|
7156
|
-
// The base extend's own keys — submission flows only.
|
|
7157
|
-
if (
|
|
7183
|
+
// The base extend's own keys — job-application submission flows only.
|
|
7184
|
+
if (usesApplicantContactSchema) {
|
|
7158
7185
|
addExtendField("Email", " Email: z.email(),");
|
|
7159
7186
|
addExtendField("ClickUrl", " ClickUrl: z.string().min(1),");
|
|
7160
7187
|
addExtendField("Answers", " Answers: multipartJsonObject(z.record(z.string(), z.unknown())),");
|
|
7161
7188
|
}
|
|
7162
|
-
// ApplicantContactSchema's own merged identity/address/resume field names
|
|
7163
|
-
// (see src/lib/application-identity.ts, application-address.ts,
|
|
7164
|
-
// application-resume.ts, applicant-payload.ts) — reserved so no discovered/
|
|
7165
|
-
// spliced source can redeclare (and silently shadow) a field the base
|
|
7166
|
-
// ApplicantContactSchema already supplies. Only relevant for submission
|
|
7167
|
-
// flows, where basePayloadSchemaExpr actually is ApplicantContactSchema.
|
|
7168
|
-
const applicantContactFieldNames = new Set([
|
|
7169
|
-
"FirstName",
|
|
7170
|
-
"LastName",
|
|
7171
|
-
"Phone",
|
|
7172
|
-
"AddressLine",
|
|
7173
|
-
"City",
|
|
7174
|
-
"State",
|
|
7175
|
-
"PostalCode",
|
|
7176
|
-
"Country",
|
|
7177
|
-
"County",
|
|
7178
|
-
"Resume",
|
|
7179
|
-
"ResumeContentType",
|
|
7180
|
-
"ResumeFilename",
|
|
7181
|
-
"ResumeBase64",
|
|
7182
|
-
]);
|
|
7183
|
-
const isReservedByApplicantContactSchema = (name) => Boolean(inputBody) && applicantContactFieldNames.has(name);
|
|
7184
7189
|
// A declared foldReturn.drillParamBindings names drill query params that
|
|
7185
7190
|
// are caller-driven instead of frozen literals (see
|
|
7186
7191
|
// recon-generate-foldreturn-cannot-bind-drill-query-param-to-caller-payload.md)
|
|
@@ -7201,9 +7206,10 @@ function emitContractTs(opts) {
|
|
|
7201
7206
|
addExtendField(binding.payloadField, ` ${binding.payloadField}: ${zod},`);
|
|
7202
7207
|
}
|
|
7203
7208
|
// Multi-step flows that include a multipart upload need the binary asset
|
|
7204
|
-
// on the payload. A
|
|
7205
|
-
// needs these fields spelled
|
|
7206
|
-
|
|
7209
|
+
// on the payload. A non-applicant flow (no ApplicantContactSchema base,
|
|
7210
|
+
// whether or not a body was captured) still needs these fields spelled
|
|
7211
|
+
// out explicitly.
|
|
7212
|
+
if (hasMultipartStep && !usesApplicantContactSchema) {
|
|
7207
7213
|
addExtendField("Resume", " Resume: z.instanceof(Buffer),");
|
|
7208
7214
|
addExtendField("ResumeContentType", " ResumeContentType: z.string(),");
|
|
7209
7215
|
addExtendField("ResumeFilename", " ResumeFilename: z.string(),");
|
|
@@ -7345,9 +7351,8 @@ function emitContractTs(opts) {
|
|
|
7345
7351
|
// comment above) — a GraphQL mutation that happens to declare an
|
|
7346
7352
|
// unpopulated variable with a matching name (e.g. `$email`) must not
|
|
7347
7353
|
// downgrade that required base field.
|
|
7348
|
-
const baseContractFieldNames = new Set(["Email", "ClickUrl", "Answers"]);
|
|
7349
7354
|
for (const [fieldName, line] of extendFields) {
|
|
7350
|
-
if (
|
|
7355
|
+
if (usesApplicantContactSchema && baseContractFieldNames.has(fieldName))
|
|
7351
7356
|
continue;
|
|
7352
7357
|
if (unpopulatedDeclaredVariables.some((name) => name.toLowerCase() === fieldName.toLowerCase())) {
|
|
7353
7358
|
extendFields.set(fieldName, line.replace(/,\s*$/, ".optional(),"));
|
|
@@ -7356,23 +7361,25 @@ function emitContractTs(opts) {
|
|
|
7356
7361
|
const mergedExtension = extendFields.size > 0 ? `.extend({\n${[...extendFields.values()].join("\n")}\n})` : "";
|
|
7357
7362
|
const payloadSchemaExpr = `${basePayloadSchemaExpr}${mergedExtension}`;
|
|
7358
7363
|
// basePayloadSchemaExpr's own Answers field always wraps in
|
|
7359
|
-
// multipartJsonObject() for submission flows
|
|
7360
|
-
// multipartBoolean() is only imported when a
|
|
7361
|
-
// wrapped in it above (an additional-body-key
|
|
7362
|
-
// multipartCoerce) — payloadNeedsMultipart
|
|
7364
|
+
// multipartJsonObject() for job-application submission flows
|
|
7365
|
+
// (usesApplicantContactSchema); multipartBoolean() is only imported when a
|
|
7366
|
+
// boolean field was actually wrapped in it above (an additional-body-key
|
|
7367
|
+
// or an inputBody field under multipartCoerce) — payloadNeedsMultipart
|
|
7368
|
+
// alone doesn't imply that.
|
|
7363
7369
|
// Named imports from the same module are combined into one import statement.
|
|
7364
7370
|
const zodMultipartNamedImports = [
|
|
7365
7371
|
...(usesMultipartBoolean ? ["multipartBoolean"] : []),
|
|
7366
|
-
...(
|
|
7372
|
+
...(usesApplicantContactSchema || (payloadNeedsMultipart && sortedStructuredEntries.length > 0)
|
|
7367
7373
|
? ["multipartJsonObject"]
|
|
7368
7374
|
: []),
|
|
7369
7375
|
];
|
|
7370
7376
|
const multipartBoolImport = zodMultipartNamedImports.length > 0
|
|
7371
7377
|
? `import { ${zodMultipartNamedImports.join(", ")} } from "${ENGINE_PKG}/lib/zod-multipart";\n`
|
|
7372
7378
|
: "";
|
|
7373
|
-
// ApplicantContactSchema backs the
|
|
7374
|
-
// (see basePayloadSchemaExpr above); only referenced when
|
|
7375
|
-
|
|
7379
|
+
// ApplicantContactSchema backs the job-application submission-flow payload
|
|
7380
|
+
// schema (see basePayloadSchemaExpr above); only referenced when
|
|
7381
|
+
// usesApplicantContactSchema is true.
|
|
7382
|
+
const applicantContactImport = usesApplicantContactSchema
|
|
7376
7383
|
? `import { ApplicantContactSchema } from "${ENGINE_PKG}/lib/applicant-payload";\n`
|
|
7377
7384
|
: "";
|
|
7378
7385
|
// Content-Type must be absent from multipart fetch calls so FormData can inject the boundary.
|
|
@@ -7773,17 +7780,17 @@ export const ${camel}Plugin: SitePlugin<${pascal}Payload, ${pascal}Response> = {
|
|
|
7773
7780
|
bodySchema: ${pascal}PayloadSchema,
|
|
7774
7781
|
responseSchema: ${pascal}ResponseSchema,
|
|
7775
7782
|
defaultBaseUrl: ${JSON.stringify(baseUrl)},
|
|
7776
|
-
${payloadNeedsMultipart ||
|
|
7783
|
+
${payloadNeedsMultipart || usesApplicantContactSchema || hasMultipartStep
|
|
7777
7784
|
? `// multipart is required whenever the flow itself uploads a file
|
|
7778
|
-
// (hasMultipartStep), OR this is a submission flow
|
|
7779
|
-
// basePayloadSchemaExpr
|
|
7780
|
-
// ApplicantContactSchema regardless of whether
|
|
7781
|
-
// contained an upload step, OR the payload
|
|
7782
|
-
// discoveredStructuredKeys field (payloadNeedsMultipart),
|
|
7783
|
-
// multipart wire format is what makes that field's
|
|
7784
|
-
// encoding parseable.
|
|
7785
|
+
// (hasMultipartStep), OR this is a job-application submission flow
|
|
7786
|
+
// (usesApplicantContactSchema) since basePayloadSchemaExpr requires a
|
|
7787
|
+
// real Resume Buffer via ApplicantContactSchema regardless of whether
|
|
7788
|
+
// the recorded browser flow contained an upload step, OR the payload
|
|
7789
|
+
// has a non-scalar discoveredStructuredKeys field (payloadNeedsMultipart),
|
|
7790
|
+
// since the multipart wire format is what makes that field's
|
|
7791
|
+
// JSON-stringified encoding parseable.
|
|
7785
7792
|
`
|
|
7786
|
-
: ""}apiVersion: ${JSON.stringify(plugin_api_version_1.PLUGIN_API_VERSION)},${payloadNeedsMultipart ||
|
|
7793
|
+
: ""}apiVersion: ${JSON.stringify(plugin_api_version_1.PLUGIN_API_VERSION)},${payloadNeedsMultipart || usesApplicantContactSchema || hasMultipartStep ? "\n multipart: true," : ""}
|
|
7787
7794
|
},
|
|
7788
7795
|
${executeHttpMethodBlock}
|
|
7789
7796
|
/** Browser fallback: Stagehand + Steel — invoked only when hot path fails. */
|
|
@@ -7792,7 +7799,7 @@ ${executeHttpMethodBlock}
|
|
|
7792
7799
|
session: BrowserSession,
|
|
7793
7800
|
context: SitePluginContext
|
|
7794
7801
|
): Promise<SitePluginResult<${pascal}Response>> {
|
|
7795
|
-
const raw = await run${pascal}BrowserFlow(session.stagehand, ${
|
|
7802
|
+
const raw = await run${pascal}BrowserFlow(session.stagehand, ${usesApplicantContactSchema ? "payload.ClickUrl" : "context.baseUrl"}, payload, session.sessionProxy ?? null);
|
|
7796
7803
|
return { data: raw as ${pascal}Response };
|
|
7797
7804
|
},
|
|
7798
7805
|
};
|