Skip to content

Commit

Permalink
refactor: finalize loader api and implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Mar 9, 2020
1 parent 6ca2aee commit 8aabcc8
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 31 deletions.
60 changes: 35 additions & 25 deletions src/Loader/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @module edge
*/

/**
* edge
*
Expand All @@ -12,9 +8,9 @@
*/

import { readFileSync } from 'fs'
import { Exception, esmResolver } from '@poppinss/utils'
import requireUncached = require('import-fresh')
import requireUncached from 'import-fresh'
import { join, isAbsolute, extname } from 'path'
import { Exception, esmResolver } from '@poppinss/utils'

import { extractDiskAndTemplateName } from '../utils'
import { LoaderContract, LoaderTemplate } from '../Contracts'
Expand All @@ -30,12 +26,12 @@ export class Loader implements LoaderContract {
/**
* List of mounted directories
*/
private _mountedDirs: Map<string, string> = new Map()
private mountedDirs: Map<string, string> = new Map()

/**
* List of pre-registered (in-memory) templates
*/
private _preRegistered: Map<string, LoaderTemplate> = new Map()
private preRegistered: Map<string, LoaderTemplate> = new Map()

/**
* Attempts to load the presenter for a given template. If presenter doesn't exists, it
Expand All @@ -44,7 +40,7 @@ export class Loader implements LoaderContract {
* Also this method will **bypass the `require` cache**, since in production compiled templates
* and their presenters are cached anyways.
*/
private _getPresenterForTemplate (templatePath: string): LoaderTemplate['Presenter'] | undefined {
private getPresenterForTemplate (templatePath: string): LoaderTemplate['Presenter'] | undefined {
const presenterPath = templatePath
.replace(/^\w/, c => c.toUpperCase())
.replace(extname(templatePath), '.presenter.js')
Expand All @@ -62,13 +58,13 @@ export class Loader implements LoaderContract {
* Reads the content of a template from the disk. An exception is raised
* when file is missing or if `readFileSync` returns an error.
*/
private _readTemplateContents (absPath: string): string {
private readTemplateContents (absPath: string): string {
try {
return readFileSync(absPath, 'utf-8')
} catch (error) {
if (error.code === 'ENOENT') {
throw new Exception(
`Cannot resolve ${absPath}. Make sure the file exists`,
`Cannot resolve "${absPath}". Make sure the file exists`,
500,
'E_MISSING_TEMPLATE_FILE',
)
Expand All @@ -93,7 +89,7 @@ export class Loader implements LoaderContract {
* ```
*/
public get mounted (): { [key: string]: string } {
return Array.from(this._mountedDirs).reduce((obj, [key, value]) => {
return Array.from(this.mountedDirs).reduce((obj, [key, value]) => {
obj[key] = value
return obj
}, {})
Expand All @@ -112,7 +108,7 @@ export class Loader implements LoaderContract {
* ```
*/
public mount (diskName: string, dirPath: string): void {
this._mountedDirs.set(diskName, dirPath)
this.mountedDirs.set(diskName, dirPath)
}

/**
Expand All @@ -123,7 +119,7 @@ export class Loader implements LoaderContract {
* ```
*/
public unmount (diskName: string): void {
this._mountedDirs.delete(diskName)
this.mountedDirs.delete(diskName)
}

/**
Expand All @@ -139,18 +135,32 @@ export class Loader implements LoaderContract {
* @throws Error if disk is not mounted and attempting to make path for it.
*/
public makePath (templatePath: string): string {
if (this._preRegistered.has(templatePath)) {
/**
* Return the template path as it is, when it is registered
* dynamically
*/
if (this.preRegistered.has(templatePath)) {
return templatePath
}

/**
* Return absolute path as it is
*/
if (isAbsolute(templatePath)) {
return templatePath
}

/**
* Extract disk name and template path from the expression
*/
const [ diskName, template ] = extractDiskAndTemplateName(templatePath)

/**
* Raise exception when disk name is not defined
* Raise exception when disk name is not registered
*/
const mountedDir = this._mountedDirs.get(diskName)
const mountedDir = this.mountedDirs.get(diskName)
if (!mountedDir) {
throw new Exception(`{${diskName}} namespace is not mounted`, 500, 'E_UNMOUNTED_DISK_NAME')
throw new Exception(`"${diskName}" namespace is not mounted`, 500, 'E_UNMOUNTED_DISK_NAME')
}

return join(mountedDir, template)
Expand Down Expand Up @@ -179,8 +189,8 @@ export class Loader implements LoaderContract {
/**
* Return from pre-registered one's if exists
*/
if (this._preRegistered.has(templatePath)) {
const contents = this._preRegistered.get(templatePath)
if (this.preRegistered.has(templatePath)) {
const contents = this.preRegistered.get(templatePath)
return withPresenter ? contents! : { template: contents!.template }
}

Expand All @@ -190,8 +200,8 @@ export class Loader implements LoaderContract {
templatePath = isAbsolute(templatePath) ? templatePath : this.makePath(templatePath)

return {
template: this._readTemplateContents(templatePath),
Presenter: withPresenter ? this._getPresenterForTemplate(templatePath) : undefined,
template: this.readTemplateContents(templatePath),
Presenter: withPresenter ? this.getPresenterForTemplate(templatePath) : undefined,
}
}

Expand Down Expand Up @@ -227,14 +237,14 @@ export class Loader implements LoaderContract {
/**
* Do not overwrite existing template with same template path
*/
if (this._preRegistered.has(templatePath)) {
if (this.preRegistered.has(templatePath)) {
throw new Exception(
`Cannot override previously registered {${templatePath}} template`,
`Cannot override previously registered "${templatePath}" template`,
500,
'E_DUPLICATE_TEMPLATE_PATH',
)
}

this._preRegistered.set(templatePath, contents)
this.preRegistered.set(templatePath, contents)
}
}
12 changes: 6 additions & 6 deletions test/loader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
* file that was distributed with this source code.
*/

import { join } from 'path'
import test from 'japa'
import { join } from 'path'
import { Filesystem } from '@poppinss/dev-utils'

import { Loader } from '../src/Loader'
Expand Down Expand Up @@ -37,10 +37,10 @@ test.group('Loader', (group) => {
test('throw exception when resolving path from undefined location', (assert) => {
const loader = new Loader()
const fn = () => loader.resolve('foo', true)
assert.throw(fn, 'E_UNMOUNTED_DISK_NAME: {default} namespace is not mounted')
assert.throw(fn, 'E_UNMOUNTED_DISK_NAME: "default" namespace is not mounted')
})

test('resolve template for default location', async (assert) => {
test('resolve template for the default disk', async (assert) => {
await fs.add('foo.edge', 'Hello world')

const loader = new Loader()
Expand All @@ -55,7 +55,7 @@ test.group('Loader', (group) => {
loader.mount('default', fs.basePath)

const fn = () => loader.resolve('foo', false)
assert.throw(fn, `Cannot resolve ${join(fs.basePath, 'foo.edge')}. Make sure the file exists`)
assert.throw(fn, `Cannot resolve "${join(fs.basePath, 'foo.edge')}". Make sure the file exists`)
})

test('resolve template with extension', async (assert) => {
Expand All @@ -68,7 +68,7 @@ test.group('Loader', (group) => {
assert.equal(template.trim(), 'Hello world')
})

test('resolve template from a named mount path', async (assert) => {
test('resolve template from a named disk', async (assert) => {
await fs.add('foo.edge', 'Hello world')

const loader = new Loader()
Expand Down Expand Up @@ -152,6 +152,6 @@ test.group('Loader', (group) => {
loader.register('my-view', { template: 'Hello world' })
const fn = () => loader.register('my-view', { template: 'Hello world' })

assert.throw(fn, 'Cannot override previously registered {my-view} template')
assert.throw(fn, 'Cannot override previously registered "my-view" template')
})
})

0 comments on commit 8aabcc8

Please sign in to comment.