Son CV dans un terminal web en Javascript! https://terminal-cv.gregandev.fr
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

465 lines
12 KiB

1 year ago
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _url() {
const data = _interopRequireWildcard(require("url"));
_url = function () {
return data;
};
return data;
}
function _utils() {
const data = require("@parcel/utils");
_utils = function () {
return data;
};
return data;
}
var _serverErrors = _interopRequireDefault(require("./serverErrors"));
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _ejs() {
const data = _interopRequireDefault(require("ejs"));
_ejs = function () {
return data;
};
return data;
}
function _connect() {
const data = _interopRequireDefault(require("connect"));
_connect = function () {
return data;
};
return data;
}
function _serveHandler() {
const data = _interopRequireDefault(require("serve-handler"));
_serveHandler = function () {
return data;
};
return data;
}
function _httpProxyMiddleware() {
const data = require("http-proxy-middleware");
_httpProxyMiddleware = function () {
return data;
};
return data;
}
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function setHeaders(res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, PUT, PATCH, POST, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Content-Type');
}
const SOURCES_ENDPOINT = '/__parcel_source_root';
const TEMPLATE_404 = _fs().default.readFileSync(_path().default.join(__dirname, 'templates/404.html'), 'utf8');
const TEMPLATE_500 = _fs().default.readFileSync(_path().default.join(__dirname, 'templates/500.html'), 'utf8');
class Server {
constructor(options) {
this.options = options;
try {
this.rootPath = new (_url().URL)(options.publicUrl).pathname;
} catch (e) {
this.rootPath = options.publicUrl;
}
this.pending = true;
this.pendingRequests = [];
this.bundleGraph = null;
this.requestBundle = null;
this.errors = null;
}
buildStart() {
this.pending = true;
}
buildSuccess(bundleGraph, requestBundle) {
this.bundleGraph = bundleGraph;
this.requestBundle = requestBundle;
this.errors = null;
this.pending = false;
if (this.pendingRequests.length > 0) {
let pendingRequests = this.pendingRequests;
this.pendingRequests = [];
for (let [req, res] of pendingRequests) {
this.respond(req, res);
}
}
}
async buildError(options, diagnostics) {
this.pending = false;
this.errors = await Promise.all(diagnostics.map(async d => {
var _d$documentationURL;
let ansiDiagnostic = await (0, _utils().prettyDiagnostic)(d, options);
return {
message: (0, _utils().ansiHtml)(ansiDiagnostic.message),
stack: ansiDiagnostic.codeframe ? (0, _utils().ansiHtml)(ansiDiagnostic.codeframe) : (0, _utils().ansiHtml)(ansiDiagnostic.stack),
hints: ansiDiagnostic.hints.map(hint => (0, _utils().ansiHtml)(hint)),
documentation: (_d$documentationURL = d.documentationURL) !== null && _d$documentationURL !== void 0 ? _d$documentationURL : ''
};
}));
}
respond(req, res) {
let {
pathname
} = _url().default.parse(req.originalUrl || req.url);
if (pathname == null) {
pathname = '/';
}
if (this.errors) {
return this.send500(req, res);
} else if (_path().default.extname(pathname) === '') {
// If the URL doesn't start with the public path, or the URL doesn't
// have a file extension, send the main HTML bundle.
return this.sendIndex(req, res);
} else if (pathname.startsWith(SOURCES_ENDPOINT)) {
req.url = pathname.slice(SOURCES_ENDPOINT.length);
return this.serve(this.options.inputFS, this.options.projectRoot, req, res, () => this.send404(req, res));
} else if (pathname.startsWith(this.rootPath)) {
// Otherwise, serve the file from the dist folder
req.url = this.rootPath === '/' ? pathname : pathname.slice(this.rootPath.length);
if (req.url[0] !== '/') {
req.url = '/' + req.url;
}
return this.serveBundle(req, res, () => this.sendIndex(req, res));
} else {
return this.send404(req, res);
}
}
sendIndex(req, res) {
if (this.bundleGraph) {
// If the main asset is an HTML file, serve it
let htmlBundleFilePaths = [];
this.bundleGraph.traverseBundles(bundle => {
if (bundle.type === 'html' && bundle.bundleBehavior !== 'inline') {
htmlBundleFilePaths.push(bundle.filePath);
}
});
htmlBundleFilePaths = htmlBundleFilePaths.map(p => {
return `/${(0, _utils().relativePath)(this.options.distDir, p, false)}`;
});
let indexFilePath = null;
if (htmlBundleFilePaths.length === 1) {
indexFilePath = htmlBundleFilePaths[0];
} else {
indexFilePath = htmlBundleFilePaths.filter(v => {
let dir = _path().default.posix.dirname(v);
let withoutExtension = _path().default.posix.basename(v, _path().default.posix.extname(v));
return withoutExtension === 'index' && req.url.startsWith(dir);
}).sort((a, b) => {
return b.length - a.length;
})[0];
}
if (indexFilePath) {
req.url = indexFilePath;
this.serveBundle(req, res, () => this.send404(req, res));
} else {
this.send404(req, res);
}
} else {
this.send404(req, res);
}
}
async serveBundle(req, res, next) {
let bundleGraph = this.bundleGraph;
if (bundleGraph) {
let {
pathname
} = _url().default.parse(req.url);
if (!pathname) {
this.send500(req, res);
return;
}
let requestedPath = _path().default.normalize(pathname.slice(1));
let bundle = bundleGraph.getBundles().find(b => _path().default.relative(this.options.distDir, b.filePath) === requestedPath);
if (!bundle) {
this.serveDist(req, res, next);
return;
}
(0, _assert().default)(this.requestBundle != null);
try {
await this.requestBundle(bundle);
} catch (err) {
this.send500(req, res);
return;
}
this.serveDist(req, res, next);
} else {
this.send404(req, res);
}
}
serveDist(req, res, next) {
return this.serve(this.options.outputFS, this.options.distDir, req, res, next);
}
async serve(fs, root, req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') {
// method not allowed
res.statusCode = 405;
res.setHeader('Allow', 'GET, HEAD');
res.setHeader('Content-Length', '0');
res.end();
return;
}
try {
var filePath = _url().default.parse(req.url).pathname || '';
filePath = decodeURIComponent(filePath);
} catch (err) {
return this.sendError(res, 400);
}
filePath = _path().default.normalize('.' + _path().default.sep + filePath); // malicious path
if (filePath.includes(_path().default.sep + '..' + _path().default.sep)) {
return this.sendError(res, 403);
} // join / normalize from the root dir
if (!_path().default.isAbsolute(filePath)) {
filePath = _path().default.normalize(_path().default.join(root, filePath));
}
try {
var stat = await fs.stat(filePath);
} catch (err) {
if (err.code === 'ENOENT') {
return next(req, res);
}
return this.sendError(res, 500);
} // Fall back to next handler if not a file
if (!stat || !stat.isFile()) {
return next(req, res);
}
if (req.method === 'HEAD') {
res.end();
return;
}
return (0, _serveHandler().default)(req, res, {
public: root,
cleanUrls: false
}, {
lstat: path => fs.stat(path),
realpath: path => fs.realpath(path),
createReadStream: (path, options) => fs.createReadStream(path, options),
readdir: path => fs.readdir(path)
});
}
sendError(res, statusCode) {
res.statusCode = statusCode;
setHeaders(res);
res.end();
}
send404(req, res) {
res.statusCode = 404;
setHeaders(res);
res.end(TEMPLATE_404);
}
send500(req, res) {
setHeaders(res);
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.writeHead(500);
if (this.errors) {
return res.end(_ejs().default.render(TEMPLATE_500, {
errors: this.errors
}));
}
}
logAccessIfVerbose(req) {
this.options.logger.verbose({
message: `Request: ${req.headers.host}${req.originalUrl || req.url}`
});
}
/**
* Load proxy table from package.json and apply them.
*/
async applyProxyTable(app) {
// avoid skipping project root
const fileInRoot = _path().default.join(this.options.projectRoot, '_');
const pkg = await (0, _utils().loadConfig)(this.options.inputFS, fileInRoot, ['.proxyrc.js', '.proxyrc', '.proxyrc.json'], this.options.projectRoot);
if (!pkg || !pkg.config || !pkg.files) {
return this;
}
const cfg = pkg.config;
const filename = _path().default.basename(pkg.files[0].filePath);
if (filename === '.proxyrc.js') {
if (typeof cfg !== 'function') {
this.options.logger.warn({
message: "Proxy configuration file '.proxyrc.js' should export a function. Skipping..."
});
return this;
}
cfg(app);
} else if (filename === '.proxyrc' || filename === '.proxyrc.json') {
if (typeof cfg !== 'object') {
this.options.logger.warn({
message: "Proxy table in '.proxyrc' should be of object type. Skipping..."
});
return this;
}
for (const [context, options] of Object.entries(cfg)) {
// each key is interpreted as context, and value as middleware options
app.use((0, _httpProxyMiddleware().createProxyMiddleware)(context, options));
}
}
return this;
}
async start() {
const app = (0, _connect().default)();
app.use((req, res, next) => {
setHeaders(res);
next();
});
await this.applyProxyTable(app);
app.use((req, res) => {
this.logAccessIfVerbose(req); // Wait for the parcelInstance to finish bundling if needed
if (this.pending) {
this.pendingRequests.push([req, res]);
} else {
this.respond(req, res);
}
});
let {
server,
stop
} = await (0, _utils().createHTTPServer)({
cacheDir: this.options.cacheDir,
https: this.options.https,
inputFS: this.options.inputFS,
listener: app,
outputFS: this.options.outputFS,
host: this.options.host
});
this.stopServer = stop;
server.listen(this.options.port, this.options.host);
return new Promise((resolve, reject) => {
server.once('error', err => {
this.options.logger.error({
message: (0, _serverErrors.default)(err, this.options.port)
});
reject(err);
});
server.once('listening', () => {
resolve(server);
});
});
}
async stop() {
(0, _assert().default)(this.stopServer != null);
await this.stopServer();
this.stopServer = null;
}
}
exports.default = Server;