Re: [whatwg/fetch] Add getStructured/setStructured to Headers (PR #1943)

@jasnell commented on this pull request.



> +  constrained profile of string rather than a separate type. When serializing
+  via {{Headers/setStructured()}}, strings that conform to
+  <a>structured field token</a> syntax are serialized as tokens; all other
+  strings are serialized as quoted structured field strings.

Ok, updated....

```js
// Without sfType — auto-detects as token (unquoted)
headers.setStructured("Example", "item", { value: "foo" });
// → Example: foo

// With sfType — forces quoted string
headers.setStructured("Example", "item", { value: "foo", sfType: "string" });
// → Example: "foo"

// Token validation — throws if value doesn't match token syntax
headers.setStructured("Example", "item", { value: "hello world", sfType: "token" });
// → TypeError (spaces not allowed in tokens)

// Deprecation header (RFC 9745) — defined as an SF Date
headers.setStructured("Deprecation", "item", {
  value: 1659578233,
  sfType: "date"
});
// → Deprecation: @1659578233

// Without sfType, the same number becomes an integer:
headers.setStructured("Deprecation", "item", { value: 1659578233 });
// → Deprecation: 1659578233   (wrong — missing @ prefix)

headers.setStructured("Example", "item", {
  value: "Ünïcödé",
  sfType: "displaystring"
});
// → Example: %"...percent-encoded UTF-8..."

// Without sfType, this would try to serialize as a regular SF string,
// which only permits printable ASCII — serialization would fail.

// Force decimal even for an integer value
headers.setStructured("Example", "item", { value: 42, sfType: "decimal" });
// → Example: 42.0

// Force integer — throws if not integral
headers.setStructured("Example", "item", { value: 3.14, sfType: "integer" });
// → TypeError

// Dictionary with mixed sfType overrides
headers.setStructured("My-Header", "dictionary", {
  name: { value: "cdn", sfType: "string" },   // quoted: "cdn"
  kind: { value: "cdn" },                      // auto: unquoted token cdn
  ts:   { value: 1700000000, sfType: "date" }  // date: @1700000000
});
// → My-Header: name="cdn", kind=cdn, ts=@1700000000

// List with sfType
headers.setStructured("My-List", "list", [
  { value: "keep-alive", sfType: "string" },  // "keep-alive"
  { value: "upgrade", sfType: "token" }        // upgrade
]);
// → My-List: "keep-alive", upgrade

// Integer out of range — throws
headers.setStructured("X", "item", { value: 1e16 });
// → TypeError (exceeds 15-digit SF integer limit)

// Decimal with too-large integer component — throws
headers.setStructured("X", "item", { value: 9999999999999.5 });
// → TypeError (integer component exceeds 12 digits)

// sfType: "date" with non-integer — throws
headers.setStructured("X", "item", { value: 3.14, sfType: "date" });
// → TypeError (dates must be integral)

// sfType only applies to item objects, not parameter values.
// Parameters always use auto-detection:
headers.setStructured("Cache-Status", "list", [
  { value: "cdn", sfType: "token", params: { hit: true, ttl: 3600 } }
  //                                         ^^^ bare values, no sfType
]);
// → Cache-Status: cdn;hit;ttl=3600
```

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/pull/1943#discussion_r3737597444
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/fetch/pull/1943/review/4885153285@github.com>

Received on Friday, 7 August 2026 17:31:09 UTC