markdown-magic 3.3.0 → 3.3.2

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/cli.test.js CHANGED
@@ -19,391 +19,4 @@ test('Exports API', () => {
19
19
  assert.equal(typeof getGlobGroupsFromArgs, 'function', 'undefined val')
20
20
  })
21
21
 
22
- const longArgs = [
23
- 'test/fixtures/md/basic.md',
24
- 'test/fixtures/md/error-missing-transforms-two.md',
25
- 'test/fixtures/md/error-missing-transforms.md',
26
- 'test/fixtures/md/error-no-block-transform-defined.md',
27
- 'test/fixtures/md/error-unbalanced.md',
28
- 'test/fixtures/md/format-inline.md',
29
- 'test/fixtures/md/format-with-wacky-indentation.md',
30
- 'test/fixtures/md/inline-two.md',
31
- 'test/fixtures/md/inline.md',
32
- 'test/fixtures/md/missing-transform.md',
33
- 'test/fixtures/md/mixed.md',
34
- 'test/fixtures/md/no-transforms.md',
35
- 'test/fixtures/md/string.md',
36
- 'test/fixtures/md/syntax-legacy-colon.md',
37
- 'test/fixtures/md/syntax-legacy-query.md',
38
- 'test/fixtures/md/transform-code.md',
39
- 'test/fixtures/md/transform-custom.md',
40
- 'test/fixtures/md/transform-file.md',
41
- 'test/fixtures/md/transform-remote.md',
42
- 'test/fixtures/md/transform-toc.md',
43
- 'test/fixtures/md/transform-wordCount.md',
44
- 'debug',
45
- '--transform',
46
- 'test/fixtures/md/transform-code.md',
47
- 'test/fixtures/md/transform-custom.md',
48
- 'test/fixtures/md/transform-file.md',
49
- 'test/fixtures/md/transform-remote.md',
50
- 'test/fixtures/md/transform-toc.md',
51
- 'test/fixtures/md/transform-wordCount.md',
52
- '1233535235',
53
- '=',
54
- 'hahah',
55
- 'funky=hi',
56
- '--ignore',
57
- 'test/fixtures/output/basic.md',
58
- 'test/fixtures/output/block-no-transform.md',
59
- 'test/fixtures/output/error-missing-transforms-two.md',
60
- 'test/fixtures/output/error-missing-transforms.md',
61
- 'test/fixtures/output/fixture-code.md',
62
- 'test/fixtures/output/format-inline.md',
63
- 'test/fixtures/output/format-with-wacky-indentation.md',
64
- 'test/fixtures/output/go-simple.md',
65
- 'test/fixtures/output/inline-two.md',
66
- 'test/fixtures/output/inline.md',
67
- 'test/fixtures/output/missing-transform.md',
68
- 'test/fixtures/output/mixed.md',
69
- 'test/fixtures/output/params.md',
70
- 'test/fixtures/output/remote.md',
71
- 'test/fixtures/output/toc.md',
72
- 'test/fixtures/output/transform-code.md',
73
- 'test/fixtures/output/transform-custom.md',
74
- 'test/fixtures/output/transform-file.md',
75
- 'test/fixtures/output/transform-remote.md',
76
- 'test/fixtures/output/transform-toc.md',
77
- 'test/fixtures/output/transform-wordCount.md',
78
- 'test/fixtures/output/with-wacky-indentation.md',
79
- '--lol',
80
- '--whatever',
81
- 'test/fixtures/md/syntax-legacy-colon.md',
82
- 'test/fixtures/md/syntax-legacy-query.md',
83
- '--foo=bar',
84
- '--fun',
85
- 'lol.md',
86
- 'what=no.md',
87
- 'x',
88
- 'xno.md',
89
- 'what'
90
- ]
91
-
92
- test('getGlobGroupsFromArgs returns globs', () => {
93
- /* CLI command with list of files already passed in
94
- node ./cli.js test/fixtures/md/**.md debug --transform test/fixtures/md/transform-**.md 1233535235 = hahah funky=hi --ignore test/fixtures/output/**.md --lol --whatever test/fixtures/md/syntax-**.md --foo=bar --fun lol.md what=no.md x 'xno.md' what
95
- */
96
- const globData = getGlobGroupsFromArgs(longArgs)
97
- //*
98
- logInput(longArgs)
99
- deepLogger(globData)
100
- /** */
101
- assert.equal(globData.globGroups, [
102
- {
103
- key: '',
104
- rawKey: '',
105
- values: [
106
- 'test/fixtures/md/basic.md',
107
- 'test/fixtures/md/error-missing-transforms-two.md',
108
- 'test/fixtures/md/error-missing-transforms.md',
109
- 'test/fixtures/md/error-no-block-transform-defined.md',
110
- 'test/fixtures/md/error-unbalanced.md',
111
- 'test/fixtures/md/format-inline.md',
112
- 'test/fixtures/md/format-with-wacky-indentation.md',
113
- 'test/fixtures/md/inline-two.md',
114
- 'test/fixtures/md/inline.md',
115
- 'test/fixtures/md/missing-transform.md',
116
- 'test/fixtures/md/mixed.md',
117
- 'test/fixtures/md/no-transforms.md',
118
- 'test/fixtures/md/string.md',
119
- 'test/fixtures/md/syntax-legacy-colon.md',
120
- 'test/fixtures/md/syntax-legacy-query.md',
121
- 'test/fixtures/md/transform-code.md',
122
- 'test/fixtures/md/transform-custom.md',
123
- 'test/fixtures/md/transform-file.md',
124
- 'test/fixtures/md/transform-remote.md',
125
- 'test/fixtures/md/transform-toc.md',
126
- 'test/fixtures/md/transform-wordCount.md'
127
- ]
128
- },
129
- {
130
- key: 'transform',
131
- rawKey: '--transform',
132
- values: [
133
- 'test/fixtures/md/transform-code.md',
134
- 'test/fixtures/md/transform-custom.md',
135
- 'test/fixtures/md/transform-file.md',
136
- 'test/fixtures/md/transform-remote.md',
137
- 'test/fixtures/md/transform-toc.md',
138
- 'test/fixtures/md/transform-wordCount.md'
139
- ]
140
- },
141
- {
142
- key: 'ignore',
143
- rawKey: '--ignore',
144
- values: [
145
- 'test/fixtures/output/basic.md',
146
- 'test/fixtures/output/block-no-transform.md',
147
- 'test/fixtures/output/error-missing-transforms-two.md',
148
- 'test/fixtures/output/error-missing-transforms.md',
149
- 'test/fixtures/output/fixture-code.md',
150
- 'test/fixtures/output/format-inline.md',
151
- 'test/fixtures/output/format-with-wacky-indentation.md',
152
- 'test/fixtures/output/go-simple.md',
153
- 'test/fixtures/output/inline-two.md',
154
- 'test/fixtures/output/inline.md',
155
- 'test/fixtures/output/missing-transform.md',
156
- 'test/fixtures/output/mixed.md',
157
- 'test/fixtures/output/params.md',
158
- 'test/fixtures/output/remote.md',
159
- 'test/fixtures/output/toc.md',
160
- 'test/fixtures/output/transform-code.md',
161
- 'test/fixtures/output/transform-custom.md',
162
- 'test/fixtures/output/transform-file.md',
163
- 'test/fixtures/output/transform-remote.md',
164
- 'test/fixtures/output/transform-toc.md',
165
- 'test/fixtures/output/transform-wordCount.md',
166
- 'test/fixtures/output/with-wacky-indentation.md'
167
- ]
168
- },
169
- {
170
- key: 'whatever',
171
- rawKey: '--whatever',
172
- values: [
173
- 'test/fixtures/md/syntax-legacy-colon.md',
174
- 'test/fixtures/md/syntax-legacy-query.md'
175
- ]
176
- },
177
- { key: 'fun', rawKey: '--fun', values: [ 'lol.md' ] }
178
- ])
179
- })
180
-
181
- test('test 2', () => {
182
- /* CLI command with list of files already passed in
183
- node ./cli.js --file '**.md' 'funky**.md' billy --foo 'bar*123'
184
- */
185
- const rawArgv = [ '--file', '**.md', 'funky**.md', 'billy', '--foo', 'bar*123' ]
186
-
187
- logger(rawArgv.join(" "))
188
-
189
- const globData = getGlobGroupsFromArgs(rawArgv, {
190
- globKeys: ['file']
191
- })
192
- //*
193
- deepLogger(globData)
194
- /** */
195
- assert.equal(globData, {
196
- globGroups: [ { key: 'file', rawKey: '--file', values: [ '**.md', 'funky**.md' ] } ],
197
- otherOpts: [ 'billy', '--foo', 'bar*123' ]
198
- })
199
- })
200
-
201
- test('Handles multiple string values and groups them', () => {
202
- /* CLI command with list of files already passed in
203
- node ./cli.js 'test/fixtures/md/bar.md' 'test/fixtures/output/foo.md'
204
- */
205
- const rawArgv = [ 'test/fixtures/md/bar.md', 'test/fixtures/output/foo.md' ]
206
-
207
- const globData = getGlobGroupsFromArgs(rawArgv)
208
- //*
209
- logInput(rawArgv)
210
- deepLogger(globData)
211
- /** */
212
- assert.equal(globData, {
213
- globGroups: [
214
- {
215
- key: '',
216
- rawKey: '',
217
- values: [ 'test/fixtures/md/bar.md', 'test/fixtures/output/foo.md' ]
218
- }
219
- ],
220
- otherOpts: []
221
- })
222
- })
223
-
224
- test('Handles multiple string GLOB values and groups them', () => {
225
- /* CLI command with list of files already passed in
226
- node ./cli.js 'test/fixtures/md/**.md' 'test/fixtures/output/**.md'
227
- */
228
- const rawArgv = [ 'test/fixtures/md/**.md', 'test/fixtures/output/**.md' ]
229
-
230
- const globData = getGlobGroupsFromArgs(rawArgv)
231
- //*
232
- logInput(rawArgv)
233
- deepLogger(globData)
234
- /** */
235
- assert.equal(globData, {
236
- globGroups: [
237
- {
238
- key: '',
239
- rawKey: '',
240
- values: [ 'test/fixtures/md/**.md', 'test/fixtures/output/**.md' ]
241
- }
242
- ],
243
- otherOpts: []
244
- })
245
- })
246
-
247
-
248
- test('Handles globKey set with multiple file/glob like values supplied afterwards', () => {
249
- /* CLI command with list of files already passed in
250
- node ./cli.js --file 'foobar.md' "funktown/bar.md" '**.md' 'funky**.md' billy --foo 'bar*123'
251
- */
252
- const rawArgv = [
253
- '--file',
254
- 'foobar.md',
255
- 'funktown/bar.md',
256
- '**.md',
257
- 'funky**.md',
258
- 'billy',
259
- '--foo',
260
- 'bar*123'
261
- ]
262
-
263
- logger(rawArgv.join(" "))
264
-
265
- const globData = getGlobGroupsFromArgs(rawArgv, {
266
- globKeys: ['file']
267
- })
268
- //*
269
- logInput(rawArgv)
270
- deepLogger(globData)
271
- /** */
272
- assert.equal(globData, {
273
- globGroups: [ { key: 'file', rawKey: '--file', values: [
274
- 'foobar.md',
275
- 'funktown/bar.md',
276
- '**.md',
277
- 'funky**.md'
278
- ]
279
- }
280
- ],
281
- otherOpts: [ 'billy', '--foo', 'bar*123' ]
282
- })
283
- })
284
-
285
- test('Handles mixed strings, glob strings, array strings, and regex strings', () => {
286
- /* CLI command with list of files already passed in
287
- node ./cli.js --file 'test/fixtures/md/**.md' 'test/fixtures/output/**.md' '[foo.md, bar.whatever.md, /patter.md/]'
288
- */
289
- const rawArgv = [
290
- '--file',
291
- 'funktown/bar.md',
292
- 'test/fixtures/md/**.md',
293
- 'test/fixtures/output/**.md',
294
- '[foo.md, bar.whatever.md, /patter.md/]',
295
- '/funk.md/'
296
- ]
297
-
298
- logger(rawArgv.join(" "))
299
-
300
- const globData = getGlobGroupsFromArgs(rawArgv, {
301
- globKeys: ['file']
302
- })
303
- //*
304
- logInput(rawArgv)
305
- deepLogger(globData)
306
- /** */
307
- assert.equal(globData, {
308
- globGroups: [
309
- {
310
- key: 'file',
311
- rawKey: '--file',
312
- values: [
313
- 'funktown/bar.md',
314
- 'test/fixtures/md/**.md',
315
- 'test/fixtures/output/**.md',
316
- 'foo.md',
317
- 'bar.whatever.md',
318
- /patter\.md/,
319
- /funk\.md/
320
- ]
321
- }
322
- ],
323
- otherOpts: []
324
- })
325
- })
326
-
327
- test('Handles string arrays if globKeys set', () => {
328
- /* CLI command with list of files already passed in
329
- node ./cli.js --file '[**.md, /xyz**.md/]' 'funky**.md' billy --foo 'bar*123' --fuzz test/fixtures/output/**.md
330
- */
331
- const rawArgv = [
332
- '--file',
333
- '[**.md, /xyz**.md/]',
334
- 'funky**.md',
335
- 'billy',
336
- '--foo',
337
- 'bar*123',
338
- '--fuzz',
339
- 'test/fixtures/output/basic.md',
340
- 'test/fixtures/output/block-no-transform.md',
341
- 'test/fixtures/output/error-missing-transforms-two.md',
342
- 'test/fixtures/output/error-missing-transforms.md',
343
- 'test/fixtures/output/fixture-code.md',
344
- 'test/fixtures/output/format-inline.md',
345
- 'test/fixtures/output/format-with-wacky-indentation.md',
346
- 'test/fixtures/output/go-simple.md',
347
- 'test/fixtures/output/inline-two.md',
348
- 'test/fixtures/output/inline.md',
349
- 'test/fixtures/output/missing-transform.md',
350
- 'test/fixtures/output/mixed.md',
351
- 'test/fixtures/output/params.md',
352
- 'test/fixtures/output/remote.md',
353
- 'test/fixtures/output/toc.md',
354
- 'test/fixtures/output/transform-code.md',
355
- 'test/fixtures/output/transform-custom.md',
356
- 'test/fixtures/output/transform-file.md',
357
- 'test/fixtures/output/transform-remote.md',
358
- 'test/fixtures/output/transform-toc.md',
359
- 'test/fixtures/output/transform-wordCount.md',
360
- 'test/fixtures/output/with-wacky-indentation.md'
361
- ]
362
- const globData = getGlobGroupsFromArgs(rawArgv, {
363
- globKeys: ['file']
364
- })
365
- //*
366
- logInput(rawArgv)
367
- deepLogger(globData)
368
- /** */
369
- assert.equal(globData, {
370
- globGroups: [
371
- {
372
- key: 'file',
373
- rawKey: '--file',
374
- values: [ '**.md', /xyz\*\*\.md/, 'funky**.md' ]
375
- },
376
- {
377
- key: 'fuzz',
378
- rawKey: '--fuzz',
379
- values: [
380
- 'test/fixtures/output/basic.md',
381
- 'test/fixtures/output/block-no-transform.md',
382
- 'test/fixtures/output/error-missing-transforms-two.md',
383
- 'test/fixtures/output/error-missing-transforms.md',
384
- 'test/fixtures/output/fixture-code.md',
385
- 'test/fixtures/output/format-inline.md',
386
- 'test/fixtures/output/format-with-wacky-indentation.md',
387
- 'test/fixtures/output/go-simple.md',
388
- 'test/fixtures/output/inline-two.md',
389
- 'test/fixtures/output/inline.md',
390
- 'test/fixtures/output/missing-transform.md',
391
- 'test/fixtures/output/mixed.md',
392
- 'test/fixtures/output/params.md',
393
- 'test/fixtures/output/remote.md',
394
- 'test/fixtures/output/toc.md',
395
- 'test/fixtures/output/transform-code.md',
396
- 'test/fixtures/output/transform-custom.md',
397
- 'test/fixtures/output/transform-file.md',
398
- 'test/fixtures/output/transform-remote.md',
399
- 'test/fixtures/output/transform-toc.md',
400
- 'test/fixtures/output/transform-wordCount.md',
401
- 'test/fixtures/output/with-wacky-indentation.md'
402
- ]
403
- }
404
- ],
405
- otherOpts: [ 'billy', '--foo', 'bar*123' ]
406
- })
407
- })
408
-
409
22
  test.run()
@@ -0,0 +1,170 @@
1
+ const path = require('path')
2
+ const isGlob = require('is-glob')
3
+ const isValidFilePath = require('is-valid-path')
4
+ const { parse } = require('oparser')
5
+ const { getFirstCharacter } = require('./utils/text')
6
+ const { REGEX_REGEX, escapeRegexString } = require('./utils/regex')
7
+
8
+ const ARRAY_REGEX = /^\[(.*)\]$/
9
+ const NOT_OBJECT_LIKE = /^{[^:,]*}/
10
+ const IS_KEY_VALUE_NON_ARRAY = /^([A-Za-z0-9_.-]*)=\s?([^\[\{]]*)([^\[\{]*)$/
11
+ const IS_KEY_VALUE_IN_QUOTES = /^([A-Za-z0-9_.-]*)=\s?("|')(.*)(\2)$/
12
+ const IS_KEY_VALUE_START_WITH_QUOTE = /^([A-Za-z0-9_.-]*)=\s?("|')(.*)/
13
+ const IS_INTEGER = /^([A-Za-z0-9_.-]*)=\s?-?\d*(\.(?=\d))?\d*$/
14
+ const IS_BOOLEAN_OR_NULL = /^([A-Za-z0-9_.-]*)=\s?true|false|null|undefined\s?/
15
+
16
+ function isArrayLike(str) {
17
+ if (typeof str !== 'string') return false
18
+ return Boolean(ARRAY_REGEX.test(str))
19
+ }
20
+
21
+ function stringLooksLikeFile(value) {
22
+ return !value.match(/^-+/) // isn't option looking
23
+ && isValidFilePath(value)
24
+ && (
25
+ path.basename(value).indexOf('.') > -1 // has period
26
+ || getFirstCharacter(value) === '_' // starts with _
27
+ )
28
+ }
29
+
30
+ function getValue(val) {
31
+ return (val[1] !== '=') ? val[1] : val[0]
32
+ }
33
+
34
+ function trimLeadingDashes(value) {
35
+ return value.replace(/^-+/, '')
36
+ }
37
+
38
+ function removeNodeModules(value = '') {
39
+ if (typeof value !== 'string') {
40
+ return true
41
+ }
42
+ return !value.match(/node_modules\//)
43
+ }
44
+
45
+ function coerceStringToRegex(str) {
46
+ const isRegex = str.match(REGEX_REGEX)
47
+ if (!isRegex) {
48
+ return str
49
+ }
50
+ const [ _match, pattern, flags ] = isRegex
51
+ return new RegExp(escapeRegexString(pattern), flags)
52
+ }
53
+
54
+ function convertToArray(str = '') {
55
+ const { fixedArray } = parse(`fixedArray=${str}`)
56
+ return (fixedArray || [])
57
+ }
58
+
59
+ function addValue(value, currentCollection) {
60
+ if (isArrayLike(value)) {
61
+ const array = convertToArray(value)
62
+ return Array.from(new Set(currentCollection.concat(array)))
63
+ }
64
+ if (currentCollection.indexOf(value) > -1) {
65
+ return currentCollection
66
+ }
67
+ return currentCollection.concat(value)
68
+ }
69
+
70
+ function customIsGlob(arg) {
71
+ // If looks like json object, return false
72
+ if (arg.match(/^{[^}]*:[^}]*}/)) {
73
+ return false
74
+ }
75
+ return isGlob(arg)
76
+ }
77
+
78
+ function getGlobGroupsFromArgs(args, opts = {}) {
79
+ const globKeys = opts.globKeys || []
80
+ let preceding = ['', '']
81
+ let collection = []
82
+ let globGroups = []
83
+ let reserved = []
84
+ let otherOpts = []
85
+ let cacheKey = ''
86
+
87
+ for (let i = 0; i < args.length; i++) {
88
+ const isLastArg = (args.length - 1) === i
89
+ const arg = args[i]
90
+ const prevArg = args[i - 1]
91
+ const looksLikeFile = stringLooksLikeFile(arg)
92
+
93
+ if (looksLikeFile && typeof cacheKey !== 'undefined') {
94
+ collection.push(arg)
95
+ } else if (arg.match(/^-+/) && !arg.match(/=/)) {
96
+ cacheKey = arg
97
+ if (collection.length) {
98
+ const val = getValue(preceding)
99
+ reserved.push(val)
100
+ globGroups.push({
101
+ key: trimLeadingDashes(val),
102
+ rawKey: val,
103
+ values: collection.filter(removeNodeModules).map((x) => coerceStringToRegex(x))
104
+ })
105
+ collection = []
106
+ }
107
+ preceding = [ prevArg, arg ]
108
+ } else if (cacheKey && arg.match(/=/)) {
109
+ cacheKey = undefined
110
+ }
111
+
112
+ const cleanKey = trimLeadingDashes(cacheKey || '')
113
+ const isDefinedGlobKey = globKeys.includes(cleanKey) || globKeys.includes(cacheKey)
114
+
115
+ if (isDefinedGlobKey && (isGlob(arg) || looksLikeFile)) {
116
+ collection = addValue(arg, collection)
117
+ } else {
118
+ const notObjectLike = arg.match(NOT_OBJECT_LIKE) && !isArrayLike(arg)
119
+ if (
120
+ (notObjectLike) ||
121
+ !cacheKey && customIsGlob(arg) && !arg.match(/=/)
122
+ ) {
123
+ collection = addValue(arg, collection)
124
+ } else if (!looksLikeFile) {
125
+ if (
126
+ arg.match(IS_KEY_VALUE_IN_QUOTES)
127
+ || arg.match(IS_KEY_VALUE_START_WITH_QUOTE)
128
+ || arg.match(IS_INTEGER)
129
+ || arg.match(IS_BOOLEAN_OR_NULL)
130
+ ) {
131
+ otherOpts.push(arg)
132
+ } else if (arg.match(IS_KEY_VALUE_NON_ARRAY)) {
133
+ otherOpts.push(arg.replace(IS_KEY_VALUE_NON_ARRAY, '$1="$2$3"'))
134
+ } else {
135
+ otherOpts.push(arg)
136
+ }
137
+ }
138
+ }
139
+
140
+ if (isLastArg && collection.length) {
141
+ const val = getValue(preceding)
142
+ reserved.push(val)
143
+ globGroups.push({
144
+ key: trimLeadingDashes(val),
145
+ rawKey: val,
146
+ values: collection.filter(removeNodeModules).map((x) => coerceStringToRegex(x)),
147
+ })
148
+ collection = []
149
+ }
150
+ }
151
+
152
+ return {
153
+ globGroups,
154
+ otherOpts: otherOpts.filter((opt) => !reserved.includes(opt))
155
+ }
156
+ }
157
+
158
+ module.exports = {
159
+ getGlobGroupsFromArgs,
160
+ // Export helpers for testing
161
+ isArrayLike,
162
+ stringLooksLikeFile,
163
+ getValue,
164
+ trimLeadingDashes,
165
+ removeNodeModules,
166
+ coerceStringToRegex,
167
+ convertToArray,
168
+ addValue,
169
+ customIsGlob
170
+ }