Skip to content

Commit

Permalink
refactor: move extractDiskandTemplateName method to loader
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Mar 10, 2020
1 parent bb4cd29 commit e93ed43
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 285 deletions.
32 changes: 28 additions & 4 deletions src/Loader/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@

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

import { extractDiskAndTemplateName } from '../utils'
import { LoaderContract, LoaderTemplate } from '../Contracts'

/**
Expand Down Expand Up @@ -74,6 +72,32 @@ export class Loader implements LoaderContract {
}
}

/**
* Extracts the disk name and the template name from the template
* path expression.
*
* If `diskName` is missing, it will be set to `default`.
*
* ```
* extractDiskAndTemplateName('users::list')
* // returns ['users', 'list.edge']
*
* extractDiskAndTemplateName('list')
* // returns ['default', 'list.edge']
* ```
*/
private extractDiskAndTemplateName (templatePath: string): [string, string] {
let [disk, ...rest] = templatePath.split('::')

if (!rest.length) {
rest = [disk]
disk = 'default'
}

const [template, ext] = rest.join('::').split('.edge')
return [disk, `${template.replace(/\./, sep)}.${ext || 'edge'}`]
}

/**
* Returns an object of mounted directories with their public
* names.
Expand Down Expand Up @@ -153,7 +177,7 @@ export class Loader implements LoaderContract {
/**
* Extract disk name and template path from the expression
*/
const [ diskName, template ] = extractDiskAndTemplateName(templatePath)
const [ diskName, template ] = this.extractDiskAndTemplateName(templatePath)

/**
* Raise exception when disk name is not registered
Expand Down
137 changes: 21 additions & 116 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @module edge
*/

/*
* edge
*
Expand All @@ -11,11 +7,22 @@
* file that was distributed with this source code.
*/

import { sep } from 'path'
import { EdgeError } from 'edge-error'
import { TagTypes } from 'edge-lexer'
import { Parser, expressions as expressionsList, ParserToken, ParserTagToken } from 'edge-parser'
import { StringifiedObject } from '../StringifiedObject'
import { expressions as expressionsList } from 'edge-parser'

type ExpressionList = (keyof typeof expressionsList)[]

/**
* Raise an `E_UNALLOWED_EXPRESSION` exception. Filename and expression is
* required to point the error stack to the correct file
*/
export function unallowedExpression (message: string, expression: any, filename: string) {
throw new EdgeError(message, 'E_UNALLOWED_EXPRESSION', {
line: expression.loc.start.line,
col: expression.loc.start.column,
filename: filename,
})
}

/**
* Validates the expression type to be part of the allowed
Expand All @@ -24,21 +31,12 @@ import { StringifiedObject } from '../StringifiedObject'
* The filename is required to report errors.
*
* ```js
* allowExpressions('include', 'SequenceExpression', ['Literal', 'Identifier'], 'foo.edge')
* isNotSubsetOf(expression, ['Literal', 'Identifier'], () => {})
* ```
*/
export function allowExpressions (
expression: any,
expressions: (keyof typeof expressionsList)[],
filename: string,
message: string,
) {
export function isSubsetOf (expression: any, expressions: ExpressionList, errorCallback: () => void) {
if (!expressions.includes(expression.type)) {
throw new EdgeError(message, 'E_UNALLOWED_EXPRESSION', {
line: expression.loc.start.line,
col: expression.loc.start.column,
filename: filename,
})
errorCallback()
}
}

Expand All @@ -49,104 +47,11 @@ export function allowExpressions (
* The filename is required to report errors.
*
* ```js
* disAllowExpressions('include', 'SequenceExpression', ['Literal', 'Identifier'], 'foo.edge')
* isNotSubsetOf(expression, 'SequenceExpression', () => {})
* ```
*/
export function disAllowExpressions (
expression: any,
expressions: (keyof typeof expressionsList)[],
filename: string,
message: string,
) {
export function isNotSubsetOf (expression: any, expressions: ExpressionList, errorCallback: () => void) {
if (expressions.includes(expression.type)) {
throw new EdgeError(message, 'E_UNALLOWED_EXPRESSION', {
line: expression.loc.start.line,
col: expression.loc.start.column,
filename: filename,
})
}
}

/**
* Parses an array of expressions to form an object. Each expression inside the array must
* be `ObjectExpression` or an `AssignmentExpression`, otherwise it will be ignored.
*
* ```js
* (title = 'hello')
* // returns { title: 'hello' }
*
* ({ title: 'hello' })
* // returns { title: 'hello' }
*
* ({ title: 'hello' }, username = 'virk')
* // returns { title: 'hello', username: 'virk' }
* ```
*/
export function expressionsToStringifyObject (expressions: any[], parser: Parser): string {
const objectifyString = new StringifiedObject()

expressions.forEach((arg) => {
if (arg.type === 'ObjectExpression') {
arg.properties.forEach((prop) => {
const key = parser.stringifyExpression(prop.key)
const value = parser.stringifyExpression(prop.value)
objectifyString.add(key, value)
})
}

if (arg.type === 'AssignmentExpression') {
objectifyString.add(arg.left.name, parser.stringifyExpression(arg.right))
}
})

return objectifyString.flush()
}

/**
* Extracts the disk name and the template name from the template
* path expression.
*
* If `diskName` is missing, it will be set to `default`.
*
* ```
* extractDiskAndTemplateName('users::list')
* // returns ['users', 'list.edge']
*
* extractDiskAndTemplateName('list')
* // returns ['default', 'list.edge']
* ```
*/
export function extractDiskAndTemplateName (templatePath: string): [string, string] {
let [disk, ...rest] = templatePath.split('::')

if (!rest.length) {
rest = [disk]
disk = 'default'
errorCallback()
}

const [template, ext] = rest.join('::').split('.edge')
return [disk, `${template.replace(/\./, sep)}.${ext || 'edge'}`]
}

/**
* Returns a boolean, telling whether the lexer node is a block node
* or not.
*/
export function isBlockToken (token: ParserToken, name: string): token is ParserTagToken {
if (token.type === TagTypes.TAG || token.type === TagTypes.ETAG) {
return token.properties.name === name
}

return false
}

/**
* Returns line and number for a given AST token
*/
export function getLineAndColumnForToken (token: ParserToken): [number, number] {
if (token.type === 'newline' || token.type === 'raw') {
return [token.line, 0]
}

return [token.loc.start.line, token.loc.start.col]
}
165 changes: 0 additions & 165 deletions test/utils.spec.ts

This file was deleted.

0 comments on commit e93ed43

Please sign in to comment.