UNPKG

chai-latte

Version:

Build expressive & readable fluent interface libraries.

108 lines 4.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createFluentAPI = exports.createExecutableFluentAPI = exports.buildFluentTree = exports.parse = exports.WordNode = void 0; const WordNode_1 = require("./WordNode"); const parse_1 = require("./parse"); const template_1 = require("./template"); var WordNode_2 = require("./WordNode"); Object.defineProperty(exports, "WordNode", { enumerable: true, get: function () { return WordNode_2.WordNode; } }); var parse_2 = require("./parse"); Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_2.parse; } }); ; const buildFluentTree = (builder) => { const executables = builder(parse_1.parse).map((parsed) => { return { sentence: () => parsed, execute: () => { }, }; }); const executableRoot = (0, exports.createExecutableFluentAPI)(executables); return executableRoot.node; }; exports.buildFluentTree = buildFluentTree; const createExecutableFluentAPI = (executables) => { const executableByTemplate = new Map(); const parsed = []; executables.forEach((executable) => { executableByTemplate.set(executable.sentence.template, executable.execute); parsed.push(executable.sentence); }); const callback = (template) => { const isfunctionAvailable = executableByTemplate.has(template.template); if (isfunctionAvailable) { const execute = executableByTemplate.get(template.template); execute(...template.variables); } }; return (0, exports.createFluentAPI)(parsed, callback); }; exports.createExecutableFluentAPI = createExecutableFluentAPI; const createFluentAPI = (sentences, onExecute) => { const root = {}; root.node = WordNode_1.WordNode.createRootNode({ accessor: root }); let lastFunctionCalled = null; const template = new template_1.TemplateBuilder(onExecute); template.disable(); sentences.forEach((parsedSentence) => { let prev = root; root.node.addparsedSentence(parsedSentence); parsedSentence.words.map((parsedChunk, i) => { const word = parsedChunk.name; const isImplemented = prev[word] && prev[word].node; if (!isImplemented) { createWordAccessor(prev, word); } const wordNode = prev[word].node; wordNode.addChunk(parsedChunk); const previousWordNode = prev.node; const currentWordNode = prev[word].node; const previousChunk = parsedSentence.words[i - 1]; previousWordNode.addNextWord(currentWordNode, previousChunk); prev = prev[word]; }); }); function createWordAccessor(parent, attribute) { const accessor = function (variable) { if (!variable) { return; } const isFirstWord = parent === root; if (isFirstWord) { template.reset(); template.trace({ word: attribute }); lastFunctionCalled = accessor; } template.trace({ variable }); return parent[attribute]; }; accessor.node = new WordNode_1.WordNode({ word: attribute, accessor: accessor, }); Object.defineProperty(parent, attribute, { get() { tracePropertyAccess(parent, attribute, accessor); return accessor; } }); } function tracePropertyAccess(parent, attribute, accessor) { const isAlreadyTraced = lastFunctionCalled === accessor; if (isAlreadyTraced) { return; } const isFirstWord = parent === root; const isReAccessed = lastFunctionCalled === parent; if (!isFirstWord && !isReAccessed) { template.reset(); template.trace({ word: parent.node.word }); } template.trace({ word: attribute }); lastFunctionCalled = accessor; } template.enable(); return root; }; exports.createFluentAPI = createFluentAPI; //# sourceMappingURL=index.js.map