Comparing version 2.1.0 to 2.2.0
@@ -0,6 +1,6 @@ | ||
export * from './src/Contracts'; | ||
import { Edge } from './src/Edge'; | ||
export { LoaderContract, LoaderTemplate, EdgeContract, EdgeRendererContract, ContextContract, ContextConstructorContract, TagContract, CompilerContract, } from './src/Contracts'; | ||
export { disAllowExpressions, allowExpressions, extractDiskAndTemplateName, } from './src/utils'; | ||
declare const edge: Edge; | ||
export { Edge }; | ||
declare const edge: Edge; | ||
export default edge; | ||
export { safeValue, withCtx } from './src/Context'; |
@@ -17,8 +17,7 @@ "use strict"; | ||
const globals_1 = __importDefault(require("./src/Edge/globals")); | ||
var utils_1 = require("./src/utils"); | ||
exports.disAllowExpressions = utils_1.disAllowExpressions; | ||
exports.allowExpressions = utils_1.allowExpressions; | ||
exports.extractDiskAndTemplateName = utils_1.extractDiskAndTemplateName; | ||
const edge = new Edge_1.Edge(); | ||
globals_1.default(edge); | ||
exports.default = edge; | ||
var Context_1 = require("./src/Context"); | ||
exports.safeValue = Context_1.safeValue; | ||
exports.withCtx = Context_1.withCtx; |
@@ -0,13 +1,15 @@ | ||
import { LoaderTemplate, CacheManagerContract } from '../Contracts'; | ||
/** | ||
* @module edge | ||
* In memory cache manager to cache pre-compiled templates. | ||
*/ | ||
import { LoaderTemplate } from '../Contracts'; | ||
/** | ||
* In memory cache manager to cache pre-compiled templates | ||
*/ | ||
export declare class CacheManager { | ||
private _enabled; | ||
private _cacheStore; | ||
constructor(_enabled: boolean); | ||
export declare class CacheManager implements CacheManagerContract { | ||
private enabled; | ||
private cacheStore; | ||
constructor(enabled: boolean); | ||
/** | ||
* Returns a boolean to tell if a template has already been cached | ||
* or not. | ||
*/ | ||
has(absPath: string): boolean; | ||
/** | ||
* Returns the template and the presenter class from the | ||
@@ -14,0 +16,0 @@ * cache. If caching is disabled, then it will |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
/* | ||
* 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. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* In memory cache manager to cache pre-compiled templates | ||
* In memory cache manager to cache pre-compiled templates. | ||
*/ | ||
class CacheManager { | ||
constructor(_enabled) { | ||
this._enabled = _enabled; | ||
this._cacheStore = new Map(); | ||
constructor(enabled) { | ||
this.enabled = enabled; | ||
this.cacheStore = new Map(); | ||
} | ||
/** | ||
* Returns a boolean to tell if a template has already been cached | ||
* or not. | ||
*/ | ||
has(absPath) { | ||
return this.cacheStore.has(absPath); | ||
} | ||
/** | ||
* Returns the template and the presenter class from the | ||
@@ -20,6 +32,6 @@ * cache. If caching is disabled, then it will | ||
get(absPath) { | ||
if (!this._enabled) { | ||
if (!this.enabled) { | ||
return; | ||
} | ||
return this._cacheStore.get(absPath); | ||
return this.cacheStore.get(absPath); | ||
} | ||
@@ -31,8 +43,8 @@ /** | ||
set(absPath, payload) { | ||
if (!this._enabled) { | ||
if (!this.enabled) { | ||
return; | ||
} | ||
this._cacheStore.set(absPath, payload); | ||
this.cacheStore.set(absPath, payload); | ||
} | ||
} | ||
exports.CacheManager = CacheManager; |
@@ -1,5 +0,3 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { ParserToken } from 'edge-parser'; | ||
import { Token } from 'edge-lexer'; | ||
import { CacheManager } from '../CacheManager'; | ||
import { LoaderContract, TagsContract, LoaderTemplate, CompilerContract } from '../Contracts'; | ||
@@ -15,11 +13,11 @@ /** | ||
export declare class Compiler implements CompilerContract { | ||
private _loader; | ||
private _tags; | ||
private _cache; | ||
private _cacheManager; | ||
constructor(_loader: LoaderContract, _tags: TagsContract, _cache?: boolean); | ||
private loader; | ||
private tags; | ||
private cache; | ||
cacheManager: CacheManager; | ||
constructor(loader: LoaderContract, tags: TagsContract, cache?: boolean); | ||
/** | ||
* Merges sections of base template and parent template tokens | ||
*/ | ||
private _mergeSections; | ||
private mergeSections; | ||
/** | ||
@@ -30,13 +28,12 @@ * Generates an array of lexer tokens from the template string. Further tokens | ||
*/ | ||
private _templateContentToTokens; | ||
private templateContentToTokens; | ||
/** | ||
* Converts the template content to an [array of lexer tokens]. The method is | ||
* same as the `parser.generateLexerTokens`, plus it will handle the layouts | ||
* and it's sections. | ||
* same as the `parser.tokenize`, but it also handles layouts natively. | ||
* | ||
* ``` | ||
* compiler.generateLexerTokens('<template-path>') | ||
* compiler.tokenize('<template-path>') | ||
* ``` | ||
*/ | ||
generateLexerTokens(templatePath: string): ParserToken[]; | ||
tokenize(templatePath: string): Token[]; | ||
/** | ||
@@ -43,0 +40,0 @@ * Compiles the template contents to a function string, which can be invoked |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,6 +10,7 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_error_1 = require("edge-error"); | ||
const edge_parser_1 = require("edge-parser"); | ||
const edge_lexer_1 = require("edge-lexer"); | ||
const CacheManager_1 = require("../CacheManager"); | ||
const utils_1 = require("../utils"); | ||
/** | ||
@@ -28,7 +25,7 @@ * Compiler compiles the template to a function, which can be invoked at a later | ||
class Compiler { | ||
constructor(_loader, _tags, _cache = true) { | ||
this._loader = _loader; | ||
this._tags = _tags; | ||
this._cache = _cache; | ||
this._cacheManager = new CacheManager_1.CacheManager(this._cache); | ||
constructor(loader, tags, cache = true) { | ||
this.loader = loader; | ||
this.tags = tags; | ||
this.cache = cache; | ||
this.cacheManager = new CacheManager_1.CacheManager(this.cache); | ||
} | ||
@@ -38,3 +35,3 @@ /** | ||
*/ | ||
_mergeSections(base, extended, filename, layoutPath) { | ||
mergeSections(base, extended) { | ||
/** | ||
@@ -45,4 +42,4 @@ * Collection of all sections from the extended tokens | ||
/** | ||
* Collection of extended set calls as top level nodes. Now since they are hanging | ||
* up in the air, they will be hoisted like `var` statements in Javascript | ||
* Collection of extended set calls as top level nodes. The set | ||
* calls are hoisted just like `var` statements in Javascript. | ||
*/ | ||
@@ -56,3 +53,3 @@ const extendedSetCalls = []; | ||
*/ | ||
if (utils_1.isBlockToken(node, 'layout') || | ||
if (edge_lexer_1.utils.isTag(node, 'layout') || | ||
node.type === 'newline' || | ||
@@ -65,3 +62,3 @@ (node.type === 'raw' && !node.value.trim())) { | ||
*/ | ||
if (utils_1.isBlockToken(node, 'section')) { | ||
if (edge_lexer_1.utils.isTag(node, 'section')) { | ||
extendedSections[node.properties.jsArg.trim()] = node; | ||
@@ -73,3 +70,3 @@ return; | ||
*/ | ||
if (utils_1.isBlockToken(node, 'set')) { | ||
if (edge_lexer_1.utils.isTag(node, 'set')) { | ||
extendedSetCalls.push(node); | ||
@@ -79,6 +76,6 @@ return; | ||
/** | ||
* Everything else if not allowed as top level nodes | ||
* Everything else is not allowed as top level nodes | ||
*/ | ||
const [line, col] = utils_1.getLineAndColumnForToken(node); | ||
throw new edge_error_1.EdgeError(`Template extending the layout can only define @sections as top level nodes`, 'E_UNALLOWED_EXPRESSION', { line, col, filename }); | ||
const [line, col] = edge_lexer_1.utils.getLineAndColumn(node); | ||
throw new edge_error_1.EdgeError('Template extending a layout can only use "@section" or "@set" tags as top level nodes', 'E_UNALLOWED_EXPRESSION', { line, col, filename: node.filename }); | ||
}); | ||
@@ -90,9 +87,8 @@ /** | ||
.map((node) => { | ||
if (!utils_1.isBlockToken(node, 'section')) { | ||
node.filename = layoutPath; | ||
if (!edge_lexer_1.utils.isTag(node, 'section')) { | ||
return node; | ||
} | ||
const extendedNode = extendedSections[node.properties.jsArg.trim()]; | ||
const sectionName = node.properties.jsArg.trim(); | ||
const extendedNode = extendedSections[sectionName]; | ||
if (!extendedNode) { | ||
node.filename = layoutPath; | ||
return node; | ||
@@ -103,7 +99,4 @@ } | ||
*/ | ||
if (extendedNode.children.length && utils_1.isBlockToken(extendedNode.children[0], 'super')) { | ||
extendedNode.children = node.children.map((child) => { | ||
child.filename = layoutPath; | ||
return child; | ||
}).concat(extendedNode.children); | ||
if (extendedNode.children.length && edge_lexer_1.utils.isTag(extendedNode.children[0], 'super')) { | ||
extendedNode.children = node.children.concat(extendedNode.children); | ||
} | ||
@@ -122,4 +115,4 @@ return extendedNode; | ||
*/ | ||
_templateContentToTokens(content, parser, filename) { | ||
let templateTokens = parser.generateLexerTokens(content); | ||
templateContentToTokens(content, parser) { | ||
let templateTokens = parser.tokenize(content); | ||
const firstToken = templateTokens[0]; | ||
@@ -130,11 +123,5 @@ /** | ||
*/ | ||
if (utils_1.isBlockToken(firstToken, 'layout')) { | ||
const layoutName = firstToken.properties.jsArg.replace(/'/g, ''); | ||
/** | ||
* Making absolute path, so that lexer errors must point to the | ||
* absolute file path | ||
*/ | ||
const absPath = this._loader.makePath(layoutName); | ||
const layoutTokens = this.generateLexerTokens(absPath); | ||
templateTokens = this._mergeSections(layoutTokens, templateTokens, filename, absPath); | ||
if (edge_lexer_1.utils.isTag(firstToken, 'layout')) { | ||
const layoutName = firstToken.properties.jsArg.replace(/'|"/g, ''); | ||
templateTokens = this.mergeSections(this.tokenize(layoutName), templateTokens); | ||
} | ||
@@ -145,13 +132,13 @@ return templateTokens; | ||
* Converts the template content to an [array of lexer tokens]. The method is | ||
* same as the `parser.generateLexerTokens`, plus it will handle the layouts | ||
* and it's sections. | ||
* same as the `parser.tokenize`, but it also handles layouts natively. | ||
* | ||
* ``` | ||
* compiler.generateLexerTokens('<template-path>') | ||
* compiler.tokenize('<template-path>') | ||
* ``` | ||
*/ | ||
generateLexerTokens(templatePath) { | ||
const { template } = this._loader.resolve(templatePath, false); | ||
const parser = new edge_parser_1.Parser(this._tags, { filename: templatePath }); | ||
return this._templateContentToTokens(template, parser, templatePath); | ||
tokenize(templatePath) { | ||
const absPath = this.loader.makePath(templatePath); | ||
const { template } = this.loader.resolve(absPath, false); | ||
const parser = new edge_parser_1.Parser(this.tags, { filename: absPath }); | ||
return this.templateContentToTokens(template, parser); | ||
} | ||
@@ -180,3 +167,3 @@ /** | ||
compile(templatePath, inline) { | ||
const absPath = this._loader.makePath(templatePath); | ||
const absPath = this.loader.makePath(templatePath); | ||
/** | ||
@@ -186,3 +173,3 @@ * If template is in the cache, then return it without | ||
*/ | ||
const cachedResponse = this._cacheManager.get(absPath); | ||
const cachedResponse = this.cacheManager.get(absPath); | ||
if (cachedResponse) { | ||
@@ -192,3 +179,3 @@ return cachedResponse; | ||
/** | ||
* Do not load presenter in inline mode | ||
* Do not return presenter in inline mode | ||
*/ | ||
@@ -204,7 +191,8 @@ const loadPresenter = !inline; | ||
*/ | ||
const parser = new edge_parser_1.Parser(this._tags, { filename: absPath }); | ||
const parser = new edge_parser_1.Parser(this.tags, { filename: absPath }); | ||
/** | ||
* Resolve the template and Presenter using the given loader | ||
* Resolve the template and Presenter using the given loader. We always | ||
* load the presenter but don't return it when `loadPresenter = false`. | ||
*/ | ||
const { template, Presenter } = this._loader.resolve(absPath, loadPresenter); | ||
const { template, Presenter } = this.loader.resolve(absPath, true); | ||
/** | ||
@@ -214,17 +202,16 @@ * Convert template to AST. The AST will have the layout actions merged (if layout) | ||
*/ | ||
const templateTokens = this._templateContentToTokens(template, parser, absPath); | ||
const templateTokens = this.templateContentToTokens(template, parser); | ||
/** | ||
* Finally process the ast | ||
*/ | ||
const buffer = new edge_parser_1.EdgeBuffer(); | ||
buffer.writeStatement(`ctx.set('$filename', '${templatePath.replace(/\.edge$/, '')}.edge');`); | ||
templateTokens.forEach((token) => parser.processLexerToken(token, buffer)); | ||
const buffer = new edge_parser_1.EdgeBuffer(absPath, wrapAsFunction); | ||
templateTokens.forEach((token) => parser.processToken(token, buffer)); | ||
const payload = { | ||
template: buffer.flush(wrapAsFunction), | ||
template: buffer.flush(), | ||
Presenter, | ||
}; | ||
this._cacheManager.set(absPath, payload); | ||
return payload; | ||
this.cacheManager.set(absPath, payload); | ||
return loadPresenter ? payload : { template: payload.template }; | ||
} | ||
} | ||
exports.Compiler = Compiler; |
@@ -0,6 +1,9 @@ | ||
import { Macroable } from 'macroable'; | ||
import { Presenter } from '../Presenter'; | ||
import { ContextContract } from '../Contracts'; | ||
/** | ||
* @module edge | ||
* An instance of this class passed to the escape | ||
* method ensures that underlying value is never | ||
* escaped. | ||
*/ | ||
import { Macroable } from 'macroable'; | ||
import { ContextContract } from '../Contracts'; | ||
declare class SafeValue { | ||
@@ -11,2 +14,13 @@ value: any; | ||
/** | ||
* A class to wrap callbacks that can access the `ctx` | ||
*/ | ||
declare class WithCtx { | ||
private callback; | ||
constructor(callback: (ctx: ContextContract, ...args: any[]) => any); | ||
/** | ||
* Invoke the callback | ||
*/ | ||
invoke(ctx: ContextContract, bindState: any): (...args: any[]) => any; | ||
} | ||
/** | ||
* Context is used at runtime to resolve values for a given | ||
@@ -19,6 +33,3 @@ * template. | ||
export declare class Context extends Macroable implements ContextContract { | ||
presenter: any; | ||
sharedState: any; | ||
protected static macros: {}; | ||
protected static getters: {}; | ||
presenter: Presenter; | ||
/** | ||
@@ -30,9 +41,19 @@ * Frames are used to define a inner scope in which values will | ||
*/ | ||
private _frames; | ||
constructor(presenter: any, sharedState: any); | ||
private frames; | ||
/** | ||
* Required by Macroable | ||
*/ | ||
protected static macros: {}; | ||
protected static getters: {}; | ||
/** | ||
* Added by compiler | ||
*/ | ||
$filename: string; | ||
$lineNumber: number; | ||
constructor(presenter: Presenter); | ||
/** | ||
* Returns value for a key inside frames. Stops looking for it, | ||
* when value is found inside any frame. | ||
*/ | ||
private _getFromFrame; | ||
private getFromFrame; | ||
/** | ||
@@ -54,3 +75,3 @@ * Returns a merged copy of the current state. The objects are merged | ||
/** | ||
* Set key/value pair on the frame object. The value will only be available until | ||
* Set key/value pair on the frame object. The value will only be available til | ||
* the `removeFrame` is not called. | ||
@@ -74,2 +95,6 @@ * | ||
/** | ||
* Returns all the frames | ||
*/ | ||
getFrames(): any[]; | ||
/** | ||
* Mark output as safe | ||
@@ -84,2 +109,7 @@ */ | ||
/** | ||
* Transform the resolved value before returning it | ||
* back | ||
*/ | ||
private transformValue; | ||
/** | ||
* Resolves value for a given key. It will look for the value in different | ||
@@ -106,5 +136,4 @@ * locations and continues till the end if `undefined` is returned at | ||
* | ||
* 1. If the value already exists on the presenter state, then it will be updated | ||
* 2. If the scope is inside a frame, then will be created/updated on the frame. | ||
* 3. At last, the value is created on the presenter state. | ||
* 1. If the scope is inside a frame, then will be created/updated on the frame. | ||
* 2. Otherwise, the value is created on the presenter state. | ||
* | ||
@@ -115,4 +144,18 @@ * ```js | ||
*/ | ||
set(key: string, value: any): void; | ||
set(key: string, value: any, isolated?: boolean): void; | ||
/** | ||
* Rethrows the runtime exception by re-constructing the error message | ||
* to point back to the original filename | ||
*/ | ||
reThrow(error: any): void; | ||
} | ||
/** | ||
* Mark value as safe and not to be escaped | ||
*/ | ||
export declare function safeValue(value: string): SafeValue; | ||
/** | ||
* Wrap a function that receives the template engine current | ||
* ctx when invoked. | ||
*/ | ||
export declare function withCtx(callback: (ctx: ContextContract, ...args: any[]) => any): WithCtx; | ||
export {}; |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -17,5 +10,15 @@ * edge.js | ||
*/ | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const he_1 = __importDefault(require("he")); | ||
const lodash_1 = require("lodash"); | ||
const macroable_1 = require("macroable"); | ||
const edge_error_1 = require("edge-error"); | ||
/** | ||
* An instance of this class passed to the escape | ||
* method ensures that underlying value is never | ||
* escaped. | ||
*/ | ||
class SafeValue { | ||
@@ -27,2 +30,18 @@ constructor(value) { | ||
/** | ||
* A class to wrap callbacks that can access the `ctx` | ||
*/ | ||
class WithCtx { | ||
constructor(callback) { | ||
this.callback = callback; | ||
} | ||
/** | ||
* Invoke the callback | ||
*/ | ||
invoke(ctx, bindState) { | ||
return (...args) => { | ||
return this.callback.bind(bindState)(ctx, ...args); | ||
}; | ||
} | ||
} | ||
/** | ||
* Context is used at runtime to resolve values for a given | ||
@@ -35,6 +54,5 @@ * template. | ||
class Context extends macroable_1.Macroable { | ||
constructor(presenter, sharedState) { | ||
constructor(presenter) { | ||
super(); | ||
this.presenter = presenter; | ||
this.sharedState = sharedState; | ||
/** | ||
@@ -46,3 +64,8 @@ * Frames are used to define a inner scope in which values will | ||
*/ | ||
this._frames = []; | ||
this.frames = []; | ||
/** | ||
* Added by compiler | ||
*/ | ||
this.$filename = ''; | ||
this.$lineNumber = 0; | ||
} | ||
@@ -53,4 +76,4 @@ /** | ||
*/ | ||
_getFromFrame(key) { | ||
const frameWithVal = this._frames.find((frame) => frame[key] !== undefined); | ||
getFromFrame(key) { | ||
const frameWithVal = this.frames.find((frame) => frame[key] !== undefined); | ||
return frameWithVal ? frameWithVal[key] : undefined; | ||
@@ -63,3 +86,3 @@ } | ||
getCurrentState() { | ||
return Object.assign({}, this.sharedState, this.presenter.state, ...this._frames); | ||
return Object.assign({}, this.presenter.sharedState, this.presenter.state, ...this.frames); | ||
} | ||
@@ -76,6 +99,6 @@ /** | ||
newFrame() { | ||
this._frames.unshift({}); | ||
this.frames.unshift({}); | ||
} | ||
/** | ||
* Set key/value pair on the frame object. The value will only be available until | ||
* Set key/value pair on the frame object. The value will only be available til | ||
* the `removeFrame` is not called. | ||
@@ -93,5 +116,5 @@ * | ||
setOnFrame(key, value) { | ||
const recentFrame = this._frames[0]; | ||
const recentFrame = this.frames[0]; | ||
if (!recentFrame) { | ||
throw new Error('Make sure to call {newFrame} before calling {setOnFrame}'); | ||
throw new Error('Make sure to call "newFrame" before calling "setOnFrame"'); | ||
} | ||
@@ -105,5 +128,11 @@ lodash_1.set(recentFrame, key, value); | ||
removeFrame() { | ||
this._frames.shift(); | ||
this.frames.shift(); | ||
} | ||
/** | ||
* Returns all the frames | ||
*/ | ||
getFrames() { | ||
return this.frames; | ||
} | ||
/** | ||
* Mark output as safe | ||
@@ -124,2 +153,15 @@ */ | ||
/** | ||
* Transform the resolved value before returning it | ||
* back | ||
*/ | ||
transformValue(value, bindState) { | ||
if (value instanceof WithCtx) { | ||
return value.invoke(this, bindState); | ||
} | ||
if (typeof (value) === 'function') { | ||
return value.bind(bindState); | ||
} | ||
return value; | ||
} | ||
/** | ||
* Resolves value for a given key. It will look for the value in different | ||
@@ -142,5 +184,22 @@ * locations and continues till the end if `undefined` is returned at | ||
resolve(key) { | ||
/** | ||
* A special key to return the template current state | ||
*/ | ||
if (key === '$state') { | ||
return this.getCurrentState(); | ||
} | ||
/** | ||
* A special key to return the filename of the current execution | ||
* scope. | ||
*/ | ||
if (key === '$filename') { | ||
return this.$filename; | ||
} | ||
/** | ||
* A special key to return the current execution line number pointing | ||
* fowards the original template file. | ||
*/ | ||
if (key === '$lineNumber') { | ||
return this.$lineNumber; | ||
} | ||
let value; | ||
@@ -150,5 +209,5 @@ /** | ||
*/ | ||
value = this._getFromFrame(key); | ||
value = this.getFromFrame(key); | ||
if (value !== undefined) { | ||
return typeof (value) === 'function' ? value.bind(this) : value; | ||
return this.transformValue(value, this); | ||
} | ||
@@ -161,3 +220,3 @@ /** | ||
if (value !== undefined) { | ||
return typeof (value) === 'function' ? value.bind(this.presenter) : value; | ||
return this.transformValue(value, this.presenter); | ||
} | ||
@@ -169,9 +228,9 @@ /** | ||
if (value !== undefined) { | ||
return typeof (value) === 'function' ? value.bind(this.presenter.state) : value; | ||
return this.transformValue(value, this.presenter.state); | ||
} | ||
/** | ||
* Finally fallback to defined globals | ||
* Finally fallback to shared globals | ||
*/ | ||
value = this.sharedState[key]; | ||
return typeof (value) === 'function' ? value.bind(this.sharedState) : value; | ||
value = this.presenter.sharedState[key]; | ||
return this.transformValue(value, this.presenter.sharedState); | ||
} | ||
@@ -182,5 +241,4 @@ /** | ||
* | ||
* 1. If the value already exists on the presenter state, then it will be updated | ||
* 2. If the scope is inside a frame, then will be created/updated on the frame. | ||
* 3. At last, the value is created on the presenter state. | ||
* 1. If the scope is inside a frame, then will be created/updated on the frame. | ||
* 2. Otherwise, the value is created on the presenter state. | ||
* | ||
@@ -191,8 +249,8 @@ * ```js | ||
*/ | ||
set(key, value) { | ||
set(key, value, isolated = false) { | ||
/** | ||
* If value already exists on the presenter | ||
* state, then mutate it first | ||
* Set value on the presenter state if it already exists and user | ||
* doesn't want an isolated state for the current frame scope | ||
*/ | ||
if (this.presenter.state[key] !== undefined || !this._frames.length) { | ||
if (lodash_1.get(this.presenter.state, key) !== undefined && !isolated) { | ||
lodash_1.set(this.presenter.state, key, value); | ||
@@ -202,9 +260,49 @@ return; | ||
/** | ||
* If frames exists, then set it on frame | ||
* If frames exists, then set the value on the framework | ||
*/ | ||
this.setOnFrame(key, value); | ||
if (this.frames.length) { | ||
this.setOnFrame(key, value); | ||
return; | ||
} | ||
/** | ||
* Otherwise set on presenter | ||
*/ | ||
lodash_1.set(this.presenter.state, key, value); | ||
} | ||
/** | ||
* Rethrows the runtime exception by re-constructing the error message | ||
* to point back to the original filename | ||
*/ | ||
reThrow(error) { | ||
if (error instanceof edge_error_1.EdgeError) { | ||
throw error; | ||
} | ||
// const message = error.message.replace(/ctx\.resolve\(\.\.\.\)/, this.lastResolvedKey) | ||
throw new edge_error_1.EdgeError(error.message, 'E_RUNTIME_EXCEPTION', { | ||
filename: this.$filename, | ||
line: this.$lineNumber, | ||
col: 0, | ||
}); | ||
} | ||
} | ||
exports.Context = Context; | ||
/** | ||
* Required by Macroable | ||
*/ | ||
Context.macros = {}; | ||
Context.getters = {}; | ||
/** | ||
* Mark value as safe and not to be escaped | ||
*/ | ||
function safeValue(value) { | ||
return new SafeValue(value); | ||
} | ||
exports.safeValue = safeValue; | ||
/** | ||
* Wrap a function that receives the template engine current | ||
* ctx when invoked. | ||
*/ | ||
function withCtx(callback) { | ||
return new WithCtx(callback); | ||
} | ||
exports.withCtx = withCtx; |
/** | ||
* @module edge | ||
*/ | ||
/** | ||
* edge | ||
@@ -14,3 +11,3 @@ * | ||
import { MacroableConstructorContract } from 'macroable'; | ||
import { ParseTagDefininationContract } from 'edge-parser'; | ||
import { ParserTagDefininationContract } from 'edge-parser'; | ||
/** | ||
@@ -57,9 +54,13 @@ * The shape in which the loader must resolve the template | ||
/** | ||
* Shape of a view presenter | ||
*/ | ||
export interface PresenterContract { | ||
state: any; | ||
sharedState: any; | ||
} | ||
/** | ||
* Shape of runtime context | ||
*/ | ||
export interface ContextContract { | ||
presenter: { | ||
state: any; | ||
}; | ||
sharedState: any; | ||
presenter: PresenterContract; | ||
safe<T extends any>(value: T): { | ||
@@ -85,3 +86,3 @@ value: T; | ||
*/ | ||
export interface TagContract extends ParseTagDefininationContract { | ||
export interface TagContract extends ParserTagDefininationContract { | ||
tagName: string; | ||
@@ -97,7 +98,16 @@ run?(context: ContextConstructorContract): void; | ||
/** | ||
* Shape of the cache manager | ||
*/ | ||
export interface CacheManagerContract { | ||
get(templatePath: string): undefined | LoaderTemplate; | ||
set(templatePath: string, compiledOutput: LoaderTemplate): void; | ||
has(templatePath: string): boolean; | ||
} | ||
/** | ||
* Shape of the compiler | ||
*/ | ||
export interface CompilerContract { | ||
cacheManager: CacheManagerContract; | ||
compile(templatePath: string, inline: boolean): LoaderTemplate; | ||
generateLexerTokens(templatePath: string): Token[]; | ||
tokenize(templatePath: string): Token[]; | ||
} | ||
@@ -104,0 +114,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
* 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. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); |
@@ -0,5 +1,5 @@ | ||
import { EdgeContract } from '../../Contracts'; | ||
/** | ||
* @module edge | ||
* A list of default globals | ||
*/ | ||
import { EdgeContract } from '../../Contracts'; | ||
export default function globals(edge: EdgeContract): void; |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,3 +10,6 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const util_1 = require("util"); | ||
const lodash_1 = require("lodash"); | ||
const Context_1 = require("../../Context"); | ||
/** | ||
@@ -28,3 +27,3 @@ * Inspect value. | ||
</span>`; | ||
return ctx.safe(`<div class="__inspect_output" style="background: #000; color: #fff; padding: 20px; position: relative;">${inspectedString}${filename}</div>`); | ||
return Context_1.safeValue(`<div class="__inspect_output" style="background: #000; color: #fff; padding: 20px; position: relative;">${inspectedString}${filename}</div>`); | ||
} | ||
@@ -37,5 +36,20 @@ /** | ||
}; | ||
/** | ||
* A list of default globals | ||
*/ | ||
function globals(edge) { | ||
edge.global('inspect', inspect); | ||
edge.global('inspect', Context_1.withCtx(inspect)); | ||
edge.global('range', (start, end, step) => lodash_1.range(start, end, step)); | ||
edge.global('first', lodash_1.first); | ||
edge.global('last', lodash_1.last); | ||
edge.global('groupBy', lodash_1.groupBy); | ||
edge.global('size', lodash_1.size); | ||
edge.global('truncate', lodash_1.truncate); | ||
edge.global('toAnchor', (url, title = url) => { | ||
return Context_1.safeValue(`<a href="${url}"> ${title} </a>`); | ||
}); | ||
edge.global('style', (url, title = url) => { | ||
return Context_1.safeValue(`<a href="${url}"> ${title} </a>`); | ||
}); | ||
} | ||
exports.default = globals; |
@@ -1,12 +0,9 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { Compiler } from '../Compiler'; | ||
import { TagContract, EdgeOptions, EdgeContract, LoaderTemplate, EdgeRendererContract } from '../Contracts'; | ||
export declare class Edge implements EdgeContract { | ||
private _options; | ||
private options; | ||
/** | ||
* Globals are shared with all rendered templates | ||
*/ | ||
private _globals; | ||
private globals; | ||
/** | ||
@@ -16,3 +13,3 @@ * List of registered tags. Adding new tags will only impact | ||
*/ | ||
private _tags; | ||
private tags; | ||
/** | ||
@@ -28,3 +25,3 @@ * The loader to load templates. A loader can read and return | ||
compiler: Compiler; | ||
constructor(_options?: EdgeOptions); | ||
constructor(options?: EdgeOptions); | ||
/** | ||
@@ -40,13 +37,4 @@ * Mount named directory to use views. Later you can reference | ||
*/ | ||
mount(diskName: string, dirPath: string): this; | ||
mount(diskName: string, dirPath?: string): this; | ||
/** | ||
* Mount defaults views directory. | ||
* | ||
* ``` | ||
* edge.mount(join(__dirname, 'admin')) | ||
* edge.render('filename') | ||
* ``` | ||
*/ | ||
mount(dirPath: string): this; | ||
/** | ||
* Un Mount a disk from the loader. | ||
@@ -53,0 +41,0 @@ * |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
/* | ||
* 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. | ||
*/ | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
@@ -13,22 +18,14 @@ if (mod && mod.__esModule) return mod; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
* 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. | ||
*/ | ||
const Tags = __importStar(require("../Tags")); | ||
const Loader_1 = require("../Loader"); | ||
const Context_1 = require("../Context"); | ||
const Compiler_1 = require("../Compiler"); | ||
const Renderer_1 = require("../Renderer"); | ||
const Context_1 = require("../Context"); | ||
class Edge { | ||
constructor(_options = {}) { | ||
this._options = _options; | ||
constructor(options = {}) { | ||
this.options = options; | ||
/** | ||
* Globals are shared with all rendered templates | ||
*/ | ||
this._globals = {}; | ||
this.globals = {}; | ||
/** | ||
@@ -38,3 +35,3 @@ * List of registered tags. Adding new tags will only impact | ||
*/ | ||
this._tags = {}; | ||
this.tags = {}; | ||
/** | ||
@@ -45,9 +42,19 @@ * The loader to load templates. A loader can read and return | ||
*/ | ||
this.loader = this._options.loader || new Loader_1.Loader(); | ||
this.loader = this.options.loader || new Loader_1.Loader(); | ||
/** | ||
* The underlying compiler in use | ||
*/ | ||
this.compiler = new Compiler_1.Compiler(this.loader, this._tags, !!this._options.cache); | ||
this.compiler = new Compiler_1.Compiler(this.loader, this.tags, !!this.options.cache); | ||
Object.keys(Tags).forEach((name) => this.registerTag(Tags[name])); | ||
} | ||
/** | ||
* Mount named directory to use views. Later you can reference | ||
* the views from a named disk as follows. | ||
* | ||
* ``` | ||
* edge.mount('admin', join(__dirname, 'admin')) | ||
* | ||
* edge.render('admin::filename') | ||
* ``` | ||
*/ | ||
mount(diskName, dirPath) { | ||
@@ -82,3 +89,3 @@ if (!dirPath) { | ||
global(name, value) { | ||
this._globals[name] = value; | ||
this.globals[name] = value; | ||
return this; | ||
@@ -105,3 +112,3 @@ } | ||
} | ||
this._tags[tag.tagName] = tag; | ||
this.tags[tag.tagName] = tag; | ||
return this; | ||
@@ -147,3 +154,3 @@ } | ||
getRenderer() { | ||
return new Renderer_1.EdgeRenderer(this.compiler, this._globals); | ||
return new Renderer_1.EdgeRenderer(this.compiler, this.globals); | ||
} | ||
@@ -150,0 +157,0 @@ /** |
/** | ||
* @module edge | ||
* 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. | ||
*/ | ||
@@ -16,7 +21,7 @@ import { LoaderContract, LoaderTemplate } from '../Contracts'; | ||
*/ | ||
private _mountedDirs; | ||
private mountedDirs; | ||
/** | ||
* List of pre-registered (in-memory) templates | ||
*/ | ||
private _preRegistered; | ||
private preRegistered; | ||
/** | ||
@@ -29,3 +34,3 @@ * Attempts to load the presenter for a given template. If presenter doesn't exists, it | ||
*/ | ||
private _getPresenterForTemplate; | ||
private getPresenterForTemplate; | ||
/** | ||
@@ -35,4 +40,19 @@ * Reads the content of a template from the disk. An exception is raised | ||
*/ | ||
private _readTemplateContents; | ||
private readTemplateContents; | ||
/** | ||
* 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; | ||
/** | ||
* Returns an object of mounted directories with their public | ||
@@ -39,0 +59,0 @@ * names. |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* edge | ||
@@ -14,7 +10,10 @@ * | ||
*/ | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs_1 = require("fs"); | ||
const import_fresh_1 = __importDefault(require("import-fresh")); | ||
const path_1 = require("path"); | ||
const utils_1 = require("@poppinss/utils"); | ||
const requireUncached = require("import-fresh"); | ||
const path_1 = require("path"); | ||
const utils_2 = require("../utils"); | ||
/** | ||
@@ -32,7 +31,7 @@ * The job of a loader is to load the template and it's presenter for a given path. | ||
*/ | ||
this._mountedDirs = new Map(); | ||
this.mountedDirs = new Map(); | ||
/** | ||
* List of pre-registered (in-memory) templates | ||
*/ | ||
this._preRegistered = new Map(); | ||
this.preRegistered = new Map(); | ||
} | ||
@@ -46,3 +45,3 @@ /** | ||
*/ | ||
_getPresenterForTemplate(templatePath) { | ||
getPresenterForTemplate(templatePath) { | ||
const presenterPath = templatePath | ||
@@ -52,3 +51,3 @@ .replace(/^\w/, c => c.toUpperCase()) | ||
try { | ||
return utils_1.esmResolver(requireUncached(presenterPath)); | ||
return utils_1.esmResolver(import_fresh_1.default(presenterPath)); | ||
} | ||
@@ -65,3 +64,3 @@ catch (error) { | ||
*/ | ||
_readTemplateContents(absPath) { | ||
readTemplateContents(absPath) { | ||
try { | ||
@@ -72,3 +71,3 @@ return fs_1.readFileSync(absPath, 'utf-8'); | ||
if (error.code === 'ENOENT') { | ||
throw new utils_1.Exception(`Cannot resolve ${absPath}. Make sure the file exists`, 500, 'E_MISSING_TEMPLATE_FILE'); | ||
throw new utils_1.Exception(`Cannot resolve "${absPath}". Make sure the file exists`, 500, 'E_MISSING_TEMPLATE_FILE'); | ||
} | ||
@@ -81,2 +80,25 @@ else { | ||
/** | ||
* 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'] | ||
* ``` | ||
*/ | ||
extractDiskAndTemplateName(templatePath) { | ||
let [disk, ...rest] = templatePath.split('::'); | ||
if (!rest.length) { | ||
rest = [disk]; | ||
disk = 'default'; | ||
} | ||
const [template, ext] = rest.join('::').split('.edge'); | ||
return [disk, `${template.replace(/\./, path_1.sep)}.${ext || 'edge'}`]; | ||
} | ||
/** | ||
* Returns an object of mounted directories with their public | ||
@@ -96,3 +118,3 @@ * names. | ||
get mounted() { | ||
return Array.from(this._mountedDirs).reduce((obj, [key, value]) => { | ||
return Array.from(this.mountedDirs).reduce((obj, [key, value]) => { | ||
obj[key] = value; | ||
@@ -115,3 +137,3 @@ return obj; | ||
mount(diskName, dirPath) { | ||
this._mountedDirs.set(diskName, dirPath); | ||
this.mountedDirs.set(diskName, dirPath); | ||
} | ||
@@ -126,3 +148,3 @@ /** | ||
unmount(diskName) { | ||
this._mountedDirs.delete(diskName); | ||
this.mountedDirs.delete(diskName); | ||
} | ||
@@ -142,12 +164,25 @@ /** | ||
makePath(templatePath) { | ||
if (this._preRegistered.has(templatePath)) { | ||
/** | ||
* Return the template path as it is, when it is registered | ||
* dynamically | ||
*/ | ||
if (this.preRegistered.has(templatePath)) { | ||
return templatePath; | ||
} | ||
const [diskName, template] = utils_2.extractDiskAndTemplateName(templatePath); | ||
/** | ||
* Raise exception when disk name is not defined | ||
* Return absolute path as it is | ||
*/ | ||
const mountedDir = this._mountedDirs.get(diskName); | ||
if (path_1.isAbsolute(templatePath)) { | ||
return templatePath; | ||
} | ||
/** | ||
* Extract disk name and template path from the expression | ||
*/ | ||
const [diskName, template] = this.extractDiskAndTemplateName(templatePath); | ||
/** | ||
* Raise exception when disk name is not registered | ||
*/ | ||
const mountedDir = this.mountedDirs.get(diskName); | ||
if (!mountedDir) { | ||
throw new utils_1.Exception(`{${diskName}} namespace is not mounted`, 500, 'E_UNMOUNTED_DISK_NAME'); | ||
throw new utils_1.Exception(`"${diskName}" namespace is not mounted`, 500, 'E_UNMOUNTED_DISK_NAME'); | ||
} | ||
@@ -179,4 +214,4 @@ return path_1.join(mountedDir, template); | ||
*/ | ||
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 }; | ||
@@ -189,4 +224,4 @@ } | ||
return { | ||
template: this._readTemplateContents(templatePath), | ||
Presenter: withPresenter ? this._getPresenterForTemplate(templatePath) : undefined, | ||
template: this.readTemplateContents(templatePath), | ||
Presenter: withPresenter ? this.getPresenterForTemplate(templatePath) : undefined, | ||
}; | ||
@@ -221,8 +256,8 @@ } | ||
*/ | ||
if (this._preRegistered.has(templatePath)) { | ||
throw new utils_1.Exception(`Cannot override previously registered {${templatePath}} template`, 500, 'E_DUPLICATE_TEMPLATE_PATH'); | ||
if (this.preRegistered.has(templatePath)) { | ||
throw new utils_1.Exception(`Cannot override previously registered "${templatePath}" template`, 500, 'E_DUPLICATE_TEMPLATE_PATH'); | ||
} | ||
this._preRegistered.set(templatePath, contents); | ||
this.preRegistered.set(templatePath, contents); | ||
} | ||
} | ||
exports.Loader = Loader; |
@@ -0,5 +1,3 @@ | ||
import { PresenterContract } from '../Contracts'; | ||
/** | ||
* @module edge | ||
*/ | ||
/** | ||
* The Base presenter is passed to context for reading | ||
@@ -11,5 +9,6 @@ * the state values. | ||
*/ | ||
export declare class Presenter { | ||
export declare class Presenter implements PresenterContract { | ||
state: any; | ||
constructor(state: any); | ||
sharedState: any; | ||
constructor(state: any, sharedState: any); | ||
} |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
@@ -23,6 +20,9 @@ * The Base presenter is passed to context for reading | ||
class Presenter { | ||
constructor(state) { | ||
constructor(state, sharedState) { | ||
this.state = state; | ||
this.sharedState = sharedState; | ||
this.state = this.state || {}; | ||
this.sharedState = this.sharedState || {}; | ||
} | ||
} | ||
exports.Presenter = Presenter; |
@@ -6,6 +6,6 @@ import { EdgeRendererContract, CompilerContract } from '../Contracts'; | ||
export declare class EdgeRenderer implements EdgeRendererContract { | ||
private _compiler; | ||
private _globals; | ||
private _locals; | ||
constructor(_compiler: CompilerContract, _globals: any); | ||
private compiler; | ||
private globals; | ||
private locals; | ||
constructor(compiler: CompilerContract, globals: any); | ||
/** | ||
@@ -12,0 +12,0 @@ * Share local variables with the template. They will overwrite the |
@@ -17,6 +17,6 @@ "use strict"; | ||
class EdgeRenderer { | ||
constructor(_compiler, _globals) { | ||
this._compiler = _compiler; | ||
this._globals = _globals; | ||
this._locals = {}; | ||
constructor(compiler, globals) { | ||
this.compiler = compiler; | ||
this.globals = globals; | ||
this.locals = {}; | ||
} | ||
@@ -28,3 +28,3 @@ /** | ||
share(data) { | ||
lodash_1.merge(this._locals, data); | ||
lodash_1.merge(this.locals, data); | ||
return this; | ||
@@ -36,3 +36,3 @@ } | ||
render(templatePath, state = {}) { | ||
const template = new Template_1.Template(this._compiler, this._globals, this._locals); | ||
const template = new Template_1.Template(this.compiler, this.globals, this.locals); | ||
return template.render(templatePath, state); | ||
@@ -39,0 +39,0 @@ } |
@@ -0,5 +1,3 @@ | ||
import { Parser } from 'edge-parser'; | ||
/** | ||
* @module edge | ||
*/ | ||
/** | ||
* This class generates a valid object as a string, which is written to the template | ||
@@ -31,2 +29,18 @@ * output. The reason we need a string like object, since we don't want it's | ||
flush(): string; | ||
/** | ||
* 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' } | ||
* ``` | ||
*/ | ||
static fromAcornExpressions(expressions: any[], parser: Parser): string; | ||
} |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
@@ -50,3 +47,37 @@ * This class generates a valid object as a string, which is written to the template | ||
} | ||
/** | ||
* 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' } | ||
* ``` | ||
*/ | ||
static fromAcornExpressions(expressions, parser) { | ||
if (!Array.isArray(expressions)) { | ||
throw new Error('"fromAcornExpressions" expects an array of acorn ast expressions'); | ||
} | ||
const objectifyString = new this(); | ||
expressions.forEach((arg) => { | ||
if (arg.type === 'ObjectExpression') { | ||
arg.properties.forEach((prop) => { | ||
const key = parser.utils.stringify(prop.key); | ||
const value = parser.utils.stringify(prop.value); | ||
objectifyString.add(key, value); | ||
}); | ||
} | ||
if (arg.type === 'AssignmentExpression') { | ||
objectifyString.add(arg.left.name, parser.utils.stringify(arg.right)); | ||
} | ||
}); | ||
return objectifyString.flush(); | ||
} | ||
} | ||
exports.StringifiedObject = StringifiedObject; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,3 +10,5 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_error_1 = require("edge-error"); | ||
const edge_lexer_1 = require("edge-lexer"); | ||
const edge_parser_1 = require("edge-parser"); | ||
@@ -22,3 +20,3 @@ const StringifiedObject_1 = require("../StringifiedObject"); | ||
*/ | ||
const componentNameAllowedExpressions = [ | ||
const ALLOWED_EXPRESSION_FOR_COMPONENT_NAME = [ | ||
edge_parser_1.expressions.Identifier, | ||
@@ -35,3 +33,3 @@ edge_parser_1.expressions.Literal, | ||
*/ | ||
function getComponentNameAndProps(expression, parser) { | ||
function getComponentNameAndProps(expression, parser, filename) { | ||
let name; | ||
@@ -52,3 +50,5 @@ /** | ||
*/ | ||
utils_1.allowExpressions(name, componentNameAllowedExpressions, parser.options.filename, `{${parser.stringifyExpression(name)}} is not a valid argument for component name`); | ||
utils_1.isSubsetOf(name, ALLOWED_EXPRESSION_FOR_COMPONENT_NAME, () => { | ||
utils_1.unallowedExpression(`"${parser.utils.stringify(name)}" is not a valid argument for component name`, name, filename); | ||
}); | ||
/** | ||
@@ -59,4 +59,4 @@ * Parse rest of sequence expressions as an objectified string. | ||
return [ | ||
parser.stringifyExpression(name), | ||
utils_1.expressionsToStringifyObject(expression.expressions, parser), | ||
parser.utils.stringify(name), | ||
StringifiedObject_1.StringifiedObject.fromAcornExpressions(expression.expressions, parser), | ||
]; | ||
@@ -68,3 +68,3 @@ } | ||
*/ | ||
return [parser.stringifyExpression(name), '{}']; | ||
return [parser.utils.stringify(name), '{}']; | ||
} | ||
@@ -74,3 +74,3 @@ /** | ||
*/ | ||
function getSlotNameAndProps(expression, parser) { | ||
function getSlotNameAndProps(token, parser) { | ||
/** | ||
@@ -80,4 +80,6 @@ * We just generate the acorn AST only, since we don't want parser to transform | ||
*/ | ||
const parsed = parser.generateAcornExpression(expression.properties.jsArg, expression.loc).expression; | ||
utils_1.allowExpressions(parsed, [edge_parser_1.expressions.Literal, edge_parser_1.expressions.SequenceExpression], parser.options.filename, `{${expression.properties.jsArg}} is not a valid argument type for the @slot tag`); | ||
const parsed = parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename).expression; | ||
utils_1.isSubsetOf(parsed, [edge_parser_1.expressions.Literal, edge_parser_1.expressions.SequenceExpression], () => { | ||
utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid argument type for the @slot tag`, parsed, token.filename); | ||
}); | ||
/** | ||
@@ -96,3 +98,5 @@ * Fetch the slot name | ||
*/ | ||
utils_1.allowExpressions(name, [edge_parser_1.expressions.Literal], parser.options.filename, 'slot name must be a valid string literal'); | ||
utils_1.isSubsetOf(name, [edge_parser_1.expressions.Literal], () => { | ||
utils_1.unallowedExpression('slot name must be a valid string literal', name, token.filename); | ||
}); | ||
/** | ||
@@ -113,6 +117,8 @@ * Return the slot name with empty props, when the expression is a literal | ||
col: parsed.loc.start.column, | ||
filename: parser.options.filename, | ||
filename: token.filename, | ||
}); | ||
} | ||
utils_1.allowExpressions(parsed.expressions[1], [edge_parser_1.expressions.Identifier], parser.options.filename, `{${parser.stringifyExpression(parsed.expressions[1])}} is not valid prop identifier for @slot tag`); | ||
utils_1.isSubsetOf(parsed.expressions[1], [edge_parser_1.expressions.Identifier], () => { | ||
utils_1.unallowedExpression(`"${parser.utils.stringify(parsed.expressions[1])}" is not valid prop identifier for @slot tag`, parsed.expressions[1], token.filename); | ||
}); | ||
/** | ||
@@ -132,7 +138,9 @@ * Returning the slot name and slot props name | ||
compile(parser, buffer, token) { | ||
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc); | ||
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename); | ||
/** | ||
* Check component js props for allowed expressions | ||
* Check component jsProps for allowed expressions | ||
*/ | ||
utils_1.allowExpressions(parsed, componentNameAllowedExpressions.concat(edge_parser_1.expressions.SequenceExpression), parser.options.filename, `{${token.properties.jsArg}} is not a valid argument type for the @component tag`); | ||
utils_1.isSubsetOf(parsed, ALLOWED_EXPRESSION_FOR_COMPONENT_NAME.concat(edge_parser_1.expressions.SequenceExpression), () => { | ||
utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid argument type for the @component tag`, parsed, token.filename); | ||
}); | ||
/** | ||
@@ -142,3 +150,3 @@ * Pulling the name and props for the component. The underlying method will | ||
*/ | ||
const [name, props] = getComponentNameAndProps(parsed, parser); | ||
const [name, props] = getComponentNameAndProps(parsed, parser, token.filename); | ||
/** | ||
@@ -149,36 +157,74 @@ * Loop over all the children and set them as part of slots. If no slot | ||
const slots = {}; | ||
/** | ||
* Main slot collects everything that is out of the named slots | ||
* inside a component | ||
*/ | ||
const mainSlot = { | ||
props: {}, | ||
buffer: new edge_parser_1.EdgeBuffer(token.filename, false, { outputVar: 'slot_main' }), | ||
line: -1, | ||
filename: token.filename, | ||
}; | ||
/** | ||
* Loop over all the component children | ||
*/ | ||
token.children.forEach((child, index) => { | ||
let slotName = `'main'`; | ||
let slotProps = null; | ||
/** | ||
* Update the slot name and props when a new slot is detected | ||
* If children is not a slot, then add it to the main slot | ||
*/ | ||
if (utils_1.isBlockToken(child, 'slot')) { | ||
[slotName, slotProps] = getSlotNameAndProps(child, parser); | ||
if (!edge_lexer_1.utils.isTag(child, 'slot')) { | ||
parser.processToken(child, mainSlot.buffer); | ||
return; | ||
} | ||
/** | ||
* Fetch slot and props | ||
*/ | ||
const [slotName, slotProps] = getSlotNameAndProps(child, parser); | ||
/** | ||
* Create a new slot with buffer to process the childs | ||
*/ | ||
if (!slots[slotName]) { | ||
slots[slotName] = { buffer: new edge_parser_1.EdgeBuffer(`slot_${index}`), props: slotProps }; | ||
/** | ||
* Slot buffer points to the component file name, since slots doesn't | ||
* have their own file names. | ||
*/ | ||
slots[slotName] = { | ||
buffer: new edge_parser_1.EdgeBuffer(token.filename, false, { outputVar: `slot_${index}` }), | ||
props: slotProps, | ||
line: -1, | ||
filename: token.filename, | ||
}; | ||
/** | ||
* Only start the frame, when there are props in use for a given slot. | ||
*/ | ||
if (slotProps) { | ||
slots[slotName].buffer.writeStatement('ctx.newFrame();'); | ||
slots[slotName].buffer.writeStatement(`ctx.setOnFrame('${slotProps}', ${slotProps});`); | ||
slots[slotName].buffer.writeExpression('ctx.newFrame()', slots[slotName].filename, slots[slotName].line); | ||
slots[slotName].buffer.writeExpression(`ctx.setOnFrame('${slotProps}', ${slotProps})`, slots[slotName].filename, slots[slotName].line); | ||
} | ||
} | ||
/** | ||
* We must process slot of a component by ourselves (instead of making slot tag) | ||
* process it. This way, we can disallow slots appearing outside the component | ||
* tag | ||
* Self process the slot children. | ||
*/ | ||
if (utils_1.isBlockToken(child, 'slot')) { | ||
child.children.forEach((token) => parser.processLexerToken(token, slots[slotName].buffer)); | ||
child.children.forEach((grandChildren) => parser.processToken(grandChildren, slots[slotName].buffer)); | ||
/** | ||
* Close the frame after process the slot children | ||
*/ | ||
if (slotProps) { | ||
slots[slotName].buffer.writeExpression('ctx.removeFrame()', slots[slotName].filename, slots[slotName].line); | ||
} | ||
}); | ||
const obj = new StringifiedObject_1.StringifiedObject(); | ||
/** | ||
* Add main slot to the stringified object, when main slot | ||
* is not defined otherwise. | ||
*/ | ||
if (!slots['main']) { | ||
if (mainSlot.buffer.size) { | ||
mainSlot.buffer.wrap('function () {', '}'); | ||
obj.add('main', mainSlot.buffer.flush()); | ||
} | ||
else { | ||
parser.processLexerToken(child, slots[slotName].buffer); | ||
obj.add('main', 'function () { return "" }'); | ||
} | ||
}); | ||
} | ||
/** | ||
@@ -188,13 +234,11 @@ * We convert the slots to an objectified string, that is passed to `template.renderWithState`, | ||
*/ | ||
const obj = new StringifiedObject_1.StringifiedObject(); | ||
Object.keys(slots).forEach((slot) => { | ||
/** | ||
* Cleanup the previously started frame scope | ||
*/ | ||
if (slots[slot].props) { | ||
slots[slot].buffer.writeStatement('ctx.removeFrame();'); | ||
Object.keys(slots).forEach((slotName) => { | ||
if (slots[slotName].buffer.size) { | ||
const fnCall = slots[slotName].props ? `function (${slots[slotName].props}) {` : 'function () {'; | ||
slots[slotName].buffer.wrap(fnCall, '}'); | ||
obj.add(slotName, slots[slotName].buffer.flush()); | ||
} | ||
const fnCall = slots[slot].props ? `return function (${slots[slot].props}) {` : 'return function () {'; | ||
slots[slot].buffer.wrap(fnCall, '};'); | ||
obj.add(slot, slots[slot].buffer.flush(true)); | ||
else { | ||
obj.add(slotName, 'function () { return "" }'); | ||
} | ||
}); | ||
@@ -204,4 +248,4 @@ /** | ||
*/ | ||
buffer.writeLine(`template.renderWithState(${name}, ${props}, ${obj.flush()})`); | ||
buffer.outputExpression(`template.renderWithState(${name}, ${props}, ${obj.flush()})`, token.filename, token.loc.start.line, false); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
/* | ||
* 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. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -20,5 +25,5 @@ /** | ||
*/ | ||
compile(_parser, buffer) { | ||
buffer.writeStatement('debugger;'); | ||
compile(_, buffer, token) { | ||
buffer.writeExpression('debugger', token.filename, token.loc.start.line); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,4 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_lexer_1 = require("edge-lexer"); | ||
const edge_parser_1 = require("edge-parser"); | ||
@@ -21,4 +19,4 @@ const lodash_1 = require("lodash"); | ||
*/ | ||
function getLoopList(expression, parser) { | ||
return parser.stringifyExpression(parser.acornToEdgeExpression(expression)); | ||
function getLoopList(expression, parser, filename) { | ||
return parser.utils.stringify(parser.utils.transformAst(expression, filename)); | ||
} | ||
@@ -29,3 +27,5 @@ /** | ||
function getLoopItemAndIndex(expression, filename) { | ||
utils_1.allowExpressions(expression, [edge_parser_1.expressions.SequenceExpression, edge_parser_1.expressions.Identifier], filename, `invalid left hand side expression for the @each tag`); | ||
utils_1.isSubsetOf(expression, [edge_parser_1.expressions.SequenceExpression, edge_parser_1.expressions.Identifier], () => { | ||
utils_1.unallowedExpression(`invalid left hand side "${expression.type}" for the @each tag`, expression, filename); | ||
}); | ||
/** | ||
@@ -35,4 +35,8 @@ * Return list index from the sequence expression | ||
if (expression.type === 'SequenceExpression') { | ||
utils_1.allowExpressions(expression.expressions[0], [edge_parser_1.expressions.Identifier], filename, `invalid expression for {value} identifier for the @each tag`); | ||
utils_1.allowExpressions(expression.expressions[1], [edge_parser_1.expressions.SequenceExpression, edge_parser_1.expressions.Identifier], filename, `invalid expression for {key} identifier for the @each tag`); | ||
utils_1.isSubsetOf(expression.expressions[0], [edge_parser_1.expressions.Identifier], () => { | ||
utils_1.unallowedExpression(`"${expression.expressions[0]}.type" is not allowed as value identifier for @each tag`, expression.expressions[0], filename); | ||
}); | ||
utils_1.isSubsetOf(expression.expressions[1], [edge_parser_1.expressions.Identifier], () => { | ||
utils_1.unallowedExpression(`"${expression.expressions[1]}.type" is not allowed as key identifier for @each tag`, expression.expressions[1], filename); | ||
}); | ||
return [expression.expressions[0].name, expression.expressions[1].name]; | ||
@@ -60,13 +64,13 @@ } | ||
/** | ||
* Instead of using `parser.generateEdgeExpression`, we make use of | ||
* `generateAcornExpression`, since we do not want to process | ||
* `Indentifer` expressions as per the normal parsing logic | ||
* and just want to extract it's name. | ||
* We just generate the AST and do not transform it, since the transform | ||
* function attempts to resolve identifiers | ||
*/ | ||
const parsed = parser.generateAcornExpression(token.properties.jsArg, token.loc).expression; | ||
utils_1.allowExpressions(parsed, [edge_parser_1.expressions.BinaryExpression], parser.options.filename, `{${token.properties.jsArg}} is not a valid binary expression for the @each tag`); | ||
const parsed = parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename).expression; | ||
utils_1.isSubsetOf(parsed, [edge_parser_1.expressions.BinaryExpression], () => { | ||
utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid binary expression for the @each tag`, parsed, token.filename); | ||
}); | ||
/** | ||
* Finding if an else child exists inside the each tag | ||
*/ | ||
const elseIndex = token.children.findIndex((child) => utils_1.isBlockToken(child, 'else')); | ||
const elseIndex = token.children.findIndex((child) => edge_lexer_1.utils.isTag(child, 'else')); | ||
const elseChild = elseIndex > -1 ? token.children.splice(elseIndex) : []; | ||
@@ -76,4 +80,4 @@ /** | ||
*/ | ||
const [item, index] = getLoopItemAndIndex(parsed.left, parser.options.filename); | ||
const list = getLoopList(parsed.right, parser); | ||
const [item, index] = getLoopItemAndIndex(parsed.left, token.filename); | ||
const list = getLoopList(parsed.right, parser, token.filename); | ||
/** | ||
@@ -84,4 +88,3 @@ * If there is an else statement, then wrap the loop | ||
if (elseIndex > -1) { | ||
buffer.writeStatement(`if(ctx.size(${list})) {`); | ||
buffer.indent(); | ||
buffer.writeStatement(`if(ctx.size(${list})) {`, token.filename, token.loc.start.line); | ||
} | ||
@@ -91,8 +94,4 @@ /** | ||
*/ | ||
buffer.writeStatement(`ctx.loop(${list}, function (${item}, loop) {`); | ||
buffer.writeStatement(`ctx.loop(${list}, function (${item}, loop) {`, token.filename, token.loc.start.line); | ||
/** | ||
* Indent block | ||
*/ | ||
buffer.indent(); | ||
/** | ||
* Start a new context frame. Frame ensures the value inside | ||
@@ -102,27 +101,21 @@ * the loop is given priority over top level values. Think | ||
*/ | ||
buffer.writeStatement('ctx.newFrame();'); | ||
buffer.writeExpression('ctx.newFrame()', token.filename, -1); | ||
/** | ||
* Set key and value pair on the context | ||
*/ | ||
buffer.writeStatement(`ctx.setOnFrame('${item}', ${item});`); | ||
buffer.writeStatement(`ctx.setOnFrame('$loop', loop);`); | ||
buffer.writeStatement(`ctx.setOnFrame('${index}', loop.key);`); | ||
buffer.writeExpression(`ctx.setOnFrame('${item}', ${item})`, token.filename, -1); | ||
buffer.writeExpression('ctx.setOnFrame(\'$loop\', loop)', token.filename, -1); | ||
buffer.writeExpression(`ctx.setOnFrame('${index}', loop.key)`, token.filename, -1); | ||
/** | ||
* Process all kids | ||
*/ | ||
token.children.forEach((child) => { | ||
parser.processLexerToken(child, buffer); | ||
}); | ||
token.children.forEach((child) => parser.processToken(child, buffer)); | ||
/** | ||
* Remove the frame | ||
*/ | ||
buffer.writeStatement('ctx.removeFrame();'); | ||
buffer.writeExpression('ctx.removeFrame()', token.filename, -1); | ||
/** | ||
* Dedent block | ||
*/ | ||
buffer.dedent(); | ||
/** | ||
* Close each loop | ||
*/ | ||
buffer.writeStatement('});'); | ||
buffer.writeExpression('})', token.filename, -1); | ||
/** | ||
@@ -133,5 +126,4 @@ * If there is an else statement, then process | ||
if (elseIndex > -1) { | ||
elseChild.forEach((child) => parser.processLexerToken(child, buffer)); | ||
buffer.dedent(); | ||
buffer.writeStatement(`}`); | ||
elseChild.forEach((child) => parser.processToken(child, buffer)); | ||
buffer.writeStatement('}', token.filename, -1); | ||
} | ||
@@ -138,0 +130,0 @@ }, |
@@ -1,5 +0,2 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
export declare const elseTag: TagContract; |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
/* | ||
* 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. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -13,7 +18,5 @@ exports.elseTag = { | ||
*/ | ||
compile(_parser, buffer) { | ||
buffer.dedent(); | ||
buffer.writeStatement(`} else {`); | ||
buffer.indent(); | ||
compile(_, buffer, token) { | ||
buffer.writeStatement('} else {', token.filename, -1); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_parser_1 = require("edge-parser"); | ||
@@ -36,17 +33,11 @@ const utils_1 = require("../utils"); | ||
compile(parser, buffer, token) { | ||
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc); | ||
utils_1.disAllowExpressions(parsed, [edge_parser_1.expressions.SequenceExpression], parser.options.filename, `{${token.properties.jsArg}} is not a valid argument type for the @elseif tag`); | ||
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename); | ||
utils_1.isNotSubsetOf(parsed, [edge_parser_1.expressions.SequenceExpression], () => { | ||
utils_1.unallowedExpression(`{${token.properties.jsArg}} is not a valid argument type for the @elseif tag`, parsed, token.filename); | ||
}); | ||
/** | ||
* Dedent block | ||
*/ | ||
buffer.dedent(); | ||
/** | ||
* Start else block | ||
*/ | ||
buffer.writeStatement(`} else if(${parser.stringifyExpression(parsed)}) {`); | ||
/** | ||
* Indent block again | ||
*/ | ||
buffer.indent(); | ||
buffer.writeStatement(`} else if (${parser.utils.stringify(parsed)}) {`, token.filename, token.loc.start.line); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_parser_1 = require("edge-parser"); | ||
@@ -33,25 +30,19 @@ const utils_1 = require("../utils"); | ||
compile(parser, buffer, token) { | ||
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc); | ||
utils_1.disAllowExpressions(parsed, [edge_parser_1.expressions.SequenceExpression], parser.options.filename, `{${token.properties.jsArg}} is not a valid argument type for the @if tag`); | ||
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename); | ||
utils_1.isNotSubsetOf(parsed, [edge_parser_1.expressions.SequenceExpression], () => { | ||
utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid argument type for the @if tag`, parsed, token.filename); | ||
}); | ||
/** | ||
* Start if block | ||
*/ | ||
buffer.writeStatement(`if(${parser.stringifyExpression(parsed)}) {`); | ||
buffer.writeStatement(`if (${parser.utils.stringify(parsed)}) {`, token.filename, token.loc.start.line); | ||
/** | ||
* Indent upcoming code | ||
*/ | ||
buffer.indent(); | ||
/** | ||
* Process of all kids recursively | ||
*/ | ||
token.children.forEach((child) => parser.processLexerToken(child, buffer)); | ||
token.children.forEach((child) => parser.processToken(child, buffer)); | ||
/** | ||
* Remove identation | ||
*/ | ||
buffer.dedent(); | ||
/** | ||
* Close if block | ||
*/ | ||
buffer.writeStatement('}'); | ||
buffer.writeStatement('}', token.filename, -1); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_parser_1 = require("edge-parser"); | ||
@@ -33,4 +30,4 @@ const utils_1 = require("../utils"); | ||
compile(parser, buffer, token) { | ||
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc); | ||
utils_1.allowExpressions(parsed, [ | ||
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename); | ||
utils_1.isSubsetOf(parsed, [ | ||
edge_parser_1.expressions.Identifier, | ||
@@ -43,3 +40,5 @@ edge_parser_1.expressions.Literal, | ||
edge_parser_1.expressions.TemplateLiteral, | ||
], parser.options.filename, `{${token.properties.jsArg}} is not a valid argument type for the @include tag`); | ||
], () => { | ||
utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid argument type for the @include tag`, parsed, token.filename); | ||
}); | ||
/** | ||
@@ -50,4 +49,4 @@ * Include template. Since the partials can be a runtime value, we cannot inline | ||
*/ | ||
buffer.writeLine(`template.renderInline(${parser.stringifyExpression(parsed)})(template, ctx)`); | ||
buffer.outputExpression(`template.renderInline(${parser.utils.stringify(parsed)})(template, ctx)`, token.filename, token.loc.start.line, true); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
export { ifTag as if } from './If'; | ||
@@ -5,0 +2,0 @@ export { elseTag as else } from './Else'; |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var If_1 = require("./If"); | ||
@@ -16,0 +13,0 @@ exports.if = If_1.ifTag; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
/* | ||
* 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. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -6,0 +11,0 @@ /** |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
/* | ||
* 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. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -15,4 +20,4 @@ /** | ||
compile(parser, buffer, token) { | ||
token.children.forEach((token) => parser.processLexerToken(token, buffer)); | ||
token.children.forEach((child) => parser.processToken(child, buffer)); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,4 +10,5 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_error_1 = require("edge-error"); | ||
const edge_parser_1 = require("edge-parser"); | ||
const edge_error_1 = require("edge-error"); | ||
const utils_1 = require("../utils"); | ||
@@ -44,27 +41,31 @@ /** | ||
compile(parser, buffer, token) { | ||
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc); | ||
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename); | ||
/** | ||
* The set tag only accepts a sequence expression. | ||
*/ | ||
utils_1.allowExpressions(parsed, [edge_parser_1.expressions.SequenceExpression], parser.options.filename, `{${token.properties.jsArg}} is not a valid key-value pair for the @slot tag`); | ||
utils_1.isSubsetOf(parsed, [edge_parser_1.expressions.SequenceExpression], () => { | ||
throw utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid key-value pair for the @slot tag`, parsed, token.filename); | ||
}); | ||
/** | ||
* Disallow more than 2 values for the sequence expression | ||
*/ | ||
if (parsed.expressions.length > 2) { | ||
throw new edge_error_1.EdgeError(`maximum of 2 arguments are allowed for the @set tag`, 'E_MAX_ARGUMENTS', { | ||
if (parsed.expressions.length > 3) { | ||
throw new edge_error_1.EdgeError('maximum of 3 arguments are allowed for the @set tag', 'E_MAX_ARGUMENTS', { | ||
line: parsed.loc.start.line, | ||
col: parsed.loc.start.column, | ||
filename: parser.options.filename, | ||
filename: token.filename, | ||
}); | ||
} | ||
const [key, value] = parsed.expressions; | ||
const [key, value, isolated] = parsed.expressions; | ||
/** | ||
* The key has to be a literal value | ||
*/ | ||
utils_1.allowExpressions(key, [edge_parser_1.expressions.Literal], parser.options.filename, 'The first argument for @set tag must be a string literal'); | ||
utils_1.isSubsetOf(key, [edge_parser_1.expressions.Literal], () => { | ||
throw utils_1.unallowedExpression('The first argument for @set tag must be a string literal', parsed, token.filename); | ||
}); | ||
/** | ||
* Write statement to mutate the key | ||
*/ | ||
buffer.writeStatement(`ctx.set(${key.raw}, ${parser.stringifyExpression(value)});`); | ||
buffer.writeExpression(`ctx.set(${key.raw}, ${parser.utils.stringify(value)}, ${!!isolated})`, token.filename, token.loc.start.line); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_error_1 = require("edge-error"); | ||
@@ -24,9 +21,9 @@ /** | ||
tagName: 'slot', | ||
compile(parser, _buffer, token) { | ||
throw new edge_error_1.EdgeError(`@slot tag must appear as top level tag inside the @component tag`, 'E_ORPHAN_SLOT_TAG', { | ||
compile(_, __, token) { | ||
throw new edge_error_1.EdgeError('@slot tag must appear as top level tag inside the @component tag', 'E_ORPHAN_SLOT_TAG', { | ||
line: token.loc.start.line, | ||
col: token.loc.start.col, | ||
filename: parser.options.filename, | ||
filename: token.filename, | ||
}); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
/* | ||
* 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. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -6,0 +11,0 @@ /** |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_parser_1 = require("edge-parser"); | ||
@@ -35,27 +32,19 @@ const utils_1 = require("../utils"); | ||
compile(parser, buffer, token) { | ||
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc); | ||
utils_1.disAllowExpressions(parsed, [edge_parser_1.expressions.SequenceExpression], parser.options.filename, `{${token.properties.jsArg}} is not a valid argument type for the @unless tag`); | ||
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename); | ||
utils_1.isNotSubsetOf(parsed, [edge_parser_1.expressions.SequenceExpression], () => { | ||
utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid argument type for the @unless tag`, parsed, token.filename); | ||
}); | ||
/** | ||
* Start if block | ||
*/ | ||
buffer.writeStatement(`if(!${parser.stringifyExpression(parsed)}) {`); | ||
buffer.writeStatement(`if (!${parser.utils.stringify(parsed)}) {`, token.filename, token.loc.start.line); | ||
/** | ||
* Indent upcoming code | ||
*/ | ||
buffer.indent(); | ||
/** | ||
* Process of all kids recursively | ||
*/ | ||
token.children.forEach((child) => { | ||
parser.processLexerToken(child, buffer); | ||
}); | ||
token.children.forEach((child) => parser.processToken(child, buffer)); | ||
/** | ||
* Remove identation | ||
*/ | ||
buffer.dedent(); | ||
/** | ||
* Close if block | ||
*/ | ||
buffer.writeStatement('}'); | ||
buffer.writeStatement('}', token.filename, -1); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { TagContract } from '../Contracts'; | ||
@@ -5,0 +2,0 @@ /** |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_parser_1 = require("edge-parser"); | ||
@@ -44,12 +41,15 @@ const utils_1 = require("../utils"); | ||
compile(parser, buffer, token) { | ||
const parsed = parser.generateEdgeExpression(token.properties.jsArg, token.loc); | ||
utils_1.disAllowExpressions(parsed, [edge_parser_1.expressions.SequenceExpression], parser.options.filename, `{${token.properties.jsArg}} is not a valid argument type for the @yield tag`); | ||
const parsedString = parser.stringifyExpression(parsed); | ||
let yieldCounter = buffer['yieldCounter'] || 0; | ||
buffer['yieldCounter'] = yieldCounter++; | ||
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename); | ||
utils_1.isNotSubsetOf(parsed, [edge_parser_1.expressions.SequenceExpression], () => { | ||
utils_1.unallowedExpression(`"${token.properties.jsArg}" is not a valid argument type for the @yield tag`, parsed, token.filename); | ||
}); | ||
const parsedString = parser.utils.stringify(parsed); | ||
/** | ||
* Write main content when it's truthy | ||
*/ | ||
buffer.writeStatement(`if(${parsedString}) {`); | ||
buffer.indent(); | ||
buffer.writeLine(parsedString); | ||
buffer.dedent(); | ||
buffer.writeExpression(`let yield_${yieldCounter} = ${parsedString}`, token.filename, token.loc.start.line); | ||
buffer.writeStatement(`if (yield_${yieldCounter}) {`, token.filename, -1); | ||
buffer.outputExpression(`yield_${yieldCounter}`, token.filename, -1, true); | ||
/** | ||
@@ -59,9 +59,7 @@ * Else write fallback | ||
if (!token.properties.selfclosed) { | ||
buffer.writeStatement('} else {'); | ||
buffer.indent(); | ||
token.children.forEach((child) => (parser.processLexerToken(child, buffer))); | ||
buffer.dedent(); | ||
buffer.writeStatement('} else {', token.filename, -1); | ||
token.children.forEach((child) => (parser.processToken(child, buffer))); | ||
} | ||
buffer.writeStatement('}'); | ||
buffer.writeStatement('}', token.filename, -1); | ||
}, | ||
}; |
@@ -1,4 +0,1 @@ | ||
/** | ||
* @module edge | ||
*/ | ||
import { CompilerContract } from '../Contracts'; | ||
@@ -11,3 +8,3 @@ /** | ||
export declare class Template { | ||
private _compiler; | ||
private compiler; | ||
/** | ||
@@ -17,4 +14,4 @@ * The shared state is used to hold the globals and locals, | ||
*/ | ||
private _sharedState; | ||
constructor(_compiler: CompilerContract, globals: any, locals: any); | ||
private sharedState; | ||
constructor(compiler: CompilerContract, globals: any, locals: any); | ||
/** | ||
@@ -21,0 +18,0 @@ * Render the template inline by sharing the state of the current template. |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,2 +10,3 @@ * edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const lodash_1 = require("lodash"); | ||
@@ -24,5 +21,5 @@ const Context_1 = require("../Context"); | ||
class Template { | ||
constructor(_compiler, globals, locals) { | ||
this._compiler = _compiler; | ||
this._sharedState = lodash_1.merge({}, globals, locals); | ||
constructor(compiler, globals, locals) { | ||
this.compiler = compiler; | ||
this.sharedState = lodash_1.merge({}, globals, locals); | ||
} | ||
@@ -40,3 +37,3 @@ /** | ||
renderInline(templatePath) { | ||
return new Function('template', 'ctx', this._compiler.compile(templatePath, true).template); | ||
return new Function('template', 'ctx', this.compiler.compile(templatePath, true).template); | ||
} | ||
@@ -55,6 +52,6 @@ /** | ||
renderWithState(template, state, slots) { | ||
const { template: compiledTemplate, Presenter } = this._compiler.compile(template, false); | ||
const presenter = new (Presenter || Presenter_1.Presenter)(lodash_1.merge(state, { $slots: slots })); | ||
const ctx = new Context_1.Context(presenter, this._sharedState); | ||
return new Function('template', 'ctx', `return ${compiledTemplate}`)(this, ctx); | ||
const { template: compiledTemplate, Presenter } = this.compiler.compile(template, false); | ||
const presenter = new (Presenter || Presenter_1.Presenter)(lodash_1.merge(state, { $slots: slots }), this.sharedState); | ||
const ctx = new Context_1.Context(presenter); | ||
return new Function('template', 'ctx', compiledTemplate)(this, ctx); | ||
} | ||
@@ -69,8 +66,8 @@ /** | ||
render(template, state) { | ||
const { template: compiledTemplate, Presenter } = this._compiler.compile(template, false); | ||
const presenter = new (Presenter || Presenter_1.Presenter)(state); | ||
const ctx = new Context_1.Context(presenter, this._sharedState); | ||
return new Function('template', 'ctx', `return ${compiledTemplate}`)(this, ctx); | ||
const { template: compiledTemplate, Presenter } = this.compiler.compile(template, false); | ||
const presenter = new (Presenter || Presenter_1.Presenter)(state, this.sharedState); | ||
const ctx = new Context_1.Context(presenter); | ||
return new Function('template', 'ctx', compiledTemplate)(this, ctx); | ||
} | ||
} | ||
exports.Template = Template; |
@@ -0,5 +1,8 @@ | ||
import { expressions as expressionsList } from 'edge-parser'; | ||
declare type ExpressionList = readonly (keyof typeof expressionsList)[]; | ||
/** | ||
* @module edge | ||
* Raise an `E_UNALLOWED_EXPRESSION` exception. Filename and expression is | ||
* required to point the error stack to the correct file | ||
*/ | ||
import { Parser, expressions as expressionsList, ParserToken, ParserTagToken } from 'edge-parser'; | ||
export declare function unallowedExpression(message: string, expression: any, filename: string): void; | ||
/** | ||
@@ -12,6 +15,6 @@ * Validates the expression type to be part of the allowed | ||
* ```js | ||
* allowExpressions('include', 'SequenceExpression', ['Literal', 'Identifier'], 'foo.edge') | ||
* isNotSubsetOf(expression, ['Literal', 'Identifier'], () => {}) | ||
* ``` | ||
*/ | ||
export declare function allowExpressions(expression: any, expressions: (keyof typeof expressionsList)[], filename: string, message: string): void; | ||
export declare function isSubsetOf(expression: any, expressions: ExpressionList, errorCallback: () => void): void; | ||
/** | ||
@@ -24,45 +27,6 @@ * Validates the expression type not to be part of the disallowed | ||
* ```js | ||
* disAllowExpressions('include', 'SequenceExpression', ['Literal', 'Identifier'], 'foo.edge') | ||
* isNotSubsetOf(expression, 'SequenceExpression', () => {}) | ||
* ``` | ||
*/ | ||
export declare function disAllowExpressions(expression: any, expressions: (keyof typeof expressionsList)[], filename: string, message: string): void; | ||
/** | ||
* 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 declare function expressionsToStringifyObject(expressions: any[], parser: Parser): string; | ||
/** | ||
* 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 declare function extractDiskAndTemplateName(templatePath: string): [string, string]; | ||
/** | ||
* Returns a boolean, telling whether the lexer node is a block node | ||
* or not. | ||
*/ | ||
export declare function isBlockToken(token: ParserToken, name: string): token is ParserTagToken; | ||
/** | ||
* Returns line and number for a given AST token | ||
*/ | ||
export declare function getLineAndColumnForToken(token: ParserToken): [number, number]; | ||
export declare function isNotSubsetOf(expression: any, expressions: ExpressionList, errorCallback: () => void): void; | ||
export {}; |
"use strict"; | ||
/** | ||
* @module edge | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
@@ -14,7 +10,17 @@ * edge | ||
*/ | ||
const path_1 = require("path"); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const edge_error_1 = require("edge-error"); | ||
const edge_lexer_1 = require("edge-lexer"); | ||
const StringifiedObject_1 = require("../StringifiedObject"); | ||
/** | ||
* Raise an `E_UNALLOWED_EXPRESSION` exception. Filename and expression is | ||
* required to point the error stack to the correct file | ||
*/ | ||
function unallowedExpression(message, expression, filename) { | ||
throw new edge_error_1.EdgeError(message, 'E_UNALLOWED_EXPRESSION', { | ||
line: expression.loc.start.line, | ||
col: expression.loc.start.column, | ||
filename: filename, | ||
}); | ||
} | ||
exports.unallowedExpression = unallowedExpression; | ||
/** | ||
* Validates the expression type to be part of the allowed | ||
@@ -26,15 +32,11 @@ * expressions only. | ||
* ```js | ||
* allowExpressions('include', 'SequenceExpression', ['Literal', 'Identifier'], 'foo.edge') | ||
* isNotSubsetOf(expression, ['Literal', 'Identifier'], () => {}) | ||
* ``` | ||
*/ | ||
function allowExpressions(expression, expressions, filename, message) { | ||
function isSubsetOf(expression, expressions, errorCallback) { | ||
if (!expressions.includes(expression.type)) { | ||
throw new edge_error_1.EdgeError(message, 'E_UNALLOWED_EXPRESSION', { | ||
line: expression.loc.start.line, | ||
col: expression.loc.start.column, | ||
filename: filename, | ||
}); | ||
errorCallback(); | ||
} | ||
} | ||
exports.allowExpressions = allowExpressions; | ||
exports.isSubsetOf = isSubsetOf; | ||
/** | ||
@@ -47,91 +49,10 @@ * Validates the expression type not to be part of the disallowed | ||
* ```js | ||
* disAllowExpressions('include', 'SequenceExpression', ['Literal', 'Identifier'], 'foo.edge') | ||
* isNotSubsetOf(expression, 'SequenceExpression', () => {}) | ||
* ``` | ||
*/ | ||
function disAllowExpressions(expression, expressions, filename, message) { | ||
function isNotSubsetOf(expression, expressions, errorCallback) { | ||
if (expressions.includes(expression.type)) { | ||
throw new edge_error_1.EdgeError(message, 'E_UNALLOWED_EXPRESSION', { | ||
line: expression.loc.start.line, | ||
col: expression.loc.start.column, | ||
filename: filename, | ||
}); | ||
errorCallback(); | ||
} | ||
} | ||
exports.disAllowExpressions = disAllowExpressions; | ||
/** | ||
* 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' } | ||
* ``` | ||
*/ | ||
function expressionsToStringifyObject(expressions, parser) { | ||
const objectifyString = new StringifiedObject_1.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(); | ||
} | ||
exports.expressionsToStringifyObject = expressionsToStringifyObject; | ||
/** | ||
* 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'] | ||
* ``` | ||
*/ | ||
function extractDiskAndTemplateName(templatePath) { | ||
let [disk, ...rest] = templatePath.split('::'); | ||
if (!rest.length) { | ||
rest = [disk]; | ||
disk = 'default'; | ||
} | ||
const [template, ext] = rest.join('::').split('.edge'); | ||
return [disk, `${template.replace(/\./, path_1.sep)}.${ext || 'edge'}`]; | ||
} | ||
exports.extractDiskAndTemplateName = extractDiskAndTemplateName; | ||
/** | ||
* Returns a boolean, telling whether the lexer node is a block node | ||
* or not. | ||
*/ | ||
function isBlockToken(token, name) { | ||
if (token.type === edge_lexer_1.TagTypes.TAG || token.type === edge_lexer_1.TagTypes.ETAG) { | ||
return token.properties.name === name; | ||
} | ||
return false; | ||
} | ||
exports.isBlockToken = isBlockToken; | ||
/** | ||
* Returns line and number for a given AST token | ||
*/ | ||
function getLineAndColumnForToken(token) { | ||
if (token.type === 'newline' || token.type === 'raw') { | ||
return [token.line, 0]; | ||
} | ||
return [token.loc.start.line, token.loc.start.col]; | ||
} | ||
exports.getLineAndColumnForToken = getLineAndColumnForToken; | ||
exports.isNotSubsetOf = isNotSubsetOf; |
{ | ||
"name": "edge.js", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "Template engine", | ||
@@ -20,3 +20,3 @@ "main": "build/index.js", | ||
"build": "npm run compile", | ||
"lint": "tslint --project tsconfig.json", | ||
"lint": "eslint . --ext=.ts", | ||
"release": "np", | ||
@@ -38,8 +38,11 @@ "version": "npm run build" | ||
"@poppinss/dev-utils": "^1.0.4", | ||
"@types/node": "^13.7.6", | ||
"@types/lodash": "^4.14.149", | ||
"@types/node": "^13.9.0", | ||
"commitizen": "^4.0.3", | ||
"cz-conventional-changelog": "^3.1.0", | ||
"dedent": "^0.7.0", | ||
"dedent-js": "^1.0.1", | ||
"del-cli": "^3.0.0", | ||
"doctoc": "^1.4.0", | ||
"eslint": "^6.8.0", | ||
"eslint-plugin-adonis": "^1.0.8", | ||
"fs-extra": "^8.1.0", | ||
@@ -51,8 +54,6 @@ "husky": "^4.2.3", | ||
"ts-node": "^8.6.2", | ||
"tslint": "^6.0.0", | ||
"tslint-eslint-rules": "^5.4.0", | ||
"typedoc": "^0.16.10", | ||
"typedoc": "^0.16.11", | ||
"typedoc-clarity-theme": "^1.1.0", | ||
"typedoc-plugin-external-module-name": "^3.0.0", | ||
"typescript": "^3.8.2", | ||
"typescript": "^3.8.3", | ||
"yorkie": "^2.0.0", | ||
@@ -77,3 +78,4 @@ "youch": "^2.0.10" | ||
"edge-error": "^1.0.4", | ||
"edge-parser": "^2.1.2", | ||
"edge-lexer": "^2.1.0", | ||
"edge-parser": "^3.0.8", | ||
"he": "^1.2.0", | ||
@@ -80,0 +82,0 @@ "import-fresh": "^3.2.1", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
109338
3140
8
23
+ Addededge-lexer@^2.1.0
+ Addededge-parser@3.0.8(transitive)
+ Addedjs-stringify@1.0.2(transitive)
- Removededge-parser@2.1.2(transitive)
Updatededge-parser@^3.0.8