fluxion-ts 0.11.1 → 0.12.0
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 +5 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -20
- package/dist/index.d.mts +30 -20
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -339,8 +339,9 @@ Meta APIs are served by the primary process on `metaPort` (default: `port + 1`).
|
|
|
339
339
|
Available endpoints:
|
|
340
340
|
|
|
341
341
|
```http
|
|
342
|
-
GET /_fluxion/healthz
|
|
343
|
-
GET /_fluxion/workers
|
|
342
|
+
GET /_fluxion/healthz # Health check
|
|
343
|
+
GET /_fluxion/workers # Worker status
|
|
344
|
+
GET /_fluxion/routes?secret=<secret> # Router snapshot, enabled when metaSecret is >= 20 chars with letters and digits, no whitespace
|
|
344
345
|
```
|
|
345
346
|
|
|
346
347
|
Example:
|
|
@@ -348,6 +349,7 @@ Example:
|
|
|
348
349
|
```bash
|
|
349
350
|
curl http://127.0.0.1:3001/_fluxion/healthz
|
|
350
351
|
curl http://127.0.0.1:3001/_fluxion/workers
|
|
352
|
+
curl 'http://127.0.0.1:3001/_fluxion/routes?secret=your-20-char-secret1'
|
|
351
353
|
```
|
|
352
354
|
|
|
353
355
|
## Options
|
|
@@ -374,6 +376,7 @@ interface FluxionOptions {
|
|
|
374
376
|
|
|
375
377
|
// Meta API
|
|
376
378
|
metaPort?: number; // Default: port + 1
|
|
379
|
+
metaSecret?: string; // Enables routes meta API when >= 20 chars, letters+digits, no whitespace
|
|
377
380
|
|
|
378
381
|
// Worker management
|
|
379
382
|
workerOptions?: {
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("node:fs");c=s(c);let l=require("node:path");l=s(l);let u=require("node:cluster");u=s(u);let d=require("node:os");d=s(d);let f=require("node:http");f=s(f);let p=require("node:https");p=s(p);let m=require("chokidar");m=s(m);let h=require("minimatch"),g=require("type-narrow");function _(e=new Date){return`${e.getFullYear()}.${String(e.getMonth()+1).padStart(2,`0`)}.${String(e.getDate()).padStart(2,`0`)} ${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}.${String(e.getMilliseconds()).padStart(3,`0`)}`}const v=JSON.stringify,y=Object.keys,b=process.env.FLUXION_COLORS!==`0`;let x;(function(e){e.reset=b?`\x1B[0m`:``,e.bold=b?`\x1B[1m`:``,e.dim=b?`\x1B[2m`:``,e.italic=b?`\x1B[3m`:``,e.underline=b?`\x1B[4m`:``,e.blink=b?`\x1B[5m`:``,e.inverse=b?`\x1B[7m`:``,e.black=b?`\x1B[30m`:``,e.red=b?`\x1B[31m`:``,e.green=b?`\x1B[32m`:``,e.yellow=b?`\x1B[33m`:``,e.blue=b?`\x1B[34m`:``,e.magenta=b?`\x1B[35m`:``,e.cyan=b?`\x1B[36m`:``,e.white=b?`\x1B[37m`:``,e.brightBlack=b?`\x1B[90m`:``,e.brightRed=b?`\x1B[91m`:``,e.brightGreen=b?`\x1B[92m`:``,e.brightYellow=b?`\x1B[93m`:``,e.brightBlue=b?`\x1B[94m`:``,e.brightMagenta=b?`\x1B[95m`:``,e.brightCyan=b?`\x1B[96m`:``,e.brightWhite=b?`\x1B[97m`:``,e.bgBlack=b?`\x1B[40m`:``,e.bgRed=b?`\x1B[41m`:``,e.bgGreen=b?`\x1B[42m`:``,e.bgYellow=b?`\x1B[43m`:``,e.bgBlue=b?`\x1B[44m`:``,e.bgMagenta=b?`\x1B[45m`:``,e.bgCyan=b?`\x1B[46m`:``,e.bgWhite=b?`\x1B[47m`:``,e.bgBrightBlack=b?`\x1B[100m`:``,e.bgBrightRed=b?`\x1B[101m`:``,e.bgBrightGreen=b?`\x1B[102m`:``,e.bgBrightYellow=b?`\x1B[103m`:``,e.bgBrightBlue=b?`\x1B[104m`:``,e.bgBrightMagenta=b?`\x1B[105m`:``,e.bgBrightCyan=b?`\x1B[106m`:``,e.bgBrightWhite=b?`\x1B[107m`:``,e.purple=b?`\x1B[38;2;225;16;248m`:``,e.orange=b?`\x1B[38;2;248;147;16m`:``,e.darkGreen=b?`\x1B[38;2;22;101;52m`:``,e.claude=b?`\x1B[38;2;217;119;87m`:``,e.deepseek=b?`\x1B[38;2;57;100;254m`:``,e.gpt=b?`\x1B[38;2;41;60;77m`:``})(x||={});const S=e=>{try{return v(e)}catch{return`[unserializable]`}},ee={INFO:`${x.cyan}INFO${x.reset}`,WARN:`${x.orange}WARN${x.reset}`,ERROR:`${x.red}ERROR${x.reset}`,SUCC:`${x.green}SUCC${x.reset}`,DEBUG:`${x.blue}DEBUG${x.reset}`,VERBOSE:`${x.purple}VERBOSE${x.reset}`},te=e=>{let{level:t,timestamp:n,message:r,...i}=e,a=`${x.darkGreen}[${n}]${x.reset}`,o=ee[t]??t,s=r,c=y(i).length>0?`${x.dim}${S(i)}${x.reset}`:``;console.log(`${a} ${o} ${s}${c}`)};function C(e){let t=e.options.logger;return t===void 0||t===`one-line`?te:t===`json-line`?e=>console.log(S(e)):t}function ne(e){let t=C(e);return{write(e,n,r={}){let i={...r,timestamp:_(),level:e,message:n};try{t(i)}catch{}},info(e,t){this.write(`INFO`,e,t)},warn(e,t){this.write(`WARN`,e,t)},error(e,t){this.write(`ERROR`,e,t)},succ(e,t){this.write(`SUCC`,e,t)},debug(e,t){this.write(`DEBUG`,e,t)},verbose(e,t){this.write(`VERBOSE`,e,t)}}}function re(e,t){let n=`[${t}]`;return{write(t,r,i){e.write(t,`${n} ${r}`,i)},info(t,r){e.info(`${n} ${t}`,r)},warn(t,r){e.warn(`${n} ${t}`,r)},error(t,r){e.error(`${n} ${t}`,r)},succ(t,r){e.succ(`${n} ${t}`,r)},debug(t,r){e.debug(`${n} ${t}`,r)},verbose(t,r){e.verbose(`${n} ${t}`,r)}}}const w=typeof Error.isError==`function`?e=>Error.isError(e)?e.message:String(e):e=>e?.message||String(e);function ie(e={}){let t=e.restartWhen??{},n=t.healthzTimeout??3e4;if(n!==1/0&&(!Number.isFinite(n)||n<1e4))throw Error(`[fluxion error] workerOptions.restartWhen.healthzTimeout must be a finite number >= 10000 (ms) or Infinity`);return{maxWorkerCount:e.maxWorkerCount??4,restartWhen:{memoryUsageGreaterThan:t.memoryUsageGreaterThan??1/0,healthzTimeout:n,uptimeGreaterThan:t.uptimeGreaterThan??1/0}}}function T(e,t){if(Buffer.isBuffer(e))return e;if(typeof e==`string`){if(!e.startsWith(`-----BEGIN`)){let n=l.default.isAbsolute(e)?e:l.default.join(t,e);if(c.default.existsSync(n))return c.default.readFileSync(n)}return Buffer.from(e)}throw Error(`[fluxion error] Certificate content must be a string or Buffer`)}function ae(e,t){if(!e)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`[fluxion error] FluxionOptions.https must be an object`);if(typeof e.key!=`string`)throw Error(`[fluxion error] FluxionOptions.https.key must be a string`);if(typeof e.cert!=`string`)throw Error(`[fluxion error] FluxionOptions.https.cert must be a string`);let n={key:T(e.key,t),cert:T(e.cert,t)};return e.ca!==void 0&&(Array.isArray(e.ca)?n.ca=e.ca.map(e=>T(e,t)):n.ca=T(e.ca,t)),n}function E(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`[fluxion error] FluxionOptions must be an object`);let{dir:t=l.default.isAbsolute(e.dir)?e.dir:l.default.join(process.cwd(),e.dir),host:n,port:r,handlerTimeoutMs:i=5e3,middlewareTimeoutMs:a=3e3,staticResourceTimeoutMs:o=10*6e5,metaPort:s=r+1,moduleDir:u=process.cwd(),workerOptions:d={},maxRequestBytes:f=8e6,reloadDelay:p=500,include:m=[`**/*`],apiInclude:h=[`**/*.ts`],exclude:g=[`**/node_modules/**`,`**/.git/**`,`**/dist/**`,`**/build/**`,`**/.vscode/**`,`**/.idea/**`,`**/*.log`,`**/.DS_Store`,`**/coverage/**`,`**/.nyc_output/**`,`**/*.tmp`,`**/*.temp`],https:_,nativeWatcher:v=!1}=e,y=e.logger??`one-line`;if(y!==`one-line`&&y!==`json-line`&&typeof y!=`function`)throw Error(`[fluxion error] Invalid logger option, Must be 'one-line', 'json-line' or a custom logger function`);if(typeof t!=`string`)throw Error(`[fluxion error] FluxionOptions.dir must be a string`);if(typeof u!=`string`)throw Error(`[fluxion error] FluxionOptions.moduleDir must be a string`);if(typeof n!=`string`)throw Error(`[fluxion error] FluxionOptions.host must be a string`);if(!Number.isSafeInteger(i)||i<=100)throw Error(`[fluxion error] FluxionOptions.handlerTimeoutMs must be an integer greater than 100`);if(!Number.isSafeInteger(a)||a<=100)throw Error(`[fluxion error] FluxionOptions.middlewareTimeoutMs must be an integer greater than 100`);if(typeof p!=`number`||p<=0||!Number.isSafeInteger(p))throw Error(`[fluxion error] FluxionOptions.reloadDelay must be a positive integer`);if(p<50)throw Error(`[fluxion error] FluxionOptions.reloadDelay must be greater than or equal to 50`);if(typeof r!=`number`||!Number.isSafeInteger(r))throw Error(`[fluxion error] FluxionOptions.port must be a positive integer`);if(r<=1||r>65535)throw Error(`[fluxion error] FluxionOptions.port must be 1 ~ 65535`);if(typeof s!=`number`||!Number.isSafeInteger(s))throw Error(`[fluxion error] FluxionOptions.metaPort must be a positive integer`);if(s<=1||s>65535)throw Error(`[fluxion error] FluxionOptions.metaPort must be 1 ~ 65535`);if(s===r)throw Error(`[fluxion error] FluxionOptions.metaPort must be different from FluxionOptions.port`);if(typeof d!=`object`||!d||Array.isArray(d))throw Error(`[fluxion error] FluxionOptions.workerOptions must be an object`);if(typeof f!=`number`||f<=0||!Number.isSafeInteger(f))throw Error(`[fluxion error] FluxionOptions.maxRequestBytes must be a positive integer`);return c.default.existsSync(t)||c.default.mkdirSync(t,{recursive:!0}),{dir:t,host:n,port:r,handlerTimeoutMs:i,middlewareTimeoutMs:a,staticResourceTimeoutMs:o,reloadDelay:p,metaPort:s,moduleDir:u,workerOptions:ie(d),maxRequestBytes:f,logger:y,include:m,apiInclude:h,exclude:g,nativeWatcher:v,https:ae(_,u)}}const D=e=>[100].includes(e?.type),O=e=>[202,200,201,203].includes(e?.type),k=e=>process.send?.(e),A=(e,t)=>e.send(t),j=Symbol.for(`fluxion.router.StaticHandled`),M=Symbol.for(`fluxion.handlerTimeout`),N=Symbol.for(`fluxion.middlewareTimeout`),oe={".css":`text/css; charset=utf-8`,".html":`text/html; charset=utf-8`,".ico":`image/x-icon`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".map":`application/json; charset=utf-8`,".png":`image/png`,".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".svg":`image/svg+xml`,".txt":`text/plain; charset=utf-8`,".webp":`image/webp`};let se=function(e){return e[e.Ok=200]=`Ok`,e[e.Created=201]=`Created`,e[e.Accepted=202]=`Accepted`,e[e.NoContent=204]=`NoContent`,e[e.PartialContent=206]=`PartialContent`,e[e.MovedPermanently=301]=`MovedPermanently`,e[e.Found=302]=`Found`,e[e.NotModified=304]=`NotModified`,e[e.TemporaryRedirect=307]=`TemporaryRedirect`,e[e.PermanentRedirect=308]=`PermanentRedirect`,e[e.BadRequest=400]=`BadRequest`,e[e.Unauthorized=401]=`Unauthorized`,e[e.Forbidden=403]=`Forbidden`,e[e.NotFound=404]=`NotFound`,e[e.MethodNotAllowed=405]=`MethodNotAllowed`,e[e.NotAcceptable=406]=`NotAcceptable`,e[e.RequestTimeout=408]=`RequestTimeout`,e[e.Conflict=409]=`Conflict`,e[e.Gone=410]=`Gone`,e[e.PayloadTooLarge=413]=`PayloadTooLarge`,e[e.UnsupportedMediaType=415]=`UnsupportedMediaType`,e[e.UnprocessableEntity=422]=`UnprocessableEntity`,e[e.TooManyRequests=429]=`TooManyRequests`,e[e.InternalServerError=500]=`InternalServerError`,e[e.NotImplemented=501]=`NotImplemented`,e[e.BadGateway=502]=`BadGateway`,e[e.ServiceUnavailable=503]=`ServiceUnavailable`,e[e.GatewayTimeout=504]=`GatewayTimeout`,e}({});function P(e,t,n=200){e.statusCode=n,e.setHeader(`Content-Type`,`application/json; charset=utf-8`),e.end(JSON.stringify(t))}function F(e,t,n=200){if(!e.writableEnded){if(e.headersSent){e.end();return}P(e,t,n)}}function ce(e,t){let n=f.default.createServer((e,n)=>{let r=e.method??`GET`,i=`/`;try{i=new URL(e.url??`/`,`http://fluxion.local`).pathname}catch{P(n,{message:`Bad Request: invalid url`},400);return}if(r===`GET`&&i===`/_fluxion/healthz`){P(n,{ok:!0,role:`primary`,pid:process.pid,now:Date.now(),uptimeSeconds:Number(process.uptime().toFixed(3))});return}if(r===`GET`&&i===`/_fluxion/workers`){P(n,{ok:!0,now:Date.now(),workers:t()});return}P(n,{message:`Not Found`},404)});return n.on(`listening`,()=>{e.logger.info(`MetaApiStarted`,{pid:process.pid,host:e.options.host,port:e.options.metaPort,prefix:`/_fluxion`})}),n.on(`error`,t=>{e.logger.error(`MetaApiError`,{host:e.options.host,port:e.options.metaPort,error:w(t)}),process.exit(1)}),n.listen(e.options.metaPort,e.options.host),n}const I=e=>Number((e/1024/1024).toFixed(2)),L=6e4;function R(e){if(!u.default.isPrimary)throw Error(`[fluxion error] createPrimary should only be called in primary process`);let{workerOptions:t}=e.options,n=t.restartWhen,r=Math.max(1,d.default.cpus().length),i=Math.max(1,Math.min(t.maxWorkerCount??Math.min(2,r),r));e.logger.info(`PrimaryStarted`,{pid:process.pid,workers:i,host:e.options.host,port:e.options.port,metaPort:e.options.metaPort});let a=new Map,o=new Map,s=e=>{let t=Date.now(),n=(o.get(e)??[]).filter(e=>t-e<L);return o.set(e,n),n.length},c=e=>{let t=Date.now(),n=(o.get(e)??[]).filter(e=>t-e<L);n.push(t),o.set(e,n)},l=e=>s(e)>=3;ce(e,()=>({primaryPid:process.pid,host:e.options.host,port:e.options.port,metaPort:e.options.metaPort,uptimeSeconds:Number(process.uptime().toFixed(3)),workers:Array.from(a.entries()).map(([e,t])=>{let{instance:n}=t,r=t.lastStats;return{workerId:e,slot:t.slot,pid:t.pid??n.process.pid??null,state:t.state,restartReason:t.restartReason??null,createdAt:t.createdAt,readyAt:t.readyAt??null,connected:n.isConnected(),dead:n.isDead(),exitedAfterDisconnect:n.exitedAfterDisconnect,lastPongAt:t.lastPongAt??null,lastRttMs:t.lastRttMs??null,stats:r===void 0?null:{at:r.at,uptimeSeconds:r.uptimeSeconds,cpu:r.cpu,memory:{...r.memory,rssMb:I(r.memory.rss),heapTotalMb:I(r.memory.heapTotal),heapUsedMb:I(r.memory.heapUsed),externalMb:I(r.memory.external),arrayBuffersMb:I(r.memory.arrayBuffers)}}}})}));let f=(t,n)=>{for(let e of a.values())if(e.state===`restarting`)return;if(l(t.slot)){e.logger.warn(`WorkerRecycleSuppressed`,{slot:t.slot,pid:t.pid,reason:n,windowMs:L,max:3});return}c(t.slot),t.state=`restarting`,t.restartReason=n,e.logger.warn(`WorkerRecycling`,{slot:t.slot,pid:t.pid,reason:n}),t.instance.kill()},p=(e,t)=>{let r=I(t.memory.rss);if(r>n.memoryUsageGreaterThan){f(e,`memoryUsageGreaterThan: rss ${r}MB > ${n.memoryUsageGreaterThan}MB`);return}let i=t.uptimeSeconds*1e3;i>n.uptimeGreaterThan&&f(e,`uptimeGreaterThan: ${Math.round(i/1e3)}s > ${Math.round(n.uptimeGreaterThan/1e3)}s`)},m=e=>{for(let t of a.values()){if(t.state!==`ready`||t.lastPongAt===void 0)continue;let r=e-t.lastPongAt;r>n.healthzTimeout&&f(t,`healthzTimeout: no pong for ${Math.round(r/1e3)}s > ${Math.round(n.healthzTimeout/1e3)}s`)}},h=e=>{g(u.default.fork({WORKER_ID:String(e)}),e)},g=(t,n)=>{let r={state:`creating`,pid:t.process.pid,slot:n,createdAt:Date.now(),instance:t};a.set(t.id,r),t.on(`message`,i=>{if(O(i)){if(i.type===202){let e=Date.now()-i.sentAt;r.pid=i.pid,r.lastPongAt=Date.now(),r.lastRttMs=e;return}if(i.type===201){r.state=`ready`,r.pid=i.pid,r.readyAt=Date.now(),e.logger.info(`WorkerReady`,{workerId:t.id,slot:n,pid:i.pid});return}if(i.type===200){r.state=`created`,r.pid=i.pid,e.logger.info(`WorkerCreated`,{workerId:t.id,slot:n,pid:i.pid});return}i.type===203&&(r.pid=i.pid,r.lastStats=i.stats,r.state===`ready`&&p(r,i.stats))}}),t.on(`exit`,(n,r)=>{let i=a.get(t.id);a.delete(t.id);let o=i?.slot,s=i?.state===`restarting`,u=i?.restartReason??null;if(e.logger.warn(`WorkerExited`,{workerId:t.id,slot:o??null,pid:t.process.pid??`unknown`,code:n,signal:r??`none`,expected:s,reason:u}),o!==void 0){if(s){h(o);return}if(c(o),l(o)){e.logger.error(`WorkerRespawnSuppressed`,{slot:o,windowMs:L,max:3});return}h(o)}})};for(let e=0;e<i;e++)h(e+1);setInterval(()=>{let e=Date.now();for(let t of a.values())if(t.instance.isConnected())try{A(t.instance,{type:100,sentAt:e})}catch{}m(Date.now())},5e3).unref()}function z(e,...t){return new Promise((n,r)=>{try{let i=e(...t);i instanceof Promise?i.then(n).catch(r):n(i)}catch(e){r(e)}})}function B(e){let t=e.headersDistinct[`x-forwarded-for`];if(t){let e=t[0]?.split(`,`)[0]?.trim();if(e&&e.length>0)return e}let n=e.headersDistinct[`x-real-ip`]?.[0].trim();return n===void 0?e.socket.remoteAddress??`unknown`:n}function V(e){if(e===void 0)return!1;let t=e.toLowerCase();return t.startsWith(`text/`)||t.includes(`json`)||t.includes(`xml`)||t.includes(`x-www-form-urlencoded`)||t.includes(`javascript`)}function H(e){if(e!==void 0)try{return new URL(e,`http://fluxion.local`)}catch{return}}function U(e){let t={};for(let[n,r]of e.entries()){let e=t[n];if(e===void 0){t[n]=r;continue}if(Array.isArray(e)){e.push(r);continue}t[n]=[e,r]}return t}var W=class extends Error{errno;code;constructor(e,t,n){super(e),this.name=`HttpException`,this.errno=t,this.code=n}},G=class extends W{constructor(e=`Bad Request`){super(e,400,`BAD_REQUEST`)}},le=class extends W{constructor(e=`Unauthorized`){super(e,401,`UNAUTHORIZED`)}},ue=class extends W{constructor(e=`Forbidden`){super(e,403,`FORBIDDEN`)}},de=class extends W{constructor(e=`Not Found`){super(e,404,`NOT_FOUND`)}},fe=class extends W{constructor(e=`Method Not Allowed`){super(e,405,`METHOD_NOT_ALLOWED`)}},pe=class extends W{constructor(e=`Not Acceptable`){super(e,406,`NOT_ACCEPTABLE`)}},me=class extends W{constructor(e=`Request Timeout`){super(e,408,`REQUEST_TIMEOUT`)}},he=class extends W{constructor(e=`Conflict`){super(e,409,`CONFLICT`)}},ge=class extends W{constructor(e=`Gone`){super(e,410,`GONE`)}},K=class extends W{constructor(e=`Payload Too Large`){super(e,413,`PAYLOAD_TOO_LARGE`)}},_e=class extends W{constructor(e=`Unsupported Media Type`){super(e,415,`UNSUPPORTED_MEDIA_TYPE`)}},ve=class extends W{constructor(e=`Unprocessable Entity`){super(e,422,`UNPROCESSABLE_ENTITY`)}},ye=class extends W{constructor(e=`Too Many Requests`){super(e,429,`TOO_MANY_REQUESTS`)}},be=class extends W{constructor(e=`Internal Server Error`){super(e,500,`INTERNAL_SERVER_ERROR`)}},xe=class extends W{constructor(e=`Not Implemented`){super(e,501,`NOT_IMPLEMENTED`)}},Se=class extends W{constructor(e=`Bad Gateway`){super(e,502,`BAD_GATEWAY`)}},Ce=class extends W{constructor(e=`Service Unavailable`){super(e,503,`SERVICE_UNAVAILABLE`)}},we=class extends W{constructor(e=`Gateway Timeout`){super(e,504,`GATEWAY_TIMEOUT`)}};function q(e,t){return new K(`request body too large: ${e.toString()} bytes exceeds ${t.toString()} bytes`)}function J(e){return Array.isArray(e)?e[0]:e}function Y(){return{exists:!1,bytes:0,truncated:!1}}function Te(e,t,n,r){return t===0?Y():V(n)?{exists:!0,value:e.toString(`utf8`),bytes:t,truncated:r}:{exists:!0,value:`<binary body: ${t} bytes>`,bytes:t,truncated:r}}async function Ee(e,t,n,r=8192){if(t===`GET`||t===`HEAD`||e.readableEnded)return{rawBody:void 0,preview:Y()};let i=J(e.headers[`content-length`]),a=i===void 0?NaN:Number.parseInt(i,10);if(Number.isFinite(a)&&a>n)throw q(a,n);return new Promise((t,i)=>{let a=[],o=[],s=0,c=0,l=!1,u=!1,d=()=>{e.off(`data`,p),e.off(`end`,m),e.off(`error`,h),e.off(`aborted`,g)},f=e=>{u||(u=!0,e())},p=t=>{let u=Buffer.isBuffer(t)?t:Buffer.from(t);if(s+=u.byteLength,s>n){d(),e.resume(),f(()=>{i(q(s,n))});return}if(a.push(u),c<r){let e=r-c,t=u.subarray(0,e);o.push(t),c+=t.length,t.length<u.length&&(l=!0)}else l=!0},m=()=>{d(),f(()=>{let n=a.length>0?Buffer.concat(a):void 0;t({rawBody:n,preview:Te(o.length>0?Buffer.concat(o):Buffer.alloc(0),n?.byteLength??0,J(e.headers[`content-type`]),l)})})},h=e=>{d(),f(()=>{i(e)})},g=()=>{d(),f(()=>{i(Error(`request aborted while reading body`))})};e.on(`data`,p),e.once(`end`,m),e.once(`error`,h),e.once(`aborted`,g)})}async function De(e,t,n){let{rawBody:r,preview:i}=await Ee(e,t,n);if(r===void 0||r.byteLength===0)return{body:{},preview:i};let a=J(e.headers[`content-type`])?.toLowerCase()??``;if(a.includes(`json`)){let e=r.toString(`utf8`).trim();if(e.length===0)return{body:{},preview:i};try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?{body:t,preview:i}:{body:{value:t},preview:i}}catch{return{body:{raw:e},preview:i}}}return a.includes(`x-www-form-urlencoded`)?{body:U(new URLSearchParams(r.toString(`utf8`))),preview:i}:V(a)?{body:{raw:r.toString(`utf8`)},preview:i}:{body:{},preview:i}}function Oe(e){if(!e)return{};let t={},n=e.split(`;`);for(let e of n){let[n,...r]=e.split(`=`);if(!n)continue;let i=n.trim(),a=r.join(`=`).trim();t[i]=decodeURIComponent(a)}return t}const X=(e,t,n)=>Promise.race([e,new Promise(e=>setTimeout(()=>e(n),t))]);function ke(e){let t=Object.freeze({logger:e.logger}),n=async(n,r)=>{let i=n.method??`GET`,a=B(n),o=H(n.url);if(o===void 0){F(r,{message:`Bad Request: req.url is undefined`},400);return}let s={method:i,ip:a,url:o,query:U(o.searchParams),body:{},headers:n.headers,cookie:Oe(n.headers.cookie),meta:{}},c={exists:!1,bytes:0,truncated:!1};e.logger.info(`Req`,{method:i,ip:a,path:o.pathname});let l=performance.now();r.once(`finish`,()=>{let t={workerId:process.env.WORKER_ID??`[primary]`,method:i,ip:a,path:o.pathname,status:r.statusCode,duration:(performance.now()-l).toFixed(4)};y(s.query).length>0&&(t.query=s.query),c.exists&&(t.body=c.value,t.bodyBytes=c.bytes,t.bodyTruncated=c.truncated),e.logger.info(`Res`,t)});try{if(s.url.pathname.startsWith(`/_fluxion/`)){F(r,{message:`Not Found`},404);return}let i=await De(n,s.method,e.options.maxRequestBytes);s.body=i.body,c=i.preview;let a=await e.router.getModule(o);if(!a){F(r,{message:`Not Found`},404);return}if(n.method&&a.methods&&!a.methods.includes(n.method)){F(r,{message:`Method Not Allowed`},405);return}let l=a.type===0?a.handlerTimeoutMs??e.options.handlerTimeoutMs:e.options.staticResourceTimeoutMs;if(a.middlewares)for(let i=0;i<a.middlewares.length;i++){if(await X(z(a.middlewares[i],s,t,n,r),e.options.middlewareTimeoutMs,N)===N){e.logger.warn(`MiddlewareTimeout`,{method:s.method,ip:s.ip}),F(r,{message:`Internal Server Error`},500);return}if(r.writableEnded)return;if(r.headersSent){r.end();return}}let u=await X(z(a.handler,s,t,n,r),l,M);if(u===M){e.logger.warn(`HandlerTimeout`,{method:s.method,ip:s.ip}),F(r,{message:`Handler timed out`},500);return}u!==j&&F(r,u)}catch(t){t instanceof W?(e.logger.error(`RequestFailed`,{method:s.method,ip:s.ip,path:s.url.pathname,error:t.message}),F(r,{message:t.message},t.errno)):(e.logger.error(`RequestFailed`,{method:s.method,ip:s.ip,path:s.url.pathname,error:w(t)}),F(r,{message:w(t)},t.errno??500))}},r=e.options.https?p.default.createServer({key:e.options.https.key,cert:e.options.https.cert,ca:e.options.https.ca},n):f.default.createServer(n);return r.on(`close`,()=>{e.logger.info(`ServerClosed`,{host:e.options.host,port:e.options.port})}),r.listen(e.options.port,e.options.host,()=>{e.logger.info(`ServerStarted`,{pid:process.pid,protocol:e.options.https?`https`:`http`,host:e.options.host,port:e.options.port}),e.logger.info(`DynamicDirectory`,{directory:e.options.dir})}),r.on(`error`,t=>{e.logger.error(`ServerError`,{error:w(t)})}),r}const Z=()=>{let e=process.cpuUsage(),t=Date.now();setInterval(()=>{let n=Date.now(),r=Math.max(1,(n-t)*1e3),i=process.cpuUsage(e),a=Number(((i.user+i.system)/r*100).toFixed(2));e=process.cpuUsage(),t=n;let o=process.memoryUsage();k({type:203,pid:process.pid,stats:{at:n,pid:process.pid,uptimeSeconds:Number(process.uptime().toFixed(3)),cpu:{userMicros:i.user,systemMicros:i.system,percent:a},memory:{rss:o.rss,heapTotal:o.heapTotal,heapUsed:o.heapUsed,external:o.external,arrayBuffers:o.arrayBuffers}}})},2e3).unref()};function Ae(e){if(u.default.isPrimary)throw Error(`[fluxion error] createWorker should only be called in worker process`);process.on(`message`,e=>{if(D(e)&&e.type===100){k({type:202,pid:process.pid,sentAt:e.sentAt,receivedAt:Date.now()});return}}),k({type:200,pid:process.pid}),Z();try{ke(e),k({type:201,pid:process.pid})}catch(t){e.logger.error(`WorkerBootstrapFailed`,{pid:process.pid,error:w(t)}),process.exit(1)}}var Q=class{cx;timer=null;filesChanged=new Map;constructor(e){this.cx=e}async init(){let e=this.cx.options.dir;if(!c.default.existsSync(e))return this.cx.logger.warn(`Directory does not exist: ${e}`),this;let t=[],n=(e,r)=>{let i=c.default.readdirSync(e,{withFileTypes:!0});for(let a=0;a<i.length;a++){let o=i[a],s=l.default.join(e,o.name),c=l.default.join(r,o.name);if(o.isDirectory())n(s,c);else if(o.isFile()){let e=this.cx.router.register(s,c).catch(e=>{this.cx.logger.error(`Error registering file ${c}: ${e.message}`)});t.push(e)}}};return n(e,``),await Promise.all(t),this.cx.logger.info(`Initial registration complete for directory: ${e}`),this}queueUp(e,t){this.filesChanged.set(e,t),!this.timer&&(this.timer=setTimeout(async()=>{let e=[...this.filesChanged].map(([e,t])=>this.cx.router.register(e,t).catch(e=>this.cx.logger.error(`Error refreshing handlers: ${e.message}`)).finally(()=>this.filesChanged.delete(e)));await Promise.all(e),this.timer=null},this.cx.options.reloadDelay))}stopCore(){this.timer&&=(clearTimeout(this.timer),null),this.filesChanged.clear()}},je=class extends Q{watcher=null;constructor(e){super(e)}async start(){this.stop(),await this.init();let e=this.cx.options.dir;return this.watcher=m.default.watch(e,{persistent:!0,ignoreInitial:!0,usePolling:!1,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}}).on(`all`,(t,n)=>{n&&this.queueUp(n,l.default.relative(e,n))}).on(`error`,e=>{let t=e instanceof Error?e:Error(String(e));this.cx.logger.error(`Watcher error: ${t.message}`),this.cx.logger.error(`Restarting watcher...`),this.start()}).on(`ready`,()=>{this.cx.logger.info(`Watcher ready and watching directory: ${e}`)}),this.cx.logger.info(`Watcher started on directory: ${e}`),this}stop(){return this.watcher&&=(this.watcher.close(),null),this.stopCore(),this}},Me=class extends Q{watcher=null;constructor(e){super(e)}async start(){this.stop(),await this.init();let e=this.cx.options.dir;return this.watcher=c.default.watch(e,{recursive:!0},(t,n)=>{n&&this.queueUp(l.default.join(e,n),n)}).on(`error`,e=>{this.cx.logger.error(`Watcher error: ${e.message}`),this.cx.logger.error(`Restarting watcher...`),this.start()}),this.cx.logger.info(`Watcher started on directory: ${e}`),this}stop(){return this.watcher&&=(this.watcher.close(),null),this.stopCore(),this}};function $(e,t){if(typeof t!=`object`||!t)return!1;if((0,g.static_cast)(t),typeof t.handler!=`function`)return e.logger.error(`handler must be a function`),!1;if(t.disposer!==void 0&&typeof t.disposer!=`function`)return e.logger.error(`disposer must be a function if provided`),!1;let n=t.handlerTimeoutMs;return n!==void 0&&(!Number.isSafeInteger(n)||n<100)?(e.logger.error(`handlerTimeoutMs must be an integer >= 100 if provided`),!1):t.type===0?!0:(e.logger.error(`You must use defineFluxionModule to create module`),!1)}function Ne(e,t){delete require.cache[t];let n=require(t);if(!$(e,n))if($(e,n.default))n=n.default;else throw Error(`[fluxion error] Invalid handler module '${t}', make sure it satisfies defineFluxionModule(...) helper`);return n}var Pe=class{cx;handlers=new Map;constructor(e){this.cx=e}makeStaticResource(e){return{type:1,handler:async(t,n,r)=>{if(t.method!==`GET`&&t.method!==`HEAD`){r.statusCode=405,r.setHeader(`Allow`,`GET, HEAD`),r.end();return}if(!c.default.existsSync(e)){r.statusCode=404,r.end(`Not Found`);return}let i=c.default.statSync(e);if(!i.isFile()){r.statusCode=404,r.end(`Not Found`);return}let a=oe[l.default.extname(e).toLowerCase()]??`application/octet-stream`;if(r.statusCode=200,r.setHeader(`Content-Type`,a),r.setHeader(`Content-Length`,String(i.size)),t.method===`HEAD`){r.end();return}return new Promise((t,n)=>{let i=c.default.createReadStream(e);i.on(`error`,n),i.on(`end`,()=>t(j)),i.pipe(r)})}}}async register(e,t){let n=this.handlers.get(t)?.disposer;if(n&&await z(n),!c.default.existsSync(e)){this.handlers.delete(t),this.cx.logger.info(`${x.red}Deleted ${x.reset} - ${t}`);return}if(!this.cx.options.include.some(e=>(0,h.minimatch)(t,e))){this.handlers.delete(t),this.cx.logger.info(`${x.yellow}Skipped ${x.reset} - ${t}`);return}if(this.cx.options.exclude.some(e=>(0,h.minimatch)(t,e))){this.handlers.delete(t),this.cx.logger.info(`${x.orange}Excluded${x.reset} - ${t}`);return}if(this.cx.options.apiInclude.some(e=>(0,h.minimatch)(t,e))){let n=Ne(this.cx,e);this.handlers.set(t,n),this.cx.logger.info(`${x.green}Api ${x.reset} - ${t}`);return}this.handlers.set(t,this.makeStaticResource(t)),this.cx.logger.info(`${x.brightBlue}Static ${x.reset} - ${t}`)}getModule(e){let t=e.pathname.replace(/^[/]+/,``).replace(/[/]+$/,``);return this.handlers.get(t)}remove(e){this.handlers.has(e)&&(this.handlers.delete(e),this.cx.logger.info(`${x.red}Deleted ${x.reset} - ${e}`));let t=e.endsWith(`/`)?e:e+`/`;for(let e of this.handlers.keys())e.startsWith(t)&&(this.handlers.delete(e),this.cx.logger.info(`${x.red}Deleted ${x.reset} - ${e}`))}};async function Fe(e){let t={options:E(e)};t.logger=ne(t),t.router=new Pe(t),u.default.isPrimary?R(t):(t.logger=re(t.logger,process.pid),t.watcher=await new(t.options.nativeWatcher?Me:je)(t).start(),Ae(t))}function Ie(e,t){if(typeof e==`function`){if(typeof t!=`function`)throw Error(`[fluxion error] Invalid disposer, expected a function but got ${typeof t}`);return{handler:e,disposer:t,type:0}}if(typeof e!=`object`||!e)throw Error(`[fluxion error] Invalid argument, expected a FluxionModule object or a handler function, but got ${typeof e}`);if(typeof e.handler!=`function`)throw Error(`[fluxion error] Invalid FluxionModule, "handler" must be a function`);if(e.disposer!==void 0&&typeof e.disposer!=`function`)throw Error(`[fluxion error] Invalid FluxionModule, "disposer" must be a function if provided`);if(e.methods!==void 0&&(!Array.isArray(e.methods)||e.methods.some(e=>typeof e!=`string`)))throw Error(`[fluxion error] Invalid FluxionModule, "methods" must be an array of strings if provided`);if(e.middlewares!==void 0&&(!Array.isArray(e.middlewares)||e.middlewares.some(e=>typeof e!=`function`)))throw Error(`[fluxion error] Invalid FluxionModule, "middlewares" must be an array of functions if provided`);return{...e,type:0}}function Le(e){if(typeof e!=`function`)throw Error(`[fluxion error] Invalid FluxionMiddleware, expected a function but got ${typeof e}`);return e}function Re(e){if(typeof e!=`function`)throw Error(`[fluxion error] Invalid FluxionLoggerFn, expected a function but got ${typeof e}`);return e}exports.BadGatewayException=Se,exports.BadRequestException=G,exports.ConflictException=he,exports.ForbiddenException=ue,exports.GatewayTimeoutException=we,exports.GoneException=ge,exports.HttpCode=se,exports.HttpException=W,exports.InternalServerErrorException=be,exports.MethodNotAllowedException=fe,exports.NotAcceptableException=pe,exports.NotFoundException=de,exports.NotImplementedException=xe,exports.PayloadTooLargeException=K,exports.RequestTimeoutException=me,exports.ServiceUnavailableException=Ce,exports.TooManyRequestsException=ye,exports.UnauthorizedException=le,exports.UnprocessableEntityException=ve,exports.UnsupportedMediaTypeException=_e,exports.defineFluxionLogger=Re,exports.defineFluxionMiddleware=Le,exports.defineFluxionModule=Ie,exports.fluxion=Fe;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require("fast-json-stable-stringify");c=s(c);let l=require("node:fs");l=s(l);let u=require("node:path");u=s(u);let d=require("node:cluster");d=s(d);let f=require("node:os");f=s(f);let p=require("node:http");p=s(p);let m=require("node:https");m=s(m);let h=require("chokidar");h=s(h);let g=require("minimatch");function _(e=new Date){return`${e.getFullYear()}.${String(e.getMonth()+1).padStart(2,`0`)}.${String(e.getDate()).padStart(2,`0`)} ${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}.${String(e.getMilliseconds()).padStart(3,`0`)}`}const v=process.env.FLUXION_COLORS!==`0`;let y;(function(e){e.reset=v?`\x1B[0m`:``,e.bold=v?`\x1B[1m`:``,e.dim=v?`\x1B[2m`:``,e.italic=v?`\x1B[3m`:``,e.underline=v?`\x1B[4m`:``,e.blink=v?`\x1B[5m`:``,e.inverse=v?`\x1B[7m`:``,e.black=v?`\x1B[30m`:``,e.red=v?`\x1B[31m`:``,e.green=v?`\x1B[32m`:``,e.yellow=v?`\x1B[33m`:``,e.blue=v?`\x1B[34m`:``,e.magenta=v?`\x1B[35m`:``,e.cyan=v?`\x1B[36m`:``,e.white=v?`\x1B[37m`:``,e.brightBlack=v?`\x1B[90m`:``,e.brightRed=v?`\x1B[91m`:``,e.brightGreen=v?`\x1B[92m`:``,e.brightYellow=v?`\x1B[93m`:``,e.brightBlue=v?`\x1B[94m`:``,e.brightMagenta=v?`\x1B[95m`:``,e.brightCyan=v?`\x1B[96m`:``,e.brightWhite=v?`\x1B[97m`:``,e.bgBlack=v?`\x1B[40m`:``,e.bgRed=v?`\x1B[41m`:``,e.bgGreen=v?`\x1B[42m`:``,e.bgYellow=v?`\x1B[43m`:``,e.bgBlue=v?`\x1B[44m`:``,e.bgMagenta=v?`\x1B[45m`:``,e.bgCyan=v?`\x1B[46m`:``,e.bgWhite=v?`\x1B[47m`:``,e.bgBrightBlack=v?`\x1B[100m`:``,e.bgBrightRed=v?`\x1B[101m`:``,e.bgBrightGreen=v?`\x1B[102m`:``,e.bgBrightYellow=v?`\x1B[103m`:``,e.bgBrightBlue=v?`\x1B[104m`:``,e.bgBrightMagenta=v?`\x1B[105m`:``,e.bgBrightCyan=v?`\x1B[106m`:``,e.bgBrightWhite=v?`\x1B[107m`:``,e.purple=v?`\x1B[38;2;225;16;248m`:``,e.orange=v?`\x1B[38;2;248;147;16m`:``,e.darkGreen=v?`\x1B[38;2;22;101;52m`:``,e.claude=v?`\x1B[38;2;217;119;87m`:``,e.deepseek=v?`\x1B[38;2;57;100;254m`:``,e.gpt=v?`\x1B[38;2;41;60;77m`:``})(y||={});const b=e=>{try{return(0,c.default)(e)}catch{return`[unserializable]`}},x={INFO:`${y.cyan}INFO${y.reset}`,WARN:`${y.orange}WARN${y.reset}`,ERROR:`${y.red}ERROR${y.reset}`,SUCC:`${y.green}SUCC${y.reset}`,DEBUG:`${y.blue}DEBUG${y.reset}`,VERBOSE:`${y.purple}VERBOSE${y.reset}`},S=e=>{let{level:t,timestamp:n,message:r,pid:i,...a}=e,o=`${y.darkGreen}[${n}]${y.reset}`,s=x[t]??t,c=i===void 0?``:` [${i}]`,l=Object.keys(a).length>0?` ${y.dim}${b(a)}${y.reset}`:``;console.log(`${o} ${s}${c} ${r}${l}`)};function ee(e){let t=e.options.logger;return t===void 0||t===`one-line`?S:t===`json-line`?e=>console.log(b(e)):t}function te(e){let t=ee(e);return{write(e,n){let r=typeof n==`string`?{message:n,timestamp:_(),level:e}:{...n,timestamp:_(),level:e};try{t(r)}catch{}},info(e){this.write(`INFO`,e)},warn(e){this.write(`WARN`,e)},error(e){this.write(`ERROR`,e)},succ(e){this.write(`SUCC`,e)},debug(e){this.write(`DEBUG`,e)},verbose(e){this.write(`VERBOSE`,e)}}}function ne(e,t){return{write(n,r){e.write(n,typeof r==`string`?{message:r,pid:t}:{...r,pid:t})},info(e){this.write(`INFO`,e)},warn(e){this.write(`WARN`,e)},error(e){this.write(`ERROR`,e)},succ(e){this.write(`SUCC`,e)},debug(e){this.write(`DEBUG`,e)},verbose(e){this.write(`VERBOSE`,e)}}}const C=typeof Error.isError==`function`?e=>Error.isError(e)?e.message:String(e):e=>e?.message||String(e);function w(e={}){let t=e.restartWhen??{},n=t.healthzTimeout??3e4;if(n!==1/0&&(!Number.isFinite(n)||n<1e4))throw Error(`[fluxion error] workerOptions.restartWhen.healthzTimeout must be a finite number >= 10000 (ms) or Infinity`);return{maxWorkerCount:e.maxWorkerCount??4,restartWhen:{memoryUsageGreaterThan:t.memoryUsageGreaterThan??1/0,healthzTimeout:n,uptimeGreaterThan:t.uptimeGreaterThan??1/0}}}function T(e,t){if(Buffer.isBuffer(e))return e;if(typeof e==`string`){if(!e.startsWith(`-----BEGIN`)){let n=u.default.isAbsolute(e)?e:u.default.join(t,e);if(l.default.existsSync(n))return l.default.readFileSync(n)}return Buffer.from(e)}throw Error(`[fluxion error] Certificate content must be a string or Buffer`)}function re(e,t){if(!e)return;if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`[fluxion error] FluxionOptions.https must be an object`);if(typeof e.key!=`string`)throw Error(`[fluxion error] FluxionOptions.https.key must be a string`);if(typeof e.cert!=`string`)throw Error(`[fluxion error] FluxionOptions.https.cert must be a string`);let n={key:T(e.key,t),cert:T(e.cert,t)};return e.ca!==void 0&&(Array.isArray(e.ca)?n.ca=e.ca.map(e=>T(e,t)):n.ca=T(e.ca,t)),n}function ie(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`[fluxion error] FluxionOptions must be an object`);let{dir:t,host:n,port:r,handlerTimeoutMs:i=5e3,middlewareTimeoutMs:a=3e3,staticResourceTimeoutMs:o=10*6e5,metaPort:s=r+1,moduleDir:c=process.cwd(),workerOptions:d={},maxRequestBytes:f=8e6,reloadDelay:p=500,include:m=[`**/*`],apiInclude:h=[`**/*.ts`],exclude:g=[`**/node_modules/**`,`**/.git/**`,`**/dist/**`,`**/build/**`,`**/.vscode/**`,`**/.idea/**`,`**/*.log`,`**/.DS_Store`,`**/coverage/**`,`**/.nyc_output/**`,`**/*.tmp`,`**/*.temp`],https:_,nativeWatcher:v=!1,metaSecret:y}=e,b=e.logger??`one-line`;if(b!==`one-line`&&b!==`json-line`&&typeof b!=`function`)throw Error(`[fluxion error] Invalid logger option, Must be 'one-line', 'json-line' or a custom logger function`);if(typeof t!=`string`)throw Error(`[fluxion error] FluxionOptions.dir must be a string`);let x=u.default.resolve(t);if(typeof c!=`string`)throw Error(`[fluxion error] FluxionOptions.moduleDir must be a string`);let S=u.default.resolve(c);if(typeof n!=`string`)throw Error(`[fluxion error] FluxionOptions.host must be a string`);if(!Number.isSafeInteger(i)||i<=100)throw Error(`[fluxion error] FluxionOptions.handlerTimeoutMs must be an integer greater than 100`);if(!Number.isSafeInteger(a)||a<=100)throw Error(`[fluxion error] FluxionOptions.middlewareTimeoutMs must be an integer greater than 100`);if(typeof p!=`number`||p<=0||!Number.isSafeInteger(p))throw Error(`[fluxion error] FluxionOptions.reloadDelay must be a positive integer`);if(p<50)throw Error(`[fluxion error] FluxionOptions.reloadDelay must be greater than or equal to 50`);if(typeof r!=`number`||!Number.isSafeInteger(r))throw Error(`[fluxion error] FluxionOptions.port must be a positive integer`);if(r<=1||r>65535)throw Error(`[fluxion error] FluxionOptions.port must be 1 ~ 65535`);if(typeof s!=`number`||!Number.isSafeInteger(s))throw Error(`[fluxion error] FluxionOptions.metaPort must be a positive integer`);if(s<=1||s>65535)throw Error(`[fluxion error] FluxionOptions.metaPort must be 1 ~ 65535`);if(s===r)throw Error(`[fluxion error] FluxionOptions.metaPort must be different from FluxionOptions.port`);if(typeof d!=`object`||!d||Array.isArray(d))throw Error(`[fluxion error] FluxionOptions.workerOptions must be an object`);if(typeof f!=`number`||f<=0||!Number.isSafeInteger(f))throw Error(`[fluxion error] FluxionOptions.maxRequestBytes must be a positive integer`);if(y!==void 0&&(typeof y!=`string`||y.length<20||/\s/.test(y)||!/[A-Za-z]/.test(y)||!/\d/.test(y)))throw Error(`[fluxion error] FluxionOptions.metaSecret must be a string with at least 20 characters, include both letters and digits, and contain no whitespace`);return l.default.existsSync(x)||l.default.mkdirSync(x,{recursive:!0}),{dir:x,host:n,port:r,handlerTimeoutMs:i,middlewareTimeoutMs:a,staticResourceTimeoutMs:o,reloadDelay:p,metaPort:s,moduleDir:S,workerOptions:w(d),maxRequestBytes:f,logger:b,include:m,apiInclude:h,exclude:g,nativeWatcher:v,metaSecret:y,https:re(_,S)}}const E=e=>[100,101].includes(e?.type),ae=e=>[202,200,201,203,204].includes(e?.type),D=e=>process.send?.(e),O=(e,t)=>e.send(t),k=Symbol.for(`fluxion.router.StaticHandled`),A=Symbol.for(`fluxion.handlerTimeout`),j=Symbol.for(`fluxion.middlewareTimeout`),M={".css":`text/css; charset=utf-8`,".html":`text/html; charset=utf-8`,".ico":`image/x-icon`,".js":`text/javascript; charset=utf-8`,".json":`application/json; charset=utf-8`,".map":`application/json; charset=utf-8`,".png":`image/png`,".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".svg":`image/svg+xml`,".txt":`text/plain; charset=utf-8`,".webp":`image/webp`};let oe=function(e){return e[e.Ok=200]=`Ok`,e[e.Created=201]=`Created`,e[e.Accepted=202]=`Accepted`,e[e.NoContent=204]=`NoContent`,e[e.PartialContent=206]=`PartialContent`,e[e.MovedPermanently=301]=`MovedPermanently`,e[e.Found=302]=`Found`,e[e.NotModified=304]=`NotModified`,e[e.TemporaryRedirect=307]=`TemporaryRedirect`,e[e.PermanentRedirect=308]=`PermanentRedirect`,e[e.BadRequest=400]=`BadRequest`,e[e.Unauthorized=401]=`Unauthorized`,e[e.Forbidden=403]=`Forbidden`,e[e.NotFound=404]=`NotFound`,e[e.MethodNotAllowed=405]=`MethodNotAllowed`,e[e.NotAcceptable=406]=`NotAcceptable`,e[e.RequestTimeout=408]=`RequestTimeout`,e[e.Conflict=409]=`Conflict`,e[e.Gone=410]=`Gone`,e[e.PayloadTooLarge=413]=`PayloadTooLarge`,e[e.UnsupportedMediaType=415]=`UnsupportedMediaType`,e[e.UnprocessableEntity=422]=`UnprocessableEntity`,e[e.TooManyRequests=429]=`TooManyRequests`,e[e.InternalServerError=500]=`InternalServerError`,e[e.NotImplemented=501]=`NotImplemented`,e[e.BadGateway=502]=`BadGateway`,e[e.ServiceUnavailable=503]=`ServiceUnavailable`,e[e.GatewayTimeout=504]=`GatewayTimeout`,e}({});function N(e,t,n=200){e.statusCode=n,e.setHeader(`Content-Type`,`application/json; charset=utf-8`),e.end(JSON.stringify(t))}function P(e,t,n=200){if(!e.writableEnded){if(e.headersSent){e.end();return}N(e,t,n)}}function se(e,t,n){let r=p.default.createServer(async(r,i)=>{let a=r.method??`GET`,o;try{o=new URL(r.url??`/`,`http://fluxion.local`)}catch{N(i,{message:`Bad Request: invalid url`},400);return}if(a===`GET`&&o.pathname===`/_fluxion/healthz`){N(i,{ok:!0,role:`primary`,pid:process.pid,now:Date.now(),uptimeSeconds:Number(process.uptime().toFixed(3))});return}if(a===`GET`&&o.pathname===`/_fluxion/workers`){N(i,{ok:!0,now:Date.now(),workers:t()});return}if(a===`GET`&&o.pathname===`/_fluxion/routes`){if(!e.options.metaSecret){N(i,{message:`Not Found`},404);return}if(o.searchParams.get(`secret`)!==e.options.metaSecret){N(i,{message:`Forbidden`},403);return}let t=await n();N(i,{ok:!0,now:Date.now(),routes:t});return}N(i,{message:`Not Found`},404)});return r.on(`listening`,()=>{e.logger.info({message:`MetaApiStarted`,pid:process.pid,host:e.options.host,port:e.options.metaPort,prefix:`/_fluxion`})}),r.on(`error`,t=>{e.logger.error({message:`MetaApiError`,host:e.options.host,port:e.options.metaPort,code:t.code,error:C(t)}),process.exit(1)}),r.listen(e.options.metaPort,e.options.host),r}const F=e=>Number((e/1024/1024).toFixed(2)),I=6e4;function ce(e){if(!d.default.isPrimary)throw Error(`[fluxion error] createPrimary should only be called in primary process`);let{workerOptions:t}=e.options,n=t.restartWhen,r=Math.max(1,f.default.cpus().length),i=Math.max(1,Math.min(t.maxWorkerCount??Math.min(2,r),r));e.logger.info({message:`PrimaryStarted`,pid:process.pid,workers:i,host:e.options.host,port:e.options.port,metaPort:e.options.metaPort});let a=new Map,o=new Map,s=0,c=new Map,l=e=>{let t=Date.now(),n=(c.get(e)??[]).filter(e=>t-e<I);return c.set(e,n),n.length},u=e=>{let t=Date.now(),n=(c.get(e)??[]).filter(e=>t-e<I);n.push(t),c.set(e,n)},p=e=>l(e)>=3;se(e,()=>({primaryPid:process.pid,host:e.options.host,port:e.options.port,metaPort:e.options.metaPort,uptimeSeconds:Number(process.uptime().toFixed(3)),workers:Array.from(a.entries()).map(([e,t])=>{let{instance:n}=t,r=t.lastStats;return{workerId:e,slot:t.slot,pid:t.pid??n.process.pid??null,state:t.state,restartReason:t.restartReason??null,createdAt:t.createdAt,readyAt:t.readyAt??null,connected:n.isConnected(),dead:n.isDead(),exitedAfterDisconnect:n.exitedAfterDisconnect,lastPongAt:t.lastPongAt??null,lastRttMs:t.lastRttMs??null,stats:r===void 0?null:{at:r.at,uptimeSeconds:r.uptimeSeconds,cpu:r.cpu,memory:{...r.memory,rssMb:F(r.memory.rss),heapTotalMb:F(r.memory.heapTotal),heapUsedMb:F(r.memory.heapUsed),externalMb:F(r.memory.external),arrayBuffersMb:F(r.memory.arrayBuffers)}}}})}),()=>{let e=Array.from(a.values()).find(e=>e.state===`ready`&&e.instance.isConnected());return e?new Promise(t=>{let n=++s,r=setTimeout(()=>{o.delete(n),t([])},1e3);r.unref(),o.set(n,{resolve:t,timer:r});try{O(e.instance,{type:101,requestId:n})}catch{clearTimeout(r),o.delete(n),t([])}}):Promise.resolve([])});let m=(t,n)=>{for(let e of a.values())if(e.state===`restarting`)return;if(p(t.slot)){e.logger.warn({message:`WorkerRecycleSuppressed`,slot:t.slot,pid:t.pid,reason:n,windowMs:I,max:3});return}u(t.slot),t.state=`restarting`,t.restartReason=n,e.logger.warn({message:`WorkerRecycling`,slot:t.slot,pid:t.pid,reason:n}),t.instance.kill()},h=(e,t)=>{let r=F(t.memory.rss);if(r>n.memoryUsageGreaterThan){m(e,`memoryUsageGreaterThan: rss ${r}MB > ${n.memoryUsageGreaterThan}MB`);return}let i=t.uptimeSeconds*1e3;i>n.uptimeGreaterThan&&m(e,`uptimeGreaterThan: ${Math.round(i/1e3)}s > ${Math.round(n.uptimeGreaterThan/1e3)}s`)},g=e=>{for(let t of a.values()){if(t.state!==`ready`||t.lastPongAt===void 0)continue;let r=e-t.lastPongAt;r>n.healthzTimeout&&m(t,`healthzTimeout: no pong for ${Math.round(r/1e3)}s > ${Math.round(n.healthzTimeout/1e3)}s`)}},_=e=>{v(d.default.fork({WORKER_ID:String(e)}),e)},v=(t,n)=>{let r={state:`creating`,pid:t.process.pid,slot:n,createdAt:Date.now(),instance:t};a.set(t.id,r),t.on(`message`,i=>{if(ae(i)){if(i.type===202){let e=Date.now()-i.sentAt;r.pid=i.pid,r.lastPongAt=Date.now(),r.lastRttMs=e;return}if(i.type===201){r.state=`ready`,r.pid=i.pid,r.readyAt=Date.now(),e.logger.info({message:`WorkerReady`,workerId:t.id,slot:n,pid:i.pid});return}if(i.type===200){r.state=`created`,r.pid=i.pid,e.logger.info({message:`WorkerCreated`,workerId:t.id,slot:n,pid:i.pid});return}if(i.type===203){r.pid=i.pid,r.lastStats=i.stats,r.state===`ready`&&h(r,i.stats);return}if(i.type===204){let e=o.get(i.requestId);e&&(clearTimeout(e.timer),o.delete(i.requestId),e.resolve(i.routes))}}}),t.on(`exit`,(n,r)=>{let i=a.get(t.id);a.delete(t.id);let o=i?.slot,s=i?.state===`restarting`,c=i?.restartReason??null;if(e.logger.warn({message:`WorkerExited`,workerId:t.id,slot:o??null,pid:t.process.pid??`unknown`,code:n,signal:r??`none`,expected:s,reason:c}),o!==void 0){if(s){_(o);return}if(u(o),p(o)){e.logger.error({message:`WorkerRespawnSuppressed`,slot:o,windowMs:I,max:3});return}_(o)}})};for(let e=0;e<i;e++)_(e+1);setInterval(()=>{let e=Date.now();for(let t of a.values())if(t.instance.isConnected())try{O(t.instance,{type:100,sentAt:e})}catch{}g(Date.now())},5e3).unref()}function L(e,...t){return new Promise((n,r)=>{try{let i=e(...t);i instanceof Promise?i.then(n).catch(r):n(i)}catch(e){r(e)}})}function R(e){let t=e.headersDistinct[`x-forwarded-for`];if(t){let e=t[0]?.split(`,`)[0]?.trim();if(e&&e.length>0)return e}let n=e.headersDistinct[`x-real-ip`]?.[0].trim();return n===void 0?e.socket.remoteAddress??`unknown`:n}function z(e){if(e===void 0)return!1;let t=e.toLowerCase();return t.startsWith(`text/`)||t.includes(`json`)||t.includes(`xml`)||t.includes(`x-www-form-urlencoded`)||t.includes(`javascript`)}function B(e){if(e!==void 0)try{return new URL(e,`http://fluxion.local`)}catch{return}}function V(e){let t={};for(let[n,r]of e.entries()){let e=t[n];if(e===void 0){t[n]=r;continue}if(Array.isArray(e)){e.push(r);continue}t[n]=[e,r]}return t}var H=class extends Error{errno;code;constructor(e,t,n){super(e),this.name=`HttpException`,this.errno=t,this.code=n}},U=class extends H{constructor(e=`Bad Request`){super(e,400,`BAD_REQUEST`)}},W=class extends H{constructor(e=`Unauthorized`){super(e,401,`UNAUTHORIZED`)}},G=class extends H{constructor(e=`Forbidden`){super(e,403,`FORBIDDEN`)}},le=class extends H{constructor(e=`Not Found`){super(e,404,`NOT_FOUND`)}},ue=class extends H{constructor(e=`Method Not Allowed`){super(e,405,`METHOD_NOT_ALLOWED`)}},de=class extends H{constructor(e=`Not Acceptable`){super(e,406,`NOT_ACCEPTABLE`)}},fe=class extends H{constructor(e=`Request Timeout`){super(e,408,`REQUEST_TIMEOUT`)}},pe=class extends H{constructor(e=`Conflict`){super(e,409,`CONFLICT`)}},me=class extends H{constructor(e=`Gone`){super(e,410,`GONE`)}},K=class extends H{constructor(e=`Payload Too Large`){super(e,413,`PAYLOAD_TOO_LARGE`)}},he=class extends H{constructor(e=`Unsupported Media Type`){super(e,415,`UNSUPPORTED_MEDIA_TYPE`)}},ge=class extends H{constructor(e=`Unprocessable Entity`){super(e,422,`UNPROCESSABLE_ENTITY`)}},_e=class extends H{constructor(e=`Too Many Requests`){super(e,429,`TOO_MANY_REQUESTS`)}},ve=class extends H{constructor(e=`Internal Server Error`){super(e,500,`INTERNAL_SERVER_ERROR`)}},ye=class extends H{constructor(e=`Not Implemented`){super(e,501,`NOT_IMPLEMENTED`)}},be=class extends H{constructor(e=`Bad Gateway`){super(e,502,`BAD_GATEWAY`)}},xe=class extends H{constructor(e=`Service Unavailable`){super(e,503,`SERVICE_UNAVAILABLE`)}},Se=class extends H{constructor(e=`Gateway Timeout`){super(e,504,`GATEWAY_TIMEOUT`)}};function q(e,t){return new K(`request body too large: ${e.toString()} bytes exceeds ${t.toString()} bytes`)}function J(e){return Array.isArray(e)?e[0]:e}function Y(){return{exists:!1,bytes:0,truncated:!1}}function Ce(e,t,n,r){return t===0?Y():z(n)?{exists:!0,value:e.toString(`utf8`),bytes:t,truncated:r}:{exists:!0,value:`<binary body: ${t} bytes>`,bytes:t,truncated:r}}async function we(e,t,n,r=8192){if(t===`GET`||t===`HEAD`||e.readableEnded)return{rawBody:void 0,preview:Y()};let i=J(e.headers[`content-length`]),a=i===void 0?NaN:Number.parseInt(i,10);if(Number.isFinite(a)&&a>n)throw q(a,n);return new Promise((t,i)=>{let a=[],o=[],s=0,c=0,l=!1,u=!1,d=()=>{e.off(`data`,p),e.off(`end`,m),e.off(`error`,h),e.off(`aborted`,g)},f=e=>{u||(u=!0,e())},p=t=>{let u=Buffer.isBuffer(t)?t:Buffer.from(t);if(s+=u.byteLength,s>n){d(),e.resume(),f(()=>{i(q(s,n))});return}if(a.push(u),c<r){let e=r-c,t=u.subarray(0,e);o.push(t),c+=t.length,t.length<u.length&&(l=!0)}else l=!0},m=()=>{d(),f(()=>{let n=a.length>0?Buffer.concat(a):void 0;t({rawBody:n,preview:Ce(o.length>0?Buffer.concat(o):Buffer.alloc(0),n?.byteLength??0,J(e.headers[`content-type`]),l)})})},h=e=>{d(),f(()=>{i(e)})},g=()=>{d(),f(()=>{i(Error(`request aborted while reading body`))})};e.on(`data`,p),e.once(`end`,m),e.once(`error`,h),e.once(`aborted`,g)})}async function Te(e,t,n){let{rawBody:r,preview:i}=await we(e,t,n);if(r===void 0||r.byteLength===0)return{body:{},preview:i};let a=J(e.headers[`content-type`])?.toLowerCase()??``;if(a.includes(`json`)){let e=r.toString(`utf8`).trim();if(e.length===0)return{body:{},preview:i};try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?{body:t,preview:i}:{body:{value:t},preview:i}}catch{return{body:{raw:e},preview:i}}}return a.includes(`x-www-form-urlencoded`)?{body:V(new URLSearchParams(r.toString(`utf8`))),preview:i}:z(a)?{body:{raw:r.toString(`utf8`)},preview:i}:{body:{},preview:i}}function Ee(e){if(!e)return{};let t={},n=e.split(`;`);for(let e of n){let[n,...r]=e.split(`=`);if(!n)continue;let i=n.trim(),a=r.join(`=`).trim();t[i]=decodeURIComponent(a)}return t}const X=(e,t,n)=>Promise.race([e,new Promise(e=>setTimeout(()=>e(n),t))]);function De(e){let t=Object.freeze({logger:e.logger}),n=async(n,r)=>{let i=n.method??`GET`,a=R(n),o=B(n.url);if(o===void 0){P(r,{message:`Bad Request: req.url is undefined`},400);return}let s={method:i,ip:a,url:o,query:V(o.searchParams),body:{},headers:n.headers,cookie:Ee(n.headers.cookie),meta:{}},c={exists:!1,bytes:0,truncated:!1};e.logger.info({message:`request`,method:i,ip:a,path:o.pathname});let l=performance.now();r.once(`finish`,()=>{let t={workerId:process.env.WORKER_ID??`[primary]`,message:`response`,method:i,ip:a,path:o.pathname,status:r.statusCode,duration:(performance.now()-l).toFixed(4)};Object.keys(s.query).length>0&&(t.query=s.query),c.exists&&(t.body=c.value,t.bodyBytes=c.bytes,t.bodyTruncated=c.truncated),e.logger.info(t)});try{if(s.url.pathname.startsWith(`/_fluxion/`)){P(r,{message:`Not Found`},404);return}let i=await Te(n,s.method,e.options.maxRequestBytes);s.body=i.body,c=i.preview;let a=await e.router.getModule(o);if(!a){P(r,{message:`Not Found`},404);return}if(n.method&&a.methods&&!a.methods.includes(n.method)){P(r,{message:`Method Not Allowed`},405);return}let l=a.type===0?a.handlerTimeoutMs??e.options.handlerTimeoutMs:e.options.staticResourceTimeoutMs;if(a.middlewares)for(let i=0;i<a.middlewares.length;i++){if(await X(L(a.middlewares[i],s,t,n,r),e.options.middlewareTimeoutMs,j)===j){e.logger.warn({message:`MiddlewareTimeout`,method:s.method,ip:s.ip}),P(r,{message:`Internal Server Error`},500);return}if(r.writableEnded)return;if(r.headersSent){r.end();return}}let u=await X(L(a.handler,s,t,n,r),l,A);if(u===A){e.logger.warn({message:`HandlerTimeout`,method:s.method,ip:s.ip}),P(r,{message:`Handler timed out`},500);return}u!==k&&P(r,u)}catch(t){t instanceof H?(e.logger.error({message:`RequestFailed`,method:s.method,ip:s.ip,path:s.url.pathname,error:t.message}),P(r,{message:t.message},t.errno)):(e.logger.error({message:`RequestFailed`,method:s.method,ip:s.ip,path:s.url.pathname,error:C(t)}),P(r,{message:C(t)},t.errno??500))}},r=e.options.https?m.default.createServer({key:e.options.https.key,cert:e.options.https.cert,ca:e.options.https.ca},n):p.default.createServer(n);return new Promise((t,n)=>{let i=!1;r.on(`close`,()=>{e.logger.info({message:`ServerClosed`,host:e.options.host,port:e.options.port})}),r.once(`listening`,()=>{i=!0,e.logger.info({message:`ServerStarted`,pid:process.pid,protocol:e.options.https?`https`:`http`,host:e.options.host,port:e.options.port}),e.logger.info({message:`DynamicDirectory`,directory:e.options.dir}),t(r)}),r.on(`error`,t=>{e.logger.error({message:`ServerError`,error:C(t)}),i&&process.exit(1),n(t)}),r.listen(e.options.port,e.options.host)})}const Oe=()=>{let e=process.cpuUsage(),t=Date.now();setInterval(()=>{let n=Date.now(),r=Math.max(1,(n-t)*1e3),i=process.cpuUsage(e),a=Number(((i.user+i.system)/r*100).toFixed(2));e=process.cpuUsage(),t=n;let o=process.memoryUsage();D({type:203,pid:process.pid,stats:{at:n,pid:process.pid,uptimeSeconds:Number(process.uptime().toFixed(3)),cpu:{userMicros:i.user,systemMicros:i.system,percent:a},memory:{rss:o.rss,heapTotal:o.heapTotal,heapUsed:o.heapUsed,external:o.external,arrayBuffers:o.arrayBuffers}}})},2e3).unref()};function ke(e){if(d.default.isPrimary)throw Error(`[fluxion error] createWorker should only be called in worker process`);process.on(`message`,t=>{if(E(t)){if(t.type===100){D({type:202,pid:process.pid,sentAt:t.sentAt,receivedAt:Date.now()});return}t.type===101&&D({type:204,pid:process.pid,requestId:t.requestId,routes:e.router.getRoutes()})}}),D({type:200,pid:process.pid}),Oe();let t,n=!1,r=r=>{n||(n=!0,e.logger.warn({message:`WorkerShuttingDown`,pid:process.pid,signal:r}),e.watcher.stop(),t||process.exit(0),setTimeout(()=>process.exit(1),1e4).unref(),t.close(t=>{t&&(e.logger.error({message:`WorkerShutdownFailed`,pid:process.pid,error:C(t)}),process.exit(1)),process.exit(0)}))};process.once(`SIGINT`,r),process.once(`SIGTERM`,r),De(e).then(e=>{t=e,D({type:201,pid:process.pid})}).catch(t=>{e.logger.error({message:`WorkerBootstrapFailed`,pid:process.pid,error:C(t)}),e.watcher.stop(),process.exit(1)})}var Z=class{cx;timer=null;filesChanged=new Map;constructor(e){this.cx=e}async init(){let e=this.cx.options.dir;if(!l.default.existsSync(e))return this.cx.logger.warn(`Directory does not exist: ${e}`),this;let t=[],n=(e,r)=>{let i=l.default.readdirSync(e,{withFileTypes:!0});for(let a=0;a<i.length;a++){let o=i[a],s=u.default.join(e,o.name),c=u.default.join(r,o.name);if(o.isDirectory())n(s,c);else if(o.isFile()){let e=this.cx.router.register(s,c).catch(e=>{this.cx.logger.error(`Error registering file ${c}: ${e.message}`)});t.push(e)}}};return n(e,``),await Promise.all(t),this.cx.logger.info(`Initial registration complete for directory: ${e}`),this}queueUp(e,t){this.filesChanged.set(e,t),!this.timer&&(this.timer=setTimeout(async()=>{let e=[...this.filesChanged].map(([e,t])=>this.cx.router.register(e,t).catch(e=>this.cx.logger.error(`Error refreshing handlers: ${e.message}`)).finally(()=>this.filesChanged.delete(e)));await Promise.all(e),this.timer=null},this.cx.options.reloadDelay))}stopCore(){this.timer&&=(clearTimeout(this.timer),null),this.filesChanged.clear()}},Ae=class extends Z{watcher=null;constructor(e){super(e)}async start(){this.stop(),await this.init();let e=this.cx.options.dir;return this.watcher=h.default.watch(e,{persistent:!0,ignoreInitial:!0,usePolling:!1,awaitWriteFinish:{stabilityThreshold:100,pollInterval:50}}).on(`all`,(t,n)=>{n&&this.queueUp(n,u.default.relative(e,n))}).on(`error`,e=>{let t=e instanceof Error?e:Error(String(e));this.cx.logger.error(`Watcher error: ${t.message}`),this.cx.logger.error(`Restarting watcher...`),this.start()}).on(`ready`,()=>{this.cx.logger.info(`Watcher ready and watching directory: ${e}`)}),this.cx.logger.info(`Watcher started on directory: ${e}`),this}stop(){return this.watcher&&=(this.watcher.close(),null),this.stopCore(),this}},je=class extends Z{watcher=null;constructor(e){super(e)}async start(){this.stop(),await this.init();let e=this.cx.options.dir;return this.watcher=l.default.watch(e,{recursive:!0},(t,n)=>{n&&this.queueUp(u.default.join(e,n),n)}).on(`error`,e=>{this.cx.logger.error(`Watcher error: ${e.message}`),this.cx.logger.error(`Restarting watcher...`),this.start()}),this.cx.logger.info(`Watcher started on directory: ${e}`),this}stop(){return this.watcher&&=(this.watcher.close(),null),this.stopCore(),this}};function Me(e){}const Ne=Me;function Q(e,t){if(typeof t!=`object`||!t)return!1;if(Ne(t),typeof t.handler!=`function`)return e.logger.error(`handler must be a function`),!1;if(t.disposer!==void 0&&typeof t.disposer!=`function`)return e.logger.error(`disposer must be a function if provided`),!1;let n=t.handlerTimeoutMs;return n!==void 0&&(!Number.isSafeInteger(n)||n<100)?(e.logger.error(`handlerTimeoutMs must be an integer >= 100 if provided`),!1):t.type===0?!0:(e.logger.error(`You must use defineFluxionModule to create module`),!1)}function Pe(e,t){delete require.cache[t];let n=require(t);if(Q(e,n.default))n=n.default;else if(!Q(e,n))throw Error(`[fluxion error] Invalid handler module '${t}', make sure it satisfies defineFluxionModule(...) helper`);return n}var $=class{cx;handlers=new Map;constructor(e){this.cx=e}makeStaticResource(e){return{type:1,handler:async(t,n,r,i)=>{if(t.method!==`GET`&&t.method!==`HEAD`){i.statusCode=405,i.setHeader(`Allow`,`GET, HEAD`),i.end();return}if(!l.default.existsSync(e)){i.statusCode=404,i.end(`Not Found`);return}let a=l.default.statSync(e);if(!a.isFile()){i.statusCode=404,i.end(`Not Found`);return}let o=M[u.default.extname(e).toLowerCase()]??`application/octet-stream`;if(i.statusCode=200,i.setHeader(`Content-Type`,o),i.setHeader(`Content-Length`,String(a.size)),t.method===`HEAD`){i.end();return}return new Promise((t,n)=>{let r=l.default.createReadStream(e);r.on(`error`,n),r.on(`end`,()=>t(k)),r.pipe(i)})}}}async register(e,t){let n=this.handlers.get(t)?.disposer;if(n&&await L(n),!l.default.existsSync(e)){this.handlers.delete(t),this.cx.logger.info({action:`Delete`,url:t});return}if(!this.cx.options.include.some(e=>(0,g.minimatch)(t,e))){this.handlers.delete(t),this.cx.logger.info({action:`Skip`,url:t});return}if(this.cx.options.exclude.some(e=>(0,g.minimatch)(t,e))){this.handlers.delete(t),this.cx.logger.info({action:`Exclude`,url:t});return}if(this.cx.options.apiInclude.some(e=>(0,g.minimatch)(t,e))){let n=Pe(this.cx,e);this.handlers.set(t,n),this.cx.logger.info({action:`RegisterApi`,url:t});return}this.handlers.set(t,this.makeStaticResource(e)),this.cx.logger.info({action:`RegisterStatic`,url:t})}getModule(e){let t=e.pathname.replace(/^[/]+/,``).replace(/[/]+$/,``);return this.handlers.get(t)}getRoutes(){return[...this.handlers.entries()].map(([e,t])=>({path:`/`+e,type:t.type===0?`api`:`static`,methods:t.methods?[...t.methods]:null})).sort((e,t)=>e.path.localeCompare(t.path))}};async function Fe(e){let t={options:ie(e)};t.logger=te(t),t.router=new $(t),d.default.isPrimary?ce(t):(t.logger=ne(t.logger,process.pid),t.watcher=await new(t.options.nativeWatcher?je:Ae)(t).start(),ke(t))}function Ie(e,t){if(typeof e==`function`){if(t!==void 0&&typeof t!=`function`)throw Error(`[fluxion error] Invalid disposer, expected a function but got ${typeof t}`);return{handler:e,disposer:t,type:0}}if(typeof e!=`object`||!e)throw Error(`[fluxion error] Invalid argument, expected a FluxionModule object or a handler function, but got ${typeof e}`);if(typeof e.handler!=`function`)throw Error(`[fluxion error] Invalid FluxionModule, "handler" must be a function`);if(e.disposer!==void 0&&typeof e.disposer!=`function`)throw Error(`[fluxion error] Invalid FluxionModule, "disposer" must be a function if provided`);if(e.methods!==void 0&&(!Array.isArray(e.methods)||e.methods.some(e=>typeof e!=`string`)))throw Error(`[fluxion error] Invalid FluxionModule, "methods" must be an array of strings if provided`);if(e.middlewares!==void 0&&(!Array.isArray(e.middlewares)||e.middlewares.some(e=>typeof e!=`function`)))throw Error(`[fluxion error] Invalid FluxionModule, "middlewares" must be an array of functions if provided`);return{...e,type:0}}function Le(e){if(typeof e!=`function`)throw Error(`[fluxion error] Invalid FluxionMiddleware, expected a function but got ${typeof e}`);return e}function Re(e){if(typeof e!=`function`)throw Error(`[fluxion error] Invalid FluxionLoggerFn, expected a function but got ${typeof e}`);return e}exports.BadGatewayException=be,exports.BadRequestException=U,exports.ConflictException=pe,exports.ForbiddenException=G,exports.GatewayTimeoutException=Se,exports.GoneException=me,exports.HttpCode=oe,exports.HttpException=H,exports.InternalServerErrorException=ve,exports.MethodNotAllowedException=ue,exports.NotAcceptableException=de,exports.NotFoundException=le,exports.NotImplementedException=ye,exports.PayloadTooLargeException=K,exports.RequestTimeoutException=fe,exports.ServiceUnavailableException=xe,exports.TooManyRequestsException=_e,exports.UnauthorizedException=W,exports.UnprocessableEntityException=ge,exports.UnsupportedMediaTypeException=he,exports.defineFluxionLogger=Re,exports.defineFluxionMiddleware=Le,exports.defineFluxionModule=Ie,exports.fluxion=Fe;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|