hono 4.12.10 → 4.12.12
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/cjs/helper/css/common.js +56 -7
- package/dist/cjs/helper/css/index.js +11 -4
- package/dist/cjs/helper/ssg/ssg.js +10 -8
- package/dist/cjs/helper/ssg/utils.js +9 -0
- package/dist/cjs/jsx/dom/css.js +11 -4
- package/dist/cjs/middleware/ip-restriction/index.js +31 -9
- package/dist/cjs/middleware/serve-static/index.js +1 -1
- package/dist/cjs/utils/cookie.js +26 -5
- package/dist/cjs/utils/ipaddr.js +10 -4
- package/dist/helper/css/common.js +56 -7
- package/dist/helper/css/index.js +11 -4
- package/dist/helper/ssg/ssg.js +17 -9
- package/dist/helper/ssg/utils.js +8 -0
- package/dist/jsx/dom/css.js +11 -4
- package/dist/middleware/ip-restriction/index.js +34 -10
- package/dist/middleware/serve-static/index.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/helper/css/common.d.ts +20 -3
- package/dist/types/helper/css/index.d.ts +9 -2
- package/dist/types/helper/ssg/utils.d.ts +1 -0
- package/dist/types/jsx/dom/css.d.ts +8 -2
- package/dist/types/utils/ipaddr.d.ts +12 -0
- package/dist/utils/cookie.js +26 -5
- package/dist/utils/ipaddr.js +7 -3
- package/package.json +1 -1
|
@@ -57,6 +57,23 @@ const toHash = (str) => {
|
|
|
57
57
|
}
|
|
58
58
|
return "css-" + out;
|
|
59
59
|
};
|
|
60
|
+
const normalizeLabel = (label) => {
|
|
61
|
+
return label.trim().replace(/\s+/g, "-");
|
|
62
|
+
};
|
|
63
|
+
const isValidClassName = (name) => /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/.test(name);
|
|
64
|
+
const RESERVED_KEYFRAME_NAMES = /* @__PURE__ */ new Set([
|
|
65
|
+
"default",
|
|
66
|
+
"inherit",
|
|
67
|
+
"initial",
|
|
68
|
+
"none",
|
|
69
|
+
"revert",
|
|
70
|
+
"revert-layer",
|
|
71
|
+
"unset"
|
|
72
|
+
]);
|
|
73
|
+
const isValidKeyframeName = (name) => isValidClassName(name) && !RESERVED_KEYFRAME_NAMES.has(name.toLowerCase());
|
|
74
|
+
const defaultOnInvalidSlug = (slug) => {
|
|
75
|
+
console.warn(`Invalid slug: ${slug}`);
|
|
76
|
+
};
|
|
60
77
|
const cssStringReStr = [
|
|
61
78
|
'"(?:(?:\\\\[\\s\\S]|[^"\\\\])*)"',
|
|
62
79
|
// double quoted string
|
|
@@ -143,13 +160,26 @@ const buildStyleString = (strings, values) => {
|
|
|
143
160
|
}
|
|
144
161
|
return [label, minify(styleString), selectors, externalClassNames];
|
|
145
162
|
};
|
|
146
|
-
const cssCommon = (strings, values) => {
|
|
163
|
+
const cssCommon = (strings, values, classNameSlug, onInvalidSlug) => {
|
|
147
164
|
let [label, thisStyleString, selectors, externalClassNames] = buildStyleString(strings, values);
|
|
148
165
|
const isPseudoGlobal = isPseudoGlobalSelectorRe.exec(thisStyleString);
|
|
149
166
|
if (isPseudoGlobal) {
|
|
150
167
|
thisStyleString = isPseudoGlobal[1];
|
|
151
168
|
}
|
|
152
|
-
const
|
|
169
|
+
const hash = toHash(label + thisStyleString);
|
|
170
|
+
let customSlug;
|
|
171
|
+
if (classNameSlug) {
|
|
172
|
+
const slug = classNameSlug(hash, normalizeLabel(label), thisStyleString);
|
|
173
|
+
if (slug) {
|
|
174
|
+
if (isValidClassName(slug)) {
|
|
175
|
+
customSlug = slug;
|
|
176
|
+
} else {
|
|
177
|
+
;
|
|
178
|
+
(onInvalidSlug || defaultOnInvalidSlug)(slug);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const selector = (isPseudoGlobal ? PSEUDO_GLOBAL_SELECTOR : "") + (customSlug || hash);
|
|
153
183
|
const className = (isPseudoGlobal ? selectors.map((s) => s[CLASS_NAME]) : [selector, ...externalClassNames]).join(" ");
|
|
154
184
|
return {
|
|
155
185
|
[SELECTOR]: selector,
|
|
@@ -174,24 +204,43 @@ const cxCommon = (args) => {
|
|
|
174
204
|
}
|
|
175
205
|
return args;
|
|
176
206
|
};
|
|
177
|
-
const keyframesCommon = (strings,
|
|
207
|
+
const keyframesCommon = (strings, values, classNameSlug, onInvalidSlug) => {
|
|
178
208
|
const [label, styleString] = buildStyleString(strings, values);
|
|
209
|
+
const hash = toHash(label + styleString);
|
|
210
|
+
let customSlug;
|
|
211
|
+
if (classNameSlug) {
|
|
212
|
+
const slug = classNameSlug(hash, normalizeLabel(label), styleString);
|
|
213
|
+
if (slug) {
|
|
214
|
+
if (isValidKeyframeName(slug)) {
|
|
215
|
+
customSlug = slug;
|
|
216
|
+
} else {
|
|
217
|
+
;
|
|
218
|
+
(onInvalidSlug || defaultOnInvalidSlug)(slug);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
179
222
|
return {
|
|
180
223
|
[SELECTOR]: "",
|
|
181
|
-
[CLASS_NAME]: `@keyframes ${
|
|
224
|
+
[CLASS_NAME]: `@keyframes ${customSlug || hash}`,
|
|
182
225
|
[STYLE_STRING]: styleString,
|
|
183
226
|
[SELECTORS]: [],
|
|
184
227
|
[EXTERNAL_CLASS_NAMES]: []
|
|
185
228
|
};
|
|
186
229
|
};
|
|
187
230
|
let viewTransitionNameIndex = 0;
|
|
188
|
-
const viewTransitionCommon = ((strings, values) => {
|
|
231
|
+
const viewTransitionCommon = ((strings, values, classNameSlug, onInvalidSlug) => {
|
|
189
232
|
if (!strings) {
|
|
190
233
|
strings = [`/* h-v-t ${viewTransitionNameIndex++} */`];
|
|
191
234
|
}
|
|
192
|
-
const content = Array.isArray(strings) ? cssCommon(strings, values) : strings;
|
|
235
|
+
const content = Array.isArray(strings) ? cssCommon(strings, values, classNameSlug, onInvalidSlug) : strings;
|
|
193
236
|
const transitionName = content[CLASS_NAME];
|
|
194
|
-
const res = cssCommon(
|
|
237
|
+
const res = cssCommon(
|
|
238
|
+
["view-transition-name:", ""],
|
|
239
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
240
|
+
[transitionName],
|
|
241
|
+
classNameSlug,
|
|
242
|
+
onInvalidSlug
|
|
243
|
+
);
|
|
195
244
|
content[CLASS_NAME] = PSEUDO_GLOBAL_SELECTOR + content[CLASS_NAME];
|
|
196
245
|
content[STYLE_STRING] = content[STYLE_STRING].replace(
|
|
197
246
|
/(?<=::view-transition(?:[a-z-]*)\()(?=\))/g,
|
|
@@ -31,7 +31,11 @@ var import_constants = require("../../jsx/constants");
|
|
|
31
31
|
var import_css = require("../../jsx/dom/css");
|
|
32
32
|
var import_common = require("./common");
|
|
33
33
|
var import_common2 = require("./common");
|
|
34
|
-
const createCssContext = ({
|
|
34
|
+
const createCssContext = ({
|
|
35
|
+
id,
|
|
36
|
+
classNameSlug,
|
|
37
|
+
onInvalidSlug
|
|
38
|
+
}) => {
|
|
35
39
|
const [cssJsxDomObject, StyleRenderToDom] = (0, import_css.createCssJsxDomObjects)({ id });
|
|
36
40
|
const contextMap = /* @__PURE__ */ new WeakMap();
|
|
37
41
|
const nonceMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -94,15 +98,18 @@ const createCssContext = ({ id }) => {
|
|
|
94
98
|
return promise;
|
|
95
99
|
};
|
|
96
100
|
const css2 = (strings, ...values) => {
|
|
97
|
-
return newCssClassNameObject((0, import_common.cssCommon)(strings, values));
|
|
101
|
+
return newCssClassNameObject((0, import_common.cssCommon)(strings, values, classNameSlug, onInvalidSlug));
|
|
98
102
|
};
|
|
99
103
|
const cx2 = (...args) => {
|
|
100
104
|
args = (0, import_common.cxCommon)(args);
|
|
101
105
|
return css2(Array(args.length).fill(""), ...args);
|
|
102
106
|
};
|
|
103
|
-
const keyframes2 = import_common.keyframesCommon;
|
|
107
|
+
const keyframes2 = (strings, ...values) => (0, import_common.keyframesCommon)(strings, values, classNameSlug, onInvalidSlug);
|
|
104
108
|
const viewTransition2 = ((strings, ...values) => {
|
|
105
|
-
return newCssClassNameObject(
|
|
109
|
+
return newCssClassNameObject(
|
|
110
|
+
(0, import_common.viewTransitionCommon)(strings, values, classNameSlug, onInvalidSlug)
|
|
111
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
112
|
+
);
|
|
106
113
|
});
|
|
107
114
|
const Style2 = ({ children, nonce } = {}) => (0, import_html.raw)(
|
|
108
115
|
`<style id="${id}"${nonce ? ` nonce="${nonce}"` : ""}>${children ? children[import_common.STYLE_STRING] : ""}</style>`,
|
|
@@ -38,16 +38,18 @@ const DEFAULT_CONTENT_TYPE = "text/plain";
|
|
|
38
38
|
const DEFAULT_OUTPUT_DIR = "./static";
|
|
39
39
|
const generateFilePath = (routePath, outDir, mimeType, extensionMap) => {
|
|
40
40
|
const extension = determineExtension(mimeType, extensionMap);
|
|
41
|
+
let filePath;
|
|
41
42
|
if (routePath.endsWith(`.${extension}`)) {
|
|
42
|
-
|
|
43
|
+
filePath = (0, import_utils2.joinPaths)(outDir, routePath);
|
|
44
|
+
} else if (routePath === "/") {
|
|
45
|
+
filePath = (0, import_utils2.joinPaths)(outDir, `index.${extension}`);
|
|
46
|
+
} else if (routePath.endsWith("/")) {
|
|
47
|
+
filePath = (0, import_utils2.joinPaths)(outDir, routePath, `index.${extension}`);
|
|
48
|
+
} else {
|
|
49
|
+
filePath = (0, import_utils2.joinPaths)(outDir, `${routePath}.${extension}`);
|
|
43
50
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
if (routePath.endsWith("/")) {
|
|
48
|
-
return (0, import_utils2.joinPaths)(outDir, routePath, `index.${extension}`);
|
|
49
|
-
}
|
|
50
|
-
return (0, import_utils2.joinPaths)(outDir, `${routePath}.${extension}`);
|
|
51
|
+
(0, import_utils2.ensureWithinOutDir)(outDir, filePath);
|
|
52
|
+
return filePath;
|
|
51
53
|
};
|
|
52
54
|
const parseResponseContent = async (response) => {
|
|
53
55
|
const contentType = response.headers.get("Content-Type");
|
|
@@ -18,6 +18,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
18
18
|
var utils_exports = {};
|
|
19
19
|
__export(utils_exports, {
|
|
20
20
|
dirname: () => dirname,
|
|
21
|
+
ensureWithinOutDir: () => ensureWithinOutDir,
|
|
21
22
|
filterStaticGenerateRoutes: () => filterStaticGenerateRoutes,
|
|
22
23
|
isDynamicRoute: () => isDynamicRoute,
|
|
23
24
|
joinPaths: () => joinPaths
|
|
@@ -75,9 +76,17 @@ const filterStaticGenerateRoutes = (hono) => {
|
|
|
75
76
|
const isDynamicRoute = (path) => {
|
|
76
77
|
return path.split("/").some((segment) => segment.startsWith(":") || segment.includes("*"));
|
|
77
78
|
};
|
|
79
|
+
const ensureWithinOutDir = (outDir, filePath) => {
|
|
80
|
+
const normalizedOutDir = joinPaths("/", outDir);
|
|
81
|
+
const normalizedFilePath = joinPaths("/", filePath);
|
|
82
|
+
if (normalizedFilePath !== normalizedOutDir && !normalizedFilePath.startsWith(`${normalizedOutDir}/`)) {
|
|
83
|
+
throw new Error(`Path traversal detected: "${filePath}" is outside the output directory`);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
78
86
|
// Annotate the CommonJS export names for ESM import in node:
|
|
79
87
|
0 && (module.exports = {
|
|
80
88
|
dirname,
|
|
89
|
+
ensureWithinOutDir,
|
|
81
90
|
filterStaticGenerateRoutes,
|
|
82
91
|
isDynamicRoute,
|
|
83
92
|
joinPaths
|
package/dist/cjs/jsx/dom/css.js
CHANGED
|
@@ -117,22 +117,29 @@ const createCssJsxDomObjects = ({ id }) => {
|
|
|
117
117
|
});
|
|
118
118
|
return [cssObject, Style2];
|
|
119
119
|
};
|
|
120
|
-
const createCssContext = ({
|
|
120
|
+
const createCssContext = ({
|
|
121
|
+
id,
|
|
122
|
+
classNameSlug,
|
|
123
|
+
onInvalidSlug
|
|
124
|
+
}) => {
|
|
121
125
|
const [cssObject, Style2] = createCssJsxDomObjects({ id });
|
|
122
126
|
const newCssClassNameObject = (cssClassName) => {
|
|
123
127
|
cssClassName.toString = cssObject.toString;
|
|
124
128
|
return cssClassName;
|
|
125
129
|
};
|
|
126
130
|
const css2 = (strings, ...values) => {
|
|
127
|
-
return newCssClassNameObject((0, import_common.cssCommon)(strings, values));
|
|
131
|
+
return newCssClassNameObject((0, import_common.cssCommon)(strings, values, classNameSlug, onInvalidSlug));
|
|
128
132
|
};
|
|
129
133
|
const cx2 = (...args) => {
|
|
130
134
|
args = (0, import_common.cxCommon)(args);
|
|
131
135
|
return css2(Array(args.length).fill(""), ...args);
|
|
132
136
|
};
|
|
133
|
-
const keyframes2 = import_common.keyframesCommon;
|
|
137
|
+
const keyframes2 = (strings, ...values) => (0, import_common.keyframesCommon)(strings, values, classNameSlug, onInvalidSlug);
|
|
134
138
|
const viewTransition2 = ((strings, ...values) => {
|
|
135
|
-
return newCssClassNameObject(
|
|
139
|
+
return newCssClassNameObject(
|
|
140
|
+
(0, import_common.viewTransitionCommon)(strings, values, classNameSlug, onInvalidSlug)
|
|
141
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
142
|
+
);
|
|
136
143
|
});
|
|
137
144
|
return {
|
|
138
145
|
css: css2,
|
|
@@ -40,12 +40,17 @@ const buildMatcher = (rules) => {
|
|
|
40
40
|
if (type2 === void 0) {
|
|
41
41
|
throw new TypeError(`Invalid rule: ${rule}`);
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
let isIPv4 = type2 === "IPv4";
|
|
44
|
+
let prefix = parseInt(separatedRule[1]);
|
|
45
45
|
if (isIPv4 ? prefix === 32 : prefix === 128) {
|
|
46
46
|
rule = addrStr;
|
|
47
47
|
} else {
|
|
48
|
-
|
|
48
|
+
let addr = (isIPv4 ? import_ipaddr.convertIPv4ToBinary : import_ipaddr.convertIPv6ToBinary)(addrStr);
|
|
49
|
+
if (type2 === "IPv6" && (0, import_ipaddr.isIPv4MappedIPv6)(addr) && prefix >= 96) {
|
|
50
|
+
isIPv4 = true;
|
|
51
|
+
addr = (0, import_ipaddr.convertIPv4MappedIPv6ToIPv4)(addr);
|
|
52
|
+
prefix -= 96;
|
|
53
|
+
}
|
|
49
54
|
const mask = (1n << BigInt(prefix)) - 1n << BigInt((isIPv4 ? 32 : 128) - prefix);
|
|
50
55
|
cidrRules.push([isIPv4, addr & mask, mask]);
|
|
51
56
|
continue;
|
|
@@ -55,21 +60,38 @@ const buildMatcher = (rules) => {
|
|
|
55
60
|
if (type === void 0) {
|
|
56
61
|
throw new TypeError(`Invalid rule: ${rule}`);
|
|
57
62
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
if (type === "IPv4") {
|
|
64
|
+
staticRules.add(rule);
|
|
65
|
+
staticRules.add(`::ffff:${rule}`);
|
|
66
|
+
} else {
|
|
67
|
+
const ipv6binary = (0, import_ipaddr.convertIPv6ToBinary)(rule);
|
|
68
|
+
const ipv6Addr = (0, import_ipaddr.convertIPv6BinaryToString)(ipv6binary);
|
|
69
|
+
staticRules.add(ipv6Addr);
|
|
70
|
+
if ((0, import_ipaddr.isIPv4MappedIPv6)(ipv6binary)) {
|
|
71
|
+
staticRules.add(ipv6Addr.substring(7));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
62
74
|
}
|
|
63
75
|
}
|
|
64
76
|
return (remote) => {
|
|
65
77
|
if (staticRules.has(remote.addr)) {
|
|
66
78
|
return true;
|
|
67
79
|
}
|
|
80
|
+
const remoteAddr = remote.binaryAddr ||= (remote.isIPv4 ? import_ipaddr.convertIPv4ToBinary : import_ipaddr.convertIPv6ToBinary)(remote.addr);
|
|
81
|
+
const remoteIPv4Addr = remote.isIPv4 || (0, import_ipaddr.isIPv4MappedIPv6)(remoteAddr) ? remote.isIPv4 ? remoteAddr : (0, import_ipaddr.convertIPv4MappedIPv6ToIPv4)(remoteAddr) : void 0;
|
|
68
82
|
for (const [isIPv4, addr, mask] of cidrRules) {
|
|
69
|
-
if (isIPv4
|
|
83
|
+
if (isIPv4) {
|
|
84
|
+
if (remoteIPv4Addr === void 0) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if ((remoteIPv4Addr & mask) === addr) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (remote.isIPv4) {
|
|
70
93
|
continue;
|
|
71
94
|
}
|
|
72
|
-
const remoteAddr = remote.binaryAddr ||= (isIPv4 ? import_ipaddr.convertIPv4ToBinary : import_ipaddr.convertIPv6ToBinary)(remote.addr);
|
|
73
95
|
if ((remoteAddr & mask) === addr) {
|
|
74
96
|
return true;
|
|
75
97
|
}
|
|
@@ -45,7 +45,7 @@ const serveStatic = (options) => {
|
|
|
45
45
|
} else {
|
|
46
46
|
try {
|
|
47
47
|
filename = (0, import_url.tryDecodeURI)(c.req.path);
|
|
48
|
-
if (/(?:^|[\/\\])
|
|
48
|
+
if (/(?:^|[\/\\])\.{1,2}(?:$|[\/\\])|[\/\\]{2,}/.test(filename)) {
|
|
49
49
|
throw new Error();
|
|
50
50
|
}
|
|
51
51
|
} catch {
|
package/dist/cjs/utils/cookie.js
CHANGED
|
@@ -48,23 +48,41 @@ const verifySignature = async (base64Signature, value, secret) => {
|
|
|
48
48
|
};
|
|
49
49
|
const validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/;
|
|
50
50
|
const validCookieValueRegEx = /^[ !#-:<-[\]-~]*$/;
|
|
51
|
+
const trimCookieWhitespace = (value) => {
|
|
52
|
+
let start = 0;
|
|
53
|
+
let end = value.length;
|
|
54
|
+
while (start < end) {
|
|
55
|
+
const charCode = value.charCodeAt(start);
|
|
56
|
+
if (charCode !== 32 && charCode !== 9) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
start++;
|
|
60
|
+
}
|
|
61
|
+
while (end > start) {
|
|
62
|
+
const charCode = value.charCodeAt(end - 1);
|
|
63
|
+
if (charCode !== 32 && charCode !== 9) {
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
end--;
|
|
67
|
+
}
|
|
68
|
+
return start === 0 && end === value.length ? value : value.slice(start, end);
|
|
69
|
+
};
|
|
51
70
|
const parse = (cookie, name) => {
|
|
52
71
|
if (name && cookie.indexOf(name) === -1) {
|
|
53
72
|
return {};
|
|
54
73
|
}
|
|
55
|
-
const pairs = cookie.
|
|
74
|
+
const pairs = cookie.split(";");
|
|
56
75
|
const parsedCookie = {};
|
|
57
|
-
for (
|
|
58
|
-
pairStr = pairStr.trim();
|
|
76
|
+
for (const pairStr of pairs) {
|
|
59
77
|
const valueStartPos = pairStr.indexOf("=");
|
|
60
78
|
if (valueStartPos === -1) {
|
|
61
79
|
continue;
|
|
62
80
|
}
|
|
63
|
-
const cookieName = pairStr.substring(0, valueStartPos)
|
|
81
|
+
const cookieName = trimCookieWhitespace(pairStr.substring(0, valueStartPos));
|
|
64
82
|
if (name && name !== cookieName || !validCookieNameRegEx.test(cookieName)) {
|
|
65
83
|
continue;
|
|
66
84
|
}
|
|
67
|
-
let cookieValue = pairStr.substring(valueStartPos + 1)
|
|
85
|
+
let cookieValue = trimCookieWhitespace(pairStr.substring(valueStartPos + 1));
|
|
68
86
|
if (cookieValue.startsWith('"') && cookieValue.endsWith('"')) {
|
|
69
87
|
cookieValue = cookieValue.slice(1, -1);
|
|
70
88
|
}
|
|
@@ -96,6 +114,9 @@ const parseSigned = async (cookie, secret, name) => {
|
|
|
96
114
|
return parsedCookie;
|
|
97
115
|
};
|
|
98
116
|
const _serialize = (name, value, opt = {}) => {
|
|
117
|
+
if (!validCookieNameRegEx.test(name)) {
|
|
118
|
+
throw new Error("Invalid cookie name");
|
|
119
|
+
}
|
|
99
120
|
let cookie = `${name}=${value}`;
|
|
100
121
|
if (name.startsWith("__Secure-") && !opt.secure) {
|
|
101
122
|
throw new Error("__Secure- Cookie must have Secure attributes");
|
package/dist/cjs/utils/ipaddr.js
CHANGED
|
@@ -18,11 +18,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
18
18
|
var ipaddr_exports = {};
|
|
19
19
|
__export(ipaddr_exports, {
|
|
20
20
|
convertIPv4BinaryToString: () => convertIPv4BinaryToString,
|
|
21
|
+
convertIPv4MappedIPv6ToIPv4: () => convertIPv4MappedIPv6ToIPv4,
|
|
21
22
|
convertIPv4ToBinary: () => convertIPv4ToBinary,
|
|
22
23
|
convertIPv6BinaryToString: () => convertIPv6BinaryToString,
|
|
23
24
|
convertIPv6ToBinary: () => convertIPv6ToBinary,
|
|
24
25
|
distinctRemoteAddr: () => distinctRemoteAddr,
|
|
25
|
-
expandIPv6: () => expandIPv6
|
|
26
|
+
expandIPv6: () => expandIPv6,
|
|
27
|
+
isIPv4MappedIPv6: () => isIPv4MappedIPv6
|
|
26
28
|
});
|
|
27
29
|
module.exports = __toCommonJS(ipaddr_exports);
|
|
28
30
|
const expandIPv6 = (ipV6) => {
|
|
@@ -81,9 +83,11 @@ const convertIPv4BinaryToString = (ipV4) => {
|
|
|
81
83
|
}
|
|
82
84
|
return sections.join(".");
|
|
83
85
|
};
|
|
86
|
+
const isIPv4MappedIPv6 = (ipv6binary) => ipv6binary >> 32n === 0xffffn;
|
|
87
|
+
const convertIPv4MappedIPv6ToIPv4 = (ipv6binary) => ipv6binary & 0xffffffffn;
|
|
84
88
|
const convertIPv6BinaryToString = (ipV6) => {
|
|
85
|
-
if (ipV6
|
|
86
|
-
return `::ffff:${convertIPv4BinaryToString(ipV6
|
|
89
|
+
if (isIPv4MappedIPv6(ipV6)) {
|
|
90
|
+
return `::ffff:${convertIPv4BinaryToString(convertIPv4MappedIPv6ToIPv4(ipV6))}`;
|
|
87
91
|
}
|
|
88
92
|
const sections = [];
|
|
89
93
|
for (let i = 0; i < 8; i++) {
|
|
@@ -121,9 +125,11 @@ const convertIPv6BinaryToString = (ipV6) => {
|
|
|
121
125
|
// Annotate the CommonJS export names for ESM import in node:
|
|
122
126
|
0 && (module.exports = {
|
|
123
127
|
convertIPv4BinaryToString,
|
|
128
|
+
convertIPv4MappedIPv6ToIPv4,
|
|
124
129
|
convertIPv4ToBinary,
|
|
125
130
|
convertIPv6BinaryToString,
|
|
126
131
|
convertIPv6ToBinary,
|
|
127
132
|
distinctRemoteAddr,
|
|
128
|
-
expandIPv6
|
|
133
|
+
expandIPv6,
|
|
134
|
+
isIPv4MappedIPv6
|
|
129
135
|
});
|
|
@@ -21,6 +21,23 @@ var toHash = (str) => {
|
|
|
21
21
|
}
|
|
22
22
|
return "css-" + out;
|
|
23
23
|
};
|
|
24
|
+
var normalizeLabel = (label) => {
|
|
25
|
+
return label.trim().replace(/\s+/g, "-");
|
|
26
|
+
};
|
|
27
|
+
var isValidClassName = (name) => /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/.test(name);
|
|
28
|
+
var RESERVED_KEYFRAME_NAMES = /* @__PURE__ */ new Set([
|
|
29
|
+
"default",
|
|
30
|
+
"inherit",
|
|
31
|
+
"initial",
|
|
32
|
+
"none",
|
|
33
|
+
"revert",
|
|
34
|
+
"revert-layer",
|
|
35
|
+
"unset"
|
|
36
|
+
]);
|
|
37
|
+
var isValidKeyframeName = (name) => isValidClassName(name) && !RESERVED_KEYFRAME_NAMES.has(name.toLowerCase());
|
|
38
|
+
var defaultOnInvalidSlug = (slug) => {
|
|
39
|
+
console.warn(`Invalid slug: ${slug}`);
|
|
40
|
+
};
|
|
24
41
|
var cssStringReStr = [
|
|
25
42
|
'"(?:(?:\\\\[\\s\\S]|[^"\\\\])*)"',
|
|
26
43
|
// double quoted string
|
|
@@ -107,13 +124,26 @@ var buildStyleString = (strings, values) => {
|
|
|
107
124
|
}
|
|
108
125
|
return [label, minify(styleString), selectors, externalClassNames];
|
|
109
126
|
};
|
|
110
|
-
var cssCommon = (strings, values) => {
|
|
127
|
+
var cssCommon = (strings, values, classNameSlug, onInvalidSlug) => {
|
|
111
128
|
let [label, thisStyleString, selectors, externalClassNames] = buildStyleString(strings, values);
|
|
112
129
|
const isPseudoGlobal = isPseudoGlobalSelectorRe.exec(thisStyleString);
|
|
113
130
|
if (isPseudoGlobal) {
|
|
114
131
|
thisStyleString = isPseudoGlobal[1];
|
|
115
132
|
}
|
|
116
|
-
const
|
|
133
|
+
const hash = toHash(label + thisStyleString);
|
|
134
|
+
let customSlug;
|
|
135
|
+
if (classNameSlug) {
|
|
136
|
+
const slug = classNameSlug(hash, normalizeLabel(label), thisStyleString);
|
|
137
|
+
if (slug) {
|
|
138
|
+
if (isValidClassName(slug)) {
|
|
139
|
+
customSlug = slug;
|
|
140
|
+
} else {
|
|
141
|
+
;
|
|
142
|
+
(onInvalidSlug || defaultOnInvalidSlug)(slug);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const selector = (isPseudoGlobal ? PSEUDO_GLOBAL_SELECTOR : "") + (customSlug || hash);
|
|
117
147
|
const className = (isPseudoGlobal ? selectors.map((s) => s[CLASS_NAME]) : [selector, ...externalClassNames]).join(" ");
|
|
118
148
|
return {
|
|
119
149
|
[SELECTOR]: selector,
|
|
@@ -138,24 +168,43 @@ var cxCommon = (args) => {
|
|
|
138
168
|
}
|
|
139
169
|
return args;
|
|
140
170
|
};
|
|
141
|
-
var keyframesCommon = (strings,
|
|
171
|
+
var keyframesCommon = (strings, values, classNameSlug, onInvalidSlug) => {
|
|
142
172
|
const [label, styleString] = buildStyleString(strings, values);
|
|
173
|
+
const hash = toHash(label + styleString);
|
|
174
|
+
let customSlug;
|
|
175
|
+
if (classNameSlug) {
|
|
176
|
+
const slug = classNameSlug(hash, normalizeLabel(label), styleString);
|
|
177
|
+
if (slug) {
|
|
178
|
+
if (isValidKeyframeName(slug)) {
|
|
179
|
+
customSlug = slug;
|
|
180
|
+
} else {
|
|
181
|
+
;
|
|
182
|
+
(onInvalidSlug || defaultOnInvalidSlug)(slug);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
143
186
|
return {
|
|
144
187
|
[SELECTOR]: "",
|
|
145
|
-
[CLASS_NAME]: `@keyframes ${
|
|
188
|
+
[CLASS_NAME]: `@keyframes ${customSlug || hash}`,
|
|
146
189
|
[STYLE_STRING]: styleString,
|
|
147
190
|
[SELECTORS]: [],
|
|
148
191
|
[EXTERNAL_CLASS_NAMES]: []
|
|
149
192
|
};
|
|
150
193
|
};
|
|
151
194
|
var viewTransitionNameIndex = 0;
|
|
152
|
-
var viewTransitionCommon = ((strings, values) => {
|
|
195
|
+
var viewTransitionCommon = ((strings, values, classNameSlug, onInvalidSlug) => {
|
|
153
196
|
if (!strings) {
|
|
154
197
|
strings = [`/* h-v-t ${viewTransitionNameIndex++} */`];
|
|
155
198
|
}
|
|
156
|
-
const content = Array.isArray(strings) ? cssCommon(strings, values) : strings;
|
|
199
|
+
const content = Array.isArray(strings) ? cssCommon(strings, values, classNameSlug, onInvalidSlug) : strings;
|
|
157
200
|
const transitionName = content[CLASS_NAME];
|
|
158
|
-
const res = cssCommon(
|
|
201
|
+
const res = cssCommon(
|
|
202
|
+
["view-transition-name:", ""],
|
|
203
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
204
|
+
[transitionName],
|
|
205
|
+
classNameSlug,
|
|
206
|
+
onInvalidSlug
|
|
207
|
+
);
|
|
159
208
|
content[CLASS_NAME] = PSEUDO_GLOBAL_SELECTOR + content[CLASS_NAME];
|
|
160
209
|
content[STYLE_STRING] = content[STYLE_STRING].replace(
|
|
161
210
|
/(?<=::view-transition(?:[a-z-]*)\()(?=\))/g,
|
package/dist/helper/css/index.js
CHANGED
|
@@ -15,7 +15,11 @@ import {
|
|
|
15
15
|
viewTransitionCommon
|
|
16
16
|
} from "./common.js";
|
|
17
17
|
import { rawCssString } from "./common.js";
|
|
18
|
-
var createCssContext = ({
|
|
18
|
+
var createCssContext = ({
|
|
19
|
+
id,
|
|
20
|
+
classNameSlug,
|
|
21
|
+
onInvalidSlug
|
|
22
|
+
}) => {
|
|
19
23
|
const [cssJsxDomObject, StyleRenderToDom] = createCssJsxDomObjects({ id });
|
|
20
24
|
const contextMap = /* @__PURE__ */ new WeakMap();
|
|
21
25
|
const nonceMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -78,15 +82,18 @@ var createCssContext = ({ id }) => {
|
|
|
78
82
|
return promise;
|
|
79
83
|
};
|
|
80
84
|
const css2 = (strings, ...values) => {
|
|
81
|
-
return newCssClassNameObject(cssCommon(strings, values));
|
|
85
|
+
return newCssClassNameObject(cssCommon(strings, values, classNameSlug, onInvalidSlug));
|
|
82
86
|
};
|
|
83
87
|
const cx2 = (...args) => {
|
|
84
88
|
args = cxCommon(args);
|
|
85
89
|
return css2(Array(args.length).fill(""), ...args);
|
|
86
90
|
};
|
|
87
|
-
const keyframes2 = keyframesCommon;
|
|
91
|
+
const keyframes2 = (strings, ...values) => keyframesCommon(strings, values, classNameSlug, onInvalidSlug);
|
|
88
92
|
const viewTransition2 = ((strings, ...values) => {
|
|
89
|
-
return newCssClassNameObject(
|
|
93
|
+
return newCssClassNameObject(
|
|
94
|
+
viewTransitionCommon(strings, values, classNameSlug, onInvalidSlug)
|
|
95
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
96
|
+
);
|
|
90
97
|
});
|
|
91
98
|
const Style2 = ({ children, nonce } = {}) => raw(
|
|
92
99
|
`<style id="${id}"${nonce ? ` nonce="${nonce}"` : ""}>${children ? children[STYLE_STRING] : ""}</style>`,
|
package/dist/helper/ssg/ssg.js
CHANGED
|
@@ -4,22 +4,30 @@ import { createPool } from "../../utils/concurrent.js";
|
|
|
4
4
|
import { getExtension } from "../../utils/mime.js";
|
|
5
5
|
import { SSG_CONTEXT, X_HONO_DISABLE_SSG_HEADER_KEY } from "./middleware.js";
|
|
6
6
|
import { defaultPlugin } from "./plugins.js";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
dirname,
|
|
9
|
+
ensureWithinOutDir,
|
|
10
|
+
filterStaticGenerateRoutes,
|
|
11
|
+
isDynamicRoute,
|
|
12
|
+
joinPaths
|
|
13
|
+
} from "./utils.js";
|
|
8
14
|
var DEFAULT_CONCURRENCY = 2;
|
|
9
15
|
var DEFAULT_CONTENT_TYPE = "text/plain";
|
|
10
16
|
var DEFAULT_OUTPUT_DIR = "./static";
|
|
11
17
|
var generateFilePath = (routePath, outDir, mimeType, extensionMap) => {
|
|
12
18
|
const extension = determineExtension(mimeType, extensionMap);
|
|
19
|
+
let filePath;
|
|
13
20
|
if (routePath.endsWith(`.${extension}`)) {
|
|
14
|
-
|
|
21
|
+
filePath = joinPaths(outDir, routePath);
|
|
22
|
+
} else if (routePath === "/") {
|
|
23
|
+
filePath = joinPaths(outDir, `index.${extension}`);
|
|
24
|
+
} else if (routePath.endsWith("/")) {
|
|
25
|
+
filePath = joinPaths(outDir, routePath, `index.${extension}`);
|
|
26
|
+
} else {
|
|
27
|
+
filePath = joinPaths(outDir, `${routePath}.${extension}`);
|
|
15
28
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
if (routePath.endsWith("/")) {
|
|
20
|
-
return joinPaths(outDir, routePath, `index.${extension}`);
|
|
21
|
-
}
|
|
22
|
-
return joinPaths(outDir, `${routePath}.${extension}`);
|
|
29
|
+
ensureWithinOutDir(outDir, filePath);
|
|
30
|
+
return filePath;
|
|
23
31
|
};
|
|
24
32
|
var parseResponseContent = async (response) => {
|
|
25
33
|
const contentType = response.headers.get("Content-Type");
|
package/dist/helper/ssg/utils.js
CHANGED
|
@@ -51,8 +51,16 @@ var filterStaticGenerateRoutes = (hono) => {
|
|
|
51
51
|
var isDynamicRoute = (path) => {
|
|
52
52
|
return path.split("/").some((segment) => segment.startsWith(":") || segment.includes("*"));
|
|
53
53
|
};
|
|
54
|
+
var ensureWithinOutDir = (outDir, filePath) => {
|
|
55
|
+
const normalizedOutDir = joinPaths("/", outDir);
|
|
56
|
+
const normalizedFilePath = joinPaths("/", filePath);
|
|
57
|
+
if (normalizedFilePath !== normalizedOutDir && !normalizedFilePath.startsWith(`${normalizedOutDir}/`)) {
|
|
58
|
+
throw new Error(`Path traversal detected: "${filePath}" is outside the output directory`);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
54
61
|
export {
|
|
55
62
|
dirname,
|
|
63
|
+
ensureWithinOutDir,
|
|
56
64
|
filterStaticGenerateRoutes,
|
|
57
65
|
isDynamicRoute,
|
|
58
66
|
joinPaths
|
package/dist/jsx/dom/css.js
CHANGED
|
@@ -100,22 +100,29 @@ var createCssJsxDomObjects = ({ id }) => {
|
|
|
100
100
|
});
|
|
101
101
|
return [cssObject, Style2];
|
|
102
102
|
};
|
|
103
|
-
var createCssContext = ({
|
|
103
|
+
var createCssContext = ({
|
|
104
|
+
id,
|
|
105
|
+
classNameSlug,
|
|
106
|
+
onInvalidSlug
|
|
107
|
+
}) => {
|
|
104
108
|
const [cssObject, Style2] = createCssJsxDomObjects({ id });
|
|
105
109
|
const newCssClassNameObject = (cssClassName) => {
|
|
106
110
|
cssClassName.toString = cssObject.toString;
|
|
107
111
|
return cssClassName;
|
|
108
112
|
};
|
|
109
113
|
const css2 = (strings, ...values) => {
|
|
110
|
-
return newCssClassNameObject(cssCommon(strings, values));
|
|
114
|
+
return newCssClassNameObject(cssCommon(strings, values, classNameSlug, onInvalidSlug));
|
|
111
115
|
};
|
|
112
116
|
const cx2 = (...args) => {
|
|
113
117
|
args = cxCommon(args);
|
|
114
118
|
return css2(Array(args.length).fill(""), ...args);
|
|
115
119
|
};
|
|
116
|
-
const keyframes2 = keyframesCommon;
|
|
120
|
+
const keyframes2 = (strings, ...values) => keyframesCommon(strings, values, classNameSlug, onInvalidSlug);
|
|
117
121
|
const viewTransition2 = ((strings, ...values) => {
|
|
118
|
-
return newCssClassNameObject(
|
|
122
|
+
return newCssClassNameObject(
|
|
123
|
+
viewTransitionCommon(strings, values, classNameSlug, onInvalidSlug)
|
|
124
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
125
|
+
);
|
|
119
126
|
});
|
|
120
127
|
return {
|
|
121
128
|
css: css2,
|