markdown-magic 3.0.9 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js
CHANGED
|
@@ -33,6 +33,11 @@ const defaultTransforms = {
|
|
|
33
33
|
remote: remoteTransform
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
const defaultOptions = {
|
|
37
|
+
failOnMissingTransforms: false,
|
|
38
|
+
failOnMissingRemote: true,
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
/**!
|
|
37
42
|
* Allowed file syntaxes
|
|
38
43
|
* @typedef {'md' | 'js' | 'yml' | 'yaml'} SyntaxType
|
|
@@ -61,7 +66,9 @@ const defaultTransforms = {
|
|
|
61
66
|
* @property {boolean} [dryRun = false] - See planned execution of matched blocks
|
|
62
67
|
* @property {boolean} [debug = false] - See debug details
|
|
63
68
|
* @property {boolean} [silent = false] - Silence all console output
|
|
69
|
+
* @property {boolean} [applyTransformsToSource = true] - Apply transforms to source file. Default is true.
|
|
64
70
|
* @property {boolean} [failOnMissingTransforms = false] - Fail if transform functions are missing. Default skip blocks.
|
|
71
|
+
* @property {boolean} [failOnMissingRemote = true] - Fail if remote file is missing.
|
|
65
72
|
*/
|
|
66
73
|
|
|
67
74
|
/**
|
|
@@ -109,6 +116,9 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
109
116
|
} else if (typeof globOrOpts === 'object') {
|
|
110
117
|
opts = globOrOpts
|
|
111
118
|
}
|
|
119
|
+
|
|
120
|
+
opts = Object.assign({}, defaultOptions, opts)
|
|
121
|
+
|
|
112
122
|
const {
|
|
113
123
|
transforms,
|
|
114
124
|
// open,
|
|
@@ -117,6 +127,7 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
117
127
|
outputFlatten = false,
|
|
118
128
|
useGitGlob = false,
|
|
119
129
|
failOnMissingTransforms = false,
|
|
130
|
+
failOnMissingRemote = true,
|
|
120
131
|
dryRun = false,
|
|
121
132
|
debug = false,
|
|
122
133
|
syntax = 'md',
|
|
@@ -128,7 +139,7 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
128
139
|
const removeComments = output.removeComments || false
|
|
129
140
|
const pathFormatter = output.pathFormatter
|
|
130
141
|
|
|
131
|
-
let applyTransformsToSource =
|
|
142
|
+
let applyTransformsToSource = true
|
|
132
143
|
if (typeof output.applyTransformsToSource !== 'undefined') {
|
|
133
144
|
applyTransformsToSource = output.applyTransformsToSource
|
|
134
145
|
// @ts-ignore
|
|
@@ -137,6 +148,8 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
137
148
|
applyTransformsToSource = opts.applyTransformsToSource
|
|
138
149
|
}
|
|
139
150
|
|
|
151
|
+
opts.applyTransformsToSource = applyTransformsToSource
|
|
152
|
+
|
|
140
153
|
const logger = (silent) ? () => {} : console.log
|
|
141
154
|
|
|
142
155
|
let open = OPEN_WORD
|
|
@@ -314,6 +327,7 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
314
327
|
if (pathFormatter) {
|
|
315
328
|
newPath = pathFormatter({ filePath: newPath })
|
|
316
329
|
}
|
|
330
|
+
// console.log('newPath', newPath)
|
|
317
331
|
// const cleanerDirPath = path.dirname(file)
|
|
318
332
|
// const baseDir = cleanerDirPath.replace(cwd, '')
|
|
319
333
|
// const cleanerDir = baseDir
|
|
@@ -628,9 +642,9 @@ async function markdownMagic(globOrOpts = {}, options = {}) {
|
|
|
628
642
|
logger(`${LINE}`)
|
|
629
643
|
success(`Markdown Magic Done. ${elasped.seconds} seconds`, silent)
|
|
630
644
|
logger(`${LINE}`)
|
|
631
|
-
|
|
632
645
|
return {
|
|
633
|
-
|
|
646
|
+
// @TODO maybe seperate changed and output files
|
|
647
|
+
filesChanged: plan.filter(({ isChanged, isNewPath }) => isChanged || isNewPath).map(({ outputPath }) => outputPath),
|
|
634
648
|
results: plan,
|
|
635
649
|
errors,
|
|
636
650
|
}
|
package/lib/process-file.js
CHANGED
|
@@ -4,18 +4,9 @@ const { readFile, writeFile } = require('./utils/fs')
|
|
|
4
4
|
const { processContents } = require('./process-contents')
|
|
5
5
|
|
|
6
6
|
async function processFile(opts = {}) {
|
|
7
|
-
const { content, syntax, outputPath, dryRun, patterns, output = {} } = opts
|
|
7
|
+
const { content, syntax, outputPath, dryRun, patterns, output = {}, applyTransformsToSource } = opts
|
|
8
8
|
const outputDir = output.directory || opts.outputDir
|
|
9
9
|
|
|
10
|
-
let applyTransformsToSource = false
|
|
11
|
-
if (typeof output.applyTransformsToSource !== 'undefined') {
|
|
12
|
-
applyTransformsToSource = output.applyTransformsToSource
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
} else if (typeof opts.applyTransformsToSource !== 'undefined') {
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
applyTransformsToSource = opts.applyTransformsToSource
|
|
17
|
-
}
|
|
18
|
-
|
|
19
10
|
let srcPath = opts.srcPath
|
|
20
11
|
if (srcPath && content) {
|
|
21
12
|
throw new Error(`Can't set both "srcPath" & "content"`)
|
|
@@ -43,7 +34,9 @@ async function processFile(opts = {}) {
|
|
|
43
34
|
srcPath,
|
|
44
35
|
syntax: syntaxType,
|
|
45
36
|
})
|
|
46
|
-
|
|
37
|
+
/*
|
|
38
|
+
console.log('result', result)
|
|
39
|
+
/** */
|
|
47
40
|
|
|
48
41
|
if (dryRun) {
|
|
49
42
|
return result
|
|
@@ -55,11 +48,11 @@ async function processFile(opts = {}) {
|
|
|
55
48
|
if (result.stripComments && patterns.openPattern && patterns.closePattern) {
|
|
56
49
|
cleanContents = result.updatedContents.replace(patterns.openPattern, '').replace(patterns.closePattern, '')
|
|
57
50
|
}
|
|
58
|
-
if (outputDir) {
|
|
51
|
+
if (outputDir || (srcPath !== outputPath)) {
|
|
59
52
|
// console.log(`- Update output file: ${outputPath}`)
|
|
60
53
|
await writeFile(outputPath, cleanContents)
|
|
61
54
|
}
|
|
62
|
-
if (
|
|
55
|
+
if (applyTransformsToSource) {
|
|
63
56
|
// console.log(`- Update source file: ${srcPath}`)
|
|
64
57
|
await writeFile(srcPath, result.updatedContents)
|
|
65
58
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
|
-
const remoteRequest = require('../../utils/remoteRequest')
|
|
3
|
+
const { remoteRequest } = require('../../utils/remoteRequest')
|
|
4
4
|
const { isLocalPath } = require('../../utils/fs')
|
|
5
5
|
const { deepLog } = require('../../utils/logs')
|
|
6
6
|
const { getLineCount, getTextBetweenLines } = require('../../utils/text')
|
|
@@ -8,6 +8,7 @@ const { resolveGithubContents, isGithubLink } = require('./resolve-github-file')
|
|
|
8
8
|
|
|
9
9
|
const GITHUB_LINK = /https:\/\/github\.com\/([^/\s]*)\/([^/\s]*)\/blob\//
|
|
10
10
|
const GIST_LINK = /https:\/\/gist\.github\.com\/([^/\s]*)\/([^/\s]*)(\/)?/
|
|
11
|
+
const RAW_URL_LIKE = /^([A-Za-z0-9_]*)\.([A-Za-z0-9_]*)\/(.*)/
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Options for specifying source code to include in documentation.
|
|
@@ -37,7 +38,7 @@ const GIST_LINK = /https:\/\/gist\.github\.com\/([^/\s]*)\/([^/\s]*)(\/)?/
|
|
|
37
38
|
// usage https://github.com/linear/linear/blame/93981d3a3db571e2f8efdce9f5271ea678941c43/packages/sdk/README.md#L1
|
|
38
39
|
|
|
39
40
|
module.exports = async function CODE(api) {
|
|
40
|
-
const { content, srcPath } = api
|
|
41
|
+
const { content, srcPath, settings } = api
|
|
41
42
|
/** @type {CodeTransformOptions} */
|
|
42
43
|
const options = api.options || {}
|
|
43
44
|
// console.log('CODE API', api)
|
|
@@ -57,19 +58,31 @@ module.exports = async function CODE(api) {
|
|
|
57
58
|
deepLog(api.getCurrentBlock())
|
|
58
59
|
throw new Error('Missing "src" attribute')
|
|
59
60
|
}
|
|
61
|
+
let remoteContent
|
|
60
62
|
let codeFilePath = src
|
|
61
63
|
if (isLocalPath(src)) {
|
|
62
64
|
const fileDir = (srcPath) ? path.dirname(srcPath) : process.cwd()
|
|
63
65
|
codeFilePath = path.resolve(fileDir, src)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
throw e
|
|
66
|
+
/* If the path looks like a URL, attempt to resolve it */
|
|
67
|
+
const isUrlLike = src.match(RAW_URL_LIKE)
|
|
68
|
+
if (isUrlLike) {
|
|
69
|
+
remoteContent = await resolveRemoteContent(options, settings, srcPath)
|
|
70
|
+
code = remoteContent
|
|
70
71
|
}
|
|
71
|
-
if (!
|
|
72
|
-
|
|
72
|
+
if (!remoteContent) {
|
|
73
|
+
try {
|
|
74
|
+
// console.log('READFILE CODE', codeFilePath)
|
|
75
|
+
code = fs.readFileSync(codeFilePath, 'utf8')
|
|
76
|
+
if (!syntax) {
|
|
77
|
+
syntax = path.extname(codeFilePath).replace(/^./, '')
|
|
78
|
+
}
|
|
79
|
+
} catch (e) {
|
|
80
|
+
if (isUrlLike) {
|
|
81
|
+
throw new Error(`Unable to resolve ${src}`)
|
|
82
|
+
}
|
|
83
|
+
console.log(`FILE NOT FOUND ${codeFilePath}`)
|
|
84
|
+
throw e
|
|
85
|
+
}
|
|
73
86
|
}
|
|
74
87
|
} else {
|
|
75
88
|
/* Automatically get raw code files from github */
|
|
@@ -83,23 +96,15 @@ module.exports = async function CODE(api) {
|
|
|
83
96
|
// https://gist.github.com/DavidWells/7d2e0e1bc78f4ac59a123ddf8b74932d
|
|
84
97
|
// https://gist.githubusercontent.com/DavidWells/7d2e0e1bc78f4ac59a123ddf8b74932d/raw/0808a83de7f07c931fb81ed691c1d6bbafad29d1/aligning-images.md
|
|
85
98
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (isGithubLink(src)) {
|
|
89
|
-
remoteContent = await resolveGithubContents({
|
|
90
|
-
repoFilePath: src,
|
|
91
|
-
accessToken,
|
|
92
|
-
// debug: true
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Try initial remote request if public url
|
|
97
|
-
if (!remoteContent) {
|
|
98
|
-
remoteContent = remoteRequest(src)
|
|
99
|
-
}
|
|
99
|
+
remoteContent = await resolveRemoteContent(options, settings, srcPath)
|
|
100
100
|
|
|
101
101
|
if (!remoteContent) {
|
|
102
|
-
|
|
102
|
+
const errorMsg = `WARNING: ${src} URL NOT FOUND or internet connection is off or no access to remove URL`
|
|
103
|
+
console.log(errorMsg)
|
|
104
|
+
console.log('settings', settings)
|
|
105
|
+
if (settings.failOnMissingRemote) {
|
|
106
|
+
throw new Error(errorMsg)
|
|
107
|
+
}
|
|
103
108
|
return originalContent
|
|
104
109
|
}
|
|
105
110
|
code = remoteContent
|
|
@@ -162,3 +167,24 @@ module.exports = async function CODE(api) {
|
|
|
162
167
|
${code}
|
|
163
168
|
\`\`\``
|
|
164
169
|
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
async function resolveRemoteContent(options, settings, srcPath) {
|
|
173
|
+
const { src, accessToken } = options
|
|
174
|
+
let remoteContent
|
|
175
|
+
|
|
176
|
+
if (isGithubLink(src)) {
|
|
177
|
+
remoteContent = await resolveGithubContents({
|
|
178
|
+
repoFilePath: src,
|
|
179
|
+
accessToken,
|
|
180
|
+
// debug: true
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Try initial remote request if public url
|
|
185
|
+
if (!remoteContent) {
|
|
186
|
+
remoteContent = await remoteRequest(src, settings, srcPath)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return remoteContent
|
|
190
|
+
}
|
|
@@ -5,7 +5,7 @@ const { getTextBetweenLines } = require('../../utils/text')
|
|
|
5
5
|
const VALID_SLUG_REGEX = /^[A-Z-a-z0-9_-]*$/
|
|
6
6
|
const VALID_FILE_REGEX = /^[^;]*$/
|
|
7
7
|
const GITHUB_LINK_REGEX = /^(?:https:\/\/)?github\.com\/([^/\s]*)\/([^/\s]*)\/blob\/([^/\s]*)\/([^\s]*)/
|
|
8
|
-
const GITHUB_RAW_LINK_REGEX = /^(?:https:\/\/)?raw\.githubusercontent\.com\/([^/\s]*)\/([^/\s]*)\/([^/\s]*)\/([^\s]*)/
|
|
8
|
+
const GITHUB_RAW_LINK_REGEX = /^(?:https:\/\/)?(?:raw\.)?githubusercontent\.com\/([^/\s]*)\/([^/\s]*)\/([^/\s]*)\/([^\s]*)/
|
|
9
9
|
|
|
10
10
|
function isGithubLink(str = '') {
|
|
11
11
|
return isGithubRepoLink(str) || isGithubRawLink(str)
|
package/lib/transforms/remote.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
const remoteRequest = require('../utils/remoteRequest')
|
|
1
|
+
const { remoteRequest } = require('../utils/remoteRequest')
|
|
2
2
|
|
|
3
|
-
module.exports = function REMOTE(api) {
|
|
3
|
+
module.exports = async function REMOTE(api) {
|
|
4
4
|
// console.log('REMOTE api', api)
|
|
5
5
|
const { options, content, settings } = api
|
|
6
6
|
const { regex } = settings
|
|
7
7
|
// console.log('MAKE REMOTE REQUEST')
|
|
8
|
-
const remoteContent = remoteRequest(options.url)
|
|
8
|
+
const remoteContent = await remoteRequest(options.url, settings, api.srcPath)
|
|
9
9
|
if (!remoteContent) {
|
|
10
10
|
return content
|
|
11
11
|
}
|
|
@@ -1,19 +1,50 @@
|
|
|
1
|
+
const fetch = require('node-fetch')
|
|
1
2
|
const request = require('sync-request')
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
function formatUrl(url = '') {
|
|
5
|
+
return url.match(/^https?:\/\//) ? url : `https://${url}`
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function remoteRequestSync(url, settings = {}, srcPath) {
|
|
4
9
|
let body
|
|
5
|
-
const finalUrl = (url
|
|
10
|
+
const finalUrl = formatUrl(url)
|
|
6
11
|
try {
|
|
7
12
|
// @ts-expect-error
|
|
8
13
|
const res = request('GET', finalUrl)
|
|
9
14
|
body = res.getBody('utf8')
|
|
10
15
|
} catch (e) {
|
|
11
|
-
console.log(
|
|
12
|
-
|
|
16
|
+
console.log(`⚠️ WARNING: REMOTE URL "${finalUrl}" NOT FOUND`)
|
|
17
|
+
const msg = (e.message || '').split('\n')[0] + `\nFix "${url}" value in ${srcPath}`
|
|
18
|
+
console.log(msg)
|
|
19
|
+
if (settings.failOnMissingRemote) {
|
|
20
|
+
throw new Error(msg)
|
|
21
|
+
}
|
|
13
22
|
}
|
|
14
23
|
return body
|
|
15
24
|
}
|
|
16
25
|
|
|
26
|
+
async function remoteRequest(url, settings = {}, srcPath) {
|
|
27
|
+
let body
|
|
28
|
+
const finalUrl = formatUrl(url)
|
|
29
|
+
try {
|
|
30
|
+
const res = await fetch(finalUrl)
|
|
31
|
+
body = await res.text()
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.log(`⚠️ WARNING: REMOTE URL "${finalUrl}" NOT FOUND`)
|
|
34
|
+
const msg = (e.message || '').split('\n')[0] + `\nFix "${url}" value in ${srcPath}`
|
|
35
|
+
console.log(msg)
|
|
36
|
+
if (settings.failOnMissingRemote) {
|
|
37
|
+
throw new Error(msg)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return body
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = {
|
|
44
|
+
remoteRequestSync,
|
|
45
|
+
remoteRequest
|
|
46
|
+
}
|
|
47
|
+
|
|
17
48
|
/*
|
|
18
49
|
TODO add file caching?
|
|
19
50
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdown-magic",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Automatically update markdown files with content from external sources",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"is-valid-path": "^0.1.1",
|
|
54
54
|
"micro-mdx-parser": "^1.1.0",
|
|
55
55
|
"mri": "^1.2.0",
|
|
56
|
+
"node-fetch": "^2.7.0",
|
|
56
57
|
"oparser": "^3.0.13",
|
|
57
58
|
"smart-glob": "^1.0.2",
|
|
58
59
|
"sync-request": "^6.1.0"
|