@rho-workspace/rho 0.5.5 → 0.5.6
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/agent-connect.d.ts +8 -0
- package/dist/agent-connect.js +15 -0
- package/dist/browser-access.js +1 -1
- package/dist/cli.js +38 -8
- package/dist/contract.generated.d.ts +148 -5
- package/dist/contract.generated.js +1 -1
- package/dist/contracts/owners.generated.js +107 -12
- package/dist/conversations.d.ts +157 -4
- package/dist/conversations.js +69 -6
- package/dist/discovery.js +1 -1
- package/dist/protocol.d.ts +1 -0
- package/dist/protocol.js +12 -5
- package/dist/server.d.ts +2 -10
- package/dist/server.js +71 -8
- package/dist/web/.vite/manifest.json +61 -61
- package/dist/web/assets/{choices-b0XhrGQV.js → choices-D-YfnFP6.js} +1 -1
- package/dist/web/assets/{console-BSjLGe0T.js → console-Trqc0swD.js} +1 -1
- package/dist/web/assets/{dist-Buk0lwzI.js → dist-DZmszrjG.js} +1 -1
- package/dist/web/assets/{dist-Cw8hRIlT.js → dist-DpIHRk3B.js} +1 -1
- package/dist/web/assets/{dist-foH9IKc6.js → dist-eMx6b8N1.js} +1 -1
- package/dist/web/assets/{dist-Tzoe_zm-.js → dist-pF902jHA.js} +1 -1
- package/dist/web/assets/{explore-in-BVUy3ZW_.js → explore-in-BCHqjJ7B.js} +1 -1
- package/dist/web/assets/{graph-1OdIJ9l7.js → graph-lENgfQNH.js} +1 -1
- package/dist/web/assets/index-B3_OVy91.css +1 -0
- package/dist/web/assets/{index-CxmItXqa.js → index-BpL_Kl_s.js} +84 -83
- package/dist/web/assets/{notes-meaning-pVbbQUGP.js → notes-meaning-DcVGUBBY.js} +1 -1
- package/dist/web/assets/{overview-B9UtVJ32.js → overview-CDnVKlOt.js} +3 -3
- package/dist/web/assets/{preview-CksD_5KS.js → preview-BEC1E9MK.js} +1 -1
- package/dist/web/assets/{review-CMxQlQ-C.js → review-DYP0aCXb.js} +1 -1
- package/dist/web/assets/{skills-BFNSyrnD.js → skills-1ec0Z-jx.js} +1 -1
- package/dist/web/assets/{skills-work-BGPSnF_I.js → skills-work-DNexV4OJ.js} +1 -1
- package/dist/web/assets/{studio-process-CsRoTHOh.js → studio-process-EYQgikxq.js} +1 -1
- package/dist/web/assets/{timeline-events-BbuuFWHV.js → timeline-events-Chj2Gbx7.js} +1 -1
- package/dist/web/assets/{work-turns-BvJlIMmA.js → work-turns-CT9RVcWY.js} +1 -1
- package/dist/web/assets/{workspace-CWlkjLNx.js → workspace-COmCbGV3.js} +1 -1
- package/dist/web/composition.json +58 -58
- package/dist/web/index.html +2 -2
- package/dist/web/renderer.json +1 -1
- package/docs/FRONTEND.md +26 -18
- package/docs/HEADLESS.md +37 -27
- package/node_modules/@rho-workspace/plugin-agent/README.md +29 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-command.js +9 -1
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.d.ts +1 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/acp-conversation.js +10 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session-contract.js +10 -5
- package/node_modules/@rho-workspace/plugin-agent/dist/external-session.d.ts +12 -1
- package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.d.ts +70 -0
- package/node_modules/@rho-workspace/plugin-agent/dist/native-sessions.js +538 -0
- package/node_modules/@rho-workspace/plugin-agent/package.json +2 -1
- package/node_modules/hono/dist/adapter/aws-lambda/handler.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +1 -1
- package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +1 -1
- package/node_modules/hono/dist/cjs/client/fetch-result-please.js +1 -1
- package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +2 -1
- package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +5 -3
- package/node_modules/hono/dist/cjs/jsx/base.js +49 -30
- package/node_modules/hono/dist/cjs/jsx/components.js +2 -2
- package/node_modules/hono/dist/cjs/jsx/constants.js +2 -0
- package/node_modules/hono/dist/cjs/jsx/jsx-runtime.js +13 -17
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +3 -1
- package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +1 -0
- package/node_modules/hono/dist/cjs/middleware/timing/timing.js +4 -3
- package/node_modules/hono/dist/cjs/utils/cookie.js +2 -2
- package/node_modules/hono/dist/cjs/utils/mime.js +1 -1
- package/node_modules/hono/dist/cjs/utils/url.js +1 -1
- package/node_modules/hono/dist/client/fetch-result-please.js +1 -1
- package/node_modules/hono/dist/helper/accepts/accepts.js +2 -1
- package/node_modules/hono/dist/helper/ssg/ssg.js +5 -3
- package/node_modules/hono/dist/jsx/base.js +49 -32
- package/node_modules/hono/dist/jsx/components.js +2 -2
- package/node_modules/hono/dist/jsx/constants.js +2 -1
- package/node_modules/hono/dist/jsx/jsx-runtime.js +15 -19
- package/node_modules/hono/dist/middleware/etag/index.js +3 -1
- package/node_modules/hono/dist/middleware/language/language.js +1 -1
- package/node_modules/hono/dist/middleware/pretty-json/index.js +1 -0
- package/node_modules/hono/dist/middleware/timing/timing.js +4 -3
- package/node_modules/hono/dist/utils/cookie.js +2 -2
- package/node_modules/hono/dist/utils/mime.js +1 -1
- package/node_modules/hono/dist/utils/url.js +1 -1
- package/node_modules/hono/package.json +1 -1
- package/package.json +2 -2
- package/protocol/index.json +39 -33
- package/protocol/operations/agent.sessions.list.json +49 -3
- package/protocol/operations/agent.sessions.read.json +53 -4
- package/protocol/operations/conversation.configure.json +29 -0
- package/protocol/operations/conversation.decide.json +29 -0
- package/protocol/operations/conversation.list.json +29 -0
- package/protocol/operations/conversation.permission.json +29 -0
- package/protocol/operations/conversation.read.json +29 -0
- package/protocol/operations/conversation.restore.json +29 -0
- package/protocol/operations/conversation.send.json +29 -0
- package/protocol/operations/conversation.settings.check.json +92 -0
- package/protocol/operations/conversation.settings.read.json +92 -0
- package/protocol/operations/conversation.settings.update.json +92 -0
- package/protocol/operations/conversation.start.json +46 -1
- package/protocol/operations/conversation.stop.json +29 -0
- package/protocol/operations/conversation.trash.json +29 -0
- package/protocol/operations/observation.snapshot.json +29 -0
- package/protocol/operations/session.instructions.json +43 -0
- package/vendor/composition.json +74 -74
- package/vendor/rho-workspace-plugin-agent-0.4.30.tgz +0 -0
- package/web/theme.css +12 -0
- package/dist/web/assets/index-CsC3sTRq.css +0 -1
- package/vendor/rho-workspace-plugin-agent-0.4.29.tgz +0 -0
|
@@ -26,7 +26,7 @@ const emptyTags = [
|
|
|
26
26
|
"track",
|
|
27
27
|
"wbr"
|
|
28
28
|
];
|
|
29
|
-
const booleanAttributes = [
|
|
29
|
+
const booleanAttributes = /* @__PURE__ */ new Set([
|
|
30
30
|
"allowfullscreen",
|
|
31
31
|
"async",
|
|
32
32
|
"autofocus",
|
|
@@ -52,8 +52,11 @@ const booleanAttributes = [
|
|
|
52
52
|
"readonly",
|
|
53
53
|
"required",
|
|
54
54
|
"reversed",
|
|
55
|
-
"selected"
|
|
56
|
-
|
|
55
|
+
"selected",
|
|
56
|
+
"shadowrootclonable",
|
|
57
|
+
"shadowrootdelegatesfocus",
|
|
58
|
+
"shadowrootserializable"
|
|
59
|
+
]);
|
|
57
60
|
const resolveFunctionComponentResult = (result, suspendedContext) => result.then((resolved) => {
|
|
58
61
|
if (typeof resolved !== "string" && !Array.isArray(resolved) && !(resolved instanceof JSXNode)) return resolved;
|
|
59
62
|
const children = Array.isArray(resolved) ? resolved : [resolved];
|
|
@@ -64,6 +67,44 @@ const resolveFunctionComponentResult = (result, suspendedContext) => result.then
|
|
|
64
67
|
};
|
|
65
68
|
return suspendedContext ? suspendedContext(render) : require_jsx_context.runWithRenderContext(render);
|
|
66
69
|
});
|
|
70
|
+
const markRenderedJSX = (value) => {
|
|
71
|
+
value[require_jsx_constants.RENDERED_JSX] = true;
|
|
72
|
+
return value;
|
|
73
|
+
};
|
|
74
|
+
const isEscapedAttribute = (value) => value instanceof String && value.isEscaped && !(require_jsx_constants.RENDERED_JSX in value);
|
|
75
|
+
const objectToAttributeString = (v) => {
|
|
76
|
+
const s = v.toString();
|
|
77
|
+
return s instanceof Promise ? s.then(String) : String(s);
|
|
78
|
+
};
|
|
79
|
+
const attributeToBuffer = (buffer, prefix, key, v, tag) => {
|
|
80
|
+
if (key === "ref" || v === null || v === void 0) return;
|
|
81
|
+
if (typeof v === "boolean" && booleanAttributes.has(key)) {
|
|
82
|
+
if (v) buffer[0] += `${prefix}${key}=""`;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (typeof v === "function") {
|
|
86
|
+
if (!key.startsWith("on")) throw new Error(`Invalid prop '${key}' of type 'function' supplied to ${tag ? `'${tag}'` : "a JSX element"}.`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
buffer[0] += `${prefix}${key}="`;
|
|
90
|
+
if (key === "style" && typeof v === "object") {
|
|
91
|
+
let styleStr = "";
|
|
92
|
+
require_jsx_utils.styleObjectForEach(v, (property, value) => {
|
|
93
|
+
if (value != null) styleStr += `${styleStr ? ";" : ""}${property}:${value}`;
|
|
94
|
+
});
|
|
95
|
+
require_utils_html.escapeToBuffer(styleStr, buffer);
|
|
96
|
+
} else if (typeof v === "string") require_utils_html.escapeToBuffer(v, buffer);
|
|
97
|
+
else if (typeof v === "number" || isEscapedAttribute(v)) buffer[0] += `${v}`;
|
|
98
|
+
else {
|
|
99
|
+
const s = v instanceof Promise ? v.then((r) => typeof r === "object" && r !== null && !isEscapedAttribute(r) ? objectToAttributeString(r) : r) : objectToAttributeString(v);
|
|
100
|
+
if (s instanceof Promise) {
|
|
101
|
+
buffer.unshift("\"", s);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
require_utils_html.escapeToBuffer(s, buffer);
|
|
105
|
+
}
|
|
106
|
+
buffer[0] += "\"";
|
|
107
|
+
};
|
|
67
108
|
const childrenToStringToBuffer = (children, buffer) => {
|
|
68
109
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
69
110
|
const child = children[i];
|
|
@@ -115,7 +156,7 @@ var JSXNode = class {
|
|
|
115
156
|
const render = () => {
|
|
116
157
|
const buffer = [""];
|
|
117
158
|
this.toStringToBuffer(buffer);
|
|
118
|
-
return buffer.length === 1 ? "callbacks" in buffer ? require_utils_html.resolveCallbackSync(require_utils_html.raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : require_utils_html.stringBufferToString(buffer, buffer.callbacks);
|
|
159
|
+
return buffer.length === 1 ? "callbacks" in buffer ? require_utils_html.resolveCallbackSync(require_utils_html.raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : require_utils_html.stringBufferToString(buffer, buffer.callbacks).then(markRenderedJSX);
|
|
119
160
|
};
|
|
120
161
|
return require_jsx_context.runWithRenderContext(render);
|
|
121
162
|
}
|
|
@@ -128,34 +169,10 @@ var JSXNode = class {
|
|
|
128
169
|
for (let [key, v] of Object.entries(props)) {
|
|
129
170
|
key = normalizeKey(key);
|
|
130
171
|
if (!require_jsx_utils.isValidAttributeName(key)) continue;
|
|
131
|
-
if (key === "children") {} else if (key === "
|
|
132
|
-
let styleStr = "";
|
|
133
|
-
require_jsx_utils.styleObjectForEach(v, (property, value) => {
|
|
134
|
-
if (value != null) styleStr += `${styleStr ? ";" : ""}${property}:${value}`;
|
|
135
|
-
});
|
|
136
|
-
buffer[0] += " style=\"";
|
|
137
|
-
require_utils_html.escapeToBuffer(styleStr, buffer);
|
|
138
|
-
buffer[0] += "\"";
|
|
139
|
-
} else if (typeof v === "string") {
|
|
140
|
-
buffer[0] += ` ${key}="`;
|
|
141
|
-
require_utils_html.escapeToBuffer(v, buffer);
|
|
142
|
-
buffer[0] += "\"";
|
|
143
|
-
} else if (v === null || v === void 0) {} else if (typeof v === "number" || v.isEscaped) buffer[0] += ` ${key}="${v}"`;
|
|
144
|
-
else if (typeof v === "boolean" && booleanAttributes.includes(key)) {
|
|
145
|
-
if (v) buffer[0] += ` ${key}=""`;
|
|
146
|
-
} else if (key === "dangerouslySetInnerHTML") {
|
|
172
|
+
if (key === "children") {} else if (key === "dangerouslySetInnerHTML" && typeof v === "object" && v !== null && "__html" in v) {
|
|
147
173
|
if (children.length > 0) throw new Error("Can only set one of `children` or `props.dangerouslySetInnerHTML`.");
|
|
148
174
|
children = [require_utils_html.raw(v.__html)];
|
|
149
|
-
} else
|
|
150
|
-
buffer[0] += ` ${key}="`;
|
|
151
|
-
buffer.unshift("\"", v);
|
|
152
|
-
} else if (typeof v === "function") {
|
|
153
|
-
if (!key.startsWith("on") && key !== "ref") throw new Error(`Invalid prop '${key}' of type 'function' supplied to '${tag}'.`);
|
|
154
|
-
} else {
|
|
155
|
-
buffer[0] += ` ${key}="`;
|
|
156
|
-
require_utils_html.escapeToBuffer(v.toString(), buffer);
|
|
157
|
-
buffer[0] += "\"";
|
|
158
|
-
}
|
|
175
|
+
} else attributeToBuffer(buffer, " ", key, v, tag);
|
|
159
176
|
}
|
|
160
177
|
if (emptyTags.includes(tag) && children.length === 0) {
|
|
161
178
|
buffer[0] += "/>";
|
|
@@ -252,6 +269,7 @@ const reactAPICompatVersion = "19.0.0-hono-jsx";
|
|
|
252
269
|
exports.Fragment = Fragment;
|
|
253
270
|
exports.JSXFragmentNode = JSXFragmentNode;
|
|
254
271
|
exports.JSXNode = JSXNode;
|
|
272
|
+
exports.attributeToBuffer = attributeToBuffer;
|
|
255
273
|
exports.booleanAttributes = booleanAttributes;
|
|
256
274
|
exports.cloneElement = cloneElement;
|
|
257
275
|
exports.getNameSpaceContext = getNameSpaceContext;
|
|
@@ -259,6 +277,7 @@ exports.isUntrustedObject = isUntrustedObject;
|
|
|
259
277
|
exports.isValidElement = isValidElement;
|
|
260
278
|
exports.jsx = jsx;
|
|
261
279
|
exports.jsxFn = jsxFn;
|
|
280
|
+
exports.markRenderedJSX = markRenderedJSX;
|
|
262
281
|
exports.memo = memo;
|
|
263
282
|
exports.reactAPICompatVersion = reactAPICompatVersion;
|
|
264
283
|
exports.renderChildren = renderChildren;
|
|
@@ -78,7 +78,7 @@ const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) =>
|
|
|
78
78
|
buffer[0] = buffer[0].replace(replaceRe, () => fallbackResString);
|
|
79
79
|
return fallbackCallbacks?.length ? require_utils_html.raw("", fallbackCallbacks) : "";
|
|
80
80
|
}
|
|
81
|
-
return require_utils_html.raw(`<template data-hono-target="E:${index}">${fallbackResString}</template><script>
|
|
81
|
+
return require_utils_html.raw(`<template data-hono-target="E:${index}">${fallbackResString}</template><script${nonce ? ` nonce="${nonce}"` : ""}>
|
|
82
82
|
((d,c,n) => {
|
|
83
83
|
c=d.currentScript.previousSibling
|
|
84
84
|
d=d.getElementById('E:${index}')
|
|
@@ -119,7 +119,7 @@ d.parentElement.insertBefore(c.content,d.nextSibling)
|
|
|
119
119
|
buffer[0] += content;
|
|
120
120
|
return require_utils_html.raw("", content.callbacks);
|
|
121
121
|
}
|
|
122
|
-
return require_utils_html.raw(content + (resolvedCount !== callbacks.length ? "" : `<script>
|
|
122
|
+
return require_utils_html.raw(content + (resolvedCount !== callbacks.length ? "" : `<script${nonce ? ` nonce="${nonce}"` : ""}>
|
|
123
123
|
((d,c,n) => {
|
|
124
124
|
d=d.getElementById('E:${index}')
|
|
125
125
|
if(!d)return
|
|
@@ -6,6 +6,7 @@ const DOM_STASH = Symbol("STASH");
|
|
|
6
6
|
const DOM_INTERNAL_TAG = Symbol("INTERNAL");
|
|
7
7
|
const DOM_MEMO = Symbol("MEMO");
|
|
8
8
|
const PERMALINK = Symbol("PERMALINK");
|
|
9
|
+
const RENDERED_JSX = Symbol("RENDERED_JSX");
|
|
9
10
|
//#endregion
|
|
10
11
|
exports.DOM_ERROR_HANDLER = DOM_ERROR_HANDLER;
|
|
11
12
|
exports.DOM_INTERNAL_TAG = DOM_INTERNAL_TAG;
|
|
@@ -13,3 +14,4 @@ exports.DOM_MEMO = DOM_MEMO;
|
|
|
13
14
|
exports.DOM_RENDERER = DOM_RENDERER;
|
|
14
15
|
exports.DOM_STASH = DOM_STASH;
|
|
15
16
|
exports.PERMALINK = PERMALINK;
|
|
17
|
+
exports.RENDERED_JSX = RENDERED_JSX;
|
|
@@ -1,30 +1,26 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_utils_html = require("../utils/html.js");
|
|
3
3
|
const require_helper_html_index = require("../helper/html/index.js");
|
|
4
|
+
const require_jsx_constants = require("./constants.js");
|
|
4
5
|
const require_jsx_utils = require("./utils.js");
|
|
5
6
|
const require_jsx_base = require("./base.js");
|
|
6
7
|
const require_jsx_jsx_dev_runtime = require("./jsx-dev-runtime.js");
|
|
7
8
|
//#region src/jsx/jsx-runtime.ts
|
|
9
|
+
const jsxTemplate = (strings, ...values) => {
|
|
10
|
+
const result = require_helper_html_index.html(strings, ...values);
|
|
11
|
+
return result instanceof Promise ? result.then(require_jsx_base.markRenderedJSX) : require_jsx_base.markRenderedJSX(result);
|
|
12
|
+
};
|
|
8
13
|
const jsxAttr = (key, v) => {
|
|
9
14
|
if (!require_jsx_utils.isValidAttributeName(key)) return require_utils_html.raw("");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let styleStr = "";
|
|
13
|
-
require_jsx_utils.styleObjectForEach(v, (property, value) => {
|
|
14
|
-
if (value != null) styleStr += `${styleStr ? ";" : ""}${property}:${value}`;
|
|
15
|
-
});
|
|
16
|
-
require_utils_html.escapeToBuffer(styleStr, buffer);
|
|
17
|
-
buffer[0] += "\"";
|
|
18
|
-
} else if (typeof v === "string") {
|
|
15
|
+
if (typeof v === "string") {
|
|
16
|
+
const buffer = [`${key}="`];
|
|
19
17
|
require_utils_html.escapeToBuffer(v, buffer);
|
|
20
|
-
buffer[0]
|
|
21
|
-
} else if (v === null || v === void 0) return require_utils_html.raw("");
|
|
22
|
-
else if (typeof v === "number" || v.isEscaped) buffer[0] += `${v}"`;
|
|
23
|
-
else if (v instanceof Promise) buffer.unshift("\"", v);
|
|
24
|
-
else {
|
|
25
|
-
require_utils_html.escapeToBuffer(v.toString(), buffer);
|
|
26
|
-
buffer[0] += "\"";
|
|
18
|
+
return require_utils_html.raw(buffer[0] + "\"");
|
|
27
19
|
}
|
|
20
|
+
let value = v;
|
|
21
|
+
if (typeof value === "function" && (key === "action" || key === "formaction")) value = require_jsx_constants.PERMALINK in value ? value[require_jsx_constants.PERMALINK] : void 0;
|
|
22
|
+
const buffer = [""];
|
|
23
|
+
require_jsx_base.attributeToBuffer(buffer, "", key, value);
|
|
28
24
|
return buffer.length === 1 ? require_utils_html.raw(buffer[0]) : require_utils_html.stringBufferToString(buffer, void 0);
|
|
29
25
|
};
|
|
30
26
|
const jsxEscape = (value) => value;
|
|
@@ -33,5 +29,5 @@ exports.Fragment = require_jsx_base.Fragment;
|
|
|
33
29
|
exports.jsx = require_jsx_jsx_dev_runtime.jsxDEV;
|
|
34
30
|
exports.jsxAttr = jsxAttr;
|
|
35
31
|
exports.jsxEscape = jsxEscape;
|
|
36
|
-
exports.jsxTemplate =
|
|
32
|
+
exports.jsxTemplate = jsxTemplate;
|
|
37
33
|
exports.jsxs = require_jsx_jsx_dev_runtime.jsxDEV;
|
|
@@ -17,7 +17,8 @@ const RETAINED_304_HEADERS = [
|
|
|
17
17
|
];
|
|
18
18
|
const stripWeak = (tag) => tag.replace(/^W\//, "");
|
|
19
19
|
function etagMatches(etag, ifNoneMatch) {
|
|
20
|
-
|
|
20
|
+
const expected = stripWeak(etag);
|
|
21
|
+
return ifNoneMatch?.match(/"[^"]*"/g)?.some((tag) => tag === expected) ?? false;
|
|
21
22
|
}
|
|
22
23
|
function initializeGenerator(generator) {
|
|
23
24
|
if (!generator) {
|
|
@@ -65,6 +66,7 @@ const etag = (options) => {
|
|
|
65
66
|
etag = weak ? `W/"${hash}"` : `"${hash}"`;
|
|
66
67
|
}
|
|
67
68
|
if (ifNoneMatch === "*" || etagMatches(etag, ifNoneMatch)) {
|
|
69
|
+
await res.body?.cancel();
|
|
68
70
|
c.res = new Response(null, {
|
|
69
71
|
status: 304,
|
|
70
72
|
statusText: "Not Modified",
|
|
@@ -75,6 +75,7 @@ const timing = (config) => {
|
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
};
|
|
78
|
+
const quote = (s) => `"${s.replace(/[\\"]/g, "\\$&")}"`;
|
|
78
79
|
/**
|
|
79
80
|
* Set a metric for the timing middleware.
|
|
80
81
|
*
|
|
@@ -97,11 +98,11 @@ const setMetric = (c, name, valueDescription, description, precision) => {
|
|
|
97
98
|
return;
|
|
98
99
|
}
|
|
99
100
|
if (typeof valueDescription === "number") {
|
|
100
|
-
const dur = valueDescription.toFixed(precision
|
|
101
|
-
const metric = description ? `${name};dur=${dur};desc
|
|
101
|
+
const dur = valueDescription.toFixed(precision ?? 1);
|
|
102
|
+
const metric = description ? `${name};dur=${dur};desc=${quote(description)}` : `${name};dur=${dur}`;
|
|
102
103
|
metrics.headers.push(metric);
|
|
103
104
|
} else {
|
|
104
|
-
const metric = valueDescription ? `${name};desc
|
|
105
|
+
const metric = valueDescription ? `${name};desc=${quote(valueDescription)}` : `${name}`;
|
|
105
106
|
metrics.headers.push(metric);
|
|
106
107
|
}
|
|
107
108
|
};
|
|
@@ -80,8 +80,8 @@ const parseSigned = async (cookie, secret, name) => {
|
|
|
80
80
|
const _serialize = (name, value, opt = {}) => {
|
|
81
81
|
if (!validCookieNameRegEx.test(name)) throw new Error("Invalid cookie name");
|
|
82
82
|
let cookie = `${name}=${value}`;
|
|
83
|
-
if (
|
|
84
|
-
if (
|
|
83
|
+
if (/^__secure-/i.test(name) && !opt.secure) throw new Error("__Secure- Cookie must have Secure attributes");
|
|
84
|
+
if (/^__host-/i.test(name)) {
|
|
85
85
|
if (!opt.secure) throw new Error("__Host- Cookie must have Secure attributes");
|
|
86
86
|
if (opt.path !== "/") throw new Error("__Host- Cookie must have Path attributes with \"/\"");
|
|
87
87
|
if (opt.domain) throw new Error("__Host- Cookie must not have Domain attributes");
|
|
@@ -10,7 +10,7 @@ const getMimeType = (filename, mimes = baseMimes) => {
|
|
|
10
10
|
return mimes[match[1].toLowerCase()];
|
|
11
11
|
};
|
|
12
12
|
const getExtension = (mimeType) => {
|
|
13
|
-
const baseType = mimeType.split(";", 1)[0].trim();
|
|
13
|
+
const baseType = mimeType.split(";", 1)[0].trim().toLowerCase();
|
|
14
14
|
for (const ext in baseMimes) {
|
|
15
15
|
const stored = baseMimes[ext];
|
|
16
16
|
if (stored === mimeType || stored.split(";", 1)[0].trim() === baseType) return ext;
|
|
@@ -162,7 +162,7 @@ const _getQueryParam = (url, key, multiple) => {
|
|
|
162
162
|
const hashIndex = url.indexOf("#", 8);
|
|
163
163
|
if (hashIndex !== -1) url = url.slice(0, hashIndex);
|
|
164
164
|
let encoded;
|
|
165
|
-
if (!multiple && key &&
|
|
165
|
+
if (!multiple && key && !/[%+&=]/.test(key)) {
|
|
166
166
|
const queryIndex = url.indexOf("?", 8);
|
|
167
167
|
let keyIndex = queryIndex;
|
|
168
168
|
if (keyIndex === -1) return;
|
|
@@ -57,7 +57,7 @@ const jsonRegex = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(?:;.+)?$/i;
|
|
|
57
57
|
function detectResponseType(response) {
|
|
58
58
|
const _contentType = response.headers.get("content-type");
|
|
59
59
|
if (!_contentType) return "text";
|
|
60
|
-
const contentType = _contentType.split(";").shift();
|
|
60
|
+
const contentType = _contentType.split(";").shift().trim();
|
|
61
61
|
if (jsonRegex.test(contentType)) return "json";
|
|
62
62
|
return "text";
|
|
63
63
|
}
|
|
@@ -19,12 +19,13 @@ const getSpecificity = (type) => {
|
|
|
19
19
|
};
|
|
20
20
|
const defaultMatch = (accepts, config) => {
|
|
21
21
|
const { supports, default: defaultSupport } = config;
|
|
22
|
+
const exactTypes = new Set(accepts.filter((accept) => getSpecificity(accept.type) === 3).map((accept) => accept.type.toLowerCase()));
|
|
22
23
|
const sortedAccepts = accepts.filter((accept) => accept.q > 0).sort((a, b) => {
|
|
23
24
|
if (b.q !== a.q) return b.q - a.q;
|
|
24
25
|
return getSpecificity(b.type) - getSpecificity(a.type);
|
|
25
26
|
});
|
|
26
27
|
for (const accept of sortedAccepts) {
|
|
27
|
-
const matched = supports.find((supported) => matchType(accept.type, supported));
|
|
28
|
+
const matched = supports.find((supported) => matchType(accept.type, supported) && (getSpecificity(accept.type) !== 2 || !exactTypes.has(supported.toLowerCase())));
|
|
28
29
|
if (matched) return matched;
|
|
29
30
|
}
|
|
30
31
|
return defaultSupport;
|
|
@@ -38,6 +38,8 @@ const defaultExtensionMap = {
|
|
|
38
38
|
const determineExtension = (mimeType, userExtensionMap) => {
|
|
39
39
|
const extensionMap = userExtensionMap || defaultExtensionMap;
|
|
40
40
|
if (mimeType in extensionMap) return extensionMap[mimeType];
|
|
41
|
+
const lowerCasedMimeType = mimeType.toLowerCase();
|
|
42
|
+
if (lowerCasedMimeType in extensionMap) return extensionMap[lowerCasedMimeType];
|
|
41
43
|
return getExtension(mimeType) || "html";
|
|
42
44
|
};
|
|
43
45
|
const combineBeforeRequestHooks = (hooks) => {
|
|
@@ -141,8 +143,7 @@ const fetchRoutesContent = function* (app, beforeRequestHook, afterResponseHook,
|
|
|
141
143
|
* `saveContentToFile` is an experimental feature.
|
|
142
144
|
* The API might be changed.
|
|
143
145
|
*/
|
|
144
|
-
const createdDirs = /* @__PURE__ */ new Set()
|
|
145
|
-
const saveContentToFile = async (data, fsModule, outDir, extensionMap) => {
|
|
146
|
+
const saveContentToFile = async (data, fsModule, outDir, extensionMap, createdDirs = /* @__PURE__ */ new Set()) => {
|
|
146
147
|
const awaitedData = await data;
|
|
147
148
|
if (!awaitedData) return;
|
|
148
149
|
const { routePath, content, mimeType } = awaitedData;
|
|
@@ -182,10 +183,11 @@ const toSSG = async (app, fs, options) => {
|
|
|
182
183
|
const concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY;
|
|
183
184
|
const combinedBeforeRequestHook = combineBeforeRequestHooks(beforeRequestHooks.length > 0 ? beforeRequestHooks : [(req) => req]);
|
|
184
185
|
const combinedAfterResponseHook = combineAfterResponseHooks(afterResponseHooks.length > 0 ? afterResponseHooks : [(req) => req]);
|
|
186
|
+
const createdDirs = /* @__PURE__ */ new Set();
|
|
185
187
|
const getInfoGen = fetchRoutesContent(app, combinedBeforeRequestHook, combinedAfterResponseHook, concurrency);
|
|
186
188
|
for (const getInfo of getInfoGen) getInfoPromises.push(getInfo.then((getContentGen) => {
|
|
187
189
|
if (!getContentGen) return;
|
|
188
|
-
for (const content of getContentGen) savePromises.push(saveContentToFile(content, fs, outputDir, options?.extensionMap).catch((e) => e));
|
|
190
|
+
for (const content of getContentGen) savePromises.push(saveContentToFile(content, fs, outputDir, options?.extensionMap, createdDirs).catch((e) => e));
|
|
189
191
|
}));
|
|
190
192
|
await Promise.all(getInfoPromises);
|
|
191
193
|
const files = [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { escapeToBuffer, raw, resolveCallbackSync, stringBufferToString } from "../utils/html.js";
|
|
2
|
-
import { DOM_MEMO, DOM_RENDERER } from "./constants.js";
|
|
2
|
+
import { DOM_MEMO, DOM_RENDERER, RENDERED_JSX } from "./constants.js";
|
|
3
3
|
import { captureRenderContext, createContext, globalContexts, runWithRenderContext, useContext } from "./context.js";
|
|
4
4
|
import { domRenderers } from "./intrinsic-element/common.js";
|
|
5
5
|
import { components_exports } from "./intrinsic-element/components.js";
|
|
@@ -25,7 +25,7 @@ const emptyTags = [
|
|
|
25
25
|
"track",
|
|
26
26
|
"wbr"
|
|
27
27
|
];
|
|
28
|
-
const booleanAttributes = [
|
|
28
|
+
const booleanAttributes = /* @__PURE__ */ new Set([
|
|
29
29
|
"allowfullscreen",
|
|
30
30
|
"async",
|
|
31
31
|
"autofocus",
|
|
@@ -51,8 +51,11 @@ const booleanAttributes = [
|
|
|
51
51
|
"readonly",
|
|
52
52
|
"required",
|
|
53
53
|
"reversed",
|
|
54
|
-
"selected"
|
|
55
|
-
|
|
54
|
+
"selected",
|
|
55
|
+
"shadowrootclonable",
|
|
56
|
+
"shadowrootdelegatesfocus",
|
|
57
|
+
"shadowrootserializable"
|
|
58
|
+
]);
|
|
56
59
|
const resolveFunctionComponentResult = (result, suspendedContext) => result.then((resolved) => {
|
|
57
60
|
if (typeof resolved !== "string" && !Array.isArray(resolved) && !(resolved instanceof JSXNode)) return resolved;
|
|
58
61
|
const children = Array.isArray(resolved) ? resolved : [resolved];
|
|
@@ -63,6 +66,44 @@ const resolveFunctionComponentResult = (result, suspendedContext) => result.then
|
|
|
63
66
|
};
|
|
64
67
|
return suspendedContext ? suspendedContext(render) : runWithRenderContext(render);
|
|
65
68
|
});
|
|
69
|
+
const markRenderedJSX = (value) => {
|
|
70
|
+
value[RENDERED_JSX] = true;
|
|
71
|
+
return value;
|
|
72
|
+
};
|
|
73
|
+
const isEscapedAttribute = (value) => value instanceof String && value.isEscaped && !(RENDERED_JSX in value);
|
|
74
|
+
const objectToAttributeString = (v) => {
|
|
75
|
+
const s = v.toString();
|
|
76
|
+
return s instanceof Promise ? s.then(String) : String(s);
|
|
77
|
+
};
|
|
78
|
+
const attributeToBuffer = (buffer, prefix, key, v, tag) => {
|
|
79
|
+
if (key === "ref" || v === null || v === void 0) return;
|
|
80
|
+
if (typeof v === "boolean" && booleanAttributes.has(key)) {
|
|
81
|
+
if (v) buffer[0] += `${prefix}${key}=""`;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (typeof v === "function") {
|
|
85
|
+
if (!key.startsWith("on")) throw new Error(`Invalid prop '${key}' of type 'function' supplied to ${tag ? `'${tag}'` : "a JSX element"}.`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
buffer[0] += `${prefix}${key}="`;
|
|
89
|
+
if (key === "style" && typeof v === "object") {
|
|
90
|
+
let styleStr = "";
|
|
91
|
+
styleObjectForEach(v, (property, value) => {
|
|
92
|
+
if (value != null) styleStr += `${styleStr ? ";" : ""}${property}:${value}`;
|
|
93
|
+
});
|
|
94
|
+
escapeToBuffer(styleStr, buffer);
|
|
95
|
+
} else if (typeof v === "string") escapeToBuffer(v, buffer);
|
|
96
|
+
else if (typeof v === "number" || isEscapedAttribute(v)) buffer[0] += `${v}`;
|
|
97
|
+
else {
|
|
98
|
+
const s = v instanceof Promise ? v.then((r) => typeof r === "object" && r !== null && !isEscapedAttribute(r) ? objectToAttributeString(r) : r) : objectToAttributeString(v);
|
|
99
|
+
if (s instanceof Promise) {
|
|
100
|
+
buffer.unshift("\"", s);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
escapeToBuffer(s, buffer);
|
|
104
|
+
}
|
|
105
|
+
buffer[0] += "\"";
|
|
106
|
+
};
|
|
66
107
|
const childrenToStringToBuffer = (children, buffer) => {
|
|
67
108
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
68
109
|
const child = children[i];
|
|
@@ -114,7 +155,7 @@ var JSXNode = class {
|
|
|
114
155
|
const render = () => {
|
|
115
156
|
const buffer = [""];
|
|
116
157
|
this.toStringToBuffer(buffer);
|
|
117
|
-
return buffer.length === 1 ? "callbacks" in buffer ? resolveCallbackSync(raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : stringBufferToString(buffer, buffer.callbacks);
|
|
158
|
+
return buffer.length === 1 ? "callbacks" in buffer ? resolveCallbackSync(raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : stringBufferToString(buffer, buffer.callbacks).then(markRenderedJSX);
|
|
118
159
|
};
|
|
119
160
|
return runWithRenderContext(render);
|
|
120
161
|
}
|
|
@@ -127,34 +168,10 @@ var JSXNode = class {
|
|
|
127
168
|
for (let [key, v] of Object.entries(props)) {
|
|
128
169
|
key = normalizeKey(key);
|
|
129
170
|
if (!isValidAttributeName(key)) continue;
|
|
130
|
-
if (key === "children") {} else if (key === "
|
|
131
|
-
let styleStr = "";
|
|
132
|
-
styleObjectForEach(v, (property, value) => {
|
|
133
|
-
if (value != null) styleStr += `${styleStr ? ";" : ""}${property}:${value}`;
|
|
134
|
-
});
|
|
135
|
-
buffer[0] += " style=\"";
|
|
136
|
-
escapeToBuffer(styleStr, buffer);
|
|
137
|
-
buffer[0] += "\"";
|
|
138
|
-
} else if (typeof v === "string") {
|
|
139
|
-
buffer[0] += ` ${key}="`;
|
|
140
|
-
escapeToBuffer(v, buffer);
|
|
141
|
-
buffer[0] += "\"";
|
|
142
|
-
} else if (v === null || v === void 0) {} else if (typeof v === "number" || v.isEscaped) buffer[0] += ` ${key}="${v}"`;
|
|
143
|
-
else if (typeof v === "boolean" && booleanAttributes.includes(key)) {
|
|
144
|
-
if (v) buffer[0] += ` ${key}=""`;
|
|
145
|
-
} else if (key === "dangerouslySetInnerHTML") {
|
|
171
|
+
if (key === "children") {} else if (key === "dangerouslySetInnerHTML" && typeof v === "object" && v !== null && "__html" in v) {
|
|
146
172
|
if (children.length > 0) throw new Error("Can only set one of `children` or `props.dangerouslySetInnerHTML`.");
|
|
147
173
|
children = [raw(v.__html)];
|
|
148
|
-
} else
|
|
149
|
-
buffer[0] += ` ${key}="`;
|
|
150
|
-
buffer.unshift("\"", v);
|
|
151
|
-
} else if (typeof v === "function") {
|
|
152
|
-
if (!key.startsWith("on") && key !== "ref") throw new Error(`Invalid prop '${key}' of type 'function' supplied to '${tag}'.`);
|
|
153
|
-
} else {
|
|
154
|
-
buffer[0] += ` ${key}="`;
|
|
155
|
-
escapeToBuffer(v.toString(), buffer);
|
|
156
|
-
buffer[0] += "\"";
|
|
157
|
-
}
|
|
174
|
+
} else attributeToBuffer(buffer, " ", key, v, tag);
|
|
158
175
|
}
|
|
159
176
|
if (emptyTags.includes(tag) && children.length === 0) {
|
|
160
177
|
buffer[0] += "/>";
|
|
@@ -248,4 +265,4 @@ const cloneElement = (element, props, ...children) => {
|
|
|
248
265
|
};
|
|
249
266
|
const reactAPICompatVersion = "19.0.0-hono-jsx";
|
|
250
267
|
//#endregion
|
|
251
|
-
export { Fragment, JSXFragmentNode, JSXNode, booleanAttributes, cloneElement, getNameSpaceContext, isUntrustedObject, isValidElement, jsx, jsxFn, memo, reactAPICompatVersion, renderChildren, renderUntrustedObject, shallowEqual };
|
|
268
|
+
export { Fragment, JSXFragmentNode, JSXNode, attributeToBuffer, booleanAttributes, cloneElement, getNameSpaceContext, isUntrustedObject, isValidElement, jsx, jsxFn, markRenderedJSX, memo, reactAPICompatVersion, renderChildren, renderUntrustedObject, shallowEqual };
|
|
@@ -77,7 +77,7 @@ const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) =>
|
|
|
77
77
|
buffer[0] = buffer[0].replace(replaceRe, () => fallbackResString);
|
|
78
78
|
return fallbackCallbacks?.length ? raw("", fallbackCallbacks) : "";
|
|
79
79
|
}
|
|
80
|
-
return raw(`<template data-hono-target="E:${index}">${fallbackResString}</template><script>
|
|
80
|
+
return raw(`<template data-hono-target="E:${index}">${fallbackResString}</template><script${nonce ? ` nonce="${nonce}"` : ""}>
|
|
81
81
|
((d,c,n) => {
|
|
82
82
|
c=d.currentScript.previousSibling
|
|
83
83
|
d=d.getElementById('E:${index}')
|
|
@@ -118,7 +118,7 @@ d.parentElement.insertBefore(c.content,d.nextSibling)
|
|
|
118
118
|
buffer[0] += content;
|
|
119
119
|
return raw("", content.callbacks);
|
|
120
120
|
}
|
|
121
|
-
return raw(content + (resolvedCount !== callbacks.length ? "" : `<script>
|
|
121
|
+
return raw(content + (resolvedCount !== callbacks.length ? "" : `<script${nonce ? ` nonce="${nonce}"` : ""}>
|
|
122
122
|
((d,c,n) => {
|
|
123
123
|
d=d.getElementById('E:${index}')
|
|
124
124
|
if(!d)return
|
|
@@ -5,5 +5,6 @@ const DOM_STASH = Symbol("STASH");
|
|
|
5
5
|
const DOM_INTERNAL_TAG = Symbol("INTERNAL");
|
|
6
6
|
const DOM_MEMO = Symbol("MEMO");
|
|
7
7
|
const PERMALINK = Symbol("PERMALINK");
|
|
8
|
+
const RENDERED_JSX = Symbol("RENDERED_JSX");
|
|
8
9
|
//#endregion
|
|
9
|
-
export { DOM_ERROR_HANDLER, DOM_INTERNAL_TAG, DOM_MEMO, DOM_RENDERER, DOM_STASH, PERMALINK };
|
|
10
|
+
export { DOM_ERROR_HANDLER, DOM_INTERNAL_TAG, DOM_MEMO, DOM_RENDERER, DOM_STASH, PERMALINK, RENDERED_JSX };
|
|
@@ -1,31 +1,27 @@
|
|
|
1
1
|
import { escapeToBuffer, raw, stringBufferToString } from "../utils/html.js";
|
|
2
2
|
import { html } from "../helper/html/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { PERMALINK } from "./constants.js";
|
|
4
|
+
import { isValidAttributeName } from "./utils.js";
|
|
5
|
+
import { Fragment, attributeToBuffer, markRenderedJSX } from "./base.js";
|
|
5
6
|
import { jsxDEV } from "./jsx-dev-runtime.js";
|
|
6
7
|
//#region src/jsx/jsx-runtime.ts
|
|
8
|
+
const jsxTemplate = (strings, ...values) => {
|
|
9
|
+
const result = html(strings, ...values);
|
|
10
|
+
return result instanceof Promise ? result.then(markRenderedJSX) : markRenderedJSX(result);
|
|
11
|
+
};
|
|
7
12
|
const jsxAttr = (key, v) => {
|
|
8
13
|
if (!isValidAttributeName(key)) return raw("");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
let styleStr = "";
|
|
12
|
-
styleObjectForEach(v, (property, value) => {
|
|
13
|
-
if (value != null) styleStr += `${styleStr ? ";" : ""}${property}:${value}`;
|
|
14
|
-
});
|
|
15
|
-
escapeToBuffer(styleStr, buffer);
|
|
16
|
-
buffer[0] += "\"";
|
|
17
|
-
} else if (typeof v === "string") {
|
|
14
|
+
if (typeof v === "string") {
|
|
15
|
+
const buffer = [`${key}="`];
|
|
18
16
|
escapeToBuffer(v, buffer);
|
|
19
|
-
buffer[0]
|
|
20
|
-
} else if (v === null || v === void 0) return raw("");
|
|
21
|
-
else if (typeof v === "number" || v.isEscaped) buffer[0] += `${v}"`;
|
|
22
|
-
else if (v instanceof Promise) buffer.unshift("\"", v);
|
|
23
|
-
else {
|
|
24
|
-
escapeToBuffer(v.toString(), buffer);
|
|
25
|
-
buffer[0] += "\"";
|
|
17
|
+
return raw(buffer[0] + "\"");
|
|
26
18
|
}
|
|
19
|
+
let value = v;
|
|
20
|
+
if (typeof value === "function" && (key === "action" || key === "formaction")) value = PERMALINK in value ? value[PERMALINK] : void 0;
|
|
21
|
+
const buffer = [""];
|
|
22
|
+
attributeToBuffer(buffer, "", key, value);
|
|
27
23
|
return buffer.length === 1 ? raw(buffer[0]) : stringBufferToString(buffer, void 0);
|
|
28
24
|
};
|
|
29
25
|
const jsxEscape = (value) => value;
|
|
30
26
|
//#endregion
|
|
31
|
-
export { Fragment, jsxDEV as jsx, jsxAttr, jsxEscape,
|
|
27
|
+
export { Fragment, jsxDEV as jsx, jsxAttr, jsxEscape, jsxTemplate, jsxDEV as jsxs };
|
|
@@ -16,7 +16,8 @@ const RETAINED_304_HEADERS = [
|
|
|
16
16
|
];
|
|
17
17
|
const stripWeak = (tag) => tag.replace(/^W\//, "");
|
|
18
18
|
function etagMatches(etag, ifNoneMatch) {
|
|
19
|
-
|
|
19
|
+
const expected = stripWeak(etag);
|
|
20
|
+
return ifNoneMatch?.match(/"[^"]*"/g)?.some((tag) => tag === expected) ?? false;
|
|
20
21
|
}
|
|
21
22
|
function initializeGenerator(generator) {
|
|
22
23
|
if (!generator) {
|
|
@@ -64,6 +65,7 @@ const etag = (options) => {
|
|
|
64
65
|
etag = weak ? `W/"${hash}"` : `"${hash}"`;
|
|
65
66
|
}
|
|
66
67
|
if (ifNoneMatch === "*" || etagMatches(etag, ifNoneMatch)) {
|
|
68
|
+
await res.body?.cancel();
|
|
67
69
|
c.res = new Response(null, {
|
|
68
70
|
status: 304,
|
|
69
71
|
statusText: "Not Modified",
|
|
@@ -74,6 +74,7 @@ const timing = (config) => {
|
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
|
+
const quote = (s) => `"${s.replace(/[\\"]/g, "\\$&")}"`;
|
|
77
78
|
/**
|
|
78
79
|
* Set a metric for the timing middleware.
|
|
79
80
|
*
|
|
@@ -96,11 +97,11 @@ const setMetric = (c, name, valueDescription, description, precision) => {
|
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
98
99
|
if (typeof valueDescription === "number") {
|
|
99
|
-
const dur = valueDescription.toFixed(precision
|
|
100
|
-
const metric = description ? `${name};dur=${dur};desc
|
|
100
|
+
const dur = valueDescription.toFixed(precision ?? 1);
|
|
101
|
+
const metric = description ? `${name};dur=${dur};desc=${quote(description)}` : `${name};dur=${dur}`;
|
|
101
102
|
metrics.headers.push(metric);
|
|
102
103
|
} else {
|
|
103
|
-
const metric = valueDescription ? `${name};desc
|
|
104
|
+
const metric = valueDescription ? `${name};desc=${quote(valueDescription)}` : `${name}`;
|
|
104
105
|
metrics.headers.push(metric);
|
|
105
106
|
}
|
|
106
107
|
};
|
|
@@ -79,8 +79,8 @@ const parseSigned = async (cookie, secret, name) => {
|
|
|
79
79
|
const _serialize = (name, value, opt = {}) => {
|
|
80
80
|
if (!validCookieNameRegEx.test(name)) throw new Error("Invalid cookie name");
|
|
81
81
|
let cookie = `${name}=${value}`;
|
|
82
|
-
if (
|
|
83
|
-
if (
|
|
82
|
+
if (/^__secure-/i.test(name) && !opt.secure) throw new Error("__Secure- Cookie must have Secure attributes");
|
|
83
|
+
if (/^__host-/i.test(name)) {
|
|
84
84
|
if (!opt.secure) throw new Error("__Host- Cookie must have Secure attributes");
|
|
85
85
|
if (opt.path !== "/") throw new Error("__Host- Cookie must have Path attributes with \"/\"");
|
|
86
86
|
if (opt.domain) throw new Error("__Host- Cookie must not have Domain attributes");
|
|
@@ -9,7 +9,7 @@ const getMimeType = (filename, mimes = baseMimes) => {
|
|
|
9
9
|
return mimes[match[1].toLowerCase()];
|
|
10
10
|
};
|
|
11
11
|
const getExtension = (mimeType) => {
|
|
12
|
-
const baseType = mimeType.split(";", 1)[0].trim();
|
|
12
|
+
const baseType = mimeType.split(";", 1)[0].trim().toLowerCase();
|
|
13
13
|
for (const ext in baseMimes) {
|
|
14
14
|
const stored = baseMimes[ext];
|
|
15
15
|
if (stored === mimeType || stored.split(";", 1)[0].trim() === baseType) return ext;
|