var o={
optionsTimeout:{
// Optional. This will be the default timeout for all endpoints.
// If omitted there is no default timeout on endpoints
timeout: 45000,
// Optional. This function will be called on a timeout and it MUST
// terminate the request.
// If omitted the module will end the request with a default 503 error.
onTimeout: function(req, res) {
res.status(503)
.send(`<h1>Timeout requesting '${req.host}${req.url}' or not found!</h1>`
+ `<a href="${req.host}${req.url}">retry...</a><br />`
+ `<a href="/">CDN Home</a><br />`
+ `<br /><br />`
// + `${JSON.stringify(req.EXTRA)}<br />`
);
},
// Optional. Define a function to be called if an attempt to send a response
// happens after the timeout where:
// - method: is the method that was called on the response object
// - args: are the arguments passed to the method
// - requestTime: is the duration of the request
// timeout happened
onDelayedResponse: function(req, method, args, requestTime) {
console.log(`Attempted to call ${method} after timeout`);
},
// Optional. Provide a list of which methods should be disabled on the
// response object when a timeout happens and an error has been sent. If
// omitted, a default list of all methods that tries to send a response
// will be disable on the response object
disable: ['write', 'setHeaders', 'send', 'json', 'end']
}//optionsTimeout
};
((o)=>{
'use strict';
var optionsTimeout = o.optionsTimeout;
var Application = exports = (module && module.exports) ? module.exports : {};
var Base64 = require('js-base64');
var b64 = require('url-safe-base64');
var {
encode, decode, trim,
isBase64, isUrlSafeBase64
} = b64;
const Module = require('module')
const os = require('os')
const express = require('express')
const timeout = require('express-timeout-handler');
//require('node-libs-browser'); // explicit import for runkit.com
var webpack = require('webpack');
var { Plugin } =webpack;
//var webpackSandboxed =require('webpack-sandboxed');
var webpackSandboxed =require('webpack-sandboxed').default;
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const debug=require('debug');
const path=require('path');
var DirectoryNamedWebpackPlugin = require("directory-named-webpack-plugin");
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const babel=require('@babel/core');
const fs_browser=require('codesandbox-browserfs');
const babelLoader= require('babel-loader');
debug('*');
var jsCode = `
exports=module.exports=new Error('Code not set in webfantized-webpack');
`;
var bodyParser = require('body-parser');
var { vol } = require('memfs')
var { patchFs, patchRequire } = require('fs-monkey')
var { VM, NodeVM, VMScript } = require('vm2')
var { ufs } = require('unionfs')
var fs = require('fs')
console.log('__dirname', __dirname)
console.log('process.cwd', process.cwd())
console.log('process.env', process.env)
console.log('Buffer',Buffer);
var app = Application.app = runkitExpress(Application)
app.use(timeout.handler(optionsTimeout));
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
Application.app.post('/webpack/', function(req, res, next)
{
var mode =req.body.mode || 'code';
var payload =req.body.code || jsCode;
// try{
/*var code =(isBase64(payload) || isUrlSafeBase64(payload) || !/[\s|\{|\}|\;|\,|\.]/.test(payload))
? decode(payload) : payload;*/
/* var code = Buffer.from(payload, 'base64').toString('ascii');*/
/* var code= decode(payload);*/
// }catch(fehler){
//return next(payload);
// }
var code =payload;
var __packages =(req.body.dependencies || '').split(/[\,\;\s]/);
if(code){
main(code, __packages).then(result=>{
if('code'===mode){
res.header['content-type']='application/javascript';
res.end(result.compiled);
}else if('meta'===mode){
res.header['content-type']='application/json';
res.json({
main: result.key,
// entry: result.compiled,
bundle: result.bundle,
// stats: result.stats//,
// exported: result.exported
link : '/webpack/'
+Buffer.from(code).toString('base64')+'/'
+__packages.join(',')
//+'/meta'
});
}else{
next('Invalid mode parameter');
}
}).catch(next);
}else{
next('Invalid code parameter');
}
});
Application.app.get('/webpack/:payload?/:dependencies?/:mode?', function(req, res, next)
{
var mode =req.params.mode || 'code';
var payload =req.params.payload || jsCode;
// try{
var code =(isBase64(payload) || isUrlSafeBase64(payload) || !/[\s|\{|\}|\;|\,|\.]/.test(payload))
? Base64.decode(payload) : payload;
/* var code = Buffer.from(payload, 'base64').toString('ascii');*/
/* var code= decode(payload);*/
// }catch(fehler){
//return next(payload);
// }
/* var code=payload;*/
var __packages =(req.params.dependencies || '').split(/[\,\;\s]/);
if(code){
main(code, __packages).then(result=>{
if('code'===mode){
res.header['content-type']='application/javascript';
res.end(result.compiled);
}else if('meta'===mode){
res.header['content-type']='application/json';
res.json({
main: result.key,
// entry: result.compiled,
bundle: result.bundle//,
// stats: result.stats//,
// exported: result.exported
});
}else{
next('Invalid mode parameter');
}
}).catch(next);
}else{
next('Invalid code parameter');
}
});
function runkitExpress(anExport)
{
var mount = express();
var app = express();
// app.use(timeout.handler(optionsTimeout));
// "mount" is our root app, and it mounts "app" at your notebook path
// which is available in the RUNKIT_MOUNT_PATH environment variable
mount.use(process.env.RUNKIT_MOUNT_PATH || "", app);
if (anExport) {
anExport.endpoint = mount;
}
// overwrite .listen since it is not needed
app.listen = function(){}
// return the express instance for use by the caller
return app;
}
function requireFromString(code, filename, opts, Module) {
// var path = require('path');
if (typeof filename === 'object') {
opts = filename;
filename = undefined;
}
if (typeof Module === 'undefined') {
var Module = require('module');
}
opts = opts || {};
filename = filename || '';
opts.appendPaths = opts.appendPaths || [];
opts.prependPaths = opts.prependPaths || [];
if (typeof code !== 'string') {
throw new Error('code must be a string, not ' + typeof code);
}
var paths = Module._nodeModulePaths(path.dirname(filename));
var parent = module.parent;
var m = new Module(filename, parent);
m.filename = filename;
m.paths = [].concat(opts.prependPaths).concat(paths).concat(opts.appendPaths);
m._compile(code, filename);
var exports = m.exports;
parent && parent.children && parent.children.splice(parent.children.indexOf(m), 1);
return exports;
}
function handlePathsLogger(err, paths) {
if(err){
return ((e)=>{throw e;})(err)
}
var relPaths = paths.map(curPath => {
return path.relative('~/', curPath);
});
relPaths = relPaths.sort();
console.log('paths', paths);
console.log('relPaths', relPaths);
}
function dependencies(){
/*
require('@frdl/eventemitter');
require('ready');
require('@babel/preset-env');
require('co');
require('@types/memory-fs');
require('memory-fs');
require('resolve');
require('express');
require('@types/debug');
require('@types/extract-text-webpack-plugin');
require('@types/jest');
require('@types/resolve');
require('@types/webpack');
require('@babel/core');
require('babel-loader');
require('babel-preset-es2015');
require('babel-preset-react');
require('css-loader');
*/
require('@babel/core');
require('codesandbox-browserfs');
// require('babel-preset-es2015');
// require('babel-preset-react');
}
function dependenciesBrowser(){
require('node-libs-browser');
require('insertion-query');
require('on-idle');
}
function main(_code, __packages, _modulesFolders, _plugins) {
return new Promise(async function(resolve,reject){
//return await jsCode;
//(code, modulesFolders, plugins)
var modulesFolders =_modulesFolders ||
[
// path.resolve(__dirname, '.'),
// path.resolve(__dirname, 'node_modules'),
// 'node_modules'
];
const productionPlugins= _plugins || [
new ExtractTextPlugin('[name].[contenthash].css'),
new webpack.ProvidePlugin({
process: ['codesandbox-browserfs/dist/shims/process.js'],
frdlweb: ['@frdl/monkeyism/shims/common.browser.js']
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
// ,new UglifyJsPlugin()
];
const plugins= [
...productionPlugins
];
// const code = `module.exports = () => 42;`;
const sandbox = await webpackSandboxed({
config: {
target: 'web',
resolve: {
extensions: [".js", ".ts", '.ts', '.css'],
modules: modulesFolders,
// roots : modulesFolders,
// Use our versions of Node modules
alias: {
'browserfs' : 'codesandbox-browserfs',
// 'fs': 'browserfs/dist/shims/fs.js',
'process':'codesandbox-browserfs/dist/shims/process.js',
'fs': 'codesandbox-browserfs/dist/shims/fs.js',
'buffer': 'codesandbox-browserfs/dist/shims/buffer.js',
'path': 'codesandbox-browserfs/dist/shims/path.js',
'processGlobal': 'codesandbox-browserfs/dist/shims/process.js',
'bufferGlobal': 'codesandbox-browserfs/dist/shims/bufferGlobal.js',
// 'bfsGlobal': require.resolve('codesandbox-browserfs')
'bfsGlobal': 'codesandbox-browserfs/dist/shims/fs.js' ,
'vm': 'vm2'
},
plugins : plugins
},
module: {
noParse: /browserfs\.js/,
rules: [
/*
{
test: /\.js$/,
exclude: /node_modules/,
loader: babelLoader,
options: {
plugins: [
"@babel/plugin-syntax-dynamic-import",
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": true
}
]
],
presets: [
'es2015',
'react',
[
'@babel/preset-env',
{
targets: {
esmodules: true
},
}
]
],
babelrc: false
}
},
*/
{
test: /\.css$/,
//use: ExtractTextPlugin.extract({
use: plugins[0].extract({
fallback: 'style-loader',
use: {
loader: 'css-loader',
options: {
modules: true
}
}
})
}
]
},
externals: {
},
plugins:[]
},
packages: __packages,
// Packages to load into the virtual filesystem.
/*
packages: [
"codesandbox-browserfs",
"@frdl/eventemitter",
"insertion-query",
"on-idle",
"ready",
"co",
// 'babel-loader'
],
*/
// Local files to load into the virtual filesystem.
includes: [/*path.resolve(__dirname,'includes', 'common.browser.js'), path.resolve(__dirname,'example', 'components')*/],
// For module resolution to work, the base directory needs to be equal to
// the parent directory of node_modules where all necessary packages are installed.
basedir:process.cwd()
});
console.log( sandbox );
// return sandbox;
//resolve(sandbox);
// try{
// var code =(isBase64(_code) || isUrlSafeBase64(_code)|| !/[\s|\{|\}|\;|\,|\.]/.test(_code) )
// ? decode(_code) : _code;
// }catch(fehler){
// var code =Buffer.from(_code, 'base64').toString('ascii') ;
// }
var code =(isBase64(_code) || isUrlSafeBase64(_code) || !(/([\s|\{|\}|\;|\,|\.])/.test(_code)))
? decode(_code) : _code;
const [bundle, stats] = await sandbox.run(code || jsCode);
// return [bundle, stats];
// console.log('[bundle, stats]',[bundle, stats]);
//resolve([bundle,stats]);
const key = Object.keys(bundle)[0];
const compiled = bundle[key];
// resolve(compiled);
// return compiled;
// const vm = new VM({
// timeout: 30 * 60* 1000,
// sandbox: {
// fs : fs_browser
// }
// });
// const exported = eval(compiled);
// const exported = vm.run(compiled);
resolve({
key:key,
bundle:bundle,
stats:stats,
compiled:compiled//,
// exported:exported
});
});
}
})(o)