UNPKG

react-native-integrate

Version:

Automate integration of additional code into React Native projects

300 lines (299 loc) 14.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.applyContentModification = applyContentModification; exports.updateBlockContent = updateBlockContent; exports.getBlockName = getBlockName; exports.applyContextReduction = applyContextReduction; const picocolors_1 = __importDefault(require("picocolors")); const processScript_1 = require("./processScript"); const prompter_1 = require("../prompter"); const variables_1 = require("../variables"); const escapeRegExp_1 = require("./escapeRegExp"); const findInsertionPoint_1 = require("./findInsertionPoint"); const findLineTools_1 = require("./findLineTools"); const getModContent_1 = require("./getModContent"); const setState_1 = require("./setState"); const stringSplice_1 = require("./stringSplice"); async function applyContentModification(args) { let { content } = args; const { configPath, packageName, action, findOrCreateBlock, indentation, additionalModification, buildComment, } = args; let blockContent = { start: 0, end: content.length - 1, match: content, justCreated: false, space: '', }; if (action.block) { action.block = (0, variables_1.getText)(action.block); const foundBlock = findOrCreateBlock(content, action.block); blockContent = foundBlock.blockContent; content = foundBlock.content; } const getCodeToInsert = (text, kind) => { const isBlockSameLine = !blockContent.match.includes('\n') || (!action.search && kind === 'replace'); let comment = '', blockIndentation = '', openingNewLine = '\n', closingNewLine = `\n${isBlockSameLine ? blockContent.space : ''}`; const isAppend = 'append' in action || 'before' in action; if (!isBlockSameLine) { if (isAppend || (blockContent.start == 0 && blockContent.match[0] != '\n')) openingNewLine = ''; else closingNewLine = ''; } if (action.block) blockIndentation = ' '.repeat(indentation); if (action.comment) { const _buildCommand = buildComment || buildCommonComment; const commentLines = _buildCommand((0, variables_1.getText)(action.comment)); commentLines.forEach(line => { comment += `${blockContent.space}${blockIndentation}${line}\n`; }); } text = text.replace(/\n/g, `\n${blockContent.space}${blockIndentation}`); return `${openingNewLine}${comment}${blockContent.space}${blockIndentation}${text}${closingNewLine}`; }; const splittingMsgArr = applyContextReduction(action, blockContent, content); const splittingMsg = splittingMsgArr.length ? ` (${splittingMsgArr.join(', ')})` : ''; const runModifiers = async (spliceCallback) => { const prependAction = async (prependRaw) => { const prependText = await (0, getModContent_1.getModContent)(configPath, packageName, prependRaw); const codeToInsert = action.exact ? prependText : getCodeToInsert(prependText, 'prepend'); if (action.ifNotPresent && blockContent.match.includes((0, variables_1.getText)(action.ifNotPresent))) { (0, prompter_1.logMessageGray)(`found existing ${(0, prompter_1.summarize)((0, variables_1.getText)(action.ifNotPresent))}, skipped inserting: ${(0, prompter_1.summarize)(prependText)}`); (0, setState_1.setState)(action.name, { state: 'skipped', reason: 'prepend.ifNotPresent', }); } else if (!blockContent.match.includes(prependText)) { const start = blockContent.start, rem = 0, insert = codeToInsert; content = (0, stringSplice_1.stringSplice)(content, start, rem, insert); if (spliceCallback) spliceCallback(start, rem, insert); updateBlockContent(blockContent, rem, insert, content); (0, prompter_1.logMessage)(`prepended code in ${(0, prompter_1.summarize)(getBlockName(action))}${splittingMsg}: ${(0, prompter_1.summarize)(prependText)}`); } else { (0, prompter_1.logMessageGray)(`code already exists, skipped prepending: ${(0, prompter_1.summarize)(prependText)}`); (0, setState_1.setState)(action.name, { state: 'skipped', reason: 'prepend.exists', }); } }; const appendAction = async (appendRaw) => { const appendText = await (0, getModContent_1.getModContent)(configPath, packageName, appendRaw); const codeToInsert = action.exact ? appendText : getCodeToInsert(appendText, 'append'); if (action.ifNotPresent && blockContent.match.includes((0, variables_1.getText)(action.ifNotPresent))) { (0, prompter_1.logMessageGray)(`found existing ${(0, prompter_1.summarize)((0, variables_1.getText)(action.ifNotPresent))}, skipped inserting: ${(0, prompter_1.summarize)(appendText)}`); (0, setState_1.setState)(action.name, { state: 'skipped', reason: 'append.ifNotPresent', }); } else if (!blockContent.match.includes(appendText)) { const lineStart = action.exact ? blockContent.end : (0, findLineTools_1.findLineStart)(content, blockContent.end, blockContent.start); const start = lineStart, rem = 0, insert = codeToInsert; content = (0, stringSplice_1.stringSplice)(content, start, rem, insert); if (spliceCallback) spliceCallback(start, rem, insert); updateBlockContent(blockContent, rem, insert, content); (0, prompter_1.logMessage)(`appended code in ${(0, prompter_1.summarize)(getBlockName(action))}${splittingMsg}: ${(0, prompter_1.summarize)(appendText)}`); } else { (0, prompter_1.logMessageGray)(`code already exists, skipped appending: ${(0, prompter_1.summarize)(appendText)}`); (0, setState_1.setState)(action.name, { state: 'skipped', reason: 'append.exists', }); } }; const replaceAction = async (replaceRaw) => { const replaceText = await (0, getModContent_1.getModContent)(configPath, packageName, replaceRaw); const codeToInsert = action.exact ? replaceText : getCodeToInsert(replaceText, 'replace'); if (action.ifNotPresent && blockContent.match.includes((0, variables_1.getText)(action.ifNotPresent))) { (0, prompter_1.logMessageGray)(`found existing ${(0, prompter_1.summarize)((0, variables_1.getText)(action.ifNotPresent))}, skipped inserting: ${(0, prompter_1.summarize)(replaceText)}`); (0, setState_1.setState)(action.name, { state: 'skipped', reason: 'replace.ifNotPresent', }); } else { const start = blockContent.start, rem = blockContent.end - blockContent.start, insert = codeToInsert; content = (0, stringSplice_1.stringSplice)(content, start, rem, insert); if (spliceCallback) spliceCallback(start, rem, insert); updateBlockContent(blockContent, rem, insert, content); (0, prompter_1.logMessage)(`replaced code in ${(0, prompter_1.summarize)(getBlockName(action))}${splittingMsg}: ${(0, prompter_1.summarize)(replaceText)}`); } }; for (const key of Object.keys(action)) { switch (key) { case 'prepend': if (action.prepend) { await prependAction(action.prepend); } break; case 'append': if (action.append) { await appendAction(action.append); } break; case 'replace': if (action.replace != null) { await replaceAction(action.replace); } break; case 'script': if (action.script != null) { if (action.ifNotPresent && blockContent.match.includes((0, variables_1.getText)(action.ifNotPresent))) { (0, prompter_1.logMessageGray)(`found existing ${(0, prompter_1.summarize)((0, variables_1.getText)(action.ifNotPresent))}, skipped running script: ${(0, prompter_1.summarize)(action.script)}`); (0, setState_1.setState)(action.name, { state: 'skipped', reason: 'script.ifNotPresent', }); } else { await (0, processScript_1.processScript)(action.script, variables_1.variables, false, true, { prepend: prependAction, append: appendAction, replace: replaceAction, }); } } break; } } }; if (action.search) { const searchBlockContent = { ...blockContent }; let searchMatcher = typeof action.search == 'string' ? new RegExp((0, escapeRegExp_1.escapeRegExp)((0, variables_1.getText)(action.search))) : new RegExp((0, variables_1.getText)(action.search.regex), action.search.flags); const searchOnce = !searchMatcher.flags.includes('g'); if (searchOnce) searchMatcher = new RegExp(searchMatcher.source, searchMatcher.flags + 'g'); let searching = true; let isFirstSearch = true; while (searching) { const match = searchMatcher.exec(searchBlockContent.match); if (!match) { if (isFirstSearch) (0, setState_1.setState)(action.name, { state: 'skipped', reason: 'search', }); break; } isFirstSearch = false; blockContent.start = searchBlockContent.start + match.index; blockContent.end = searchBlockContent.start + match.index + match[0].length; blockContent.match = match[0]; if (!action.exact) { //find context start blockContent.start = (0, findLineTools_1.findLineStart)(content, blockContent.start, searchBlockContent.start, true); //find context end const lineEnd = (0, findLineTools_1.findLineEnd)(content, blockContent.end, searchBlockContent.end); searchMatcher.lastIndex += lineEnd - blockContent.end; blockContent.end = lineEnd; blockContent.match = content.substring(blockContent.start, blockContent.end); } await runModifiers((_start, rem, insert) => { searchMatcher.lastIndex += -rem + insert.length; updateBlockContent(searchBlockContent, rem, insert, content); }); if (searchOnce) searching = false; } } else await runModifiers(); if (additionalModification) { content = additionalModification({ content, blockContent, }); } return content; } function buildCommonComment(comment) { return comment.split('\n').map(x => `// ${x}`); } function updateBlockContent(blockContent, rem, insert, content) { blockContent.end += -rem + insert.length; blockContent.match = content.substring(blockContent.start, blockContent.end); } function resolveInsertionPoint(blockContent, _content, textOrRegex) { if (blockContent.justCreated) { return { start: blockContent.start, end: blockContent.end, match: blockContent.match, }; } else { const insertionPoint = (0, findInsertionPoint_1.findInsertionPoint)(blockContent.match, textOrRegex); if (insertionPoint.start == -1) return insertionPoint; insertionPoint.start += blockContent.start; insertionPoint.end += blockContent.start; return insertionPoint; } } function getBlockName(action) { return action.block || 'file'; } function applyContextReduction(action, blockContent, content) { const splittingMsgArr = []; if (action.after) { const foundIndex = resolveInsertionPoint(blockContent, content, action.after); if (foundIndex.start == -1) { if (action.strict) throw new Error('Could not find insertion point'); (0, prompter_1.logMessageGray)(`insertion point not found, ignoring ${picocolors_1.default.yellow('before')} criteria`); } else { blockContent.start = action.exact ? foundIndex.end : (0, findLineTools_1.findLineEnd)(content, foundIndex.end, blockContent.end); blockContent.match = content.substring(blockContent.start, blockContent.end); splittingMsgArr.push(`after ${(0, prompter_1.summarize)(foundIndex.match, 20)}`); } } if (action.before) { const foundIndex = resolveInsertionPoint(blockContent, content, action.before); if (foundIndex.start == -1) { if (action.strict) throw new Error('Could not find insertion point'); (0, prompter_1.logMessageGray)(`insertion point not found, ignoring ${picocolors_1.default.yellow('before')} criteria`); } else { blockContent.end = action.exact ? foundIndex.start : (0, findLineTools_1.findLineStart)(content, foundIndex.start, blockContent.start); blockContent.match = content.substring(blockContent.start, blockContent.end); splittingMsgArr.push(`before ${(0, prompter_1.summarize)(foundIndex.match, 20)}`); } } return splittingMsgArr; }