UNPKG

@glimmer/compiler

Version:
116 lines (99 loc) 13.2 kB
import { normalize, Source } from '@glimmer/syntax'; import { LOCAL_LOGGER } from '@glimmer/util'; import pass0 from './passes/1-normalization/index'; import { visit as pass2 } from './passes/2-encoding/index'; export const defaultId = (() => { let req = typeof module === 'object' && typeof module.require === 'function' ? module.require : require; if (req) { try { const crypto = req('crypto'); let idFn = src => { let hash = crypto.createHash('sha1'); hash.update(src, 'utf8'); // trim to 6 bytes of data (2^48 - 1) return hash.digest('base64').substring(0, 8); }; idFn('test'); return idFn; } catch (e) {} } return function idFn() { return null; }; })(); const defaultOptions = { id: defaultId }; /* * Compile a string into a template javascript string. * * Example usage: * import { precompile } from '@glimmer/compiler'; * import { templateFactory } from 'glimmer-runtime'; * let templateJs = precompile("Howdy {{name}}"); * let factory = templateFactory(new Function("return " + templateJs)()); * let template = factory.create(env); * * @method precompile * @param {string} string a Glimmer template string * @return {string} a template javascript string */ export function precompileJSON(string, options = defaultOptions) { var _a, _b; let source = new Source(string, (_a = options.meta) === null || _a === void 0 ? void 0 : _a.moduleName); let [ast, locals] = normalize(source, options); let block = pass0(source, ast, (_b = options.strictMode) !== null && _b !== void 0 ? _b : false).mapOk(pass2In => { return pass2(pass2In); }); if (false /* LOCAL_SHOULD_LOG */ ) { LOCAL_LOGGER.log(`Template ->`, block); } if (block.isOk) { return [block.value, locals]; } else { throw block.reason; } } // UUID used as a unique placeholder for placing a snippet of JS code into // the otherwise JSON stringified value below. const SCOPE_PLACEHOLDER = '796d24e6-2450-4fb0-8cdf-b65638b5ef70'; /* * Compile a string into a template javascript string. * * Example usage: * import { precompile } from '@glimmer/compiler'; * import { templateFactory } from 'glimmer-runtime'; * let templateJs = precompile("Howdy {{name}}"); * let factory = templateFactory(new Function("return " + templateJs)()); * let template = factory.create(env); * * @method precompile * @param {string} string a Glimmer template string * @return {string} a template javascript string */ export function precompile(source, options = defaultOptions) { var _a, _b; let [block, usedLocals] = precompileJSON(source, options); let moduleName = (_a = options.meta) === null || _a === void 0 ? void 0 : _a.moduleName; let idFn = options.id || defaultId; let blockJSON = JSON.stringify(block); let templateJSONObject = { id: idFn(JSON.stringify(options.meta) + blockJSON), block: blockJSON, moduleName: moduleName !== null && moduleName !== void 0 ? moduleName : '(unknown template module)', // lying to the type checker here because we're going to // replace it just below, after stringification scope: SCOPE_PLACEHOLDER, isStrictMode: (_b = options.strictMode) !== null && _b !== void 0 ? _b : false }; if (usedLocals.length === 0) { delete templateJSONObject.scope; } // JSON is javascript let stringified = JSON.stringify(templateJSONObject); if (usedLocals.length > 0) { let scopeFn = `()=>[${usedLocals.join(',')}]`; stringified = stringified.replace(`"${SCOPE_PLACEHOLDER}"`, scopeFn); } return stringified; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL2NvbXBpbGVyL2xpYi9jb21waWxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxTQUFTLFNBQVQsRUFBdUMsTUFBdkMsUUFBbUUsaUJBQW5FO0FBQ0EsU0FBUyxZQUFULFFBQTZCLGVBQTdCO0FBRUEsT0FBTyxLQUFQLE1BQWtCLGdDQUFsQjtBQUNBLFNBQVMsS0FBSyxJQUFJLEtBQWxCLFFBQStCLDJCQUEvQjtBQWNBLE9BQU8sTUFBTSxTQUFTLEdBQWlCLENBQUMsTUFBSztBQUMzQyxNQUFJLEdBQUcsR0FDTCxPQUFPLE1BQVAsS0FBa0IsUUFBbEIsSUFBOEIsT0FBTyxNQUFNLENBQUMsT0FBZCxLQUEwQixVQUF4RCxHQUFxRSxNQUFNLENBQUMsT0FBNUUsR0FBc0YsT0FEeEY7O0FBR0EsTUFBSSxHQUFKLEVBQVM7QUFDUCxRQUFJO0FBQ0YsWUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLFFBQUQsQ0FBbEI7O0FBRUEsVUFBSSxJQUFJLEdBQWtCLEdBQUQsSUFBUTtBQUMvQixZQUFJLElBQUksR0FBRyxNQUFNLENBQUMsVUFBUCxDQUFrQixNQUFsQixDQUFYO0FBQ0EsUUFBQSxJQUFJLENBQUMsTUFBTCxDQUFZLEdBQVosRUFBaUIsTUFBakIsRUFGK0IsQ0FHL0I7O0FBQ0EsZUFBTyxJQUFJLENBQUMsTUFBTCxDQUFZLFFBQVosRUFBc0IsU0FBdEIsQ0FBZ0MsQ0FBaEMsRUFBbUMsQ0FBbkMsQ0FBUDtBQUNELE9BTEQ7O0FBT0EsTUFBQSxJQUFJLENBQUMsTUFBRCxDQUFKO0FBRUEsYUFBTyxJQUFQO0FBQ0QsS0FiRCxDQWFFLE9BQU8sQ0FBUCxFQUFVLENBQUU7QUFDZjs7QUFFRCxTQUFPLFNBQVMsSUFBVCxHQUFhO0FBQ2xCLFdBQU8sSUFBUDtBQUNELEdBRkQ7QUFHRCxDQXhCc0MsR0FBaEM7QUEwQlAsTUFBTSxjQUFjLEdBQXNCO0FBQ3hDLEVBQUEsRUFBRSxFQUFFO0FBRG9DLENB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WixDQUFvQixJQUFJLGlCQUFpQixHQUF6QyxFQUE4QyxPQUE5QyxDQUFkO0FBQ0Q7O0FBRUQsU0FBTyxXQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBTZXJpYWxpemVkVGVtcGxhdGVCbG9jayxcbiAgU2VyaWFsaXplZFRlbXBsYXRlV2l0aExhenlCbG9jayxcbiAgVGVtcGxhdGVKYXZhc2NyaXB0LFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IExPQ0FMX1NIT1VMRF9MT0cgfSBmcm9tICdAZ2xpbW1lci9sb2NhbC1kZWJ1Zy1mbGFncyc7XG5pbXBvcnQgeyBub3JtYWxpemUsIFByZWNvbXBpbGVPcHRpb25zLCBTb3VyY2UsIFRlbXBsYXRlSWRGbiB9IGZyb20gJ0BnbGltbWVyL3N5bnRheCc7XG5pbXBvcnQgeyBMT0NBTF9MT0dHRVIgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcblxuaW1wb3J0IHBhc3MwIGZyb20gJy4vcGFzc2VzLzEtbm9ybWFsaXphdGlvbi9pbmRleCc7XG5pbXBvcnQgeyB2aXNpdCBhcyBwYXNzMiB9IGZyb20gJy4vcGFzc2VzLzItZW5jb2RpbmcvaW5kZXgnO1xuXG5kZWNsYXJlIGZ1bmN0aW9uIHJlcXVpcmUoaWQ6ICdjcnlwdG8nKTogQ3J5cHRvO1xuZGVjbGFyZSBmdW5jdGlvbiByZXF1aXJlKGlkOiBzdHJpbmcpOiB1bmtub3duO1xuXG5pbnRlcmZhY2UgQ3J5cHRvIHtcbiAgY3JlYXRlSGFzaChcbiAgICBhbGc6ICdzaGExJ1xuICApOiB7XG4gICAgdXBkYXRlKHNyYzogc3RyaW5nLCBlbmNvZGluZzogJ3V0ZjgnKTogdm9pZDtcbiAgICBkaWdlc3QoZW5jb2Rpbmc6ICdiYXNlNjQnKTogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdElkOiBUZW1wbGF0ZUlkRm4gPSAoKCkgPT4ge1xuICBsZXQgcmVxOiB0eXBlb2YgcmVxdWlyZSB8IHVuZGVmaW5lZCA9XG4gICAgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZS5yZXF1aXJlID09PSAnZnVuY3Rpb24nID8gbW9kdWxlLnJlcXVpcmUgOiByZXF1aXJlO1xuXG4gIGlmIChyZXEpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY3J5cHRvID0gcmVxKCdjcnlwdG8nKTtcblxuICAgICAgbGV0IGlkRm46IFRlbXBsYXRlSWRGbiA9IChzcmMpID0+IHtcbiAgICAgICAgbGV0IGhhc2ggPSBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhMScpO1xuICAgICAgICBoYXNoLnVwZGF0ZShzcmMsICd1dGY4Jyk7XG4gICAgICAgIC8vIHRyaW0gdG8gNiBieXRlcyBvZiBkYXRhICgyXjQ4IC0gMSlcbiAgICAgICAgcmV0dXJuIGhhc2guZGlnZXN0KCdiYXNlNjQnKS5zdWJzdHJpbmcoMCwgOCk7XG4gICAgICB9O1xuXG4gICAgICBpZEZuKCd0ZXN0Jyk7XG5cbiAgICAgIHJldHVybiBpZEZuO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gaWRGbigpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcbn0pKCk7XG5cbmNvbnN0IGRlZmF1bHRPcHRpb25zOiBQcmVjb21waWxlT3B0aW9ucyA9IHtcbiAgaWQ6IGRlZmF1bHRJZCxcbn07XG5cbi8qXG4gKiBDb21waWxlIGEgc3RyaW5nIGludG8gYSB0ZW1wbGF0ZSBqYXZhc2NyaXB0IHN0cmluZy5cbiAqXG4gKiBFeGFtcGxlIHVzYWdlOlxuICogICAgIGltcG9ydCB7IHByZWNvbXBpbGUgfSBmcm9tICdAZ2xpbW1lci9jb21waWxlcic7XG4gKiAgICAgaW1wb3J0IHsgdGVtcGxhdGVGYWN0b3J5IH0gZnJvbSAnZ2xpbW1lci1ydW50aW1lJztcbiAqICAgICBsZXQgdGVtcGxhdGVKcyA9IHByZWNvbXBpbGUoXCJIb3dkeSB7e25hbWV9fVwiKTtcbiAqICAgICBsZXQgZmFjdG9yeSA9IHRlbXBsYXRlRmFjdG9yeShuZXcgRnVuY3Rpb24oXCJyZXR1cm4gXCIgKyB0ZW1wbGF0ZUpzKSgpKTtcbiAqICAgICBsZXQgdGVtcGxhdGUgPSBmYWN0b3J5LmNyZWF0ZShlbnYpO1xuICpcbiAqIEBtZXRob2QgcHJlY29tcGlsZVxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBhIEdsaW1tZXIgdGVtcGxhdGUgc3RyaW5nXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGEgdGVtcGxhdGUgamF2YXNjcmlwdCBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZWNvbXBpbGVKU09OKFxuICBzdHJpbmc6IHN0cmluZyxcbiAgb3B0aW9uczogUHJlY29tcGlsZU9wdGlvbnMgPSBkZWZhdWx0T3B0aW9uc1xuKTogW2Jsb2NrOiBTZXJpYWxpemVkVGVtcGxhdGVCbG9jaywgdXNlZExvY2Fsczogc3RyaW5nW11dIHtcbiAgbGV0IHNvdXJjZSA9IG5ldyBTb3VyY2Uoc3RyaW5nLCBvcHRpb25zLm1ldGE/Lm1vZHVsZU5hbWUpO1xuICBsZXQgW2FzdCwgbG9jYWxzXSA9IG5vcm1hbGl6ZShzb3VyY2UsIG9wdGlvbnMpO1xuICBsZXQgYmxvY2sgPSBwYXNzMChzb3VyY2UsIGFzdCwgb3B0aW9ucy5zdHJpY3RNb2RlID8/IGZhbHNlKS5tYXBPaygocGFzczJJbikgPT4ge1xuICAgIHJldHVybiBwYXNzMihwYXNzMkluKTtcbiAgfSk7XG5cbiAgaWYgKExPQ0FMX1NIT1VMRF9MT0cpIHtcbiAgICBMT0NBTF9MT0dHRVIubG9nKGBUZW1wbGF0ZSAtPmAsIGJsb2NrKTtcbiAgfVxuXG4gIGlmIChibG9jay5pc09rKSB7XG4gICAgcmV0dXJuIFtibG9jay52YWx1ZSwgbG9jYWxzXTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBibG9jay5yZWFzb247XG4gIH1cbn1cblxuLy8gVVVJRCB1c2VkIGFzIGEgdW5pcXVlIHBsYWNlaG9sZGVyIGZvciBwbGFjaW5nIGEgc25pcHBldCBvZiBKUyBjb2RlIGludG9cbi8vIHRoZSBvdGhlcndpc2UgSlNPTiBzdHJpbmdpZmllZCB2YWx1ZSBiZWxvdy5cbmNvbnN0IFNDT1BFX1BMQUNFSE9MREVSID0gJzc5NmQyNGU2LTI0NTAtNGZiMC04Y2RmLWI2NTYzOGI1ZWY3MCc7XG5cbi8qXG4gKiBDb21waWxlIGEgc3RyaW5nIGludG8gYSB0ZW1wbGF0ZSBqYXZhc2NyaXB0IHN0cmluZy5cbiAqXG4gKiBFeGFtcGxlIHVzYWdlOlxuICogICAgIGltcG9ydCB7IHByZWNvbXBpbGUgfSBmcm9tICdAZ2xpbW1lci9jb21waWxlcic7XG4gKiAgICAgaW1wb3J0IHsgdGVtcGxhdGVGYWN0b3J5IH0gZnJvbSAnZ2xpbW1lci1ydW50aW1lJztcbiAqICAgICBsZXQgdGVtcGxhdGVKcyA9IHByZWNvbXBpbGUoXCJIb3dkeSB7e25hbWV9fVwiKTtcbiAqICAgICBsZXQgZmFjdG9yeSA9IHRlbXBsYXRlRmFjdG9yeShuZXcgRnVuY3Rpb24oXCJyZXR1cm4gXCIgKyB0ZW1wbGF0ZUpzKSgpKTtcbiAqICAgICBsZXQgdGVtcGxhdGUgPSBmYWN0b3J5LmNyZWF0ZShlbnYpO1xuICpcbiAqIEBtZXRob2QgcHJlY29tcGlsZVxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBhIEdsaW1tZXIgdGVtcGxhdGUgc3RyaW5nXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGEgdGVtcGxhdGUgamF2YXNjcmlwdCBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZWNvbXBpbGUoXG4gIHNvdXJjZTogc3RyaW5nLFxuICBvcHRpb25zOiBQcmVjb21waWxlT3B0aW9ucyA9IGRlZmF1bHRPcHRpb25zXG4pOiBUZW1wbGF0ZUphdmFzY3JpcHQge1xuICBsZXQgW2Jsb2NrLCB1c2VkTG9jYWxzXSA9IHByZWNvbXBpbGVKU09OKHNvdXJjZSwgb3B0aW9ucyk7XG5cbiAgbGV0IG1vZHVsZU5hbWUgPSBvcHRpb25zLm1ldGE/Lm1vZHVsZU5hbWU7XG4gIGxldCBpZEZuID0gb3B0aW9ucy5pZCB8fCBkZWZhdWx0SWQ7XG4gIGxldCBibG9ja0pTT04gPSBKU09OLnN0cmluZ2lmeShibG9jayk7XG4gIGxldCB0ZW1wbGF0ZUpTT05PYmplY3Q6IFNlcmlhbGl6ZWRUZW1wbGF0ZVdpdGhMYXp5QmxvY2sgPSB7XG4gICAgaWQ6IGlkRm4oSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5tZXRhKSArIGJsb2NrSlNPTiksXG4gICAgYmxvY2s6IGJsb2NrSlNPTixcbiAgICBtb2R1bGVOYW1lOiBtb2R1bGVOYW1lID8/ICcodW5rbm93biB0ZW1wbGF0ZSBtb2R1bGUpJyxcbiAgICAvLyBseWluZyB0byB0aGUgdHlwZSBjaGVja2VyIGhlcmUgYmVjYXVzZSB3ZSdyZSBnb2luZyB0b1xuICAgIC8vIHJlcGxhY2UgaXQganVzdCBiZWxvdywgYWZ0ZXIgc3RyaW5naWZpY2F0aW9uXG4gICAgc2NvcGU6IChTQ09QRV9QTEFDRUhPTERFUiBhcyB1bmtub3duKSBhcyBudWxsLFxuICAgIGlzU3RyaWN0TW9kZTogb3B0aW9ucy5zdHJpY3RNb2RlID8/IGZhbHNlLFxuICB9O1xuXG4gIGlmICh1c2VkTG9jYWxzLmxlbmd0aCA9PT0gMCkge1xuICAgIGRlbGV0ZSB0ZW1wbGF0ZUpTT05PYmplY3Quc2NvcGU7XG4gIH1cblxuICAvLyBKU09OIGlzIGphdmFzY3JpcHRcbiAgbGV0IHN0cmluZ2lmaWVkID0gSlNPTi5zdHJpbmdpZnkodGVtcGxhdGVKU09OT2JqZWN0KTtcblxuICBpZiAodXNlZExvY2Fscy5sZW5ndGggPiAwKSB7XG4gICAgbGV0IHNjb3BlRm4gPSBgKCk9Plske3VzZWRMb2NhbHMuam9pbignLCcpfV1gO1xuXG4gICAgc3RyaW5naWZpZWQgPSBzdHJpbmdpZmllZC5yZXBsYWNlKGBcIiR7U0NPUEVfUExBQ0VIT0xERVJ9XCJgLCBzY29wZUZuKTtcbiAgfVxuXG4gIHJldHVybiBzdHJpbmdpZmllZDtcbn1cblxuZXhwb3J0IHsgUHJlY29tcGlsZU9wdGlvbnMgfTtcbiJdLCJzb3VyY2VSb290IjoiIn0=