@autofleet/super-express 6.0.3 → 6.0.4
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/README.md +2 -6
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
@@ -37,7 +37,7 @@ const options = {
|
|
37
37
|
stats: true,
|
38
38
|
tracing: true,
|
39
39
|
eagerLoadUserPermissions: true,
|
40
|
-
aliveEndpointOptions: { sequelize }
|
40
|
+
aliveEndpointOptions: { sequelize }
|
41
41
|
};
|
42
42
|
|
43
43
|
const app = await createSuperExpressApp(options);
|
@@ -97,7 +97,7 @@ const options = {
|
|
97
97
|
stats: true,
|
98
98
|
tracing: true,
|
99
99
|
eagerLoadUserPermissions: true,
|
100
|
-
aliveEndpointOptions: { sequelize }
|
100
|
+
aliveEndpointOptions: { sequelize }
|
101
101
|
};
|
102
102
|
|
103
103
|
const app = await createSuperExpressApp(options);
|
@@ -110,7 +110,3 @@ app.listen(3000, () => {
|
|
110
110
|
## Contributing
|
111
111
|
|
112
112
|
Feel free to submit issues or pull requests. Contributions are welcome!
|
113
|
-
|
114
|
-
## License
|
115
|
-
|
116
|
-
This project is licensed under the MIT License.
|
package/dist/index.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var f=require('node:fs'),b=require('node:path'),node_module=require('node:module'),c=require('express');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var f__default=/*#__PURE__*/_interopDefault(f);var b__default=/*#__PURE__*/_interopDefault(b);var c__default=/*#__PURE__*/_interopDefault(c);var d={bodyParser:"1000mb",helmet:true,morgan:true,nitur:true,stats:true,tracing:true,eagerLoadUserPermissions:true};var{url:
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var f=require('node:fs'),b=require('node:path'),node_module=require('node:module'),c=require('express');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var f__default=/*#__PURE__*/_interopDefault(f);var b__default=/*#__PURE__*/_interopDefault(b);var c__default=/*#__PURE__*/_interopDefault(c);var d={bodyParser:"1000mb",helmet:true,morgan:true,nitur:true,stats:true,tracing:true,eagerLoadUserPermissions:true};var{url:l}=({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }),p=node_module.createRequire(l),y=b__default.default.dirname(l),x=JSON.parse(f__default.default.readFileSync(new URL("package.json",y),"utf8"));function S({logger:e,...m}){let o=c__default.default(),r={...d,...m};if(r.morgan){let t=p("morgan");e.debug("[SuperExpress] formatting is enabled \u2705"),o.use(t((n,s,i)=>{let a={method:n.method(s,i),url:n.url(s,i)??"unknown URL",status:n.status(s,i),contentLength:n.res(s,i,"content-length"),responseTime:n["response-time"](s,i)??"0",userAgent:n["user-agent"](s,i)};e.info(a.url,{httpRequest:{status:a.status,requestUrl:a.url,requestMethod:a.method,responseSize:a.contentLength,latency:{seconds:Number.parseInt(a.responseTime,10)/1e3,nanos:Number.parseInt(a.responseTime,10)*1e6},userAgent:a.userAgent}});}));}if(r.helmet){e.debug("[SuperExpress] security is enabled \u2705");let t={"Content-Security-Policy":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests","Cross-Origin-Opener-Policy":"same-origin","Cross-Origin-Resource-Policy":"same-origin","Origin-Agent-Cluster":"?1","Referrer-Policy":"no-referrer","Strict-Transport-Security":"max-age=15552000; includeSubDomains","X-Content-Type-Options":"nosniff","X-DNS-Prefetch-Control":"off","X-Download-Options":"noopen","X-Frame-Options":"SAMEORIGIN","X-Permitted-Cross-Domain-Policies":"none","X-XSS-Protection":"0"};o.use((n,s,i)=>{s.set(t),i();}),o.disable("x-powered-by");}else e.warn("[SuperExpress] security headers are disabled \u{1F628}");if(r.bodyParser){e.debug("[SuperExpress] body-parser is enabled \u2705");let t=typeof r.bodyParser=="string"?r.bodyParser:"1000mb";o.use(c__default.default.json({limit:t}));}else e.debug("[SuperExpress] body-parser is disabled \u274C");if(r.nitur){let{aliveEndpoint:t}=p("@autofleet/nitur");o.get("/alive",t({logger:e,...r.aliveEndpointOptions})),e.debug("[SuperExpress] added /alive endpoint \u2705");}if(r.stats){let t=new Date;o.get("/stats",(n,s)=>{s.json({name:r.name||"default-name",version:r.version||"default-version",serverRunningSince:t});}),e.debug("[SuperExpress] added /stats endpoint \u2705");}if(r.tracing){let{enableTracing:t,middleware:n,outbreak:s}=p("@autofleet/zehut");t(),e.addContextMiddleware(()=>({traceId:s.getCurrentContext()?.context?.get("x-trace-id")})),o.use(n({eagerLoadUserPermissions:r.eagerLoadUserPermissions})),e.debug("[SuperExpress] tracing is enabled \u2705");}let u=o.listen.bind(o);return o.listen=function(t,n){let s=process.env.NODE_ENV==="production",i=x?.version||"unknown";return e.debug(`[SuperExpress] is started with version ${i}`),e.debug(`[SuperExpress] will listen on port ${t}`),e.debug(`[SuperExpress] production mode: ${s}`),u(t,n)},Object.assign(o,{nativeListen:u})}var A=S;exports.default=A;exports.superExpress=S;//# sourceMappingURL=index.cjs.map
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../config/default-options.ts","../src/index.ts"],"names":["defaultOptions","url","safeRequire","createRequire","dirname","path","packageJson","fs","superExpress","logger","options","app","express","mergedOptions","morgan","tokens","req","res","values","HEADERS","_req","next","limit","aliveEndpoint","serverRunningSince","enableTracing","middleware","outbreak","nativeListen","port","callback","isProd","version","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import { LoggerInstanceManager } from '@autofleet/logger';\nimport { aliveEndpoint } from '@autofleet/nitur';\n\n/** Options to customize the behavior of the SuperExpress application. */\nexport interface Options {\n /** The name of the application. @default 'default-name' */\n name?: string;\n /** The version of the application. @default 'default-version' */\n version?: string;\n /** Enables or disables body parser middleware. if given a string, will be used as the limit for body size @default '1000mb' */\n bodyParser?: boolean | string;\n /** Enables or disables security headers middleware. @default true */\n helmet?: boolean;\n /** Enables or disables HTTP request logging middleware. @default true */\n morgan?: boolean;\n /** Enables or disables the alive endpoint middleware. @default true */\n nitur?: boolean;\n /** Enables or disables the stats endpoint middleware. @default true */\n stats?: boolean;\n /** Enables or disables request tracing middleware. @default true */\n tracing?: boolean;\n /** Enables or disables eager loading of user permissions for tracing middleware. @default true */\n eagerLoadUserPermissions?: boolean;\n /** Options to customize the alive endpoint middleware. */\n aliveEndpointOptions?: Omit<Parameters<typeof aliveEndpoint>[0], 'logger'>;\n /** The servers logger instance. */\n logger: LoggerInstanceManager;\n}\n\nexport const defaultOptions = {\n bodyParser: '1000mb',\n helmet: true,\n morgan: true,\n nitur: true,\n stats: true,\n tracing: true,\n eagerLoadUserPermissions: true,\n} satisfies Omit<Options, 'logger'>;","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { Server } from 'node:http';\nimport { createRequire } from 'node:module';\nimport express from 'express';\nimport { defaultOptions, Options } from '../config/default-options.js';\n\nconst { url } = import.meta;\nconst safeRequire = createRequire(url);\nconst dirname = path.dirname(url);\nconst packageJson = JSON.parse(fs.readFileSync(new URL('package.json', dirname), 'utf8'));\n\n/** Extended express.Application interface which includes nativeListen and the overridden listen method. */\ninterface SuperExpressApp extends Omit<express.Application, 'listen'> {\n /** Original express listen method. */\n nativeListen: express.Application['listen'];\n\n /**\n * Overridden listen method to add custom behavior.\n * @param port - The port number to listen on.\n * @param cb - Optional callback function to execute after the server starts listening.\n */\n listen(port: number, cb?: () => void): Server;\n}\n\n/**\n * Creates a new SuperExpress application with the given options.\n * @param options - Optional settings to customize the application.\n * @param expressOptions - Optional settings to customize express.\n * @returns A SuperExpress application instance.\n */\nexport function superExpress({ logger, ...options }: Options): SuperExpressApp {\n const app = express();\n const mergedOptions = { ...defaultOptions, ...options };\n /** Formatting */\n if (mergedOptions.morgan) {\n const morgan = safeRequire('morgan') as typeof import('morgan');\n logger.debug('[SuperExpress] formatting is enabled ✅');\n app.use(morgan((tokens, req, res) => {\n const values = {\n method: tokens.method(req, res),\n url: tokens.url(req, res) ?? 'unknown URL',\n status: tokens.status(req, res),\n contentLength: tokens.res(req, res, 'content-length'),\n responseTime: tokens['response-time'](req, res) ?? '0',\n userAgent: tokens['user-agent'](req, res),\n };\n logger.info(values.url, {\n httpRequest: {\n status: values.status,\n requestUrl: values.url,\n requestMethod: values.method,\n responseSize: values.contentLength,\n latency: {\n seconds: Number.parseInt(values.responseTime, 10) / 1_000,\n nanos: Number.parseInt(values.responseTime, 10) * 1_000_000,\n },\n userAgent: values.userAgent,\n },\n });\n return undefined;\n }));\n }\n /** Security */\n if (mergedOptions.helmet) {\n logger.debug('[SuperExpress] security is enabled ✅');\n // this is what helmet does by default. https://helmetjs.github.io/faq/you-might-not-need-helmet/\n const HEADERS = {\n \"Content-Security-Policy\":\n \"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\",\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n \"Cross-Origin-Resource-Policy\": \"same-origin\",\n \"Origin-Agent-Cluster\": \"?1\",\n \"Referrer-Policy\": \"no-referrer\",\n \"Strict-Transport-Security\": \"max-age=15552000; includeSubDomains\",\n \"X-Content-Type-Options\": \"nosniff\",\n \"X-DNS-Prefetch-Control\": \"off\",\n \"X-Download-Options\": \"noopen\",\n \"X-Frame-Options\": \"SAMEORIGIN\",\n \"X-Permitted-Cross-Domain-Policies\": \"none\",\n \"X-XSS-Protection\": \"0\",\n };\n app.use((_req, res, next) => {\n res.set(HEADERS);\n next();\n });\n app.disable('x-powered-by');\n } else {\n logger.warn('[SuperExpress] security headers are disabled 😨');\n }\n /** Body Parser */\n if (mergedOptions.bodyParser) {\n logger.debug('[SuperExpress] body-parser is enabled ✅');\n const limit = typeof mergedOptions.bodyParser === 'string' ? mergedOptions.bodyParser : '1000mb';\n app.use(express.json({ limit }))\n } else {\n logger.debug('[SuperExpress] body-parser is disabled ❌');\n }\n /** Alive Endpoint */\n if (mergedOptions.nitur) {\n const { aliveEndpoint } = safeRequire('@autofleet/nitur') as typeof import('@autofleet/nitur');\n app.get('/alive', aliveEndpoint({ logger, ...mergedOptions.aliveEndpointOptions }));\n logger.debug('[SuperExpress] added /alive endpoint ✅');\n }\n /** Stats Endpoint */\n if (mergedOptions.stats) {\n const serverRunningSince = new Date();\n app.get('/stats', (_req, res) => {\n res.json({\n name: mergedOptions.name || 'default-name',\n version: mergedOptions.version || 'default-version',\n serverRunningSince,\n });\n });\n logger.debug('[SuperExpress] added /stats endpoint ✅');\n }\n /** Tracing */\n if (mergedOptions.tracing) {\n const { enableTracing, middleware, outbreak } = safeRequire('@autofleet/zehut') as typeof import('@autofleet/zehut');\n enableTracing();\n logger.addContextMiddleware(() => ({\n traceId: outbreak.getCurrentContext()?.context?.get('x-trace-id'),\n }));\n\n app.use(middleware({\n eagerLoadUserPermissions: mergedOptions.eagerLoadUserPermissions,\n }));\n logger.debug('[SuperExpress] tracing is enabled ✅');\n }\n\n const nativeListen: typeof app['listen'] = app.listen.bind(app);\n app.listen = function (port: number, callback?: () => void) {\n const isProd = process.env.NODE_ENV === 'production';\n const version = packageJson?.version || 'unknown';\n logger.debug(`[SuperExpress] is started with version ${version}`);\n logger.debug(`[SuperExpress] will listen on port ${port}`);\n logger.debug(`[SuperExpress] production mode: ${isProd}`);\n return nativeListen(port, callback)\n } as typeof app['listen'];\n\n return Object.assign(app, { nativeListen }) as SuperExpressApp;\n};\n\nexport default superExpress;\n"]}
|
1
|
+
{"version":3,"sources":["../config/default-options.ts","../src/index.ts"],"names":["defaultOptions","url","safeRequire","createRequire","dirname","path","packageJson","fs","superExpress","logger","options","app","express","mergedOptions","morgan","tokens","req","res","values","HEADERS","_req","next","limit","aliveEndpoint","serverRunningSince","enableTracing","middleware","outbreak","nativeListen","port","callback","isProd","version","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { LoggerInstanceManager } from '@autofleet/logger';\nimport type { aliveEndpoint } from '@autofleet/nitur';\n\n/** Options to customize the behavior of the SuperExpress application. */\nexport interface Options {\n /** The name of the application. @default 'default-name' */\n name?: string;\n /** The version of the application. @default 'default-version' */\n version?: string;\n /** Enables or disables body parser middleware. if given a string, will be used as the limit for body size @default '1000mb' */\n bodyParser?: boolean | string;\n /** Enables or disables security headers middleware. @default true */\n helmet?: boolean;\n /** Enables or disables HTTP request logging middleware. @default true */\n morgan?: boolean;\n /** Enables or disables the alive endpoint middleware. @default true */\n nitur?: boolean;\n /** Enables or disables the stats endpoint middleware. @default true */\n stats?: boolean;\n /** Enables or disables request tracing middleware. @default true */\n tracing?: boolean;\n /** Enables or disables eager loading of user permissions for tracing middleware. @default true */\n eagerLoadUserPermissions?: boolean;\n /** Options to customize the alive endpoint middleware. */\n aliveEndpointOptions?: Omit<Parameters<typeof aliveEndpoint>[0], 'logger'>;\n /** The servers logger instance. */\n logger: LoggerInstanceManager;\n}\n\nexport const defaultOptions = {\n bodyParser: '1000mb',\n helmet: true,\n morgan: true,\n nitur: true,\n stats: true,\n tracing: true,\n eagerLoadUserPermissions: true,\n} satisfies Omit<Options, 'logger'>;\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { Server } from 'node:http';\nimport { createRequire } from 'node:module';\nimport express from 'express';\nimport { defaultOptions, Options } from '../config/default-options.js';\n\nconst { url } = import.meta;\nconst safeRequire = createRequire(url);\nconst dirname = path.dirname(url);\nconst packageJson = JSON.parse(fs.readFileSync(new URL('package.json', dirname), 'utf8'));\n\n/** Extended express.Application interface which includes nativeListen and the overridden listen method. */\ninterface SuperExpressApp extends Omit<express.Application, 'listen'> {\n /** Original express listen method. */\n nativeListen: express.Application['listen'];\n\n /**\n * Overridden listen method to add custom behavior.\n * @param port - The port number to listen on.\n * @param cb - Optional callback function to execute after the server starts listening.\n */\n listen(port: number, cb?: () => void): Server;\n}\n\n/**\n * Creates a new SuperExpress application with the given options.\n * @param options Optional settings to customize the application.\n * @returns A SuperExpress application instance.\n */\nexport function superExpress({ logger, ...options }: Options): SuperExpressApp {\n const app = express();\n const mergedOptions = { ...defaultOptions, ...options };\n /** Formatting */\n if (mergedOptions.morgan) {\n const morgan = safeRequire('morgan') as typeof import('morgan');\n logger.debug('[SuperExpress] formatting is enabled ✅');\n app.use(morgan((tokens, req, res) => {\n const values = {\n method: tokens.method(req, res),\n url: tokens.url(req, res) ?? 'unknown URL',\n status: tokens.status(req, res),\n contentLength: tokens.res(req, res, 'content-length'),\n responseTime: tokens['response-time'](req, res) ?? '0',\n userAgent: tokens['user-agent'](req, res),\n };\n logger.info(values.url, {\n httpRequest: {\n status: values.status,\n requestUrl: values.url,\n requestMethod: values.method,\n responseSize: values.contentLength,\n latency: {\n seconds: Number.parseInt(values.responseTime, 10) / 1_000,\n nanos: Number.parseInt(values.responseTime, 10) * 1_000_000,\n },\n userAgent: values.userAgent,\n },\n });\n return undefined;\n }));\n }\n /** Security */\n if (mergedOptions.helmet) {\n logger.debug('[SuperExpress] security is enabled ✅');\n // this is what helmet does by default. https://helmetjs.github.io/faq/you-might-not-need-helmet/\n const HEADERS = {\n 'Content-Security-Policy':\n \"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\",\n 'Cross-Origin-Opener-Policy': 'same-origin',\n 'Cross-Origin-Resource-Policy': 'same-origin',\n 'Origin-Agent-Cluster': '?1',\n 'Referrer-Policy': 'no-referrer',\n 'Strict-Transport-Security': 'max-age=15552000; includeSubDomains',\n 'X-Content-Type-Options': 'nosniff',\n 'X-DNS-Prefetch-Control': 'off',\n 'X-Download-Options': 'noopen',\n 'X-Frame-Options': 'SAMEORIGIN',\n 'X-Permitted-Cross-Domain-Policies': 'none',\n 'X-XSS-Protection': '0',\n };\n app.use((_req, res, next) => {\n res.set(HEADERS);\n next();\n });\n app.disable('x-powered-by');\n } else {\n logger.warn('[SuperExpress] security headers are disabled 😨');\n }\n /** Body Parser */\n if (mergedOptions.bodyParser) {\n logger.debug('[SuperExpress] body-parser is enabled ✅');\n const limit = typeof mergedOptions.bodyParser === 'string' ? mergedOptions.bodyParser : '1000mb';\n app.use(express.json({ limit }));\n } else {\n logger.debug('[SuperExpress] body-parser is disabled ❌');\n }\n /** Alive Endpoint */\n if (mergedOptions.nitur) {\n const { aliveEndpoint } = safeRequire('@autofleet/nitur') as typeof import('@autofleet/nitur');\n app.get('/alive', aliveEndpoint({ logger, ...mergedOptions.aliveEndpointOptions }));\n logger.debug('[SuperExpress] added /alive endpoint ✅');\n }\n /** Stats Endpoint */\n if (mergedOptions.stats) {\n const serverRunningSince = new Date();\n app.get('/stats', (_req, res) => {\n res.json({\n name: mergedOptions.name || 'default-name',\n version: mergedOptions.version || 'default-version',\n serverRunningSince,\n });\n });\n logger.debug('[SuperExpress] added /stats endpoint ✅');\n }\n /** Tracing */\n if (mergedOptions.tracing) {\n const { enableTracing, middleware, outbreak } = safeRequire('@autofleet/zehut') as typeof import('@autofleet/zehut');\n enableTracing();\n logger.addContextMiddleware(() => ({\n traceId: outbreak.getCurrentContext()?.context?.get('x-trace-id'),\n }));\n\n app.use(middleware({\n eagerLoadUserPermissions: mergedOptions.eagerLoadUserPermissions,\n }));\n logger.debug('[SuperExpress] tracing is enabled ✅');\n }\n\n const nativeListen: typeof app['listen'] = app.listen.bind(app);\n app.listen = function (port: number, callback?: () => void) {\n const isProd = process.env.NODE_ENV === 'production';\n const version = packageJson?.version || 'unknown';\n logger.debug(`[SuperExpress] is started with version ${version}`);\n logger.debug(`[SuperExpress] will listen on port ${port}`);\n logger.debug(`[SuperExpress] production mode: ${isProd}`);\n return nativeListen(port, callback);\n } as typeof app['listen'];\n\n return Object.assign(app, { nativeListen }) as SuperExpressApp;\n}\n\nexport default superExpress;\n"]}
|
package/dist/index.d.cts
CHANGED
@@ -42,8 +42,7 @@ interface SuperExpressApp extends Omit<express.Application, 'listen'> {
|
|
42
42
|
}
|
43
43
|
/**
|
44
44
|
* Creates a new SuperExpress application with the given options.
|
45
|
-
* @param options
|
46
|
-
* @param expressOptions - Optional settings to customize express.
|
45
|
+
* @param options Optional settings to customize the application.
|
47
46
|
* @returns A SuperExpress application instance.
|
48
47
|
*/
|
49
48
|
declare function superExpress({ logger, ...options }: Options): SuperExpressApp;
|
package/dist/index.d.ts
CHANGED
@@ -42,8 +42,7 @@ interface SuperExpressApp extends Omit<express.Application, 'listen'> {
|
|
42
42
|
}
|
43
43
|
/**
|
44
44
|
* Creates a new SuperExpress application with the given options.
|
45
|
-
* @param options
|
46
|
-
* @param expressOptions - Optional settings to customize express.
|
45
|
+
* @param options Optional settings to customize the application.
|
47
46
|
* @returns A SuperExpress application instance.
|
48
47
|
*/
|
49
48
|
declare function superExpress({ logger, ...options }: Options): SuperExpressApp;
|
package/dist/index.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import f from'node:fs';import b from'node:path';import {createRequire}from'node:module';import c from'express';var d={bodyParser:"1000mb",helmet:true,morgan:true,nitur:true,stats:true,tracing:true,eagerLoadUserPermissions:true};var{url:
|
1
|
+
import f from'node:fs';import b from'node:path';import {createRequire}from'node:module';import c from'express';var d={bodyParser:"1000mb",helmet:true,morgan:true,nitur:true,stats:true,tracing:true,eagerLoadUserPermissions:true};var{url:l}=import.meta,p=createRequire(l),y=b.dirname(l),x=JSON.parse(f.readFileSync(new URL("package.json",y),"utf8"));function S({logger:e,...m}){let o=c(),r={...d,...m};if(r.morgan){let t=p("morgan");e.debug("[SuperExpress] formatting is enabled \u2705"),o.use(t((n,s,i)=>{let a={method:n.method(s,i),url:n.url(s,i)??"unknown URL",status:n.status(s,i),contentLength:n.res(s,i,"content-length"),responseTime:n["response-time"](s,i)??"0",userAgent:n["user-agent"](s,i)};e.info(a.url,{httpRequest:{status:a.status,requestUrl:a.url,requestMethod:a.method,responseSize:a.contentLength,latency:{seconds:Number.parseInt(a.responseTime,10)/1e3,nanos:Number.parseInt(a.responseTime,10)*1e6},userAgent:a.userAgent}});}));}if(r.helmet){e.debug("[SuperExpress] security is enabled \u2705");let t={"Content-Security-Policy":"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests","Cross-Origin-Opener-Policy":"same-origin","Cross-Origin-Resource-Policy":"same-origin","Origin-Agent-Cluster":"?1","Referrer-Policy":"no-referrer","Strict-Transport-Security":"max-age=15552000; includeSubDomains","X-Content-Type-Options":"nosniff","X-DNS-Prefetch-Control":"off","X-Download-Options":"noopen","X-Frame-Options":"SAMEORIGIN","X-Permitted-Cross-Domain-Policies":"none","X-XSS-Protection":"0"};o.use((n,s,i)=>{s.set(t),i();}),o.disable("x-powered-by");}else e.warn("[SuperExpress] security headers are disabled \u{1F628}");if(r.bodyParser){e.debug("[SuperExpress] body-parser is enabled \u2705");let t=typeof r.bodyParser=="string"?r.bodyParser:"1000mb";o.use(c.json({limit:t}));}else e.debug("[SuperExpress] body-parser is disabled \u274C");if(r.nitur){let{aliveEndpoint:t}=p("@autofleet/nitur");o.get("/alive",t({logger:e,...r.aliveEndpointOptions})),e.debug("[SuperExpress] added /alive endpoint \u2705");}if(r.stats){let t=new Date;o.get("/stats",(n,s)=>{s.json({name:r.name||"default-name",version:r.version||"default-version",serverRunningSince:t});}),e.debug("[SuperExpress] added /stats endpoint \u2705");}if(r.tracing){let{enableTracing:t,middleware:n,outbreak:s}=p("@autofleet/zehut");t(),e.addContextMiddleware(()=>({traceId:s.getCurrentContext()?.context?.get("x-trace-id")})),o.use(n({eagerLoadUserPermissions:r.eagerLoadUserPermissions})),e.debug("[SuperExpress] tracing is enabled \u2705");}let u=o.listen.bind(o);return o.listen=function(t,n){let s=process.env.NODE_ENV==="production",i=x?.version||"unknown";return e.debug(`[SuperExpress] is started with version ${i}`),e.debug(`[SuperExpress] will listen on port ${t}`),e.debug(`[SuperExpress] production mode: ${s}`),u(t,n)},Object.assign(o,{nativeListen:u})}var A=S;export{A as default,S as superExpress};//# sourceMappingURL=index.js.map
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../config/default-options.ts","../src/index.ts"],"names":["defaultOptions","url","safeRequire","createRequire","dirname","path","packageJson","fs","superExpress","logger","options","app","express","mergedOptions","morgan","tokens","req","res","values","HEADERS","_req","next","limit","aliveEndpoint","serverRunningSince","enableTracing","middleware","outbreak","nativeListen","port","callback","isProd","version","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import { LoggerInstanceManager } from '@autofleet/logger';\nimport { aliveEndpoint } from '@autofleet/nitur';\n\n/** Options to customize the behavior of the SuperExpress application. */\nexport interface Options {\n /** The name of the application. @default 'default-name' */\n name?: string;\n /** The version of the application. @default 'default-version' */\n version?: string;\n /** Enables or disables body parser middleware. if given a string, will be used as the limit for body size @default '1000mb' */\n bodyParser?: boolean | string;\n /** Enables or disables security headers middleware. @default true */\n helmet?: boolean;\n /** Enables or disables HTTP request logging middleware. @default true */\n morgan?: boolean;\n /** Enables or disables the alive endpoint middleware. @default true */\n nitur?: boolean;\n /** Enables or disables the stats endpoint middleware. @default true */\n stats?: boolean;\n /** Enables or disables request tracing middleware. @default true */\n tracing?: boolean;\n /** Enables or disables eager loading of user permissions for tracing middleware. @default true */\n eagerLoadUserPermissions?: boolean;\n /** Options to customize the alive endpoint middleware. */\n aliveEndpointOptions?: Omit<Parameters<typeof aliveEndpoint>[0], 'logger'>;\n /** The servers logger instance. */\n logger: LoggerInstanceManager;\n}\n\nexport const defaultOptions = {\n bodyParser: '1000mb',\n helmet: true,\n morgan: true,\n nitur: true,\n stats: true,\n tracing: true,\n eagerLoadUserPermissions: true,\n} satisfies Omit<Options, 'logger'>;","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { Server } from 'node:http';\nimport { createRequire } from 'node:module';\nimport express from 'express';\nimport { defaultOptions, Options } from '../config/default-options.js';\n\nconst { url } = import.meta;\nconst safeRequire = createRequire(url);\nconst dirname = path.dirname(url);\nconst packageJson = JSON.parse(fs.readFileSync(new URL('package.json', dirname), 'utf8'));\n\n/** Extended express.Application interface which includes nativeListen and the overridden listen method. */\ninterface SuperExpressApp extends Omit<express.Application, 'listen'> {\n /** Original express listen method. */\n nativeListen: express.Application['listen'];\n\n /**\n * Overridden listen method to add custom behavior.\n * @param port - The port number to listen on.\n * @param cb - Optional callback function to execute after the server starts listening.\n */\n listen(port: number, cb?: () => void): Server;\n}\n\n/**\n * Creates a new SuperExpress application with the given options.\n * @param options - Optional settings to customize the application.\n * @param expressOptions - Optional settings to customize express.\n * @returns A SuperExpress application instance.\n */\nexport function superExpress({ logger, ...options }: Options): SuperExpressApp {\n const app = express();\n const mergedOptions = { ...defaultOptions, ...options };\n /** Formatting */\n if (mergedOptions.morgan) {\n const morgan = safeRequire('morgan') as typeof import('morgan');\n logger.debug('[SuperExpress] formatting is enabled ✅');\n app.use(morgan((tokens, req, res) => {\n const values = {\n method: tokens.method(req, res),\n url: tokens.url(req, res) ?? 'unknown URL',\n status: tokens.status(req, res),\n contentLength: tokens.res(req, res, 'content-length'),\n responseTime: tokens['response-time'](req, res) ?? '0',\n userAgent: tokens['user-agent'](req, res),\n };\n logger.info(values.url, {\n httpRequest: {\n status: values.status,\n requestUrl: values.url,\n requestMethod: values.method,\n responseSize: values.contentLength,\n latency: {\n seconds: Number.parseInt(values.responseTime, 10) / 1_000,\n nanos: Number.parseInt(values.responseTime, 10) * 1_000_000,\n },\n userAgent: values.userAgent,\n },\n });\n return undefined;\n }));\n }\n /** Security */\n if (mergedOptions.helmet) {\n logger.debug('[SuperExpress] security is enabled ✅');\n // this is what helmet does by default. https://helmetjs.github.io/faq/you-might-not-need-helmet/\n const HEADERS = {\n \"Content-Security-Policy\":\n \"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\",\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n \"Cross-Origin-Resource-Policy\": \"same-origin\",\n \"Origin-Agent-Cluster\": \"?1\",\n \"Referrer-Policy\": \"no-referrer\",\n \"Strict-Transport-Security\": \"max-age=15552000; includeSubDomains\",\n \"X-Content-Type-Options\": \"nosniff\",\n \"X-DNS-Prefetch-Control\": \"off\",\n \"X-Download-Options\": \"noopen\",\n \"X-Frame-Options\": \"SAMEORIGIN\",\n \"X-Permitted-Cross-Domain-Policies\": \"none\",\n \"X-XSS-Protection\": \"0\",\n };\n app.use((_req, res, next) => {\n res.set(HEADERS);\n next();\n });\n app.disable('x-powered-by');\n } else {\n logger.warn('[SuperExpress] security headers are disabled 😨');\n }\n /** Body Parser */\n if (mergedOptions.bodyParser) {\n logger.debug('[SuperExpress] body-parser is enabled ✅');\n const limit = typeof mergedOptions.bodyParser === 'string' ? mergedOptions.bodyParser : '1000mb';\n app.use(express.json({ limit }))\n } else {\n logger.debug('[SuperExpress] body-parser is disabled ❌');\n }\n /** Alive Endpoint */\n if (mergedOptions.nitur) {\n const { aliveEndpoint } = safeRequire('@autofleet/nitur') as typeof import('@autofleet/nitur');\n app.get('/alive', aliveEndpoint({ logger, ...mergedOptions.aliveEndpointOptions }));\n logger.debug('[SuperExpress] added /alive endpoint ✅');\n }\n /** Stats Endpoint */\n if (mergedOptions.stats) {\n const serverRunningSince = new Date();\n app.get('/stats', (_req, res) => {\n res.json({\n name: mergedOptions.name || 'default-name',\n version: mergedOptions.version || 'default-version',\n serverRunningSince,\n });\n });\n logger.debug('[SuperExpress] added /stats endpoint ✅');\n }\n /** Tracing */\n if (mergedOptions.tracing) {\n const { enableTracing, middleware, outbreak } = safeRequire('@autofleet/zehut') as typeof import('@autofleet/zehut');\n enableTracing();\n logger.addContextMiddleware(() => ({\n traceId: outbreak.getCurrentContext()?.context?.get('x-trace-id'),\n }));\n\n app.use(middleware({\n eagerLoadUserPermissions: mergedOptions.eagerLoadUserPermissions,\n }));\n logger.debug('[SuperExpress] tracing is enabled ✅');\n }\n\n const nativeListen: typeof app['listen'] = app.listen.bind(app);\n app.listen = function (port: number, callback?: () => void) {\n const isProd = process.env.NODE_ENV === 'production';\n const version = packageJson?.version || 'unknown';\n logger.debug(`[SuperExpress] is started with version ${version}`);\n logger.debug(`[SuperExpress] will listen on port ${port}`);\n logger.debug(`[SuperExpress] production mode: ${isProd}`);\n return nativeListen(port, callback)\n } as typeof app['listen'];\n\n return Object.assign(app, { nativeListen }) as SuperExpressApp;\n};\n\nexport default superExpress;\n"]}
|
1
|
+
{"version":3,"sources":["../config/default-options.ts","../src/index.ts"],"names":["defaultOptions","url","safeRequire","createRequire","dirname","path","packageJson","fs","superExpress","logger","options","app","express","mergedOptions","morgan","tokens","req","res","values","HEADERS","_req","next","limit","aliveEndpoint","serverRunningSince","enableTracing","middleware","outbreak","nativeListen","port","callback","isProd","version","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import type { LoggerInstanceManager } from '@autofleet/logger';\nimport type { aliveEndpoint } from '@autofleet/nitur';\n\n/** Options to customize the behavior of the SuperExpress application. */\nexport interface Options {\n /** The name of the application. @default 'default-name' */\n name?: string;\n /** The version of the application. @default 'default-version' */\n version?: string;\n /** Enables or disables body parser middleware. if given a string, will be used as the limit for body size @default '1000mb' */\n bodyParser?: boolean | string;\n /** Enables or disables security headers middleware. @default true */\n helmet?: boolean;\n /** Enables or disables HTTP request logging middleware. @default true */\n morgan?: boolean;\n /** Enables or disables the alive endpoint middleware. @default true */\n nitur?: boolean;\n /** Enables or disables the stats endpoint middleware. @default true */\n stats?: boolean;\n /** Enables or disables request tracing middleware. @default true */\n tracing?: boolean;\n /** Enables or disables eager loading of user permissions for tracing middleware. @default true */\n eagerLoadUserPermissions?: boolean;\n /** Options to customize the alive endpoint middleware. */\n aliveEndpointOptions?: Omit<Parameters<typeof aliveEndpoint>[0], 'logger'>;\n /** The servers logger instance. */\n logger: LoggerInstanceManager;\n}\n\nexport const defaultOptions = {\n bodyParser: '1000mb',\n helmet: true,\n morgan: true,\n nitur: true,\n stats: true,\n tracing: true,\n eagerLoadUserPermissions: true,\n} satisfies Omit<Options, 'logger'>;\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport type { Server } from 'node:http';\nimport { createRequire } from 'node:module';\nimport express from 'express';\nimport { defaultOptions, Options } from '../config/default-options.js';\n\nconst { url } = import.meta;\nconst safeRequire = createRequire(url);\nconst dirname = path.dirname(url);\nconst packageJson = JSON.parse(fs.readFileSync(new URL('package.json', dirname), 'utf8'));\n\n/** Extended express.Application interface which includes nativeListen and the overridden listen method. */\ninterface SuperExpressApp extends Omit<express.Application, 'listen'> {\n /** Original express listen method. */\n nativeListen: express.Application['listen'];\n\n /**\n * Overridden listen method to add custom behavior.\n * @param port - The port number to listen on.\n * @param cb - Optional callback function to execute after the server starts listening.\n */\n listen(port: number, cb?: () => void): Server;\n}\n\n/**\n * Creates a new SuperExpress application with the given options.\n * @param options Optional settings to customize the application.\n * @returns A SuperExpress application instance.\n */\nexport function superExpress({ logger, ...options }: Options): SuperExpressApp {\n const app = express();\n const mergedOptions = { ...defaultOptions, ...options };\n /** Formatting */\n if (mergedOptions.morgan) {\n const morgan = safeRequire('morgan') as typeof import('morgan');\n logger.debug('[SuperExpress] formatting is enabled ✅');\n app.use(morgan((tokens, req, res) => {\n const values = {\n method: tokens.method(req, res),\n url: tokens.url(req, res) ?? 'unknown URL',\n status: tokens.status(req, res),\n contentLength: tokens.res(req, res, 'content-length'),\n responseTime: tokens['response-time'](req, res) ?? '0',\n userAgent: tokens['user-agent'](req, res),\n };\n logger.info(values.url, {\n httpRequest: {\n status: values.status,\n requestUrl: values.url,\n requestMethod: values.method,\n responseSize: values.contentLength,\n latency: {\n seconds: Number.parseInt(values.responseTime, 10) / 1_000,\n nanos: Number.parseInt(values.responseTime, 10) * 1_000_000,\n },\n userAgent: values.userAgent,\n },\n });\n return undefined;\n }));\n }\n /** Security */\n if (mergedOptions.helmet) {\n logger.debug('[SuperExpress] security is enabled ✅');\n // this is what helmet does by default. https://helmetjs.github.io/faq/you-might-not-need-helmet/\n const HEADERS = {\n 'Content-Security-Policy':\n \"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests\",\n 'Cross-Origin-Opener-Policy': 'same-origin',\n 'Cross-Origin-Resource-Policy': 'same-origin',\n 'Origin-Agent-Cluster': '?1',\n 'Referrer-Policy': 'no-referrer',\n 'Strict-Transport-Security': 'max-age=15552000; includeSubDomains',\n 'X-Content-Type-Options': 'nosniff',\n 'X-DNS-Prefetch-Control': 'off',\n 'X-Download-Options': 'noopen',\n 'X-Frame-Options': 'SAMEORIGIN',\n 'X-Permitted-Cross-Domain-Policies': 'none',\n 'X-XSS-Protection': '0',\n };\n app.use((_req, res, next) => {\n res.set(HEADERS);\n next();\n });\n app.disable('x-powered-by');\n } else {\n logger.warn('[SuperExpress] security headers are disabled 😨');\n }\n /** Body Parser */\n if (mergedOptions.bodyParser) {\n logger.debug('[SuperExpress] body-parser is enabled ✅');\n const limit = typeof mergedOptions.bodyParser === 'string' ? mergedOptions.bodyParser : '1000mb';\n app.use(express.json({ limit }));\n } else {\n logger.debug('[SuperExpress] body-parser is disabled ❌');\n }\n /** Alive Endpoint */\n if (mergedOptions.nitur) {\n const { aliveEndpoint } = safeRequire('@autofleet/nitur') as typeof import('@autofleet/nitur');\n app.get('/alive', aliveEndpoint({ logger, ...mergedOptions.aliveEndpointOptions }));\n logger.debug('[SuperExpress] added /alive endpoint ✅');\n }\n /** Stats Endpoint */\n if (mergedOptions.stats) {\n const serverRunningSince = new Date();\n app.get('/stats', (_req, res) => {\n res.json({\n name: mergedOptions.name || 'default-name',\n version: mergedOptions.version || 'default-version',\n serverRunningSince,\n });\n });\n logger.debug('[SuperExpress] added /stats endpoint ✅');\n }\n /** Tracing */\n if (mergedOptions.tracing) {\n const { enableTracing, middleware, outbreak } = safeRequire('@autofleet/zehut') as typeof import('@autofleet/zehut');\n enableTracing();\n logger.addContextMiddleware(() => ({\n traceId: outbreak.getCurrentContext()?.context?.get('x-trace-id'),\n }));\n\n app.use(middleware({\n eagerLoadUserPermissions: mergedOptions.eagerLoadUserPermissions,\n }));\n logger.debug('[SuperExpress] tracing is enabled ✅');\n }\n\n const nativeListen: typeof app['listen'] = app.listen.bind(app);\n app.listen = function (port: number, callback?: () => void) {\n const isProd = process.env.NODE_ENV === 'production';\n const version = packageJson?.version || 'unknown';\n logger.debug(`[SuperExpress] is started with version ${version}`);\n logger.debug(`[SuperExpress] will listen on port ${port}`);\n logger.debug(`[SuperExpress] production mode: ${isProd}`);\n return nativeListen(port, callback);\n } as typeof app['listen'];\n\n return Object.assign(app, { nativeListen }) as SuperExpressApp;\n}\n\nexport default superExpress;\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@autofleet/super-express",
|
3
|
-
"version": "6.0.
|
3
|
+
"version": "6.0.4",
|
4
4
|
"description": "AF Express with built in boilerplate",
|
5
5
|
"type": "module",
|
6
6
|
"main": "./dist/index.js",
|
@@ -22,7 +22,7 @@
|
|
22
22
|
"node": ">=18"
|
23
23
|
},
|
24
24
|
"author": "Autofleet",
|
25
|
-
"license": "
|
25
|
+
"license": "Proprietary",
|
26
26
|
"files": [
|
27
27
|
"dist/"
|
28
28
|
],
|
@@ -44,14 +44,18 @@
|
|
44
44
|
},
|
45
45
|
"devDependencies": {
|
46
46
|
"@autofleet/logger": "^4.2.1",
|
47
|
+
"@autofleet/nitur": "^2.1.0",
|
48
|
+
"@autofleet/zehut": "3.2.0",
|
47
49
|
"@types/express": "^4.17.21",
|
48
50
|
"@types/morgan": "^1.9.9",
|
49
51
|
"@types/supertest": "^6.0.2",
|
52
|
+
"morgan": "^1.10.0",
|
50
53
|
"supertest": "^7.0.0",
|
51
54
|
"tsup": "^8.4.0",
|
52
55
|
"tsx": "^4.19.3",
|
53
56
|
"typescript": "^5.8.2"
|
54
57
|
},
|
58
|
+
|
55
59
|
"peerDependencies": {
|
56
60
|
"@autofleet/logger": ">=4.0.0",
|
57
61
|
"@autofleet/nitur": ">=2.1.0",
|