@camstack/types 1.2.436 → 1.2.437
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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.2.437] - 2026-10-28
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- The vendor sign-in proxy keeps the vendor's session cookie when the vendor also deletes a same-named cookie on another domain
|
|
15
|
+
- An AI profile can turn the model's thinking off or set its effort
|
|
16
|
+
|
|
10
17
|
## [1.2.436] - 2026-10-28
|
|
11
18
|
|
|
12
19
|
### Changed
|
|
@@ -63,6 +63,12 @@ export declare const LlmProfileSchema: z.ZodObject<{
|
|
|
63
63
|
topP: z.ZodOptional<z.ZodNumber>;
|
|
64
64
|
topK: z.ZodOptional<z.ZodNumber>;
|
|
65
65
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
66
|
+
reasoningEffort: z.ZodOptional<z.ZodEnum<{
|
|
67
|
+
high: "high";
|
|
68
|
+
low: "low";
|
|
69
|
+
medium: "medium";
|
|
70
|
+
off: "off";
|
|
71
|
+
}>>;
|
|
66
72
|
contextLength: z.ZodOptional<z.ZodNumber>;
|
|
67
73
|
systemPrompt: z.ZodOptional<z.ZodString>;
|
|
68
74
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
@@ -87,6 +93,7 @@ export declare const LlmProfileFieldSchema: z.ZodEnum<{
|
|
|
87
93
|
firstTokenTimeoutMs: "firstTokenTimeoutMs";
|
|
88
94
|
idleTimeoutMs: "idleTimeoutMs";
|
|
89
95
|
maxTokens: "maxTokens";
|
|
96
|
+
reasoningEffort: "reasoningEffort";
|
|
90
97
|
retry: "retry";
|
|
91
98
|
systemPrompt: "systemPrompt";
|
|
92
99
|
temperature: "temperature";
|
|
@@ -144,6 +151,7 @@ export declare const LlmProfileKindDescriptorSchema: z.ZodObject<{
|
|
|
144
151
|
firstTokenTimeoutMs: "firstTokenTimeoutMs";
|
|
145
152
|
idleTimeoutMs: "idleTimeoutMs";
|
|
146
153
|
maxTokens: "maxTokens";
|
|
154
|
+
reasoningEffort: "reasoningEffort";
|
|
147
155
|
retry: "retry";
|
|
148
156
|
systemPrompt: "systemPrompt";
|
|
149
157
|
temperature: "temperature";
|
|
@@ -527,6 +535,7 @@ export declare const llmCapability: {
|
|
|
527
535
|
firstTokenTimeoutMs: "firstTokenTimeoutMs";
|
|
528
536
|
idleTimeoutMs: "idleTimeoutMs";
|
|
529
537
|
maxTokens: "maxTokens";
|
|
538
|
+
reasoningEffort: "reasoningEffort";
|
|
530
539
|
retry: "retry";
|
|
531
540
|
systemPrompt: "systemPrompt";
|
|
532
541
|
temperature: "temperature";
|
|
@@ -556,6 +565,12 @@ export declare const llmCapability: {
|
|
|
556
565
|
topP: z.ZodOptional<z.ZodNumber>;
|
|
557
566
|
topK: z.ZodOptional<z.ZodNumber>;
|
|
558
567
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
568
|
+
reasoningEffort: z.ZodOptional<z.ZodEnum<{
|
|
569
|
+
high: "high";
|
|
570
|
+
low: "low";
|
|
571
|
+
medium: "medium";
|
|
572
|
+
off: "off";
|
|
573
|
+
}>>;
|
|
559
574
|
contextLength: z.ZodOptional<z.ZodNumber>;
|
|
560
575
|
systemPrompt: z.ZodOptional<z.ZodString>;
|
|
561
576
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
@@ -582,6 +597,12 @@ export declare const llmCapability: {
|
|
|
582
597
|
topP: z.ZodOptional<z.ZodNumber>;
|
|
583
598
|
topK: z.ZodOptional<z.ZodNumber>;
|
|
584
599
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
600
|
+
reasoningEffort: z.ZodOptional<z.ZodEnum<{
|
|
601
|
+
high: "high";
|
|
602
|
+
low: "low";
|
|
603
|
+
medium: "medium";
|
|
604
|
+
off: "off";
|
|
605
|
+
}>>;
|
|
585
606
|
contextLength: z.ZodOptional<z.ZodNumber>;
|
|
586
607
|
systemPrompt: z.ZodOptional<z.ZodString>;
|
|
587
608
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
@@ -607,6 +628,12 @@ export declare const llmCapability: {
|
|
|
607
628
|
topP: z.ZodOptional<z.ZodNumber>;
|
|
608
629
|
topK: z.ZodOptional<z.ZodNumber>;
|
|
609
630
|
maxTokens: z.ZodOptional<z.ZodNumber>;
|
|
631
|
+
reasoningEffort: z.ZodOptional<z.ZodEnum<{
|
|
632
|
+
high: "high";
|
|
633
|
+
low: "low";
|
|
634
|
+
medium: "medium";
|
|
635
|
+
off: "off";
|
|
636
|
+
}>>;
|
|
610
637
|
contextLength: z.ZodOptional<z.ZodNumber>;
|
|
611
638
|
systemPrompt: z.ZodOptional<z.ZodString>;
|
|
612
639
|
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
package/dist/index.js
CHANGED
|
@@ -44650,6 +44650,17 @@ var LlmProfileSchema = zod.z.object({
|
|
|
44650
44650
|
* field in its editor only when its descriptor lists it in `profileFields`. */
|
|
44651
44651
|
topK: zod.z.number().int().positive().optional(),
|
|
44652
44652
|
maxTokens: zod.z.number().int().positive().optional(),
|
|
44653
|
+
/** How hard the model "thinks" before it answers. Omitted = the model's own
|
|
44654
|
+
* default. `off` matters for structured output: a thinking model can spend
|
|
44655
|
+
* the whole completion on reasoning and return an empty `content`. Carried
|
|
44656
|
+
* only by the wires that have it — a kind offers the field in its editor
|
|
44657
|
+
* only when its descriptor lists it in `profileFields`. */
|
|
44658
|
+
reasoningEffort: zod.z.enum([
|
|
44659
|
+
"off",
|
|
44660
|
+
"low",
|
|
44661
|
+
"medium",
|
|
44662
|
+
"high"
|
|
44663
|
+
]).optional(),
|
|
44653
44664
|
/** Prompt context window. Advisory for cloud kinds (they enforce their own). */
|
|
44654
44665
|
contextLength: zod.z.number().int().positive().optional(),
|
|
44655
44666
|
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
@@ -44688,6 +44699,7 @@ var LlmProfileFieldSchema = zod.z.enum([
|
|
|
44688
44699
|
"topP",
|
|
44689
44700
|
"topK",
|
|
44690
44701
|
"maxTokens",
|
|
44702
|
+
"reasoningEffort",
|
|
44691
44703
|
"contextLength",
|
|
44692
44704
|
"systemPrompt",
|
|
44693
44705
|
"timeoutMs",
|
|
@@ -118280,6 +118292,29 @@ function rewriteSetCookie(cookie, route) {
|
|
|
118280
118292
|
return kept.join("; ");
|
|
118281
118293
|
}
|
|
118282
118294
|
/**
|
|
118295
|
+
* Every Set-Cookie of one vendor response, rewritten. Dropping `Domain` folds cookies
|
|
118296
|
+
* the vendor keeps apart (`session-id` on `.amazon.it` and on `.www.amazon.it`) into
|
|
118297
|
+
* one, so a past-dated set that only deleted the other domain's copy would delete the
|
|
118298
|
+
* live one the same response just set: that deletion is dropped.
|
|
118299
|
+
*/
|
|
118300
|
+
function rewriteSetCookies(cookies, route) {
|
|
118301
|
+
const now = Date.now();
|
|
118302
|
+
const liveNames = new Set(cookies.filter((c) => !isExpiredCookie(c, now)).map(cookieName));
|
|
118303
|
+
return cookies.filter((c) => !(isExpiredCookie(c, now) && liveNames.has(cookieName(c)))).map((c) => rewriteSetCookie(c, route));
|
|
118304
|
+
}
|
|
118305
|
+
function cookieName(cookie) {
|
|
118306
|
+
return cookie.split(";")[0]?.split("=")[0]?.trim() ?? "";
|
|
118307
|
+
}
|
|
118308
|
+
function isExpiredCookie(cookie, now) {
|
|
118309
|
+
const attrs = cookie.split(";").slice(1).map((part) => part.trim());
|
|
118310
|
+
const maxAge = attrs.find((a) => /^max-age=/i.test(a));
|
|
118311
|
+
if (maxAge !== void 0) return Number(maxAge.slice(8)) <= 0;
|
|
118312
|
+
const expires = attrs.find((a) => /^expires=/i.test(a));
|
|
118313
|
+
if (expires === void 0) return false;
|
|
118314
|
+
const at = Date.parse(expires.slice(8));
|
|
118315
|
+
return Number.isFinite(at) && at <= now;
|
|
118316
|
+
}
|
|
118317
|
+
/**
|
|
118283
118318
|
* A browser `Referer` that points into this proxy, turned back into the vendor URL it
|
|
118284
118319
|
* stands for. A Referer that is not ours is dropped (null): it names the hub.
|
|
118285
118320
|
*/
|
|
@@ -118398,6 +118433,26 @@ async function readRequestBody(req) {
|
|
|
118398
118433
|
}
|
|
118399
118434
|
return Buffer.concat(chunks);
|
|
118400
118435
|
}
|
|
118436
|
+
/** The path of the Referer sent upstream, or why none was sent — the query is never logged. */
|
|
118437
|
+
function forwardedRefererPath(forwarded, received) {
|
|
118438
|
+
if (forwarded !== void 0) return URL.canParse(forwarded) ? new URL(forwarded).pathname : "unparsable";
|
|
118439
|
+
return received === void 0 ? "absent" : "unmapped";
|
|
118440
|
+
}
|
|
118441
|
+
/** The form targets a vendor page posts to, path only (no query), so a lost path prefix is visible. */
|
|
118442
|
+
function formActionPaths(html) {
|
|
118443
|
+
const actions = [...html.matchAll(/<form\b[^>]*\baction\s*=\s*["']([^"']*)["']/gi)].map((m) => (m[1] ?? "").split("?")[0] ?? "").slice(0, 5);
|
|
118444
|
+
return actions.length === 0 ? "none" : actions.join(" | ");
|
|
118445
|
+
}
|
|
118446
|
+
/** Cookie NAMES only — values are session secrets and are never logged. */
|
|
118447
|
+
function cookieNames(header) {
|
|
118448
|
+
if (header === void 0 || header.length === 0) return "none";
|
|
118449
|
+
return header.split(";").map((part) => part.split("=")[0]?.trim() ?? "").join(",");
|
|
118450
|
+
}
|
|
118451
|
+
/** A Set-Cookie's name and attributes without its value, so a cookie the browser refuses is visible. */
|
|
118452
|
+
function setCookieShape(cookie) {
|
|
118453
|
+
const [first, ...attrs] = cookie.split(";").map((part) => part.trim());
|
|
118454
|
+
return [first?.split("=")[0] ?? "", ...attrs.filter((a) => !/^expires=/i.test(a))].join(";");
|
|
118455
|
+
}
|
|
118401
118456
|
function sendPlain(res, status, text) {
|
|
118402
118457
|
res.writeHead(status, {
|
|
118403
118458
|
"content-type": "text/plain; charset=utf-8",
|
|
@@ -118533,7 +118588,11 @@ var VendorLoginProxy = class {
|
|
|
118533
118588
|
host: upstream.host,
|
|
118534
118589
|
path: target.pathname,
|
|
118535
118590
|
status: upstreamRes.status,
|
|
118536
|
-
method
|
|
118591
|
+
method,
|
|
118592
|
+
refererPath: forwardedRefererPath(headers["referer"], req.headers["referer"]),
|
|
118593
|
+
formActions: kind === "html" && text !== null ? formActionPaths(text) : void 0,
|
|
118594
|
+
sentNames: cookieNames(headers["cookie"]),
|
|
118595
|
+
vendorSets: setCookies.map(setCookieShape).join(" | ")
|
|
118537
118596
|
} });
|
|
118538
118597
|
const settled = await attempt.evaluate({
|
|
118539
118598
|
status: upstreamRes.status,
|
|
@@ -118555,7 +118614,7 @@ var VendorLoginProxy = class {
|
|
|
118555
118614
|
upstreamRes.headers.forEach((value, name) => {
|
|
118556
118615
|
if (!DROP_RESPONSE_HEADERS.has(name.toLowerCase())) out[name] = value;
|
|
118557
118616
|
});
|
|
118558
|
-
if (setCookies.length > 0) out["set-cookie"] = setCookies
|
|
118617
|
+
if (setCookies.length > 0) out["set-cookie"] = rewriteSetCookies(setCookies, route);
|
|
118559
118618
|
if (location !== null) out["location"] = rewriteLocation(location, upstream, route);
|
|
118560
118619
|
out["cache-control"] = "no-store";
|
|
118561
118620
|
if (text !== null && kind !== null) {
|
package/dist/index.mjs
CHANGED
|
@@ -44649,6 +44649,17 @@ var LlmProfileSchema = z.object({
|
|
|
44649
44649
|
* field in its editor only when its descriptor lists it in `profileFields`. */
|
|
44650
44650
|
topK: z.number().int().positive().optional(),
|
|
44651
44651
|
maxTokens: z.number().int().positive().optional(),
|
|
44652
|
+
/** How hard the model "thinks" before it answers. Omitted = the model's own
|
|
44653
|
+
* default. `off` matters for structured output: a thinking model can spend
|
|
44654
|
+
* the whole completion on reasoning and return an empty `content`. Carried
|
|
44655
|
+
* only by the wires that have it — a kind offers the field in its editor
|
|
44656
|
+
* only when its descriptor lists it in `profileFields`. */
|
|
44657
|
+
reasoningEffort: z.enum([
|
|
44658
|
+
"off",
|
|
44659
|
+
"low",
|
|
44660
|
+
"medium",
|
|
44661
|
+
"high"
|
|
44662
|
+
]).optional(),
|
|
44652
44663
|
/** Prompt context window. Advisory for cloud kinds (they enforce their own). */
|
|
44653
44664
|
contextLength: z.number().int().positive().optional(),
|
|
44654
44665
|
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
@@ -44687,6 +44698,7 @@ var LlmProfileFieldSchema = z.enum([
|
|
|
44687
44698
|
"topP",
|
|
44688
44699
|
"topK",
|
|
44689
44700
|
"maxTokens",
|
|
44701
|
+
"reasoningEffort",
|
|
44690
44702
|
"contextLength",
|
|
44691
44703
|
"systemPrompt",
|
|
44692
44704
|
"timeoutMs",
|
|
@@ -118279,6 +118291,29 @@ function rewriteSetCookie(cookie, route) {
|
|
|
118279
118291
|
return kept.join("; ");
|
|
118280
118292
|
}
|
|
118281
118293
|
/**
|
|
118294
|
+
* Every Set-Cookie of one vendor response, rewritten. Dropping `Domain` folds cookies
|
|
118295
|
+
* the vendor keeps apart (`session-id` on `.amazon.it` and on `.www.amazon.it`) into
|
|
118296
|
+
* one, so a past-dated set that only deleted the other domain's copy would delete the
|
|
118297
|
+
* live one the same response just set: that deletion is dropped.
|
|
118298
|
+
*/
|
|
118299
|
+
function rewriteSetCookies(cookies, route) {
|
|
118300
|
+
const now = Date.now();
|
|
118301
|
+
const liveNames = new Set(cookies.filter((c) => !isExpiredCookie(c, now)).map(cookieName));
|
|
118302
|
+
return cookies.filter((c) => !(isExpiredCookie(c, now) && liveNames.has(cookieName(c)))).map((c) => rewriteSetCookie(c, route));
|
|
118303
|
+
}
|
|
118304
|
+
function cookieName(cookie) {
|
|
118305
|
+
return cookie.split(";")[0]?.split("=")[0]?.trim() ?? "";
|
|
118306
|
+
}
|
|
118307
|
+
function isExpiredCookie(cookie, now) {
|
|
118308
|
+
const attrs = cookie.split(";").slice(1).map((part) => part.trim());
|
|
118309
|
+
const maxAge = attrs.find((a) => /^max-age=/i.test(a));
|
|
118310
|
+
if (maxAge !== void 0) return Number(maxAge.slice(8)) <= 0;
|
|
118311
|
+
const expires = attrs.find((a) => /^expires=/i.test(a));
|
|
118312
|
+
if (expires === void 0) return false;
|
|
118313
|
+
const at = Date.parse(expires.slice(8));
|
|
118314
|
+
return Number.isFinite(at) && at <= now;
|
|
118315
|
+
}
|
|
118316
|
+
/**
|
|
118282
118317
|
* A browser `Referer` that points into this proxy, turned back into the vendor URL it
|
|
118283
118318
|
* stands for. A Referer that is not ours is dropped (null): it names the hub.
|
|
118284
118319
|
*/
|
|
@@ -118397,6 +118432,26 @@ async function readRequestBody(req) {
|
|
|
118397
118432
|
}
|
|
118398
118433
|
return Buffer.concat(chunks);
|
|
118399
118434
|
}
|
|
118435
|
+
/** The path of the Referer sent upstream, or why none was sent — the query is never logged. */
|
|
118436
|
+
function forwardedRefererPath(forwarded, received) {
|
|
118437
|
+
if (forwarded !== void 0) return URL.canParse(forwarded) ? new URL(forwarded).pathname : "unparsable";
|
|
118438
|
+
return received === void 0 ? "absent" : "unmapped";
|
|
118439
|
+
}
|
|
118440
|
+
/** The form targets a vendor page posts to, path only (no query), so a lost path prefix is visible. */
|
|
118441
|
+
function formActionPaths(html) {
|
|
118442
|
+
const actions = [...html.matchAll(/<form\b[^>]*\baction\s*=\s*["']([^"']*)["']/gi)].map((m) => (m[1] ?? "").split("?")[0] ?? "").slice(0, 5);
|
|
118443
|
+
return actions.length === 0 ? "none" : actions.join(" | ");
|
|
118444
|
+
}
|
|
118445
|
+
/** Cookie NAMES only — values are session secrets and are never logged. */
|
|
118446
|
+
function cookieNames(header) {
|
|
118447
|
+
if (header === void 0 || header.length === 0) return "none";
|
|
118448
|
+
return header.split(";").map((part) => part.split("=")[0]?.trim() ?? "").join(",");
|
|
118449
|
+
}
|
|
118450
|
+
/** A Set-Cookie's name and attributes without its value, so a cookie the browser refuses is visible. */
|
|
118451
|
+
function setCookieShape(cookie) {
|
|
118452
|
+
const [first, ...attrs] = cookie.split(";").map((part) => part.trim());
|
|
118453
|
+
return [first?.split("=")[0] ?? "", ...attrs.filter((a) => !/^expires=/i.test(a))].join(";");
|
|
118454
|
+
}
|
|
118400
118455
|
function sendPlain(res, status, text) {
|
|
118401
118456
|
res.writeHead(status, {
|
|
118402
118457
|
"content-type": "text/plain; charset=utf-8",
|
|
@@ -118532,7 +118587,11 @@ var VendorLoginProxy = class {
|
|
|
118532
118587
|
host: upstream.host,
|
|
118533
118588
|
path: target.pathname,
|
|
118534
118589
|
status: upstreamRes.status,
|
|
118535
|
-
method
|
|
118590
|
+
method,
|
|
118591
|
+
refererPath: forwardedRefererPath(headers["referer"], req.headers["referer"]),
|
|
118592
|
+
formActions: kind === "html" && text !== null ? formActionPaths(text) : void 0,
|
|
118593
|
+
sentNames: cookieNames(headers["cookie"]),
|
|
118594
|
+
vendorSets: setCookies.map(setCookieShape).join(" | ")
|
|
118536
118595
|
} });
|
|
118537
118596
|
const settled = await attempt.evaluate({
|
|
118538
118597
|
status: upstreamRes.status,
|
|
@@ -118554,7 +118613,7 @@ var VendorLoginProxy = class {
|
|
|
118554
118613
|
upstreamRes.headers.forEach((value, name) => {
|
|
118555
118614
|
if (!DROP_RESPONSE_HEADERS.has(name.toLowerCase())) out[name] = value;
|
|
118556
118615
|
});
|
|
118557
|
-
if (setCookies.length > 0) out["set-cookie"] = setCookies
|
|
118616
|
+
if (setCookies.length > 0) out["set-cookie"] = rewriteSetCookies(setCookies, route);
|
|
118558
118617
|
if (location !== null) out["location"] = rewriteLocation(location, upstream, route);
|
|
118559
118618
|
out["cache-control"] = "no-store";
|
|
118560
118619
|
if (text !== null && kind !== null) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { VendorLoginProxy, type LoginProxyAttemptSpec, type LoginProxyResponseView, type LoginProxyVerdict, type VendorLoginProxyOptions, } from './login-proxy.js';
|
|
2
|
-
export { rewriteBody, rewriteLocation, rewriteReferer, rewriteFormBody, rewriteSetCookie, type LoginProxyRoute, type LoginProxyScheme, type LoginProxyUpstream, } from './url-rewrite.js';
|
|
2
|
+
export { rewriteBody, rewriteLocation, rewriteReferer, rewriteFormBody, rewriteSetCookie, rewriteSetCookies, type LoginProxyRoute, type LoginProxyScheme, type LoginProxyUpstream, } from './url-rewrite.js';
|
|
3
3
|
export { VENDOR_LOGIN_PROXY_PREFIX } from './prefix.js';
|
|
@@ -59,6 +59,13 @@ export declare function rewriteBody(body: string, kind: BodyKind, currentUpstrea
|
|
|
59
59
|
* origin), `Path` narrowed to this attempt's prefix, `Secure` kept (the hub is HTTPS).
|
|
60
60
|
*/
|
|
61
61
|
export declare function rewriteSetCookie(cookie: string, route: LoginProxyRoute): string;
|
|
62
|
+
/**
|
|
63
|
+
* Every Set-Cookie of one vendor response, rewritten. Dropping `Domain` folds cookies
|
|
64
|
+
* the vendor keeps apart (`session-id` on `.amazon.it` and on `.www.amazon.it`) into
|
|
65
|
+
* one, so a past-dated set that only deleted the other domain's copy would delete the
|
|
66
|
+
* live one the same response just set: that deletion is dropped.
|
|
67
|
+
*/
|
|
68
|
+
export declare function rewriteSetCookies(cookies: readonly string[], route: LoginProxyRoute): string[];
|
|
62
69
|
/**
|
|
63
70
|
* A browser `Referer` that points into this proxy, turned back into the vendor URL it
|
|
64
71
|
* stands for. A Referer that is not ours is dropped (null): it names the hub.
|