{"version":3,"sources":["jsdelivr-header.js","/npm/june-webserver@2.1.1/webserver.js"],"names":[],"mappings":"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","file":"/npm/june-webserver@2.1.1/webserver.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/june-webserver@2.1.1/webserver.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","#!/usr/bin/env node\r\n\r\n//\r\n// =============== JuNe WebServer 2.1.1 ===============\r\n//\r\n// Copyright (c) 2024 Eduardo Ruiz <eruiz@dataclick.es>\r\n// https://github.com/EduardoRuizM/june-webserver\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a copy\r\n// of this software and associated documentation files (the \"Software\"), to deal\r\n// in the Software without restriction, including without limitation the rights\r\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n// copies of the Software, and to permit persons to whom the Software is\r\n// furnished to do so, subject to the following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included in\r\n// all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n// THE SOFTWARE\r\n\r\nconst fs = require('fs');\r\nconst net = require('net');\r\nconst path = require('path');\r\nconst http = require('http');\r\nconst https = require('https');\r\nconst http2 = require('http2');\r\nconst { URL } = require('url');\r\nconst crypto = require('crypto');\r\n\r\nclass WebServer {\r\n  constructor(options) {\r\n    if(!options) {\r\n\r\n      options = {};\r\n      for(let i = 0; i < process.argv.length - 1; i++) {\r\n\r\n\tif(/^url|folder|cert|key|http2|index|if404|dev|hmr|script$/.test(process.argv[i].substring(1)) && process.argv[i + 1])\r\n\t  options[process.argv[i].substring(1)] = process.argv[i + 1];\r\n      }\r\n    }\r\n\r\n    this.url = new URL(options.url ?? 'http://localhost:8180');\r\n    this.folder = options.folder || process.cwd();\r\n    this.cert = options.cert;\r\n    this.key = options.key;\r\n    this.http2 = options.http2;\r\n    this.mime = {};\r\n    this.index = (options.index || 'index.html index.htm').split(' ');\r\n    this.if404 = options.if404;\r\n    this.dev = !!options.dev;\r\n    this.hmr = options.hmr || 30795;\r\n    this.hmrsocket = 0;\r\n    this.hmrtmr = 0;\r\n    this.script = options.script;\r\n\r\n    const mimes = 'html,htm text/html css,xml,txt text/* ics text/calendar png,gif,webp,avif image/* jpg,jpeg image/jpeg ico image/x-icon svg image/svg+xml mp3,mpg,mpeg audio/mpeg ogg,aac,opus audio/* mp4,webm video/* js,mjs text/javascript json,pdf,zip application/* ttf,woff2 font/*'.split(' ');\r\n    for(let i = 0; i < mimes.length; i+= 2) {\r\n\r\n      let ex = mimes[i].split(',');\r\n      for(let e of ex)\r\n\tthis.mime[e] = mimes[i + 1].replace('*', e);\r\n    }\r\n\r\n    this.createServer();\r\n\r\n    if(this.dev) {\r\n\r\n      this.watch(this.folder);\r\n      require('child_process').exec(((/^win/.test(process.platform)) ? 'start ' : ((/^darwin/.test(process.platform)) ? 'open ' : 'xdg-open ')) + this.url.toString());\r\n\r\n      this.hmrserver = net.createServer(socket => {\r\n\tsocket.on('data', data => {\r\n\t  let d = data.toString();\r\n\t  if(d.includes('Upgrade: websocket')) {\r\n\t    const h = /Host:\\s*(.*?)\\r\\n/i.exec(d)[1], k = /Sec-WebSocket-Key:\\s*(.*?)\\r\\n/i.exec(d)[1];\r\n\t    socket.write(`HTTP/1.1 101 Web Socket Protocol Handshake\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\nWebSocket-Origin: ${h}\\r\\nWebSocket-Location: ws://${h}/\\r\\nSec-WebSocket-Accept: ` + crypto.createHash('sha1').update(k + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11').digest('base64') + '\\r\\n\\r\\n');\r\n\t    this.hmrsocket = socket;\r\n\t  }\r\n\t});\r\n      }).listen(this.hmr, () => console.log('JuNe DevServer HMR listening', this.hmrserver.address()));\r\n    }\r\n  }\r\n  createServer() {\r\n    this.cert_dt = (this.cert && fs.existsSync(this.cert) && this.url.protocol === 'https:') ? fs.statSync(this.cert).mtime : 0;\r\n    this.server = ((this.cert_dt) ? ((this.http2) ? http2.createSecureServer : https.createServer)({cert: fs.readFileSync(this.cert), key: fs.readFileSync(this.key)}) : http.createServer())\r\n      .on('listening', () => console.log('JuNe WebServer listening', this.server.address()))\r\n      .on('request', (req, res) => this.request(req, res))\r\n      .on('error', err => console.error('Error', err));\r\n    this.server.listen((this.url.port) ? this.url.port : ((this.cert) ? 443 : 80), this.url.hostname);\r\n  }\r\n  watch(p) {\r\n    fs.watch(p, (eventType, filename) => this.change());\r\n    p = this.path(p);\r\n    fs.readdirSync(p, {withFileTypes: true}).filter(f => f.isDirectory() && f.name !== 'node_modules').map(f => this.watch(p + f.name));\r\n  }\r\n  change() {\r\n    clearTimeout(this.hmrtmr);\r\n    this.hmrtmr = setTimeout(() => {if(this.hmrsocket) this.hmrsocket.write(this.encodeWS('1'))}, 500);\r\n  }\r\n  encodeWS(t) {\r\n    let b1 = 0x80 | (0x1 & 0x0f), length = Buffer.from(t, 'utf8').length, h;\r\n    if(length <= 125) {\r\n      h = Buffer.alloc(2);\r\n      h.writeUInt8(b1, 0);\r\n      h.writeUInt8(length, 1);\r\n    } else if(length > 125 && length < 65536) {\r\n      h = Buffer.alloc(4);\r\n      h.writeUInt8(b1, 0);\r\n      h.writeUInt8(126, 1);\r\n      h.writeUInt16BE(length, 2);\r\n    } else if(length >= 65536) {\r\n      h = Buffer.alloc(10);\r\n      h.writeUInt8(b1, 0);\r\n      h.writeUInt8(127, 1);\r\n      h.writeUInt32BE(0, 2);\r\n      h.writeUInt32BE(length, 6);\r\n    }\r\n    return Buffer.concat([h, Buffer.from(t, 'utf8')]);\r\n  }\r\n  path(p) {\r\n    if(p.substring(p.length - 1) !== path.sep)\r\n      p+= path.sep;\r\n\r\n    return p;\r\n  }\r\n  async request(req, res) {\r\n    const { method, url, headers } = req;\r\n    let status = 404, str, f = this.folder + url, ext, fp;\r\n\r\n    if(fs.existsSync(f)) {\r\n\r\n      if(fs.lstatSync(f).isDirectory()) {\r\n\r\n\tf = this.path(f);\r\n\tthis.index.forEach(i => {\r\n\r\n\t  if(!fp && fs.existsSync(f + i))\r\n\t    fp = f + i;\r\n\t});\r\n\r\n      } else\r\n\tfp = f;\r\n    }\r\n\r\n    if(!fp && this.if404 && (!headers.accept || headers.accept.includes('text/html')) && (f = this.path(this.folder) + this.if404) && fs.existsSync(f))\r\n      fp = f;\r\n\r\n    if(fp) {\r\n\r\n      status = 200;\r\n      ext = fp.split('.').pop().toLowerCase();\r\n      str = fs.readFileSync(fp);\r\n      if(this.dev && ext === 'html')\r\n\tstr = str.toString('binary').replace(/<\\/head>/i, `<script>let _w_s;function _w_sf() {if(_w_s) {_w_s.close(); _w_s = null}_w_s = new WebSocket('ws://localhost:${this.hmr}'); _w_s.onmessage = e => {` + (this.script || 'location.reload()') + '}; _w_s.onerror = e => setTimeout(() => _w_sf(), 2000)}_w_sf()</script></head>');\r\n    }\r\n\r\n    res.writeHead(status, {'Content-Type': (!fp || !ext || ext === '/') ? 'text/html' : ((this.mime[ext]) ? this.mime[ext] : 'application/octet-stream')});\r\n    res.write((status === 404) ? '<div style=\"text-align: center\"><h1>404 Not Found</h1><hr><h3>JuNe WebServer</h3></div>' : str);\r\n    res.end();\r\n\r\n    if(this.cert_dt && fs.existsSync(this.cert) && this.cert_dt !== fs.statSync(this.cert).mtime) {\r\n\r\n      this.server.close();\r\n      this.createServer();\r\n    };\r\n  }\r\n}\r\n\r\nnew WebServer();\r\n"]}