@zuplo/cli 7.1.9 → 7.1.10

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.
Files changed (83) hide show
  1. package/node_modules/@hono/node-server/dist/index.cjs +151 -9
  2. package/node_modules/@hono/node-server/dist/index.mjs +151 -9
  3. package/node_modules/@hono/node-server/package.json +1 -1
  4. package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts +24 -3
  5. package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts.map +1 -1
  6. package/node_modules/@posthog/core/dist/posthog-core-stateless.js +30 -9
  7. package/node_modules/@posthog/core/dist/posthog-core-stateless.mjs +28 -10
  8. package/node_modules/@posthog/core/dist/posthog-core.d.ts +3 -3
  9. package/node_modules/@posthog/core/dist/posthog-core.d.ts.map +1 -1
  10. package/node_modules/@posthog/core/dist/posthog-core.js +1 -0
  11. package/node_modules/@posthog/core/dist/posthog-core.mjs +1 -0
  12. package/node_modules/@posthog/core/dist/types.d.ts +2 -1
  13. package/node_modules/@posthog/core/dist/types.d.ts.map +1 -1
  14. package/node_modules/@posthog/core/dist/types.js +1 -0
  15. package/node_modules/@posthog/core/dist/types.mjs +1 -0
  16. package/node_modules/@posthog/core/package.json +2 -2
  17. package/node_modules/@posthog/core/src/posthog-core-stateless.ts +42 -10
  18. package/node_modules/@posthog/core/src/posthog-core.ts +4 -3
  19. package/node_modules/@posthog/core/src/types.ts +2 -1
  20. package/node_modules/@posthog/types/dist/capture.d.ts +1 -1
  21. package/node_modules/@posthog/types/dist/index.d.ts +1 -1
  22. package/node_modules/@posthog/types/dist/index.d.ts.map +1 -1
  23. package/node_modules/@posthog/types/dist/posthog-config.d.ts +54 -5
  24. package/node_modules/@posthog/types/dist/posthog-config.d.ts.map +1 -1
  25. package/node_modules/@posthog/types/dist/posthog.d.ts +3 -3
  26. package/node_modules/@posthog/types/dist/posthog.d.ts.map +1 -1
  27. package/node_modules/@posthog/types/dist/segment.d.ts +11 -2
  28. package/node_modules/@posthog/types/dist/segment.d.ts.map +1 -1
  29. package/node_modules/@posthog/types/package.json +1 -1
  30. package/node_modules/@posthog/types/src/capture.ts +1 -1
  31. package/node_modules/@posthog/types/src/index.ts +1 -0
  32. package/node_modules/@posthog/types/src/posthog-config.ts +64 -6
  33. package/node_modules/@posthog/types/src/posthog.ts +3 -3
  34. package/node_modules/@posthog/types/src/segment.ts +11 -2
  35. package/node_modules/@zuplo/core/package.json +1 -1
  36. package/node_modules/@zuplo/graphql/package.json +1 -1
  37. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  38. package/node_modules/@zuplo/otel/package.json +1 -1
  39. package/node_modules/@zuplo/runtime/out/esm/chunk-4VE55TG3.js +26 -0
  40. package/node_modules/@zuplo/runtime/out/esm/chunk-4VE55TG3.js.map +1 -0
  41. package/node_modules/@zuplo/runtime/out/esm/{chunk-MXYNCB5D.js → chunk-DEKK4CFE.js} +95 -95
  42. package/node_modules/@zuplo/runtime/out/esm/chunk-DEKK4CFE.js.map +1 -0
  43. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  44. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  45. package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
  46. package/node_modules/@zuplo/runtime/out/types/index.d.ts +18 -6
  47. package/node_modules/@zuplo/runtime/out/types/internal/index.d.ts +1 -0
  48. package/node_modules/@zuplo/runtime/out/types/mcp/messages/index.d.ts +1 -0
  49. package/node_modules/@zuplo/runtime/out/types/mcp-gateway/index.d.ts +1 -0
  50. package/node_modules/@zuplo/runtime/out/types/mocks/index.d.ts +1 -0
  51. package/node_modules/@zuplo/runtime/out/types/sdks/aws/index.d.ts +1 -0
  52. package/node_modules/@zuplo/runtime/package.json +1 -1
  53. package/node_modules/ansi-regex/index.js +3 -2
  54. package/node_modules/ansi-regex/package.json +1 -1
  55. package/node_modules/body-parser/node_modules/content-type/README.md +2 -0
  56. package/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +20 -0
  57. package/node_modules/body-parser/node_modules/content-type/dist/index.js +20 -14
  58. package/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -1
  59. package/node_modules/body-parser/node_modules/content-type/package.json +1 -1
  60. package/node_modules/hono/dist/cjs/client/client.js +3 -3
  61. package/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +1 -1
  62. package/node_modules/hono/dist/cjs/middleware/cors/index.js +15 -12
  63. package/node_modules/hono/dist/cjs/middleware/etag/digest.js +47 -1
  64. package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +6 -3
  65. package/node_modules/hono/dist/cjs/utils/url.js +2 -2
  66. package/node_modules/hono/dist/client/client.js +3 -3
  67. package/node_modules/hono/dist/jsx/intrinsic-element/components.js +1 -1
  68. package/node_modules/hono/dist/middleware/cors/index.js +15 -12
  69. package/node_modules/hono/dist/middleware/etag/digest.js +47 -1
  70. package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +6 -3
  71. package/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +3 -3
  72. package/node_modules/hono/dist/utils/url.js +2 -2
  73. package/node_modules/hono/package.json +1 -1
  74. package/node_modules/type-is/node_modules/content-type/README.md +2 -0
  75. package/node_modules/type-is/node_modules/content-type/dist/index.d.ts +20 -0
  76. package/node_modules/type-is/node_modules/content-type/dist/index.js +20 -14
  77. package/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -1
  78. package/node_modules/type-is/node_modules/content-type/package.json +1 -1
  79. package/package.json +6 -6
  80. package/node_modules/@zuplo/runtime/out/esm/chunk-MXYNCB5D.js.map +0 -1
  81. package/node_modules/@zuplo/runtime/out/esm/chunk-RAZK5G27.js +0 -26
  82. package/node_modules/@zuplo/runtime/out/esm/chunk-RAZK5G27.js.map +0 -1
  83. /package/node_modules/@zuplo/runtime/out/esm/{chunk-MXYNCB5D.js.LEGAL.txt → chunk-DEKK4CFE.js.LEGAL.txt} +0 -0
@@ -22,5 +22,5 @@
22
22
  * DEALINGS IN THE SOFTWARE.
23
23
  *--------------------------------------------------------------------------------------------*/
24
24
 
25
- import{b as l}from"../chunk-RAZK5G27.js";import{_ as n}from"../chunk-4POCC75H.js";import{a as o}from"../chunk-TYV53J3B.js";function g(u={request:new Request("https://api.example.com")}){let e=[];function t(r){e.push(Promise.resolve(r))}return o(t,"waitUntil"),{context:new s({event:{waitUntil:t},route:u.route}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(g,"createMockContext");var a={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},s=class extends EventTarget{static{o(this,"MockZuploContext")}#e;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=a,parentContext:i}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:n.console.info,log:n.console.log,debug:n.console.debug,warn:n.console.warn,error:n.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=i,this.#e=e,this.analyticsContext=new l(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,i){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addEventListener(e,t,i){let d=o(r=>{try{typeof t=="function"?t(r):t.handleEvent(r)}catch(p){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),p}},"wrapped");super.addEventListener(e,d,i)}};export{s as MockZuploContext,g as createMockContext};
25
+ import{b as l}from"../chunk-4VE55TG3.js";import{_ as n}from"../chunk-4POCC75H.js";import{a as o}from"../chunk-TYV53J3B.js";function g(u={request:new Request("https://api.example.com")}){let e=[];function t(r){e.push(Promise.resolve(r))}return o(t,"waitUntil"),{context:new s({event:{waitUntil:t},route:u.route}),invokeResponse:o(async()=>{await Promise.all(e)},"invokeResponse")}}o(g,"createMockContext");var a={path:"/",methods:["GET"],handler:{module:{},export:"default"},raw:o(()=>({}),"raw")},s=class extends EventTarget{static{o(this,"MockZuploContext")}#e;contextId;requestId;log;route;custom;incomingRequestProperties;parentContext;analyticsContext;constructor({event:e,route:t=a,parentContext:i}){super(),this.requestId=crypto.randomUUID(),this.contextId=crypto.randomUUID(),this.log={info:n.console.info,log:n.console.log,debug:n.console.debug,warn:n.console.warn,error:n.console.error,setLogProperties:o(()=>{},"setLogProperties")},this.custom={},this.route=t,this.incomingRequestProperties={ip:"203.0.113.7",asn:1234,asOrganization:"ORGANIZATION",city:"Seattle",region:"Washington",regionCode:"WA",colo:"SEA",continent:"NA",country:"US",postalCode:"98004",metroCode:"SEA",latitude:void 0,longitude:void 0,timezone:void 0,httpProtocol:void 0,clientCert:void 0,clientMtlsVerificationStatus:void 0,clientMtlsVerificationReason:void 0,clientCertFingerprintSha256:void 0,clientCertNotBefore:void 0,clientCertNotAfter:void 0,clientCertIssuerDn:void 0,clientCertSubjectDn:void 0},this.parentContext=i,this.#e=e,this.analyticsContext=new l(this.requestId)}waitUntil(e){this.#e.waitUntil(e)}invokeInboundPolicy(e,t){throw new Error("Not implemented")}invokeOutboundPolicy(e,t,i){throw new Error("Not implemented")}invokeRoute(e,t){throw new Error("Not implemented")}addResponseSendingHook(e){throw new Error("Not implemented")}addResponseSendingFinalHook(e){throw new Error("Not implemented")}addEventListener(e,t,i){let d=o(r=>{try{typeof t=="function"?t(r):t.handleEvent(r)}catch(p){throw this.log.error(`Error invoking event ${e}. See following logs for details.`),p}},"wrapped");super.addEventListener(e,d,i)}};export{s as MockZuploContext,g as createMockContext};
26
26
  //# sourceMappingURL=index.js.map
@@ -960,10 +960,14 @@ export declare interface AIGatewaySemanticCacheOutboundPolicyOptions {}
960
960
  * response-sending hook to write the upstream response back into the cache —
961
961
  * matching the firewall's single-policy shape (no separate outbound policy).
962
962
  *
963
- * Caching parameters (semanticTolerance, expirationSecondsTtl, namespace) come
964
- * from the policy options, and presence in the route's chain is what enables
965
- * it. An id from the authenticated app configuration always provides the cache
966
- * namespace so application-supplied options cannot cross tenant partitions.
963
+ * Caching parameters (semanticTolerance, expirationSecondsTtl, namespace,
964
+ * recentMessageCount) come from the policy options, and presence in the
965
+ * route's chain is what enables it. An id from the authenticated app
966
+ * configuration always provides the cache namespace so application-supplied
967
+ * options cannot cross tenant partitions. The cache key covers the system
968
+ * prompt plus the last `recentMessageCount` messages (default 1) — applied
969
+ * when storing and when matching — so multi-turn conversations can hit
970
+ * entries cached from earlier, shorter ones.
967
971
  *
968
972
  * Cache outcomes are reported on the response via the RFC 9211 `Cache-Status`
969
973
  * header under the cache name `zp-aigw-sem-cache` (hit:
@@ -997,6 +1001,7 @@ export declare interface AIGatewaySemanticCacheV2InboundPolicyOptions {
997
1001
  semanticTolerance?: SemanticTolerance;
998
1002
  expirationSecondsTtl?: CacheTTLSeconds;
999
1003
  namespace?: CacheNamespace;
1004
+ recentMessageCount?: RecentMessageCount;
1000
1005
  maxConversationLength?: MaxConversationLength;
1001
1006
  endpoints?: ApplicableEndpoints;
1002
1007
  onUnknownShape?: OnUnknownShape;
@@ -1837,7 +1842,7 @@ declare interface APITokenCredentialConfig {
1837
1842
  }
1838
1843
 
1839
1844
  /**
1840
- * The endpoint shapes to cache. Defaults to ['openai-chat', 'anthropic-messages']; OpenAI Responses remains unsupported.
1845
+ * The endpoint shapes to cache. Defaults to all shapes: ['openai-chat', 'anthropic-messages', 'openai-responses'].
1841
1846
  * @public
1842
1847
  */
1843
1848
  declare type ApplicableEndpoints = (
@@ -4917,6 +4922,7 @@ declare const EventType: {
4917
4922
  readonly MCP_AUTH_UPSTREAM_RECONSENT_REQUIRED: "mcp_auth_upstream_reconsent_required";
4918
4923
  readonly GRAPHQL_OPERATION: "graphql_operation";
4919
4924
  readonly CACHE_OPERATION: "cache_operation";
4925
+ readonly HANDLER_EXECUTION: "handler_execution";
4920
4926
  };
4921
4927
 
4922
4928
  declare type EventType = (typeof EventType)[keyof typeof EventType];
@@ -8046,7 +8052,7 @@ declare type LokiTransportVersion = 1 | 2;
8046
8052
  /* Excluded from this release type: LookupResult */
8047
8053
 
8048
8054
  /**
8049
- * Skip caching requests whose message count exceeds this value. Longer conversations rarely repeat and dilute cache quality. Defaults to 3.
8055
+ * Skip caching entirely when the conversation has more than this many messages. Unset by default (no limit). Set a bound to guard against topic drift: the cache key covers only the last recentMessageCount messages, so the deeper a conversation goes, the more likely a match on recent messages alone ignores earlier context that should change the answer.
8050
8056
  * @public
8051
8057
  */
8052
8058
  declare type MaxConversationLength = number;
@@ -12339,6 +12345,12 @@ export declare function ReadmeMetricsInboundPolicy(
12339
12345
  policyName: string
12340
12346
  ): Promise<ZuploRequest<RequestGeneric>>;
12341
12347
 
12348
+ /**
12349
+ * How many of the conversation's most recent messages (input items on the Responses endpoint) form the cache key, both when storing a response and when matching later requests. Earlier messages are ignored, so a multi-turn conversation can hit an entry cached from a shorter one; system messages are always included. Requests whose keyed window contains no user message (for example a conversation ending in an assistant prefill) are not cached. Defaults to 1 (match on the newest message only).
12350
+ * @public
12351
+ */
12352
+ declare type RecentMessageCount = number;
12353
+
12342
12354
  /**
12343
12355
  * Record the GraphQL response-cache outcome for the in-flight operation so
12344
12356
  * the analytics middleware can emit it as the `cacheState` dimension on the
@@ -208,6 +208,7 @@ declare const EventType: {
208
208
  readonly MCP_AUTH_UPSTREAM_RECONSENT_REQUIRED: "mcp_auth_upstream_reconsent_required";
209
209
  readonly GRAPHQL_OPERATION: "graphql_operation";
210
210
  readonly CACHE_OPERATION: "cache_operation";
211
+ readonly HANDLER_EXECUTION: "handler_execution";
211
212
  };
212
213
 
213
214
  declare type EventType = (typeof EventType)[keyof typeof EventType];
@@ -138,6 +138,7 @@ declare const EventType: {
138
138
  readonly MCP_AUTH_UPSTREAM_RECONSENT_REQUIRED: "mcp_auth_upstream_reconsent_required";
139
139
  readonly GRAPHQL_OPERATION: "graphql_operation";
140
140
  readonly CACHE_OPERATION: "cache_operation";
141
+ readonly HANDLER_EXECUTION: "handler_execution";
141
142
  };
142
143
 
143
144
  declare type EventType = (typeof EventType)[keyof typeof EventType];
@@ -198,6 +198,7 @@ declare const EventType: {
198
198
  readonly MCP_AUTH_UPSTREAM_RECONSENT_REQUIRED: "mcp_auth_upstream_reconsent_required";
199
199
  readonly GRAPHQL_OPERATION: "graphql_operation";
200
200
  readonly CACHE_OPERATION: "cache_operation";
201
+ readonly HANDLER_EXECUTION: "handler_execution";
201
202
  };
202
203
 
203
204
  declare type EventType = (typeof EventType)[keyof typeof EventType];
@@ -113,6 +113,7 @@ declare const EventType: {
113
113
  readonly MCP_AUTH_UPSTREAM_RECONSENT_REQUIRED: "mcp_auth_upstream_reconsent_required";
114
114
  readonly GRAPHQL_OPERATION: "graphql_operation";
115
115
  readonly CACHE_OPERATION: "cache_operation";
116
+ readonly HANDLER_EXECUTION: "handler_execution";
116
117
  };
117
118
 
118
119
  declare type EventType = (typeof EventType)[keyof typeof EventType];
@@ -357,6 +357,7 @@ declare const EventType: {
357
357
  readonly MCP_AUTH_UPSTREAM_RECONSENT_REQUIRED: "mcp_auth_upstream_reconsent_required";
358
358
  readonly GRAPHQL_OPERATION: "graphql_operation";
359
359
  readonly CACHE_OPERATION: "cache_operation";
360
+ readonly HANDLER_EXECUTION: "handler_execution";
360
361
  };
361
362
 
362
363
  declare type EventType = (typeof EventType)[keyof typeof EventType];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zuplo/runtime",
3
3
  "type": "module",
4
- "version": "7.1.9",
4
+ "version": "7.1.10",
5
5
  "repository": "https://github.com/zuplo/zuplo",
6
6
  "author": "Zuplo, Inc.",
7
7
  "exports": {
@@ -2,8 +2,9 @@ export default function ansiRegex({onlyFirst = false} = {}) {
2
2
  // Valid string terminator sequences are BEL, ESC\, and 0x9c
3
3
  const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
4
4
 
5
- // OSC sequences only: ESC ] ... ST (non-greedy until the first ST)
6
- const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
5
+ // OSC sequences only: ESC ] ... ST
6
+ // The payload stops at the first terminator character rather than scanning ahead for one, so an unterminated `ESC ]` cannot rescan the rest of the input. Terminals likewise abort a control string on an unexpected ESC.
7
+ const osc = `(?:\\u001B\\][^\\u0007\\u001B\\u009C]*${ST})`;
7
8
 
8
9
  // CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte
9
10
  const csi = '[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]';
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ansi-regex",
3
- "version": "6.2.2",
3
+ "version": "6.3.0",
4
4
  "description": "Regular expression for matching ANSI escape codes",
5
5
  "license": "MIT",
6
6
  "repository": "chalk/ansi-regex",
@@ -36,6 +36,8 @@ The parser is lenient and does not error. You should validate `type` and `parame
36
36
  #### Options
37
37
 
38
38
  - `parameters` (default: `true`): Set to `false` to skip parameters.
39
+ - `comma` (default: `false`): Set to `true` to stop on a comma. This can be used to parse the media range in an `Accept` header.
40
+ - `start` (default: `0`): Set index to start parsing from.
39
41
 
40
42
  ### contentType.format(obj)
41
43
 
@@ -8,6 +8,7 @@
8
8
  */
9
9
  export interface ContentType {
10
10
  type: string;
11
+ index: number;
11
12
  parameters: Record<string, string>;
12
13
  }
13
14
  /**
@@ -18,7 +19,26 @@ export declare function format(obj: Partial<ContentType>): string;
18
19
  * Options for parsing a `Content-Type` header.
19
20
  */
20
21
  export interface ParseOptions {
22
+ /**
23
+ * Exit early on the first semicolon, returning only the type.
24
+ * This is useful for parsing the MIME from `Content-Type` headers.
25
+ *
26
+ * @default false
27
+ */
21
28
  parameters?: boolean;
29
+ /**
30
+ * Exits early on a comma, returning the first value and parameters.
31
+ * This is useful for parsing `Accept` headers.
32
+ *
33
+ * @default false
34
+ */
35
+ comma?: boolean;
36
+ /**
37
+ * The index to start parsing from.
38
+ *
39
+ * @default 0
40
+ */
41
+ start?: number;
22
42
  }
23
43
  /**
24
44
  * Parse a `Content-Type` header.
@@ -52,16 +52,17 @@ function format(obj) {
52
52
  * Parse a `Content-Type` header.
53
53
  */
54
54
  function parse(header, options) {
55
+ const stopChar = options?.comma === true ? COMMA : 65536; // Sentinel for "no stop char".
55
56
  const len = header.length;
56
- let index = skipOWS(header, 0, len);
57
+ let index = skipOWS(header, options?.start ?? 0, len);
57
58
  const valueStart = index;
58
- index = skipValue(header, index, len);
59
+ index = skipValue(header, index, len, stopChar);
59
60
  const valueEnd = trailingOWS(header, valueStart, index);
60
61
  const type = header.slice(valueStart, valueEnd).toLowerCase();
61
- const parameters = options?.parameters === false
62
- ? new NullObject()
63
- : parseParameters(header, index, len);
64
- return { type, parameters };
62
+ if (options?.parameters === false) {
63
+ return { type, index, parameters: new NullObject() };
64
+ }
65
+ return parseParameters(header, type, index, len, stopChar);
65
66
  }
66
67
  const SP = 32; // " "
67
68
  const HTAB = 9; // "\t"
@@ -69,16 +70,21 @@ const SEMI = 59; // ";"
69
70
  const EQ = 61; // "="
70
71
  const DQUOTE = 34; // '"'
71
72
  const BSLASH = 92; // "\\"
73
+ const COMMA = 44; // ","
72
74
  /**
73
75
  * Parses the parameters of a `Content-Type` header starting at the given index.
74
76
  */
75
- function parseParameters(header, index, len) {
77
+ function parseParameters(header, type, index, len, stopChar) {
76
78
  const parameters = new NullObject();
77
79
  parameter: while (index < len) {
80
+ if (header.charCodeAt(index) === stopChar)
81
+ break;
78
82
  index = skipOWS(header, index + 1 /* Skip over ; */, len);
79
83
  const keyStart = index;
80
84
  while (index < len) {
81
85
  const code = header.charCodeAt(index);
86
+ if (code === stopChar)
87
+ break parameter;
82
88
  if (code === SEMI)
83
89
  continue parameter;
84
90
  if (code === EQ) {
@@ -91,7 +97,7 @@ function parseParameters(header, index, len) {
91
97
  while (index < len) {
92
98
  const code = header.charCodeAt(index++);
93
99
  if (code === DQUOTE) {
94
- index = skipValue(header, index, len);
100
+ index = skipValue(header, index, len, stopChar);
95
101
  if (parameters[key] === undefined)
96
102
  parameters[key] = value;
97
103
  break;
@@ -105,7 +111,7 @@ function parseParameters(header, index, len) {
105
111
  continue parameter;
106
112
  }
107
113
  const valueStart = index;
108
- index = skipValue(header, index, len);
114
+ index = skipValue(header, index, len, stopChar);
109
115
  if (parameters[key] === undefined) {
110
116
  const valueEnd = trailingOWS(header, valueStart, index);
111
117
  parameters[key] = header.slice(valueStart, valueEnd);
@@ -115,15 +121,15 @@ function parseParameters(header, index, len) {
115
121
  index++;
116
122
  }
117
123
  }
118
- return parameters;
124
+ return { type, index, parameters };
119
125
  }
120
126
  /**
121
- * Skip over characters until a semicolon.
127
+ * Skip over characters until a semicolon or other exit character.
122
128
  */
123
- function skipValue(str, index, len) {
129
+ function skipValue(str, index, len, stopChar) {
124
130
  while (index < len) {
125
- const char = str.charCodeAt(index);
126
- if (char === SEMI)
131
+ const code = str.charCodeAt(index);
132
+ if (code === SEMI || code === stopChar)
127
133
  break;
128
134
  index++;
129
135
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * content-type\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\nconst TEXT_REGEXP = /^[\\u0009\\u0020-\\u007e\\u0080-\\u00ff]*$/;\nconst TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4\n */\nconst QUOTE_REGEXP = /[\\\\\"]/g;\n\n/**\n * RegExp to match type in RFC 9110 sec 8.3.1\n *\n * media-type = type \"/\" subtype\n * type = token\n * subtype = token\n */\nconst TYPE_REGEXP =\n /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`.\n */\nconst NullObject = /* @__PURE__ */ (() => {\n const C = function () {};\n C.prototype = Object.create(null);\n return C;\n})() as unknown as { new (): any };\n\n/**\n * The content type object contains a type string and optional parameters.\n */\nexport interface ContentType {\n type: string;\n parameters: Record<string, string>;\n}\n\n/**\n * Format an object into a `Content-Type` header.\n */\nexport function format(obj: Partial<ContentType>): string {\n const { type, parameters } = obj;\n\n if (!type || !TYPE_REGEXP.test(type)) {\n throw new TypeError(`Invalid type: ${type}`);\n }\n\n let result = type;\n\n if (parameters) {\n for (const param of Object.keys(parameters)) {\n if (!TOKEN_REGEXP.test(param)) {\n throw new TypeError(`Invalid parameter name: ${param}`);\n }\n\n result += `; ${param}=${qstring(parameters[param])}`;\n }\n }\n\n return result;\n}\n\n/**\n * Options for parsing a `Content-Type` header.\n */\nexport interface ParseOptions {\n parameters?: boolean;\n}\n\n/**\n * Parse a `Content-Type` header.\n */\nexport function parse(header: string, options?: ParseOptions): ContentType {\n const len = header.length;\n let index = skipOWS(header, 0, len);\n\n const valueStart = index;\n index = skipValue(header, index, len);\n const valueEnd = trailingOWS(header, valueStart, index);\n const type = header.slice(valueStart, valueEnd).toLowerCase();\n const parameters =\n options?.parameters === false\n ? new NullObject()\n : parseParameters(header, index, len);\n\n return { type, parameters };\n}\n\nconst SP = 32; // \" \"\nconst HTAB = 9; // \"\\t\"\nconst SEMI = 59; // \";\"\nconst EQ = 61; // \"=\"\nconst DQUOTE = 34; // '\"'\nconst BSLASH = 92; // \"\\\\\"\n\n/**\n * Parses the parameters of a `Content-Type` header starting at the given index.\n */\nfunction parseParameters(\n header: string,\n index: number,\n len: number,\n): Record<string, string> {\n const parameters: Record<string, string> = new NullObject();\n\n parameter: while (index < len) {\n index = skipOWS(header, index + 1 /* Skip over ; */, len);\n\n const keyStart = index;\n\n while (index < len) {\n const code = header.charCodeAt(index);\n if (code === SEMI) continue parameter;\n\n if (code === EQ) {\n const keyEnd = trailingOWS(header, keyStart, index);\n const key = header.slice(keyStart, keyEnd).toLowerCase();\n\n index = skipOWS(header, index + 1, len);\n\n if (index < len && header.charCodeAt(index) === DQUOTE) {\n index++;\n\n let value = \"\";\n while (index < len) {\n const code = header.charCodeAt(index++);\n if (code === DQUOTE) {\n index = skipValue(header, index, len);\n if (parameters[key] === undefined) parameters[key] = value;\n break;\n }\n\n if (code === BSLASH && index < len) {\n value += header[index++];\n continue;\n }\n\n value += String.fromCharCode(code);\n }\n\n continue parameter;\n }\n\n const valueStart = index;\n index = skipValue(header, index, len);\n\n if (parameters[key] === undefined) {\n const valueEnd = trailingOWS(header, valueStart, index);\n parameters[key] = header.slice(valueStart, valueEnd);\n }\n\n continue parameter;\n }\n\n index++;\n }\n }\n\n return parameters;\n}\n\n/**\n * Skip over characters until a semicolon.\n */\nfunction skipValue(str: string, index: number, len: number): number {\n while (index < len) {\n const char = str.charCodeAt(index);\n if (char === SEMI) break;\n index++;\n }\n return index;\n}\n\n/**\n * Skip optional whitespace (OWS) in an HTTP header value.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction skipOWS(header: string, index: number, len: number): number {\n while (index < len) {\n const char = header.charCodeAt(index);\n if (char !== SP && char !== HTAB) break;\n index++;\n }\n return index;\n}\n\n/**\n * Trim optional whitespace (OWS) from the end of a substring.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction trailingOWS(header: string, start: number, end: number): number {\n while (end > start) {\n const char = header.charCodeAt(end - 1);\n if (char !== SP && char !== HTAB) break;\n end--;\n }\n return end;\n}\n\n/**\n * Serialize a parameter value.\n */\nfunction qstring(str: string): string {\n if (TOKEN_REGEXP.test(str)) return str;\n if (TEXT_REGEXP.test(str)) return `\"${str.replace(QUOTE_REGEXP, \"\\\\$&\")}\"`;\n\n throw new TypeError(`Invalid parameter value: ${str}`);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * content-type\n * Copyright(c) 2015 Douglas Christopher Wilson\n * MIT Licensed\n */\n\nconst TEXT_REGEXP = /^[\\u0009\\u0020-\\u007e\\u0080-\\u00ff]*$/;\nconst TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * RegExp to match chars that must be quoted-pair in RFC 9110 sec 5.6.4\n */\nconst QUOTE_REGEXP = /[\\\\\"]/g;\n\n/**\n * RegExp to match type in RFC 9110 sec 8.3.1\n *\n * media-type = type \"/\" subtype\n * type = token\n * subtype = token\n */\nconst TYPE_REGEXP =\n /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;\n\n/**\n * Null object perf optimization. Faster than `Object.create(null)` and `{ __proto__: null }`.\n */\nconst NullObject = /* @__PURE__ */ (() => {\n const C = function () {};\n C.prototype = Object.create(null);\n return C;\n})() as unknown as { new (): any };\n\n/**\n * The content type object contains a type string and optional parameters.\n */\nexport interface ContentType {\n type: string;\n index: number;\n parameters: Record<string, string>;\n}\n\n/**\n * Format an object into a `Content-Type` header.\n */\nexport function format(obj: Partial<ContentType>): string {\n const { type, parameters } = obj;\n\n if (!type || !TYPE_REGEXP.test(type)) {\n throw new TypeError(`Invalid type: ${type}`);\n }\n\n let result = type;\n\n if (parameters) {\n for (const param of Object.keys(parameters)) {\n if (!TOKEN_REGEXP.test(param)) {\n throw new TypeError(`Invalid parameter name: ${param}`);\n }\n\n result += `; ${param}=${qstring(parameters[param])}`;\n }\n }\n\n return result;\n}\n\n/**\n * Options for parsing a `Content-Type` header.\n */\nexport interface ParseOptions {\n /**\n * Exit early on the first semicolon, returning only the type.\n * This is useful for parsing the MIME from `Content-Type` headers.\n *\n * @default false\n */\n parameters?: boolean;\n /**\n * Exits early on a comma, returning the first value and parameters.\n * This is useful for parsing `Accept` headers.\n *\n * @default false\n */\n comma?: boolean;\n /**\n * The index to start parsing from.\n *\n * @default 0\n */\n start?: number;\n}\n\n/**\n * Parse a `Content-Type` header.\n */\nexport function parse(header: string, options?: ParseOptions): ContentType {\n const stopChar = options?.comma === true ? COMMA : 65_536; // Sentinel for \"no stop char\".\n const len = header.length;\n let index = skipOWS(header, options?.start ?? 0, len);\n\n const valueStart = index;\n index = skipValue(header, index, len, stopChar);\n const valueEnd = trailingOWS(header, valueStart, index);\n const type = header.slice(valueStart, valueEnd).toLowerCase();\n\n if (options?.parameters === false) {\n return { type, index, parameters: new NullObject() };\n }\n\n return parseParameters(header, type, index, len, stopChar);\n}\n\nconst SP = 32; // \" \"\nconst HTAB = 9; // \"\\t\"\nconst SEMI = 59; // \";\"\nconst EQ = 61; // \"=\"\nconst DQUOTE = 34; // '\"'\nconst BSLASH = 92; // \"\\\\\"\nconst COMMA = 44; // \",\"\n\n/**\n * Parses the parameters of a `Content-Type` header starting at the given index.\n */\nfunction parseParameters(\n header: string,\n type: string,\n index: number,\n len: number,\n stopChar: number,\n): ContentType {\n const parameters: Record<string, string> = new NullObject();\n\n parameter: while (index < len) {\n if (header.charCodeAt(index) === stopChar) break;\n\n index = skipOWS(header, index + 1 /* Skip over ; */, len);\n\n const keyStart = index;\n\n while (index < len) {\n const code = header.charCodeAt(index);\n if (code === stopChar) break parameter;\n\n if (code === SEMI) continue parameter;\n\n if (code === EQ) {\n const keyEnd = trailingOWS(header, keyStart, index);\n const key = header.slice(keyStart, keyEnd).toLowerCase();\n\n index = skipOWS(header, index + 1, len);\n\n if (index < len && header.charCodeAt(index) === DQUOTE) {\n index++;\n\n let value = \"\";\n while (index < len) {\n const code = header.charCodeAt(index++);\n if (code === DQUOTE) {\n index = skipValue(header, index, len, stopChar);\n if (parameters[key] === undefined) parameters[key] = value;\n break;\n }\n\n if (code === BSLASH && index < len) {\n value += header[index++];\n continue;\n }\n\n value += String.fromCharCode(code);\n }\n\n continue parameter;\n }\n\n const valueStart = index;\n index = skipValue(header, index, len, stopChar);\n\n if (parameters[key] === undefined) {\n const valueEnd = trailingOWS(header, valueStart, index);\n parameters[key] = header.slice(valueStart, valueEnd);\n }\n\n continue parameter;\n }\n\n index++;\n }\n }\n\n return { type, index, parameters };\n}\n\n/**\n * Skip over characters until a semicolon or other exit character.\n */\nfunction skipValue(\n str: string,\n index: number,\n len: number,\n stopChar: number,\n): number {\n while (index < len) {\n const code = str.charCodeAt(index);\n if (code === SEMI || code === stopChar) break;\n index++;\n }\n return index;\n}\n\n/**\n * Skip optional whitespace (OWS) in an HTTP header value.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction skipOWS(header: string, index: number, len: number): number {\n while (index < len) {\n const char = header.charCodeAt(index);\n if (char !== SP && char !== HTAB) break;\n index++;\n }\n return index;\n}\n\n/**\n * Trim optional whitespace (OWS) from the end of a substring.\n *\n * OWS is defined in RFC 9110 sec 5.6.3 as SP (\" \") or HTAB (\"\\t\").\n */\nfunction trailingOWS(header: string, start: number, end: number): number {\n while (end > start) {\n const char = header.charCodeAt(end - 1);\n if (char !== SP && char !== HTAB) break;\n end--;\n }\n return end;\n}\n\n/**\n * Serialize a parameter value.\n */\nfunction qstring(str: string): string {\n if (TOKEN_REGEXP.test(str)) return str;\n if (TEXT_REGEXP.test(str)) return `\"${str.replace(QUOTE_REGEXP, \"\\\\$&\")}\"`;\n\n throw new TypeError(`Invalid parameter value: ${str}`);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "content-type",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Create and parse HTTP Content-Type header",
5
5
  "keywords": [
6
6
  "content-type",
@@ -74,7 +74,7 @@ class ClientRequestImpl {
74
74
  }
75
75
  this.rBody = form;
76
76
  }
77
- if (args.json) {
77
+ if (args.json !== void 0) {
78
78
  this.rBody = JSON.stringify(args.json);
79
79
  this.cType = "application/json";
80
80
  }
@@ -90,9 +90,9 @@ class ClientRequestImpl {
90
90
  if (args?.cookie) {
91
91
  const cookies = [];
92
92
  for (const [key, value] of Object.entries(args.cookie)) {
93
- cookies.push((0, import_cookie.serialize)(key, value, { path: "/" }));
93
+ cookies.push((0, import_cookie.serialize)(key, value));
94
94
  }
95
- headerValues["Cookie"] = cookies.join(",");
95
+ headerValues["Cookie"] = cookies.join("; ");
96
96
  }
97
97
  if (this.cType) {
98
98
  headerValues["Content-Type"] = this.cType;
@@ -101,7 +101,7 @@ const documentMetadataTag = (tag, children, props, sort) => {
101
101
  const string = new import_base.JSXNode(tag, restProps, (0, import_children.toArray)(children || [])).toString();
102
102
  if (string instanceof Promise) {
103
103
  return string.then(
104
- (resString) => (0, import_html.raw)(string, [
104
+ (resString) => (0, import_html.raw)(resString, [
105
105
  ...resString.callbacks || [],
106
106
  insertIntoHead(tag, resString, restProps, precedence)
107
107
  ])
@@ -28,6 +28,8 @@ const cors = (options) => {
28
28
  exposeHeaders: [],
29
29
  ...options
30
30
  };
31
+ const exposeHeadersStr = opts.exposeHeaders?.length ? opts.exposeHeaders.join(",") : void 0;
32
+ const allowHeadersStr = opts.allowHeaders?.length ? opts.allowHeaders.join(",") : void 0;
31
33
  const findAllowOrigin = ((optsOrigin) => {
32
34
  if (typeof optsOrigin === "string") {
33
35
  if (optsOrigin === "*") {
@@ -43,11 +45,12 @@ const cors = (options) => {
43
45
  })(opts.origin);
44
46
  const findAllowMethods = ((optsAllowMethods) => {
45
47
  if (typeof optsAllowMethods === "function") {
46
- return optsAllowMethods;
48
+ return async (origin, c) => (await optsAllowMethods(origin, c)).join(",");
47
49
  } else if (Array.isArray(optsAllowMethods)) {
48
- return () => optsAllowMethods;
50
+ const methodsStr = optsAllowMethods.join(",");
51
+ return () => methodsStr;
49
52
  } else {
50
- return () => [];
53
+ return () => "";
51
54
  }
52
55
  })(opts.allowMethods);
53
56
  return async function cors2(c, next) {
@@ -61,8 +64,8 @@ const cors = (options) => {
61
64
  if (opts.credentials) {
62
65
  set("Access-Control-Allow-Credentials", "true");
63
66
  }
64
- if (opts.exposeHeaders?.length) {
65
- set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
67
+ if (exposeHeadersStr) {
68
+ set("Access-Control-Expose-Headers", exposeHeadersStr);
66
69
  }
67
70
  if (c.req.method === "OPTIONS") {
68
71
  if (opts.origin !== "*") {
@@ -72,18 +75,18 @@ const cors = (options) => {
72
75
  set("Access-Control-Max-Age", opts.maxAge.toString());
73
76
  }
74
77
  const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
75
- if (allowMethods.length) {
76
- set("Access-Control-Allow-Methods", allowMethods.join(","));
78
+ if (allowMethods) {
79
+ set("Access-Control-Allow-Methods", allowMethods);
77
80
  }
78
- let headers = opts.allowHeaders;
79
- if (!headers?.length) {
81
+ let headersStr = allowHeadersStr;
82
+ if (!headersStr) {
80
83
  const requestHeaders = c.req.header("Access-Control-Request-Headers");
81
84
  if (requestHeaders) {
82
- headers = requestHeaders.split(",").map((h) => h.trim());
85
+ headersStr = requestHeaders.split(",").map((h) => h.trim()).join(",");
83
86
  }
84
87
  }
85
- if (headers?.length) {
86
- set("Access-Control-Allow-Headers", headers.join(","));
88
+ if (headersStr) {
89
+ set("Access-Control-Allow-Headers", headersStr);
87
90
  c.res.headers.append("Vary", "Access-Control-Request-Headers");
88
91
  }
89
92
  c.res.headers.delete("Content-Length");
@@ -31,18 +31,64 @@ const mergeBuffers = (buffer1, buffer2) => {
31
31
  merged.set(buffer2, buffer1.byteLength);
32
32
  return merged;
33
33
  };
34
+ const CHUNK_SIZE = 256 * 1024;
34
35
  const generateDigest = async (stream, generator) => {
35
36
  if (!stream) {
36
37
  return null;
37
38
  }
38
39
  let result = void 0;
40
+ let chunk;
41
+ let chunkLength = 0;
42
+ const digest = async (body) => {
43
+ result = await generator(mergeBuffers(result, body));
44
+ };
39
45
  const reader = stream.getReader();
40
46
  for (; ; ) {
41
47
  const { value, done } = await reader.read();
42
48
  if (done) {
43
49
  break;
44
50
  }
45
- result = await generator(mergeBuffers(result, value));
51
+ let offset = 0;
52
+ while (offset < value.byteLength) {
53
+ const remaining = value.byteLength - offset;
54
+ if (chunkLength === 0 && remaining >= CHUNK_SIZE) {
55
+ await digest(value.subarray(offset, offset + CHUNK_SIZE));
56
+ offset += CHUNK_SIZE;
57
+ continue;
58
+ }
59
+ const requiredLength = chunkLength + remaining;
60
+ if (requiredLength < CHUNK_SIZE) {
61
+ if (!chunk) {
62
+ chunk = value.subarray(offset);
63
+ } else {
64
+ if (chunk.byteLength < requiredLength) {
65
+ const nextChunk = new Uint8Array(
66
+ new ArrayBuffer(Math.min(CHUNK_SIZE, Math.max(requiredLength, chunk.byteLength * 2)))
67
+ );
68
+ nextChunk.set(chunk.subarray(0, chunkLength));
69
+ chunk = nextChunk;
70
+ }
71
+ chunk.set(value.subarray(offset), chunkLength);
72
+ }
73
+ chunkLength = requiredLength;
74
+ break;
75
+ }
76
+ const length = CHUNK_SIZE - chunkLength;
77
+ if (chunk?.byteLength !== CHUNK_SIZE) {
78
+ const nextChunk = new Uint8Array(new ArrayBuffer(CHUNK_SIZE));
79
+ if (chunk) {
80
+ nextChunk.set(chunk.subarray(0, chunkLength));
81
+ }
82
+ chunk = nextChunk;
83
+ }
84
+ chunk.set(value.subarray(offset, offset + length), chunkLength);
85
+ await digest(chunk);
86
+ chunkLength = 0;
87
+ offset += length;
88
+ }
89
+ }
90
+ if (chunk && chunkLength > 0) {
91
+ await digest(chunk.subarray(0, chunkLength));
46
92
  }
47
93
  if (!result) {
48
94
  return null;
@@ -159,14 +159,17 @@ function getPermissionsPolicyDirectives(policy) {
159
159
  return Object.entries(policy).map(([directive, value]) => {
160
160
  const kebabDirective = camelToKebab(directive);
161
161
  if (typeof value === "boolean") {
162
- return `${kebabDirective}=${value ? "*" : "none"}`;
162
+ return `${kebabDirective}=${value ? "*" : "()"}`;
163
163
  }
164
164
  if (Array.isArray(value)) {
165
165
  if (value.length === 0) {
166
166
  return `${kebabDirective}=()`;
167
167
  }
168
- if (value.length === 1 && (value[0] === "*" || value[0] === "none")) {
169
- return `${kebabDirective}=${value[0]}`;
168
+ if (value.length === 1 && value[0] === "*") {
169
+ return `${kebabDirective}=*`;
170
+ }
171
+ if (value.length === 1 && value[0] === "none") {
172
+ return `${kebabDirective}=()`;
170
173
  }
171
174
  const allowlist = value.map((item) => ["self", "src"].includes(item) ? item : `"${item}"`);
172
175
  return `${kebabDirective}=(${allowlist.join(" ")})`;
@@ -142,13 +142,13 @@ const checkOptionalParameter = (path) => {
142
142
  if (segment !== "" && !/\:/.test(segment)) {
143
143
  basePath += "/" + segment;
144
144
  } else if (/\:/.test(segment)) {
145
- if (/\?/.test(segment)) {
145
+ if (segment.charCodeAt(segment.length - 1) === 63) {
146
146
  if (results.length === 0 && basePath === "") {
147
147
  results.push("/");
148
148
  } else {
149
149
  results.push(basePath);
150
150
  }
151
- const optionalSegment = segment.replace("?", "");
151
+ const optionalSegment = segment.slice(0, -1);
152
152
  basePath += "/" + optionalSegment;
153
153
  results.push(basePath);
154
154
  } else {
@@ -60,7 +60,7 @@ var ClientRequestImpl = class {
60
60
  }
61
61
  this.rBody = form;
62
62
  }
63
- if (args.json) {
63
+ if (args.json !== void 0) {
64
64
  this.rBody = JSON.stringify(args.json);
65
65
  this.cType = "application/json";
66
66
  }
@@ -76,9 +76,9 @@ var ClientRequestImpl = class {
76
76
  if (args?.cookie) {
77
77
  const cookies = [];
78
78
  for (const [key, value] of Object.entries(args.cookie)) {
79
- cookies.push(serialize(key, value, { path: "/" }));
79
+ cookies.push(serialize(key, value));
80
80
  }
81
- headerValues["Cookie"] = cookies.join(",");
81
+ headerValues["Cookie"] = cookies.join("; ");
82
82
  }
83
83
  if (this.cType) {
84
84
  headerValues["Content-Type"] = this.cType;
@@ -78,7 +78,7 @@ var documentMetadataTag = (tag, children, props, sort) => {
78
78
  const string = new JSXNode(tag, restProps, toArray(children || [])).toString();
79
79
  if (string instanceof Promise) {
80
80
  return string.then(
81
- (resString) => raw(string, [
81
+ (resString) => raw(resString, [
82
82
  ...resString.callbacks || [],
83
83
  insertIntoHead(tag, resString, restProps, precedence)
84
84
  ])