UNPKG

@nx/devkit

Version:

The Nx Devkit is used to customize Nx for different technologies and use cases. It contains many utility functions for reading and writing files, updating configuration, working with Abstract Syntax Trees(ASTs), and more. Learn more about [extending Nx by

110 lines (109 loc) 3.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChangeType = void 0; exports.applyChangesToString = applyChangesToString; var ChangeType; (function (ChangeType) { ChangeType["Delete"] = "Delete"; ChangeType["Insert"] = "Insert"; })(ChangeType || (exports.ChangeType = ChangeType = {})); /** * Applies a list of changes to a string's original value. * * This is useful when working with ASTs. * * For Example, to rename a property in a method's options: * * ```typescript * const code = `bootstrap({ * target: document.querySelector('#app') * })`; * * const indexOfPropertyName = 13; // Usually determined by analyzing an AST. * const updatedCode = applyChangesToString(code, [ * { * type: ChangeType.Insert, * index: indexOfPropertyName, * text: 'element' * }, * { * type: ChangeType.Delete, * start: indexOfPropertyName, * length: 6 * }, * ]); * * bootstrap({ * element: document.querySelector('#app') * }); * ``` */ function applyChangesToString(text, changes) { assertChangesValid(changes); const sortedChanges = changes.sort((a, b) => { const diff = getChangeIndex(a) - getChangeIndex(b); if (diff === 0) { if (a.type === b.type) { return 0; } else { // When at the same place, Insert before Delete return isStringInsertion(a) ? -1 : 1; } } return diff; }); let offset = 0; for (const change of sortedChanges) { const index = getChangeIndex(change) + offset; if (isStringInsertion(change)) { text = text.slice(0, index) + change.text + text.slice(index); offset += change.text.length; } else { text = text.slice(0, index) + text.slice(index + change.length); offset -= change.length; } } return text; } function assertChangesValid(changes) { for (const change of changes) { if (isStringInsertion(change)) { if (!Number.isInteger(change.index)) { throw new TypeError(`${change.index} must be an integer.`); } if (change.index < 0) { throw new Error(`${change.index} must be a positive integer.`); } if (typeof change.text !== 'string') { throw new Error(`${change.text} must be a string.`); } } else { if (!Number.isInteger(change.start)) { throw new TypeError(`${change.start} must be an integer.`); } if (change.start < 0) { throw new Error(`${change.start} must be a positive integer.`); } if (!Number.isInteger(change.length)) { throw new TypeError(`${change.length} must be an integer.`); } if (change.length < 0) { throw new Error(`${change.length} must be a positive integer.`); } } } } function getChangeIndex(change) { if (isStringInsertion(change)) { return change.index; } else { return change.start; } } function isStringInsertion(change) { return change.type === ChangeType.Insert; }