UNPKG

twing

Version:

First-class Twig engine for Node.js

311 lines (310 loc) 14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createSynchronousEnvironment = exports.createEnvironment = void 0; const extension_set_1 = require("./extension-set"); const parser_1 = require("./parser"); const html_1 = require("./escaping-stragegy/html"); const css_1 = require("./escaping-stragegy/css"); const js_1 = require("./escaping-stragegy/js"); const url_1 = require("./escaping-stragegy/url"); const html_attribute_1 = require("./escaping-stragegy/html-attribute"); const token_stream_1 = require("./token-stream"); const source_map_runtime_1 = require("./source-map-runtime"); const security_policy_1 = require("./sandbox/security-policy"); const luxon_1 = require("luxon"); const lexer_1 = require("./lexer"); const core_1 = require("./extension/core"); const lib_1 = require("../lib"); const template_loader_1 = require("./template-loader"); const context_1 = require("./context"); const iterator_to_map_1 = require("./helpers/iterator-to-map"); /** * Creates an instance of {@link TwingEnvironment} backed by the passed loader. * * @param loader * @param options */ const createEnvironment = (loader, options) => { const cssEscapingStrategy = (0, css_1.createCssEscapingStrategyHandler)(); const htmlEscapingStrategy = (0, html_1.createHtmlEscapingStrategyHandler)(); const htmlAttributeEscapingStrategy = (0, html_attribute_1.createHtmlAttributeEscapingStrategyHandler)(); const jsEscapingStrategy = (0, js_1.createJsEscapingStrategyHandler)(); const urlEscapingStrategy = (0, url_1.createUrlEscapingStrategyHandler)(); const escapingStrategyHandlers = { css: cssEscapingStrategy, html: htmlEscapingStrategy, html_attr: htmlAttributeEscapingStrategy, js: jsEscapingStrategy, url: urlEscapingStrategy }; const extensionSet = (0, extension_set_1.createExtensionSet)(); extensionSet.addExtension((0, core_1.createCoreExtension)()); const cache = (options === null || options === void 0 ? void 0 : options.cache) || null; const charset = (options === null || options === void 0 ? void 0 : options.charset) || 'UTF-8'; const dateFormat = (options === null || options === void 0 ? void 0 : options.dateFormat) || 'F j, Y H:i'; const dateIntervalFormat = (options === null || options === void 0 ? void 0 : options.dateIntervalFormat) || '%d days'; const numberFormat = (options === null || options === void 0 ? void 0 : options.numberFormat) || { decimalPoint: '.', numberOfDecimals: 0, thousandSeparator: ',' }; const sandboxPolicy = (options === null || options === void 0 ? void 0 : options.sandboxPolicy) || (0, security_policy_1.createSandboxSecurityPolicy)(); const globals = (0, context_1.createContext)((0, iterator_to_map_1.iterableToMap)((options === null || options === void 0 ? void 0 : options.globals) || {})); let lexer; let parser; const environment = { get cache() { return cache; }, get charset() { return charset; }, get dateFormat() { return dateFormat; }, get dateIntervalFormat() { return dateIntervalFormat; }, get escapingStrategyHandlers() { return escapingStrategyHandlers; }, get filters() { return extensionSet.filters; }, get functions() { return extensionSet.functions; }, get globals() { return globals; }, get loader() { return loader; }, get numberFormat() { return numberFormat; }, get sandboxPolicy() { return sandboxPolicy; }, get tests() { return extensionSet.tests; }, get timezone() { return (options === null || options === void 0 ? void 0 : options.timezone) || luxon_1.Settings.defaultZoneName; }, addExtension: extensionSet.addExtension, addFilter: extensionSet.addFilter, addFunction: extensionSet.addFunction, addNodeVisitor: extensionSet.addNodeVisitor, addOperator: extensionSet.addOperator, addTagHandler: extensionSet.addTagHandler, addTest: extensionSet.addTest, loadTemplate: async (name, from = null) => { const templateLoader = (0, template_loader_1.createTemplateLoader)(environment); return templateLoader(name, from) .then((template) => { if (template === null) { throw (0, lib_1.createTemplateLoadingError)([name]); } return template; }); }, registerEscapingStrategy: (handler, name) => { escapingStrategyHandlers[name] = handler; }, parse: (stream, parserOptions) => { if (!parser) { const visitors = extensionSet.nodeVisitors; if (options === null || options === void 0 ? void 0 : options.autoEscapingStrategy) { const strategy = options.autoEscapingStrategy; visitors.unshift({ enterNode: (node) => { return node; }, leaveNode: (node) => { if (node.type === "template") { node.children.body = (0, lib_1.createAutoEscapeNode)(strategy, node.children.body, node.line, node.column); } return node; } }); } parser = (0, parser_1.createParser)(extensionSet.unaryOperators, extensionSet.binaryOperators, extensionSet.tagHandlers, extensionSet.nodeVisitors, extensionSet.filters, extensionSet.functions, extensionSet.tests, parserOptions || (options === null || options === void 0 ? void 0 : options.parserOptions) || { strict: true, level: 3 }); } return parser.parse(stream); }, render: (name, context, options) => { return environment.loadTemplate(name) .then((template) => { return template.render(environment, context, options); }); }, renderWithSourceMap: (name, context, options) => { const sourceMapRuntime = (0, source_map_runtime_1.createSourceMapRuntime)(); return environment.loadTemplate(name) .then((template) => { return template.render(environment, context, Object.assign(Object.assign({}, options), { sourceMapRuntime })); }) .then((data) => { const { sourceMap } = sourceMapRuntime; return { data, sourceMap }; }); }, tokenize: (source) => { var _a; const level = ((_a = options === null || options === void 0 ? void 0 : options.parserOptions) === null || _a === void 0 ? void 0 : _a.level) || 3; if (!lexer) { lexer = (0, lexer_1.createLexer)(level, extensionSet.binaryOperators, extensionSet.unaryOperators); } const stream = lexer.tokenizeSource(source); return (0, token_stream_1.createTokenStream)(stream.toAst(), stream.source); } }; return environment; }; exports.createEnvironment = createEnvironment; const createSynchronousEnvironment = (loader, options) => { const cssEscapingStrategy = (0, css_1.createCssEscapingStrategyHandler)(); const htmlEscapingStrategy = (0, html_1.createHtmlEscapingStrategyHandler)(); const htmlAttributeEscapingStrategy = (0, html_attribute_1.createHtmlAttributeEscapingStrategyHandler)(); const jsEscapingStrategy = (0, js_1.createJsEscapingStrategyHandler)(); const urlEscapingStrategy = (0, url_1.createUrlEscapingStrategyHandler)(); const escapingStrategyHandlers = { css: cssEscapingStrategy, html: htmlEscapingStrategy, html_attr: htmlAttributeEscapingStrategy, js: jsEscapingStrategy, url: urlEscapingStrategy }; const extensionSet = (0, extension_set_1.createExtensionSet)(); extensionSet.addExtension((0, core_1.createSynchronousCoreExtension)()); const cache = (options === null || options === void 0 ? void 0 : options.cache) || null; const charset = (options === null || options === void 0 ? void 0 : options.charset) || 'UTF-8'; const dateFormat = (options === null || options === void 0 ? void 0 : options.dateFormat) || 'F j, Y H:i'; const dateIntervalFormat = (options === null || options === void 0 ? void 0 : options.dateIntervalFormat) || '%d days'; const numberFormat = (options === null || options === void 0 ? void 0 : options.numberFormat) || { decimalPoint: '.', numberOfDecimals: 0, thousandSeparator: ',' }; const sandboxPolicy = (options === null || options === void 0 ? void 0 : options.sandboxPolicy) || (0, security_policy_1.createSandboxSecurityPolicy)(); const globals = new Map(Object.entries((options === null || options === void 0 ? void 0 : options.globals) || {})); let lexer; let parser; const environment = { get cache() { return cache; }, get charset() { return charset; }, get dateFormat() { return dateFormat; }, get dateIntervalFormat() { return dateIntervalFormat; }, get escapingStrategyHandlers() { return escapingStrategyHandlers; }, get filters() { return extensionSet.filters; }, get functions() { return extensionSet.functions; }, get globals() { return globals; }, get loader() { return loader; }, get numberFormat() { return numberFormat; }, get sandboxPolicy() { return sandboxPolicy; }, get tests() { return extensionSet.tests; }, get timezone() { return (options === null || options === void 0 ? void 0 : options.timezone) || luxon_1.Settings.defaultZoneName; }, addExtension: extensionSet.addExtension, addFilter: extensionSet.addFilter, addFunction: extensionSet.addFunction, addNodeVisitor: extensionSet.addNodeVisitor, addOperator: extensionSet.addOperator, addTagHandler: extensionSet.addTagHandler, addTest: extensionSet.addTest, loadTemplate: (name, from = null) => { const templateLoader = (0, template_loader_1.createSynchronousTemplateLoader)(environment); const template = templateLoader(name, from); if (template === null) { throw (0, lib_1.createTemplateLoadingError)([name]); } return template; }, registerEscapingStrategy: (handler, name) => { escapingStrategyHandlers[name] = handler; }, parse: (stream, parserOptions) => { if (!parser) { const visitors = extensionSet.nodeVisitors; if (options === null || options === void 0 ? void 0 : options.autoEscapingStrategy) { const strategy = options.autoEscapingStrategy; visitors.unshift({ enterNode: (node) => { return node; }, leaveNode: (node) => { if (node.type === "template") { node.children.body = (0, lib_1.createAutoEscapeNode)(strategy, node.children.body, node.line, node.column); } return node; } }); } parser = (0, parser_1.createParser)(extensionSet.unaryOperators, extensionSet.binaryOperators, extensionSet.tagHandlers, extensionSet.nodeVisitors, extensionSet.filters, extensionSet.functions, extensionSet.tests, parserOptions || (options === null || options === void 0 ? void 0 : options.parserOptions) || { strict: true, level: 3 }); } return parser.parse(stream); }, render: (name, data, options) => { const template = environment.loadTemplate(name); const context = new Map(Object.entries(data)); return template.render(environment, context, options); }, renderWithSourceMap: (name, data, options) => { const sourceMapRuntime = (0, source_map_runtime_1.createSourceMapRuntime)(); const context = new Map(Object.entries(data)); const template = environment.loadTemplate(name); const output = template.render(environment, context, Object.assign(Object.assign({}, options), { sourceMapRuntime })); const { sourceMap } = sourceMapRuntime; return { data: output, sourceMap }; }, tokenize: (source) => { var _a; const level = ((_a = options === null || options === void 0 ? void 0 : options.parserOptions) === null || _a === void 0 ? void 0 : _a.level) || 3; if (!lexer) { lexer = (0, lexer_1.createLexer)(level, extensionSet.binaryOperators, extensionSet.unaryOperators); } const stream = lexer.tokenizeSource(source); return (0, token_stream_1.createTokenStream)(stream.toAst(), stream.source); } }; return environment; }; exports.createSynchronousEnvironment = createSynchronousEnvironment;