UNPKG

4.45 kBJavaScriptView Raw
1const fs = require('fs')
2const mkdirp = require('mkdirp')
3const path = require('path')
4const merge = require('deepmerge')
5const transforms = require('./transforms')
6const regexUtils = require('./utils/regex')
7const pluginSortOrder = require('./utils/sortOrder')
8const updateContents = require('./updateContents')
9const cwd = process.cwd()
10
11module.exports = async function processFile(filePath, config) {
12 let content
13 try {
14 content = fs.readFileSync(filePath, 'utf8')
15 } catch (e) {
16 console.log(`FILE NOT FOUND ${filePath}`)
17 throw e
18 }
19 /**
20 * ### Configuration Options
21 */
22 const defaultConfig = {
23 /**
24 * - `transforms` - *object* - (optional) Custom commands to transform block contents, see transforms & custom transforms sections below.
25 * @type {Object}
26 */
27 transforms: transforms,
28 /**
29 * - `outputDir` - *string* - (optional) Change output path of new content. Default behavior is replacing the original file
30 * @type {string}
31 */
32 outputDir: path.dirname(filePath),
33 /**
34 * - `matchWord` - *string* - (optional) Comment pattern to look for & replace inner contents. Default `AUTO-GENERATED-CONTENT`
35 * @type {string}
36 * @default [AUTO-GENERATED-CONTENT]
37 */
38 matchWord: 'AUTO-GENERATED-CONTENT',
39 /**
40 * - `DEBUG` - *Boolean* - (optional) set debug flag to `true` to inspect the process
41 * @type {string}
42 */
43 DEBUG: false,
44 }
45
46 const userConfig = (config && typeof config === 'object') ? config : {}
47 const mergedConfig = merge(defaultConfig, userConfig)
48
49 const registeredTransforms = Object.keys(mergedConfig.transforms)
50 // Set originalPath constant
51 mergedConfig.originalPath = filePath
52 // contents of original MD file
53 mergedConfig.originalContent = content
54 // set default outputContents for first pass for single commands
55 mergedConfig.outputContent = content
56
57 const regex = regexUtils.matchCommentBlock(mergedConfig.matchWord)
58 const match = content.match(regex)
59 const transformsFound = []
60
61 if (match) {
62 let commentMatches
63 let matchIndex = 0
64 while ((commentMatches = regex.exec(content)) !== null) { // eslint-disable-line
65 if (commentMatches.index === regex.lastIndex) {
66 regex.lastIndex++ // This is necessary to avoid infinite loops
67 }
68 const command = `Transform ${commentMatches[1]}` // eslint-disable-line
69 // console.log(command)
70 transformsFound.push({
71 spaces: commentMatches[1], // Preserve indentation
72 transform: commentMatches[2],
73 match: match[matchIndex]
74 })
75 // wait
76 matchIndex++
77 }
78
79 const transformsToRun = pluginSortOrder(registeredTransforms, transformsFound)
80 if (mergedConfig.DEBUG) {
81 console.log('↓ transformsToRun') // eslint-disable-line
82 console.log(transformsToRun) // eslint-disable-line
83 }
84
85 const fileName = path.basename(filePath)
86 const outputFilePath = path.join(mergedConfig.outputDir, fileName)
87
88 // create folder path if doesnt exist
89 mkdirp.sync(mergedConfig.outputDir)
90
91 // run sort
92 let transformMsg = ''
93 const waiter = transformsToRun.map(async (element) => {
94 transformMsg += ` ⁕ ${element.transform} \n`
95 // console.log('order', element.transform)
96 const newContent = await updateContents(element.match, mergedConfig)
97 const firstLineIndentation = element.spaces
98 const contentWithIndentation = newContent.split('\n').join(`\n` + element.spaces)
99 const preserveTabs = `${firstLineIndentation}${contentWithIndentation}`
100
101 content = content.replace(element.match, preserveTabs)
102 mergedConfig.outputContent = content
103 return Promise.resolve(content)
104 })
105
106 // Wait for everything to resolve
107 await Promise.all(waiter)
108
109 // update file contents
110 fs.writeFileSync(outputFilePath, content)
111
112 const msg = outputFilePath.replace(cwd, '')
113
114 console.log(`✔ ${msg} Updated`) // eslint-disable-line
115 console.log(` Transforms run`)
116 console.log(transformMsg) // eslint-disable-line
117
118 // set return values
119 mergedConfig.outputFilePath = outputFilePath
120 mergedConfig.outputContent = content
121
122 return mergedConfig
123 }
124
125 if (mergedConfig.DEBUG) {
126 console.log(`↓ ${filePath}`) // eslint-disable-line
127 console.log(`[No match] <!-- ${mergedConfig.matchWord} --> comment found`) // eslint-disable-line
128 }
129
130 // no match return original contents
131 return mergedConfig
132}