const _ = require(`caro`)

class CaroBack {
  constructor () {
    this._modelMap = {}
    this._hookMap = {}
  }

  _getCallerPath () {
    try {
      const err = new Error()
      let callerFile
      let currentFile

      Error.prepareStackTrace = (err, stack) => {return stack}

      currentFile = err.stack.shift().getFileName()

      while (err.stack.length) {
        callerFile = err.stack.shift().getFileName()

        if (currentFile !== callerFile) return callerFile
      }
    } catch (err) {
      // 跳過
    }
    return undefined
  }

  _parseRequirePath (p) {
    const path = require(`path`)
    if (p.startsWith(`./`) || p.startsWith(`../`)) {
      const callerPath = this._getCallerPath()
      const callerDir = path.dirname(callerPath)
      p = path.join(callerDir, p)
    }
    return p
  }

  require (p, opt = {}) {
    const path = require(`path`)
    const skip = opt.skip // require 之後不要放入 ck
    this.require.count = this.require.count || 0

    p = this._parseRequirePath(p)

    try {
      const filename = path.basename(p).replace(path.extname(p), ``)
      const modelName = _.replaceAll(filename, `.`, `_`)
      if (!skip) {
        if (this[modelName]) console.error(`model ${modelName} 已被佔用`)
        this[filename] = require(p)
      }
      else require(p)
    } catch (e) {
      if (++this.require.count > 100) throw Error(`載入 ${p} 失敗 - ${e}`)
      setTimeout(() => this.require(p), 1)
    }
  }

  requireDir (fileOrDirPath, opt) {
    const fs = require(`fs`)
    const path = require(`path`)
    let fileCount = 0

    const requireFile = (fileOrDir) => {
      const stat = fs.statSync(fileOrDir)
      if (stat.isFile() && fileOrDir.endsWith(`.js`)) {
        this.require(fileOrDir, opt)
        fileCount++
      }
      if (stat.isDirectory()) {
        const fileArr = fs.readdirSync(fileOrDir)
        _.forEach(fileArr, (file) => {
          const filePath = path.join(fileOrDir, file)
          requireFile(filePath)
        })
      }
    }

    fileOrDirPath = this._parseRequirePath(fileOrDirPath)

    if (!fs.existsSync(fileOrDirPath)) {
      throw Error(`路徑 ${fileOrDirPath} 不存在`)
    }

    const stat = fs.statSync(fileOrDirPath)
    if (!stat.isDirectory()) {
      throw Error(`路徑 ${fileOrDirPath} 必須為資料夾`)
    }

    requireFile(fileOrDirPath)
    return fileCount
  }
}

module.exports = CaroBack

@@ -138,43 +138,147 @@
     
-try %7B%0A      const err = new Error()
+const prepareStackTrace = Error.prepareStackTrace%0A    try %7B%0A      const err = new Error()%0A      Error.prepareStackTrace = prepareStackTrace
 %0A   
@@ -369,23 +369,14 @@
 ) =%3E
- %7Breturn
  stack
-%7D
 %0A%0A  
@@ -552,16 +552,88 @@
 lerFile)
+ %7B%0A          Error.prepareStackTrace = prepareStackTrace      %0A         
  return 
@@ -639,24 +639,34 @@
  callerFile%0A
+        %7D%0A
       %7D%0A    
@@ -707,24 +707,65 @@
     
-return undefined
+Error.prepareStackTrace = prepareStackTrace%0A    return %60%60
 %0A  %7D
@@ -1406,16 +1406,28 @@
 elName%5D)
+ %7B%0A         
  console
@@ -1460,16 +1460,43 @@
  %E5%B7%B2%E8%A2%AB%E4%BD%94%E7%94%A8%60)%0A
+          return%0A        %7D%0A
         
@@ -1567,24 +1567,47 @@
 catch (e) %7B%0A
+      console.error(e)%0A
       if (++

更新 ck 取得 caller 方式