markdown-magic
Advanced tools
Comparing version 0.0.5 to 0.1.0
const fs = require('fs') | ||
const path = require('path') | ||
const dox = require('dox') | ||
const execSync = require('child_process').execSync | ||
@@ -9,3 +8,3 @@ const markdownMagic = require('../index') // 'markdown-magic' | ||
transforms: { | ||
/* Update the content in comment in .md matching | ||
/* Update the content in comment matching: | ||
AUTO-GENERATED-CONTENT (customTransform:optionOne=hi&optionOne=DUDE) | ||
@@ -18,9 +17,8 @@ */ | ||
}, | ||
/* Update the content in comment in .md matching | ||
/* Update the content in comment matching: | ||
AUTO-GENERATED-CONTENT (RENDERDOCS:path=../file.js) | ||
*/ | ||
RENDERDOCS(content, options) { | ||
const filePath = path.join(__dirname, options.path) | ||
const contents = fs.readFileSync(filePath, 'utf8') | ||
const docBlocs = dox.parseComments(contents, { raw: true, skipSingleStar: true }) | ||
const contents = fs.readFileSync(options.path, 'utf8') | ||
const docBlocs = require('dox').parseComments(contents, { raw: true, skipSingleStar: true }) | ||
let updatedContent = '' | ||
@@ -37,12 +35,15 @@ docBlocs.forEach((data) => { | ||
/* This example callback automatically updates Readme.md and commits the changes */ | ||
const callback = function autoGitCommit(updatedContent, outputConfig) { | ||
const mdPath = outputConfig.outputPath | ||
const gitAdd = execSync(`git add ${mdPath}`, {}, (error) => { | ||
if (error) console.warn(error) | ||
console.log('git add complete') | ||
const msg = `${mdPath} automatically updated by markdown-magic` | ||
const gitCommitCommand = `git commit -m '${msg}' --no-verify` | ||
execSync(gitCommitCommand, {}, (err) => { | ||
if (err) console.warn(err) | ||
console.log('git commit automatically ran. Push up your changes!') | ||
const callback = function autoGitCommit(err, output) { | ||
// output is array of file information | ||
output.forEach(function(data) { | ||
const mdPath = data.outputFilePath | ||
const gitAdd = execSync(`git add ${mdPath}`, {}, (error) => { | ||
if (error) console.warn(error) | ||
console.log('git add complete') | ||
const msg = `${mdPath} automatically updated by markdown-magic` | ||
const gitCommitCommand = `git commit -m '${msg}' --no-verify` | ||
execSync(gitCommitCommand, {}, (err) => { | ||
if (err) console.warn(err) | ||
console.log('git commit automatically ran. Push up your changes!') | ||
}) | ||
}) | ||
@@ -49,0 +50,0 @@ }) |
90
index.js
@@ -1,12 +0,13 @@ | ||
const fs = require('fs') | ||
const merge = require('deepmerge') | ||
const defaultCommands = require('./lib/transforms') | ||
const updateContents = require('./update-contents') | ||
const globby = require('globby') | ||
const processFile = require('./lib/processFile') | ||
/** | ||
* ### Function signature | ||
* ### API | ||
* ```js | ||
* markdownMagic(filename, config, callback) | ||
* // Configuration and callback are optional params | ||
* markdownMagic(filePath, config, callback) | ||
* ``` | ||
* - `filePaths` - *String or Array* - Path or glob pattern. Uses [globby patterns](https://github.com/sindresorhus/multimatch/blob/master/test.js) | ||
* - `config` - See configuration options below | ||
* - `callback` - callback to run after markdown updates | ||
* | ||
* @param {string} filePath - Path to markdown file | ||
@@ -16,66 +17,15 @@ * @param {object} [config] - configuration object | ||
*/ | ||
module.exports = function markdownMagic(filePath, config, callback) { | ||
let content | ||
try { | ||
content = fs.readFileSync(filePath, 'utf8') | ||
} catch (e) { | ||
console.log(`FILE NOT FOUND ${filePath}`) | ||
throw e | ||
module.exports = function markdownMagic(filePaths, config, callback) { | ||
const files = globby.sync(filePaths) | ||
const data = [] | ||
const configuration = config || {} | ||
if (!callback && typeof configuration === 'function') { | ||
callback = configuration // eslint-disable-line | ||
} | ||
/** | ||
* ### Configuration Options | ||
*/ | ||
const defaultConfig = { | ||
/** | ||
* `transforms` - *object* - (optional) Custom commands to transform block contents, see configuration options below. | ||
* @type {Object} | ||
*/ | ||
transforms: defaultCommands, | ||
/** | ||
* `matchWord` - *string* - (optional) Comment pattern to look for & replace inner contents. Default `AUTO-GENERATED-CONTENT` | ||
* @type {String} | ||
* @default [AUTO-GENERATED-CONTENT] | ||
*/ | ||
matchWord: 'AUTO-GENERATED-CONTENT', | ||
/** | ||
* `outputPath` - *string* - (optional) Change output path of new content. Default behavior is replacing the original file | ||
* @type {string} | ||
*/ | ||
outputPath: filePath, | ||
} | ||
const userConfig = config || {} | ||
const mergedConfig = merge(defaultConfig, userConfig) | ||
// Set originalPath constant | ||
mergedConfig.originalPath = filePath | ||
// contents of original MD file | ||
mergedConfig.originalContents = content | ||
const word = mergedConfig.matchWord | ||
const regex = new RegExp(`(?:\\<\\!--(?:.|\\n)*?${word}:START(?:.|\\n)*?\\()(.*)\\)(?:.|\\n)*?<!--(?:.|\\n)*?${word}:END(?:.|\\n)*?--\\>`, 'g') | ||
let commentMatches | ||
while ((commentMatches = regex.exec(content)) !== null) { // eslint-disable-line | ||
// This is necessary to avoid infinite loops with zero-width matches | ||
if (commentMatches.index === regex.lastIndex) { regex.lastIndex++ } | ||
// const command = `Command ${commentMatches[1]}` | ||
// console.log(command) | ||
} | ||
const match = content.match(regex) | ||
if (match) { | ||
match.forEach((element) => { | ||
const newContent = updateContents(element, mergedConfig) | ||
content = content.replace(element, newContent) | ||
}) | ||
// then write to file | ||
fs.writeFileSync(mergedConfig.outputPath, content) | ||
console.log(`${mergedConfig.outputPath} updated`) | ||
callback && callback(content, mergedConfig) | ||
} else { | ||
console.log(`no ${word} comment block found in markdown file`) | ||
console.log(`path: ${filePath}`) | ||
callback && callback(content, mergedConfig) | ||
} | ||
configuration.originalFilePaths = files | ||
files.forEach((file) => { | ||
const output = processFile(file, configuration) | ||
data.push(output) | ||
}) | ||
callback && callback(null, data) | ||
} |
@@ -33,3 +33,8 @@ const path = require('path') | ||
// do remote request | ||
code = remoteRequest(options.src) | ||
const remoteContent = remoteRequest(options.src) | ||
if (!remoteContent) { | ||
console.log(`WARNING: ${options.src} URL NOT FOUND or internet connection is off`) | ||
return content | ||
} | ||
code = remoteContent | ||
syntax = path.extname(options.src).replace(/^./, '') | ||
@@ -36,0 +41,0 @@ } |
@@ -5,3 +5,6 @@ const request = require('sync-request') | ||
module.exports = function REMOTE(content, options, config) { | ||
const remoteContent = remoteRequest(options.url) | ||
const remoteContent = remoteRequest(options.url) || content | ||
if (!remoteContent) { | ||
return content | ||
} | ||
if (options.keepComments) { | ||
@@ -21,4 +24,4 @@ return remoteContent | ||
} catch (e) { | ||
console.log(`URL NOT FOUND ${url}`) | ||
throw e | ||
console.log(`WARNING: REMOTE URL ${url} NOT FOUND`) // eslint-disable-line | ||
console.log(e.message) // eslint-disable-line | ||
} | ||
@@ -25,0 +28,0 @@ return body |
/*eslint-disable */ | ||
module.exports.matchCommentBlock = function(matchWord) { | ||
return new RegExp(`(?:\\<\\!--(?:.|\\n)*?${matchWord}:START(?:.|\\n)*?\\()(.*)\\)(?:.|\\n)*?<!--(?:.|\\n)*?${matchWord}:END(?:.|\\n)*?--\\>`, 'g') | ||
} | ||
module.exports.matchOpeningCommentTag = function (matchWord) { | ||
@@ -4,0 +8,0 @@ return new RegExp(`(\\<\\!--(?:.|\\n)*?${matchWord}:START)((?:.|\\n)*?--\\>)`, 'g') |
{ | ||
"name": "markdown-magic", | ||
"version": "0.0.5", | ||
"version": "0.1.0", | ||
"description": "Automatically update markdown files with content from external sources", | ||
@@ -9,2 +9,3 @@ "main": "index.js", | ||
"test": "ava --verbose", | ||
"test:watch": "ava --verbose --watch", | ||
"lint": "eslint .", | ||
@@ -20,2 +21,4 @@ "publish": "git push origin && git push origin --tags", | ||
"deepmerge": "^1.3.0", | ||
"fs-extra": "^1.0.0", | ||
"globby": "^6.1.0", | ||
"is-local-path": "^0.1.6", | ||
@@ -22,0 +25,0 @@ "sync-request": "^3.0.1" |
@@ -32,19 +32,27 @@ # Markdown Magic | ||
<!-- ⛔️ AUTO-GENERATED-CONTENT:START (RENDERDOCS:path=../index.js) | ||
<!-- ⛔️ AUTO-GENERATED-CONTENT:START (RENDERDOCS:path=./index.js) | ||
- Do not remove or modify this section --> | ||
### Function signature | ||
### API | ||
```js | ||
markdownMagic(filename, config, callback) | ||
// Configuration and callback are optional params | ||
markdownMagic(filePath, config, callback) | ||
``` | ||
- `filePaths` - *String or Array* - Path or glob pattern. Uses [globby patterns](https://github.com/sindresorhus/multimatch/blob/master/test.js) | ||
- `config` - See configuration options below | ||
- `callback` - callback to run after markdown updates | ||
<!-- ⛔️ AUTO-GENERATED-CONTENT:END - Do not remove or modify this section --> | ||
<!-- ⛔️ AUTO-GENERATED-CONTENT:START (RENDERDOCS:path=./lib/processFile.js) | ||
- Do not remove or modify this section --> | ||
### Configuration Options | ||
`transforms` - *object* - (optional) Custom commands to transform block contents, see configuration options below. | ||
`transforms` - *Object* - (optional) Custom commands to transform block contents, see transforms & custom transforms sections below. | ||
`matchWord` - *string* - (optional) Comment pattern to look for & replace inner contents. Default `AUTO-GENERATED-CONTENT` | ||
`outputDir` - *String* - (optional) Change output path of new content. Default behavior is replacing the original file | ||
`outputPath` - *string* - (optional) Change output path of new content. Default behavior is replacing the original file | ||
`matchWord` - *String* - (optional) Comment pattern to look for & replace inner contents. Default `AUTO-GENERATED-CONTENT` | ||
`DEBUG` - *Boolean* - (optional) set debug flag to `true` to inspect the process | ||
<!-- ⛔️ AUTO-GENERATED-CONTENT:END - Do not remove or modify this section --> | ||
### Transforms | ||
@@ -54,3 +62,3 @@ | ||
<!-- ⛔️ AUTO-GENERATED-CONTENT:START (RENDERDOCS:path=../lib/transforms/index.js) - Do not remove or modify this section --> | ||
<!-- ⛔️ AUTO-GENERATED-CONTENT:START (RENDERDOCS:path=./lib/transforms/index.js) - Do not remove or modify this section --> | ||
### - `CODE` | ||
@@ -101,3 +109,2 @@ | ||
const path = require('path') | ||
const dox = require('dox') | ||
const execSync = require('child_process').execSync | ||
@@ -108,3 +115,3 @@ const markdownMagic = require('../index') // 'markdown-magic' | ||
transforms: { | ||
/* Update the content in comment in .md matching | ||
/* Update the content in comment matching: | ||
AUTO-GENERATED-CONTENT (customTransform:optionOne=hi&optionOne=DUDE) | ||
@@ -117,9 +124,8 @@ */ | ||
}, | ||
/* Update the content in comment in .md matching | ||
/* Update the content in comment matching: | ||
AUTO-GENERATED-CONTENT (RENDERDOCS:path=../file.js) | ||
*/ | ||
RENDERDOCS(content, options) { | ||
const filePath = path.join(__dirname, options.path) | ||
const contents = fs.readFileSync(filePath, 'utf8') | ||
const docBlocs = dox.parseComments(contents, { raw: true, skipSingleStar: true }) | ||
const contents = fs.readFileSync(options.path, 'utf8') | ||
const docBlocs = require('dox').parseComments(contents, { raw: true, skipSingleStar: true }) | ||
let updatedContent = '' | ||
@@ -136,12 +142,15 @@ docBlocs.forEach((data) => { | ||
/* This example callback automatically updates Readme.md and commits the changes */ | ||
const callback = function autoGitCommit(updatedContent, outputConfig) { | ||
const mdPath = outputConfig.outputPath | ||
const gitAdd = execSync(`git add ${mdPath}`, {}, (error) => { | ||
if (error) console.warn(error) | ||
console.log('git add complete') | ||
const msg = `${mdPath} automatically updated by markdown-magic` | ||
const gitCommitCommand = `git commit -m '${msg}' --no-verify` | ||
execSync(gitCommitCommand, {}, (err) => { | ||
if (err) console.warn(err) | ||
console.log('git commit automatically ran. Push up your changes!') | ||
const callback = function autoGitCommit(err, output) { | ||
// output is array of file information | ||
output.forEach(function(data) { | ||
const mdPath = data.outputFilePath | ||
const gitAdd = execSync(`git add ${mdPath}`, {}, (error) => { | ||
if (error) console.warn(error) | ||
console.log('git add complete') | ||
const msg = `${mdPath} automatically updated by markdown-magic` | ||
const gitCommitCommand = `git commit -m '${msg}' --no-verify` | ||
execSync(gitCommitCommand, {}, (err) => { | ||
if (err) console.warn(err) | ||
console.log('git commit automatically ran. Push up your changes!') | ||
}) | ||
}) | ||
@@ -148,0 +157,0 @@ }) |
116
test/test.js
@@ -0,21 +1,35 @@ | ||
import fs from 'fs-extra' | ||
import path from 'path' | ||
import fs from 'fs' | ||
import test from 'ava' | ||
import sinon from 'sinon' | ||
import markdownSteriods from '../index' | ||
import markdownMagic from '../index' | ||
const markdownPath = path.join(__dirname, 'fixtures', 'test.md') | ||
const outputDir = path.join(__dirname, 'fixtures', 'output') | ||
const DEBUG = false | ||
/** | ||
* Test markdownSteriods Function | ||
* Test markdownMagic Function | ||
*/ | ||
test('if valid path supplied', t => { | ||
markdownSteriods(markdownPath) | ||
test('if valid string path supplied', t => { | ||
markdownMagic(markdownPath) | ||
t.pass() | ||
// emptyDirectory(outputDir) | ||
}) | ||
test('if valid glob pattern supplied', t => { | ||
const config = { | ||
outputDir: outputDir | ||
} | ||
markdownMagic(['test/fixtures/**/*md', '!test/fixtures/output/*.md'], config) | ||
t.pass() | ||
// empty dir | ||
//fs.emptyDirSync(outputDir) | ||
}) | ||
test('if valid config supplied', t => { | ||
const config = {} | ||
markdownSteriods(markdownPath, config) | ||
markdownMagic(markdownPath, config) | ||
t.pass() | ||
// emptyDirectory(outputDir) | ||
}) | ||
@@ -26,5 +40,12 @@ | ||
const config = {} | ||
markdownSteriods(markdownPath, config, callback) | ||
markdownMagic(markdownPath, config, callback) | ||
t.true(callback.calledOnce) | ||
// emptyDirectory(outputDir) | ||
}) | ||
test('if callback function supplied, as second arg, call it once', t => { | ||
const callback = sinon.spy() | ||
markdownMagic(markdownPath, callback) | ||
t.true(callback.calledOnce) | ||
// emptyDirectory(outputDir) | ||
}) | ||
@@ -35,14 +56,13 @@ | ||
*/ | ||
test('if config.outputPath supplied, make new file', t => { | ||
test('if config.outputDir supplied, make new file', t => { | ||
const config = { | ||
outputPath: path.join(__dirname, 'fixtures', 'output', 'different-path.md') | ||
outputDir: outputDir | ||
} | ||
markdownSteriods(markdownPath, config) | ||
const fileWasCreated = filePathExists(config.outputPath) | ||
t.true(fileWasCreated) | ||
// remove test file after assertion | ||
if (fileWasCreated && !DEBUG) { | ||
fs.unlinkSync(config.outputPath) | ||
} | ||
markdownMagic(markdownPath, config, function() { | ||
const newfile = path.join(outputDir, 'test.md') | ||
const fileWasCreated = filePathExists(newfile) | ||
t.true(fileWasCreated) | ||
// remove test file after assertion | ||
// emptyDirectory(outputDir) | ||
}) | ||
}) | ||
@@ -54,12 +74,11 @@ | ||
matchWord: 'YOLO', | ||
outputPath: path.join(__dirname, 'fixtures', 'output', 'test-match-word.md') | ||
outputDir: outputDir | ||
} | ||
markdownSteriods(filePath, config) | ||
const newContent = fs.readFileSync(config.outputPath, 'utf8') | ||
markdownMagic(filePath, config) | ||
const newfile = path.join(config.outputDir, 'custom-match-word-test.md') | ||
const newContent = fs.readFileSync(newfile, 'utf8') | ||
t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted') | ||
// remove test file after assertion | ||
if (filePathExists(config.outputPath) && !DEBUG) { | ||
fs.unlinkSync(config.outputPath) | ||
} | ||
fs.emptyDirSync(outputDir) | ||
}) | ||
@@ -72,17 +91,18 @@ | ||
const filePath = path.join(__dirname, 'fixtures', 'CODE-test.md') | ||
const updatedPath = path.join(__dirname, 'fixtures', 'output', 'new-code-path.md') | ||
const config = { outputDir: outputDir } | ||
const newfile = path.join(config.outputDir, 'CODE-test.md') | ||
const config = { outputPath: updatedPath } | ||
markdownSteriods(filePath, config) | ||
markdownMagic(filePath, config, function(err, data) { | ||
// console.log('data', data) | ||
const newContent = fs.readFileSync(newfile, 'utf8') | ||
// check local code | ||
t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted') | ||
// check remotely fetched code | ||
t.regex(newContent, /require\('dox'\)/, 'remote code snippet inserted') | ||
}) | ||
const newContent = fs.readFileSync(config.outputPath, 'utf8') | ||
// check local code | ||
t.regex(newContent, /module\.exports\.run/, 'local code snippet inserted') | ||
// check remotely fetched code | ||
t.regex(newContent, /const dox/, 'remote code snippet inserted') | ||
if (filePathExists(newfile)) { | ||
// fs.emptyDirSync(outputDir) | ||
} | ||
// remove test file after assertion | ||
if (filePathExists(config.outputPath) && !DEBUG) { | ||
fs.unlinkSync(config.outputPath) | ||
} | ||
}) | ||
@@ -92,15 +112,12 @@ | ||
const filePath = path.join(__dirname, 'fixtures', 'REMOTE-test.md') | ||
const updatedPath = path.join(__dirname, 'fixtures', 'output', 'new-remote-path.md') | ||
const config = { outputPath: updatedPath } | ||
markdownSteriods(filePath, config) | ||
const newContent = fs.readFileSync(config.outputPath, 'utf8') | ||
// check local code | ||
t.regex(newContent, /Install/, 'word Install not found in remote block') | ||
// remove test file after assertion | ||
if (filePathExists(config.outputPath) && !DEBUG) { | ||
fs.unlinkSync(config.outputPath) | ||
} | ||
const config = { outputDir: outputDir } | ||
markdownMagic(filePath, config, function() { | ||
const newfile = path.join(config.outputDir, 'REMOTE-test.md') | ||
const newContent = fs.readFileSync(newfile, 'utf8') | ||
// check local code | ||
t.regex(newContent, /Install/, 'word Install not found in remote block') | ||
// remove test file after assertion | ||
fs.emptyDirSync(outputDir) | ||
}) | ||
}) | ||
@@ -119,1 +136,6 @@ | ||
} | ||
function emptyDirectory(filePath, callBack) { | ||
fs.emptyDirSync(filePath) | ||
callBack && callBack(null) | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
37657
24
538
207
5
2
+ Addedfs-extra@^1.0.0
+ Addedglobby@^6.1.0
+ Addedarray-union@1.0.2(transitive)
+ Addedarray-uniq@1.0.3(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedfs-extra@1.0.0(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglobby@6.1.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedjsonfile@2.4.0(transitive)
+ Addedklaw@1.3.1(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpify@2.3.0(transitive)
+ Addedpinkie@2.0.4(transitive)
+ Addedpinkie-promise@2.0.1(transitive)
+ Addedwrappy@1.0.2(transitive)