Skip to content

Commit

Permalink
feat(loader): list components
Browse files Browse the repository at this point in the history
  • Loading branch information
Harminder Virk authored and Harminder Virk committed Aug 13, 2023
1 parent f88193a commit 3b25406
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 2 deletions.
52 changes: 50 additions & 2 deletions src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
* file that was distributed with this source code.
*/

import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import string from '@poppinss/utils/string'
import { join, isAbsolute } from 'node:path'
import { readFileSync, readdirSync } from 'node:fs'
import type { LoaderContract, LoaderTemplate } from './types.js'

/**
Expand Down Expand Up @@ -46,6 +47,34 @@ export class Loader implements LoaderContract {
}
}

/**
* Returns a list of components for a given disk
*/
#getDiskComponents(diskName: string): { componentName: string; tagName: string }[] {
const diskBasePath = this.#mountedDirs.get(diskName)!
const files = readdirSync(join(diskBasePath, 'components'), {
recursive: true,
encoding: 'utf8',
}).filter((file) => file.endsWith('.edge'))

return files.map((file) => {
const fileName = file.replace(/\.edge$/, '')
const componentPath = `components/${fileName}`
const tagName = fileName
.split('/')
.filter((segment, index) => {
return index === 0 || segment !== 'index'
})
.map((segment) => string.camelCase(segment))
.join('.')

return {
componentName: diskName !== 'default' ? `${diskName}::${componentPath}` : componentPath,
tagName: diskName !== 'default' ? `${diskName}.${tagName}` : tagName,
}
})
}

/**
* Extracts the disk name and the template name from the template
* path expression.
Expand Down Expand Up @@ -104,7 +133,7 @@ export class Loader implements LoaderContract {
* // output
*
* {
* 'form.label': { template: '/users/virk/code/app/form/label' }
* 'form.label': { template: 'Template contents' }
* }
* ```
*/
Expand Down Expand Up @@ -260,4 +289,23 @@ export class Loader implements LoaderContract {
remove(templatePath: string) {
this.#preRegistered.delete(templatePath)
}

/**
* Returns a list of components from all the disks. We assume
* the components are stored within the components directory.
*
* Also, we treat all in-memory templates as components.
*
* The return path is same the path you will pass to the `@component`
* tag.
*/
listComponents(): { diskName: string; components: string[] }[] {
const diskNames = [...this.#mountedDirs.keys()]
return diskNames.map((diskName) => {
return {
diskName,
components: this.#getDiskComponents(diskName),
}
})
}
}
113 changes: 113 additions & 0 deletions tests/loader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,117 @@ test.group('Loader', () => {

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

test('get components for the default disk', async ({ assert, fs }) => {
await fs.create('components/foo.edge', 'Hello world')

const loader = new Loader()
loader.mount('default', fs.basePath)

const componentsList = loader.listComponents()
assert.deepEqual(componentsList, [
{
diskName: 'default',
components: [
{
componentName: 'components/foo',
tagName: 'foo',
},
],
},
])
})

test('get components from nested directories', async ({ assert, fs }) => {
await fs.create('components/modal/root.edge', 'Hello world')

const loader = new Loader()
loader.mount('default', fs.basePath)

const componentsList = loader.listComponents()
assert.deepEqual(componentsList, [
{
diskName: 'default',
components: [
{
componentName: 'components/modal/root',
tagName: 'modal.root',
},
],
},
])
})

test('get components from nested directories from a named disk', async ({ assert, fs }) => {
await fs.create('components/modal/root.edge', 'Hello world')

const loader = new Loader()
loader.mount('uikit', fs.basePath)

const componentsList = loader.listComponents()
assert.deepEqual(componentsList, [
{
diskName: 'uikit',
components: [
{
componentName: 'uikit::components/modal/root',
tagName: 'uikit.modal.root',
},
],
},
])
})

test('rename nested components saved in index.edge file', async ({ assert, fs }) => {
await fs.create('components/modal/index.edge', 'Hello world')
await fs.create('components/index.edge', 'Hello world')

const loader = new Loader()
loader.mount('uikit', fs.basePath)

const componentsList = loader.listComponents()
assert.deepEqual(componentsList, [
{
diskName: 'uikit',
components: [
{
componentName: 'uikit::components/index',
tagName: 'uikit.index',
},
{
componentName: 'uikit::components/modal/index',
tagName: 'uikit.modal',
},
],
},
])
})

test('rename nested components saved in index.edge file from default disk', async ({
assert,
fs,
}) => {
await fs.create('components/modal/index.edge', 'Hello world')
await fs.create('components/index.edge', 'Hello world')

const loader = new Loader()
loader.mount('default', fs.basePath)

const componentsList = loader.listComponents()
assert.deepEqual(componentsList, [
{
diskName: 'default',
components: [
{
componentName: 'components/index',
tagName: 'index',
},
{
componentName: 'components/modal/index',
tagName: 'modal',
},
],
},
])
})
})

0 comments on commit 3b25406

Please sign in to comment.