runkit-plus-ultra
Version:
Runkit tools for loading TypeScript, ES Modules and more. Makes testing Isomorphic code easyer, lets you use unstable features and import modules from git.
161 lines (130 loc) • 4.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _runkitPlusUltra = require("runkit-plus-ultra");
var _fs = require("fs");
var _child_process = require("child_process");
var _os = require("os");
// Todo, depends on PWD to determine node_modules location
// This makes testing hard.
// This might work: node -e 'console.log(require.resolve("@babel/core"))'
// import { URL } from 'url'
const utils = {}; // hoist
const cm = {
root: process.cwd(),
NS: "runkit-plus-ultra",
// Warning: Accessing non-existent property 'version' of module exports inside circular dependency
// depVer: dep.version,
defaultEnv: {
NODE_OPTIONS: '--no-warnings --loader ts-node/esm/transpile-only'
}
};
cm.workdir = `${cm.root}/.${cm.NS}`;
cm.myScripts = `${cm.workdir}/internal`;
class OmniLoader {
constructor(argsRaw) {
const args = argsRaw || {
env: {}
};
Object.assign(this, {
auto: true,
nodeModules: '',
runKitVersion: '',
vcsVersion: '',
promise: new Promise((resolve, reject) => resolve()),
scriptSpecs: [],
env: cm.defaultEnv
}, args);
Object.assign(this.env, args.env);
console.debug(`cm.root is ${cm.root}`);
if (this.auto) {
// todo seperate prepare function and require promise
this.prepareBasics();
this.prepareTSNode();
this.saveCode();
this.runCode();
}
} // get promise {}
// Use promise to allow async when { async: true } is set
// Otherwise block until async resolves.
static getPkgJson(path) {
return JSON.parse(_fs.readFileSync(`${path}/package.json`).toString());
}
static getModVer(path) {
return utils.getPkgJson(path).version;
}
static getModRepo(path) {
// https://docs.npmjs.com/cli/v7/configuring-npm/package-json#repository
const repo = utils.getPkgJson(path).repository || {};
if (typeof repo.url === 'undefined') throw new Error('CANT_READ_MOD_REPO_URL');
return repo.url;
}
prepareBasics() {
(0, _child_process.execSync)(`rm -r "${cm.workdir}" || :`);
(0, _child_process.execSync)(`mkdir -p "${cm.workdir}"`);
(0, _child_process.execSync)(`cd "${cm.workdir}" npm init --yes ${cm.NS}`);
(0, _child_process.execSync)(`cd "${cm.workdir}" && npm config set type=module`);
if (process.env.RUNKIT_HOST) {
// Create a symlink to the real node_modules under our work directory
const upSince = Math.round(Date.now() / 1000 - _os.uptime()) * 1000;
(0, _child_process.execSync)(`ln -s /app/available_modules/${upSince}/ "${cm.root}/node_modules" || :`);
} else {
console.debug('Not running in Runkit, not creating node_modules link.');
}
(0, _child_process.execSync)(`mkdir -p "${cm.myScripts}"`);
}
prepareTSNode() {
const tsConfig = {
compilerOptions: {
"target": "ESnext",
"module": "ESNext",
"allowJs": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
}
};
_fs.writeFileSync(`${cm.workdir}/tsconfig.json`, JSON.stringify(tsConfig, null, 2));
}
/* canned due to overhead
loadLatest(modName) {
const modIPath = `${cm.myScripts}/${modName}`
// const modRepo = utils.getModRepo(modNMPath)
execSync(`git clone "${modRepo}" "${cm.myScripts}/${modName}"`)
this.vcsVersion = utils.getModVer(modIPath)
}*/
getScriptSpecs(scriptSpecsRaw) {
return scriptSpecsRaw || this.scriptSpecs;
}
saveCode(scriptSpecsRaw) {
for (const spec of this.getScriptSpecs(scriptSpecsRaw)) {
_fs.writeFileSync(`${cm.workdir}/${spec.path}`, spec.code);
}
}
getEnvString() {
const envVars = Object.keys(this.env);
const resultTokens = [];
for (const envK of envVars) {
resultTokens.push(`${envK}="${this.env[envK]}"`);
}
return resultTokens.join(' ');
}
runCode() {
const results = [];
for (const spec of this.scriptSpecs) {
results.push({
path: spec.path,
output: (0, _child_process.execSync)(`cd "${cm.workdir}" && env ${this.getEnvString()} node ${spec.path}`).toString()
});
}
return results;
}
}
exports.default = OmniLoader;
Object.assign(utils, (ClassRef => {
// returns static Fn's as Object entries
const pNames = Object.getOwnPropertyNames(ClassRef); // const staticFnNames = pNames.filter(n => typeof ClassRef[n] === 'function')
const map = pNames.map(n => [n, ClassRef[n]]);
return Object.fromEntries(map);
})(OmniLoader));