@arkstack/driver-h3 0.10.10 → 0.11.1
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/app.d.ts +21 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/middlewares/index.js +1 -1
- package/dist/{middlewares-BqHKlMaT.js → middlewares-DWmfAXws.js} +5 -3
- package/dist/middlewares-DWmfAXws.js.map +1 -0
- package/dist/types.d.ts +11 -2
- package/package.json +7 -6
- package/dist/middlewares-BqHKlMaT.js.map +0 -1
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { H3Event } from 'h3'
|
|
2
|
+
|
|
3
|
+
declare module '@arkstack/common' {
|
|
4
|
+
interface HookRegistry {
|
|
5
|
+
'middleware:auth': {
|
|
6
|
+
before: (event: H3Event) => void
|
|
7
|
+
after: (event: H3Event) => void
|
|
8
|
+
error: (error: unknown, event: H3Event) => void
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare module '@arkstack/foundry' {
|
|
14
|
+
interface HookRegistry {
|
|
15
|
+
'middleware:auth': {
|
|
16
|
+
before: (event: H3Event) => void
|
|
17
|
+
after: (event: H3Event) => void
|
|
18
|
+
error: (error: unknown, event: H3Event) => void
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
/// <reference path="./app.d.ts" />
|
|
1
2
|
import { a as Router, i as H3Middleware, n as H3DriverOptions, o as defaultErrorHandler, r as H3EventResponse, t as H3Driver } from "./index-DBhjKP9Z.js";
|
|
2
3
|
export { H3Driver, H3DriverOptions, H3EventResponse, H3Middleware, Router, defaultErrorHandler };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as staticAssetHandler } from "./middlewares-
|
|
1
|
+
import { t as staticAssetHandler } from "./middlewares-DWmfAXws.js";
|
|
2
2
|
import { Arkstack, ArkstackKitDriver } from "@arkstack/contract";
|
|
3
3
|
import { H3, HTTPResponse, serve, toResponse } from "h3";
|
|
4
4
|
import { ErrorHandler, Logger, importFile, renderError } from "@arkstack/common";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as auth, n as requestLogger, r as cors, t as staticAssetHandler } from "../middlewares-
|
|
1
|
+
import { i as auth, n as requestLogger, r as cors, t as staticAssetHandler } from "../middlewares-DWmfAXws.js";
|
|
2
2
|
export { auth, cors, requestLogger, staticAssetHandler };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Arkstack } from "@arkstack/contract";
|
|
2
2
|
import { serveStatic } from "h3";
|
|
3
|
-
import {
|
|
3
|
+
import { Logger, nodeEnv } from "@arkstack/common";
|
|
4
|
+
import { Hook } from "@arkstack/foundry";
|
|
4
5
|
import { join, resolve } from "node:path";
|
|
5
6
|
import { readFile, stat } from "node:fs/promises";
|
|
6
7
|
//#region src/middlewares/auth.ts
|
|
@@ -273,7 +274,8 @@ const colors = {
|
|
|
273
274
|
* @returns H3Middleware function
|
|
274
275
|
*/
|
|
275
276
|
const requestLogger = ({ allowInProduction = false } = {}) => async (event, next) => {
|
|
276
|
-
|
|
277
|
+
const VERBOSE = process.env.VERBOSITY != "0";
|
|
278
|
+
if (nodeEnv() === "prod" && !allowInProduction || !VERBOSE) return next();
|
|
277
279
|
await next();
|
|
278
280
|
const start = Date.now();
|
|
279
281
|
const req = event.req;
|
|
@@ -316,4 +318,4 @@ const staticAssetHandler = (publicPath = "public") => {
|
|
|
316
318
|
//#endregion
|
|
317
319
|
export { auth as i, requestLogger as n, cors as r, staticAssetHandler as t };
|
|
318
320
|
|
|
319
|
-
//# sourceMappingURL=middlewares-
|
|
321
|
+
//# sourceMappingURL=middlewares-DWmfAXws.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middlewares-DWmfAXws.js","names":[],"sources":["../src/middlewares/auth.ts","../src/utils/vary.ts","../src/middlewares/cors.ts","../src/middlewares/request-logger.ts","../src/middlewares/static-asset-handler.ts"],"sourcesContent":["import type { H3Event } from 'h3'\nimport { Hook } from '@arkstack/foundry'\n\nexport const auth = async (event: H3Event, next: () => unknown | Promise<unknown>) => {\n const { Auth, AuthenticationException } = await import('@arkstack/auth')\n\n try {\n const token = readBearerToken(event.req.headers.get('authorization'))\n\n if (!token) {\n throw new AuthenticationException('Unauthenticated', {\n req: {\n headers: event.req.headers,\n method: event.req.method,\n url: event.req.url,\n path: getEventPath(event),\n },\n status: 401,\n })\n }\n\n if (Hook.has('middleware:auth', 'before'))\n Hook.get('middleware:auth', 'before')?.(event as never)\n\n const requestSource = {\n headers: event.req.headers,\n method: event.req.method,\n url: event.req.url,\n path: getEventPath(event),\n }\n const auth = Auth.make().setRequest(requestSource)\n const user = await auth.authorizeToken(token)\n\n event.context.user = user\n event.context.auth = auth\n event.context.session = auth.session()\n event.context.authUser = user\n event.context.authToken = token;\n (event.req as any).user = user;\n (event.req as any).auth = auth;\n (event.req as any).session = event.context.session;\n (event.req as any).authUser = user;\n (event.req as any).authToken = token\n\n if (Hook.has('middleware:auth', 'after'))\n Hook.get('middleware:auth', 'after')?.(event as never)\n\n return await next()\n } catch (error) {\n if (Hook.has('middleware:auth', 'error'))\n Hook.get('middleware:auth', 'error')?.(error, event as never)\n\n throw error\n }\n}\n\nconst readBearerToken = (authorization: string | null) => {\n if (!authorization?.startsWith('Bearer ')) {\n return null\n }\n\n return authorization.substring(7)\n}\n\nconst getEventPath = (event: H3Event) => event.req._url?.pathname\n","/*!\n * vary\n * Copyright(c) 2014-2017 Douglas Christopher Wilson\n * MIT Licensed\n */\nimport { H3Event } from 'h3'\n\n/**\n * RegExp to match field-name in RFC 7230 sec 3.2\n *\n * field-name = token\n * token = 1*tchar\n * tchar = \"!\" / \"#\" / \"$\" / \"%\" / \"&\" / \"'\" / \"*\"\n * / \"+\" / \"-\" / \".\" / \"^\" / \"_\" / \"`\" / \"|\" / \"~\"\n * / DIGIT / ALPHA\n * ; any VCHAR, except delimiters\n */\n\nconst FIELD_NAME_REGEXP = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/\n\n/**\n * Append a field to a vary header.\n *\n * @param header\n * @param field\n * @return\n * @public\n */\nexport const append = (header: string, field: string | string[]) => {\n if (typeof header !== 'string') {\n throw new TypeError('header argument is required')\n }\n\n if (!field) {\n throw new TypeError('field argument is required')\n }\n\n // get fields array\n const fields = !Array.isArray(field) ? parse(String(field)) : field\n\n // assert on invalid field names\n for (let j = 0; j < fields.length; j++) {\n if (!FIELD_NAME_REGEXP.test(fields[j])) {\n throw new TypeError('field argument contains an invalid header name')\n }\n }\n\n // existing, unspecified vary\n if (header === '*') {\n return header\n }\n\n // enumerate current values\n let val = header\n const vals = parse(header.toLowerCase())\n\n // unspecified vary\n if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) {\n return '*'\n }\n\n for (let i = 0; i < fields.length; i++) {\n const fld = fields[i].toLowerCase()\n\n // append value (case-preserving)\n if (vals.indexOf(fld) === -1) {\n vals.push(fld)\n val = val ? val + ', ' + fields[i] : fields[i]\n }\n }\n\n return val\n}\n\n/**\n * Parse a vary header into an array.\n *\n * @param header\n * @return\n * @private\n */\n\nexport const parse = (header: string) => {\n let end = 0\n const list = []\n let start = 0\n\n // gather tokens\n for (let i = 0, len = header.length; i < len; i++) {\n switch (header.charCodeAt(i)) {\n case 0x20 /* */:\n if (start === end) {\n start = end = i + 1\n }\n break\n case 0x2c /* , */:\n list.push(header.substring(start, end))\n start = end = i + 1\n break\n default:\n end = i + 1\n break\n }\n }\n\n // final token\n list.push(header.substring(start, end))\n\n return list\n}\n\n/**\n * Mark that a request is varied on a header field.\n *\n * @param res\n * @param field\n * @public\n */\n\nexport const vary = (res?: H3Event['res'], field?: string | string[]) => {\n if (!res || !res.headers.get || !res.headers.set) {\n throw new TypeError('res argument is required')\n }\n\n // get existing header\n let val = res.headers.get('Vary') || ''\n const header = Array.isArray(val) ? val.join(', ') : String(val)\n\n if (!field) {\n return res.headers.set('Vary', '*')\n }\n\n // set new header\n if ((val = append(header, field))) {\n res.headers.set('Vary', val)\n }\n}\n","import { H3Event } from 'h3'\nimport { NextFunction } from 'clear-router/types/h3'\nimport { vary } from '../utils/vary'\n\nconst isString = (s: any) => {\n return typeof s === 'string' || s instanceof String\n}\n\nconst isOriginAllowed = (origin: string, allowedOrigin: string | string[] | RegExp | boolean) => {\n if (Array.isArray(allowedOrigin)) {\n for (let i = 0; i < allowedOrigin.length; ++i) {\n if (isOriginAllowed(origin, allowedOrigin[i])) {\n return true\n }\n }\n\n return false\n } else if (isString(allowedOrigin)) {\n return origin === allowedOrigin\n } else if (allowedOrigin instanceof RegExp) {\n return allowedOrigin.test(origin)\n } else {\n return !!allowedOrigin\n }\n}\n\nconst configureOrigin = (\n options: { origin?: string | string[] | RegExp | boolean },\n req: H3Event['req'],\n) => {\n let isAllowed: boolean\n const requestOrigin = req.headers.get('origin') || '*',\n headers = []\n\n if (!options.origin || options.origin === '*') {\n // allow any origin\n headers.push([\n {\n key: 'Access-Control-Allow-Origin',\n value: '*',\n },\n ])\n } else if (isString(options.origin)) {\n // fixed origin\n headers.push([\n {\n key: 'Access-Control-Allow-Origin',\n value: options.origin,\n },\n ])\n headers.push([\n {\n key: 'Vary',\n value: 'Origin',\n },\n ])\n } else {\n isAllowed = isOriginAllowed(requestOrigin, options.origin)\n // reflect origin\n headers.push([\n {\n key: 'Access-Control-Allow-Origin',\n value: isAllowed ? requestOrigin : false,\n },\n ])\n headers.push([\n {\n key: 'Vary',\n value: 'Origin',\n },\n ])\n }\n\n return headers\n}\n\nconst configureMethods = (options: { methods?: string[] | string }) => {\n let methods = options.methods\n if (Array.isArray(methods)) {\n methods = methods.join(',') // .methods is an array, so turn it into a string\n }\n\n return {\n key: 'Access-Control-Allow-Methods',\n value: methods,\n }\n}\n\nconst configureCredentials = (options: { credentials?: boolean }) => {\n if (options.credentials === true) {\n return {\n key: 'Access-Control-Allow-Credentials',\n value: 'true',\n }\n }\n\n return null\n}\n\nconst configureAllowedHeaders = (\n options: { allowedHeaders?: string[] | string | null; headers?: string[] | string | null },\n req: H3Event['req'],\n) => {\n let allowedHeaders = options.allowedHeaders || options.headers\n const headers = []\n\n if (!allowedHeaders) {\n allowedHeaders = req.headers.get('access-control-request-headers') // .headers wasn't specified, so reflect the request headers\n headers.push([\n {\n key: 'Vary',\n value: 'Access-Control-Request-Headers',\n },\n ])\n } else if (Array.isArray(allowedHeaders)) {\n allowedHeaders = allowedHeaders.join(',') // .headers is an array, so turn it into a string\n }\n if (allowedHeaders && allowedHeaders.length) {\n headers.push([\n {\n key: 'Access-Control-Allow-Headers',\n value: allowedHeaders,\n },\n ])\n }\n\n return headers\n}\n\nfunction configureExposedHeaders (options: { exposedHeaders?: string[] | string }) {\n let headers = options.exposedHeaders\n if (!headers) {\n return null\n } else if (Array.isArray(headers)) {\n headers = headers.join(',') // .headers is an array, so turn it into a string\n }\n if (headers && headers.length) {\n return {\n key: 'Access-Control-Expose-Headers',\n value: headers,\n }\n }\n\n return null\n}\n\nfunction configureMaxAge (options: { maxAge?: number | string }) {\n const maxAge = (typeof options.maxAge === 'number' || options.maxAge) && options.maxAge.toString()\n if (maxAge && maxAge.length) {\n return {\n key: 'Access-Control-Max-Age',\n value: maxAge,\n }\n }\n\n return null\n}\n\nfunction applyHeaders (headers: any[], res: H3Event['res']) {\n for (let i = 0, n = headers.length; i < n; i++) {\n const header = headers[i]\n if (header) {\n if (Array.isArray(header)) {\n applyHeaders(header, res)\n } else if (header.key === 'Vary' && header.value) {\n vary(res, header.value)\n } else if (header.value) {\n res.headers.set(header.key, header.value)\n }\n }\n }\n}\n\nexport const cors =\n (\n options: {\n origin?: string | string[] | RegExp | boolean;\n methods?: string[] | string;\n allowedHeaders?: string[] | string | null;\n exposedHeaders?: string[] | string;\n credentials?: boolean;\n maxAge?: number | string;\n optionsSuccessStatus?: number;\n preflightContinue?: boolean;\n } = {},\n ) =>\n async (event: H3Event, next: NextFunction) => {\n const headers = [],\n method = event.req.method && event.req.method.toUpperCase && event.req.method.toUpperCase()\n\n if (method === 'OPTIONS') {\n // preflight\n headers.push(configureOrigin(options, event.req))\n headers.push(configureCredentials(options))\n headers.push(configureMethods(options))\n headers.push(configureAllowedHeaders(options, event.req))\n headers.push(configureMaxAge(options))\n headers.push(configureExposedHeaders(options))\n applyHeaders(headers, event.res)\n\n if (options.preflightContinue) {\n next()\n } else {\n // Safari (and potentially other browsers) need content-length 0,\n // for 204 or they just hang waiting for a body\n event.res.status = options.optionsSuccessStatus\n event.res.headers.set('Content-Length', '0')\n }\n } else {\n // actual response\n headers.push(configureOrigin(options, event.req))\n headers.push(configureCredentials(options))\n headers.push(configureExposedHeaders(options))\n applyHeaders(headers, event.res)\n next()\n }\n }\n","import { Logger, nodeEnv } from '@arkstack/common'\n\nimport { H3Middleware } from '..'\n\nconst colors: Record<string, 'green' | 'blue' | 'yellow' | 'red' | 'cyan'> = {\n GET: 'green',\n POST: 'blue',\n PUT: 'yellow',\n DELETE: 'red',\n PATCH: 'cyan',\n}\n\n/**\n * Middleware to log incoming requests and their response times.\n * \n * @param config Configuration options for the request logger middleware.\n * @param config.allowInProduction If true, the logger will also log requests in production environment. Default is false. \n * @returns H3Middleware function\n */\nexport const requestLogger = ({\n allowInProduction = false,\n}: {\n allowInProduction?: boolean\n} = {}): H3Middleware => async (event, next) => {\n const VERBOSE = process.env.VERBOSITY != '0'\n if ((nodeEnv() === 'prod' && !allowInProduction) || !VERBOSE) return next()\n\n await next()\n\n const start = Date.now()\n const req = event.req\n const status = event.res.status || 200\n const duration = Date.now() - start\n\n Logger.log([\n [`[${req.method}]`, colors[req.method] || 'green'],\n [req.url, 'cyan'],\n [status.toString(), status >= 500 ? 'red' : status >= 400 ? 'yellow' : 'green'],\n [`- ${duration}ms`, 'dim']\n ], ' ')\n}","import { H3Event, serveStatic } from 'h3'\nimport { join, resolve } from 'node:path'\nimport { readFile, stat } from 'node:fs/promises'\n\nimport { Arkstack } from '@arkstack/contract'\n\nexport const staticAssetHandler = (publicPath: string = 'public') => {\n const rootPath = resolve(Arkstack.rootDir(), publicPath)\n\n return (event: H3Event) => {\n const { pathname } = new URL(event.req.url)\n\n if (!/\\.[a-zA-Z0-9]+$/.test(pathname)) return\n if (pathname.startsWith('/.') || pathname.includes('..')) return\n\n event.res.headers.set('Cache-Control', 'public, max-age=31536000, immutable')\n event.res.headers.set('Access-Control-Allow-Origin', '*')\n event.res.headers.set('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS')\n event.res.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')\n\n return serveStatic(event, {\n indexNames: ['/index.html'],\n getContents: (id) => {\n const relativePath = id.replace(/^\\/+/, '')\n const file = join(rootPath, relativePath)\n\n return readFile(file).catch(() => null) as never\n },\n getMeta: async (id) => {\n const relativePath = id.replace(/^\\/+/, '')\n const file = join(rootPath, relativePath)\n const stats = await stat(file).catch(() => undefined)\n\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n }\n }\n },\n })\n }\n}"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
/// <reference path="./app.d.ts" />
|
|
2
|
+
import { ArkstackKitDriver, ArkstackMiddlewareConfig, ArkstackRouteListOptions, PromiseOrValue } from "@arkstack/contract";
|
|
3
|
+
import { H3, H3Event, HTTPError, HTTPResponse } from "h3";
|
|
4
|
+
import { Router } from "clear-router/h3";
|
|
5
|
+
import { H3App, Handler, HttpContext, Middleware } from "clear-router/types/h3";
|
|
6
|
+
import { Route } from "clear-router";
|
|
3
7
|
|
|
8
|
+
//#region dist/index-DBhjKP9Z.d.ts
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/index.d.ts
|
|
11
|
+
type H3Middleware = Middleware | [Middleware, Record<string, any>];
|
|
12
|
+
//#endregion
|
|
4
13
|
//#region src/types.d.ts
|
|
5
14
|
type MiddlewareConfig = ArkstackMiddlewareConfig<H3Middleware>;
|
|
6
15
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arkstack/driver-h3",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "H3 driver for Arkstack, providing H3-based runtime integration for the framework.",
|
|
6
6
|
"homepage": "https://arkstack.toneflix.net",
|
|
@@ -40,12 +40,13 @@
|
|
|
40
40
|
"clear-router": "^2.7.7",
|
|
41
41
|
"@resora/plugin-clear-router": "^1.0.33",
|
|
42
42
|
"resora": "^1.3.6",
|
|
43
|
-
"@arkstack/contract": "^0.
|
|
43
|
+
"@arkstack/contract": "^0.11.1"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"h3": "2.0.1-rc.
|
|
47
|
-
"@arkstack/auth": "^0.
|
|
48
|
-
"@arkstack/common": "^0.
|
|
46
|
+
"h3": "2.0.1-rc.22",
|
|
47
|
+
"@arkstack/auth": "^0.11.1",
|
|
48
|
+
"@arkstack/common": "^0.11.1",
|
|
49
|
+
"@arkstack/foundry": "^0.11.1"
|
|
49
50
|
},
|
|
50
51
|
"peerDependenciesMeta": {
|
|
51
52
|
"@arkstack/auth": {
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
}
|
|
54
55
|
},
|
|
55
56
|
"scripts": {
|
|
56
|
-
"build": "tsdown",
|
|
57
|
+
"build": "tsdown --config-loader unrun",
|
|
57
58
|
"version:patch": "pnpm version patch"
|
|
58
59
|
}
|
|
59
60
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"middlewares-BqHKlMaT.js","names":[],"sources":["../src/middlewares/auth.ts","../src/utils/vary.ts","../src/middlewares/cors.ts","../src/middlewares/request-logger.ts","../src/middlewares/static-asset-handler.ts"],"sourcesContent":["import type { H3Event } from 'h3'\nimport { Hook } from '@arkstack/common'\n\nexport const auth = async (event: H3Event, next: () => unknown | Promise<unknown>) => {\n const { Auth, AuthenticationException } = await import('@arkstack/auth')\n\n try {\n const token = readBearerToken(event.req.headers.get('authorization'))\n\n if (!token) {\n throw new AuthenticationException('Unauthenticated', {\n req: {\n headers: event.req.headers,\n method: event.req.method,\n url: event.req.url,\n path: getEventPath(event),\n },\n status: 401,\n })\n }\n\n if (Hook.has('middleware:auth', 'before'))\n Hook.get('middleware:auth', 'before')?.(event)\n\n const requestSource = {\n headers: event.req.headers,\n method: event.req.method,\n url: event.req.url,\n path: getEventPath(event),\n }\n const auth = Auth.make().setRequest(requestSource)\n const user = await auth.authorizeToken(token)\n\n event.context.user = user\n event.context.auth = auth\n event.context.session = auth.session()\n event.context.authUser = user\n event.context.authToken = token;\n (event.req as any).user = user;\n (event.req as any).auth = auth;\n (event.req as any).session = event.context.session;\n (event.req as any).authUser = user;\n (event.req as any).authToken = token\n\n if (Hook.has('middleware:auth', 'after'))\n Hook.get('middleware:auth', 'after')?.(event)\n\n return await next()\n } catch (error) {\n if (Hook.has('middleware:auth', 'error'))\n Hook.get('middleware:auth', 'error')?.(error, event)\n\n throw error\n }\n}\n\nconst readBearerToken = (authorization: string | null) => {\n if (!authorization?.startsWith('Bearer ')) {\n return null\n }\n\n return authorization.substring(7)\n}\n\nconst getEventPath = (event: H3Event) => event.req._url?.pathname\n","/*!\n * vary\n * Copyright(c) 2014-2017 Douglas Christopher Wilson\n * MIT Licensed\n */\nimport { H3Event } from 'h3'\n\n/**\n * RegExp to match field-name in RFC 7230 sec 3.2\n *\n * field-name = token\n * token = 1*tchar\n * tchar = \"!\" / \"#\" / \"$\" / \"%\" / \"&\" / \"'\" / \"*\"\n * / \"+\" / \"-\" / \".\" / \"^\" / \"_\" / \"`\" / \"|\" / \"~\"\n * / DIGIT / ALPHA\n * ; any VCHAR, except delimiters\n */\n\nconst FIELD_NAME_REGEXP = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/\n\n/**\n * Append a field to a vary header.\n *\n * @param header\n * @param field\n * @return\n * @public\n */\nexport const append = (header: string, field: string | string[]) => {\n if (typeof header !== 'string') {\n throw new TypeError('header argument is required')\n }\n\n if (!field) {\n throw new TypeError('field argument is required')\n }\n\n // get fields array\n const fields = !Array.isArray(field) ? parse(String(field)) : field\n\n // assert on invalid field names\n for (let j = 0; j < fields.length; j++) {\n if (!FIELD_NAME_REGEXP.test(fields[j])) {\n throw new TypeError('field argument contains an invalid header name')\n }\n }\n\n // existing, unspecified vary\n if (header === '*') {\n return header\n }\n\n // enumerate current values\n let val = header\n const vals = parse(header.toLowerCase())\n\n // unspecified vary\n if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) {\n return '*'\n }\n\n for (let i = 0; i < fields.length; i++) {\n const fld = fields[i].toLowerCase()\n\n // append value (case-preserving)\n if (vals.indexOf(fld) === -1) {\n vals.push(fld)\n val = val ? val + ', ' + fields[i] : fields[i]\n }\n }\n\n return val\n}\n\n/**\n * Parse a vary header into an array.\n *\n * @param header\n * @return\n * @private\n */\n\nexport const parse = (header: string) => {\n let end = 0\n const list = []\n let start = 0\n\n // gather tokens\n for (let i = 0, len = header.length; i < len; i++) {\n switch (header.charCodeAt(i)) {\n case 0x20 /* */:\n if (start === end) {\n start = end = i + 1\n }\n break\n case 0x2c /* , */:\n list.push(header.substring(start, end))\n start = end = i + 1\n break\n default:\n end = i + 1\n break\n }\n }\n\n // final token\n list.push(header.substring(start, end))\n\n return list\n}\n\n/**\n * Mark that a request is varied on a header field.\n *\n * @param res\n * @param field\n * @public\n */\n\nexport const vary = (res?: H3Event['res'], field?: string | string[]) => {\n if (!res || !res.headers.get || !res.headers.set) {\n throw new TypeError('res argument is required')\n }\n\n // get existing header\n let val = res.headers.get('Vary') || ''\n const header = Array.isArray(val) ? val.join(', ') : String(val)\n\n if (!field) {\n return res.headers.set('Vary', '*')\n }\n\n // set new header\n if ((val = append(header, field))) {\n res.headers.set('Vary', val)\n }\n}\n","import { H3Event } from 'h3'\nimport { NextFunction } from 'clear-router/types/h3'\nimport { vary } from '../utils/vary'\n\nconst isString = (s: any) => {\n return typeof s === 'string' || s instanceof String\n}\n\nconst isOriginAllowed = (origin: string, allowedOrigin: string | string[] | RegExp | boolean) => {\n if (Array.isArray(allowedOrigin)) {\n for (let i = 0; i < allowedOrigin.length; ++i) {\n if (isOriginAllowed(origin, allowedOrigin[i])) {\n return true\n }\n }\n\n return false\n } else if (isString(allowedOrigin)) {\n return origin === allowedOrigin\n } else if (allowedOrigin instanceof RegExp) {\n return allowedOrigin.test(origin)\n } else {\n return !!allowedOrigin\n }\n}\n\nconst configureOrigin = (\n options: { origin?: string | string[] | RegExp | boolean },\n req: H3Event['req'],\n) => {\n let isAllowed: boolean\n const requestOrigin = req.headers.get('origin') || '*',\n headers = []\n\n if (!options.origin || options.origin === '*') {\n // allow any origin\n headers.push([\n {\n key: 'Access-Control-Allow-Origin',\n value: '*',\n },\n ])\n } else if (isString(options.origin)) {\n // fixed origin\n headers.push([\n {\n key: 'Access-Control-Allow-Origin',\n value: options.origin,\n },\n ])\n headers.push([\n {\n key: 'Vary',\n value: 'Origin',\n },\n ])\n } else {\n isAllowed = isOriginAllowed(requestOrigin, options.origin)\n // reflect origin\n headers.push([\n {\n key: 'Access-Control-Allow-Origin',\n value: isAllowed ? requestOrigin : false,\n },\n ])\n headers.push([\n {\n key: 'Vary',\n value: 'Origin',\n },\n ])\n }\n\n return headers\n}\n\nconst configureMethods = (options: { methods?: string[] | string }) => {\n let methods = options.methods\n if (Array.isArray(methods)) {\n methods = methods.join(',') // .methods is an array, so turn it into a string\n }\n\n return {\n key: 'Access-Control-Allow-Methods',\n value: methods,\n }\n}\n\nconst configureCredentials = (options: { credentials?: boolean }) => {\n if (options.credentials === true) {\n return {\n key: 'Access-Control-Allow-Credentials',\n value: 'true',\n }\n }\n\n return null\n}\n\nconst configureAllowedHeaders = (\n options: { allowedHeaders?: string[] | string | null; headers?: string[] | string | null },\n req: H3Event['req'],\n) => {\n let allowedHeaders = options.allowedHeaders || options.headers\n const headers = []\n\n if (!allowedHeaders) {\n allowedHeaders = req.headers.get('access-control-request-headers') // .headers wasn't specified, so reflect the request headers\n headers.push([\n {\n key: 'Vary',\n value: 'Access-Control-Request-Headers',\n },\n ])\n } else if (Array.isArray(allowedHeaders)) {\n allowedHeaders = allowedHeaders.join(',') // .headers is an array, so turn it into a string\n }\n if (allowedHeaders && allowedHeaders.length) {\n headers.push([\n {\n key: 'Access-Control-Allow-Headers',\n value: allowedHeaders,\n },\n ])\n }\n\n return headers\n}\n\nfunction configureExposedHeaders (options: { exposedHeaders?: string[] | string }) {\n let headers = options.exposedHeaders\n if (!headers) {\n return null\n } else if (Array.isArray(headers)) {\n headers = headers.join(',') // .headers is an array, so turn it into a string\n }\n if (headers && headers.length) {\n return {\n key: 'Access-Control-Expose-Headers',\n value: headers,\n }\n }\n\n return null\n}\n\nfunction configureMaxAge (options: { maxAge?: number | string }) {\n const maxAge = (typeof options.maxAge === 'number' || options.maxAge) && options.maxAge.toString()\n if (maxAge && maxAge.length) {\n return {\n key: 'Access-Control-Max-Age',\n value: maxAge,\n }\n }\n\n return null\n}\n\nfunction applyHeaders (headers: any[], res: H3Event['res']) {\n for (let i = 0, n = headers.length; i < n; i++) {\n const header = headers[i]\n if (header) {\n if (Array.isArray(header)) {\n applyHeaders(header, res)\n } else if (header.key === 'Vary' && header.value) {\n vary(res, header.value)\n } else if (header.value) {\n res.headers.set(header.key, header.value)\n }\n }\n }\n}\n\nexport const cors =\n (\n options: {\n origin?: string | string[] | RegExp | boolean;\n methods?: string[] | string;\n allowedHeaders?: string[] | string | null;\n exposedHeaders?: string[] | string;\n credentials?: boolean;\n maxAge?: number | string;\n optionsSuccessStatus?: number;\n preflightContinue?: boolean;\n } = {},\n ) =>\n async (event: H3Event, next: NextFunction) => {\n const headers = [],\n method = event.req.method && event.req.method.toUpperCase && event.req.method.toUpperCase()\n\n if (method === 'OPTIONS') {\n // preflight\n headers.push(configureOrigin(options, event.req))\n headers.push(configureCredentials(options))\n headers.push(configureMethods(options))\n headers.push(configureAllowedHeaders(options, event.req))\n headers.push(configureMaxAge(options))\n headers.push(configureExposedHeaders(options))\n applyHeaders(headers, event.res)\n\n if (options.preflightContinue) {\n next()\n } else {\n // Safari (and potentially other browsers) need content-length 0,\n // for 204 or they just hang waiting for a body\n event.res.status = options.optionsSuccessStatus\n event.res.headers.set('Content-Length', '0')\n }\n } else {\n // actual response\n headers.push(configureOrigin(options, event.req))\n headers.push(configureCredentials(options))\n headers.push(configureExposedHeaders(options))\n applyHeaders(headers, event.res)\n next()\n }\n }\n","import { Logger, nodeEnv } from '@arkstack/common'\n\nimport { H3Middleware } from '..'\n\nconst colors: Record<string, 'green' | 'blue' | 'yellow' | 'red' | 'cyan'> = {\n GET: 'green',\n POST: 'blue',\n PUT: 'yellow',\n DELETE: 'red',\n PATCH: 'cyan',\n}\n\n/**\n * Middleware to log incoming requests and their response times.\n * \n * @param config Configuration options for the request logger middleware.\n * @param config.allowInProduction If true, the logger will also log requests in production environment. Default is false. \n * @returns H3Middleware function\n */\nexport const requestLogger = ({\n allowInProduction = false,\n}: {\n allowInProduction?: boolean\n} = {}): H3Middleware => async (event, next) => {\n if (nodeEnv() === 'prod' && !allowInProduction) return next()\n\n await next()\n\n const start = Date.now()\n const req = event.req\n const status = event.res.status || 200\n const duration = Date.now() - start\n\n Logger.log([\n [`[${req.method}]`, colors[req.method] || 'green'],\n [req.url, 'cyan'],\n [status.toString(), status >= 500 ? 'red' : status >= 400 ? 'yellow' : 'green'],\n [`- ${duration}ms`, 'dim']\n ], ' ')\n}","import { H3Event, serveStatic } from 'h3'\nimport { join, resolve } from 'node:path'\nimport { readFile, stat } from 'node:fs/promises'\n\nimport { Arkstack } from '@arkstack/contract'\n\nexport const staticAssetHandler = (publicPath: string = 'public') => {\n const rootPath = resolve(Arkstack.rootDir(), publicPath)\n\n return (event: H3Event) => {\n const { pathname } = new URL(event.req.url)\n\n if (!/\\.[a-zA-Z0-9]+$/.test(pathname)) return\n if (pathname.startsWith('/.') || pathname.includes('..')) return\n\n event.res.headers.set('Cache-Control', 'public, max-age=31536000, immutable')\n event.res.headers.set('Access-Control-Allow-Origin', '*')\n event.res.headers.set('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS')\n event.res.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization')\n\n return serveStatic(event, {\n indexNames: ['/index.html'],\n getContents: (id) => {\n const relativePath = id.replace(/^\\/+/, '')\n const file = join(rootPath, relativePath)\n\n return readFile(file).catch(() => null) as never\n },\n getMeta: async (id) => {\n const relativePath = id.replace(/^\\/+/, '')\n const file = join(rootPath, relativePath)\n const stats = await stat(file).catch(() => undefined)\n\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n }\n }\n },\n })\n }\n}"],"mappings":"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"}
|