@stencil/core 2.17.4 → 2.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.cjs +285 -220
- package/cli/index.d.ts +1 -0
- package/cli/index.js +285 -220
- package/cli/package.json +1 -1
- package/compiler/lib.dom.d.ts +620 -89
- package/compiler/lib.dom.iterable.d.ts +27 -3
- package/compiler/lib.es2015.core.d.ts +3 -3
- package/compiler/lib.es2015.iterable.d.ts +2 -1
- package/compiler/lib.es2015.reflect.d.ts +1 -1
- package/compiler/lib.es2020.bigint.d.ts +7 -5
- package/compiler/lib.es2020.d.ts +2 -0
- package/compiler/lib.es2020.date.d.ts +44 -0
- package/compiler/lib.es2020.intl.d.ts +51 -11
- package/compiler/lib.es2020.number.d.ts +30 -0
- package/compiler/lib.es2021.intl.d.ts +106 -4
- package/compiler/lib.es2022.array.d.ts +123 -0
- package/compiler/lib.es2022.d.ts +26 -0
- package/compiler/lib.es2022.error.d.ts +75 -0
- package/compiler/lib.es2022.full.d.ts +25 -0
- package/compiler/lib.es2022.intl.d.ts +111 -0
- package/compiler/lib.es2022.object.d.ts +28 -0
- package/compiler/lib.es2022.string.d.ts +27 -0
- package/compiler/lib.es5.d.ts +25 -19
- package/compiler/lib.esnext.d.ts +1 -1
- package/compiler/lib.esnext.intl.d.ts +4 -1
- package/compiler/lib.webworker.d.ts +236 -40
- package/compiler/lib.webworker.iterable.d.ts +10 -3
- package/compiler/package.json +1 -1
- package/compiler/stencil.d.ts +2 -2
- package/compiler/stencil.js +47263 -45624
- package/compiler/stencil.min.js +2 -2
- package/compiler/sys/in-memory-fs.d.ts +218 -0
- package/dependencies.json +10 -1
- package/dev-server/client/index.d.ts +2 -2
- package/dev-server/client/index.js +241 -241
- package/dev-server/client/package.json +1 -1
- package/dev-server/connector.html +3 -3
- package/dev-server/index.d.ts +1 -1
- package/dev-server/index.js +2 -2
- package/dev-server/package.json +1 -1
- package/dev-server/server-process.js +1198 -1167
- package/internal/app-data/package.json +1 -1
- package/internal/client/css-shim.js +2 -2
- package/internal/client/dom.js +1 -1
- package/internal/client/index.js +1022 -824
- package/internal/client/package.json +1 -1
- package/internal/client/patch-browser.js +1 -1
- package/internal/client/patch-esm.js +1 -1
- package/internal/client/polyfills/css-shim.js +1 -1
- package/internal/client/shadow-css.js +1 -1
- package/internal/hydrate/index.js +119 -119
- package/internal/hydrate/package.json +1 -1
- package/internal/hydrate/runner.d.ts +1 -1
- package/internal/hydrate/runner.js +100 -100
- package/internal/package.json +1 -1
- package/internal/stencil-core/index.d.ts +8 -10
- package/internal/stencil-private.d.ts +77 -138
- package/internal/stencil-public-compiler.d.ts +44 -10
- package/internal/stencil-public-runtime.d.ts +15 -4
- package/internal/testing/index.js +148 -148
- package/internal/testing/package.json +1 -1
- package/mock-doc/index.cjs +534 -518
- package/mock-doc/index.d.ts +13 -12
- package/mock-doc/index.js +534 -518
- package/mock-doc/package.json +1 -1
- package/package.json +23 -32
- package/readme.md +27 -33
- package/screenshot/index.d.ts +1 -1
- package/screenshot/index.js +13 -13
- package/screenshot/package.json +1 -1
- package/screenshot/pixel-match.js +983 -849
- package/sys/node/glob.js +1 -1
- package/sys/node/index.d.ts +2 -0
- package/sys/node/index.js +374 -373
- package/sys/node/package.json +1 -1
- package/sys/node/worker.js +1 -1
- package/testing/index.d.ts +6 -6
- package/testing/index.js +427 -441
- package/testing/jest/jest-config.d.ts +1 -1
- package/testing/matchers/index.d.ts +3 -3
- package/testing/mock-fetch.d.ts +1 -1
- package/testing/mocks.d.ts +2 -2
- package/testing/package.json +1 -1
- package/testing/puppeteer/puppeteer-element.d.ts +2 -2
- package/testing/puppeteer/puppeteer-events.d.ts +1 -1
- package/testing/testing-logger.d.ts +1 -1
- package/testing/testing-utils.d.ts +5 -4
- package/testing/testing.d.ts +1 -1
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Stencil Dev Server Process v2.
|
|
2
|
+
Stencil Dev Server Process v2.18.1 | MIT Licensed | https://stenciljs.com
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const index_js = require('../sys/node/index.js');
|
|
7
7
|
const path = require('path');
|
|
8
|
+
const childProcess = require('child_process');
|
|
9
|
+
const fs$1 = require('fs');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
const fs$2 = require('../sys/node/graceful-fs.js');
|
|
8
12
|
const util = require('util');
|
|
9
|
-
const zlib = require('zlib');
|
|
10
|
-
const buffer = require('buffer');
|
|
11
|
-
const openInEditorApi = require('./open-in-editor-api.js');
|
|
12
13
|
const http = require('http');
|
|
13
14
|
const https = require('https');
|
|
14
15
|
const net = require('net');
|
|
15
|
-
const
|
|
16
|
+
const openInEditorApi = require('./open-in-editor-api.js');
|
|
17
|
+
const buffer = require('buffer');
|
|
18
|
+
const zlib = require('zlib');
|
|
16
19
|
const ws = require('./ws.js');
|
|
17
|
-
const childProcess = require('child_process');
|
|
18
|
-
const fs$2 = require('fs');
|
|
19
|
-
const os = require('os');
|
|
20
20
|
|
|
21
21
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
22
22
|
|
|
@@ -40,248 +40,18 @@ function _interopNamespace(e) {
|
|
|
40
40
|
return Object.freeze(n);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs$1);
|
|
44
43
|
const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
44
|
+
const childProcess__default = /*#__PURE__*/_interopDefaultLegacy(childProcess);
|
|
45
|
+
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs$1);
|
|
46
|
+
const os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
47
|
+
const fs__default$1 = /*#__PURE__*/_interopDefaultLegacy(fs$2);
|
|
45
48
|
const util__default = /*#__PURE__*/_interopDefaultLegacy(util);
|
|
46
|
-
const zlib__namespace = /*#__PURE__*/_interopNamespace(zlib);
|
|
47
|
-
const openInEditorApi__default = /*#__PURE__*/_interopDefaultLegacy(openInEditorApi);
|
|
48
49
|
const http__namespace = /*#__PURE__*/_interopNamespace(http);
|
|
49
50
|
const https__namespace = /*#__PURE__*/_interopNamespace(https);
|
|
50
51
|
const net__namespace = /*#__PURE__*/_interopNamespace(net);
|
|
52
|
+
const openInEditorApi__default = /*#__PURE__*/_interopDefaultLegacy(openInEditorApi);
|
|
53
|
+
const zlib__namespace = /*#__PURE__*/_interopNamespace(zlib);
|
|
51
54
|
const ws__namespace = /*#__PURE__*/_interopNamespace(ws);
|
|
52
|
-
const childProcess__default = /*#__PURE__*/_interopDefaultLegacy(childProcess);
|
|
53
|
-
const fs__default$1 = /*#__PURE__*/_interopDefaultLegacy(fs$2);
|
|
54
|
-
const os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
55
|
-
|
|
56
|
-
const DEV_SERVER_URL = '/~dev-server';
|
|
57
|
-
const DEV_MODULE_URL = '/~dev-module';
|
|
58
|
-
const DEV_SERVER_INIT_URL = `${DEV_SERVER_URL}-init`;
|
|
59
|
-
const OPEN_IN_EDITOR_URL = `${DEV_SERVER_URL}-open-in-editor`;
|
|
60
|
-
|
|
61
|
-
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","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","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","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","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","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/vnd.apple.keynote","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","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","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/vnd.apple.numbers","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/vnd.apple.pages","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","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","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","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","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/xcap-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"};
|
|
62
|
-
|
|
63
|
-
const version = '2.17.4';
|
|
64
|
-
|
|
65
|
-
function responseHeaders(headers, httpCache = false) {
|
|
66
|
-
headers = { ...DEFAULT_HEADERS, ...headers };
|
|
67
|
-
if (httpCache) {
|
|
68
|
-
headers['cache-control'] = 'max-age=3600';
|
|
69
|
-
delete headers['date'];
|
|
70
|
-
delete headers['expires'];
|
|
71
|
-
}
|
|
72
|
-
return headers;
|
|
73
|
-
}
|
|
74
|
-
const DEFAULT_HEADERS = {
|
|
75
|
-
'cache-control': 'no-cache, no-store, must-revalidate, max-age=0',
|
|
76
|
-
expires: '0',
|
|
77
|
-
date: 'Wed, 1 Jan 2000 00:00:00 GMT',
|
|
78
|
-
server: 'Stencil Dev Server ' + version,
|
|
79
|
-
'access-control-allow-origin': '*',
|
|
80
|
-
'access-control-expose-headers': '*',
|
|
81
|
-
};
|
|
82
|
-
function getBrowserUrl(protocol, address, port, basePath, pathname) {
|
|
83
|
-
address = address === `0.0.0.0` ? `localhost` : address;
|
|
84
|
-
const portSuffix = !port || port === 80 || port === 443 ? '' : ':' + port;
|
|
85
|
-
let path = basePath;
|
|
86
|
-
if (pathname.startsWith('/')) {
|
|
87
|
-
pathname = pathname.substring(1);
|
|
88
|
-
}
|
|
89
|
-
path += pathname;
|
|
90
|
-
protocol = protocol.replace(/\:/g, '');
|
|
91
|
-
return `${protocol}://${address}${portSuffix}${path}`;
|
|
92
|
-
}
|
|
93
|
-
function getDevServerClientUrl(devServerConfig, host, protocol) {
|
|
94
|
-
let address = devServerConfig.address;
|
|
95
|
-
let port = devServerConfig.port;
|
|
96
|
-
if (host) {
|
|
97
|
-
address = host;
|
|
98
|
-
port = null;
|
|
99
|
-
}
|
|
100
|
-
return getBrowserUrl(protocol !== null && protocol !== void 0 ? protocol : devServerConfig.protocol, address, port, devServerConfig.basePath, DEV_SERVER_URL);
|
|
101
|
-
}
|
|
102
|
-
function getContentType(filePath) {
|
|
103
|
-
const last = filePath.replace(/^.*[/\\]/, '').toLowerCase();
|
|
104
|
-
const ext = last.replace(/^.*\./, '').toLowerCase();
|
|
105
|
-
const hasPath = last.length < filePath.length;
|
|
106
|
-
const hasDot = ext.length < last.length - 1;
|
|
107
|
-
return ((hasDot || !hasPath) && contentTypes[ext]) || 'application/octet-stream';
|
|
108
|
-
}
|
|
109
|
-
function isHtmlFile(filePath) {
|
|
110
|
-
filePath = filePath.toLowerCase().trim();
|
|
111
|
-
return filePath.endsWith('.html') || filePath.endsWith('.htm');
|
|
112
|
-
}
|
|
113
|
-
function isCssFile(filePath) {
|
|
114
|
-
filePath = filePath.toLowerCase().trim();
|
|
115
|
-
return filePath.endsWith('.css');
|
|
116
|
-
}
|
|
117
|
-
const TXT_EXT = ['css', 'html', 'htm', 'js', 'json', 'svg', 'xml'];
|
|
118
|
-
function isSimpleText(filePath) {
|
|
119
|
-
const ext = filePath.toLowerCase().trim().split('.').pop();
|
|
120
|
-
return TXT_EXT.includes(ext);
|
|
121
|
-
}
|
|
122
|
-
function isExtensionLessPath(pathname) {
|
|
123
|
-
const parts = pathname.split('/');
|
|
124
|
-
const lastPart = parts[parts.length - 1];
|
|
125
|
-
return !lastPart.includes('.');
|
|
126
|
-
}
|
|
127
|
-
function isSsrStaticDataPath(pathname) {
|
|
128
|
-
const parts = pathname.split('/');
|
|
129
|
-
const fileName = parts[parts.length - 1].split('?')[0];
|
|
130
|
-
return fileName === 'page.state.json';
|
|
131
|
-
}
|
|
132
|
-
function getSsrStaticDataPath(req) {
|
|
133
|
-
const parts = req.url.href.split('/');
|
|
134
|
-
const fileName = parts[parts.length - 1];
|
|
135
|
-
const fileNameParts = fileName.split('?');
|
|
136
|
-
parts.pop();
|
|
137
|
-
let ssrPath = new URL(parts.join('/')).href;
|
|
138
|
-
if (!ssrPath.endsWith('/') && req.headers) {
|
|
139
|
-
const h = new Headers(req.headers);
|
|
140
|
-
if (h.get('referer').endsWith('/')) {
|
|
141
|
-
ssrPath += '/';
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return {
|
|
145
|
-
ssrPath,
|
|
146
|
-
fileName: fileNameParts[0],
|
|
147
|
-
hasQueryString: typeof fileNameParts[1] === 'string' && fileNameParts[1].length > 0,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
function isDevClient(pathname) {
|
|
151
|
-
return pathname.startsWith(DEV_SERVER_URL);
|
|
152
|
-
}
|
|
153
|
-
function isDevModule(pathname) {
|
|
154
|
-
return pathname.includes(DEV_MODULE_URL);
|
|
155
|
-
}
|
|
156
|
-
function isOpenInEditor(pathname) {
|
|
157
|
-
return pathname === OPEN_IN_EDITOR_URL;
|
|
158
|
-
}
|
|
159
|
-
function isInitialDevServerLoad(pathname) {
|
|
160
|
-
return pathname === DEV_SERVER_INIT_URL;
|
|
161
|
-
}
|
|
162
|
-
function isDevServerClient(pathname) {
|
|
163
|
-
return pathname === DEV_SERVER_URL;
|
|
164
|
-
}
|
|
165
|
-
function shouldCompress(devServerConfig, req) {
|
|
166
|
-
if (!devServerConfig.gzip) {
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
if (req.method !== 'GET') {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
const acceptEncoding = req.headers && req.headers['accept-encoding'];
|
|
173
|
-
if (typeof acceptEncoding !== 'string') {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
if (!acceptEncoding.includes('gzip')) {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function createServerContext(sys, sendMsg, devServerConfig, buildResultsResolves, compilerRequestResolves) {
|
|
183
|
-
const logRequest = (req, status) => {
|
|
184
|
-
if (devServerConfig) {
|
|
185
|
-
sendMsg({
|
|
186
|
-
requestLog: {
|
|
187
|
-
method: req.method || '?',
|
|
188
|
-
url: req.pathname || '?',
|
|
189
|
-
status,
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
const serve500 = (req, res, error, xSource) => {
|
|
195
|
-
try {
|
|
196
|
-
res.writeHead(500, responseHeaders({
|
|
197
|
-
'content-type': 'text/plain; charset=utf-8',
|
|
198
|
-
'x-source': xSource,
|
|
199
|
-
}));
|
|
200
|
-
res.write(util__default['default'].inspect(error));
|
|
201
|
-
res.end();
|
|
202
|
-
logRequest(req, 500);
|
|
203
|
-
}
|
|
204
|
-
catch (e) {
|
|
205
|
-
sendMsg({ error: { message: 'serve500: ' + e } });
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
const serve404 = (req, res, xSource, content = null) => {
|
|
209
|
-
try {
|
|
210
|
-
if (req.pathname === '/favicon.ico') {
|
|
211
|
-
const defaultFavicon = path__default['default'].join(devServerConfig.devServerDir, 'static', 'favicon.ico');
|
|
212
|
-
res.writeHead(200, responseHeaders({
|
|
213
|
-
'content-type': 'image/x-icon',
|
|
214
|
-
'x-source': `favicon: ${xSource}`,
|
|
215
|
-
}));
|
|
216
|
-
const rs = fs__default['default'].createReadStream(defaultFavicon);
|
|
217
|
-
rs.on('error', (err) => {
|
|
218
|
-
res.writeHead(404, responseHeaders({
|
|
219
|
-
'content-type': 'text/plain; charset=utf-8',
|
|
220
|
-
'x-source': `createReadStream error: ${err}, ${xSource}`,
|
|
221
|
-
}));
|
|
222
|
-
res.write(util__default['default'].inspect(err));
|
|
223
|
-
res.end();
|
|
224
|
-
});
|
|
225
|
-
rs.pipe(res);
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
if (content == null) {
|
|
229
|
-
content = ['404 File Not Found', 'Url: ' + req.pathname, 'File: ' + req.filePath].join('\n');
|
|
230
|
-
}
|
|
231
|
-
res.writeHead(404, responseHeaders({
|
|
232
|
-
'content-type': 'text/plain; charset=utf-8',
|
|
233
|
-
'x-source': xSource,
|
|
234
|
-
}));
|
|
235
|
-
res.write(content);
|
|
236
|
-
res.end();
|
|
237
|
-
logRequest(req, 400);
|
|
238
|
-
}
|
|
239
|
-
catch (e) {
|
|
240
|
-
serve500(req, res, e, xSource);
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
const serve302 = (req, res, pathname = null) => {
|
|
244
|
-
logRequest(req, 302);
|
|
245
|
-
res.writeHead(302, { location: pathname || devServerConfig.basePath || '/' });
|
|
246
|
-
res.end();
|
|
247
|
-
};
|
|
248
|
-
const getBuildResults = () => new Promise((resolve, reject) => {
|
|
249
|
-
if (serverCtx.isServerListening) {
|
|
250
|
-
buildResultsResolves.push({ resolve, reject });
|
|
251
|
-
sendMsg({ requestBuildResults: true });
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
reject('dev server closed');
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
const getCompilerRequest = (compilerRequestPath) => new Promise((resolve, reject) => {
|
|
258
|
-
if (serverCtx.isServerListening) {
|
|
259
|
-
compilerRequestResolves.push({
|
|
260
|
-
path: compilerRequestPath,
|
|
261
|
-
resolve,
|
|
262
|
-
reject,
|
|
263
|
-
});
|
|
264
|
-
sendMsg({ compilerRequestPath });
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
reject('dev server closed');
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
const serverCtx = {
|
|
271
|
-
connectorHtml: null,
|
|
272
|
-
dirTemplate: null,
|
|
273
|
-
getBuildResults,
|
|
274
|
-
getCompilerRequest,
|
|
275
|
-
isServerListening: false,
|
|
276
|
-
logRequest,
|
|
277
|
-
prerenderConfig: null,
|
|
278
|
-
serve302,
|
|
279
|
-
serve404,
|
|
280
|
-
serve500,
|
|
281
|
-
sys,
|
|
282
|
-
};
|
|
283
|
-
return serverCtx;
|
|
284
|
-
}
|
|
285
55
|
|
|
286
56
|
const noop = () => {
|
|
287
57
|
/* noop*/
|
|
@@ -400,18 +170,18 @@ const getEncodedRootLength = (path) => {
|
|
|
400
170
|
return 0;
|
|
401
171
|
const ch0 = path.charCodeAt(0);
|
|
402
172
|
// POSIX or UNC
|
|
403
|
-
if (ch0 === 47 /* slash */ || ch0 === 92 /* backslash */) {
|
|
173
|
+
if (ch0 === 47 /* CharacterCodes.slash */ || ch0 === 92 /* CharacterCodes.backslash */) {
|
|
404
174
|
if (path.charCodeAt(1) !== ch0)
|
|
405
175
|
return 1; // POSIX: "/" (or non-normalized "\")
|
|
406
|
-
const p1 = path.indexOf(ch0 === 47 /* slash */ ? '/' : altDirectorySeparator, 2);
|
|
176
|
+
const p1 = path.indexOf(ch0 === 47 /* CharacterCodes.slash */ ? '/' : altDirectorySeparator, 2);
|
|
407
177
|
if (p1 < 0)
|
|
408
178
|
return path.length; // UNC: "//server" or "\\server"
|
|
409
179
|
return p1 + 1; // UNC: "//server/" or "\\server\"
|
|
410
180
|
}
|
|
411
181
|
// DOS
|
|
412
|
-
if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* colon */) {
|
|
182
|
+
if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* CharacterCodes.colon */) {
|
|
413
183
|
const ch2 = path.charCodeAt(2);
|
|
414
|
-
if (ch2 === 47 /* slash */ || ch2 === 92 /* backslash */)
|
|
184
|
+
if (ch2 === 47 /* CharacterCodes.slash */ || ch2 === 92 /* CharacterCodes.backslash */)
|
|
415
185
|
return 3; // DOS: "c:/" or "c:\"
|
|
416
186
|
if (path.length === 2)
|
|
417
187
|
return 2; // DOS: "c:" (but not "c:d")
|
|
@@ -433,7 +203,7 @@ const getEncodedRootLength = (path) => {
|
|
|
433
203
|
isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
|
|
434
204
|
const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
|
|
435
205
|
if (volumeSeparatorEnd !== -1) {
|
|
436
|
-
if (path.charCodeAt(volumeSeparatorEnd) === 47 /* slash */) {
|
|
206
|
+
if (path.charCodeAt(volumeSeparatorEnd) === 47 /* CharacterCodes.slash */) {
|
|
437
207
|
// URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/"
|
|
438
208
|
return ~(volumeSeparatorEnd + 1);
|
|
439
209
|
}
|
|
@@ -451,15 +221,15 @@ const getEncodedRootLength = (path) => {
|
|
|
451
221
|
// relative
|
|
452
222
|
return 0;
|
|
453
223
|
};
|
|
454
|
-
const isVolumeCharacter = (charCode) => (charCode >= 97 /* a */ && charCode <= 122 /* z */) ||
|
|
455
|
-
(charCode >= 65 /* A */ && charCode <= 90 /* Z */);
|
|
224
|
+
const isVolumeCharacter = (charCode) => (charCode >= 97 /* CharacterCodes.a */ && charCode <= 122 /* CharacterCodes.z */) ||
|
|
225
|
+
(charCode >= 65 /* CharacterCodes.A */ && charCode <= 90 /* CharacterCodes.Z */);
|
|
456
226
|
const getFileUrlVolumeSeparatorEnd = (url, start) => {
|
|
457
227
|
const ch0 = url.charCodeAt(start);
|
|
458
|
-
if (ch0 === 58 /* colon */)
|
|
228
|
+
if (ch0 === 58 /* CharacterCodes.colon */)
|
|
459
229
|
return start + 1;
|
|
460
|
-
if (ch0 === 37 /* percent */ && url.charCodeAt(start + 1) === 51 /* _3 */) {
|
|
230
|
+
if (ch0 === 37 /* CharacterCodes.percent */ && url.charCodeAt(start + 1) === 51 /* CharacterCodes._3 */) {
|
|
461
231
|
const ch2 = url.charCodeAt(start + 2);
|
|
462
|
-
if (ch2 === 97 /* a */ || ch2 === 65 /* A */)
|
|
232
|
+
if (ch2 === 97 /* CharacterCodes.a */ || ch2 === 65 /* CharacterCodes.A */)
|
|
463
233
|
return start + 3;
|
|
464
234
|
}
|
|
465
235
|
return -1;
|
|
@@ -474,847 +244,163 @@ const pathComponents = (path, rootLength) => {
|
|
|
474
244
|
return [root, ...rest];
|
|
475
245
|
};
|
|
476
246
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
content = appendDevServerClientScript(devServerConfig, req, content);
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
'content-type': getContentType(req.filePath) + '; charset=utf-8',
|
|
493
|
-
'content-encoding': 'gzip',
|
|
494
|
-
vary: 'Accept-Encoding',
|
|
495
|
-
}));
|
|
496
|
-
zlib__namespace.gzip(content, { level: 9 }, (_, data) => {
|
|
497
|
-
res.end(data);
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
else {
|
|
501
|
-
// let's not gzip this file
|
|
502
|
-
res.writeHead(200, responseHeaders({
|
|
503
|
-
'content-type': getContentType(req.filePath) + '; charset=utf-8',
|
|
504
|
-
'content-length': buffer.Buffer.byteLength(content, 'utf8'),
|
|
505
|
-
}));
|
|
506
|
-
res.write(content);
|
|
507
|
-
res.end();
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
else {
|
|
511
|
-
// non-well-known text file or other file, probably best we use a stream
|
|
512
|
-
// but don't bother trying to gzip this file for the dev server
|
|
513
|
-
res.writeHead(200, responseHeaders({
|
|
514
|
-
'content-type': getContentType(req.filePath),
|
|
515
|
-
'content-length': req.stats.size,
|
|
516
|
-
}));
|
|
517
|
-
fs__default['default'].createReadStream(req.filePath).pipe(res);
|
|
518
|
-
}
|
|
519
|
-
serverCtx.logRequest(req, 200);
|
|
520
|
-
}
|
|
521
|
-
catch (e) {
|
|
522
|
-
serverCtx.serve500(req, res, e, 'serveFile');
|
|
247
|
+
const DEV_SERVER_URL = '/~dev-server';
|
|
248
|
+
const DEV_MODULE_URL = '/~dev-module';
|
|
249
|
+
const DEV_SERVER_INIT_URL = `${DEV_SERVER_URL}-init`;
|
|
250
|
+
const OPEN_IN_EDITOR_URL = `${DEV_SERVER_URL}-open-in-editor`;
|
|
251
|
+
|
|
252
|
+
const version = '2.18.1';
|
|
253
|
+
|
|
254
|
+
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"};
|
|
255
|
+
|
|
256
|
+
function responseHeaders(headers, httpCache = false) {
|
|
257
|
+
headers = { ...DEFAULT_HEADERS, ...headers };
|
|
258
|
+
if (httpCache) {
|
|
259
|
+
headers['cache-control'] = 'max-age=3600';
|
|
260
|
+
delete headers['date'];
|
|
261
|
+
delete headers['expires'];
|
|
523
262
|
}
|
|
263
|
+
return headers;
|
|
524
264
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
265
|
+
const DEFAULT_HEADERS = {
|
|
266
|
+
'cache-control': 'no-cache, no-store, must-revalidate, max-age=0',
|
|
267
|
+
expires: '0',
|
|
268
|
+
date: 'Wed, 1 Jan 2000 00:00:00 GMT',
|
|
269
|
+
server: 'Stencil Dev Server ' + version,
|
|
270
|
+
'access-control-allow-origin': '*',
|
|
271
|
+
'access-control-expose-headers': '*',
|
|
272
|
+
};
|
|
273
|
+
function getBrowserUrl(protocol, address, port, basePath, pathname) {
|
|
274
|
+
address = address === `0.0.0.0` ? `localhost` : address;
|
|
275
|
+
const portSuffix = !port || port === 80 || port === 443 ? '' : ':' + port;
|
|
276
|
+
let path = basePath;
|
|
277
|
+
if (pathname.startsWith('/')) {
|
|
278
|
+
pathname = pathname.substring(1);
|
|
532
279
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
544
|
-
parsedUrl.searchParams.set('s-hmr', versionId);
|
|
545
|
-
newCss = newCss.replace(oldUrl, parsedUrl.pathname);
|
|
280
|
+
path += pathname;
|
|
281
|
+
protocol = protocol.replace(/\:/g, '');
|
|
282
|
+
return `${protocol}://${address}${portSuffix}${path}`;
|
|
283
|
+
}
|
|
284
|
+
function getDevServerClientUrl(devServerConfig, host, protocol) {
|
|
285
|
+
let address = devServerConfig.address;
|
|
286
|
+
let port = devServerConfig.port;
|
|
287
|
+
if (host) {
|
|
288
|
+
address = host;
|
|
289
|
+
port = null;
|
|
546
290
|
}
|
|
547
|
-
return
|
|
291
|
+
return getBrowserUrl(protocol !== null && protocol !== void 0 ? protocol : devServerConfig.protocol, address, port, devServerConfig.basePath, DEV_SERVER_URL);
|
|
548
292
|
}
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const
|
|
553
|
-
const
|
|
554
|
-
return
|
|
293
|
+
function getContentType(filePath) {
|
|
294
|
+
const last = filePath.replace(/^.*[/\\]/, '').toLowerCase();
|
|
295
|
+
const ext = last.replace(/^.*\./, '').toLowerCase();
|
|
296
|
+
const hasPath = last.length < filePath.length;
|
|
297
|
+
const hasDot = ext.length < last.length - 1;
|
|
298
|
+
return ((hasDot || !hasPath) && contentTypes[ext]) || 'application/octet-stream';
|
|
555
299
|
}
|
|
556
|
-
function
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
}
|
|
560
|
-
if (content.includes('</html>')) {
|
|
561
|
-
return content.replace('</html>', `${iframe}</html>`);
|
|
562
|
-
}
|
|
563
|
-
return `${content}${iframe}`;
|
|
300
|
+
function isHtmlFile(filePath) {
|
|
301
|
+
filePath = filePath.toLowerCase().trim();
|
|
302
|
+
return filePath.endsWith('.html') || filePath.endsWith('.htm');
|
|
564
303
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
const data = {};
|
|
569
|
-
try {
|
|
570
|
-
const editors = await getEditors();
|
|
571
|
-
if (editors.length > 0) {
|
|
572
|
-
await parseData(editors, serverCtx.sys, req, data);
|
|
573
|
-
await openDataInEditor(data);
|
|
574
|
-
}
|
|
575
|
-
else {
|
|
576
|
-
data.error = `no editors available`;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
catch (e) {
|
|
580
|
-
data.error = e + '';
|
|
581
|
-
status = 500;
|
|
582
|
-
}
|
|
583
|
-
serverCtx.logRequest(req, status);
|
|
584
|
-
res.writeHead(status, responseHeaders({
|
|
585
|
-
'content-type': 'application/json; charset=utf-8',
|
|
586
|
-
}));
|
|
587
|
-
res.write(JSON.stringify(data, null, 2));
|
|
588
|
-
res.end();
|
|
304
|
+
function isCssFile(filePath) {
|
|
305
|
+
filePath = filePath.toLowerCase().trim();
|
|
306
|
+
return filePath.endsWith('.css');
|
|
589
307
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
else {
|
|
616
|
-
data.error = `invalid editor: ${editor}`;
|
|
617
|
-
return;
|
|
308
|
+
const TXT_EXT = ['css', 'html', 'htm', 'js', 'json', 'svg', 'xml'];
|
|
309
|
+
function isSimpleText(filePath) {
|
|
310
|
+
const ext = filePath.toLowerCase().trim().split('.').pop();
|
|
311
|
+
return TXT_EXT.includes(ext);
|
|
312
|
+
}
|
|
313
|
+
function isExtensionLessPath(pathname) {
|
|
314
|
+
const parts = pathname.split('/');
|
|
315
|
+
const lastPart = parts[parts.length - 1];
|
|
316
|
+
return !lastPart.includes('.');
|
|
317
|
+
}
|
|
318
|
+
function isSsrStaticDataPath(pathname) {
|
|
319
|
+
const parts = pathname.split('/');
|
|
320
|
+
const fileName = parts[parts.length - 1].split('?')[0];
|
|
321
|
+
return fileName === 'page.state.json';
|
|
322
|
+
}
|
|
323
|
+
function getSsrStaticDataPath(req) {
|
|
324
|
+
const parts = req.url.href.split('/');
|
|
325
|
+
const fileName = parts[parts.length - 1];
|
|
326
|
+
const fileNameParts = fileName.split('?');
|
|
327
|
+
parts.pop();
|
|
328
|
+
let ssrPath = new URL(parts.join('/')).href;
|
|
329
|
+
if (!ssrPath.endsWith('/') && req.headers) {
|
|
330
|
+
const h = new Headers(req.headers);
|
|
331
|
+
if (h.get('referer').endsWith('/')) {
|
|
332
|
+
ssrPath += '/';
|
|
618
333
|
}
|
|
619
334
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
335
|
+
return {
|
|
336
|
+
ssrPath,
|
|
337
|
+
fileName: fileNameParts[0],
|
|
338
|
+
hasQueryString: typeof fileNameParts[1] === 'string' && fileNameParts[1].length > 0,
|
|
339
|
+
};
|
|
625
340
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
341
|
+
function isDevClient(pathname) {
|
|
342
|
+
return pathname.startsWith(DEV_SERVER_URL);
|
|
343
|
+
}
|
|
344
|
+
function isDevModule(pathname) {
|
|
345
|
+
return pathname.includes(DEV_MODULE_URL);
|
|
346
|
+
}
|
|
347
|
+
function isOpenInEditor(pathname) {
|
|
348
|
+
return pathname === OPEN_IN_EDITOR_URL;
|
|
349
|
+
}
|
|
350
|
+
function isInitialDevServerLoad(pathname) {
|
|
351
|
+
return pathname === DEV_SERVER_INIT_URL;
|
|
352
|
+
}
|
|
353
|
+
function isDevServerClient(pathname) {
|
|
354
|
+
return pathname === DEV_SERVER_URL;
|
|
355
|
+
}
|
|
356
|
+
function shouldCompress(devServerConfig, req) {
|
|
357
|
+
if (!devServerConfig.gzip) {
|
|
358
|
+
return false;
|
|
629
359
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
editor: data.editor,
|
|
633
|
-
};
|
|
634
|
-
const editor = openInEditorApi__default['default'].configure(opts, (err) => (data.error = err + ''));
|
|
635
|
-
if (data.error) {
|
|
636
|
-
return;
|
|
637
|
-
}
|
|
638
|
-
data.open = `${data.file}:${data.line}:${data.column}`;
|
|
639
|
-
await editor.open(data.open);
|
|
360
|
+
if (req.method !== 'GET') {
|
|
361
|
+
return false;
|
|
640
362
|
}
|
|
641
|
-
|
|
642
|
-
|
|
363
|
+
const acceptEncoding = req.headers && req.headers['accept-encoding'];
|
|
364
|
+
if (typeof acceptEncoding !== 'string') {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
if (!acceptEncoding.includes('gzip')) {
|
|
368
|
+
return false;
|
|
643
369
|
}
|
|
370
|
+
return true;
|
|
644
371
|
}
|
|
645
|
-
let editors = null;
|
|
646
|
-
function getEditors() {
|
|
647
|
-
if (!editors) {
|
|
648
|
-
editors = new Promise(async (resolve) => {
|
|
649
|
-
const editors = [];
|
|
650
|
-
try {
|
|
651
|
-
await Promise.all(Object.keys(openInEditorApi__default['default'].editors).map(async (editorId) => {
|
|
652
|
-
const isSupported = await isEditorSupported(editorId);
|
|
653
|
-
editors.push({
|
|
654
|
-
id: editorId,
|
|
655
|
-
priority: EDITOR_PRIORITY[editorId],
|
|
656
|
-
supported: isSupported,
|
|
657
|
-
});
|
|
658
|
-
}));
|
|
659
|
-
}
|
|
660
|
-
catch (e) { }
|
|
661
|
-
resolve(editors
|
|
662
|
-
.filter((e) => e.supported)
|
|
663
|
-
.sort((a, b) => {
|
|
664
|
-
if (a.priority < b.priority)
|
|
665
|
-
return -1;
|
|
666
|
-
if (a.priority > b.priority)
|
|
667
|
-
return 1;
|
|
668
|
-
return 0;
|
|
669
|
-
})
|
|
670
|
-
.map((e) => {
|
|
671
|
-
return {
|
|
672
|
-
id: e.id,
|
|
673
|
-
name: EDITORS[e.id],
|
|
674
|
-
};
|
|
675
|
-
}));
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
return editors;
|
|
679
|
-
}
|
|
680
|
-
async function isEditorSupported(editorId) {
|
|
681
|
-
let isSupported = false;
|
|
682
|
-
try {
|
|
683
|
-
await openInEditorApi__default['default'].editors[editorId].detect();
|
|
684
|
-
isSupported = true;
|
|
685
|
-
}
|
|
686
|
-
catch (e) { }
|
|
687
|
-
return isSupported;
|
|
688
|
-
}
|
|
689
|
-
const EDITORS = {
|
|
690
|
-
atom: 'Atom',
|
|
691
|
-
code: 'Code',
|
|
692
|
-
emacs: 'Emacs',
|
|
693
|
-
idea14ce: 'IDEA 14 Community Edition',
|
|
694
|
-
phpstorm: 'PhpStorm',
|
|
695
|
-
sublime: 'Sublime',
|
|
696
|
-
webstorm: 'WebStorm',
|
|
697
|
-
vim: 'Vim',
|
|
698
|
-
visualstudio: 'Visual Studio',
|
|
699
|
-
};
|
|
700
|
-
const EDITOR_PRIORITY = {
|
|
701
|
-
code: 1,
|
|
702
|
-
atom: 2,
|
|
703
|
-
sublime: 3,
|
|
704
|
-
visualstudio: 4,
|
|
705
|
-
idea14ce: 5,
|
|
706
|
-
webstorm: 6,
|
|
707
|
-
phpstorm: 7,
|
|
708
|
-
vim: 8,
|
|
709
|
-
emacs: 9,
|
|
710
|
-
};
|
|
711
372
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
if (isInitialDevServerLoad(req.pathname)) {
|
|
721
|
-
req.filePath = path__default['default'].join(devServerConfig.devServerDir, 'templates', 'initial-load.html');
|
|
722
|
-
}
|
|
723
|
-
else {
|
|
724
|
-
const staticFile = req.pathname.replace(DEV_SERVER_URL + '/', '');
|
|
725
|
-
req.filePath = path__default['default'].join(devServerConfig.devServerDir, 'static', staticFile);
|
|
726
|
-
}
|
|
727
|
-
try {
|
|
728
|
-
req.stats = await serverCtx.sys.stat(req.filePath);
|
|
729
|
-
if (req.stats.isFile) {
|
|
730
|
-
return serveFile(devServerConfig, serverCtx, req, res);
|
|
731
|
-
}
|
|
732
|
-
return serverCtx.serve404(req, res, 'serveDevClient not file');
|
|
733
|
-
}
|
|
734
|
-
catch (e) {
|
|
735
|
-
return serverCtx.serve404(req, res, `serveDevClient stats error ${e}`);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
catch (e) {
|
|
739
|
-
return serverCtx.serve500(req, res, e, 'serveDevClient');
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
async function serveDevClientScript(devServerConfig, serverCtx, req, res) {
|
|
743
|
-
try {
|
|
744
|
-
if (serverCtx.connectorHtml == null) {
|
|
745
|
-
const filePath = path__default['default'].join(devServerConfig.devServerDir, 'connector.html');
|
|
746
|
-
serverCtx.connectorHtml = serverCtx.sys.readFileSync(filePath, 'utf8');
|
|
747
|
-
if (typeof serverCtx.connectorHtml !== 'string') {
|
|
748
|
-
return serverCtx.serve404(req, res, `serveDevClientScript`);
|
|
749
|
-
}
|
|
750
|
-
const devClientConfig = {
|
|
751
|
-
basePath: devServerConfig.basePath,
|
|
752
|
-
editors: await getEditors(),
|
|
753
|
-
reloadStrategy: devServerConfig.reloadStrategy,
|
|
754
|
-
};
|
|
755
|
-
serverCtx.connectorHtml = serverCtx.connectorHtml.replace('window.__DEV_CLIENT_CONFIG__', JSON.stringify(devClientConfig));
|
|
756
|
-
}
|
|
757
|
-
res.writeHead(200, responseHeaders({
|
|
758
|
-
'content-type': 'text/html; charset=utf-8',
|
|
759
|
-
}));
|
|
760
|
-
res.write(serverCtx.connectorHtml);
|
|
761
|
-
res.end();
|
|
762
|
-
}
|
|
763
|
-
catch (e) {
|
|
764
|
-
return serverCtx.serve500(req, res, e, `serveDevClientScript`);
|
|
765
|
-
}
|
|
373
|
+
function createCommonjsModule(fn, basedir, module) {
|
|
374
|
+
return module = {
|
|
375
|
+
path: basedir,
|
|
376
|
+
exports: {},
|
|
377
|
+
require: function (path, base) {
|
|
378
|
+
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
|
|
379
|
+
}
|
|
380
|
+
}, fn(module, module.exports), module.exports;
|
|
766
381
|
}
|
|
767
382
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
const results = await serverCtx.getCompilerRequest(req.pathname);
|
|
771
|
-
const headers = {
|
|
772
|
-
'content-type': 'application/javascript; charset=utf-8',
|
|
773
|
-
'content-length': Buffer.byteLength(results.content, 'utf8'),
|
|
774
|
-
'x-dev-node-module-id': results.nodeModuleId,
|
|
775
|
-
'x-dev-node-module-version': results.nodeModuleVersion,
|
|
776
|
-
'x-dev-node-module-resolved-path': results.nodeResolvedPath,
|
|
777
|
-
'x-dev-node-module-cache-path': results.cachePath,
|
|
778
|
-
'x-dev-node-module-cache-hit': results.cacheHit,
|
|
779
|
-
};
|
|
780
|
-
res.writeHead(results.status, responseHeaders(headers));
|
|
781
|
-
res.write(results.content);
|
|
782
|
-
res.end();
|
|
783
|
-
}
|
|
784
|
-
catch (e) {
|
|
785
|
-
serverCtx.serve500(req, res, e, `serveDevNodeModule`);
|
|
786
|
-
}
|
|
383
|
+
function commonjsRequire () {
|
|
384
|
+
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
|
|
787
385
|
}
|
|
788
386
|
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
}
|
|
799
|
-
try {
|
|
800
|
-
const dirFilePaths = await serverCtx.sys.readDir(req.filePath);
|
|
801
|
-
try {
|
|
802
|
-
if (serverCtx.dirTemplate == null) {
|
|
803
|
-
const dirTemplatePath = path__default['default'].join(devServerConfig.devServerDir, 'templates', 'directory-index.html');
|
|
804
|
-
serverCtx.dirTemplate = serverCtx.sys.readFileSync(dirTemplatePath);
|
|
805
|
-
}
|
|
806
|
-
const files = await getFiles(serverCtx.sys, req.url, dirFilePaths);
|
|
807
|
-
const templateHtml = serverCtx.dirTemplate
|
|
808
|
-
.replace('{{title}}', getTitle(req.pathname))
|
|
809
|
-
.replace('{{nav}}', getName(req.pathname))
|
|
810
|
-
.replace('{{files}}', files);
|
|
811
|
-
serverCtx.logRequest(req, 200);
|
|
812
|
-
res.writeHead(200, responseHeaders({
|
|
813
|
-
'content-type': 'text/html; charset=utf-8',
|
|
814
|
-
'x-directory-index': req.pathname,
|
|
815
|
-
}));
|
|
816
|
-
res.write(templateHtml);
|
|
817
|
-
res.end();
|
|
818
|
-
}
|
|
819
|
-
catch (e) {
|
|
820
|
-
return serverCtx.serve500(req, res, e, 'serveDirectoryIndex');
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
catch (e) {
|
|
824
|
-
return serverCtx.serve404(req, res, 'serveDirectoryIndex');
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
async function getFiles(sys, baseUrl, dirItemNames) {
|
|
828
|
-
const items = await getDirectoryItems(sys, baseUrl, dirItemNames);
|
|
829
|
-
if (baseUrl.pathname !== '/') {
|
|
830
|
-
items.unshift({
|
|
831
|
-
isDirectory: true,
|
|
832
|
-
pathname: '../',
|
|
833
|
-
name: '..',
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
return items
|
|
837
|
-
.map((item) => {
|
|
838
|
-
return `
|
|
839
|
-
<li class="${item.isDirectory ? 'directory' : 'file'}">
|
|
840
|
-
<a href="${item.pathname}">
|
|
841
|
-
<span class="icon"></span>
|
|
842
|
-
<span>${item.name}</span>
|
|
843
|
-
</a>
|
|
844
|
-
</li>`;
|
|
845
|
-
})
|
|
846
|
-
.join('');
|
|
847
|
-
}
|
|
848
|
-
async function getDirectoryItems(sys, baseUrl, dirFilePaths) {
|
|
849
|
-
const items = await Promise.all(dirFilePaths.map(async (dirFilePath) => {
|
|
850
|
-
const fileName = path__default['default'].basename(dirFilePath);
|
|
851
|
-
const url = new URL(fileName, baseUrl);
|
|
852
|
-
const stats = await sys.stat(dirFilePath);
|
|
853
|
-
const item = {
|
|
854
|
-
name: fileName,
|
|
855
|
-
pathname: url.pathname,
|
|
856
|
-
isDirectory: stats.isDirectory,
|
|
857
|
-
};
|
|
858
|
-
return item;
|
|
859
|
-
}));
|
|
860
|
-
return items;
|
|
861
|
-
}
|
|
862
|
-
function getTitle(pathName) {
|
|
863
|
-
return pathName;
|
|
387
|
+
let isDocker;
|
|
388
|
+
|
|
389
|
+
function hasDockerEnv() {
|
|
390
|
+
try {
|
|
391
|
+
fs__default['default'].statSync('/.dockerenv');
|
|
392
|
+
return true;
|
|
393
|
+
} catch (_) {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
864
396
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
const text = index === 0 ? `~` : dir;
|
|
873
|
-
return `<a href="${url}">${text}</a>`;
|
|
874
|
-
})
|
|
875
|
-
.join('<span>/</span>') + '<span>/</span>');
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
async function ssrPageRequest(devServerConfig, serverCtx, req, res) {
|
|
879
|
-
try {
|
|
880
|
-
let status = 500;
|
|
881
|
-
let content = '';
|
|
882
|
-
const { hydrateApp, srcIndexHtml, diagnostics } = await setupHydrateApp(devServerConfig, serverCtx);
|
|
883
|
-
if (!diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
|
|
884
|
-
try {
|
|
885
|
-
const opts = getSsrHydrateOptions(devServerConfig, serverCtx, req.url);
|
|
886
|
-
const ssrResults = await hydrateApp.renderToString(srcIndexHtml, opts);
|
|
887
|
-
diagnostics.push(...ssrResults.diagnostics);
|
|
888
|
-
status = ssrResults.httpStatus;
|
|
889
|
-
content = ssrResults.html;
|
|
890
|
-
}
|
|
891
|
-
catch (e) {
|
|
892
|
-
catchError(diagnostics, e);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
if (diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
|
|
896
|
-
content = getSsrErrorContent(diagnostics);
|
|
897
|
-
status = 500;
|
|
898
|
-
}
|
|
899
|
-
if (devServerConfig.websocket) {
|
|
900
|
-
content = appendDevServerClientScript(devServerConfig, req, content);
|
|
901
|
-
}
|
|
902
|
-
serverCtx.logRequest(req, status);
|
|
903
|
-
res.writeHead(status, responseHeaders({
|
|
904
|
-
'content-type': 'text/html; charset=utf-8',
|
|
905
|
-
'content-length': Buffer.byteLength(content, 'utf8'),
|
|
906
|
-
}));
|
|
907
|
-
res.write(content);
|
|
908
|
-
res.end();
|
|
909
|
-
}
|
|
910
|
-
catch (e) {
|
|
911
|
-
serverCtx.serve500(req, res, e, `ssrPageRequest`);
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
async function ssrStaticDataRequest(devServerConfig, serverCtx, req, res) {
|
|
915
|
-
try {
|
|
916
|
-
const data = {};
|
|
917
|
-
let httpCache = false;
|
|
918
|
-
const { hydrateApp, srcIndexHtml, diagnostics } = await setupHydrateApp(devServerConfig, serverCtx);
|
|
919
|
-
if (!diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
|
|
920
|
-
try {
|
|
921
|
-
const { ssrPath, hasQueryString } = getSsrStaticDataPath(req);
|
|
922
|
-
const url = new URL(ssrPath, req.url);
|
|
923
|
-
const opts = getSsrHydrateOptions(devServerConfig, serverCtx, url);
|
|
924
|
-
const ssrResults = await hydrateApp.renderToString(srcIndexHtml, opts);
|
|
925
|
-
diagnostics.push(...ssrResults.diagnostics);
|
|
926
|
-
ssrResults.staticData.forEach((s) => {
|
|
927
|
-
if (s.type === 'application/json') {
|
|
928
|
-
data[s.id] = JSON.parse(s.content);
|
|
929
|
-
}
|
|
930
|
-
else {
|
|
931
|
-
data[s.id] = s.content;
|
|
932
|
-
}
|
|
933
|
-
});
|
|
934
|
-
data.components = ssrResults.components.map((c) => c.tag).sort();
|
|
935
|
-
httpCache = hasQueryString;
|
|
936
|
-
}
|
|
937
|
-
catch (e) {
|
|
938
|
-
catchError(diagnostics, e);
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
if (diagnostics.length > 0) {
|
|
942
|
-
data.diagnostics = diagnostics;
|
|
943
|
-
}
|
|
944
|
-
const status = diagnostics.some((diagnostic) => diagnostic.level === 'error') ? 500 : 200;
|
|
945
|
-
const content = JSON.stringify(data);
|
|
946
|
-
serverCtx.logRequest(req, status);
|
|
947
|
-
res.writeHead(status, responseHeaders({
|
|
948
|
-
'content-type': 'application/json; charset=utf-8',
|
|
949
|
-
'content-length': Buffer.byteLength(content, 'utf8'),
|
|
950
|
-
}, httpCache && status === 200));
|
|
951
|
-
res.write(content);
|
|
952
|
-
res.end();
|
|
953
|
-
}
|
|
954
|
-
catch (e) {
|
|
955
|
-
serverCtx.serve500(req, res, e, `ssrStaticDataRequest`);
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
async function setupHydrateApp(devServerConfig, serverCtx) {
|
|
959
|
-
let srcIndexHtml = null;
|
|
960
|
-
let hydrateApp = null;
|
|
961
|
-
const buildResults = await serverCtx.getBuildResults();
|
|
962
|
-
const diagnostics = [];
|
|
963
|
-
if (serverCtx.prerenderConfig == null && isString(devServerConfig.prerenderConfig)) {
|
|
964
|
-
const compilerPath = path__default['default'].join(devServerConfig.devServerDir, '..', 'compiler', 'stencil.js');
|
|
965
|
-
const compiler = require(compilerPath);
|
|
966
|
-
const prerenderConfigResults = compiler.nodeRequire(devServerConfig.prerenderConfig);
|
|
967
|
-
diagnostics.push(...prerenderConfigResults.diagnostics);
|
|
968
|
-
if (prerenderConfigResults.module && prerenderConfigResults.module.config) {
|
|
969
|
-
serverCtx.prerenderConfig = prerenderConfigResults.module.config;
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
if (!isString(buildResults.hydrateAppFilePath)) {
|
|
973
|
-
diagnostics.push({ messageText: `Missing hydrateAppFilePath`, level: `error`, type: `ssr` });
|
|
974
|
-
}
|
|
975
|
-
else if (!isString(devServerConfig.srcIndexHtml)) {
|
|
976
|
-
diagnostics.push({ messageText: `Missing srcIndexHtml`, level: `error`, type: `ssr` });
|
|
977
|
-
}
|
|
978
|
-
else {
|
|
979
|
-
srcIndexHtml = await serverCtx.sys.readFile(devServerConfig.srcIndexHtml);
|
|
980
|
-
if (!isString(srcIndexHtml)) {
|
|
981
|
-
diagnostics.push({
|
|
982
|
-
messageText: `Unable to load src index html: ${devServerConfig.srcIndexHtml}`,
|
|
983
|
-
level: `error`,
|
|
984
|
-
type: `ssr`,
|
|
985
|
-
});
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
// ensure we cleared out node's internal require() cache for this file
|
|
989
|
-
const hydrateAppFilePath = path__default['default'].resolve(buildResults.hydrateAppFilePath);
|
|
990
|
-
// brute force way of clearning node's module cache
|
|
991
|
-
// not using `delete require.cache[id]` since it'll cause memory leaks
|
|
992
|
-
require.cache = {};
|
|
993
|
-
const Module = require('module');
|
|
994
|
-
Module._cache[hydrateAppFilePath] = undefined;
|
|
995
|
-
hydrateApp = require(hydrateAppFilePath);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return {
|
|
999
|
-
hydrateApp,
|
|
1000
|
-
srcIndexHtml,
|
|
1001
|
-
diagnostics,
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
function getSsrHydrateOptions(devServerConfig, serverCtx, url) {
|
|
1005
|
-
const opts = {
|
|
1006
|
-
url: url.href,
|
|
1007
|
-
addModulePreloads: false,
|
|
1008
|
-
approximateLineWidth: 120,
|
|
1009
|
-
inlineExternalStyleSheets: false,
|
|
1010
|
-
minifyScriptElements: false,
|
|
1011
|
-
minifyStyleElements: false,
|
|
1012
|
-
removeAttributeQuotes: false,
|
|
1013
|
-
removeBooleanAttributeQuotes: false,
|
|
1014
|
-
removeEmptyAttributes: false,
|
|
1015
|
-
removeHtmlComments: false,
|
|
1016
|
-
prettyHtml: true,
|
|
1017
|
-
};
|
|
1018
|
-
const prerenderConfig = serverCtx === null || serverCtx === void 0 ? void 0 : serverCtx.prerenderConfig;
|
|
1019
|
-
if (isFunction(prerenderConfig === null || prerenderConfig === void 0 ? void 0 : prerenderConfig.hydrateOptions)) {
|
|
1020
|
-
const userOpts = prerenderConfig.hydrateOptions(url);
|
|
1021
|
-
if (userOpts) {
|
|
1022
|
-
Object.assign(opts, userOpts);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
if (isFunction(serverCtx.sys.applyPrerenderGlobalPatch)) {
|
|
1026
|
-
const orgBeforeHydrate = opts.beforeHydrate;
|
|
1027
|
-
opts.beforeHydrate = (document) => {
|
|
1028
|
-
// patch this new window with the fetch global from node-fetch
|
|
1029
|
-
const devServerBaseUrl = new URL(devServerConfig.browserUrl);
|
|
1030
|
-
const devServerHostUrl = devServerBaseUrl.origin;
|
|
1031
|
-
serverCtx.sys.applyPrerenderGlobalPatch({
|
|
1032
|
-
devServerHostUrl: devServerHostUrl,
|
|
1033
|
-
window: document.defaultView,
|
|
1034
|
-
});
|
|
1035
|
-
if (typeof orgBeforeHydrate === 'function') {
|
|
1036
|
-
return orgBeforeHydrate(document);
|
|
1037
|
-
}
|
|
1038
|
-
};
|
|
1039
|
-
}
|
|
1040
|
-
return opts;
|
|
1041
|
-
}
|
|
1042
|
-
function getSsrErrorContent(diagnostics) {
|
|
1043
|
-
return `<!doctype html>
|
|
1044
|
-
<html>
|
|
1045
|
-
<head>
|
|
1046
|
-
<title>SSR Error</title>
|
|
1047
|
-
<style>
|
|
1048
|
-
body {
|
|
1049
|
-
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important;
|
|
1050
|
-
}
|
|
1051
|
-
</style>
|
|
1052
|
-
</head>
|
|
1053
|
-
<body>
|
|
1054
|
-
<h1>SSR Dev Error</h1>
|
|
1055
|
-
${diagnostics.map((diagnostic) => `
|
|
1056
|
-
<p>
|
|
1057
|
-
${diagnostic.messageText}
|
|
1058
|
-
</p>
|
|
1059
|
-
`)}
|
|
1060
|
-
</body>
|
|
1061
|
-
</html>`;
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
function createRequestHandler(devServerConfig, serverCtx) {
|
|
1065
|
-
let userRequestHandler = null;
|
|
1066
|
-
if (typeof devServerConfig.requestListenerPath === 'string') {
|
|
1067
|
-
userRequestHandler = require(devServerConfig.requestListenerPath);
|
|
1068
|
-
}
|
|
1069
|
-
return async function (incomingReq, res) {
|
|
1070
|
-
async function defaultHandler() {
|
|
1071
|
-
try {
|
|
1072
|
-
const req = normalizeHttpRequest(devServerConfig, incomingReq);
|
|
1073
|
-
if (!req.url) {
|
|
1074
|
-
return serverCtx.serve302(req, res);
|
|
1075
|
-
}
|
|
1076
|
-
if (isDevClient(req.pathname) && devServerConfig.websocket) {
|
|
1077
|
-
return serveDevClient(devServerConfig, serverCtx, req, res);
|
|
1078
|
-
}
|
|
1079
|
-
if (isDevModule(req.pathname)) {
|
|
1080
|
-
return serveDevNodeModule(serverCtx, req, res);
|
|
1081
|
-
}
|
|
1082
|
-
if (!isValidUrlBasePath(devServerConfig.basePath, req.url)) {
|
|
1083
|
-
return serverCtx.serve404(req, res, `invalid basePath`, `404 File Not Found, base path: ${devServerConfig.basePath}`);
|
|
1084
|
-
}
|
|
1085
|
-
if (devServerConfig.ssr) {
|
|
1086
|
-
if (isExtensionLessPath(req.url.pathname)) {
|
|
1087
|
-
return ssrPageRequest(devServerConfig, serverCtx, req, res);
|
|
1088
|
-
}
|
|
1089
|
-
if (isSsrStaticDataPath(req.url.pathname)) {
|
|
1090
|
-
return ssrStaticDataRequest(devServerConfig, serverCtx, req, res);
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
req.stats = await serverCtx.sys.stat(req.filePath);
|
|
1094
|
-
if (req.stats.isFile) {
|
|
1095
|
-
return serveFile(devServerConfig, serverCtx, req, res);
|
|
1096
|
-
}
|
|
1097
|
-
if (req.stats.isDirectory) {
|
|
1098
|
-
return serveDirectoryIndex(devServerConfig, serverCtx, req, res);
|
|
1099
|
-
}
|
|
1100
|
-
const xSource = ['notfound'];
|
|
1101
|
-
const validHistoryApi = isValidHistoryApi(devServerConfig, req);
|
|
1102
|
-
xSource.push(`validHistoryApi: ${validHistoryApi}`);
|
|
1103
|
-
if (validHistoryApi) {
|
|
1104
|
-
try {
|
|
1105
|
-
const indexFilePath = path__default['default'].join(devServerConfig.root, devServerConfig.historyApiFallback.index);
|
|
1106
|
-
xSource.push(`indexFilePath: ${indexFilePath}`);
|
|
1107
|
-
req.stats = await serverCtx.sys.stat(indexFilePath);
|
|
1108
|
-
if (req.stats.isFile) {
|
|
1109
|
-
req.filePath = indexFilePath;
|
|
1110
|
-
return serveFile(devServerConfig, serverCtx, req, res);
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
catch (e) {
|
|
1114
|
-
xSource.push(`notfound error: ${e}`);
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
return serverCtx.serve404(req, res, xSource.join(', '));
|
|
1118
|
-
}
|
|
1119
|
-
catch (e) {
|
|
1120
|
-
return serverCtx.serve500(incomingReq, res, e, `not found error`);
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
if (typeof userRequestHandler === 'function') {
|
|
1124
|
-
await userRequestHandler(incomingReq, res, defaultHandler);
|
|
1125
|
-
}
|
|
1126
|
-
else {
|
|
1127
|
-
await defaultHandler();
|
|
1128
|
-
}
|
|
1129
|
-
};
|
|
1130
|
-
}
|
|
1131
|
-
function isValidUrlBasePath(basePath, url) {
|
|
1132
|
-
// normalize the paths to always end with a slash for the check
|
|
1133
|
-
let pathname = url.pathname;
|
|
1134
|
-
if (!pathname.endsWith('/')) {
|
|
1135
|
-
pathname += '/';
|
|
1136
|
-
}
|
|
1137
|
-
if (!basePath.endsWith('/')) {
|
|
1138
|
-
basePath += '/';
|
|
1139
|
-
}
|
|
1140
|
-
return pathname.startsWith(basePath);
|
|
1141
|
-
}
|
|
1142
|
-
function normalizeHttpRequest(devServerConfig, incomingReq) {
|
|
1143
|
-
const req = {
|
|
1144
|
-
method: (incomingReq.method || 'GET').toUpperCase(),
|
|
1145
|
-
headers: incomingReq.headers,
|
|
1146
|
-
acceptHeader: (incomingReq.headers && typeof incomingReq.headers.accept === 'string' && incomingReq.headers.accept) || '',
|
|
1147
|
-
host: (incomingReq.headers && typeof incomingReq.headers.host === 'string' && incomingReq.headers.host) || null,
|
|
1148
|
-
url: null,
|
|
1149
|
-
searchParams: null,
|
|
1150
|
-
};
|
|
1151
|
-
const incomingUrl = (incomingReq.url || '').trim() || null;
|
|
1152
|
-
if (incomingUrl) {
|
|
1153
|
-
if (req.host) {
|
|
1154
|
-
req.url = new URL(incomingReq.url, `http://${req.host}`);
|
|
1155
|
-
}
|
|
1156
|
-
else {
|
|
1157
|
-
req.url = new URL(incomingReq.url, `http://dev.stenciljs.com`);
|
|
1158
|
-
}
|
|
1159
|
-
req.searchParams = req.url.searchParams;
|
|
1160
|
-
}
|
|
1161
|
-
if (req.url) {
|
|
1162
|
-
const parts = req.url.pathname.replace(/\\/g, '/').split('/');
|
|
1163
|
-
req.pathname = parts.map((part) => decodeURIComponent(part)).join('/');
|
|
1164
|
-
if (req.pathname.length > 0 && !isDevClient(req.pathname)) {
|
|
1165
|
-
req.pathname = '/' + req.pathname.substring(devServerConfig.basePath.length);
|
|
1166
|
-
}
|
|
1167
|
-
req.filePath = normalizePath(path__default['default'].normalize(path__default['default'].join(devServerConfig.root, path__default['default'].relative('/', req.pathname))));
|
|
1168
|
-
}
|
|
1169
|
-
return req;
|
|
1170
|
-
}
|
|
1171
|
-
function isValidHistoryApi(devServerConfig, req) {
|
|
1172
|
-
if (!devServerConfig.historyApiFallback) {
|
|
1173
|
-
return false;
|
|
1174
|
-
}
|
|
1175
|
-
if (req.method !== 'GET') {
|
|
1176
|
-
return false;
|
|
1177
|
-
}
|
|
1178
|
-
if (!req.acceptHeader.includes('text/html')) {
|
|
1179
|
-
return false;
|
|
1180
|
-
}
|
|
1181
|
-
if (!devServerConfig.historyApiFallback.disableDotRule && req.pathname.includes('.')) {
|
|
1182
|
-
return false;
|
|
1183
|
-
}
|
|
1184
|
-
return true;
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
function createHttpServer(devServerConfig, serverCtx) {
|
|
1188
|
-
// create our request handler
|
|
1189
|
-
const reqHandler = createRequestHandler(devServerConfig, serverCtx);
|
|
1190
|
-
const credentials = devServerConfig.https;
|
|
1191
|
-
return credentials ? https__namespace.createServer(credentials, reqHandler) : http__namespace.createServer(reqHandler);
|
|
1192
|
-
}
|
|
1193
|
-
async function findClosestOpenPort(host, port) {
|
|
1194
|
-
async function t(portToCheck) {
|
|
1195
|
-
const isTaken = await isPortTaken(host, portToCheck);
|
|
1196
|
-
if (!isTaken) {
|
|
1197
|
-
return portToCheck;
|
|
1198
|
-
}
|
|
1199
|
-
return t(portToCheck + 1);
|
|
1200
|
-
}
|
|
1201
|
-
return t(port);
|
|
1202
|
-
}
|
|
1203
|
-
function isPortTaken(host, port) {
|
|
1204
|
-
return new Promise((resolve, reject) => {
|
|
1205
|
-
const tester = net__namespace
|
|
1206
|
-
.createServer()
|
|
1207
|
-
.once('error', () => {
|
|
1208
|
-
resolve(true);
|
|
1209
|
-
})
|
|
1210
|
-
.once('listening', () => {
|
|
1211
|
-
tester
|
|
1212
|
-
.once('close', () => {
|
|
1213
|
-
resolve(false);
|
|
1214
|
-
})
|
|
1215
|
-
.close();
|
|
1216
|
-
})
|
|
1217
|
-
.on('error', (err) => {
|
|
1218
|
-
reject(err);
|
|
1219
|
-
})
|
|
1220
|
-
.listen(port, host);
|
|
1221
|
-
});
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
function createWebSocket(httpServer, onMessageFromClient) {
|
|
1225
|
-
const wsConfig = {
|
|
1226
|
-
server: httpServer,
|
|
1227
|
-
};
|
|
1228
|
-
const wsServer = new ws__namespace.Server(wsConfig);
|
|
1229
|
-
function heartbeat() {
|
|
1230
|
-
this.isAlive = true;
|
|
1231
|
-
}
|
|
1232
|
-
wsServer.on('connection', (ws) => {
|
|
1233
|
-
ws.on('message', (data) => {
|
|
1234
|
-
// the server process has received a message from the browser
|
|
1235
|
-
// pass the message received from the browser to the main cli process
|
|
1236
|
-
try {
|
|
1237
|
-
onMessageFromClient(JSON.parse(data.toString()));
|
|
1238
|
-
}
|
|
1239
|
-
catch (e) {
|
|
1240
|
-
console.error(e);
|
|
1241
|
-
}
|
|
1242
|
-
});
|
|
1243
|
-
ws.isAlive = true;
|
|
1244
|
-
ws.on('pong', heartbeat);
|
|
1245
|
-
// ignore invalid close frames sent by Safari 15
|
|
1246
|
-
ws.on('error', console.error);
|
|
1247
|
-
});
|
|
1248
|
-
const pingInternval = setInterval(() => {
|
|
1249
|
-
wsServer.clients.forEach((ws) => {
|
|
1250
|
-
if (!ws.isAlive) {
|
|
1251
|
-
return ws.close(1000);
|
|
1252
|
-
}
|
|
1253
|
-
ws.isAlive = false;
|
|
1254
|
-
ws.ping(noop);
|
|
1255
|
-
});
|
|
1256
|
-
}, 10000);
|
|
1257
|
-
return {
|
|
1258
|
-
sendToBrowser: (msg) => {
|
|
1259
|
-
if (msg && wsServer && wsServer.clients) {
|
|
1260
|
-
const data = JSON.stringify(msg);
|
|
1261
|
-
wsServer.clients.forEach((ws) => {
|
|
1262
|
-
if (ws.readyState === ws.OPEN) {
|
|
1263
|
-
ws.send(data);
|
|
1264
|
-
}
|
|
1265
|
-
});
|
|
1266
|
-
}
|
|
1267
|
-
},
|
|
1268
|
-
close: () => {
|
|
1269
|
-
return new Promise((resolve, reject) => {
|
|
1270
|
-
clearInterval(pingInternval);
|
|
1271
|
-
wsServer.clients.forEach((ws) => {
|
|
1272
|
-
ws.close(1000);
|
|
1273
|
-
});
|
|
1274
|
-
wsServer.close((err) => {
|
|
1275
|
-
if (err) {
|
|
1276
|
-
reject(err);
|
|
1277
|
-
}
|
|
1278
|
-
else {
|
|
1279
|
-
resolve();
|
|
1280
|
-
}
|
|
1281
|
-
});
|
|
1282
|
-
});
|
|
1283
|
-
},
|
|
1284
|
-
};
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
function createCommonjsModule(fn, basedir, module) {
|
|
1288
|
-
return module = {
|
|
1289
|
-
path: basedir,
|
|
1290
|
-
exports: {},
|
|
1291
|
-
require: function (path, base) {
|
|
1292
|
-
return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
|
|
1293
|
-
}
|
|
1294
|
-
}, fn(module, module.exports), module.exports;
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
function commonjsRequire () {
|
|
1298
|
-
throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
let isDocker;
|
|
1302
|
-
|
|
1303
|
-
function hasDockerEnv() {
|
|
1304
|
-
try {
|
|
1305
|
-
fs__default$1['default'].statSync('/.dockerenv');
|
|
1306
|
-
return true;
|
|
1307
|
-
} catch (_) {
|
|
1308
|
-
return false;
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
function hasDockerCGroup() {
|
|
1313
|
-
try {
|
|
1314
|
-
return fs__default$1['default'].readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
|
|
1315
|
-
} catch (_) {
|
|
1316
|
-
return false;
|
|
1317
|
-
}
|
|
397
|
+
|
|
398
|
+
function hasDockerCGroup() {
|
|
399
|
+
try {
|
|
400
|
+
return fs__default['default'].readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
|
|
401
|
+
} catch (_) {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
1318
404
|
}
|
|
1319
405
|
|
|
1320
406
|
var isDocker_1 = () => {
|
|
@@ -1344,7 +430,7 @@ const isWsl = () => {
|
|
|
1344
430
|
}
|
|
1345
431
|
|
|
1346
432
|
try {
|
|
1347
|
-
return fs__default
|
|
433
|
+
return fs__default['default'].readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ?
|
|
1348
434
|
!isDocker_1() : false;
|
|
1349
435
|
} catch (_) {
|
|
1350
436
|
return false;
|
|
@@ -1377,7 +463,7 @@ var defineLazyProp = (object, propertyName, fn) => {
|
|
|
1377
463
|
return object;
|
|
1378
464
|
};
|
|
1379
465
|
|
|
1380
|
-
const {promises: fs, constants: fsConstants} = fs__default
|
|
466
|
+
const {promises: fs, constants: fsConstants} = fs__default['default'];
|
|
1381
467
|
|
|
1382
468
|
|
|
1383
469
|
|
|
@@ -1446,11 +532,7 @@ const pTryEach = async (array, mapper) => {
|
|
|
1446
532
|
throw latestError;
|
|
1447
533
|
};
|
|
1448
534
|
|
|
1449
|
-
const
|
|
1450
|
-
if (typeof target !== 'string') {
|
|
1451
|
-
throw new TypeError('Expected a `target`');
|
|
1452
|
-
}
|
|
1453
|
-
|
|
535
|
+
const baseOpen = async options => {
|
|
1454
536
|
options = {
|
|
1455
537
|
wait: false,
|
|
1456
538
|
background: false,
|
|
@@ -1460,7 +542,7 @@ const open = async (target, options) => {
|
|
|
1460
542
|
};
|
|
1461
543
|
|
|
1462
544
|
if (Array.isArray(options.app)) {
|
|
1463
|
-
return pTryEach(options.app, singleApp =>
|
|
545
|
+
return pTryEach(options.app, singleApp => baseOpen({
|
|
1464
546
|
...options,
|
|
1465
547
|
app: singleApp
|
|
1466
548
|
}));
|
|
@@ -1470,7 +552,7 @@ const open = async (target, options) => {
|
|
|
1470
552
|
appArguments = [...appArguments];
|
|
1471
553
|
|
|
1472
554
|
if (Array.isArray(app)) {
|
|
1473
|
-
return pTryEach(app, appName =>
|
|
555
|
+
return pTryEach(app, appName => baseOpen({
|
|
1474
556
|
...options,
|
|
1475
557
|
app: {
|
|
1476
558
|
name: appName,
|
|
@@ -1530,9 +612,11 @@ const open = async (target, options) => {
|
|
|
1530
612
|
// Double quote with double quotes to ensure the inner quotes are passed through.
|
|
1531
613
|
// Inner quotes are delimited for PowerShell interpretation with backticks.
|
|
1532
614
|
encodedArguments.push(`"\`"${app}\`""`, '-ArgumentList');
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
615
|
+
if (options.target) {
|
|
616
|
+
appArguments.unshift(options.target);
|
|
617
|
+
}
|
|
618
|
+
} else if (options.target) {
|
|
619
|
+
encodedArguments.push(`"${options.target}"`);
|
|
1536
620
|
}
|
|
1537
621
|
|
|
1538
622
|
if (appArguments.length > 0) {
|
|
@@ -1541,7 +625,7 @@ const open = async (target, options) => {
|
|
|
1541
625
|
}
|
|
1542
626
|
|
|
1543
627
|
// Using Base64-encoded command, accepted by PowerShell, to allow special characters.
|
|
1544
|
-
target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
|
|
628
|
+
options.target = Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
|
|
1545
629
|
} else {
|
|
1546
630
|
if (app) {
|
|
1547
631
|
command = app;
|
|
@@ -1561,108 +645,1055 @@ const open = async (target, options) => {
|
|
|
1561
645
|
command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath;
|
|
1562
646
|
}
|
|
1563
647
|
|
|
1564
|
-
if (appArguments.length > 0) {
|
|
1565
|
-
cliArguments.push(...appArguments);
|
|
1566
|
-
}
|
|
648
|
+
if (appArguments.length > 0) {
|
|
649
|
+
cliArguments.push(...appArguments);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
if (!options.wait) {
|
|
653
|
+
// `xdg-open` will block the process unless stdio is ignored
|
|
654
|
+
// and it's detached from the parent even if it's unref'd.
|
|
655
|
+
childProcessOptions.stdio = 'ignore';
|
|
656
|
+
childProcessOptions.detached = true;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
if (options.target) {
|
|
661
|
+
cliArguments.push(options.target);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (platform === 'darwin' && appArguments.length > 0) {
|
|
665
|
+
cliArguments.push('--args', ...appArguments);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const subprocess = childProcess__default['default'].spawn(command, cliArguments, childProcessOptions);
|
|
669
|
+
|
|
670
|
+
if (options.wait) {
|
|
671
|
+
return new Promise((resolve, reject) => {
|
|
672
|
+
subprocess.once('error', reject);
|
|
673
|
+
|
|
674
|
+
subprocess.once('close', exitCode => {
|
|
675
|
+
if (options.allowNonzeroExitCode && exitCode > 0) {
|
|
676
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
resolve(subprocess);
|
|
681
|
+
});
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
subprocess.unref();
|
|
686
|
+
|
|
687
|
+
return subprocess;
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
const open = (target, options) => {
|
|
691
|
+
if (typeof target !== 'string') {
|
|
692
|
+
throw new TypeError('Expected a `target`');
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return baseOpen({
|
|
696
|
+
...options,
|
|
697
|
+
target
|
|
698
|
+
});
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
const openApp = (name, options) => {
|
|
702
|
+
if (typeof name !== 'string') {
|
|
703
|
+
throw new TypeError('Expected a `name`');
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const {arguments: appArguments = []} = options || {};
|
|
707
|
+
if (appArguments !== undefined && appArguments !== null && !Array.isArray(appArguments)) {
|
|
708
|
+
throw new TypeError('Expected `appArguments` as Array type');
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
return baseOpen({
|
|
712
|
+
...options,
|
|
713
|
+
app: {
|
|
714
|
+
name,
|
|
715
|
+
arguments: appArguments
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
function detectArchBinary(binary) {
|
|
721
|
+
if (typeof binary === 'string' || Array.isArray(binary)) {
|
|
722
|
+
return binary;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
const {[arch]: archBinary} = binary;
|
|
1567
726
|
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
// and it's detached from the parent even if it's unref'd.
|
|
1571
|
-
childProcessOptions.stdio = 'ignore';
|
|
1572
|
-
childProcessOptions.detached = true;
|
|
1573
|
-
}
|
|
727
|
+
if (!archBinary) {
|
|
728
|
+
throw new Error(`${arch} is not supported`);
|
|
1574
729
|
}
|
|
1575
730
|
|
|
1576
|
-
|
|
731
|
+
return archBinary;
|
|
732
|
+
}
|
|
1577
733
|
|
|
1578
|
-
|
|
1579
|
-
|
|
734
|
+
function detectPlatformBinary({[platform]: platformBinary}, {wsl}) {
|
|
735
|
+
if (wsl && isWsl_1) {
|
|
736
|
+
return detectArchBinary(wsl);
|
|
1580
737
|
}
|
|
1581
738
|
|
|
1582
|
-
|
|
739
|
+
if (!platformBinary) {
|
|
740
|
+
throw new Error(`${platform} is not supported`);
|
|
741
|
+
}
|
|
1583
742
|
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
subprocess.once('error', reject);
|
|
743
|
+
return detectArchBinary(platformBinary);
|
|
744
|
+
}
|
|
1587
745
|
|
|
1588
|
-
|
|
1589
|
-
if (options.allowNonzeroExitCode && exitCode > 0) {
|
|
1590
|
-
reject(new Error(`Exited with code ${exitCode}`));
|
|
1591
|
-
return;
|
|
1592
|
-
}
|
|
746
|
+
const apps = {};
|
|
1593
747
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
748
|
+
defineLazyProp(apps, 'chrome', () => detectPlatformBinary({
|
|
749
|
+
darwin: 'google chrome',
|
|
750
|
+
win32: 'chrome',
|
|
751
|
+
linux: ['google-chrome', 'google-chrome-stable', 'chromium']
|
|
752
|
+
}, {
|
|
753
|
+
wsl: {
|
|
754
|
+
ia32: '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe',
|
|
755
|
+
x64: ['/mnt/c/Program Files/Google/Chrome/Application/chrome.exe', '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe']
|
|
1597
756
|
}
|
|
757
|
+
}));
|
|
1598
758
|
|
|
1599
|
-
|
|
759
|
+
defineLazyProp(apps, 'firefox', () => detectPlatformBinary({
|
|
760
|
+
darwin: 'firefox',
|
|
761
|
+
win32: 'C:\\Program Files\\Mozilla Firefox\\firefox.exe',
|
|
762
|
+
linux: 'firefox'
|
|
763
|
+
}, {
|
|
764
|
+
wsl: '/mnt/c/Program Files/Mozilla Firefox/firefox.exe'
|
|
765
|
+
}));
|
|
1600
766
|
|
|
1601
|
-
|
|
767
|
+
defineLazyProp(apps, 'edge', () => detectPlatformBinary({
|
|
768
|
+
darwin: 'microsoft edge',
|
|
769
|
+
win32: 'msedge',
|
|
770
|
+
linux: ['microsoft-edge', 'microsoft-edge-dev']
|
|
771
|
+
}, {
|
|
772
|
+
wsl: '/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe'
|
|
773
|
+
}));
|
|
774
|
+
|
|
775
|
+
open.apps = apps;
|
|
776
|
+
open.openApp = openApp;
|
|
777
|
+
|
|
778
|
+
var open_1 = open;
|
|
779
|
+
|
|
780
|
+
async function openInBrowser(opts) {
|
|
781
|
+
// await open(opts.url, { app: ['google chrome', '--auto-open-devtools-for-tabs'] });
|
|
782
|
+
await open_1(opts.url);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
function createServerContext(sys, sendMsg, devServerConfig, buildResultsResolves, compilerRequestResolves) {
|
|
786
|
+
const logRequest = (req, status) => {
|
|
787
|
+
if (devServerConfig) {
|
|
788
|
+
sendMsg({
|
|
789
|
+
requestLog: {
|
|
790
|
+
method: req.method || '?',
|
|
791
|
+
url: req.pathname || '?',
|
|
792
|
+
status,
|
|
793
|
+
},
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
const serve500 = (req, res, error, xSource) => {
|
|
798
|
+
try {
|
|
799
|
+
res.writeHead(500, responseHeaders({
|
|
800
|
+
'content-type': 'text/plain; charset=utf-8',
|
|
801
|
+
'x-source': xSource,
|
|
802
|
+
}));
|
|
803
|
+
res.write(util__default['default'].inspect(error));
|
|
804
|
+
res.end();
|
|
805
|
+
logRequest(req, 500);
|
|
806
|
+
}
|
|
807
|
+
catch (e) {
|
|
808
|
+
sendMsg({ error: { message: 'serve500: ' + e } });
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
const serve404 = (req, res, xSource, content = null) => {
|
|
812
|
+
try {
|
|
813
|
+
if (req.pathname === '/favicon.ico') {
|
|
814
|
+
const defaultFavicon = path__default['default'].join(devServerConfig.devServerDir, 'static', 'favicon.ico');
|
|
815
|
+
res.writeHead(200, responseHeaders({
|
|
816
|
+
'content-type': 'image/x-icon',
|
|
817
|
+
'x-source': `favicon: ${xSource}`,
|
|
818
|
+
}));
|
|
819
|
+
const rs = fs__default$1['default'].createReadStream(defaultFavicon);
|
|
820
|
+
rs.on('error', (err) => {
|
|
821
|
+
res.writeHead(404, responseHeaders({
|
|
822
|
+
'content-type': 'text/plain; charset=utf-8',
|
|
823
|
+
'x-source': `createReadStream error: ${err}, ${xSource}`,
|
|
824
|
+
}));
|
|
825
|
+
res.write(util__default['default'].inspect(err));
|
|
826
|
+
res.end();
|
|
827
|
+
});
|
|
828
|
+
rs.pipe(res);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (content == null) {
|
|
832
|
+
content = ['404 File Not Found', 'Url: ' + req.pathname, 'File: ' + req.filePath].join('\n');
|
|
833
|
+
}
|
|
834
|
+
res.writeHead(404, responseHeaders({
|
|
835
|
+
'content-type': 'text/plain; charset=utf-8',
|
|
836
|
+
'x-source': xSource,
|
|
837
|
+
}));
|
|
838
|
+
res.write(content);
|
|
839
|
+
res.end();
|
|
840
|
+
logRequest(req, 400);
|
|
841
|
+
}
|
|
842
|
+
catch (e) {
|
|
843
|
+
serve500(req, res, e, xSource);
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
const serve302 = (req, res, pathname = null) => {
|
|
847
|
+
logRequest(req, 302);
|
|
848
|
+
res.writeHead(302, { location: pathname || devServerConfig.basePath || '/' });
|
|
849
|
+
res.end();
|
|
850
|
+
};
|
|
851
|
+
const getBuildResults = () => new Promise((resolve, reject) => {
|
|
852
|
+
if (serverCtx.isServerListening) {
|
|
853
|
+
buildResultsResolves.push({ resolve, reject });
|
|
854
|
+
sendMsg({ requestBuildResults: true });
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
reject('dev server closed');
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
const getCompilerRequest = (compilerRequestPath) => new Promise((resolve, reject) => {
|
|
861
|
+
if (serverCtx.isServerListening) {
|
|
862
|
+
compilerRequestResolves.push({
|
|
863
|
+
path: compilerRequestPath,
|
|
864
|
+
resolve,
|
|
865
|
+
reject,
|
|
866
|
+
});
|
|
867
|
+
sendMsg({ compilerRequestPath });
|
|
868
|
+
}
|
|
869
|
+
else {
|
|
870
|
+
reject('dev server closed');
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
const serverCtx = {
|
|
874
|
+
connectorHtml: null,
|
|
875
|
+
dirTemplate: null,
|
|
876
|
+
getBuildResults,
|
|
877
|
+
getCompilerRequest,
|
|
878
|
+
isServerListening: false,
|
|
879
|
+
logRequest,
|
|
880
|
+
prerenderConfig: null,
|
|
881
|
+
serve302,
|
|
882
|
+
serve404,
|
|
883
|
+
serve500,
|
|
884
|
+
sys,
|
|
885
|
+
};
|
|
886
|
+
return serverCtx;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
async function serveOpenInEditor(serverCtx, req, res) {
|
|
890
|
+
let status = 200;
|
|
891
|
+
const data = {};
|
|
892
|
+
try {
|
|
893
|
+
const editors = await getEditors();
|
|
894
|
+
if (editors.length > 0) {
|
|
895
|
+
await parseData(editors, serverCtx.sys, req, data);
|
|
896
|
+
await openDataInEditor(data);
|
|
897
|
+
}
|
|
898
|
+
else {
|
|
899
|
+
data.error = `no editors available`;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
catch (e) {
|
|
903
|
+
data.error = e + '';
|
|
904
|
+
status = 500;
|
|
905
|
+
}
|
|
906
|
+
serverCtx.logRequest(req, status);
|
|
907
|
+
res.writeHead(status, responseHeaders({
|
|
908
|
+
'content-type': 'application/json; charset=utf-8',
|
|
909
|
+
}));
|
|
910
|
+
res.write(JSON.stringify(data, null, 2));
|
|
911
|
+
res.end();
|
|
912
|
+
}
|
|
913
|
+
async function parseData(editors, sys, req, data) {
|
|
914
|
+
const qs = req.searchParams;
|
|
915
|
+
if (!qs.has('file')) {
|
|
916
|
+
data.error = `missing file`;
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
data.file = qs.get('file');
|
|
920
|
+
if (qs.has('line') && !isNaN(qs.get('line'))) {
|
|
921
|
+
data.line = parseInt(qs.get('line'), 10);
|
|
922
|
+
}
|
|
923
|
+
if (typeof data.line !== 'number' || data.line < 1) {
|
|
924
|
+
data.line = 1;
|
|
925
|
+
}
|
|
926
|
+
if (qs.has('column') && !isNaN(qs.get('column'))) {
|
|
927
|
+
data.column = parseInt(qs.get('column'), 10);
|
|
928
|
+
}
|
|
929
|
+
if (typeof data.column !== 'number' || data.column < 1) {
|
|
930
|
+
data.column = 1;
|
|
931
|
+
}
|
|
932
|
+
let editor = qs.get('editor');
|
|
933
|
+
if (typeof editor === 'string') {
|
|
934
|
+
editor = editor.trim().toLowerCase();
|
|
935
|
+
if (editors.some((e) => e.id === editor)) {
|
|
936
|
+
data.editor = editor;
|
|
937
|
+
}
|
|
938
|
+
else {
|
|
939
|
+
data.error = `invalid editor: ${editor}`;
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
data.editor = editors[0].id;
|
|
945
|
+
}
|
|
946
|
+
const stat = await sys.stat(data.file);
|
|
947
|
+
data.exists = stat.isFile;
|
|
948
|
+
}
|
|
949
|
+
async function openDataInEditor(data) {
|
|
950
|
+
if (!data.exists || data.error) {
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
try {
|
|
954
|
+
const opts = {
|
|
955
|
+
editor: data.editor,
|
|
956
|
+
};
|
|
957
|
+
const editor = openInEditorApi__default['default'].configure(opts, (err) => (data.error = err + ''));
|
|
958
|
+
if (data.error) {
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
data.open = `${data.file}:${data.line}:${data.column}`;
|
|
962
|
+
await editor.open(data.open);
|
|
963
|
+
}
|
|
964
|
+
catch (e) {
|
|
965
|
+
data.error = e + '';
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
let editors = null;
|
|
969
|
+
function getEditors() {
|
|
970
|
+
if (!editors) {
|
|
971
|
+
editors = new Promise(async (resolve) => {
|
|
972
|
+
const editors = [];
|
|
973
|
+
try {
|
|
974
|
+
await Promise.all(Object.keys(openInEditorApi__default['default'].editors).map(async (editorId) => {
|
|
975
|
+
const isSupported = await isEditorSupported(editorId);
|
|
976
|
+
editors.push({
|
|
977
|
+
id: editorId,
|
|
978
|
+
priority: EDITOR_PRIORITY[editorId],
|
|
979
|
+
supported: isSupported,
|
|
980
|
+
});
|
|
981
|
+
}));
|
|
982
|
+
}
|
|
983
|
+
catch (e) { }
|
|
984
|
+
resolve(editors
|
|
985
|
+
.filter((e) => e.supported)
|
|
986
|
+
.sort((a, b) => {
|
|
987
|
+
if (a.priority < b.priority)
|
|
988
|
+
return -1;
|
|
989
|
+
if (a.priority > b.priority)
|
|
990
|
+
return 1;
|
|
991
|
+
return 0;
|
|
992
|
+
})
|
|
993
|
+
.map((e) => {
|
|
994
|
+
return {
|
|
995
|
+
id: e.id,
|
|
996
|
+
name: EDITORS[e.id],
|
|
997
|
+
};
|
|
998
|
+
}));
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
return editors;
|
|
1002
|
+
}
|
|
1003
|
+
async function isEditorSupported(editorId) {
|
|
1004
|
+
let isSupported = false;
|
|
1005
|
+
try {
|
|
1006
|
+
await openInEditorApi__default['default'].editors[editorId].detect();
|
|
1007
|
+
isSupported = true;
|
|
1008
|
+
}
|
|
1009
|
+
catch (e) { }
|
|
1010
|
+
return isSupported;
|
|
1011
|
+
}
|
|
1012
|
+
const EDITORS = {
|
|
1013
|
+
atom: 'Atom',
|
|
1014
|
+
code: 'Code',
|
|
1015
|
+
emacs: 'Emacs',
|
|
1016
|
+
idea14ce: 'IDEA 14 Community Edition',
|
|
1017
|
+
phpstorm: 'PhpStorm',
|
|
1018
|
+
sublime: 'Sublime',
|
|
1019
|
+
webstorm: 'WebStorm',
|
|
1020
|
+
vim: 'Vim',
|
|
1021
|
+
visualstudio: 'Visual Studio',
|
|
1022
|
+
};
|
|
1023
|
+
const EDITOR_PRIORITY = {
|
|
1024
|
+
code: 1,
|
|
1025
|
+
atom: 2,
|
|
1026
|
+
sublime: 3,
|
|
1027
|
+
visualstudio: 4,
|
|
1028
|
+
idea14ce: 5,
|
|
1029
|
+
webstorm: 6,
|
|
1030
|
+
phpstorm: 7,
|
|
1031
|
+
vim: 8,
|
|
1032
|
+
emacs: 9,
|
|
1602
1033
|
};
|
|
1603
1034
|
|
|
1604
|
-
function
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1035
|
+
async function serveFile(devServerConfig, serverCtx, req, res) {
|
|
1036
|
+
try {
|
|
1037
|
+
if (isSimpleText(req.filePath)) {
|
|
1038
|
+
// easy text file, use the internal cache
|
|
1039
|
+
let content = await serverCtx.sys.readFile(req.filePath, 'utf8');
|
|
1040
|
+
if (devServerConfig.websocket && isHtmlFile(req.filePath) && !isDevServerClient(req.pathname)) {
|
|
1041
|
+
// auto inject our dev server script
|
|
1042
|
+
content = appendDevServerClientScript(devServerConfig, req, content);
|
|
1043
|
+
}
|
|
1044
|
+
else if (isCssFile(req.filePath)) {
|
|
1045
|
+
content = updateStyleUrls(req.url, content);
|
|
1046
|
+
}
|
|
1047
|
+
if (shouldCompress(devServerConfig, req)) {
|
|
1048
|
+
// let's gzip this well known web dev text file
|
|
1049
|
+
res.writeHead(200, responseHeaders({
|
|
1050
|
+
'content-type': getContentType(req.filePath) + '; charset=utf-8',
|
|
1051
|
+
'content-encoding': 'gzip',
|
|
1052
|
+
vary: 'Accept-Encoding',
|
|
1053
|
+
}));
|
|
1054
|
+
zlib__namespace.gzip(content, { level: 9 }, (_, data) => {
|
|
1055
|
+
res.end(data);
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
else {
|
|
1059
|
+
// let's not gzip this file
|
|
1060
|
+
res.writeHead(200, responseHeaders({
|
|
1061
|
+
'content-type': getContentType(req.filePath) + '; charset=utf-8',
|
|
1062
|
+
'content-length': buffer.Buffer.byteLength(content, 'utf8'),
|
|
1063
|
+
}));
|
|
1064
|
+
res.write(content);
|
|
1065
|
+
res.end();
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
// non-well-known text file or other file, probably best we use a stream
|
|
1070
|
+
// but don't bother trying to gzip this file for the dev server
|
|
1071
|
+
res.writeHead(200, responseHeaders({
|
|
1072
|
+
'content-type': getContentType(req.filePath),
|
|
1073
|
+
'content-length': req.stats.size,
|
|
1074
|
+
}));
|
|
1075
|
+
fs__default$1['default'].createReadStream(req.filePath).pipe(res);
|
|
1076
|
+
}
|
|
1077
|
+
serverCtx.logRequest(req, 200);
|
|
1078
|
+
}
|
|
1079
|
+
catch (e) {
|
|
1080
|
+
serverCtx.serve500(req, res, e, 'serveFile');
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
function updateStyleUrls(url, oldCss) {
|
|
1084
|
+
const versionId = url.searchParams.get('s-hmr');
|
|
1085
|
+
const hmrUrls = url.searchParams.get('s-hmr-urls');
|
|
1086
|
+
if (versionId && hmrUrls) {
|
|
1087
|
+
hmrUrls.split(',').forEach((hmrUrl) => {
|
|
1088
|
+
urlVersionIds.set(hmrUrl, versionId);
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
const reg = /url\((['"]?)(.*)\1\)/gi;
|
|
1092
|
+
let result;
|
|
1093
|
+
let newCss = oldCss;
|
|
1094
|
+
while ((result = reg.exec(oldCss)) !== null) {
|
|
1095
|
+
const oldUrl = result[2];
|
|
1096
|
+
const parsedUrl = new URL(oldUrl, url);
|
|
1097
|
+
const fileName = path__default['default'].basename(parsedUrl.pathname);
|
|
1098
|
+
const versionId = urlVersionIds.get(fileName);
|
|
1099
|
+
if (!versionId) {
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
parsedUrl.searchParams.set('s-hmr', versionId);
|
|
1103
|
+
newCss = newCss.replace(oldUrl, parsedUrl.pathname);
|
|
1104
|
+
}
|
|
1105
|
+
return newCss;
|
|
1106
|
+
}
|
|
1107
|
+
const urlVersionIds = new Map();
|
|
1108
|
+
function appendDevServerClientScript(devServerConfig, req, content) {
|
|
1109
|
+
var _a, _b, _c;
|
|
1110
|
+
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']);
|
|
1111
|
+
const iframe = `<iframe title="Stencil Dev Server Connector ${version} ⚡" src="${devServerClientUrl}" style="display:block;width:0;height:0;border:0;visibility:hidden" aria-hidden="true"></iframe>`;
|
|
1112
|
+
return appendDevServerClientIframe(content, iframe);
|
|
1113
|
+
}
|
|
1114
|
+
function appendDevServerClientIframe(content, iframe) {
|
|
1115
|
+
if (content.includes('</body>')) {
|
|
1116
|
+
return content.replace('</body>', `${iframe}</body>`);
|
|
1117
|
+
}
|
|
1118
|
+
if (content.includes('</html>')) {
|
|
1119
|
+
return content.replace('</html>', `${iframe}</html>`);
|
|
1120
|
+
}
|
|
1121
|
+
return `${content}${iframe}`;
|
|
1122
|
+
}
|
|
1608
1123
|
|
|
1609
|
-
|
|
1124
|
+
async function serveDevClient(devServerConfig, serverCtx, req, res) {
|
|
1125
|
+
try {
|
|
1126
|
+
if (isOpenInEditor(req.pathname)) {
|
|
1127
|
+
return serveOpenInEditor(serverCtx, req, res);
|
|
1128
|
+
}
|
|
1129
|
+
if (isDevServerClient(req.pathname)) {
|
|
1130
|
+
return serveDevClientScript(devServerConfig, serverCtx, req, res);
|
|
1131
|
+
}
|
|
1132
|
+
if (isInitialDevServerLoad(req.pathname)) {
|
|
1133
|
+
req.filePath = path__default['default'].join(devServerConfig.devServerDir, 'templates', 'initial-load.html');
|
|
1134
|
+
}
|
|
1135
|
+
else {
|
|
1136
|
+
const staticFile = req.pathname.replace(DEV_SERVER_URL + '/', '');
|
|
1137
|
+
req.filePath = path__default['default'].join(devServerConfig.devServerDir, 'static', staticFile);
|
|
1138
|
+
}
|
|
1139
|
+
try {
|
|
1140
|
+
req.stats = await serverCtx.sys.stat(req.filePath);
|
|
1141
|
+
if (req.stats.isFile) {
|
|
1142
|
+
return serveFile(devServerConfig, serverCtx, req, res);
|
|
1143
|
+
}
|
|
1144
|
+
return serverCtx.serve404(req, res, 'serveDevClient not file');
|
|
1145
|
+
}
|
|
1146
|
+
catch (e) {
|
|
1147
|
+
return serverCtx.serve404(req, res, `serveDevClient stats error ${e}`);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
catch (e) {
|
|
1151
|
+
return serverCtx.serve500(req, res, e, 'serveDevClient');
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
async function serveDevClientScript(devServerConfig, serverCtx, req, res) {
|
|
1155
|
+
try {
|
|
1156
|
+
if (serverCtx.connectorHtml == null) {
|
|
1157
|
+
const filePath = path__default['default'].join(devServerConfig.devServerDir, 'connector.html');
|
|
1158
|
+
serverCtx.connectorHtml = serverCtx.sys.readFileSync(filePath, 'utf8');
|
|
1159
|
+
if (typeof serverCtx.connectorHtml !== 'string') {
|
|
1160
|
+
return serverCtx.serve404(req, res, `serveDevClientScript`);
|
|
1161
|
+
}
|
|
1162
|
+
const devClientConfig = {
|
|
1163
|
+
basePath: devServerConfig.basePath,
|
|
1164
|
+
editors: await getEditors(),
|
|
1165
|
+
reloadStrategy: devServerConfig.reloadStrategy,
|
|
1166
|
+
};
|
|
1167
|
+
serverCtx.connectorHtml = serverCtx.connectorHtml.replace('window.__DEV_CLIENT_CONFIG__', JSON.stringify(devClientConfig));
|
|
1168
|
+
}
|
|
1169
|
+
res.writeHead(200, responseHeaders({
|
|
1170
|
+
'content-type': 'text/html; charset=utf-8',
|
|
1171
|
+
}));
|
|
1172
|
+
res.write(serverCtx.connectorHtml);
|
|
1173
|
+
res.end();
|
|
1174
|
+
}
|
|
1175
|
+
catch (e) {
|
|
1176
|
+
return serverCtx.serve500(req, res, e, `serveDevClientScript`);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1610
1179
|
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1180
|
+
async function serveDevNodeModule(serverCtx, req, res) {
|
|
1181
|
+
try {
|
|
1182
|
+
const results = await serverCtx.getCompilerRequest(req.pathname);
|
|
1183
|
+
const headers = {
|
|
1184
|
+
'content-type': 'application/javascript; charset=utf-8',
|
|
1185
|
+
'content-length': Buffer.byteLength(results.content, 'utf8'),
|
|
1186
|
+
'x-dev-node-module-id': results.nodeModuleId,
|
|
1187
|
+
'x-dev-node-module-version': results.nodeModuleVersion,
|
|
1188
|
+
'x-dev-node-module-resolved-path': results.nodeResolvedPath,
|
|
1189
|
+
'x-dev-node-module-cache-path': results.cachePath,
|
|
1190
|
+
'x-dev-node-module-cache-hit': results.cacheHit,
|
|
1191
|
+
};
|
|
1192
|
+
res.writeHead(results.status, responseHeaders(headers));
|
|
1193
|
+
res.write(results.content);
|
|
1194
|
+
res.end();
|
|
1195
|
+
}
|
|
1196
|
+
catch (e) {
|
|
1197
|
+
serverCtx.serve500(req, res, e, `serveDevNodeModule`);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1614
1200
|
|
|
1615
|
-
|
|
1201
|
+
async function serveDirectoryIndex(devServerConfig, serverCtx, req, res) {
|
|
1202
|
+
const indexFilePath = path__default['default'].join(req.filePath, 'index.html');
|
|
1203
|
+
req.stats = await serverCtx.sys.stat(indexFilePath);
|
|
1204
|
+
if (req.stats.isFile) {
|
|
1205
|
+
req.filePath = indexFilePath;
|
|
1206
|
+
return serveFile(devServerConfig, serverCtx, req, res);
|
|
1207
|
+
}
|
|
1208
|
+
if (!req.pathname.endsWith('/')) {
|
|
1209
|
+
return serverCtx.serve302(req, res, req.pathname + '/');
|
|
1210
|
+
}
|
|
1211
|
+
try {
|
|
1212
|
+
const dirFilePaths = await serverCtx.sys.readDir(req.filePath);
|
|
1213
|
+
try {
|
|
1214
|
+
if (serverCtx.dirTemplate == null) {
|
|
1215
|
+
const dirTemplatePath = path__default['default'].join(devServerConfig.devServerDir, 'templates', 'directory-index.html');
|
|
1216
|
+
serverCtx.dirTemplate = serverCtx.sys.readFileSync(dirTemplatePath);
|
|
1217
|
+
}
|
|
1218
|
+
const files = await getFiles(serverCtx.sys, req.url, dirFilePaths);
|
|
1219
|
+
const templateHtml = serverCtx.dirTemplate
|
|
1220
|
+
.replace('{{title}}', getTitle(req.pathname))
|
|
1221
|
+
.replace('{{nav}}', getName(req.pathname))
|
|
1222
|
+
.replace('{{files}}', files);
|
|
1223
|
+
serverCtx.logRequest(req, 200);
|
|
1224
|
+
res.writeHead(200, responseHeaders({
|
|
1225
|
+
'content-type': 'text/html; charset=utf-8',
|
|
1226
|
+
'x-directory-index': req.pathname,
|
|
1227
|
+
}));
|
|
1228
|
+
res.write(templateHtml);
|
|
1229
|
+
res.end();
|
|
1230
|
+
}
|
|
1231
|
+
catch (e) {
|
|
1232
|
+
return serverCtx.serve500(req, res, e, 'serveDirectoryIndex');
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
catch (e) {
|
|
1236
|
+
return serverCtx.serve404(req, res, 'serveDirectoryIndex');
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
async function getFiles(sys, baseUrl, dirItemNames) {
|
|
1240
|
+
const items = await getDirectoryItems(sys, baseUrl, dirItemNames);
|
|
1241
|
+
if (baseUrl.pathname !== '/') {
|
|
1242
|
+
items.unshift({
|
|
1243
|
+
isDirectory: true,
|
|
1244
|
+
pathname: '../',
|
|
1245
|
+
name: '..',
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
return items
|
|
1249
|
+
.map((item) => {
|
|
1250
|
+
return `
|
|
1251
|
+
<li class="${item.isDirectory ? 'directory' : 'file'}">
|
|
1252
|
+
<a href="${item.pathname}">
|
|
1253
|
+
<span class="icon"></span>
|
|
1254
|
+
<span>${item.name}</span>
|
|
1255
|
+
</a>
|
|
1256
|
+
</li>`;
|
|
1257
|
+
})
|
|
1258
|
+
.join('');
|
|
1259
|
+
}
|
|
1260
|
+
async function getDirectoryItems(sys, baseUrl, dirFilePaths) {
|
|
1261
|
+
const items = await Promise.all(dirFilePaths.map(async (dirFilePath) => {
|
|
1262
|
+
const fileName = path__default['default'].basename(dirFilePath);
|
|
1263
|
+
const url = new URL(fileName, baseUrl);
|
|
1264
|
+
const stats = await sys.stat(dirFilePath);
|
|
1265
|
+
const item = {
|
|
1266
|
+
name: fileName,
|
|
1267
|
+
pathname: url.pathname,
|
|
1268
|
+
isDirectory: stats.isDirectory,
|
|
1269
|
+
};
|
|
1270
|
+
return item;
|
|
1271
|
+
}));
|
|
1272
|
+
return items;
|
|
1273
|
+
}
|
|
1274
|
+
function getTitle(pathName) {
|
|
1275
|
+
return pathName;
|
|
1276
|
+
}
|
|
1277
|
+
function getName(pathName) {
|
|
1278
|
+
const dirs = pathName.split('/');
|
|
1279
|
+
dirs.pop();
|
|
1280
|
+
let url = '';
|
|
1281
|
+
return (dirs
|
|
1282
|
+
.map((dir, index) => {
|
|
1283
|
+
url += dir + '/';
|
|
1284
|
+
const text = index === 0 ? `~` : dir;
|
|
1285
|
+
return `<a href="${url}">${text}</a>`;
|
|
1286
|
+
})
|
|
1287
|
+
.join('<span>/</span>') + '<span>/</span>');
|
|
1616
1288
|
}
|
|
1617
1289
|
|
|
1618
|
-
function
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1290
|
+
async function ssrPageRequest(devServerConfig, serverCtx, req, res) {
|
|
1291
|
+
try {
|
|
1292
|
+
let status = 500;
|
|
1293
|
+
let content = '';
|
|
1294
|
+
const { hydrateApp, srcIndexHtml, diagnostics } = await setupHydrateApp(devServerConfig, serverCtx);
|
|
1295
|
+
if (!diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
|
|
1296
|
+
try {
|
|
1297
|
+
const opts = getSsrHydrateOptions(devServerConfig, serverCtx, req.url);
|
|
1298
|
+
const ssrResults = await hydrateApp.renderToString(srcIndexHtml, opts);
|
|
1299
|
+
diagnostics.push(...ssrResults.diagnostics);
|
|
1300
|
+
status = ssrResults.httpStatus;
|
|
1301
|
+
content = ssrResults.html;
|
|
1302
|
+
}
|
|
1303
|
+
catch (e) {
|
|
1304
|
+
catchError(diagnostics, e);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
if (diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
|
|
1308
|
+
content = getSsrErrorContent(diagnostics);
|
|
1309
|
+
status = 500;
|
|
1310
|
+
}
|
|
1311
|
+
if (devServerConfig.websocket) {
|
|
1312
|
+
content = appendDevServerClientScript(devServerConfig, req, content);
|
|
1313
|
+
}
|
|
1314
|
+
serverCtx.logRequest(req, status);
|
|
1315
|
+
res.writeHead(status, responseHeaders({
|
|
1316
|
+
'content-type': 'text/html; charset=utf-8',
|
|
1317
|
+
'content-length': Buffer.byteLength(content, 'utf8'),
|
|
1318
|
+
}));
|
|
1319
|
+
res.write(content);
|
|
1320
|
+
res.end();
|
|
1321
|
+
}
|
|
1322
|
+
catch (e) {
|
|
1323
|
+
serverCtx.serve500(req, res, e, `ssrPageRequest`);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
async function ssrStaticDataRequest(devServerConfig, serverCtx, req, res) {
|
|
1327
|
+
try {
|
|
1328
|
+
const data = {};
|
|
1329
|
+
let httpCache = false;
|
|
1330
|
+
const { hydrateApp, srcIndexHtml, diagnostics } = await setupHydrateApp(devServerConfig, serverCtx);
|
|
1331
|
+
if (!diagnostics.some((diagnostic) => diagnostic.level === 'error')) {
|
|
1332
|
+
try {
|
|
1333
|
+
const { ssrPath, hasQueryString } = getSsrStaticDataPath(req);
|
|
1334
|
+
const url = new URL(ssrPath, req.url);
|
|
1335
|
+
const opts = getSsrHydrateOptions(devServerConfig, serverCtx, url);
|
|
1336
|
+
const ssrResults = await hydrateApp.renderToString(srcIndexHtml, opts);
|
|
1337
|
+
diagnostics.push(...ssrResults.diagnostics);
|
|
1338
|
+
ssrResults.staticData.forEach((s) => {
|
|
1339
|
+
if (s.type === 'application/json') {
|
|
1340
|
+
data[s.id] = JSON.parse(s.content);
|
|
1341
|
+
}
|
|
1342
|
+
else {
|
|
1343
|
+
data[s.id] = s.content;
|
|
1344
|
+
}
|
|
1345
|
+
});
|
|
1346
|
+
data.components = ssrResults.components.map((c) => c.tag).sort();
|
|
1347
|
+
httpCache = hasQueryString;
|
|
1348
|
+
}
|
|
1349
|
+
catch (e) {
|
|
1350
|
+
catchError(diagnostics, e);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
if (diagnostics.length > 0) {
|
|
1354
|
+
data.diagnostics = diagnostics;
|
|
1355
|
+
}
|
|
1356
|
+
const status = diagnostics.some((diagnostic) => diagnostic.level === 'error') ? 500 : 200;
|
|
1357
|
+
const content = JSON.stringify(data);
|
|
1358
|
+
serverCtx.logRequest(req, status);
|
|
1359
|
+
res.writeHead(status, responseHeaders({
|
|
1360
|
+
'content-type': 'application/json; charset=utf-8',
|
|
1361
|
+
'content-length': Buffer.byteLength(content, 'utf8'),
|
|
1362
|
+
}, httpCache && status === 200));
|
|
1363
|
+
res.write(content);
|
|
1364
|
+
res.end();
|
|
1365
|
+
}
|
|
1366
|
+
catch (e) {
|
|
1367
|
+
serverCtx.serve500(req, res, e, `ssrStaticDataRequest`);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
async function setupHydrateApp(devServerConfig, serverCtx) {
|
|
1371
|
+
let srcIndexHtml = null;
|
|
1372
|
+
let hydrateApp = null;
|
|
1373
|
+
const buildResults = await serverCtx.getBuildResults();
|
|
1374
|
+
const diagnostics = [];
|
|
1375
|
+
if (serverCtx.prerenderConfig == null && isString(devServerConfig.prerenderConfig)) {
|
|
1376
|
+
const compilerPath = path__default['default'].join(devServerConfig.devServerDir, '..', 'compiler', 'stencil.js');
|
|
1377
|
+
const compiler = require(compilerPath);
|
|
1378
|
+
const prerenderConfigResults = compiler.nodeRequire(devServerConfig.prerenderConfig);
|
|
1379
|
+
diagnostics.push(...prerenderConfigResults.diagnostics);
|
|
1380
|
+
if (prerenderConfigResults.module && prerenderConfigResults.module.config) {
|
|
1381
|
+
serverCtx.prerenderConfig = prerenderConfigResults.module.config;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
if (!isString(buildResults.hydrateAppFilePath)) {
|
|
1385
|
+
diagnostics.push({ messageText: `Missing hydrateAppFilePath`, level: `error`, type: `ssr` });
|
|
1386
|
+
}
|
|
1387
|
+
else if (!isString(devServerConfig.srcIndexHtml)) {
|
|
1388
|
+
diagnostics.push({ messageText: `Missing srcIndexHtml`, level: `error`, type: `ssr` });
|
|
1389
|
+
}
|
|
1390
|
+
else {
|
|
1391
|
+
srcIndexHtml = await serverCtx.sys.readFile(devServerConfig.srcIndexHtml);
|
|
1392
|
+
if (!isString(srcIndexHtml)) {
|
|
1393
|
+
diagnostics.push({
|
|
1394
|
+
messageText: `Unable to load src index html: ${devServerConfig.srcIndexHtml}`,
|
|
1395
|
+
level: `error`,
|
|
1396
|
+
type: `ssr`,
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
else {
|
|
1400
|
+
// ensure we cleared out node's internal require() cache for this file
|
|
1401
|
+
const hydrateAppFilePath = path__default['default'].resolve(buildResults.hydrateAppFilePath);
|
|
1402
|
+
// brute force way of clearning node's module cache
|
|
1403
|
+
// not using `delete require.cache[id]` since it'll cause memory leaks
|
|
1404
|
+
require.cache = {};
|
|
1405
|
+
const Module = require('module');
|
|
1406
|
+
Module._cache[hydrateAppFilePath] = undefined;
|
|
1407
|
+
hydrateApp = require(hydrateAppFilePath);
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
return {
|
|
1411
|
+
hydrateApp,
|
|
1412
|
+
srcIndexHtml,
|
|
1413
|
+
diagnostics,
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
function getSsrHydrateOptions(devServerConfig, serverCtx, url) {
|
|
1417
|
+
const opts = {
|
|
1418
|
+
url: url.href,
|
|
1419
|
+
addModulePreloads: false,
|
|
1420
|
+
approximateLineWidth: 120,
|
|
1421
|
+
inlineExternalStyleSheets: false,
|
|
1422
|
+
minifyScriptElements: false,
|
|
1423
|
+
minifyStyleElements: false,
|
|
1424
|
+
removeAttributeQuotes: false,
|
|
1425
|
+
removeBooleanAttributeQuotes: false,
|
|
1426
|
+
removeEmptyAttributes: false,
|
|
1427
|
+
removeHtmlComments: false,
|
|
1428
|
+
prettyHtml: true,
|
|
1429
|
+
};
|
|
1430
|
+
const prerenderConfig = serverCtx === null || serverCtx === void 0 ? void 0 : serverCtx.prerenderConfig;
|
|
1431
|
+
if (isFunction(prerenderConfig === null || prerenderConfig === void 0 ? void 0 : prerenderConfig.hydrateOptions)) {
|
|
1432
|
+
const userOpts = prerenderConfig.hydrateOptions(url);
|
|
1433
|
+
if (userOpts) {
|
|
1434
|
+
Object.assign(opts, userOpts);
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
if (isFunction(serverCtx.sys.applyPrerenderGlobalPatch)) {
|
|
1438
|
+
const orgBeforeHydrate = opts.beforeHydrate;
|
|
1439
|
+
opts.beforeHydrate = (document) => {
|
|
1440
|
+
// patch this new window with the fetch global from node-fetch
|
|
1441
|
+
const devServerBaseUrl = new URL(devServerConfig.browserUrl);
|
|
1442
|
+
const devServerHostUrl = devServerBaseUrl.origin;
|
|
1443
|
+
serverCtx.sys.applyPrerenderGlobalPatch({
|
|
1444
|
+
devServerHostUrl: devServerHostUrl,
|
|
1445
|
+
window: document.defaultView,
|
|
1446
|
+
});
|
|
1447
|
+
if (typeof orgBeforeHydrate === 'function') {
|
|
1448
|
+
return orgBeforeHydrate(document);
|
|
1449
|
+
}
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
return opts;
|
|
1453
|
+
}
|
|
1454
|
+
function getSsrErrorContent(diagnostics) {
|
|
1455
|
+
return `<!doctype html>
|
|
1456
|
+
<html>
|
|
1457
|
+
<head>
|
|
1458
|
+
<title>SSR Error</title>
|
|
1459
|
+
<style>
|
|
1460
|
+
body {
|
|
1461
|
+
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace !important;
|
|
1462
|
+
}
|
|
1463
|
+
</style>
|
|
1464
|
+
</head>
|
|
1465
|
+
<body>
|
|
1466
|
+
<h1>SSR Dev Error</h1>
|
|
1467
|
+
${diagnostics.map((diagnostic) => `
|
|
1468
|
+
<p>
|
|
1469
|
+
${diagnostic.messageText}
|
|
1470
|
+
</p>
|
|
1471
|
+
`)}
|
|
1472
|
+
</body>
|
|
1473
|
+
</html>`;
|
|
1628
1474
|
}
|
|
1629
1475
|
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
}
|
|
1648
|
-
|
|
1649
|
-
})
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1476
|
+
function createRequestHandler(devServerConfig, serverCtx) {
|
|
1477
|
+
let userRequestHandler = null;
|
|
1478
|
+
if (typeof devServerConfig.requestListenerPath === 'string') {
|
|
1479
|
+
userRequestHandler = require(devServerConfig.requestListenerPath);
|
|
1480
|
+
}
|
|
1481
|
+
return async function (incomingReq, res) {
|
|
1482
|
+
async function defaultHandler() {
|
|
1483
|
+
try {
|
|
1484
|
+
const req = normalizeHttpRequest(devServerConfig, incomingReq);
|
|
1485
|
+
if (!req.url) {
|
|
1486
|
+
return serverCtx.serve302(req, res);
|
|
1487
|
+
}
|
|
1488
|
+
if (isDevClient(req.pathname) && devServerConfig.websocket) {
|
|
1489
|
+
return serveDevClient(devServerConfig, serverCtx, req, res);
|
|
1490
|
+
}
|
|
1491
|
+
if (isDevModule(req.pathname)) {
|
|
1492
|
+
return serveDevNodeModule(serverCtx, req, res);
|
|
1493
|
+
}
|
|
1494
|
+
if (!isValidUrlBasePath(devServerConfig.basePath, req.url)) {
|
|
1495
|
+
return serverCtx.serve404(req, res, `invalid basePath`, `404 File Not Found, base path: ${devServerConfig.basePath}`);
|
|
1496
|
+
}
|
|
1497
|
+
if (devServerConfig.ssr) {
|
|
1498
|
+
if (isExtensionLessPath(req.url.pathname)) {
|
|
1499
|
+
return ssrPageRequest(devServerConfig, serverCtx, req, res);
|
|
1500
|
+
}
|
|
1501
|
+
if (isSsrStaticDataPath(req.url.pathname)) {
|
|
1502
|
+
return ssrStaticDataRequest(devServerConfig, serverCtx, req, res);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
req.stats = await serverCtx.sys.stat(req.filePath);
|
|
1506
|
+
if (req.stats.isFile) {
|
|
1507
|
+
return serveFile(devServerConfig, serverCtx, req, res);
|
|
1508
|
+
}
|
|
1509
|
+
if (req.stats.isDirectory) {
|
|
1510
|
+
return serveDirectoryIndex(devServerConfig, serverCtx, req, res);
|
|
1511
|
+
}
|
|
1512
|
+
const xSource = ['notfound'];
|
|
1513
|
+
const validHistoryApi = isValidHistoryApi(devServerConfig, req);
|
|
1514
|
+
xSource.push(`validHistoryApi: ${validHistoryApi}`);
|
|
1515
|
+
if (validHistoryApi) {
|
|
1516
|
+
try {
|
|
1517
|
+
const indexFilePath = path__default['default'].join(devServerConfig.root, devServerConfig.historyApiFallback.index);
|
|
1518
|
+
xSource.push(`indexFilePath: ${indexFilePath}`);
|
|
1519
|
+
req.stats = await serverCtx.sys.stat(indexFilePath);
|
|
1520
|
+
if (req.stats.isFile) {
|
|
1521
|
+
req.filePath = indexFilePath;
|
|
1522
|
+
return serveFile(devServerConfig, serverCtx, req, res);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
catch (e) {
|
|
1526
|
+
xSource.push(`notfound error: ${e}`);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
return serverCtx.serve404(req, res, xSource.join(', '));
|
|
1530
|
+
}
|
|
1531
|
+
catch (e) {
|
|
1532
|
+
return serverCtx.serve500(incomingReq, res, e, `not found error`);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
if (typeof userRequestHandler === 'function') {
|
|
1536
|
+
await userRequestHandler(incomingReq, res, defaultHandler);
|
|
1537
|
+
}
|
|
1538
|
+
else {
|
|
1539
|
+
await defaultHandler();
|
|
1540
|
+
}
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
function isValidUrlBasePath(basePath, url) {
|
|
1544
|
+
// normalize the paths to always end with a slash for the check
|
|
1545
|
+
let pathname = url.pathname;
|
|
1546
|
+
if (!pathname.endsWith('/')) {
|
|
1547
|
+
pathname += '/';
|
|
1548
|
+
}
|
|
1549
|
+
if (!basePath.endsWith('/')) {
|
|
1550
|
+
basePath += '/';
|
|
1551
|
+
}
|
|
1552
|
+
return pathname.startsWith(basePath);
|
|
1553
|
+
}
|
|
1554
|
+
function normalizeHttpRequest(devServerConfig, incomingReq) {
|
|
1555
|
+
const req = {
|
|
1556
|
+
method: (incomingReq.method || 'GET').toUpperCase(),
|
|
1557
|
+
headers: incomingReq.headers,
|
|
1558
|
+
acceptHeader: (incomingReq.headers && typeof incomingReq.headers.accept === 'string' && incomingReq.headers.accept) || '',
|
|
1559
|
+
host: (incomingReq.headers && typeof incomingReq.headers.host === 'string' && incomingReq.headers.host) || null,
|
|
1560
|
+
url: null,
|
|
1561
|
+
searchParams: null,
|
|
1562
|
+
};
|
|
1563
|
+
const incomingUrl = (incomingReq.url || '').trim() || null;
|
|
1564
|
+
if (incomingUrl) {
|
|
1565
|
+
if (req.host) {
|
|
1566
|
+
req.url = new URL(incomingReq.url, `http://${req.host}`);
|
|
1567
|
+
}
|
|
1568
|
+
else {
|
|
1569
|
+
req.url = new URL(incomingReq.url, `http://dev.stenciljs.com`);
|
|
1570
|
+
}
|
|
1571
|
+
req.searchParams = req.url.searchParams;
|
|
1572
|
+
}
|
|
1573
|
+
if (req.url) {
|
|
1574
|
+
const parts = req.url.pathname.replace(/\\/g, '/').split('/');
|
|
1575
|
+
req.pathname = parts.map((part) => decodeURIComponent(part)).join('/');
|
|
1576
|
+
if (req.pathname.length > 0 && !isDevClient(req.pathname)) {
|
|
1577
|
+
req.pathname = '/' + req.pathname.substring(devServerConfig.basePath.length);
|
|
1578
|
+
}
|
|
1579
|
+
req.filePath = normalizePath(path__default['default'].normalize(path__default['default'].join(devServerConfig.root, path__default['default'].relative('/', req.pathname))));
|
|
1580
|
+
}
|
|
1581
|
+
return req;
|
|
1582
|
+
}
|
|
1583
|
+
function isValidHistoryApi(devServerConfig, req) {
|
|
1584
|
+
if (!devServerConfig.historyApiFallback) {
|
|
1585
|
+
return false;
|
|
1586
|
+
}
|
|
1587
|
+
if (req.method !== 'GET') {
|
|
1588
|
+
return false;
|
|
1589
|
+
}
|
|
1590
|
+
if (!req.acceptHeader.includes('text/html')) {
|
|
1591
|
+
return false;
|
|
1592
|
+
}
|
|
1593
|
+
if (!devServerConfig.historyApiFallback.disableDotRule && req.pathname.includes('.')) {
|
|
1594
|
+
return false;
|
|
1595
|
+
}
|
|
1596
|
+
return true;
|
|
1597
|
+
}
|
|
1660
1598
|
|
|
1661
|
-
|
|
1599
|
+
function createHttpServer(devServerConfig, serverCtx) {
|
|
1600
|
+
// create our request handler
|
|
1601
|
+
const reqHandler = createRequestHandler(devServerConfig, serverCtx);
|
|
1602
|
+
const credentials = devServerConfig.https;
|
|
1603
|
+
return credentials ? https__namespace.createServer(credentials, reqHandler) : http__namespace.createServer(reqHandler);
|
|
1604
|
+
}
|
|
1605
|
+
async function findClosestOpenPort(host, port) {
|
|
1606
|
+
async function t(portToCheck) {
|
|
1607
|
+
const isTaken = await isPortTaken(host, portToCheck);
|
|
1608
|
+
if (!isTaken) {
|
|
1609
|
+
return portToCheck;
|
|
1610
|
+
}
|
|
1611
|
+
return t(portToCheck + 1);
|
|
1612
|
+
}
|
|
1613
|
+
return t(port);
|
|
1614
|
+
}
|
|
1615
|
+
function isPortTaken(host, port) {
|
|
1616
|
+
return new Promise((resolve, reject) => {
|
|
1617
|
+
const tester = net__namespace
|
|
1618
|
+
.createServer()
|
|
1619
|
+
.once('error', () => {
|
|
1620
|
+
resolve(true);
|
|
1621
|
+
})
|
|
1622
|
+
.once('listening', () => {
|
|
1623
|
+
tester
|
|
1624
|
+
.once('close', () => {
|
|
1625
|
+
resolve(false);
|
|
1626
|
+
})
|
|
1627
|
+
.close();
|
|
1628
|
+
})
|
|
1629
|
+
.on('error', (err) => {
|
|
1630
|
+
reject(err);
|
|
1631
|
+
})
|
|
1632
|
+
.listen(port, host);
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1662
1635
|
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1636
|
+
function createWebSocket(httpServer, onMessageFromClient) {
|
|
1637
|
+
const wsConfig = {
|
|
1638
|
+
server: httpServer,
|
|
1639
|
+
};
|
|
1640
|
+
const wsServer = new ws__namespace.Server(wsConfig);
|
|
1641
|
+
function heartbeat() {
|
|
1642
|
+
this.isAlive = true;
|
|
1643
|
+
}
|
|
1644
|
+
wsServer.on('connection', (ws) => {
|
|
1645
|
+
ws.on('message', (data) => {
|
|
1646
|
+
// the server process has received a message from the browser
|
|
1647
|
+
// pass the message received from the browser to the main cli process
|
|
1648
|
+
try {
|
|
1649
|
+
onMessageFromClient(JSON.parse(data.toString()));
|
|
1650
|
+
}
|
|
1651
|
+
catch (e) {
|
|
1652
|
+
console.error(e);
|
|
1653
|
+
}
|
|
1654
|
+
});
|
|
1655
|
+
ws.isAlive = true;
|
|
1656
|
+
ws.on('pong', heartbeat);
|
|
1657
|
+
// ignore invalid close frames sent by Safari 15
|
|
1658
|
+
ws.on('error', console.error);
|
|
1659
|
+
});
|
|
1660
|
+
const pingInternval = setInterval(() => {
|
|
1661
|
+
wsServer.clients.forEach((ws) => {
|
|
1662
|
+
if (!ws.isAlive) {
|
|
1663
|
+
return ws.close(1000);
|
|
1664
|
+
}
|
|
1665
|
+
ws.isAlive = false;
|
|
1666
|
+
ws.ping(noop);
|
|
1667
|
+
});
|
|
1668
|
+
}, 10000);
|
|
1669
|
+
return {
|
|
1670
|
+
sendToBrowser: (msg) => {
|
|
1671
|
+
if (msg && wsServer && wsServer.clients) {
|
|
1672
|
+
const data = JSON.stringify(msg);
|
|
1673
|
+
wsServer.clients.forEach((ws) => {
|
|
1674
|
+
if (ws.readyState === ws.OPEN) {
|
|
1675
|
+
ws.send(data);
|
|
1676
|
+
}
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
},
|
|
1680
|
+
close: () => {
|
|
1681
|
+
return new Promise((resolve, reject) => {
|
|
1682
|
+
clearInterval(pingInternval);
|
|
1683
|
+
wsServer.clients.forEach((ws) => {
|
|
1684
|
+
ws.close(1000);
|
|
1685
|
+
});
|
|
1686
|
+
wsServer.close((err) => {
|
|
1687
|
+
if (err) {
|
|
1688
|
+
reject(err);
|
|
1689
|
+
}
|
|
1690
|
+
else {
|
|
1691
|
+
resolve();
|
|
1692
|
+
}
|
|
1693
|
+
});
|
|
1694
|
+
});
|
|
1695
|
+
},
|
|
1696
|
+
};
|
|
1666
1697
|
}
|
|
1667
1698
|
|
|
1668
1699
|
function initServerProcess(sendMsg) {
|