Skip to content

Commit

Permalink
Merge pull request #4 from whefter/feature/autoload-named-exports
Browse files Browse the repository at this point in the history
feat: allow autoloading of named exports
  • Loading branch information
jeffijoe committed Jan 17, 2019
2 parents 9f55598 + e67ed09 commit 0128f8f
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 5 deletions.
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -51,6 +51,9 @@ yarn add awilix-router-core

The end-user of the routing library will be able to use decorators or a builder pattern to declaratively set up their routes, middleware and methods.

**Note**: in the examples below, an ES6 `default` export is used, but named exports and multiple exports
per file are supported.

## With decorators

```js
Expand Down
9 changes: 9 additions & 0 deletions __fixtures__/mixedExports.js
@@ -0,0 +1,9 @@
const { createController } = require('../src/controller')

class MixedDefaultExportClass {}
MixedDefaultExportClass.isMixedDefaultExport = true
module.exports.default = createController(MixedDefaultExportClass)

class MixedNamedExportClass {}
MixedNamedExportClass.isMixedNamedExport = true
module.exports.MixedNamedExportClass = createController(MixedNamedExportClass)
13 changes: 13 additions & 0 deletions __fixtures__/mixedModuleExports.js
@@ -0,0 +1,13 @@
const { createController } = require('../src/controller')

class MixedModuleExportsClass {}
MixedModuleExportsClass.isMixedModuleExports = true
module.exports = createController(MixedModuleExportsClass)

class MixedModuleDefaultExportClass {}
MixedModuleDefaultExportClass.isMixedModuleDefaultExport = true
module.exports.default = createController(MixedModuleDefaultExportClass)

class MixedModuleNamedExportClass {}
MixedModuleNamedExportClass.isMixedModuleNamedExport = true
module.exports.MixedModuleNamedExportClass = createController(MixedModuleNamedExportClass)
1 change: 1 addition & 0 deletions __fixtures__/moduleNoneExports.js
@@ -0,0 +1 @@
module.exports = null
5 changes: 5 additions & 0 deletions __fixtures__/namedExport.js
@@ -0,0 +1,5 @@
const { createController } = require('../src/controller')

class NamedExportClass {}
NamedExportClass.isNamedExport = true
module.exports.NamedExportClass = createController(NamedExportClass)
24 changes: 23 additions & 1 deletion src/__tests__/find-controllers.test.ts
Expand Up @@ -5,8 +5,30 @@ describe('findControllers', () => {
const result = findControllers('__fixtures__/*.js', { absolute: true })
const moduleExports = result.find((x: any) => x.target.isModuleExports)
const defaultExports = result.find((x: any) => x.target.isDefaultExport)
expect(result.length).toBe(2)
const namedExports = result.find((x: any) => x.target.isNamedExport)
const mixedDefaultExports = result.find(
(x: any) => x.target.isMixedDefaultExport
)
const mixedNamedExports = result.find(
(x: any) => x.target.isMixedNamedExport
)
const mixedModuleExports = result.find(
(x: any) => x.target.isMixedModuleExports
)
const mixedModuleDefaultExports = result.find(
(x: any) => x.target.isMixedModuleDefaultExport
)
const mixedModuleNamedExports = result.find(
(x: any) => x.target.isMixedModuleNamedExport
)
expect(result.length).toBe(6)
expect(typeof (moduleExports as any).target).toBe('function')
expect(typeof (defaultExports as any).target).toBe('function')
expect(typeof (namedExports as any).target).toBe('function')
expect(typeof (mixedDefaultExports as any).target).toBe('function')
expect(typeof (mixedNamedExports as any).target).toBe('function')
expect(typeof (mixedModuleExports as any).target).toBe('function')
expect(mixedModuleDefaultExports).toBeUndefined()
expect(mixedModuleNamedExports).toBeUndefined()
})
})
19 changes: 15 additions & 4 deletions src/find-controllers.ts
Expand Up @@ -19,14 +19,25 @@ export function findControllers(
const result = glob.sync(pattern, opts)
return result
.map(path => {
const items: Array<IStateAndTarget | null> = []

let required = require(path)

// Support default exports (ES6).
if (required.default) {
required = required.default
if (required) {
const stateAndTarget = getStateAndTarget(required)
if (stateAndTarget) {
items.push(stateAndTarget)
return items
}

// loop through exports - this will cover named as well as a default export
for (const key of Object.keys(required)) {
items.push(getStateAndTarget(required[key]))
}
}

return getStateAndTarget(required)
return items
})
.reduce((acc, cur) => acc.concat(cur), [])
.filter(x => x !== null) as FindControllersResult
}

0 comments on commit 0128f8f

Please sign in to comment.