server-process.js 97 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796
  1. /*!
  2. Stencil Dev Server Process v2.18.1 | MIT Licensed | https://stenciljs.com
  3. */
  4. 'use strict';
  5. const index_js = require('../sys/node/index.js');
  6. const path = require('path');
  7. const childProcess = require('child_process');
  8. const fs$1 = require('fs');
  9. const os = require('os');
  10. const fs$2 = require('../sys/node/graceful-fs.js');
  11. const util = require('util');
  12. const http = require('http');
  13. const https = require('https');
  14. const net = require('net');
  15. const openInEditorApi = require('./open-in-editor-api.js');
  16. const buffer = require('buffer');
  17. const zlib = require('zlib');
  18. const ws = require('./ws.js');
  19. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  20. function _interopNamespace(e) {
  21. if (e && e.__esModule) return e;
  22. var n = Object.create(null);
  23. if (e) {
  24. Object.keys(e).forEach(function (k) {
  25. if (k !== 'default') {
  26. var d = Object.getOwnPropertyDescriptor(e, k);
  27. Object.defineProperty(n, k, d.get ? d : {
  28. enumerable: true,
  29. get: function () {
  30. return e[k];
  31. }
  32. });
  33. }
  34. });
  35. }
  36. n['default'] = e;
  37. return Object.freeze(n);
  38. }
  39. const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
  40. const childProcess__default = /*#__PURE__*/_interopDefaultLegacy(childProcess);
  41. const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs$1);
  42. const os__default = /*#__PURE__*/_interopDefaultLegacy(os);
  43. const fs__default$1 = /*#__PURE__*/_interopDefaultLegacy(fs$2);
  44. const util__default = /*#__PURE__*/_interopDefaultLegacy(util);
  45. const http__namespace = /*#__PURE__*/_interopNamespace(http);
  46. const https__namespace = /*#__PURE__*/_interopNamespace(https);
  47. const net__namespace = /*#__PURE__*/_interopNamespace(net);
  48. const openInEditorApi__default = /*#__PURE__*/_interopDefaultLegacy(openInEditorApi);
  49. const zlib__namespace = /*#__PURE__*/_interopNamespace(zlib);
  50. const ws__namespace = /*#__PURE__*/_interopNamespace(ws);
  51. const noop = () => {
  52. /* noop*/
  53. };
  54. const isFunction = (v) => typeof v === 'function';
  55. const isString = (v) => typeof v === 'string';
  56. /**
  57. * Builds a diagnostic from an `Error`, appends it to the `diagnostics` parameter, and returns the created diagnostic
  58. * @param diagnostics the series of diagnostics the newly created diagnostics should be added to
  59. * @param err the error to derive information from in generating the diagnostic
  60. * @param msg an optional message to use in place of `err` to generate the diagnostic
  61. * @returns the generated diagnostic
  62. */
  63. const catchError = (diagnostics, err, msg) => {
  64. const diagnostic = {
  65. level: 'error',
  66. type: 'build',
  67. header: 'Build Error',
  68. messageText: 'build error',
  69. relFilePath: null,
  70. absFilePath: null,
  71. lines: [],
  72. };
  73. if (isString(msg)) {
  74. diagnostic.messageText = msg.length ? msg : 'UNKNOWN ERROR';
  75. }
  76. else if (err != null) {
  77. if (err.stack != null) {
  78. diagnostic.messageText = err.stack.toString();
  79. }
  80. else {
  81. if (err.message != null) {
  82. diagnostic.messageText = err.message.length ? err.message : 'UNKNOWN ERROR';
  83. }
  84. else {
  85. diagnostic.messageText = err.toString();
  86. }
  87. }
  88. }
  89. if (diagnostics != null && !shouldIgnoreError(diagnostic.messageText)) {
  90. diagnostics.push(diagnostic);
  91. }
  92. return diagnostic;
  93. };
  94. const shouldIgnoreError = (msg) => {
  95. return msg === TASK_CANCELED_MSG;
  96. };
  97. const TASK_CANCELED_MSG = `task canceled`;
  98. /**
  99. * Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar
  100. * Forward-slash paths can be used in Windows as long as they're not
  101. * extended-length paths and don't contain any non-ascii characters.
  102. * This was created since the path methods in Node.js outputs \\ paths on Windows.
  103. * @param path the Windows-based path to convert
  104. * @returns the converted path
  105. */
  106. const normalizePath = (path) => {
  107. if (typeof path !== 'string') {
  108. throw new Error(`invalid path to normalize`);
  109. }
  110. path = normalizeSlashes(path.trim());
  111. const components = pathComponents(path, getRootLength(path));
  112. const reducedComponents = reducePathComponents(components);
  113. const rootPart = reducedComponents[0];
  114. const secondPart = reducedComponents[1];
  115. const normalized = rootPart + reducedComponents.slice(1).join('/');
  116. if (normalized === '') {
  117. return '.';
  118. }
  119. if (rootPart === '' &&
  120. secondPart &&
  121. path.includes('/') &&
  122. !secondPart.startsWith('.') &&
  123. !secondPart.startsWith('@')) {
  124. return './' + normalized;
  125. }
  126. return normalized;
  127. };
  128. const normalizeSlashes = (path) => path.replace(backslashRegExp, '/');
  129. const altDirectorySeparator = '\\';
  130. const urlSchemeSeparator = '://';
  131. const backslashRegExp = /\\/g;
  132. const reducePathComponents = (components) => {
  133. if (!Array.isArray(components) || components.length === 0) {
  134. return [];
  135. }
  136. const reduced = [components[0]];
  137. for (let i = 1; i < components.length; i++) {
  138. const component = components[i];
  139. if (!component)
  140. continue;
  141. if (component === '.')
  142. continue;
  143. if (component === '..') {
  144. if (reduced.length > 1) {
  145. if (reduced[reduced.length - 1] !== '..') {
  146. reduced.pop();
  147. continue;
  148. }
  149. }
  150. else if (reduced[0])
  151. continue;
  152. }
  153. reduced.push(component);
  154. }
  155. return reduced;
  156. };
  157. const getRootLength = (path) => {
  158. const rootLength = getEncodedRootLength(path);
  159. return rootLength < 0 ? ~rootLength : rootLength;
  160. };
  161. const getEncodedRootLength = (path) => {
  162. if (!path)
  163. return 0;
  164. const ch0 = path.charCodeAt(0);
  165. // POSIX or UNC
  166. if (ch0 === 47 /* CharacterCodes.slash */ || ch0 === 92 /* CharacterCodes.backslash */) {
  167. if (path.charCodeAt(1) !== ch0)
  168. return 1; // POSIX: "/" (or non-normalized "\")
  169. const p1 = path.indexOf(ch0 === 47 /* CharacterCodes.slash */ ? '/' : altDirectorySeparator, 2);
  170. if (p1 < 0)
  171. return path.length; // UNC: "//server" or "\\server"
  172. return p1 + 1; // UNC: "//server/" or "\\server\"
  173. }
  174. // DOS
  175. if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* CharacterCodes.colon */) {
  176. const ch2 = path.charCodeAt(2);
  177. if (ch2 === 47 /* CharacterCodes.slash */ || ch2 === 92 /* CharacterCodes.backslash */)
  178. return 3; // DOS: "c:/" or "c:\"
  179. if (path.length === 2)
  180. return 2; // DOS: "c:" (but not "c:d")
  181. }
  182. // URL
  183. const schemeEnd = path.indexOf(urlSchemeSeparator);
  184. if (schemeEnd !== -1) {
  185. const authorityStart = schemeEnd + urlSchemeSeparator.length;
  186. const authorityEnd = path.indexOf('/', authorityStart);
  187. if (authorityEnd !== -1) {
  188. // URL: "file:///", "file://server/", "file://server/path"
  189. // For local "file" URLs, include the leading DOS volume (if present).
  190. // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a
  191. // special case interpreted as "the machine from which the URL is being interpreted".
  192. const scheme = path.slice(0, schemeEnd);
  193. const authority = path.slice(authorityStart, authorityEnd);
  194. if (scheme === 'file' &&
  195. (authority === '' || authority === 'localhost') &&
  196. isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
  197. const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
  198. if (volumeSeparatorEnd !== -1) {
  199. if (path.charCodeAt(volumeSeparatorEnd) === 47 /* CharacterCodes.slash */) {
  200. // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/"
  201. return ~(volumeSeparatorEnd + 1);
  202. }
  203. if (volumeSeparatorEnd === path.length) {
  204. // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a"
  205. // but not "file:///c:d" or "file:///c%3ad"
  206. return ~volumeSeparatorEnd;
  207. }
  208. }
  209. }
  210. return ~(authorityEnd + 1); // URL: "file://server/", "http://server/"
  211. }
  212. return ~path.length; // URL: "file://server", "http://server"
  213. }
  214. // relative
  215. return 0;
  216. };
  217. const isVolumeCharacter = (charCode) => (charCode >= 97 /* CharacterCodes.a */ && charCode <= 122 /* CharacterCodes.z */) ||
  218. (charCode >= 65 /* CharacterCodes.A */ && charCode <= 90 /* CharacterCodes.Z */);
  219. const getFileUrlVolumeSeparatorEnd = (url, start) => {
  220. const ch0 = url.charCodeAt(start);
  221. if (ch0 === 58 /* CharacterCodes.colon */)
  222. return start + 1;
  223. if (ch0 === 37 /* CharacterCodes.percent */ && url.charCodeAt(start + 1) === 51 /* CharacterCodes._3 */) {
  224. const ch2 = url.charCodeAt(start + 2);
  225. if (ch2 === 97 /* CharacterCodes.a */ || ch2 === 65 /* CharacterCodes.A */)
  226. return start + 3;
  227. }
  228. return -1;
  229. };
  230. const pathComponents = (path, rootLength) => {
  231. const root = path.substring(0, rootLength);
  232. const rest = path.substring(rootLength).split('/');
  233. const restLen = rest.length;
  234. if (restLen > 0 && !rest[restLen - 1]) {
  235. rest.pop();
  236. }
  237. return [root, ...rest];
  238. };
  239. const DEV_SERVER_URL = '/~dev-server';
  240. const DEV_MODULE_URL = '/~dev-module';
  241. const DEV_SERVER_INIT_URL = `${DEV_SERVER_URL}-init`;
  242. const OPEN_IN_EDITOR_URL = `${DEV_SERVER_URL}-open-in-editor`;
  243. const version = '2.18.1';
  244. const contentTypes = {"123":"application/vnd.lotus-1-2-3","1km":"application/vnd.1000minds.decision-model+xml","3dml":"text/vnd.in3d.3dml","3ds":"image/x-3ds","3g2":"video/3gpp2","3gp":"video/3gpp","3gpp":"video/3gpp","3mf":"model/3mf","7z":"application/x-7z-compressed","aab":"application/x-authorware-bin","aac":"audio/x-aac","aam":"application/x-authorware-map","aas":"application/x-authorware-seg","abw":"application/x-abiword","ac":"application/vnd.nokia.n-gage.ac+xml","acc":"application/vnd.americandynamics.acc","ace":"application/x-ace-compressed","acu":"application/vnd.acucobol","acutc":"application/vnd.acucorp","adp":"audio/adpcm","aep":"application/vnd.audiograph","afm":"application/x-font-type1","afp":"application/vnd.ibm.modcap","age":"application/vnd.age","ahead":"application/vnd.ahead.space","ai":"application/postscript","aif":"audio/x-aiff","aifc":"audio/x-aiff","aiff":"audio/x-aiff","air":"application/vnd.adobe.air-application-installer-package+zip","ait":"application/vnd.dvb.ait","ami":"application/vnd.amiga.ami","amr":"audio/amr","apk":"application/vnd.android.package-archive","apng":"image/apng","appcache":"text/cache-manifest","application":"application/x-ms-application","apr":"application/vnd.lotus-approach","arc":"application/x-freearc","arj":"application/x-arj","asc":"application/pgp-signature","asf":"video/x-ms-asf","asm":"text/x-asm","aso":"application/vnd.accpac.simply.aso","asx":"video/x-ms-asf","atc":"application/vnd.acucorp","atom":"application/atom+xml","atomcat":"application/atomcat+xml","atomdeleted":"application/atomdeleted+xml","atomsvc":"application/atomsvc+xml","atx":"application/vnd.antix.game-component","au":"audio/basic","avci":"image/avci","avcs":"image/avcs","avi":"video/x-msvideo","avif":"image/avif","aw":"application/applixware","azf":"application/vnd.airzip.filesecure.azf","azs":"application/vnd.airzip.filesecure.azs","azv":"image/vnd.airzip.accelerator.azv","azw":"application/vnd.amazon.ebook","b16":"image/vnd.pco.b16","bat":"application/x-msdownload","bcpio":"application/x-bcpio","bdf":"application/x-font-bdf","bdm":"application/vnd.syncml.dm+wbxml","bdoc":"application/x-bdoc","bed":"application/vnd.realvnc.bed","bh2":"application/vnd.fujitsu.oasysprs","bin":"application/octet-stream","blb":"application/x-blorb","blorb":"application/x-blorb","bmi":"application/vnd.bmi","bmml":"application/vnd.balsamiq.bmml+xml","bmp":"image/x-ms-bmp","book":"application/vnd.framemaker","box":"application/vnd.previewsystems.box","boz":"application/x-bzip2","bpk":"application/octet-stream","bsp":"model/vnd.valve.source.compiled-map","btif":"image/prs.btif","buffer":"application/octet-stream","bz":"application/x-bzip","bz2":"application/x-bzip2","c":"text/x-c","c11amc":"application/vnd.cluetrust.cartomobile-config","c11amz":"application/vnd.cluetrust.cartomobile-config-pkg","c4d":"application/vnd.clonk.c4group","c4f":"application/vnd.clonk.c4group","c4g":"application/vnd.clonk.c4group","c4p":"application/vnd.clonk.c4group","c4u":"application/vnd.clonk.c4group","cab":"application/vnd.ms-cab-compressed","caf":"audio/x-caf","cap":"application/vnd.tcpdump.pcap","car":"application/vnd.curl.car","cat":"application/vnd.ms-pki.seccat","cb7":"application/x-cbr","cba":"application/x-cbr","cbr":"application/x-cbr","cbt":"application/x-cbr","cbz":"application/x-cbr","cc":"text/x-c","cco":"application/x-cocoa","cct":"application/x-director","ccxml":"application/ccxml+xml","cdbcmsg":"application/vnd.contact.cmsg","cdf":"application/x-netcdf","cdfx":"application/cdfx+xml","cdkey":"application/vnd.mediastation.cdkey","cdmia":"application/cdmi-capability","cdmic":"application/cdmi-container","cdmid":"application/cdmi-domain","cdmio":"application/cdmi-object","cdmiq":"application/cdmi-queue","cdx":"chemical/x-cdx","cdxml":"application/vnd.chemdraw+xml","cdy":"application/vnd.cinderella","cer":"application/pkix-cert","cfs":"application/x-cfs-compressed","cgm":"image/cgm","chat":"application/x-chat","chm":"application/vnd.ms-htmlhelp","chrt":"application/vnd.kde.kchart","cif":"chemical/x-cif","cii":"application/vnd.anser-web-certificate-issue-initiation","cil":"application/vnd.ms-artgalry","cjs":"application/node","cla":"application/vnd.claymore","class":"application/java-vm","clkk":"application/vnd.crick.clicker.keyboard","clkp":"application/vnd.crick.clicker.palette","clkt":"application/vnd.crick.clicker.template","clkw":"application/vnd.crick.clicker.wordbank","clkx":"application/vnd.crick.clicker","clp":"application/x-msclip","cmc":"application/vnd.cosmocaller","cmdf":"chemical/x-cmdf","cml":"chemical/x-cml","cmp":"application/vnd.yellowriver-custom-menu","cmx":"image/x-cmx","cod":"application/vnd.rim.cod","coffee":"text/coffeescript","com":"application/x-msdownload","conf":"text/plain","cpio":"application/x-cpio","cpl":"application/cpl+xml","cpp":"text/x-c","cpt":"application/mac-compactpro","crd":"application/x-mscardfile","crl":"application/pkix-crl","crt":"application/x-x509-ca-cert","crx":"application/x-chrome-extension","cryptonote":"application/vnd.rig.cryptonote","csh":"application/x-csh","csl":"application/vnd.citationstyles.style+xml","csml":"chemical/x-csml","csp":"application/vnd.commonspace","css":"text/css","cst":"application/x-director","csv":"text/csv","cu":"application/cu-seeme","curl":"text/vnd.curl","cww":"application/prs.cww","cxt":"application/x-director","cxx":"text/x-c","dae":"model/vnd.collada+xml","daf":"application/vnd.mobius.daf","dart":"application/vnd.dart","dataless":"application/vnd.fdsn.seed","davmount":"application/davmount+xml","dbf":"application/vnd.dbf","dbk":"application/docbook+xml","dcr":"application/x-director","dcurl":"text/vnd.curl.dcurl","dd2":"application/vnd.oma.dd2+xml","ddd":"application/vnd.fujixerox.ddd","ddf":"application/vnd.syncml.dmddf+xml","dds":"image/vnd.ms-dds","deb":"application/x-debian-package","def":"text/plain","deploy":"application/octet-stream","der":"application/x-x509-ca-cert","dfac":"application/vnd.dreamfactory","dgc":"application/x-dgc-compressed","dic":"text/x-c","dir":"application/x-director","dis":"application/vnd.mobius.dis","disposition-notification":"message/disposition-notification","dist":"application/octet-stream","distz":"application/octet-stream","djv":"image/vnd.djvu","djvu":"image/vnd.djvu","dll":"application/x-msdownload","dmg":"application/x-apple-diskimage","dmp":"application/vnd.tcpdump.pcap","dms":"application/octet-stream","dna":"application/vnd.dna","doc":"application/msword","docm":"application/vnd.ms-word.document.macroenabled.12","docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document","dot":"application/msword","dotm":"application/vnd.ms-word.template.macroenabled.12","dotx":"application/vnd.openxmlformats-officedocument.wordprocessingml.template","dp":"application/vnd.osgi.dp","dpg":"application/vnd.dpgraph","dra":"audio/vnd.dra","drle":"image/dicom-rle","dsc":"text/prs.lines.tag","dssc":"application/dssc+der","dtb":"application/x-dtbook+xml","dtd":"application/xml-dtd","dts":"audio/vnd.dts","dtshd":"audio/vnd.dts.hd","dump":"application/octet-stream","dvb":"video/vnd.dvb.file","dvi":"application/x-dvi","dwd":"application/atsc-dwd+xml","dwf":"model/vnd.dwf","dwg":"image/vnd.dwg","dxf":"image/vnd.dxf","dxp":"application/vnd.spotfire.dxp","dxr":"application/x-director","ear":"application/java-archive","ecelp4800":"audio/vnd.nuera.ecelp4800","ecelp7470":"audio/vnd.nuera.ecelp7470","ecelp9600":"audio/vnd.nuera.ecelp9600","ecma":"application/ecmascript","edm":"application/vnd.novadigm.edm","edx":"application/vnd.novadigm.edx","efif":"application/vnd.picsel","ei6":"application/vnd.pg.osasli","elc":"application/octet-stream","emf":"image/emf","eml":"message/rfc822","emma":"application/emma+xml","emotionml":"application/emotionml+xml","emz":"application/x-msmetafile","eol":"audio/vnd.digital-winds","eot":"application/vnd.ms-fontobject","eps":"application/postscript","epub":"application/epub+zip","es":"application/ecmascript","es3":"application/vnd.eszigno3+xml","esa":"application/vnd.osgi.subsystem","esf":"application/vnd.epson.esf","et3":"application/vnd.eszigno3+xml","etx":"text/x-setext","eva":"application/x-eva","evy":"application/x-envoy","exe":"application/x-msdownload","exi":"application/exi","exp":"application/express","exr":"image/aces","ext":"application/vnd.novadigm.ext","ez":"application/andrew-inset","ez2":"application/vnd.ezpix-album","ez3":"application/vnd.ezpix-package","f":"text/x-fortran","f4v":"video/x-f4v","f77":"text/x-fortran","f90":"text/x-fortran","fbs":"image/vnd.fastbidsheet","fcdt":"application/vnd.adobe.formscentral.fcdt","fcs":"application/vnd.isac.fcs","fdf":"application/vnd.fdf","fdt":"application/fdt+xml","fe_launch":"application/vnd.denovo.fcselayout-link","fg5":"application/vnd.fujitsu.oasysgp","fgd":"application/x-director","fh":"image/x-freehand","fh4":"image/x-freehand","fh5":"image/x-freehand","fh7":"image/x-freehand","fhc":"image/x-freehand","fig":"application/x-xfig","fits":"image/fits","flac":"audio/x-flac","fli":"video/x-fli","flo":"application/vnd.micrografx.flo","flv":"video/x-flv","flw":"application/vnd.kde.kivio","flx":"text/vnd.fmi.flexstor","fly":"text/vnd.fly","fm":"application/vnd.framemaker","fnc":"application/vnd.frogans.fnc","fo":"application/vnd.software602.filler.form+xml","for":"text/x-fortran","fpx":"image/vnd.fpx","frame":"application/vnd.framemaker","fsc":"application/vnd.fsc.weblaunch","fst":"image/vnd.fst","ftc":"application/vnd.fluxtime.clip","fti":"application/vnd.anser-web-funds-transfer-initiation","fvt":"video/vnd.fvt","fxp":"application/vnd.adobe.fxp","fxpl":"application/vnd.adobe.fxp","fzs":"application/vnd.fuzzysheet","g2w":"application/vnd.geoplan","g3":"image/g3fax","g3w":"application/vnd.geospace","gac":"application/vnd.groove-account","gam":"application/x-tads","gbr":"application/rpki-ghostbusters","gca":"application/x-gca-compressed","gdl":"model/vnd.gdl","gdoc":"application/vnd.google-apps.document","ged":"text/vnd.familysearch.gedcom","geo":"application/vnd.dynageo","geojson":"application/geo+json","gex":"application/vnd.geometry-explorer","ggb":"application/vnd.geogebra.file","ggt":"application/vnd.geogebra.tool","ghf":"application/vnd.groove-help","gif":"image/gif","gim":"application/vnd.groove-identity-message","glb":"model/gltf-binary","gltf":"model/gltf+json","gml":"application/gml+xml","gmx":"application/vnd.gmx","gnumeric":"application/x-gnumeric","gph":"application/vnd.flographit","gpx":"application/gpx+xml","gqf":"application/vnd.grafeq","gqs":"application/vnd.grafeq","gram":"application/srgs","gramps":"application/x-gramps-xml","gre":"application/vnd.geometry-explorer","grv":"application/vnd.groove-injector","grxml":"application/srgs+xml","gsf":"application/x-font-ghostscript","gsheet":"application/vnd.google-apps.spreadsheet","gslides":"application/vnd.google-apps.presentation","gtar":"application/x-gtar","gtm":"application/vnd.groove-tool-message","gtw":"model/vnd.gtw","gv":"text/vnd.graphviz","gxf":"application/gxf","gxt":"application/vnd.geonext","gz":"application/gzip","h":"text/x-c","h261":"video/h261","h263":"video/h263","h264":"video/h264","hal":"application/vnd.hal+xml","hbci":"application/vnd.hbci","hbs":"text/x-handlebars-template","hdd":"application/x-virtualbox-hdd","hdf":"application/x-hdf","heic":"image/heic","heics":"image/heic-sequence","heif":"image/heif","heifs":"image/heif-sequence","hej2":"image/hej2k","held":"application/atsc-held+xml","hh":"text/x-c","hjson":"application/hjson","hlp":"application/winhlp","hpgl":"application/vnd.hp-hpgl","hpid":"application/vnd.hp-hpid","hps":"application/vnd.hp-hps","hqx":"application/mac-binhex40","hsj2":"image/hsj2","htc":"text/x-component","htke":"application/vnd.kenameaapp","htm":"text/html","html":"text/html","hvd":"application/vnd.yamaha.hv-dic","hvp":"application/vnd.yamaha.hv-voice","hvs":"application/vnd.yamaha.hv-script","i2g":"application/vnd.intergeo","icc":"application/vnd.iccprofile","ice":"x-conference/x-cooltalk","icm":"application/vnd.iccprofile","ico":"image/x-icon","ics":"text/calendar","ief":"image/ief","ifb":"text/calendar","ifm":"application/vnd.shana.informed.formdata","iges":"model/iges","igl":"application/vnd.igloader","igm":"application/vnd.insors.igm","igs":"model/iges","igx":"application/vnd.micrografx.igx","iif":"application/vnd.shana.informed.interchange","img":"application/octet-stream","imp":"application/vnd.accpac.simply.imp","ims":"application/vnd.ms-ims","in":"text/plain","ini":"text/plain","ink":"application/inkml+xml","inkml":"application/inkml+xml","install":"application/x-install-instructions","iota":"application/vnd.astraea-software.iota","ipfix":"application/ipfix","ipk":"application/vnd.shana.informed.package","irm":"application/vnd.ibm.rights-management","irp":"application/vnd.irepository.package+xml","iso":"application/x-iso9660-image","itp":"application/vnd.shana.informed.formtemplate","its":"application/its+xml","ivp":"application/vnd.immervision-ivp","ivu":"application/vnd.immervision-ivu","jad":"text/vnd.sun.j2me.app-descriptor","jade":"text/jade","jam":"application/vnd.jam","jar":"application/java-archive","jardiff":"application/x-java-archive-diff","java":"text/x-java-source","jhc":"image/jphc","jisp":"application/vnd.jisp","jls":"image/jls","jlt":"application/vnd.hp-jlyt","jng":"image/x-jng","jnlp":"application/x-java-jnlp-file","joda":"application/vnd.joost.joda-archive","jp2":"image/jp2","jpe":"image/jpeg","jpeg":"image/jpeg","jpf":"image/jpx","jpg":"image/jpeg","jpg2":"image/jp2","jpgm":"video/jpm","jpgv":"video/jpeg","jph":"image/jph","jpm":"video/jpm","jpx":"image/jpx","js":"application/javascript","json":"application/json","json5":"application/json5","jsonld":"application/ld+json","jsonml":"application/jsonml+json","jsx":"text/jsx","jxr":"image/jxr","jxra":"image/jxra","jxrs":"image/jxrs","jxs":"image/jxs","jxsc":"image/jxsc","jxsi":"image/jxsi","jxss":"image/jxss","kar":"audio/midi","karbon":"application/vnd.kde.karbon","kdbx":"application/x-keepass2","key":"application/x-iwork-keynote-sffkey","kfo":"application/vnd.kde.kformula","kia":"application/vnd.kidspiration","kml":"application/vnd.google-earth.kml+xml","kmz":"application/vnd.google-earth.kmz","kne":"application/vnd.kinar","knp":"application/vnd.kinar","kon":"application/vnd.kde.kontour","kpr":"application/vnd.kde.kpresenter","kpt":"application/vnd.kde.kpresenter","kpxx":"application/vnd.ds-keypoint","ksp":"application/vnd.kde.kspread","ktr":"application/vnd.kahootz","ktx":"image/ktx","ktx2":"image/ktx2","ktz":"application/vnd.kahootz","kwd":"application/vnd.kde.kword","kwt":"application/vnd.kde.kword","lasxml":"application/vnd.las.las+xml","latex":"application/x-latex","lbd":"application/vnd.llamagraphics.life-balance.desktop","lbe":"application/vnd.llamagraphics.life-balance.exchange+xml","les":"application/vnd.hhe.lesson-player","less":"text/less","lgr":"application/lgr+xml","lha":"application/x-lzh-compressed","link66":"application/vnd.route66.link66+xml","list":"text/plain","list3820":"application/vnd.ibm.modcap","listafp":"application/vnd.ibm.modcap","litcoffee":"text/coffeescript","lnk":"application/x-ms-shortcut","log":"text/plain","lostxml":"application/lost+xml","lrf":"application/octet-stream","lrm":"application/vnd.ms-lrm","ltf":"application/vnd.frogans.ltf","lua":"text/x-lua","luac":"application/x-lua-bytecode","lvp":"audio/vnd.lucent.voice","lwp":"application/vnd.lotus-wordpro","lzh":"application/x-lzh-compressed","m13":"application/x-msmediaview","m14":"application/x-msmediaview","m1v":"video/mpeg","m21":"application/mp21","m2a":"audio/mpeg","m2v":"video/mpeg","m3a":"audio/mpeg","m3u":"audio/x-mpegurl","m3u8":"application/vnd.apple.mpegurl","m4a":"audio/x-m4a","m4p":"application/mp4","m4s":"video/iso.segment","m4u":"video/vnd.mpegurl","m4v":"video/x-m4v","ma":"application/mathematica","mads":"application/mads+xml","maei":"application/mmt-aei+xml","mag":"application/vnd.ecowin.chart","maker":"application/vnd.framemaker","man":"text/troff","manifest":"text/cache-manifest","map":"application/json","mar":"application/octet-stream","markdown":"text/markdown","mathml":"application/mathml+xml","mb":"application/mathematica","mbk":"application/vnd.mobius.mbk","mbox":"application/mbox","mc1":"application/vnd.medcalcdata","mcd":"application/vnd.mcd","mcurl":"text/vnd.curl.mcurl","md":"text/markdown","mdb":"application/x-msaccess","mdi":"image/vnd.ms-modi","mdx":"text/mdx","me":"text/troff","mesh":"model/mesh","meta4":"application/metalink4+xml","metalink":"application/metalink+xml","mets":"application/mets+xml","mfm":"application/vnd.mfmp","mft":"application/rpki-manifest","mgp":"application/vnd.osgeo.mapguide.package","mgz":"application/vnd.proteus.magazine","mid":"audio/midi","midi":"audio/midi","mie":"application/x-mie","mif":"application/vnd.mif","mime":"message/rfc822","mj2":"video/mj2","mjp2":"video/mj2","mjs":"application/javascript","mk3d":"video/x-matroska","mka":"audio/x-matroska","mkd":"text/x-markdown","mks":"video/x-matroska","mkv":"video/x-matroska","mlp":"application/vnd.dolby.mlp","mmd":"application/vnd.chipnuts.karaoke-mmd","mmf":"application/vnd.smaf","mml":"text/mathml","mmr":"image/vnd.fujixerox.edmics-mmr","mng":"video/x-mng","mny":"application/x-msmoney","mobi":"application/x-mobipocket-ebook","mods":"application/mods+xml","mov":"video/quicktime","movie":"video/x-sgi-movie","mp2":"audio/mpeg","mp21":"application/mp21","mp2a":"audio/mpeg","mp3":"audio/mpeg","mp4":"video/mp4","mp4a":"audio/mp4","mp4s":"application/mp4","mp4v":"video/mp4","mpc":"application/vnd.mophun.certificate","mpd":"application/dash+xml","mpe":"video/mpeg","mpeg":"video/mpeg","mpf":"application/media-policy-dataset+xml","mpg":"video/mpeg","mpg4":"video/mp4","mpga":"audio/mpeg","mpkg":"application/vnd.apple.installer+xml","mpm":"application/vnd.blueice.multipass","mpn":"application/vnd.mophun.application","mpp":"application/vnd.ms-project","mpt":"application/vnd.ms-project","mpy":"application/vnd.ibm.minipay","mqy":"application/vnd.mobius.mqy","mrc":"application/marc","mrcx":"application/marcxml+xml","ms":"text/troff","mscml":"application/mediaservercontrol+xml","mseed":"application/vnd.fdsn.mseed","mseq":"application/vnd.mseq","msf":"application/vnd.epson.msf","msg":"application/vnd.ms-outlook","msh":"model/mesh","msi":"application/x-msdownload","msl":"application/vnd.mobius.msl","msm":"application/octet-stream","msp":"application/octet-stream","msty":"application/vnd.muvee.style","mtl":"model/mtl","mts":"model/vnd.mts","mus":"application/vnd.musician","musd":"application/mmt-usd+xml","musicxml":"application/vnd.recordare.musicxml+xml","mvb":"application/x-msmediaview","mvt":"application/vnd.mapbox-vector-tile","mwf":"application/vnd.mfer","mxf":"application/mxf","mxl":"application/vnd.recordare.musicxml","mxmf":"audio/mobile-xmf","mxml":"application/xv+xml","mxs":"application/vnd.triscape.mxs","mxu":"video/vnd.mpegurl","n-gage":"application/vnd.nokia.n-gage.symbian.install","n3":"text/n3","nb":"application/mathematica","nbp":"application/vnd.wolfram.player","nc":"application/x-netcdf","ncx":"application/x-dtbncx+xml","nfo":"text/x-nfo","ngdat":"application/vnd.nokia.n-gage.data","nitf":"application/vnd.nitf","nlu":"application/vnd.neurolanguage.nlu","nml":"application/vnd.enliven","nnd":"application/vnd.noblenet-directory","nns":"application/vnd.noblenet-sealer","nnw":"application/vnd.noblenet-web","npx":"image/vnd.net-fpx","nq":"application/n-quads","nsc":"application/x-conference","nsf":"application/vnd.lotus-notes","nt":"application/n-triples","ntf":"application/vnd.nitf","numbers":"application/x-iwork-numbers-sffnumbers","nzb":"application/x-nzb","oa2":"application/vnd.fujitsu.oasys2","oa3":"application/vnd.fujitsu.oasys3","oas":"application/vnd.fujitsu.oasys","obd":"application/x-msbinder","obgx":"application/vnd.openblox.game+xml","obj":"model/obj","oda":"application/oda","odb":"application/vnd.oasis.opendocument.database","odc":"application/vnd.oasis.opendocument.chart","odf":"application/vnd.oasis.opendocument.formula","odft":"application/vnd.oasis.opendocument.formula-template","odg":"application/vnd.oasis.opendocument.graphics","odi":"application/vnd.oasis.opendocument.image","odm":"application/vnd.oasis.opendocument.text-master","odp":"application/vnd.oasis.opendocument.presentation","ods":"application/vnd.oasis.opendocument.spreadsheet","odt":"application/vnd.oasis.opendocument.text","oga":"audio/ogg","ogex":"model/vnd.opengex","ogg":"audio/ogg","ogv":"video/ogg","ogx":"application/ogg","omdoc":"application/omdoc+xml","onepkg":"application/onenote","onetmp":"application/onenote","onetoc":"application/onenote","onetoc2":"application/onenote","opf":"application/oebps-package+xml","opml":"text/x-opml","oprc":"application/vnd.palm","opus":"audio/ogg","org":"text/x-org","osf":"application/vnd.yamaha.openscoreformat","osfpvg":"application/vnd.yamaha.openscoreformat.osfpvg+xml","osm":"application/vnd.openstreetmap.data+xml","otc":"application/vnd.oasis.opendocument.chart-template","otf":"font/otf","otg":"application/vnd.oasis.opendocument.graphics-template","oth":"application/vnd.oasis.opendocument.text-web","oti":"application/vnd.oasis.opendocument.image-template","otp":"application/vnd.oasis.opendocument.presentation-template","ots":"application/vnd.oasis.opendocument.spreadsheet-template","ott":"application/vnd.oasis.opendocument.text-template","ova":"application/x-virtualbox-ova","ovf":"application/x-virtualbox-ovf","owl":"application/rdf+xml","oxps":"application/oxps","oxt":"application/vnd.openofficeorg.extension","p":"text/x-pascal","p10":"application/pkcs10","p12":"application/x-pkcs12","p7b":"application/x-pkcs7-certificates","p7c":"application/pkcs7-mime","p7m":"application/pkcs7-mime","p7r":"application/x-pkcs7-certreqresp","p7s":"application/pkcs7-signature","p8":"application/pkcs8","pac":"application/x-ns-proxy-autoconfig","pages":"application/x-iwork-pages-sffpages","pas":"text/x-pascal","paw":"application/vnd.pawaafile","pbd":"application/vnd.powerbuilder6","pbm":"image/x-portable-bitmap","pcap":"application/vnd.tcpdump.pcap","pcf":"application/x-font-pcf","pcl":"application/vnd.hp-pcl","pclxl":"application/vnd.hp-pclxl","pct":"image/x-pict","pcurl":"application/vnd.curl.pcurl","pcx":"image/x-pcx","pdb":"application/x-pilot","pde":"text/x-processing","pdf":"application/pdf","pem":"application/x-x509-ca-cert","pfa":"application/x-font-type1","pfb":"application/x-font-type1","pfm":"application/x-font-type1","pfr":"application/font-tdpfr","pfx":"application/x-pkcs12","pgm":"image/x-portable-graymap","pgn":"application/x-chess-pgn","pgp":"application/pgp-encrypted","php":"application/x-httpd-php","pic":"image/x-pict","pkg":"application/octet-stream","pki":"application/pkixcmp","pkipath":"application/pkix-pkipath","pkpass":"application/vnd.apple.pkpass","pl":"application/x-perl","plb":"application/vnd.3gpp.pic-bw-large","plc":"application/vnd.mobius.plc","plf":"application/vnd.pocketlearn","pls":"application/pls+xml","pm":"application/x-perl","pml":"application/vnd.ctc-posml","png":"image/png","pnm":"image/x-portable-anymap","portpkg":"application/vnd.macports.portpkg","pot":"application/vnd.ms-powerpoint","potm":"application/vnd.ms-powerpoint.template.macroenabled.12","potx":"application/vnd.openxmlformats-officedocument.presentationml.template","ppam":"application/vnd.ms-powerpoint.addin.macroenabled.12","ppd":"application/vnd.cups-ppd","ppm":"image/x-portable-pixmap","pps":"application/vnd.ms-powerpoint","ppsm":"application/vnd.ms-powerpoint.slideshow.macroenabled.12","ppsx":"application/vnd.openxmlformats-officedocument.presentationml.slideshow","ppt":"application/vnd.ms-powerpoint","pptm":"application/vnd.ms-powerpoint.presentation.macroenabled.12","pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation","pqa":"application/vnd.palm","prc":"application/x-pilot","pre":"application/vnd.lotus-freelance","prf":"application/pics-rules","provx":"application/provenance+xml","ps":"application/postscript","psb":"application/vnd.3gpp.pic-bw-small","psd":"image/vnd.adobe.photoshop","psf":"application/x-font-linux-psf","pskcxml":"application/pskc+xml","pti":"image/prs.pti","ptid":"application/vnd.pvi.ptid1","pub":"application/x-mspublisher","pvb":"application/vnd.3gpp.pic-bw-var","pwn":"application/vnd.3m.post-it-notes","pya":"audio/vnd.ms-playready.media.pya","pyv":"video/vnd.ms-playready.media.pyv","qam":"application/vnd.epson.quickanime","qbo":"application/vnd.intu.qbo","qfx":"application/vnd.intu.qfx","qps":"application/vnd.publishare-delta-tree","qt":"video/quicktime","qwd":"application/vnd.quark.quarkxpress","qwt":"application/vnd.quark.quarkxpress","qxb":"application/vnd.quark.quarkxpress","qxd":"application/vnd.quark.quarkxpress","qxl":"application/vnd.quark.quarkxpress","qxt":"application/vnd.quark.quarkxpress","ra":"audio/x-realaudio","ram":"audio/x-pn-realaudio","raml":"application/raml+yaml","rapd":"application/route-apd+xml","rar":"application/x-rar-compressed","ras":"image/x-cmu-raster","rcprofile":"application/vnd.ipunplugged.rcprofile","rdf":"application/rdf+xml","rdz":"application/vnd.data-vision.rdz","relo":"application/p2p-overlay+xml","rep":"application/vnd.businessobjects","res":"application/x-dtbresource+xml","rgb":"image/x-rgb","rif":"application/reginfo+xml","rip":"audio/vnd.rip","ris":"application/x-research-info-systems","rl":"application/resource-lists+xml","rlc":"image/vnd.fujixerox.edmics-rlc","rld":"application/resource-lists-diff+xml","rm":"application/vnd.rn-realmedia","rmi":"audio/midi","rmp":"audio/x-pn-realaudio-plugin","rms":"application/vnd.jcp.javame.midlet-rms","rmvb":"application/vnd.rn-realmedia-vbr","rnc":"application/relax-ng-compact-syntax","rng":"application/xml","roa":"application/rpki-roa","roff":"text/troff","rp9":"application/vnd.cloanto.rp9","rpm":"application/x-redhat-package-manager","rpss":"application/vnd.nokia.radio-presets","rpst":"application/vnd.nokia.radio-preset","rq":"application/sparql-query","rs":"application/rls-services+xml","rsat":"application/atsc-rsat+xml","rsd":"application/rsd+xml","rsheet":"application/urc-ressheet+xml","rss":"application/rss+xml","rtf":"text/rtf","rtx":"text/richtext","run":"application/x-makeself","rusd":"application/route-usd+xml","s":"text/x-asm","s3m":"audio/s3m","saf":"application/vnd.yamaha.smaf-audio","sass":"text/x-sass","sbml":"application/sbml+xml","sc":"application/vnd.ibm.secure-container","scd":"application/x-msschedule","scm":"application/vnd.lotus-screencam","scq":"application/scvp-cv-request","scs":"application/scvp-cv-response","scss":"text/x-scss","scurl":"text/vnd.curl.scurl","sda":"application/vnd.stardivision.draw","sdc":"application/vnd.stardivision.calc","sdd":"application/vnd.stardivision.impress","sdkd":"application/vnd.solent.sdkm+xml","sdkm":"application/vnd.solent.sdkm+xml","sdp":"application/sdp","sdw":"application/vnd.stardivision.writer","sea":"application/x-sea","see":"application/vnd.seemail","seed":"application/vnd.fdsn.seed","sema":"application/vnd.sema","semd":"application/vnd.semd","semf":"application/vnd.semf","senmlx":"application/senml+xml","sensmlx":"application/sensml+xml","ser":"application/java-serialized-object","setpay":"application/set-payment-initiation","setreg":"application/set-registration-initiation","sfd-hdstx":"application/vnd.hydrostatix.sof-data","sfs":"application/vnd.spotfire.sfs","sfv":"text/x-sfv","sgi":"image/sgi","sgl":"application/vnd.stardivision.writer-global","sgm":"text/sgml","sgml":"text/sgml","sh":"application/x-sh","shar":"application/x-shar","shex":"text/shex","shf":"application/shf+xml","shtml":"text/html","sid":"image/x-mrsid-image","sieve":"application/sieve","sig":"application/pgp-signature","sil":"audio/silk","silo":"model/mesh","sis":"application/vnd.symbian.install","sisx":"application/vnd.symbian.install","sit":"application/x-stuffit","sitx":"application/x-stuffitx","siv":"application/sieve","skd":"application/vnd.koan","skm":"application/vnd.koan","skp":"application/vnd.koan","skt":"application/vnd.koan","sldm":"application/vnd.ms-powerpoint.slide.macroenabled.12","sldx":"application/vnd.openxmlformats-officedocument.presentationml.slide","slim":"text/slim","slm":"text/slim","sls":"application/route-s-tsid+xml","slt":"application/vnd.epson.salt","sm":"application/vnd.stepmania.stepchart","smf":"application/vnd.stardivision.math","smi":"application/smil+xml","smil":"application/smil+xml","smv":"video/x-smv","smzip":"application/vnd.stepmania.package","snd":"audio/basic","snf":"application/x-font-snf","so":"application/octet-stream","spc":"application/x-pkcs7-certificates","spdx":"text/spdx","spf":"application/vnd.yamaha.smaf-phrase","spl":"application/x-futuresplash","spot":"text/vnd.in3d.spot","spp":"application/scvp-vp-response","spq":"application/scvp-vp-request","spx":"audio/ogg","sql":"application/x-sql","src":"application/x-wais-source","srt":"application/x-subrip","sru":"application/sru+xml","srx":"application/sparql-results+xml","ssdl":"application/ssdl+xml","sse":"application/vnd.kodak-descriptor","ssf":"application/vnd.epson.ssf","ssml":"application/ssml+xml","st":"application/vnd.sailingtracker.track","stc":"application/vnd.sun.xml.calc.template","std":"application/vnd.sun.xml.draw.template","stf":"application/vnd.wt.stf","sti":"application/vnd.sun.xml.impress.template","stk":"application/hyperstudio","stl":"model/stl","stpx":"model/step+xml","stpxz":"model/step-xml+zip","stpz":"model/step+zip","str":"application/vnd.pg.format","stw":"application/vnd.sun.xml.writer.template","styl":"text/stylus","stylus":"text/stylus","sub":"text/vnd.dvb.subtitle","sus":"application/vnd.sus-calendar","susp":"application/vnd.sus-calendar","sv4cpio":"application/x-sv4cpio","sv4crc":"application/x-sv4crc","svc":"application/vnd.dvb.service","svd":"application/vnd.svd","svg":"image/svg+xml","svgz":"image/svg+xml","swa":"application/x-director","swf":"application/x-shockwave-flash","swi":"application/vnd.aristanetworks.swi","swidtag":"application/swid+xml","sxc":"application/vnd.sun.xml.calc","sxd":"application/vnd.sun.xml.draw","sxg":"application/vnd.sun.xml.writer.global","sxi":"application/vnd.sun.xml.impress","sxm":"application/vnd.sun.xml.math","sxw":"application/vnd.sun.xml.writer","t":"text/troff","t3":"application/x-t3vm-image","t38":"image/t38","taglet":"application/vnd.mynfc","tao":"application/vnd.tao.intent-module-archive","tap":"image/vnd.tencent.tap","tar":"application/x-tar","tcap":"application/vnd.3gpp2.tcap","tcl":"application/x-tcl","td":"application/urc-targetdesc+xml","teacher":"application/vnd.smart.teacher","tei":"application/tei+xml","teicorpus":"application/tei+xml","tex":"application/x-tex","texi":"application/x-texinfo","texinfo":"application/x-texinfo","text":"text/plain","tfi":"application/thraud+xml","tfm":"application/x-tex-tfm","tfx":"image/tiff-fx","tga":"image/x-tga","thmx":"application/vnd.ms-officetheme","tif":"image/tiff","tiff":"image/tiff","tk":"application/x-tcl","tmo":"application/vnd.tmobile-livetv","toml":"application/toml","torrent":"application/x-bittorrent","tpl":"application/vnd.groove-tool-template","tpt":"application/vnd.trid.tpt","tr":"text/troff","tra":"application/vnd.trueapp","trig":"application/trig","trm":"application/x-msterminal","ts":"video/mp2t","tsd":"application/timestamped-data","tsv":"text/tab-separated-values","ttc":"font/collection","ttf":"font/ttf","ttl":"text/turtle","ttml":"application/ttml+xml","twd":"application/vnd.simtech-mindmapper","twds":"application/vnd.simtech-mindmapper","txd":"application/vnd.genomatix.tuxedo","txf":"application/vnd.mobius.txf","txt":"text/plain","u32":"application/x-authorware-bin","u8dsn":"message/global-delivery-status","u8hdr":"message/global-headers","u8mdn":"message/global-disposition-notification","u8msg":"message/global","ubj":"application/ubjson","udeb":"application/x-debian-package","ufd":"application/vnd.ufdl","ufdl":"application/vnd.ufdl","ulx":"application/x-glulx","umj":"application/vnd.umajin","unityweb":"application/vnd.unity","uoml":"application/vnd.uoml+xml","uri":"text/uri-list","uris":"text/uri-list","urls":"text/uri-list","usdz":"model/vnd.usdz+zip","ustar":"application/x-ustar","utz":"application/vnd.uiq.theme","uu":"text/x-uuencode","uva":"audio/vnd.dece.audio","uvd":"application/vnd.dece.data","uvf":"application/vnd.dece.data","uvg":"image/vnd.dece.graphic","uvh":"video/vnd.dece.hd","uvi":"image/vnd.dece.graphic","uvm":"video/vnd.dece.mobile","uvp":"video/vnd.dece.pd","uvs":"video/vnd.dece.sd","uvt":"application/vnd.dece.ttml+xml","uvu":"video/vnd.uvvu.mp4","uvv":"video/vnd.dece.video","uvva":"audio/vnd.dece.audio","uvvd":"application/vnd.dece.data","uvvf":"application/vnd.dece.data","uvvg":"image/vnd.dece.graphic","uvvh":"video/vnd.dece.hd","uvvi":"image/vnd.dece.graphic","uvvm":"video/vnd.dece.mobile","uvvp":"video/vnd.dece.pd","uvvs":"video/vnd.dece.sd","uvvt":"application/vnd.dece.ttml+xml","uvvu":"video/vnd.uvvu.mp4","uvvv":"video/vnd.dece.video","uvvx":"application/vnd.dece.unspecified","uvvz":"application/vnd.dece.zip","uvx":"application/vnd.dece.unspecified","uvz":"application/vnd.dece.zip","vbox":"application/x-virtualbox-vbox","vbox-extpack":"application/x-virtualbox-vbox-extpack","vcard":"text/vcard","vcd":"application/x-cdlink","vcf":"text/x-vcard","vcg":"application/vnd.groove-vcard","vcs":"text/x-vcalendar","vcx":"application/vnd.vcx","vdi":"application/x-virtualbox-vdi","vds":"model/vnd.sap.vds","vhd":"application/x-virtualbox-vhd","vis":"application/vnd.visionary","viv":"video/vnd.vivo","vmdk":"application/x-virtualbox-vmdk","vob":"video/x-ms-vob","vor":"application/vnd.stardivision.writer","vox":"application/x-authorware-bin","vrml":"model/vrml","vsd":"application/vnd.visio","vsf":"application/vnd.vsf","vss":"application/vnd.visio","vst":"application/vnd.visio","vsw":"application/vnd.visio","vtf":"image/vnd.valve.source.texture","vtt":"text/vtt","vtu":"model/vnd.vtu","vxml":"application/voicexml+xml","w3d":"application/x-director","wad":"application/x-doom","wadl":"application/vnd.sun.wadl+xml","war":"application/java-archive","wasm":"application/wasm","wav":"audio/x-wav","wax":"audio/x-ms-wax","wbmp":"image/vnd.wap.wbmp","wbs":"application/vnd.criticaltools.wbs+xml","wbxml":"application/vnd.wap.wbxml","wcm":"application/vnd.ms-works","wdb":"application/vnd.ms-works","wdp":"image/vnd.ms-photo","weba":"audio/webm","webapp":"application/x-web-app-manifest+json","webm":"video/webm","webmanifest":"application/manifest+json","webp":"image/webp","wg":"application/vnd.pmi.widget","wgt":"application/widget","wif":"application/watcherinfo+xml","wks":"application/vnd.ms-works","wm":"video/x-ms-wm","wma":"audio/x-ms-wma","wmd":"application/x-ms-wmd","wmf":"image/wmf","wml":"text/vnd.wap.wml","wmlc":"application/vnd.wap.wmlc","wmls":"text/vnd.wap.wmlscript","wmlsc":"application/vnd.wap.wmlscriptc","wmv":"video/x-ms-wmv","wmx":"video/x-ms-wmx","wmz":"application/x-msmetafile","woff":"font/woff","woff2":"font/woff2","wpd":"application/vnd.wordperfect","wpl":"application/vnd.ms-wpl","wps":"application/vnd.ms-works","wqd":"application/vnd.wqd","wri":"application/x-mswrite","wrl":"model/vrml","wsc":"message/vnd.wfa.wsc","wsdl":"application/wsdl+xml","wspolicy":"application/wspolicy+xml","wtb":"application/vnd.webturbo","wvx":"video/x-ms-wvx","x32":"application/x-authorware-bin","x3d":"model/x3d+xml","x3db":"model/x3d+fastinfoset","x3dbz":"model/x3d+binary","x3dv":"model/x3d-vrml","x3dvz":"model/x3d+vrml","x3dz":"model/x3d+xml","x_b":"model/vnd.parasolid.transmit.binary","x_t":"model/vnd.parasolid.transmit.text","xaml":"application/xaml+xml","xap":"application/x-silverlight-app","xar":"application/vnd.xara","xav":"application/xcap-att+xml","xbap":"application/x-ms-xbap","xbd":"application/vnd.fujixerox.docuworks.binder","xbm":"image/x-xbitmap","xca":"application/xcap-caps+xml","xcs":"application/calendar+xml","xdf":"application/xcap-diff+xml","xdm":"application/vnd.syncml.dm+xml","xdp":"application/vnd.adobe.xdp+xml","xdssc":"application/dssc+xml","xdw":"application/vnd.fujixerox.docuworks","xel":"application/xcap-el+xml","xenc":"application/xenc+xml","xer":"application/patch-ops-error+xml","xfdf":"application/vnd.adobe.xfdf","xfdl":"application/vnd.xfdl","xht":"application/xhtml+xml","xhtml":"application/xhtml+xml","xhvml":"application/xv+xml","xif":"image/vnd.xiff","xla":"application/vnd.ms-excel","xlam":"application/vnd.ms-excel.addin.macroenabled.12","xlc":"application/vnd.ms-excel","xlf":"application/xliff+xml","xlm":"application/vnd.ms-excel","xls":"application/vnd.ms-excel","xlsb":"application/vnd.ms-excel.sheet.binary.macroenabled.12","xlsm":"application/vnd.ms-excel.sheet.macroenabled.12","xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","xlt":"application/vnd.ms-excel","xltm":"application/vnd.ms-excel.template.macroenabled.12","xltx":"application/vnd.openxmlformats-officedocument.spreadsheetml.template","xlw":"application/vnd.ms-excel","xm":"audio/xm","xml":"text/xml","xns":"application/xcap-ns+xml","xo":"application/vnd.olpc-sugar","xop":"application/xop+xml","xpi":"application/x-xpinstall","xpl":"application/xproc+xml","xpm":"image/x-xpixmap","xpr":"application/vnd.is-xpr","xps":"application/vnd.ms-xpsdocument","xpw":"application/vnd.intercon.formnet","xpx":"application/vnd.intercon.formnet","xsd":"application/xml","xsl":"application/xslt+xml","xslt":"application/xslt+xml","xsm":"application/vnd.syncml+xml","xspf":"application/xspf+xml","xul":"application/vnd.mozilla.xul+xml","xvm":"application/xv+xml","xvml":"application/xv+xml","xwd":"image/x-xwindowdump","xyz":"chemical/x-xyz","xz":"application/x-xz","yaml":"text/yaml","yang":"application/yang","yin":"application/yin+xml","yml":"text/yaml","ymp":"text/x-suse-ymp","z1":"application/x-zmachine","z2":"application/x-zmachine","z3":"application/x-zmachine","z4":"application/x-zmachine","z5":"application/x-zmachine","z6":"application/x-zmachine","z7":"application/x-zmachine","z8":"application/x-zmachine","zaz":"application/vnd.zzazz.deck+xml","zip":"application/zip","zir":"application/vnd.zul","zirz":"application/vnd.zul","zmm":"application/vnd.handheld-entertainment+xml"};
  245. function responseHeaders(headers, httpCache = false) {
  246. headers = { ...DEFAULT_HEADERS, ...headers };
  247. if (httpCache) {
  248. headers['cache-control'] = 'max-age=3600';
  249. delete headers['date'];
  250. delete headers['expires'];
  251. }
  252. return headers;
  253. }
  254. const DEFAULT_HEADERS = {
  255. 'cache-control': 'no-cache, no-store, must-revalidate, max-age=0',
  256. expires: '0',
  257. date: 'Wed, 1 Jan 2000 00:00:00 GMT',
  258. server: 'Stencil Dev Server ' + version,
  259. 'access-control-allow-origin': '*',
  260. 'access-control-expose-headers': '*',
  261. };
  262. function getBrowserUrl(protocol, address, port, basePath, pathname) {
  263. address = address === `0.0.0.0` ? `localhost` : address;
  264. const portSuffix = !port || port === 80 || port === 443 ? '' : ':' + port;
  265. let path = basePath;
  266. if (pathname.startsWith('/')) {
  267. pathname = pathname.substring(1);
  268. }
  269. path += pathname;
  270. protocol = protocol.replace(/\:/g, '');
  271. return `${protocol}://${address}${portSuffix}${path}`;
  272. }
  273. function getDevServerClientUrl(devServerConfig, host, protocol) {
  274. let address = devServerConfig.address;
  275. let port = devServerConfig.port;
  276. if (host) {
  277. address = host;
  278. port = null;
  279. }
  280. return getBrowserUrl(protocol !== null && protocol !== void 0 ? protocol : devServerConfig.protocol, address, port, devServerConfig.basePath, DEV_SERVER_URL);
  281. }
  282. function getContentType(filePath) {
  283. const last = filePath.replace(/^.*[/\\]/, '').toLowerCase();
  284. const ext = last.replace(/^.*\./, '').toLowerCase();
  285. const hasPath = last.length < filePath.length;
  286. const hasDot = ext.length < last.length - 1;
  287. return ((hasDot || !hasPath) && contentTypes[ext]) || 'application/octet-stream';
  288. }
  289. function isHtmlFile(filePath) {
  290. filePath = filePath.toLowerCase().trim();
  291. return filePath.endsWith('.html') || filePath.endsWith('.htm');
  292. }
  293. function isCssFile(filePath) {
  294. filePath = filePath.toLowerCase().trim();
  295. return filePath.endsWith('.css');
  296. }
  297. const TXT_EXT = ['css', 'html', 'htm', 'js', 'json', 'svg', 'xml'];
  298. function isSimpleText(filePath) {
  299. const ext = filePath.toLowerCase().trim().split('.').pop();
  300. return TXT_EXT.includes(ext);
  301. }
  302. function isExtensionLessPath(pathname) {
  303. const parts = pathname.split('/');
  304. const lastPart = parts[parts.length - 1];
  305. return !lastPart.includes('.');
  306. }
  307. function isSsrStaticDataPath(pathname) {
  308. const parts = pathname.split('/');
  309. const fileName = parts[parts.length - 1].split('?')[0];
  310. return fileName === 'page.state.json';
  311. }
  312. function getSsrStaticDataPath(req) {
  313. const parts = req.url.href.split('/');
  314. const fileName = parts[parts.length - 1];
  315. const fileNameParts = fileName.split('?');
  316. parts.pop();
  317. let ssrPath = new URL(parts.join('/')).href;
  318. if (!ssrPath.endsWith('/') && req.headers) {
  319. const h = new Headers(req.headers);
  320. if (h.get('referer').endsWith('/')) {
  321. ssrPath += '/';
  322. }
  323. }
  324. return {
  325. ssrPath,
  326. fileName: fileNameParts[0],
  327. hasQueryString: typeof fileNameParts[1] === 'string' && fileNameParts[1].length > 0,
  328. };
  329. }
  330. function isDevClient(pathname) {
  331. return pathname.startsWith(DEV_SERVER_URL);
  332. }
  333. function isDevModule(pathname) {
  334. return pathname.includes(DEV_MODULE_URL);
  335. }
  336. function isOpenInEditor(pathname) {
  337. return pathname === OPEN_IN_EDITOR_URL;
  338. }
  339. function isInitialDevServerLoad(pathname) {
  340. return pathname === DEV_SERVER_INIT_URL;
  341. }
  342. function isDevServerClient(pathname) {
  343. return pathname === DEV_SERVER_URL;
  344. }
  345. function shouldCompress(devServerConfig, req) {
  346. if (!devServerConfig.gzip) {
  347. return false;
  348. }
  349. if (req.method !== 'GET') {
  350. return false;
  351. }
  352. const acceptEncoding = req.headers && req.headers['accept-encoding'];
  353. if (typeof acceptEncoding !== 'string') {
  354. return false;
  355. }
  356. if (!acceptEncoding.includes('gzip')) {
  357. return false;
  358. }
  359. return true;
  360. }
  361. function createCommonjsModule(fn, basedir, module) {
  362. return module = {
  363. path: basedir,
  364. exports: {},
  365. require: function (path, base) {
  366. return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
  367. }
  368. }, fn(module, module.exports), module.exports;
  369. }
  370. function commonjsRequire () {
  371. throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
  372. }
  373. let isDocker;
  374. function hasDockerEnv() {
  375. try {
  376. fs__default['default'].statSync('/.dockerenv');
  377. return true;
  378. } catch (_) {
  379. return false;
  380. }
  381. }
  382. function hasDockerCGroup() {
  383. try {
  384. return fs__default['default'].readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
  385. } catch (_) {
  386. return false;
  387. }
  388. }
  389. var isDocker_1 = () => {
  390. if (isDocker === undefined) {
  391. isDocker = hasDockerEnv() || hasDockerCGroup();
  392. }
  393. return isDocker;
  394. };
  395. var isWsl_1 = createCommonjsModule(function (module) {
  396. const isWsl = () => {
  397. if (process.platform !== 'linux') {
  398. return false;
  399. }
  400. if (os__default['default'].release().toLowerCase().includes('microsoft')) {
  401. if (isDocker_1()) {
  402. return false;
  403. }
  404. return true;
  405. }
  406. try {
  407. return fs__default['default'].readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ?
  408. !isDocker_1() : false;
  409. } catch (_) {
  410. return false;
  411. }
  412. };
  413. if (process.env.__IS_WSL_TEST__) {
  414. module.exports = isWsl;
  415. } else {
  416. module.exports = isWsl();
  417. }
  418. });
  419. var defineLazyProp = (object, propertyName, fn) => {
  420. const define = value => Object.defineProperty(object, propertyName, {value, enumerable: true, writable: true});
  421. Object.defineProperty(object, propertyName, {
  422. configurable: true,
  423. enumerable: true,
  424. get() {
  425. const result = fn();
  426. define(result);
  427. return result;
  428. },
  429. set(value) {
  430. define(value);
  431. }
  432. });
  433. return object;
  434. };
  435. const {promises: fs, constants: fsConstants} = fs__default['default'];
  436. // Path to included `xdg-open`.
  437. const localXdgOpenPath = path__default['default'].join(__dirname, 'xdg-open');
  438. const {platform, arch} = process;
  439. /**
  440. Get the mount point for fixed drives in WSL.
  441. @inner
  442. @returns {string} The mount point.
  443. */
  444. const getWslDrivesMountPoint = (() => {
  445. // Default value for "root" param
  446. // according to https://docs.microsoft.com/en-us/windows/wsl/wsl-config
  447. const defaultMountPoint = '/mnt/';
  448. let mountPoint;
  449. return async function () {
  450. if (mountPoint) {
  451. // Return memoized mount point value
  452. return mountPoint;
  453. }
  454. const configFilePath = '/etc/wsl.conf';
  455. let isConfigFileExists = false;
  456. try {
  457. await fs.access(configFilePath, fsConstants.F_OK);
  458. isConfigFileExists = true;
  459. } catch {}
  460. if (!isConfigFileExists) {
  461. return defaultMountPoint;
  462. }
  463. const configContent = await fs.readFile(configFilePath, {encoding: 'utf8'});
  464. const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
  465. if (!configMountPoint) {
  466. return defaultMountPoint;
  467. }
  468. mountPoint = configMountPoint.groups.mountPoint.trim();
  469. mountPoint = mountPoint.endsWith('/') ? mountPoint : `${mountPoint}/`;
  470. return mountPoint;
  471. };
  472. })();
  473. const pTryEach = async (array, mapper) => {
  474. let latestError;
  475. for (const item of array) {
  476. try {
  477. return await mapper(item); // eslint-disable-line no-await-in-loop
  478. } catch (error) {
  479. latestError = error;
  480. }
  481. }
  482. throw latestError;
  483. };
  484. const baseOpen = async options => {
  485. options = {
  486. wait: false,
  487. background: false,
  488. newInstance: false,
  489. allowNonzeroExitCode: false,
  490. ...options
  491. };
  492. if (Array.isArray(options.app)) {
  493. return pTryEach(options.app, singleApp => baseOpen({
  494. ...options,
  495. app: singleApp
  496. }));
  497. }
  498. let {name: app, arguments: appArguments = []} = options.app || {};
  499. appArguments = [...appArguments];
  500. if (Array.isArray(app)) {
  501. return pTryEach(app, appName => baseOpen({
  502. ...options,
  503. app: {
  504. name: appName,
  505. arguments: appArguments
  506. }
  507. }));
  508. }
  509. let command;
  510. const cliArguments = [];
  511. const childProcessOptions = {};
  512. if (platform === 'darwin') {
  513. command = 'open';
  514. if (options.wait) {
  515. cliArguments.push('--wait-apps');
  516. }
  517. if (options.background) {
  518. cliArguments.push('--background');
  519. }
  520. if (options.newInstance) {
  521. cliArguments.push('--new');
  522. }
  523. if (app) {
  524. cliArguments.push('-a', app);
  525. }
  526. } else if (platform === 'win32' || (isWsl_1 && !isDocker_1())) {
  527. const mountPoint = await getWslDrivesMountPoint();
  528. command = isWsl_1 ?
  529. `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` :
  530. `${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
  531. cliArguments.push(
  532. '-NoProfile',
  533. '-NonInteractive',
  534. '–ExecutionPolicy',
  535. 'Bypass',
  536. '-EncodedCommand'
  537. );
  538. if (!isWsl_1) {
  539. childProcessOptions.windowsVerbatimArguments = true;
  540. }
  541. const encodedArguments = ['Start'];
  542. if (options.wait) {
  543. encodedArguments.push('-Wait');
  544. }
  545. if (app) {
  546. // Double quote with double quotes to ensure the inner quotes are passed through.
  547. // Inner quotes are delimited for PowerShell interpretation with backticks.
  548. encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList');
  549. if (options.target) {
  550. appArguments.unshift(options.target);
  551. }
  552. } else if (options.target) {
  553. encodedArguments.push(`"${options.target}"`);
  554. }
  555. if (appArguments.length > 0) {
  556. appArguments = appArguments.map(arg => `"\`"${arg}\`""`);
  557. encodedArguments.push(appArguments.join(','));
  558. }
  559. // Using Base64-encoded command, accepted by PowerShell, to allow special characters.
  560. options.target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
  561. } else {
  562. if (app) {
  563. command = app;
  564. } else {
  565. // When bundled by Webpack, there's no actual package file path and no local `xdg-open`.
  566. const isBundled = !__dirname || __dirname === '/';
  567. // Check if local `xdg-open` exists and is executable.
  568. let exeLocalXdgOpen = false;
  569. try {
  570. await fs.access(localXdgOpenPath, fsConstants.X_OK);
  571. exeLocalXdgOpen = true;
  572. } catch {}
  573. const useSystemXdgOpen = process.versions.electron ||
  574. platform === 'android' || isBundled || !exeLocalXdgOpen;
  575. command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath;
  576. }
  577. if (appArguments.length > 0) {
  578. cliArguments.push(...appArguments);
  579. }
  580. if (!options.wait) {
  581. // `xdg-open` will block the process unless stdio is ignored
  582. // and it's detached from the parent even if it's unref'd.
  583. childProcessOptions.stdio = 'ignore';
  584. childProcessOptions.detached = true;
  585. }
  586. }
  587. if (options.target) {
  588. cliArguments.push(options.target);
  589. }
  590. if (platform === 'darwin' && appArguments.length > 0) {
  591. cliArguments.push('--args', ...appArguments);
  592. }
  593. const subprocess = childProcess__default['default'].spawn(command, cliArguments, childProcessOptions);
  594. if (options.wait) {
  595. return new Promise((resolve, reject) => {
  596. subprocess.once('error', reject);
  597. subprocess.once('close', exitCode => {
  598. if (options.allowNonzeroExitCode && exitCode > 0) {
  599. reject(new Error(`Exited with code ${exitCode}`));
  600. return;
  601. }
  602. resolve(subprocess);
  603. });
  604. });
  605. }
  606. subprocess.unref();
  607. return subprocess;
  608. };
  609. const open = (target, options) => {
  610. if (typeof target !== 'string') {
  611. throw new TypeError('Expected a `target`');
  612. }
  613. return baseOpen({
  614. ...options,
  615. target
  616. });
  617. };
  618. const openApp = (name, options) => {
  619. if (typeof name !== 'string') {
  620. throw new TypeError('Expected a `name`');
  621. }
  622. const {arguments: appArguments = []} = options || {};
  623. if (appArguments !== undefined && appArguments !== null && !Array.isArray(appArguments)) {
  624. throw new TypeError('Expected `appArguments` as Array type');
  625. }
  626. return baseOpen({
  627. ...options,
  628. app: {
  629. name,
  630. arguments: appArguments
  631. }
  632. });
  633. };
  634. function detectArchBinary(binary) {
  635. if (typeof binary === 'string' || Array.isArray(binary)) {
  636. return binary;
  637. }
  638. const {[arch]: archBinary} = binary;
  639. if (!archBinary) {
  640. throw new Error(`${arch} is not supported`);
  641. }
  642. return archBinary;
  643. }
  644. function detectPlatformBinary({[platform]: platformBinary}, {wsl}) {
  645. if (wsl && isWsl_1) {
  646. return detectArchBinary(wsl);
  647. }
  648. if (!platformBinary) {
  649. throw new Error(`${platform} is not supported`);
  650. }
  651. return detectArchBinary(platformBinary);
  652. }
  653. const apps = {};
  654. defineLazyProp(apps, 'chrome', () => detectPlatformBinary({
  655. darwin: 'google chrome',
  656. win32: 'chrome',
  657. linux: ['google-chrome', 'google-chrome-stable', 'chromium']
  658. }, {
  659. wsl: {
  660. ia32: '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe',
  661. x64: ['/mnt/c/Program Files/Google/Chrome/Application/chrome.exe', '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe']
  662. }
  663. }));
  664. defineLazyProp(apps, 'firefox', () => detectPlatformBinary({
  665. darwin: 'firefox',
  666. win32: 'C:\\Program Files\\Mozilla Firefox\\firefox.exe',
  667. linux: 'firefox'
  668. }, {
  669. wsl: '/mnt/c/Program Files/Mozilla Firefox/firefox.exe'
  670. }));
  671. defineLazyProp(apps, 'edge', () => detectPlatformBinary({
  672. darwin: 'microsoft edge',
  673. win32: 'msedge',
  674. linux: ['microsoft-edge', 'microsoft-edge-dev']
  675. }, {
  676. wsl: '/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe'
  677. }));
  678. open.apps = apps;
  679. open.openApp = openApp;
  680. var open_1 = open;
  681. async function openInBrowser(opts) {
  682. // await open(opts.url, { app: ['google chrome', '--auto-open-devtools-for-tabs'] });
  683. await open_1(opts.url);
  684. }
  685. function createServerContext(sys, sendMsg, devServerConfig, buildResultsResolves, compilerRequestResolves) {
  686. const logRequest = (req, status) => {
  687. if (devServerConfig) {
  688. sendMsg({
  689. requestLog: {
  690. method: req.method || '?',
  691. url: req.pathname || '?',
  692. status,
  693. },
  694. });
  695. }
  696. };
  697. const serve500 = (req, res, error, xSource) => {
  698. try {
  699. res.writeHead(500, responseHeaders({
  700. 'content-type': 'text/plain; charset=utf-8',
  701. 'x-source': xSource,
  702. }));
  703. res.write(util__default['default'].inspect(error));
  704. res.end();
  705. logRequest(req, 500);
  706. }
  707. catch (e) {
  708. sendMsg({ error: { message: 'serve500: ' + e } });
  709. }
  710. };
  711. const serve404 = (req, res, xSource, content = null) => {
  712. try {
  713. if (req.pathname === '/favicon.ico') {
  714. const defaultFavicon = path__default['default'].join(devServerConfig.devServerDir, 'static', 'favicon.ico');
  715. res.writeHead(200, responseHeaders({
  716. 'content-type': 'image/x-icon',
  717. 'x-source': `favicon: ${xSource}`,
  718. }));
  719. const rs = fs__default$1['default'].createReadStream(defaultFavicon);
  720. rs.on('error', (err) => {
  721. res.writeHead(404, responseHeaders({
  722. 'content-type': 'text/plain; charset=utf-8',
  723. 'x-source': `createReadStream error: ${err}, ${xSource}`,
  724. }));
  725. res.write(util__default['default'].inspect(err));
  726. res.end();
  727. });
  728. rs.pipe(res);
  729. return;
  730. }
  731. if (content == null) {
  732. content = ['404 File Not Found', 'Url: ' + req.pathname, 'File: ' + req.filePath].join('\n');
  733. }
  734. res.writeHead(404, responseHeaders({
  735. 'content-type': 'text/plain; charset=utf-8',
  736. 'x-source': xSource,
  737. }));
  738. res.write(content);
  739. res.end();
  740. logRequest(req, 400);
  741. }
  742. catch (e) {
  743. serve500(req, res, e, xSource);
  744. }
  745. };
  746. const serve302 = (req, res, pathname = null) => {
  747. logRequest(req, 302);
  748. res.writeHead(302, { location: pathname || devServerConfig.basePath || '/' });
  749. res.end();
  750. };
  751. const getBuildResults = () => new Promise((resolve, reject) => {
  752. if (serverCtx.isServerListening) {
  753. buildResultsResolves.push({ resolve, reject });
  754. sendMsg({ requestBuildResults: true });
  755. }
  756. else {
  757. reject('dev server closed');
  758. }
  759. });
  760. const getCompilerRequest = (compilerRequestPath) => new Promise((resolve, reject) => {
  761. if (serverCtx.isServerListening) {
  762. compilerRequestResolves.push({
  763. path: compilerRequestPath,
  764. resolve,
  765. reject,
  766. });
  767. sendMsg({ compilerRequestPath });
  768. }
  769. else {
  770. reject('dev server closed');
  771. }
  772. });
  773. const serverCtx = {
  774. connectorHtml: null,
  775. dirTemplate: null,
  776. getBuildResults,
  777. getCompilerRequest,
  778. isServerListening: false,
  779. logRequest,
  780. prerenderConfig: null,
  781. serve302,
  782. serve404,
  783. serve500,
  784. sys,
  785. };
  786. return serverCtx;
  787. }
  788. async function serveOpenInEditor(serverCtx, req, res) {
  789. let status = 200;
  790. const data = {};
  791. try {
  792. const editors = await getEditors();
  793. if (editors.length > 0) {
  794. await parseData(editors, serverCtx.sys, req, data);
  795. await openDataInEditor(data);
  796. }
  797. else {
  798. data.error = `no editors available`;
  799. }
  800. }
  801. catch (e) {
  802. data.error = e + '';
  803. status = 500;
  804. }
  805. serverCtx.logRequest(req, status);
  806. res.writeHead(status, responseHeaders({
  807. 'content-type': 'application/json; charset=utf-8',
  808. }));
  809. res.write(JSON.stringify(data, null, 2));
  810. res.end();
  811. }
  812. async function parseData(editors, sys, req, data) {
  813. const qs = req.searchParams;
  814. if (!qs.has('file')) {
  815. data.error = `missing file`;
  816. return;
  817. }
  818. data.file = qs.get('file');
  819. if (qs.has('line') && !isNaN(qs.get('line'))) {
  820. data.line = parseInt(qs.get('line'), 10);
  821. }
  822. if (typeof data.line !== 'number' || data.line < 1) {
  823. data.line = 1;
  824. }
  825. if (qs.has('column') && !isNaN(qs.get('column'))) {
  826. data.column = parseInt(qs.get('column'), 10);
  827. }
  828. if (typeof data.column !== 'number' || data.column < 1) {
  829. data.column = 1;
  830. }
  831. let editor = qs.get('editor');
  832. if (typeof editor === 'string') {
  833. editor = editor.trim().toLowerCase();
  834. if (editors.some((e) => e.id === editor)) {
  835. data.editor = editor;
  836. }
  837. else {
  838. data.error = `invalid editor: ${editor}`;
  839. return;
  840. }
  841. }
  842. else {
  843. data.editor = editors[0].id;
  844. }
  845. const stat = await sys.stat(data.file);
  846. data.exists = stat.isFile;
  847. }
  848. async function openDataInEditor(data) {
  849. if (!data.exists || data.error) {
  850. return;
  851. }
  852. try {
  853. const opts = {
  854. editor: data.editor,
  855. };
  856. const editor = openInEditorApi__default['default'].configure(opts, (err) => (data.error = err + ''));
  857. if (data.error) {
  858. return;
  859. }
  860. data.open = `${data.file}:${data.line}:${data.column}`;
  861. await editor.open(data.open);
  862. }
  863. catch (e) {
  864. data.error = e + '';
  865. }
  866. }
  867. let editors = null;
  868. function getEditors() {
  869. if (!editors) {
  870. editors = new Promise(async (resolve) => {
  871. const editors = [];
  872. try {
  873. await Promise.all(Object.keys(openInEditorApi__default['default'].editors).map(async (editorId) => {
  874. const isSupported = await isEditorSupported(editorId);
  875. editors.push({
  876. id: editorId,
  877. priority: EDITOR_PRIORITY[editorId],
  878. supported: isSupported,
  879. });
  880. }));
  881. }
  882. catch (e) { }
  883. resolve(editors
  884. .filter((e) => e.supported)
  885. .sort((a, b) => {
  886. if (a.priority < b.priority)
  887. return -1;
  888. if (a.priority > b.priority)
  889. return 1;
  890. return 0;
  891. })
  892. .map((e) => {
  893. return {
  894. id: e.id,
  895. name: EDITORS[e.id],
  896. };
  897. }));
  898. });
  899. }
  900. return editors;
  901. }
  902. async function isEditorSupported(editorId) {
  903. let isSupported = false;
  904. try {
  905. await openInEditorApi__default['default'].editors[editorId].detect();
  906. isSupported = true;
  907. }
  908. catch (e) { }
  909. return isSupported;
  910. }
  911. const EDITORS = {
  912. atom: 'Atom',
  913. code: 'Code',
  914. emacs: 'Emacs',
  915. idea14ce: 'IDEA 14 Community Edition',
  916. phpstorm: 'PhpStorm',
  917. sublime: 'Sublime',
  918. webstorm: 'WebStorm',
  919. vim: 'Vim',
  920. visualstudio: 'Visual Studio',
  921. };
  922. const EDITOR_PRIORITY = {
  923. code: 1,
  924. atom: 2,
  925. sublime: 3,
  926. visualstudio: 4,
  927. idea14ce: 5,
  928. webstorm: 6,
  929. phpstorm: 7,
  930. vim: 8,
  931. emacs: 9,
  932. };
  933. async function serveFile(devServerConfig, serverCtx, req, res) {
  934. try {
  935. if (isSimpleText(req.filePath)) {
  936. // easy text file, use the internal cache
  937. let content = await serverCtx.sys.readFile(req.filePath, 'utf8');
  938. if (devServerConfig.websocket && isHtmlFile(req.filePath) && !isDevServerClient(req.pathname)) {
  939. // auto inject our dev server script
  940. content = appendDevServerClientScript(devServerConfig, req, content);
  941. }
  942. else if (isCssFile(req.filePath)) {
  943. content = updateStyleUrls(req.url, content);
  944. }
  945. if (shouldCompress(devServerConfig, req)) {
  946. // let's gzip this well known web dev text file
  947. res.writeHead(200, responseHeaders({
  948. 'content-type': getContentType(req.filePath) + '; charset=utf-8',
  949. 'content-encoding': 'gzip',
  950. vary: 'Accept-Encoding',
  951. }));
  952. zlib__namespace.gzip(content, { level: 9 }, (_, data) => {
  953. res.end(data);
  954. });
  955. }
  956. else {
  957. // let's not gzip this file
  958. res.writeHead(200, responseHeaders({
  959. 'content-type': getContentType(req.filePath) + '; charset=utf-8',
  960. 'content-length': buffer.Buffer.byteLength(content, 'utf8'),
  961. }));
  962. res.write(content);
  963. res.end();
  964. }
  965. }
  966. else {
  967. // non-well-known text file or other file, probably best we use a stream
  968. // but don't bother trying to gzip this file for the dev server
  969. res.writeHead(200, responseHeaders({
  970. 'content-type': getContentType(req.filePath),
  971. 'content-length': req.stats.size,
  972. }));
  973. fs__default$1['default'].createReadStream(req.filePath).pipe(res);
  974. }
  975. serverCtx.logRequest(req, 200);
  976. }
  977. catch (e) {
  978. serverCtx.serve500(req, res, e, 'serveFile');
  979. }
  980. }
  981. function updateStyleUrls(url, oldCss) {
  982. const versionId = url.searchParams.get('s-hmr');
  983. const hmrUrls = url.searchParams.get('s-hmr-urls');
  984. if (versionId && hmrUrls) {
  985. hmrUrls.split(',').forEach((hmrUrl) => {
  986. urlVersionIds.set(hmrUrl, versionId);
  987. });
  988. }
  989. const reg = /url\((['"]?)(.*)\1\)/gi;
  990. let result;
  991. let newCss = oldCss;
  992. while ((result = reg.exec(oldCss)) !== null) {
  993. const oldUrl = result[2];
  994. const parsedUrl = new URL(oldUrl, url);
  995. const fileName = path__default['default'].basename(parsedUrl.pathname);
  996. const versionId = urlVersionIds.get(fileName);
  997. if (!versionId) {
  998. continue;
  999. }
  1000. parsedUrl.searchParams.set('s-hmr', versionId);
  1001. newCss = newCss.replace(oldUrl, parsedUrl.pathname);
  1002. }
  1003. return newCss;
  1004. }
  1005. const urlVersionIds = new Map();
  1006. function appendDevServerClientScript(devServerConfig, req, content) {
  1007. var _a, _b, _c;
  1008. const devServerClientUrl = getDevServerClientUrl(devServerConfig, (_b = (_a = req.headers) === null || _a === void 0 ? void 0 : _a['x-forwarded-host']) !== null && _b !== void 0 ? _b : req.host, (_c = req.headers) === null || _c === void 0 ? void 0 : _c['x-forwarded-proto']);
  1009. const iframe = `<iframe title="Stencil Dev Server Connector ${version} &#9889;" src="${devServerClientUrl}" style="display:block;width:0;height:0;border:0;visibility:hidden" aria-hidden="true"></iframe>`;
  1010. return appendDevServerClientIframe(content, iframe);
  1011. }
  1012. function appendDevServerClientIframe(content, iframe) {
  1013. if (content.includes('</body>')) {
  1014. return content.replace('</body>', `${iframe}</body>`);
  1015. }
  1016. if (content.includes('</html>')) {
  1017. return content.replace('</html>', `${iframe}</html>`);
  1018. }
  1019. return `${content}${iframe}`;
  1020. }
  1021. async function serveDevClient(devServerConfig, serverCtx, req, res) {
  1022. try {
  1023. if (isOpenInEditor(req.pathname)) {
  1024. return serveOpenInEditor(serverCtx, req, res);
  1025. }
  1026. if (isDevServerClient(req.pathname)) {
  1027. return serveDevClientScript(devServerConfig, serverCtx, req, res);
  1028. }
  1029. if (isInitialDevServerLoad(req.pathname)) {
  1030. req.filePath = path__default['default'].join(devServerConfig.devServerDir, 'templates', 'initial-load.html');
  1031. }
  1032. else {
  1033. const staticFile = req.pathname.replace(DEV_SERVER_URL + '/', '');
  1034. req.filePath = path__default['default'].join(devServerConfig.devServerDir, 'static', staticFile);
  1035. }
  1036. try {
  1037. req.stats = await serverCtx.sys.stat(req.filePath);
  1038. if (req.stats.isFile) {
  1039. return serveFile(devServerConfig, serverCtx, req, res);
  1040. }
  1041. return serverCtx.serve404(req, res, 'serveDevClient not file');
  1042. }
  1043. catch (e) {
  1044. return serverCtx.serve404(req, res, `serveDevClient stats error ${e}`);
  1045. }
  1046. }
  1047. catch (e) {
  1048. return serverCtx.serve500(req, res, e, 'serveDevClient');
  1049. }
  1050. }
  1051. async function serveDevClientScript(devServerConfig, serverCtx, req, res) {
  1052. try {
  1053. if (serverCtx.connectorHtml == null) {
  1054. const filePath = path__default['default'].join(devServerConfig.devServerDir, 'connector.html');
  1055. serverCtx.connectorHtml = serverCtx.sys.readFileSync(filePath, 'utf8');
  1056. if (typeof serverCtx.connectorHtml !== 'string') {
  1057. return serverCtx.serve404(req, res, `serveDevClientScript`);
  1058. }
  1059. const devClientConfig = {
  1060. basePath: devServerConfig.basePath,
  1061. editors: await getEditors(),
  1062. reloadStrategy: devServerConfig.reloadStrategy,
  1063. };
  1064. serverCtx.connectorHtml = serverCtx.connectorHtml.replace('window.__DEV_CLIENT_CONFIG__', JSON.stringify(devClientConfig));
  1065. }
  1066. res.writeHead(200, responseHeaders({
  1067. 'content-type': 'text/html; charset=utf-8',
  1068. }));
  1069. res.write(serverCtx.connectorHtml);
  1070. res.end();
  1071. }
  1072. catch (e) {
  1073. return serverCtx.serve500(req, res, e, `serveDevClientScript`);
  1074. }
  1075. }
  1076. async function serveDevNodeModule(serverCtx, req, res) {
  1077. try {
  1078. const results = await serverCtx.getCompilerRequest(req.pathname);
  1079. const headers = {
  1080. 'content-type': 'application/javascript; charset=utf-8',
  1081. 'content-length': Buffer.byteLength(results.content, 'utf8'),
  1082. 'x-dev-node-module-id': results.nodeModuleId,
  1083. 'x-dev-node-module-version': results.nodeModuleVersion,
  1084. 'x-dev-node-module-resolved-path': results.nodeResolvedPath,
  1085. 'x-dev-node-module-cache-path': results.cachePath,
  1086. 'x-dev-node-module-cache-hit': results.cacheHit,
  1087. };
  1088. res.writeHead(results.status, responseHeaders(headers));
  1089. res.write(results.content);
  1090. res.end();
  1091. }
  1092. catch (e) {
  1093. serverCtx.serve500(req, res, e, `serveDevNodeModule`);
  1094. }
  1095. }
  1096. async function serveDirectoryIndex(devServerConfig, serverCtx, req, res) {
  1097. const indexFilePath = path__default['default'].join(req.filePath, 'index.html');
  1098. req.stats = await serverCtx.sys.stat(indexFilePath);
  1099. if (req.stats.isFile) {
  1100. req.filePath = indexFilePath;
  1101. return serveFile(devServerConfig, serverCtx, req, res);
  1102. }
  1103. if (!req.pathname.endsWith('/')) {
  1104. return serverCtx.serve302(req, res, req.pathname + '/');
  1105. }
  1106. try {
  1107. const dirFilePaths = await serverCtx.sys.readDir(req.filePath);
  1108. try {
  1109. if (serverCtx.dirTemplate == null) {
  1110. const dirTemplatePath = path__default['default'].join(devServerConfig.devServerDir, 'templates', 'directory-index.html');
  1111. serverCtx.dirTemplate = serverCtx.sys.readFileSync(dirTemplatePath);
  1112. }
  1113. const files = await getFiles(serverCtx.sys, req.url, dirFilePaths);
  1114. const templateHtml = serverCtx.dirTemplate
  1115. .replace('{{title}}', getTitle(req.pathname))
  1116. .replace('{{nav}}', getName(req.pathname))
  1117. .replace('{{files}}', files);
  1118. serverCtx.logRequest(req, 200);
  1119. res.writeHead(200, responseHeaders({
  1120. 'content-type': 'text/html; charset=utf-8',
  1121. 'x-directory-index': req.pathname,
  1122. }));
  1123. res.write(templateHtml);
  1124. res.end();
  1125. }
  1126. catch (e) {
  1127. return serverCtx.serve500(req, res, e, 'serveDirectoryIndex');
  1128. }
  1129. }
  1130. catch (e) {
  1131. return serverCtx.serve404(req, res, 'serveDirectoryIndex');
  1132. }
  1133. }
  1134. async function getFiles(sys, baseUrl, dirItemNames) {
  1135. const items = await getDirectoryItems(sys, baseUrl, dirItemNames);
  1136. if (baseUrl.pathname !== '/') {
  1137. items.unshift({
  1138. isDirectory: true,
  1139. pathname: '../',
  1140. name: '..',
  1141. });
  1142. }
  1143. return items
  1144. .map((item) => {
  1145. return `
  1146. <li class="${item.isDirectory ? 'directory' : 'file'}">
  1147. <a href="${item.pathname}">
  1148. <span class="icon"></span>
  1149. <span>${item.name}</span>
  1150. </a>
  1151. </li>`;
  1152. })
  1153. .join('');
  1154. }
  1155. async function getDirectoryItems(sys, baseUrl, dirFilePaths) {
  1156. const items = await Promise.all(dirFilePaths.map(async (dirFilePath) => {
  1157. const fileName = path__default['default'].basename(dirFilePath);
  1158. const url = new URL(fileName, baseUrl);
  1159. const stats = await sys.stat(dirFilePath);
  1160. const item = {
  1161. name: fileName,
  1162. pathname: url.pathname,
  1163. isDirectory: stats.isDirectory,
  1164. };
  1165. return item;
  1166. }));
  1167. return items;
  1168. }
  1169. function getTitle(pathName) {
  1170. return pathName;
  1171. }
  1172. function getName(pathName) {
  1173. const dirs = pathName.split('/');
  1174. dirs.pop();
  1175. let url = '';
  1176. return (dirs
  1177. .map((dir, index) => {
  1178. url += dir + '/';
  1179. const text = index === 0 ? `~` : dir;
  1180. return `<a href="${url}">${text}</a>`;
  1181. })
  1182. .join('<span>/</span>') + '<span>/</span>');
  1183. }
  1184. async function ssrPageRequest(devServerConfig, serverCtx, req, res) {
  1185. try {
  1186. let status = 500;
  1187. let content = '';
  1188. const { hydrateApp, srcIndexHtml, diagnostics } = await setupHydrateApp(devServerConfig, serverCtx);
  1189. if (!diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
  1190. try {
  1191. const opts = getSsrHydrateOptions(devServerConfig, serverCtx, req.url);
  1192. const ssrResults = await hydrateApp.renderToString(srcIndexHtml, opts);
  1193. diagnostics.push(...ssrResults.diagnostics);
  1194. status = ssrResults.httpStatus;
  1195. content = ssrResults.html;
  1196. }
  1197. catch (e) {
  1198. catchError(diagnostics, e);
  1199. }
  1200. }
  1201. if (diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
  1202. content = getSsrErrorContent(diagnostics);
  1203. status = 500;
  1204. }
  1205. if (devServerConfig.websocket) {
  1206. content = appendDevServerClientScript(devServerConfig, req, content);
  1207. }
  1208. serverCtx.logRequest(req, status);
  1209. res.writeHead(status, responseHeaders({
  1210. 'content-type': 'text/html; charset=utf-8',
  1211. 'content-length': Buffer.byteLength(content, 'utf8'),
  1212. }));
  1213. res.write(content);
  1214. res.end();
  1215. }
  1216. catch (e) {
  1217. serverCtx.serve500(req, res, e, `ssrPageRequest`);
  1218. }
  1219. }
  1220. async function ssrStaticDataRequest(devServerConfig, serverCtx, req, res) {
  1221. try {
  1222. const data = {};
  1223. let httpCache = false;
  1224. const { hydrateApp, srcIndexHtml, diagnostics } = await setupHydrateApp(devServerConfig, serverCtx);
  1225. if (!diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
  1226. try {
  1227. const { ssrPath, hasQueryString } = getSsrStaticDataPath(req);
  1228. const url = new URL(ssrPath, req.url);
  1229. const opts = getSsrHydrateOptions(devServerConfig, serverCtx, url);
  1230. const ssrResults = await hydrateApp.renderToString(srcIndexHtml, opts);
  1231. diagnostics.push(...ssrResults.diagnostics);
  1232. ssrResults.staticData.forEach((s) => {
  1233. if (s.type === 'application/json') {
  1234. data[s.id] = JSON.parse(s.content);
  1235. }
  1236. else {
  1237. data[s.id] = s.content;
  1238. }
  1239. });
  1240. data.components = ssrResults.components.map((c) => c.tag).sort();
  1241. httpCache = hasQueryString;
  1242. }
  1243. catch (e) {
  1244. catchError(diagnostics, e);
  1245. }
  1246. }
  1247. if (diagnostics.length > 0) {
  1248. data.diagnostics = diagnostics;
  1249. }
  1250. const status = diagnostics.some((diagnostic) => diagnostic.level === 'error') ? 500 : 200;
  1251. const content = JSON.stringify(data);
  1252. serverCtx.logRequest(req, status);
  1253. res.writeHead(status, responseHeaders({
  1254. 'content-type': 'application/json; charset=utf-8',
  1255. 'content-length': Buffer.byteLength(content, 'utf8'),
  1256. }, httpCache && status === 200));
  1257. res.write(content);
  1258. res.end();
  1259. }
  1260. catch (e) {
  1261. serverCtx.serve500(req, res, e, `ssrStaticDataRequest`);
  1262. }
  1263. }
  1264. async function setupHydrateApp(devServerConfig, serverCtx) {
  1265. let srcIndexHtml = null;
  1266. let hydrateApp = null;
  1267. const buildResults = await serverCtx.getBuildResults();
  1268. const diagnostics = [];
  1269. if (serverCtx.prerenderConfig == null && isString(devServerConfig.prerenderConfig)) {
  1270. const compilerPath = path__default['default'].join(devServerConfig.devServerDir, '..', 'compiler', 'stencil.js');
  1271. const compiler = require(compilerPath);
  1272. const prerenderConfigResults = compiler.nodeRequire(devServerConfig.prerenderConfig);
  1273. diagnostics.push(...prerenderConfigResults.diagnostics);
  1274. if (prerenderConfigResults.module && prerenderConfigResults.module.config) {
  1275. serverCtx.prerenderConfig = prerenderConfigResults.module.config;
  1276. }
  1277. }
  1278. if (!isString(buildResults.hydrateAppFilePath)) {
  1279. diagnostics.push({ messageText: `Missing hydrateAppFilePath`, level: `error`, type: `ssr` });
  1280. }
  1281. else if (!isString(devServerConfig.srcIndexHtml)) {
  1282. diagnostics.push({ messageText: `Missing srcIndexHtml`, level: `error`, type: `ssr` });
  1283. }
  1284. else {
  1285. srcIndexHtml = await serverCtx.sys.readFile(devServerConfig.srcIndexHtml);
  1286. if (!isString(srcIndexHtml)) {
  1287. diagnostics.push({
  1288. messageText: `Unable to load src index html: ${devServerConfig.srcIndexHtml}`,
  1289. level: `error`,
  1290. type: `ssr`,
  1291. });
  1292. }
  1293. else {
  1294. // ensure we cleared out node's internal require() cache for this file
  1295. const hydrateAppFilePath = path__default['default'].resolve(buildResults.hydrateAppFilePath);
  1296. // brute force way of clearning node's module cache
  1297. // not using `delete require.cache[id]` since it'll cause memory leaks
  1298. require.cache = {};
  1299. const Module = require('module');
  1300. Module._cache[hydrateAppFilePath] = undefined;
  1301. hydrateApp = require(hydrateAppFilePath);
  1302. }
  1303. }
  1304. return {
  1305. hydrateApp,
  1306. srcIndexHtml,
  1307. diagnostics,
  1308. };
  1309. }
  1310. function getSsrHydrateOptions(devServerConfig, serverCtx, url) {
  1311. const opts = {
  1312. url: url.href,
  1313. addModulePreloads: false,
  1314. approximateLineWidth: 120,
  1315. inlineExternalStyleSheets: false,
  1316. minifyScriptElements: false,
  1317. minifyStyleElements: false,
  1318. removeAttributeQuotes: false,
  1319. removeBooleanAttributeQuotes: false,
  1320. removeEmptyAttributes: false,
  1321. removeHtmlComments: false,
  1322. prettyHtml: true,
  1323. };
  1324. const prerenderConfig = serverCtx === null || serverCtx === void 0 ? void 0 : serverCtx.prerenderConfig;
  1325. if (isFunction(prerenderConfig === null || prerenderConfig === void 0 ? void 0 : prerenderConfig.hydrateOptions)) {
  1326. const userOpts = prerenderConfig.hydrateOptions(url);
  1327. if (userOpts) {
  1328. Object.assign(opts, userOpts);
  1329. }
  1330. }
  1331. if (isFunction(serverCtx.sys.applyPrerenderGlobalPatch)) {
  1332. const orgBeforeHydrate = opts.beforeHydrate;
  1333. opts.beforeHydrate = (document) => {
  1334. // patch this new window with the fetch global from node-fetch
  1335. const devServerBaseUrl = new URL(devServerConfig.browserUrl);
  1336. const devServerHostUrl = devServerBaseUrl.origin;
  1337. serverCtx.sys.applyPrerenderGlobalPatch({
  1338. devServerHostUrl: devServerHostUrl,
  1339. window: document.defaultView,
  1340. });
  1341. if (typeof orgBeforeHydrate === 'function') {
  1342. return orgBeforeHydrate(document);
  1343. }
  1344. };
  1345. }
  1346. return opts;
  1347. }
  1348. function getSsrErrorContent(diagnostics) {
  1349. return `<!doctype html>
  1350. <html>
  1351. <head>
  1352. <title>SSR Error</title>
  1353. <style>
  1354. body {
  1355. font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important;
  1356. }
  1357. </style>
  1358. </head>
  1359. <body>
  1360. <h1>SSR Dev Error</h1>
  1361. ${diagnostics.map((diagnostic) => `
  1362. <p>
  1363. ${diagnostic.messageText}
  1364. </p>
  1365. `)}
  1366. </body>
  1367. </html>`;
  1368. }
  1369. function createRequestHandler(devServerConfig, serverCtx) {
  1370. let userRequestHandler = null;
  1371. if (typeof devServerConfig.requestListenerPath === 'string') {
  1372. userRequestHandler = require(devServerConfig.requestListenerPath);
  1373. }
  1374. return async function (incomingReq, res) {
  1375. async function defaultHandler() {
  1376. try {
  1377. const req = normalizeHttpRequest(devServerConfig, incomingReq);
  1378. if (!req.url) {
  1379. return serverCtx.serve302(req, res);
  1380. }
  1381. if (isDevClient(req.pathname) && devServerConfig.websocket) {
  1382. return serveDevClient(devServerConfig, serverCtx, req, res);
  1383. }
  1384. if (isDevModule(req.pathname)) {
  1385. return serveDevNodeModule(serverCtx, req, res);
  1386. }
  1387. if (!isValidUrlBasePath(devServerConfig.basePath, req.url)) {
  1388. return serverCtx.serve404(req, res, `invalid basePath`, `404 File Not Found, base path: ${devServerConfig.basePath}`);
  1389. }
  1390. if (devServerConfig.ssr) {
  1391. if (isExtensionLessPath(req.url.pathname)) {
  1392. return ssrPageRequest(devServerConfig, serverCtx, req, res);
  1393. }
  1394. if (isSsrStaticDataPath(req.url.pathname)) {
  1395. return ssrStaticDataRequest(devServerConfig, serverCtx, req, res);
  1396. }
  1397. }
  1398. req.stats = await serverCtx.sys.stat(req.filePath);
  1399. if (req.stats.isFile) {
  1400. return serveFile(devServerConfig, serverCtx, req, res);
  1401. }
  1402. if (req.stats.isDirectory) {
  1403. return serveDirectoryIndex(devServerConfig, serverCtx, req, res);
  1404. }
  1405. const xSource = ['notfound'];
  1406. const validHistoryApi = isValidHistoryApi(devServerConfig, req);
  1407. xSource.push(`validHistoryApi: ${validHistoryApi}`);
  1408. if (validHistoryApi) {
  1409. try {
  1410. const indexFilePath = path__default['default'].join(devServerConfig.root, devServerConfig.historyApiFallback.index);
  1411. xSource.push(`indexFilePath: ${indexFilePath}`);
  1412. req.stats = await serverCtx.sys.stat(indexFilePath);
  1413. if (req.stats.isFile) {
  1414. req.filePath = indexFilePath;
  1415. return serveFile(devServerConfig, serverCtx, req, res);
  1416. }
  1417. }
  1418. catch (e) {
  1419. xSource.push(`notfound error: ${e}`);
  1420. }
  1421. }
  1422. return serverCtx.serve404(req, res, xSource.join(', '));
  1423. }
  1424. catch (e) {
  1425. return serverCtx.serve500(incomingReq, res, e, `not found error`);
  1426. }
  1427. }
  1428. if (typeof userRequestHandler === 'function') {
  1429. await userRequestHandler(incomingReq, res, defaultHandler);
  1430. }
  1431. else {
  1432. await defaultHandler();
  1433. }
  1434. };
  1435. }
  1436. function isValidUrlBasePath(basePath, url) {
  1437. // normalize the paths to always end with a slash for the check
  1438. let pathname = url.pathname;
  1439. if (!pathname.endsWith('/')) {
  1440. pathname += '/';
  1441. }
  1442. if (!basePath.endsWith('/')) {
  1443. basePath += '/';
  1444. }
  1445. return pathname.startsWith(basePath);
  1446. }
  1447. function normalizeHttpRequest(devServerConfig, incomingReq) {
  1448. const req = {
  1449. method: (incomingReq.method || 'GET').toUpperCase(),
  1450. headers: incomingReq.headers,
  1451. acceptHeader: (incomingReq.headers && typeof incomingReq.headers.accept === 'string' && incomingReq.headers.accept) || '',
  1452. host: (incomingReq.headers && typeof incomingReq.headers.host === 'string' && incomingReq.headers.host) || null,
  1453. url: null,
  1454. searchParams: null,
  1455. };
  1456. const incomingUrl = (incomingReq.url || '').trim() || null;
  1457. if (incomingUrl) {
  1458. if (req.host) {
  1459. req.url = new URL(incomingReq.url, `http://${req.host}`);
  1460. }
  1461. else {
  1462. req.url = new URL(incomingReq.url, `http://dev.stenciljs.com`);
  1463. }
  1464. req.searchParams = req.url.searchParams;
  1465. }
  1466. if (req.url) {
  1467. const parts = req.url.pathname.replace(/\\/g, '/').split('/');
  1468. req.pathname = parts.map((part) => decodeURIComponent(part)).join('/');
  1469. if (req.pathname.length > 0 && !isDevClient(req.pathname)) {
  1470. req.pathname = '/' + req.pathname.substring(devServerConfig.basePath.length);
  1471. }
  1472. req.filePath = normalizePath(path__default['default'].normalize(path__default['default'].join(devServerConfig.root, path__default['default'].relative('/', req.pathname))));
  1473. }
  1474. return req;
  1475. }
  1476. function isValidHistoryApi(devServerConfig, req) {
  1477. if (!devServerConfig.historyApiFallback) {
  1478. return false;
  1479. }
  1480. if (req.method !== 'GET') {
  1481. return false;
  1482. }
  1483. if (!req.acceptHeader.includes('text/html')) {
  1484. return false;
  1485. }
  1486. if (!devServerConfig.historyApiFallback.disableDotRule && req.pathname.includes('.')) {
  1487. return false;
  1488. }
  1489. return true;
  1490. }
  1491. function createHttpServer(devServerConfig, serverCtx) {
  1492. // create our request handler
  1493. const reqHandler = createRequestHandler(devServerConfig, serverCtx);
  1494. const credentials = devServerConfig.https;
  1495. return credentials ? https__namespace.createServer(credentials, reqHandler) : http__namespace.createServer(reqHandler);
  1496. }
  1497. async function findClosestOpenPort(host, port) {
  1498. async function t(portToCheck) {
  1499. const isTaken = await isPortTaken(host, portToCheck);
  1500. if (!isTaken) {
  1501. return portToCheck;
  1502. }
  1503. return t(portToCheck + 1);
  1504. }
  1505. return t(port);
  1506. }
  1507. function isPortTaken(host, port) {
  1508. return new Promise((resolve, reject) => {
  1509. const tester = net__namespace
  1510. .createServer()
  1511. .once('error', () => {
  1512. resolve(true);
  1513. })
  1514. .once('listening', () => {
  1515. tester
  1516. .once('close', () => {
  1517. resolve(false);
  1518. })
  1519. .close();
  1520. })
  1521. .on('error', (err) => {
  1522. reject(err);
  1523. })
  1524. .listen(port, host);
  1525. });
  1526. }
  1527. function createWebSocket(httpServer, onMessageFromClient) {
  1528. const wsConfig = {
  1529. server: httpServer,
  1530. };
  1531. const wsServer = new ws__namespace.Server(wsConfig);
  1532. function heartbeat() {
  1533. this.isAlive = true;
  1534. }
  1535. wsServer.on('connection', (ws) => {
  1536. ws.on('message', (data) => {
  1537. // the server process has received a message from the browser
  1538. // pass the message received from the browser to the main cli process
  1539. try {
  1540. onMessageFromClient(JSON.parse(data.toString()));
  1541. }
  1542. catch (e) {
  1543. console.error(e);
  1544. }
  1545. });
  1546. ws.isAlive = true;
  1547. ws.on('pong', heartbeat);
  1548. // ignore invalid close frames sent by Safari 15
  1549. ws.on('error', console.error);
  1550. });
  1551. const pingInternval = setInterval(() => {
  1552. wsServer.clients.forEach((ws) => {
  1553. if (!ws.isAlive) {
  1554. return ws.close(1000);
  1555. }
  1556. ws.isAlive = false;
  1557. ws.ping(noop);
  1558. });
  1559. }, 10000);
  1560. return {
  1561. sendToBrowser: (msg) => {
  1562. if (msg && wsServer && wsServer.clients) {
  1563. const data = JSON.stringify(msg);
  1564. wsServer.clients.forEach((ws) => {
  1565. if (ws.readyState === ws.OPEN) {
  1566. ws.send(data);
  1567. }
  1568. });
  1569. }
  1570. },
  1571. close: () => {
  1572. return new Promise((resolve, reject) => {
  1573. clearInterval(pingInternval);
  1574. wsServer.clients.forEach((ws) => {
  1575. ws.close(1000);
  1576. });
  1577. wsServer.close((err) => {
  1578. if (err) {
  1579. reject(err);
  1580. }
  1581. else {
  1582. resolve();
  1583. }
  1584. });
  1585. });
  1586. },
  1587. };
  1588. }
  1589. function initServerProcess(sendMsg) {
  1590. let server = null;
  1591. let webSocket = null;
  1592. let serverCtx = null;
  1593. const buildResultsResolves = [];
  1594. const compilerRequestResolves = [];
  1595. const startServer = async (msg) => {
  1596. const devServerConfig = msg.startServer;
  1597. devServerConfig.port = await findClosestOpenPort(devServerConfig.address, devServerConfig.port);
  1598. devServerConfig.browserUrl = getBrowserUrl(devServerConfig.protocol, devServerConfig.address, devServerConfig.port, devServerConfig.basePath, '/');
  1599. devServerConfig.root = normalizePath(devServerConfig.root);
  1600. const sys = index_js.createNodeSys({ process });
  1601. serverCtx = createServerContext(sys, sendMsg, devServerConfig, buildResultsResolves, compilerRequestResolves);
  1602. server = createHttpServer(devServerConfig, serverCtx);
  1603. webSocket = devServerConfig.websocket ? createWebSocket(server, sendMsg) : null;
  1604. server.listen(devServerConfig.port, devServerConfig.address);
  1605. serverCtx.isServerListening = true;
  1606. if (devServerConfig.openBrowser) {
  1607. const initialLoadUrl = getBrowserUrl(devServerConfig.protocol, devServerConfig.address, devServerConfig.port, devServerConfig.basePath, devServerConfig.initialLoadUrl || DEV_SERVER_INIT_URL);
  1608. openInBrowser({ url: initialLoadUrl });
  1609. }
  1610. sendMsg({ serverStarted: devServerConfig });
  1611. };
  1612. const closeServer = () => {
  1613. const promises = [];
  1614. buildResultsResolves.forEach((r) => r.reject('dev server closed'));
  1615. buildResultsResolves.length = 0;
  1616. compilerRequestResolves.forEach((r) => r.reject('dev server closed'));
  1617. compilerRequestResolves.length = 0;
  1618. if (serverCtx) {
  1619. if (serverCtx.sys) {
  1620. promises.push(serverCtx.sys.destroy());
  1621. }
  1622. }
  1623. if (webSocket) {
  1624. promises.push(webSocket.close());
  1625. webSocket = null;
  1626. }
  1627. if (server) {
  1628. promises.push(new Promise((resolve) => {
  1629. server.close((err) => {
  1630. if (err) {
  1631. console.error(`close error: ${err}`);
  1632. }
  1633. resolve();
  1634. });
  1635. }));
  1636. }
  1637. Promise.all(promises).finally(() => {
  1638. sendMsg({
  1639. serverClosed: true,
  1640. });
  1641. });
  1642. };
  1643. const receiveMessageFromMain = (msg) => {
  1644. // the server process received a message from main thread
  1645. try {
  1646. if (msg) {
  1647. if (msg.startServer) {
  1648. startServer(msg);
  1649. }
  1650. else if (msg.closeServer) {
  1651. closeServer();
  1652. }
  1653. else if (msg.compilerRequestResults) {
  1654. for (let i = compilerRequestResolves.length - 1; i >= 0; i--) {
  1655. const r = compilerRequestResolves[i];
  1656. if (r.path === msg.compilerRequestResults.path) {
  1657. r.resolve(msg.compilerRequestResults);
  1658. compilerRequestResolves.splice(i, 1);
  1659. }
  1660. }
  1661. }
  1662. else if (serverCtx) {
  1663. if (msg.buildResults && !msg.isActivelyBuilding) {
  1664. buildResultsResolves.forEach((r) => r.resolve(msg.buildResults));
  1665. buildResultsResolves.length = 0;
  1666. }
  1667. if (webSocket) {
  1668. webSocket.sendToBrowser(msg);
  1669. }
  1670. }
  1671. }
  1672. }
  1673. catch (e) {
  1674. let stack = null;
  1675. if (e instanceof Error) {
  1676. stack = e.stack;
  1677. }
  1678. sendMsg({
  1679. error: { message: e + '', stack },
  1680. });
  1681. }
  1682. };
  1683. return receiveMessageFromMain;
  1684. }
  1685. exports.initServerProcess = initServerProcess;