@enricai/barnacle 1.6.2 → 1.6.4
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 +23 -18
- 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/errors.d.ts +1 -12
- package/dist/scraper/errors.d.ts.map +1 -1
- package/dist/scraper/errors.js +2 -16
- package/dist/scraper/errors.js.map +1 -1
- package/dist/scraper/flow-runner.d.ts +43 -27
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +70 -60
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/http-client.d.ts +25 -3
- package/dist/scraper/http-client.d.ts.map +1 -1
- package/dist/scraper/http-client.js +95 -4
- package/dist/scraper/http-client.js.map +1 -1
- package/dist/scraper/rate-limited-json-client.d.ts +1 -1
- package/dist/scraper/rate-limited-json-client.d.ts.map +1 -1
- 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-warmup.d.ts +1 -1
- package/dist/scraper/session-warmup.js +1 -1
- 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 +2 -2
- package/dist/scripts/recon-browser.js +14 -14
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate-multicall-fixture.d.ts +36 -0
- package/dist/scripts/recon-generate-multicall-fixture.d.ts.map +1 -0
- package/dist/scripts/recon-generate-multicall-fixture.js +102 -0
- package/dist/scripts/recon-generate-multicall-fixture.js.map +1 -0
- package/dist/scripts/recon-generate.d.ts +49 -0
- package/dist/scripts/recon-generate.d.ts.map +1 -1
- package/dist/scripts/recon-generate.js +129 -45
- package/dist/scripts/recon-generate.js.map +1 -1
- package/dist/scripts/recon-replay-jobs.d.ts +9 -4
- package/dist/scripts/recon-replay-jobs.d.ts.map +1 -1
- package/dist/scripts/recon-replay-jobs.js +15 -8
- package/dist/scripts/recon-replay-jobs.js.map +1 -1
- package/dist/scripts/recon-shared.d.ts +10 -0
- package/dist/scripts/recon-shared.d.ts.map +1 -1
- package/dist/scripts/recon-shared.js +25 -0
- package/dist/scripts/recon-shared.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
|
@@ -24,11 +24,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
24
24
|
exports.resolveStepPayloadField = resolveStepPayloadField;
|
|
25
25
|
exports.inferZodSchemaFromSamples = inferZodSchemaFromSamples;
|
|
26
26
|
exports.selectPayloadAction = selectPayloadAction;
|
|
27
|
+
exports.selectReturnAction = selectReturnAction;
|
|
28
|
+
exports.selectEffectiveResponseBody = selectEffectiveResponseBody;
|
|
27
29
|
exports.extractActionSequence = extractActionSequence;
|
|
28
30
|
exports.detectFormSchemaFieldNames = detectFormSchemaFieldNames;
|
|
29
31
|
exports.walkSetCookiePairs = walkSetCookiePairs;
|
|
30
32
|
exports.indexStateValues = indexStateValues;
|
|
31
33
|
exports.compileActionSteps = compileActionSteps;
|
|
34
|
+
exports.collectHeaderBindings = collectHeaderBindings;
|
|
32
35
|
exports.loadQuestionPromptKeywords = loadQuestionPromptKeywords;
|
|
33
36
|
exports.emitMultiStepExecuteHttp = emitMultiStepExecuteHttp;
|
|
34
37
|
exports.emitContractTs = emitContractTs;
|
|
@@ -270,6 +273,31 @@ function isVoidResponse(body) {
|
|
|
270
273
|
return body.length === 0;
|
|
271
274
|
return Object.keys(body).length === 0;
|
|
272
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Finds actions whose endpoint was re-hit with a varying, non-void body —
|
|
278
|
+
* the signature of a search/inventory endpoint the page queries repeatedly,
|
|
279
|
+
* as opposed to an endpoint that merely fired once or repeated an identical
|
|
280
|
+
* (retry) or void (chatter/beacon) call. Shared by `selectPayloadAction` and
|
|
281
|
+
* `selectReturnAction`, which each pick a different fallback when nothing
|
|
282
|
+
* was re-queried.
|
|
283
|
+
*/
|
|
284
|
+
function findRequeriedActions(steps) {
|
|
285
|
+
const bodiesByEndpoint = new Map();
|
|
286
|
+
for (const step of steps) {
|
|
287
|
+
const key = endpointKey(step.capture.url);
|
|
288
|
+
const bodies = bodiesByEndpoint.get(key) ?? new Set();
|
|
289
|
+
bodies.add(step.capture.requestPostData ?? "");
|
|
290
|
+
bodiesByEndpoint.set(key, bodies);
|
|
291
|
+
}
|
|
292
|
+
return steps.filter((step) => {
|
|
293
|
+
const bodies = bodiesByEndpoint.get(endpointKey(step.capture.url));
|
|
294
|
+
if (!bodies || bodies.size < 2)
|
|
295
|
+
return false;
|
|
296
|
+
// An endpoint re-hit with varying bodies but nothing to show for it is
|
|
297
|
+
// chatter — client-side error reporting, beacons — not the flow's subject.
|
|
298
|
+
return !isVoidResponse(step.capture.responseBody);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
273
301
|
/**
|
|
274
302
|
* Picks the action whose request body should define the payload schema.
|
|
275
303
|
*
|
|
@@ -291,23 +319,40 @@ function selectPayloadAction(steps) {
|
|
|
291
319
|
const first = steps[0];
|
|
292
320
|
if (!first)
|
|
293
321
|
return null;
|
|
294
|
-
const
|
|
295
|
-
for (const step of steps) {
|
|
296
|
-
const key = endpointKey(step.capture.url);
|
|
297
|
-
const bodies = bodiesByEndpoint.get(key) ?? new Set();
|
|
298
|
-
bodies.add(step.capture.requestPostData ?? "");
|
|
299
|
-
bodiesByEndpoint.set(key, bodies);
|
|
300
|
-
}
|
|
301
|
-
const requeried = steps.filter((step) => {
|
|
302
|
-
const bodies = bodiesByEndpoint.get(endpointKey(step.capture.url));
|
|
303
|
-
if (!bodies || bodies.size < 2)
|
|
304
|
-
return false;
|
|
305
|
-
// An endpoint re-hit with varying bodies but nothing to show for it is
|
|
306
|
-
// chatter — client-side error reporting, beacons — not the flow's subject.
|
|
307
|
-
return !isVoidResponse(step.capture.responseBody);
|
|
308
|
-
});
|
|
322
|
+
const requeried = findRequeriedActions(steps);
|
|
309
323
|
return requeried[0] ?? first;
|
|
310
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Picks the action whose response body `executeHttp` should return.
|
|
327
|
+
*
|
|
328
|
+
* Defaults to the last action, which is right for a transactional/submission
|
|
329
|
+
* flow: the final call is the terminal success signal the caller wants back.
|
|
330
|
+
* It is wrong when the flow is a read/search whose last call happens to be an
|
|
331
|
+
* incidental drill-down (e.g. previewing one result) rather than the search
|
|
332
|
+
* result itself — the same re-queried-endpoint signal `selectPayloadAction`
|
|
333
|
+
* uses to find the flow's subject applies here: an endpoint hit repeatedly
|
|
334
|
+
* with varying, non-void bodies is what the flow is about, and its most
|
|
335
|
+
* recent response is the freshest instance of that answer.
|
|
336
|
+
*/
|
|
337
|
+
function selectReturnAction(steps) {
|
|
338
|
+
const last = steps[steps.length - 1] ?? null;
|
|
339
|
+
if (!last)
|
|
340
|
+
return null;
|
|
341
|
+
const requeried = findRequeriedActions(steps);
|
|
342
|
+
return requeried[requeried.length - 1] ?? last;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Picks the response body used to infer the emitted contract's response
|
|
346
|
+
* shape. MUST target the same call `selectReturnAction` returns — a
|
|
347
|
+
* submission flow's `executeHttp` and its inferred type/schema have to agree
|
|
348
|
+
* on which call they describe, or the emitted type disagrees with the value
|
|
349
|
+
* actually returned. Falls back to the replay body for single-endpoint sites.
|
|
350
|
+
*/
|
|
351
|
+
function selectEffectiveResponseBody(isSubmissionFlow, actionSteps, replayResponseBody) {
|
|
352
|
+
if (!isSubmissionFlow)
|
|
353
|
+
return replayResponseBody;
|
|
354
|
+
return selectReturnAction(actionSteps)?.capture.responseBody ?? replayResponseBody;
|
|
355
|
+
}
|
|
311
356
|
function deriveBaseUrl(captures) {
|
|
312
357
|
for (const c of captures) {
|
|
313
358
|
try {
|
|
@@ -1365,21 +1410,36 @@ function compileActionSteps(actions, stateIndex) {
|
|
|
1365
1410
|
* step order — this is what `emitContractTs` renders as `createHttpClient`'s
|
|
1366
1411
|
* `bind` option so the generated `executeHttp` actually forwards a value like
|
|
1367
1412
|
* disneycruise's `Set-Cookie: __pa=<jwt>` mint to the stateful call that 401s
|
|
1368
|
-
* without it. Deduped by `targetHeader
|
|
1369
|
-
*
|
|
1370
|
-
*
|
|
1413
|
+
* without it. Deduped by `targetHeader.toLowerCase()` + `cookieName` (HTTP
|
|
1414
|
+
* header names are case-insensitive, and compileActionSteps derives
|
|
1415
|
+
* `targetHeader` verbatim from observed request-header casing, so the same
|
|
1416
|
+
* logical target can show up as e.g. `Cookie` on one step and `cookie` on
|
|
1417
|
+
* another): the `Cookie` request header carries many cookies by design, so
|
|
1418
|
+
* every distinct cookie-origin produce targeting it must survive (the
|
|
1419
|
+
* runtime accumulates them into one `Cookie` header per binding — see
|
|
1420
|
+
* http-client.ts); only a produce that re-mints the SAME cookie on a later
|
|
1421
|
+
* step collapses to its earliest occurrence. Non-cookie targets (e.g.
|
|
1422
|
+
* `X-Conversation-Id`) still keep first-wins, since `HttpResponseBinding` is
|
|
1423
|
+
* one binding per target header there and two steps producing the same
|
|
1424
|
+
* non-cookie target (even under differing casing) would otherwise race with
|
|
1425
|
+
* no defined winner.
|
|
1426
|
+
*
|
|
1427
|
+
* Exported for unit testing (as `walkSetCookiePairs` is) — lets tests exercise
|
|
1428
|
+
* the produce → bind collection step directly against synthetic ActionStep
|
|
1429
|
+
* sequences.
|
|
1371
1430
|
*/
|
|
1372
1431
|
function collectHeaderBindings(actionSteps) {
|
|
1373
|
-
const
|
|
1432
|
+
const byKey = new Map();
|
|
1374
1433
|
for (const step of actionSteps) {
|
|
1375
1434
|
for (const p of step.produces) {
|
|
1376
1435
|
if (p.kind !== "header")
|
|
1377
1436
|
continue;
|
|
1378
|
-
|
|
1379
|
-
|
|
1437
|
+
const key = `${p.targetHeader.toLowerCase()}\0${p.cookieName ?? ""}`;
|
|
1438
|
+
if (!byKey.has(key))
|
|
1439
|
+
byKey.set(key, p);
|
|
1380
1440
|
}
|
|
1381
1441
|
}
|
|
1382
|
-
return [...
|
|
1442
|
+
return [...byKey.values()];
|
|
1383
1443
|
}
|
|
1384
1444
|
/**
|
|
1385
1445
|
* Replaces occurrences of state values in `template` with `${varName}`
|
|
@@ -1859,7 +1919,14 @@ function emitMultiStepExecuteHttp(actions, inputBody, errorSignals, fieldNameMap
|
|
|
1859
1919
|
.join(", ")} },`
|
|
1860
1920
|
: "";
|
|
1861
1921
|
const bodyArg = bodyTemplate ? `body: \`${bodyTemplate}\`,` : "";
|
|
1862
|
-
|
|
1922
|
+
// G2: each call gets its own schema, inferred from this step's captured
|
|
1923
|
+
// response — the client-level schema (z.unknown() for multi-step flows,
|
|
1924
|
+
// see emitContractTs) stays the plugin's caller-facing contract, not what
|
|
1925
|
+
// validates any individual call. Without this override, HttpRequestInit.schema
|
|
1926
|
+
// would default to the client's z.unknown() and narrowing the caller-facing
|
|
1927
|
+
// contract would enforce that narrowed shape on every call in the chain.
|
|
1928
|
+
const schemaExpr = inferZodSchema(cap.responseBody);
|
|
1929
|
+
rendered.push({ url, method: cap.method, headersExpr, bodyArg, schemaExpr });
|
|
1863
1930
|
}
|
|
1864
1931
|
// Identifier scan against the rendered text — captures `${foo}`, `${foo.bar}`,
|
|
1865
1932
|
// etc. The first segment (anchored at `${`) is the binding's name. Closed
|
|
@@ -1879,9 +1946,11 @@ function emitMultiStepExecuteHttp(actions, inputBody, errorSignals, fieldNameMap
|
|
|
1879
1946
|
}
|
|
1880
1947
|
}
|
|
1881
1948
|
}
|
|
1882
|
-
// The
|
|
1883
|
-
|
|
1884
|
-
|
|
1949
|
+
// The relevance-selected step's var is also referenced by the closing
|
|
1950
|
+
// `return { data }` — see selectReturnAction.
|
|
1951
|
+
const returnAction = selectReturnAction(actions);
|
|
1952
|
+
if (returnAction)
|
|
1953
|
+
referencedNames.add(returnAction.varName);
|
|
1885
1954
|
// Base64 Content overrides reference variables inside function calls
|
|
1886
1955
|
// (e.g. buildBase64Content(payload, questionnaireId, ...)) that the
|
|
1887
1956
|
// ${name} regex above doesn't capture. Add them explicitly.
|
|
@@ -1981,6 +2050,7 @@ function emitMultiStepExecuteHttp(actions, inputBody, errorSignals, fieldNameMap
|
|
|
1981
2050
|
if (joined !== "") {
|
|
1982
2051
|
lines.push(` ${joined}`);
|
|
1983
2052
|
}
|
|
2053
|
+
lines.push(` schema: ${r.schemaExpr},`);
|
|
1984
2054
|
if (needsBinding) {
|
|
1985
2055
|
lines.push(` })) as Record<string, unknown>;`);
|
|
1986
2056
|
}
|
|
@@ -2010,8 +2080,8 @@ function emitMultiStepExecuteHttp(actions, inputBody, errorSignals, fieldNameMap
|
|
|
2010
2080
|
}
|
|
2011
2081
|
lines.push("");
|
|
2012
2082
|
}
|
|
2013
|
-
const
|
|
2014
|
-
lines.push(` return { data: ${
|
|
2083
|
+
const returnVar = returnAction ? returnAction.varName : "undefined";
|
|
2084
|
+
lines.push(` return { data: ${returnVar} };`);
|
|
2015
2085
|
return lines.join("\n");
|
|
2016
2086
|
}
|
|
2017
2087
|
function summariseResponseShape(value) {
|
|
@@ -2049,16 +2119,25 @@ function bindOptionLiteral(headerBindings) {
|
|
|
2049
2119
|
* unit tests can drive the emitter directly without spawning the CLI. */
|
|
2050
2120
|
function emitContractTs(opts) {
|
|
2051
2121
|
const { siteId, pascal, baseUrl, baseHeaders, minTime, safeRps, responseBody, gql, gqlQuery, endpointPath, auxFiles, multiStepBody, inputBody, hasMultipartStep = false, discoveredFormFields, fieldOptionsMap, discoveredOptionFields, discoveredRawOptionFields, discoveredAdditionalBodyKeys, payloadFieldNames, base64ContentHelper = "", headerBindings = [], } = opts;
|
|
2052
|
-
//
|
|
2053
|
-
//
|
|
2054
|
-
//
|
|
2122
|
+
// This is the CLIENT-level schema — createHttpClient's default, and the
|
|
2123
|
+
// plugin's caller-facing contract (what executeHttp's return value promises
|
|
2124
|
+
// its own caller). It does NOT validate any individual call in a multi-step
|
|
2125
|
+
// flow: emitMultiStepExecuteHttp threads a per-call `schema:` override
|
|
2126
|
+
// (inferred from that step's own capture) onto every httpClient(...)
|
|
2127
|
+
// invocation, so heterogeneous per-call shapes are each checked against
|
|
2128
|
+
// their own inferred schema regardless of what this client-level schema is.
|
|
2055
2129
|
//
|
|
2056
|
-
//
|
|
2057
|
-
// shape is the plugin's OWN contract with its
|
|
2058
|
-
// a field that appears in zero
|
|
2059
|
-
//
|
|
2060
|
-
//
|
|
2061
|
-
//
|
|
2130
|
+
// For multi-step flows this stays z.unknown(), not an unfinished schema: a
|
|
2131
|
+
// submission flow's terminal shape is the plugin's OWN contract with its
|
|
2132
|
+
// caller (e.g. { verified: boolean }), a field that appears in zero
|
|
2133
|
+
// captured responses. Inferring a schema from the captures would emit the
|
|
2134
|
+
// wrong shape with false confidence. z.unknown() plus the generated
|
|
2135
|
+
// `[ ] Narrow ResponseSchema` checklist item is the intended hand-off to
|
|
2136
|
+
// the plugin author, who alone knows that contract — narrowing it only
|
|
2137
|
+
// changes what executeHttp promises its caller, and is now safe to do
|
|
2138
|
+
// without affecting per-call validation. Single-endpoint plugins keep the
|
|
2139
|
+
// inferred schema, since there both roles (client default and sole call)
|
|
2140
|
+
// coincide.
|
|
2062
2141
|
const responseSchemaExpr = multiStepBody ? `z.unknown()` : inferZodSchema(responseBody);
|
|
2063
2142
|
// Multi-step flows that include a multipart upload need the binary asset
|
|
2064
2143
|
// on the payload. Add Resume/ResumeContentType/ResumeFilename as required
|
|
@@ -2235,12 +2314,20 @@ const httpClient = createHttpClient({ schema: ${pascal}ResponseSchema, bottlenec
|
|
|
2235
2314
|
const queryChecklistLine = gql
|
|
2236
2315
|
? `\n * [ ] Trim UI-only fields from ${pascal.toUpperCase()}_QUERY (keep only fields you need)`
|
|
2237
2316
|
: "";
|
|
2317
|
+
// Multi-step flows validate each call against its own per-call inferred
|
|
2318
|
+
// schema (emitMultiStepExecuteHttp) — narrowing ResponseSchema only changes
|
|
2319
|
+
// what executeHttp promises ITS OWN caller, never a per-call validator, so
|
|
2320
|
+
// the checklist item must say that explicitly. Single-endpoint plugins have
|
|
2321
|
+
// exactly one call, so the client schema and that call's validator are the
|
|
2322
|
+
// same schema and the shorter wording stays accurate.
|
|
2323
|
+
const narrowSchemaChecklistLine = multiStepBody
|
|
2324
|
+
? `\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)`
|
|
2325
|
+
: `\n * [ ] Narrow ${pascal}ResponseSchema to match the real response shape`;
|
|
2238
2326
|
const camel = siteId.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
2239
2327
|
return `/**
|
|
2240
2328
|
* Generated by recon-generate.ts — review before shipping.
|
|
2241
2329
|
*
|
|
2242
|
-
* Checklist:${queryChecklistLine}
|
|
2243
|
-
* [ ] Narrow ${pascal}ResponseSchema to match the real response shape
|
|
2330
|
+
* Checklist:${queryChecklistLine}${narrowSchemaChecklistLine}
|
|
2244
2331
|
* [ ] Adjust ${pascal}PayloadSchema to your actual request parameters
|
|
2245
2332
|
* [ ] Verify BASE_HEADERS — remove any that aren't load-bearing
|
|
2246
2333
|
* [ ] Out-of-tree: \`pnpm add bottleneck zod\` — this file imports both
|
|
@@ -2970,12 +3057,9 @@ async function main() {
|
|
|
2970
3057
|
: multiStepBody;
|
|
2971
3058
|
const hasMultipartStep = actionSteps.some((s) => s.isMultipart);
|
|
2972
3059
|
const headerBindings = collectHeaderBindings(actionSteps);
|
|
2973
|
-
//
|
|
2974
|
-
//
|
|
2975
|
-
|
|
2976
|
-
const effectiveResponseBody = isSubmissionFlow
|
|
2977
|
-
? (actionSteps[actionSteps.length - 1].capture.responseBody ?? responseBody)
|
|
2978
|
-
: responseBody;
|
|
3060
|
+
// Shape inference targets the SAME call executeHttp returns — see
|
|
3061
|
+
// selectEffectiveResponseBody — so the two surfaces can't describe different calls.
|
|
3062
|
+
const effectiveResponseBody = selectEffectiveResponseBody(isSubmissionFlow, actionSteps, responseBody);
|
|
2979
3063
|
logger.info(`generating plugin for ${siteId} (${gql ? "GraphQL" : isSubmissionFlow ? `submission flow, ${actionSteps.length} steps` : "single-endpoint REST"}, baseUrl: ${baseUrl})`);
|
|
2980
3064
|
if (emit === "config") {
|
|
2981
3065
|
(0, node_fs_1.mkdirSync)(outDir, { recursive: true });
|