-
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(loader): add file system loader
loader will resolve templates from the file system
- Loading branch information
1 parent
aa10de0
commit cc3aa63
Showing
5 changed files
with
193 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* edge | ||
* | ||
* (c) Harminder Virk <virk@adonisjs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
import { join } from 'path' | ||
import { readFileSync } from 'fs' | ||
|
||
export class Loader { | ||
private mountedDirs: Map<string, string> = new Map() | ||
|
||
/** | ||
* Returns an object of mounted directories with their public | ||
* names | ||
*/ | ||
public get mounted (): object { | ||
return Array.from(this.mountedDirs).reduce((obj, [key, value]) => { | ||
obj[key] = value | ||
return obj | ||
}, {}) | ||
} | ||
|
||
/** | ||
* Mount a directory for resolving views | ||
*/ | ||
public mount (name: string, dirPath: string): void { | ||
this.mountedDirs.set(name, dirPath) | ||
} | ||
|
||
/** | ||
* Remove directory from the list of directories | ||
* for resolving views | ||
*/ | ||
public unmount (name: string): void { | ||
this.mountedDirs.delete(name) | ||
} | ||
|
||
/** | ||
* Resolves a template from disk and returns it as a string | ||
*/ | ||
public resolve (template: string, name: string = 'default'): string { | ||
const mountedDir = this.mountedDirs.get(name) | ||
if (!mountedDir) { | ||
throw new Error(`Attempting to resolve ${template} template for unmounted ${name} location`) | ||
} | ||
|
||
/** | ||
* Normalize template name by adding extension | ||
*/ | ||
template = `${template.replace(/\.edge$/, '')}.edge` | ||
|
||
try { | ||
return readFileSync(join(mountedDir, template), 'utf-8') | ||
} catch (error) { | ||
if (error.code === 'ENOENT') { | ||
throw new Error(`Cannot resolve ${template}. Make sure file exists at ${mountedDir} location.`) | ||
} | ||
throw error | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* edge | ||
* | ||
* (c) Harminder Virk <virk@adonisjs.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
import * as test from 'japa' | ||
import * as fs from 'fs-extra' | ||
|
||
import { join } from 'path' | ||
import { Loader } from '../src/Loader' | ||
|
||
const viewsDir = join(__dirname, 'views') | ||
|
||
test.group('Loader', (group) => { | ||
group.afterEach(async () => { | ||
await fs.remove(viewsDir) | ||
}) | ||
|
||
test('mount path with a name', (assert) => { | ||
const loader = new Loader() | ||
loader.mount('default', viewsDir) | ||
assert.deepEqual(loader.mounted, { default: join(__dirname, 'views') }) | ||
}) | ||
|
||
test('unmount path with a name', (assert) => { | ||
const loader = new Loader() | ||
loader.mount('default', viewsDir) | ||
loader.unmount('default') | ||
|
||
assert.deepEqual(loader.mounted, {}) | ||
}) | ||
|
||
test('throw exception when resolve path from undefined location', (assert) => { | ||
const loader = new Loader() | ||
const fn = () => loader.resolve('foo') | ||
assert.throw(fn, 'Attempting to resolve foo template for unmounted default location') | ||
}) | ||
|
||
test('resolve template for given location', async (assert) => { | ||
await fs.outputFile(join(viewsDir, 'foo.edge'), 'Hello world') | ||
|
||
const loader = new Loader() | ||
loader.mount('default', viewsDir) | ||
|
||
const template = loader.resolve('foo') | ||
assert.equal(template.trim(), 'Hello world') | ||
}) | ||
|
||
test('raise error when template is missing', async (assert) => { | ||
const loader = new Loader() | ||
loader.mount('default', viewsDir) | ||
|
||
const fn = () => loader.resolve('foo') | ||
assert.throw(fn, `Cannot resolve foo.edge. Make sure file exists at ${viewsDir} location.`) | ||
}) | ||
|
||
test('resolve template with extension', async (assert) => { | ||
await fs.outputFile(join(viewsDir, 'foo.edge'), 'Hello world') | ||
|
||
const loader = new Loader() | ||
loader.mount('default', viewsDir) | ||
|
||
const template = loader.resolve('foo.edge') | ||
assert.equal(template.trim(), 'Hello world') | ||
}) | ||
}) |