index.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. 'use strict';
  2. const convert = require('koa-convert');
  3. const is = require('is-type-of');
  4. const path = require('path');
  5. const fs = require('fs');
  6. const co = require('co');
  7. const BuiltinModule = require('module');
  8. // Guard against poorly mocked module constructors.
  9. const Module = module.constructor.length > 1
  10. ? module.constructor
  11. /* istanbul ignore next */
  12. : BuiltinModule;
  13. module.exports = {
  14. extensions: Module._extensions,
  15. loadFile(filepath) {
  16. try {
  17. // if not js module, just return content buffer
  18. const extname = path.extname(filepath);
  19. if (extname && !Module._extensions[extname]) {
  20. return fs.readFileSync(filepath);
  21. }
  22. // require js module
  23. const obj = require(filepath);
  24. if (!obj) return obj;
  25. // it's es module
  26. if (obj.__esModule) return 'default' in obj ? obj.default : obj;
  27. return obj;
  28. } catch (err) {
  29. err.message = `[egg-core] load file: ${filepath}, error: ${err.message}`;
  30. throw err;
  31. }
  32. },
  33. methods: [ 'head', 'options', 'get', 'put', 'patch', 'post', 'delete' ],
  34. async callFn(fn, args, ctx) {
  35. args = args || [];
  36. if (!is.function(fn)) return;
  37. if (is.generatorFunction(fn)) fn = co.wrap(fn);
  38. return ctx ? fn.call(ctx, ...args) : fn(...args);
  39. },
  40. middleware(fn) {
  41. return is.generatorFunction(fn) ? convert(fn) : fn;
  42. },
  43. getCalleeFromStack(withLine, stackIndex) {
  44. stackIndex = stackIndex === undefined ? 2 : stackIndex;
  45. const limit = Error.stackTraceLimit;
  46. const prep = Error.prepareStackTrace;
  47. Error.prepareStackTrace = prepareObjectStackTrace;
  48. Error.stackTraceLimit = 5;
  49. // capture the stack
  50. const obj = {};
  51. Error.captureStackTrace(obj);
  52. let callSite = obj.stack[stackIndex];
  53. let fileName;
  54. /* istanbul ignore else */
  55. if (callSite) {
  56. // egg-mock will create a proxy
  57. // https://github.com/eggjs/egg-mock/blob/master/lib/app.js#L174
  58. fileName = callSite.getFileName();
  59. /* istanbul ignore if */
  60. if (fileName && fileName.endsWith('egg-mock/lib/app.js')) {
  61. // TODO: add test
  62. callSite = obj.stack[stackIndex + 1];
  63. fileName = callSite.getFileName();
  64. }
  65. }
  66. Error.prepareStackTrace = prep;
  67. Error.stackTraceLimit = limit;
  68. /* istanbul ignore if */
  69. if (!callSite || !fileName) return '<anonymous>';
  70. if (!withLine) return fileName;
  71. return `${fileName}:${callSite.getLineNumber()}:${callSite.getColumnNumber()}`;
  72. },
  73. getResolvedFilename(filepath, baseDir) {
  74. const reg = /[/\\]/g;
  75. return filepath.replace(baseDir + path.sep, '').replace(reg, '/');
  76. },
  77. };
  78. /**
  79. * Capture call site stack from v8.
  80. * https://github.com/v8/v8/wiki/Stack-Trace-API
  81. */
  82. function prepareObjectStackTrace(obj, stack) {
  83. return stack;
  84. }