New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

botbuilder-lg

Package Overview
Dependencies
Maintainers
1
Versions
514
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

botbuilder-lg - npm Package Compare versions

Comparing version 4.11.0-dev.20200909.b3c2acc to 4.11.0-dev.20200911.2b4d430

lib/lgResource.d.ts

21

lib/evaluationOptions.d.ts

@@ -12,2 +12,19 @@ /**

}
/**
* LG cache scope options.
*/
export declare enum LGCacheScope {
/**
* Global template cache scope.
*/
Global = "global",
/**
* Only cache result in the same layer of children in template.
*/
Local = "local",
/**
* Without cache.
*/
None = "none"
}
export declare class EvaluationOptions {

@@ -21,2 +38,6 @@ private readonly nullKeyReplaceStrRegex;

LineBreakStyle: LGLineBreakStyle | undefined;
/**
* Cache scope of the evaluation result.
*/
cacheScope: LGCacheScope | undefined;
constructor(opt?: EvaluationOptions | string[]);

@@ -23,0 +44,0 @@ merge(opt: EvaluationOptions): EvaluationOptions;

@@ -15,2 +15,20 @@ "use strict";

})(LGLineBreakStyle = exports.LGLineBreakStyle || (exports.LGLineBreakStyle = {}));
/**
* LG cache scope options.
*/
var LGCacheScope;
(function (LGCacheScope) {
/**
* Global template cache scope.
*/
LGCacheScope["Global"] = "global";
/**
* Only cache result in the same layer of children in template.
*/
LGCacheScope["Local"] = "local";
/**
* Without cache.
*/
LGCacheScope["None"] = "none";
})(LGCacheScope = exports.LGCacheScope || (exports.LGCacheScope = {}));
class EvaluationOptions {

@@ -26,2 +44,3 @@ constructor(opt) {

this.LineBreakStyle = undefined;
this.cacheScope = undefined;
}

@@ -33,2 +52,3 @@ else {

this.LineBreakStyle = opt.LineBreakStyle;
this.cacheScope = opt.cacheScope;
}

@@ -35,0 +55,0 @@ else {

2

lib/evaluationTarget.d.ts

@@ -24,3 +24,3 @@ /**

*/
evaluatedChildren: Map<string, any>;
cachedEvaluatedChildren: Map<string, any>;
constructor(templateName: string, scope: MemoryInterface);

@@ -27,0 +27,0 @@ /**

@@ -10,3 +10,3 @@ "use strict";

this.scope = scope;
this.evaluatedChildren = new Map();
this.cachedEvaluatedChildren = new Map();
}

@@ -13,0 +13,0 @@ /**

@@ -34,2 +34,3 @@ /**

private readonly lgOptions;
private readonly cacheResult;
static readonly LGType = "lgType";

@@ -36,0 +37,0 @@ static readonly activityAttachmentFunctionName = "ActivityAttachment";

@@ -20,2 +20,3 @@ "use strict";

const templateErrors_1 = require("./templateErrors");
const evaluationOptions_1 = require("./evaluationOptions");
const templates_1 = require("./templates");

@@ -29,2 +30,3 @@ /**

this.evaluationTargetStack = [];
this.cacheResult = new Map();
// Genearte a new lookup function based on one lookup function

@@ -137,16 +139,37 @@ this.customizedEvaluatorLookup = (baseLookup) => (name) => {

}
let previousEvaluateTarget;
if (this.evaluationTargetStack.length !== 0) {
previousEvaluateTarget = this.evaluationTargetStack[this.evaluationTargetStack.length - 1];
if (!reExecute && previousEvaluateTarget.evaluatedChildren.has(currentEvulateId)) {
return previousEvaluateTarget.evaluatedChildren.get(currentEvulateId);
let result;
let hasResult = false;
if (!reExecute) {
if (this.lgOptions.cacheScope === evaluationOptions_1.LGCacheScope.Global) {
if (this.cacheResult.has(currentEvulateId)) {
result = this.cacheResult.get(currentEvulateId);
hasResult = true;
}
}
else if (this.lgOptions.cacheScope === undefined || this.lgOptions.cacheScope === evaluationOptions_1.LGCacheScope.Local) {
let previousEvaluateTarget;
if (this.evaluationTargetStack.length !== 0) {
previousEvaluateTarget = this.evaluationTargetStack[this.evaluationTargetStack.length - 1];
if (previousEvaluateTarget.cachedEvaluatedChildren.has(currentEvulateId)) {
result = previousEvaluateTarget.cachedEvaluatedChildren.get(currentEvulateId);
hasResult = true;
}
}
}
}
// Using a stack to track the evalution trace
this.evaluationTargetStack.push(templateTarget);
let result = this.visit(this.templateMap[templateName].templateBodyParseTree);
if (previousEvaluateTarget) {
previousEvaluateTarget.evaluatedChildren.set(currentEvulateId, result);
if (!hasResult) {
this.evaluationTargetStack.push(templateTarget);
result = this.visit(this.templateMap[templateName].templateBodyParseTree);
this.evaluationTargetStack.pop();
if (!reExecute) {
if (this.lgOptions.cacheScope === evaluationOptions_1.LGCacheScope.Global) {
this.cacheResult.set(currentEvulateId, result);
}
else if (this.lgOptions.cacheScope === undefined || this.lgOptions.cacheScope === evaluationOptions_1.LGCacheScope.Local) {
if (this.evaluationTargetStack.length !== 0) {
this.evaluationTargetStack[this.evaluationTargetStack.length - 1].cachedEvaluatedChildren.set(currentEvulateId, result);
}
}
}
}
this.evaluationTargetStack.pop();
return result;

@@ -153,0 +176,0 @@ }

@@ -31,2 +31,3 @@ /**

export * from './evaluationOptions';
export * from './lgResource';
//# sourceMappingURL=index.d.ts.map

@@ -36,2 +36,3 @@ "use strict";

__export(require("./evaluationOptions"));
__export(require("./lgResource"));
//# sourceMappingURL=index.js.map

@@ -36,3 +36,3 @@ "use strict";

if (this.templates.allTemplates.length === 0) {
const diagnostic = new diagnostic_1.Diagnostic(range_1.Range.DefaultRange, templateErrors_1.TemplateErrors.noTemplate, diagnostic_1.DiagnosticSeverity.Warning, this.templates.id);
const diagnostic = new diagnostic_1.Diagnostic(range_1.Range.DefaultRange, templateErrors_1.TemplateErrors.noTemplate, diagnostic_1.DiagnosticSeverity.Warning, this.templates.source);
result.push(diagnostic);

@@ -49,3 +49,3 @@ return result;

const range = new range_1.Range(startLine, 0, startLine, template.name.length + 1);
const diagnostic = new diagnostic_1.Diagnostic(range, templateErrors_1.TemplateErrors.duplicatedTemplateInDiffTemplate(sameTemplate.name, sameTemplate.sourceRange.source), diagnostic_1.DiagnosticSeverity.Error, this.templates.id);
const diagnostic = new diagnostic_1.Diagnostic(range, templateErrors_1.TemplateErrors.duplicatedTemplateInDiffTemplate(sameTemplate.name, sameTemplate.sourceRange.source), diagnostic_1.DiagnosticSeverity.Error, this.templates.source);
templateDiagnostics.push(diagnostic);

@@ -269,3 +269,3 @@ }

const range = context === undefined ? new range_1.Range(lineOffset + 1, 0, lineOffset + 1, 0) : templateExtensions_1.TemplateExtensions.convertToRange(context, lineOffset);
return new diagnostic_1.Diagnostic(range, templateNameInfo + message, severity, this.templates.id);
return new diagnostic_1.Diagnostic(range, templateNameInfo + message, severity, this.templates.source);
}

@@ -272,0 +272,0 @@ }

@@ -15,2 +15,3 @@ /**

import { EvaluationOptions } from './evaluationOptions';
import { LGResource } from './lgResource';
/**

@@ -49,3 +50,3 @@ * LG entrance, including properties that LG file has, and evaluate functions.

/**
* id of this lg source. For file, is full path.
* Id of the lg resource.
*/

@@ -58,2 +59,6 @@ id: string;

/**
* Source of the lg resource. Full path for lg file.
*/
source: string;
/**
* Delegate for resolving resource id of imported lg file.

@@ -66,3 +71,3 @@ */

options: string[];
constructor(items?: Template[], imports?: TemplateImport[], diagnostics?: Diagnostic[], references?: Templates[], content?: string, id?: string, expressionParser?: ExpressionParser, importResolverDelegate?: ImportResolverDelegate, options?: string[]);
constructor(items?: Template[], imports?: TemplateImport[], diagnostics?: Diagnostic[], references?: Templates[], content?: string, id?: string, expressionParser?: ExpressionParser, importResolverDelegate?: ImportResolverDelegate, options?: string[], source?: string);
/**

@@ -107,2 +112,3 @@ * Returns a new iterator for the template collection.

* Parser to turn lg content into a Templates.
* @deprecated This method will soon be deprecated. Use ParseResource instead.
* @param content Text content contains lg templates.

@@ -116,2 +122,10 @@ * @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.

/**
* Parser to turn lg content into a Templates.
* @param aresource LG resource.
* @param importResolver Resolver to resolve LG import id to template text.
* @param expressionParser Expression parser for evaluating expressions.
* @returns Entity.
*/
static parseResource(resource: LGResource, importResolver?: ImportResolverDelegate, expressionParser?: ExpressionParser): Templates;
/**
* Evaluate a template with given name and scope.

@@ -118,0 +132,0 @@ * @param templateName Template name to be evaluated.

@@ -22,2 +22,3 @@ "use strict";

const staticChecker_1 = require("./staticChecker");
const lgResource_1 = require("./lgResource");
const customizedMemory_1 = require("./customizedMemory");

@@ -28,3 +29,3 @@ /**

class Templates {
constructor(items, imports, diagnostics, references, content, id, expressionParser, importResolverDelegate, options) {
constructor(items, imports, diagnostics, references, content, id, expressionParser, importResolverDelegate, options, source) {
this.newLineRegex = /(\r?\n)/g;

@@ -43,2 +44,3 @@ this.newLine = '\r\n';

this.options = options || [];
this.source = source;
this.injectToExpressionFunction();

@@ -115,2 +117,3 @@ }

* Parser to turn lg content into a Templates.
* @deprecated This method will soon be deprecated. Use ParseResource instead.
* @param content Text content contains lg templates.

@@ -126,2 +129,12 @@ * @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.

/**
* Parser to turn lg content into a Templates.
* @param aresource LG resource.
* @param importResolver Resolver to resolve LG import id to template text.
* @param expressionParser Expression parser for evaluating expressions.
* @returns Entity.
*/
static parseResource(resource, importResolver, expressionParser) {
return templatesParser_2.TemplatesParser.parseResource(resource, importResolver, expressionParser).injectToExpressionFunction();
}
/**
* Evaluate a template with given name and scope.

@@ -203,3 +216,4 @@ * @param templateName Template name to be evaluated.

let updatedTemplates = new Templates([], [], [], [], '', this.id, this.expressionParser, this.importResolver);
updatedTemplates = new templatesParser_1.TemplatesTransformer(updatedTemplates).transform(templatesParser_2.TemplatesParser.antlrParseTemplates(content, this.id));
const resource = new lgResource_1.LGResource(this.id, this.id, content);
updatedTemplates = new templatesParser_1.TemplatesTransformer(updatedTemplates).transform(templatesParser_2.TemplatesParser.antlrParseTemplates(resource));
const originalStartLine = template.sourceRange.range.start.line - 1;

@@ -235,3 +249,4 @@ this.appendDiagnosticWithOffset(updatedTemplates.diagnostics, originalStartLine);

let updatedTemplates = new Templates([], [], [], [], '', this.id, this.expressionParser, this.importResolver);
updatedTemplates = new templatesParser_1.TemplatesTransformer(updatedTemplates).transform(templatesParser_2.TemplatesParser.antlrParseTemplates(content, this.id));
const resource = new lgResource_1.LGResource(this.id, this.id, content);
updatedTemplates = new templatesParser_1.TemplatesTransformer(updatedTemplates).transform(templatesParser_2.TemplatesParser.antlrParseTemplates(resource));
this.appendDiagnosticWithOffset(updatedTemplates.diagnostics, originalStartLine);

@@ -412,4 +427,4 @@ if (updatedTemplates.toArray().length > 0) {

if (!result) {
if (path_1.isAbsolute(this.id)) {
result = path_1.basename(this.id).split('.')[0];
if (path_1.isAbsolute(this.source)) {
result = path_1.basename(this.source).split('.')[0];
}

@@ -416,0 +431,0 @@ else {

@@ -7,6 +7,4 @@ import { FileContext } from './generated/LGFileParser';

import * as lp from './generated/LGFileParser';
export declare type ImportResolverDelegate = (source: string, resourceId: string) => {
content: string;
id: string;
};
import { LGResource } from './lgResource';
export declare type ImportResolverDelegate = (lgResource: LGResource, resourceId: string) => LGResource;
/**

@@ -38,2 +36,3 @@ * LG Parser

* Parser to turn lg content into a Templates.
* @deprecated This method will soon be deprecated. Use ParseResource instead.
* @param content Text content contains lg templates.

@@ -52,10 +51,11 @@ * @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.

static parseTextWithRef(content: string, originalTemplates: Templates): Templates;
static defaultFileResolver(sourceId: string, resourceId: string): {
content: string;
id: string;
};
/**
* Default import resolver, using relative/absolute file path to access the file content.
* @param resource Original Resource.
* @param resourceId Import path.
*/
static defaultFileResolver(resource: LGResource, resourceId: string): LGResource;
/**
* Parser to turn lg content into a Templates.
* @param content Text content contains lg templates.
* @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.
* @param resource LG resource.
* @param importResolver Resolver to resolve LG import id to template text.

@@ -66,10 +66,9 @@ * @param expressionParser Expression parser for evaluating expressions.

*/
static innerParseText(content: string, id?: string, importResolver?: ImportResolverDelegate, expressionParser?: ExpressionParser, cachedTemplates?: Map<string, Templates>): Templates;
static parseResource(resource: LGResource, importResolver?: ImportResolverDelegate, expressionParser?: ExpressionParser, cachedTemplates?: Map<string, Templates>): Templates;
/**
* Parse LG content and return the AST.
* @param text LG content.
* @param source Source id.
* @param resource LG resource.
* @returns The abstract syntax tree of lg file.
*/
static antlrParseTemplates(text: string, source: string): FileContext;
static antlrParseTemplates(resource: LGResource): FileContext;
private static getReferences;

@@ -76,0 +75,0 @@ private static resolveImportResources;

@@ -29,2 +29,3 @@ "use strict";

const LGTemplateParser_1 = require("./generated/LGTemplateParser");
const lgResource_1 = require("./lgResource");
/**

@@ -44,6 +45,8 @@ * LG Parser

const content = fs.readFileSync(fullPath, 'utf-8');
return TemplatesParser.innerParseText(content, fullPath, importResolver, expressionParser);
const resource = new lgResource_1.LGResource(fullPath, fullPath, content);
return TemplatesParser.parseResource(resource, importResolver, expressionParser);
}
/**
* Parser to turn lg content into a Templates.
* @deprecated This method will soon be deprecated. Use ParseResource instead.
* @param content Text content contains lg templates.

@@ -56,3 +59,4 @@ * @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.

static parseText(content, id = '', importResolver, expressionParser) {
return TemplatesParser.innerParseText(content, id, importResolver, expressionParser);
const resource = new lgResource_1.LGResource(id, id, content);
return TemplatesParser.parseResource(resource, importResolver, expressionParser);
}

@@ -72,2 +76,3 @@ /**

newTemplates.id = id;
newTemplates.source = id;
newTemplates.importResolver = originalTemplates.importResolver;

@@ -77,3 +82,4 @@ newTemplates.options = originalTemplates.options;

// eslint-disable-next-line @typescript-eslint/no-use-before-define
newTemplates = new TemplatesTransformer(newTemplates).transform(this.antlrParseTemplates(content, id));
const resource = new lgResource_1.LGResource(id, id, content);
newTemplates = new TemplatesTransformer(newTemplates).transform(this.antlrParseTemplates(resource));
newTemplates.references = this.getReferences(newTemplates)

@@ -95,7 +101,12 @@ .concat(originalTemplates.references)

}
static defaultFileResolver(sourceId, resourceId) {
/**
* Default import resolver, using relative/absolute file path to access the file content.
* @param resource Original Resource.
* @param resourceId Import path.
*/
static defaultFileResolver(resource, resourceId) {
let importPath = templateExtensions_1.TemplateExtensions.normalizePath(resourceId);
if (!path.isAbsolute(importPath)) {
// get full path for importPath relative to path which is doing the import.
importPath = templateExtensions_1.TemplateExtensions.normalizePath(path.join(path.dirname(sourceId), importPath));
importPath = templateExtensions_1.TemplateExtensions.normalizePath(path.join(path.dirname(resource.fullName), importPath));
}

@@ -106,8 +117,7 @@ if (!fs.existsSync(importPath) || !fs.statSync(importPath).isFile()) {

const content = fs.readFileSync(importPath, 'utf-8');
return { content, id: importPath };
return new lgResource_1.LGResource(importPath, importPath, content);
}
/**
* Parser to turn lg content into a Templates.
* @param content Text content contains lg templates.
* @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.
* @param resource LG resource.
* @param importResolver Resolver to resolve LG import id to template text.

@@ -118,11 +128,15 @@ * @param expressionParser Expression parser for evaluating expressions.

*/
static innerParseText(content, id = '', importResolver, expressionParser, cachedTemplates) {
static parseResource(resource, importResolver, expressionParser, cachedTemplates) {
if (!resource) {
throw new Error('lg resource is empty.');
}
cachedTemplates = cachedTemplates || new Map();
if (cachedTemplates.has(id)) {
return cachedTemplates.get(id);
if (cachedTemplates.has(resource.id)) {
return cachedTemplates.get(resource.id);
}
importResolver = importResolver || TemplatesParser.defaultFileResolver;
let templates = new templates_1.Templates();
templates.content = content;
templates.id = id;
templates.content = resource.content;
templates.id = resource.id;
templates.source = resource.fullName;
templates.importResolver = importResolver;

@@ -134,3 +148,3 @@ if (expressionParser) {

// eslint-disable-next-line @typescript-eslint/no-use-before-define
templates = new TemplatesTransformer(templates).transform(this.antlrParseTemplates(content, id));
templates = new TemplatesTransformer(templates).transform(this.antlrParseTemplates(resource));
templates.references = this.getReferences(templates, cachedTemplates);

@@ -152,11 +166,10 @@ const semanticErrors = new staticChecker_1.StaticChecker(templates).check();

* Parse LG content and return the AST.
* @param text LG content.
* @param source Source id.
* @param resource LG resource.
* @returns The abstract syntax tree of lg file.
*/
static antlrParseTemplates(text, source) {
if (!text || text.trim() === '') {
static antlrParseTemplates(resource) {
if (!resource.content || resource.content.trim() === '') {
return undefined;
}
const input = new ANTLRInputStream_1.ANTLRInputStream(text);
const input = new ANTLRInputStream_1.ANTLRInputStream(resource.content);
const lexer = new LGFileLexer_1.LGFileLexer(input);

@@ -166,3 +179,3 @@ const tokens = new CommonTokenStream_1.CommonTokenStream(lexer);

parser.removeErrorListeners();
parser.addErrorListener(new errorListener_1.ErrorListener(source));
parser.addErrorListener(new errorListener_1.ErrorListener(resource.fullName));
parser.buildParseTree = true;

@@ -180,19 +193,19 @@ return parser.file();

for (const importItem of start.imports) {
let content;
let path;
let resource;
try {
({ content, id: path } = start.importResolver(start.id, importItem.id));
const originalResource = new lgResource_1.LGResource(start.id, start.source, start.content);
resource = start.importResolver(originalResource, importItem.id);
}
catch (error) {
const diagnostic = new diagnostic_1.Diagnostic(importItem.sourceRange.range, error.message, diagnostic_1.DiagnosticSeverity.Error, start.id);
const diagnostic = new diagnostic_1.Diagnostic(importItem.sourceRange.range, error.message, diagnostic_1.DiagnosticSeverity.Error, start.source);
throw new templateException_1.TemplateException(error.message, [diagnostic]);
}
if (Array.from(resourcesFound).every((u) => u.id !== path)) {
if (Array.from(resourcesFound).every((u) => u.id !== resource.id)) {
let childResource;
if (cachedTemplates.has(path)) {
childResource = cachedTemplates.get(path);
if (cachedTemplates.has(resource.id)) {
childResource = cachedTemplates.get(resource.id);
}
else {
childResource = TemplatesParser.innerParseText(content, path, start.importResolver, start.expressionParser, cachedTemplates);
cachedTemplates.set(path, childResource);
childResource = TemplatesParser.parseResource(resource, start.importResolver, start.expressionParser, cachedTemplates);
cachedTemplates.set(resource.id, childResource);
}

@@ -261,3 +274,3 @@ this.resolveImportResources(childResource, resourcesFound, cachedTemplates);

const id = groups[2].trim();
const sourceRange = new sourceRange_1.SourceRange(context, this.templates.id);
const sourceRange = new sourceRange_1.SourceRange(context, this.templates.source);
const templateImport = new templateImport_1.TemplateImport(description, id, sourceRange);

@@ -294,3 +307,3 @@ this.templates.imports.push(templateImport);

let templateBody = context.templateBody().text;
const sourceRange = new sourceRange_1.SourceRange(context, this.templates.id);
const sourceRange = new sourceRange_1.SourceRange(context, this.templates.source);
const template = new template_1.Template(templateName, parameters, templateBody, sourceRange);

@@ -348,3 +361,3 @@ this.checkTemplateName(templateName, context.templateNameLine());

parser.removeErrorListeners();
parser.addErrorListener(new errorListener_1.ErrorListener(this.templates.id, startLine));
parser.addErrorListener(new errorListener_1.ErrorListener(this.templates.source, startLine));
parser.buildParseTree = true;

@@ -380,3 +393,3 @@ return parser.template().body();

buildTemplatesDiagnostic(errorMessage, context, severity = diagnostic_1.DiagnosticSeverity.Error) {
return new diagnostic_1.Diagnostic(templateExtensions_1.TemplateExtensions.convertToRange(context), errorMessage, severity, this.templates.id);
return new diagnostic_1.Diagnostic(templateExtensions_1.TemplateExtensions.convertToRange(context), errorMessage, severity, this.templates.source);
}

@@ -383,0 +396,0 @@ }

@@ -5,3 +5,3 @@ {

"description": "Bot Builder Language Generation is a library to help build sophisticated bot responses with multiple phrases and context-based expressions.",
"version": "4.11.0-dev.20200909.b3c2acc",
"version": "4.11.0-dev.20200911.2b4d430",
"license": "MIT",

@@ -23,3 +23,3 @@ "keywords": [

"dependencies": {
"adaptive-expressions": "4.11.0-dev.20200909.b3c2acc",
"adaptive-expressions": "4.11.0-dev.20200911.2b4d430",
"antlr4ts": "0.5.0-alpha.3",

@@ -44,3 +44,3 @@ "lodash": "^4.17.19",

"clean": "erase /q /s .\\lib",
"set-version": "npm version --allow-same-version 4.11.0-dev.20200909.b3c2acc",
"set-version": "npm version --allow-same-version 4.11.0-dev.20200911.2b4d430",
"test": "tsc && mocha tests/ --timeout 60000",

@@ -47,0 +47,0 @@ "antlr-build": "antlr4ts src/LGFileLexer.g4 -o src/generated && antlr4ts src/LGFileParser.g4 -visitor -o src/generated && antlr4ts src/LGTemplateLexer.g4 -o src/generated && antlr4ts src/LGTemplateParser.g4 -visitor -o src/generated"

@@ -14,2 +14,22 @@

/**
* LG cache scope options.
*/
export enum LGCacheScope {
/**
* Global template cache scope.
*/
Global = 'global',
/**
* Only cache result in the same layer of children in template.
*/
Local = 'local',
/**
* Without cache.
*/
None = 'none'
}
export class EvaluationOptions {

@@ -27,2 +47,7 @@ private readonly nullKeyReplaceStrRegex = /\${\s*path\s*}/g;

/**
* Cache scope of the evaluation result.
*/
public cacheScope: LGCacheScope | undefined;
public constructor(opt?: EvaluationOptions | string[]) {

@@ -33,2 +58,3 @@ if (arguments.length === 0) {

this.LineBreakStyle = undefined;
this.cacheScope = undefined;
} else {

@@ -39,2 +65,3 @@ if (opt instanceof EvaluationOptions) {

this.LineBreakStyle = opt.LineBreakStyle;
this.cacheScope = opt.cacheScope;
} else {

@@ -41,0 +68,0 @@ if(opt !== undefined && opt.length > 0) {

@@ -30,7 +30,7 @@

*/
public evaluatedChildren: Map<string, any>;
public cachedEvaluatedChildren : Map<string, any>;
public constructor(templateName: string, scope: MemoryInterface) {
this.templateName = templateName;
this.scope = scope;
this.evaluatedChildren = new Map<string, any>();
this.cachedEvaluatedChildren = new Map<string, any>();
}

@@ -37,0 +37,0 @@

@@ -21,3 +21,3 @@ /**

import { TemplateErrors } from './templateErrors';
import { EvaluationOptions } from './evaluationOptions';
import { EvaluationOptions, LGCacheScope } from './evaluationOptions';
import { Templates } from './templates';

@@ -45,2 +45,3 @@ /**

private readonly lgOptions: EvaluationOptions;
private readonly cacheResult: Map<string, any> = new Map<string, any>();

@@ -91,21 +92,38 @@ public static readonly LGType = 'lgType';

let previousEvaluateTarget: EvaluationTarget;
if (this.evaluationTargetStack.length !== 0) {
previousEvaluateTarget = this.evaluationTargetStack[this.evaluationTargetStack.length - 1];
if (!reExecute && previousEvaluateTarget.evaluatedChildren.has(currentEvulateId)) {
return previousEvaluateTarget.evaluatedChildren.get(currentEvulateId);
let result: any;
let hasResult = false;
if (!reExecute) {
if (this.lgOptions.cacheScope === LGCacheScope.Global) {
if (this.cacheResult.has(currentEvulateId)) {
result = this.cacheResult.get(currentEvulateId);
hasResult = true;
}
} else if (this.lgOptions.cacheScope === undefined || this.lgOptions.cacheScope === LGCacheScope.Local) {
let previousEvaluateTarget: EvaluationTarget;
if (this.evaluationTargetStack.length !== 0) {
previousEvaluateTarget = this.evaluationTargetStack[this.evaluationTargetStack.length - 1];
if (previousEvaluateTarget.cachedEvaluatedChildren.has(currentEvulateId)) {
result = previousEvaluateTarget.cachedEvaluatedChildren.get(currentEvulateId);
hasResult = true;
}
}
}
}
// Using a stack to track the evalution trace
this.evaluationTargetStack.push(templateTarget);
let result: string = this.visit(this.templateMap[templateName].templateBodyParseTree);
if (!hasResult) {
this.evaluationTargetStack.push(templateTarget);
result = this.visit(this.templateMap[templateName].templateBodyParseTree);
this.evaluationTargetStack.pop();
if (previousEvaluateTarget) {
previousEvaluateTarget.evaluatedChildren.set(currentEvulateId, result);
if (!reExecute) {
if (this.lgOptions.cacheScope === LGCacheScope.Global) {
this.cacheResult.set(currentEvulateId, result);
} else if (this.lgOptions.cacheScope === undefined || this.lgOptions.cacheScope === LGCacheScope.Local) {
if (this.evaluationTargetStack.length !== 0) {
this.evaluationTargetStack[this.evaluationTargetStack.length - 1].cachedEvaluatedChildren.set(currentEvulateId, result);
}
}
}
}
this.evaluationTargetStack.pop();
return result;

@@ -112,0 +130,0 @@ }

@@ -31,1 +31,2 @@ /**

export * from './evaluationOptions';
export * from './lgResource';

@@ -56,3 +56,3 @@ /**

{
const diagnostic = new Diagnostic(Range.DefaultRange, TemplateErrors.noTemplate, DiagnosticSeverity.Warning, this.templates.id);
const diagnostic = new Diagnostic(Range.DefaultRange, TemplateErrors.noTemplate, DiagnosticSeverity.Warning, this.templates.source);
result.push(diagnostic);

@@ -71,3 +71,3 @@ return result;

const range = new Range(startLine, 0, startLine, template.name.length + 1);
const diagnostic = new Diagnostic(range, TemplateErrors.duplicatedTemplateInDiffTemplate(sameTemplate.name, sameTemplate.sourceRange.source), DiagnosticSeverity.Error, this.templates.id);
const diagnostic = new Diagnostic(range, TemplateErrors.duplicatedTemplateInDiffTemplate(sameTemplate.name, sameTemplate.sourceRange.source), DiagnosticSeverity.Error, this.templates.source);
templateDiagnostics.push(diagnostic);

@@ -320,4 +320,4 @@ }

const range = context === undefined ? new Range(lineOffset + 1, 0, lineOffset + 1, 0) : TemplateExtensions.convertToRange(context, lineOffset);
return new Diagnostic(range, templateNameInfo + message, severity, this.templates.id);
return new Diagnostic(range, templateNameInfo + message, severity, this.templates.source);
}
}

@@ -24,2 +24,3 @@ /**

import { StaticChecker } from './staticChecker';
import { LGResource } from './lgResource';
import { CustomizedMemory } from './customizedMemory';

@@ -66,3 +67,3 @@

/**
* id of this lg source. For file, is full path.
* Id of the lg resource.
*/

@@ -77,2 +78,7 @@ public id: string;

/**
* Source of the lg resource. Full path for lg file.
*/
public source: string;
/**
* Delegate for resolving resource id of imported lg file.

@@ -95,3 +101,4 @@ */

importResolverDelegate?: ImportResolverDelegate,
options?: string[]) {
options?: string[],
source?: string) {
this.items = items || [];

@@ -106,2 +113,3 @@ this.imports = imports || [];

this.options = options || [];
this.source = source;
this.injectToExpressionFunction();

@@ -187,2 +195,3 @@ }

* Parser to turn lg content into a Templates.
* @deprecated This method will soon be deprecated. Use ParseResource instead.
* @param content Text content contains lg templates.

@@ -199,2 +208,13 @@ * @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.

/**
* Parser to turn lg content into a Templates.
* @param aresource LG resource.
* @param importResolver Resolver to resolve LG import id to template text.
* @param expressionParser Expression parser for evaluating expressions.
* @returns Entity.
*/
public static parseResource(resource: LGResource, importResolver?: ImportResolverDelegate, expressionParser?: ExpressionParser): Templates {
return TemplatesParser.parseResource(resource, importResolver, expressionParser).injectToExpressionFunction();
}
/**
* Evaluate a template with given name and scope.

@@ -210,3 +230,3 @@ * @param templateName Template name to be evaluated.

const evaluator = new Evaluator(this.allTemplates, this.expressionParser, evalOpt);
let result = evaluator.evaluateTemplate(templateName, scope);
let result = evaluator.evaluateTemplate(templateName, scope);
if (evalOpt.LineBreakStyle === LGLineBreakStyle.Markdown && typeof result === 'string') {

@@ -251,3 +271,3 @@ result = result.replace(this.newLineRegex, '$1$1');

*/
public evaluateText(inlineStr: string, scope?: object, opt: EvaluationOptions = undefined): any {
public evaluateText(inlineStr: string, scope?: object, opt: EvaluationOptions = undefined): any {
if (inlineStr === undefined) {

@@ -265,5 +285,5 @@ throw Error('inline string is empty');

inlineStr = !(inlineStr.trim().startsWith(multiLineMark) && inlineStr.includes('\n'))
? `${ multiLineMark }${ inlineStr }${ multiLineMark }` : inlineStr;
? `${multiLineMark}${inlineStr}${multiLineMark}` : inlineStr;
const newContent = `#${ inlineTemplateId } ${ this.newLine } - ${ inlineStr }`;
const newContent = `#${inlineTemplateId} ${this.newLine} - ${inlineStr}`;

@@ -290,3 +310,3 @@ const newTemplates = TemplatesParser.parseTextWithRef(newContent, this);

const newTemplateBody: string = this.convertTemplateBody(templateBody);
const content = `${ templateNameLine }${ this.newLine }${ newTemplateBody }`;
const content = `${templateNameLine}${this.newLine}${newTemplateBody}`;

@@ -298,5 +318,6 @@ // update content

content);
let updatedTemplates = new Templates([], [], [], [], '', this.id, this.expressionParser, this.importResolver);
updatedTemplates = new TemplatesTransformer(updatedTemplates).transform(TemplatesParser.antlrParseTemplates(content, this.id));
const resource = new LGResource(this.id, this.id, content);
updatedTemplates = new TemplatesTransformer(updatedTemplates).transform(TemplatesParser.antlrParseTemplates(resource));

@@ -333,9 +354,10 @@ const originalStartLine = template.sourceRange.range.start.line - 1;

const newTemplateBody: string = this.convertTemplateBody(templateBody);
const content = `${ templateNameLine }${ this.newLine }${ newTemplateBody }`;
const content = `${templateNameLine}${this.newLine}${newTemplateBody}`;
const originalStartLine = TemplateExtensions.readLine(this.content).length;
// update content
this.content = `${ this.content }${ this.newLine }${ templateNameLine }${ this.newLine }${ newTemplateBody }`;
this.content = `${this.content}${this.newLine}${templateNameLine}${this.newLine}${newTemplateBody}`;
let updatedTemplates = new Templates([], [], [], [], '', this.id, this.expressionParser, this.importResolver);
updatedTemplates = new TemplatesTransformer(updatedTemplates).transform(TemplatesParser.antlrParseTemplates(content, this.id));
const resource = new LGResource(this.id, this.id, content);
updatedTemplates = new TemplatesTransformer(updatedTemplates).transform(TemplatesParser.antlrParseTemplates(resource));

@@ -421,3 +443,3 @@ this.appendDiagnosticWithOffset(updatedTemplates.diagnostics, originalStartLine);

const lineLength = newTemplate.sourceRange.range.end.line - newTemplate.sourceRange.range.start.line;
newTemplate.sourceRange.range.start.line = lineOffset + 1;
newTemplate.sourceRange.range.start.line = lineOffset + 1;
newTemplate.sourceRange.range.end.line = lineOffset + lineLength + 1;

@@ -467,3 +489,3 @@ }

const destList: string[] = replaceList.map((u: string): string => {
return u.trimLeft().startsWith('#') ? `- ${ u.trimLeft() }` : u;
return u.trimLeft().startsWith('#') ? `- ${u.trimLeft()}` : u;
});

@@ -477,5 +499,5 @@

if (parameters === undefined || parameters === undefined) {
return `# ${ templateName }`;
return `# ${templateName}`;
} else {
return `# ${ templateName }(${ parameters.join(', ') })`;
return `# ${templateName}(${parameters.join(', ')})`;
}

@@ -494,3 +516,3 @@ }

private injectToExpressionFunction(): Templates {
const totalTemplates = [ this as Templates].concat(this.references);
const totalTemplates = [this as Templates].concat(this.references);
for (const curTemplates of totalTemplates) {

@@ -500,4 +522,4 @@ const globalFuncs = curTemplates.getGlobalFunctionTable(curTemplates.options);

if (curTemplates.items.find(u => u.name === templateName) !== undefined) {
const newGlobalName = `${ curTemplates.namespace }.${ templateName }`;
Expression.functions.add(newGlobalName, new ExpressionEvaluator(newGlobalName, (expr, state, options): {value: any, error: string} => {
const newGlobalName = `${curTemplates.namespace}.${templateName}`;
Expression.functions.add(newGlobalName, new ExpressionEvaluator(newGlobalName, (expr, state, options): { value: any, error: string } => {
let value: any;

@@ -519,4 +541,4 @@ let error: string;

}
return {value, error};
return { value, error };
}, ReturnType.Object));

@@ -547,5 +569,5 @@ }

let result = this.extractOptionByKey(this.namespaceKey, options);
if(!result) {
if (isAbsolute(this.id)) {
result = basename(this.id).split('.')[0];
if (!result) {
if (isAbsolute(this.source)) {
result = basename(this.source).split('.')[0];
} else {

@@ -552,0 +574,0 @@ throw new Error('namespace is required or the id should be an absoulte path!"');

@@ -12,3 +12,3 @@ /**

import { LGFileLexer } from './generated/LGFileLexer';
import { FileContext, LGFileParser} from './generated/LGFileParser';
import { FileContext, LGFileParser } from './generated/LGFileParser';
import { TemplateImport } from './templateImport';

@@ -32,4 +32,5 @@ import { Template } from './template';

import { LGTemplateParser, BodyContext } from './generated/LGTemplateParser';
import { LGResource } from './lgResource';
export declare type ImportResolverDelegate = (source: string, resourceId: string) => { content: string; id: string };
export declare type ImportResolverDelegate = (lgResource: LGResource, resourceId: string) => LGResource;

@@ -56,3 +57,3 @@

public static readonly importRegex: RegExp = new RegExp(/\[([^\]]*)\]\(([^\)]*)\)/);
/**

@@ -68,4 +69,4 @@ * parse a file and return LG file.

const content = fs.readFileSync(fullPath, 'utf-8');
return TemplatesParser.innerParseText(content, fullPath, importResolver, expressionParser);
const resource = new LGResource(fullPath, fullPath, content);
return TemplatesParser.parseResource(resource, importResolver, expressionParser);
}

@@ -75,2 +76,3 @@

* Parser to turn lg content into a Templates.
* @deprecated This method will soon be deprecated. Use ParseResource instead.
* @param content Text content contains lg templates.

@@ -83,3 +85,4 @@ * @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.

public static parseText(content: string, id: string = '', importResolver?: ImportResolverDelegate, expressionParser?: ExpressionParser): Templates {
return TemplatesParser.innerParseText(content, id, importResolver, expressionParser);
const resource = new LGResource(id, id, content);
return TemplatesParser.parseResource(resource, importResolver, expressionParser);
}

@@ -101,2 +104,3 @@

newTemplates.id = id;
newTemplates.source = id;
newTemplates.importResolver = originalTemplates.importResolver;

@@ -107,3 +111,4 @@ newTemplates.options = originalTemplates.options;

// eslint-disable-next-line @typescript-eslint/no-use-before-define
newTemplates = new TemplatesTransformer(newTemplates).transform(this.antlrParseTemplates(content, id));
const resource = new LGResource(id, id, content);
newTemplates = new TemplatesTransformer(newTemplates).transform(this.antlrParseTemplates(resource));
newTemplates.references = this.getReferences(newTemplates)

@@ -126,15 +131,19 @@ .concat(originalTemplates.references)

}
public static defaultFileResolver(sourceId: string, resourceId: string): { content: string; id: string } {
/**
* Default import resolver, using relative/absolute file path to access the file content.
* @param resource Original Resource.
* @param resourceId Import path.
*/
public static defaultFileResolver(resource: LGResource, resourceId: string): LGResource {
let importPath = TemplateExtensions.normalizePath(resourceId);
if (!path.isAbsolute(importPath)) {
// get full path for importPath relative to path which is doing the import.
importPath = TemplateExtensions.normalizePath(path.join(path.dirname(sourceId), importPath));
importPath = TemplateExtensions.normalizePath(path.join(path.dirname(resource.fullName), importPath));
}
if (!fs.existsSync(importPath) || !fs.statSync(importPath).isFile()) {
throw Error(`Could not find file: ${ importPath }`);
throw Error(`Could not find file: ${importPath}`);
}
const content: string = fs.readFileSync(importPath, 'utf-8');
return { content, id: importPath };
return new LGResource(importPath, importPath, content);
}

@@ -144,4 +153,3 @@

* Parser to turn lg content into a Templates.
* @param content Text content contains lg templates.
* @param id Id is the identifier of content. If importResolver is undefined, id must be a full path string.
* @param resource LG resource.
* @param importResolver Resolver to resolve LG import id to template text.

@@ -152,11 +160,14 @@ * @param expressionParser Expression parser for evaluating expressions.

*/
public static innerParseText(content: string,
id: string = '',
public static parseResource(
resource: LGResource,
importResolver?: ImportResolverDelegate,
expressionParser?: ExpressionParser,
cachedTemplates?: Map<string, Templates>): Templates {
if (!resource) {
throw new Error('lg resource is empty.');
}
cachedTemplates = cachedTemplates || new Map<string, Templates>();
if (cachedTemplates.has(id)) {
return cachedTemplates.get(id);
if (cachedTemplates.has(resource.id)) {
return cachedTemplates.get(resource.id);
}

@@ -166,4 +177,5 @@

let templates = new Templates();
templates.content = content;
templates.id = id;
templates.content = resource.content;
templates.id = resource.id;
templates.source = resource.fullName;
templates.importResolver = importResolver;

@@ -176,3 +188,3 @@ if (expressionParser) {

// eslint-disable-next-line @typescript-eslint/no-use-before-define
templates = new TemplatesTransformer(templates).transform(this.antlrParseTemplates(content, id));
templates = new TemplatesTransformer(templates).transform(this.antlrParseTemplates(resource));
templates.references = this.getReferences(templates, cachedTemplates);

@@ -193,12 +205,11 @@ const semanticErrors = new StaticChecker(templates).check();

* Parse LG content and return the AST.
* @param text LG content.
* @param source Source id.
* @param resource LG resource.
* @returns The abstract syntax tree of lg file.
*/
public static antlrParseTemplates(text: string, source: string): FileContext {
if (!text || text.trim() === '') {
public static antlrParseTemplates(resource: LGResource): FileContext {
if (!resource.content || resource.content.trim() === '') {
return undefined;
}
const input: ANTLRInputStream = new ANTLRInputStream(text);
const input: ANTLRInputStream = new ANTLRInputStream(resource.content);
const lexer: LGFileLexer = new LGFileLexer(input);

@@ -208,3 +219,3 @@ const tokens: CommonTokenStream = new CommonTokenStream(lexer);

parser.removeErrorListeners();
parser.addErrorListener(new ErrorListener(source));
parser.addErrorListener(new ErrorListener(resource.fullName));
parser.buildParseTree = true;

@@ -227,18 +238,18 @@

for (const importItem of start.imports) {
let content: string;
let path: string;
let resource: LGResource;
try {
({content, id: path} = start.importResolver(start.id, importItem.id));
const originalResource = new LGResource(start.id, start.source, start.content);
resource = start.importResolver(originalResource, importItem.id);
} catch (error) {
const diagnostic = new Diagnostic(importItem.sourceRange.range, error.message, DiagnosticSeverity.Error, start.id);
const diagnostic = new Diagnostic(importItem.sourceRange.range, error.message, DiagnosticSeverity.Error, start.source);
throw new TemplateException(error.message, [diagnostic]);
}
if (Array.from(resourcesFound).every((u): boolean => u.id !== path)) {
if (Array.from(resourcesFound).every((u): boolean => u.id !== resource.id)) {
let childResource: Templates;
if (cachedTemplates.has(path)) {
childResource = cachedTemplates.get(path);
if (cachedTemplates.has(resource.id)) {
childResource = cachedTemplates.get(resource.id);
} else {
childResource = TemplatesParser.innerParseText(content, path, start.importResolver, start.expressionParser, cachedTemplates);
cachedTemplates.set(path, childResource);
childResource = TemplatesParser.parseResource(resource, start.importResolver, start.expressionParser, cachedTemplates);
cachedTemplates.set(resource.id, childResource);
}

@@ -265,3 +276,3 @@

/**

@@ -294,3 +305,3 @@ * Transform the parse tree into templates.

if (lineContent === undefined || lineContent.trim() === '') {
this.templates.diagnostics.push(this.buildTemplatesDiagnostic(TemplateErrors.syntaxError(`Unexpected content: '${ lineContent }'`), context));
this.templates.diagnostics.push(this.buildTemplatesDiagnostic(TemplateErrors.syntaxError(`Unexpected content: '${lineContent}'`), context));
}

@@ -306,3 +317,3 @@ return;

const id = groups[2].trim();
const sourceRange = new SourceRange(context, this.templates.id);
const sourceRange = new SourceRange(context, this.templates.source);
const templateImport = new TemplateImport(description, id, sourceRange);

@@ -336,3 +347,3 @@ this.templates.imports.push(templateImport);

let parameters: string[];
({templateName, parameters} = this.extractTemplateNameLine(templateNameLine));
({ templateName, parameters } = this.extractTemplateNameLine(templateNameLine));

@@ -345,3 +356,3 @@ if (this.templates.toArray().some((u): boolean => u.name === templateName)) {

const sourceRange = new SourceRange(context, this.templates.id);
const sourceRange = new SourceRange(context, this.templates.source);
const template = new Template(templateName, parameters, templateBody, sourceRange);

@@ -359,3 +370,3 @@

const functionNameSplitDot = templateName.split('.');
for(let id of functionNameSplitDot) {
for (let id of functionNameSplitDot) {
if (!this.templateNamePartRegex.test(id)) {

@@ -405,3 +416,3 @@ const diagnostic = this.buildTemplatesDiagnostic(TemplateErrors.invalidTemplateName(templateName), context);

parser.removeErrorListeners();
parser.addErrorListener(new ErrorListener(this.templates.id, startLine));
parser.addErrorListener(new ErrorListener(this.templates.source, startLine));
parser.buildParseTree = true;

@@ -439,8 +450,8 @@

return {templateName, parameters};
return { templateName, parameters };
}
private buildTemplatesDiagnostic(errorMessage: string, context: ParserRuleContext, severity: DiagnosticSeverity = DiagnosticSeverity.Error): Diagnostic {
return new Diagnostic(TemplateExtensions.convertToRange(context), errorMessage, severity, this.templates.id);
return new Diagnostic(TemplateExtensions.convertToRange(context), errorMessage, severity, this.templates.source);
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc