markdown-magic 3.6.5 → 3.7.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/README.md CHANGED
@@ -43,6 +43,8 @@ This `README.md` is generated with `markdown-magic` [view the raw file](https://
43
43
  - [> CODE](#-code)
44
44
  - [> FILE](#-file)
45
45
  - [> REMOTE](#-remote)
46
+ - [> fileTree](#-filetree)
47
+ - [> install](#-install)
46
48
  - [Inline transforms](#inline-transforms)
47
49
  - [Legacy v1 & v2 plugins](#legacy-v1--v2-plugins)
48
50
  - [Adding Custom Transforms](#adding-custom-transforms)
@@ -267,7 +269,7 @@ Markdown Magic comes with a couple of built-in transforms for you to use or you
267
269
  Generate table of contents from markdown file
268
270
 
269
271
  **Options:**
270
- - `firsth1` - *boolean* - (optional): Show first h1 of doc in table of contents. Default `false`
272
+ - `firstH1` - *boolean* - (optional): Show first h1 of doc in table of contents. Default `false`
271
273
  - `collapse` - *boolean* - (optional): Collapse the table of contents in a detail accordion. Default `false`
272
274
  - `collapseText` - *string* - (optional): Text the toc accordion summary
273
275
  - `excludeText` - *string* - (optional): Text to exclude in the table of contents. Default `Table of Contents`
@@ -362,6 +364,99 @@ Default `matchWord` is `doc-gen`
362
364
 
363
365
  ---
364
366
 
367
+ | Name | Type | Description |
368
+ |:---------------------------|:---------------:|:-----------|
369
+ | `content` | `string` | The current content of the comment block. |
370
+ | `options` | `object` | The options passed in from the comment declaration. |
371
+
372
+ ### > fileTree
373
+
374
+ Generate a file tree table of contents
375
+
376
+ **Options:**
377
+ - `src` (optional): The directory path to generate the file tree for. Default `.` (current directory)
378
+ - `maxDepth` (optional): Maximum depth to traverse in the directory tree. Default `3`
379
+ - `includeFiles` (optional): Whether to include files in the tree or just directories. Default `true`
380
+ - `exclude` (optional): Array of glob patterns to exclude from the tree. Default `[]`
381
+ - `showSize` (optional): Whether to show file sizes. Default `false`
382
+ - `format` (optional): Output format: "tree" or "list". Default `"tree"`
383
+
384
+ **Example:**
385
+ ```md
386
+ <!-- doc-gen fileTree src="./src" maxDepth=2 -->
387
+ file tree will be generated here
388
+ <!-- end-doc-gen -->
389
+ ```
390
+
391
+ **Example Output (tree format):**
392
+ ```
393
+ └── src/
394
+ ├── transforms/
395
+ │ ├── code/
396
+ │ │ ...
397
+ │ ├── fileTree.js
398
+ │ ├── index.js
399
+ │ └── toc.js
400
+ ├── utils/
401
+ │ ├── fs.js
402
+ │ ├── logs.js
403
+ │ └── text.js
404
+ └── index.js
405
+ ```
406
+
407
+ **Example Output (list format):**
408
+ ```md
409
+ - **src/**
410
+ - **transforms/**
411
+ - **code/**
412
+ - ...
413
+ - fileTree.js
414
+ - index.js
415
+ - toc.js
416
+ - **utils/**
417
+ - fs.js
418
+ - logs.js
419
+ - text.js
420
+ - index.js
421
+ ```
422
+
423
+ **Example with file sizes:**
424
+ ```
425
+ └── src/
426
+ ├── index.js (15.2 KB)
427
+ └── package.json (552 B)
428
+ ```
429
+
430
+ Default `matchWord` is `doc-gen`
431
+
432
+ ---
433
+
434
+ | Name | Type | Description |
435
+ |:---------------------------|:---------------:|:-----------|
436
+ | `content` | `string` | The current content of the comment block. |
437
+ | `options` | `object` | The options passed in from the comment declaration. |
438
+
439
+ ### > install
440
+
441
+ Generate installation instructions in a markdown table format
442
+
443
+ **Options:**
444
+ - `packageName` (optional): The name of the package to install. If not provided, will try to read from package.json
445
+ - `isDev` (optional): Whether to install the package as a dev dependency. Default `false`
446
+ - `header` (optional): The header to use for the installation instructions. Default `# Installation`
447
+ - `body` (optional): The body to use for the installation instructions. Default `Install the \`${packageName}\` cli using your favorite package manager.`
448
+
449
+ **Example:**
450
+ ```md
451
+ <!-- doc-gen install -->
452
+ Installation instructions will be generated here
453
+ <!-- end-doc-gen -->
454
+ ```
455
+
456
+ Default `matchWord` is `doc-gen`
457
+
458
+ ---
459
+
365
460
  | Name | Type | Description |
366
461
  |:---------------------------|:---------------:|:-----------|
367
462
  | `content` | `string` | The current content of the comment block. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markdown-magic",
3
- "version": "3.6.5",
3
+ "version": "3.7.0",
4
4
  "description": "Automatically update markdown files with content from external sources",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  const path = require('path')
2
2
  // @TODO remove this once we have swapped out node-fetch@2.7
3
- const moduleAlias = require('module-alias') // "Fix" for puncode dep warning in node 22+
4
- moduleAlias.addAlias('punycode', 'punycode/') // "Fix" for puncode dep warning in node 22+
3
+ const moduleAlias = require('module-alias') // "Fix" for punycode dep warning in node 22+
4
+ moduleAlias.addAlias('punycode', 'punycode/') // "Fix" for punycode dep warning in node 22+
5
5
  const { glob, globWithGit } = require('smart-glob')
6
6
  const codeTransform = require('./transforms/code')
7
7
  const fileTransform = require('./transforms/file')
8
+ const fileTreeTransform = require('./transforms/fileTree')
8
9
  const tocTransform = require('./transforms/toc')
9
10
  const sectionTocTransform = require('./transforms/sectionToc')
10
11
  const wordCountTransform = require('./transforms/wordCount')
@@ -32,6 +33,7 @@ const LINE = '──────────────────────
32
33
  const defaultTransforms = {
33
34
  CODE: codeTransform,
34
35
  FILE: fileTransform,
36
+ fileTree: fileTreeTransform,
35
37
  TOC: tocTransform,
36
38
  sectionToc: sectionTocTransform,
37
39
  wordCount: wordCountTransform,
@@ -0,0 +1,213 @@
1
+ const fs = require('fs')
2
+ const path = require('path')
3
+
4
+ /**
5
+ * Options for configuring the file tree table of contents.
6
+ * @typedef {Object} FileTreeTransformOptions
7
+ * @property {string} [src="."] - The directory path to generate the file tree for. Default is `.` (current directory).
8
+ * @property {number} [maxDepth=3] - Maximum depth to traverse in the directory tree. Default is `3`.
9
+ * @property {boolean} [includeFiles=true] - Whether to include files in the tree or just directories. Default is `true`.
10
+ * @property {string[]} [exclude=[]] - Array of glob patterns to exclude from the tree.
11
+ * @property {boolean} [showSize=false] - Whether to show file sizes. Default is `false`.
12
+ * @property {string} [format="tree"] - Output format: "tree" or "list". Default is `"tree"`.
13
+ * @example
14
+ ```md
15
+ <!-- doc-gen fileTree src="./src" maxDepth=2 -->
16
+ file tree will be generated here
17
+ <!-- end-doc-gen -->
18
+ ```
19
+ */
20
+
21
+ /**
22
+ * Generate a file tree table of contents
23
+ * @param {Object} api - The markdown-magic API object
24
+ * @returns {string} The generated file tree markdown
25
+ */
26
+ module.exports = function fileTree(api) {
27
+ const { options, srcPath } = api
28
+ /** @type {FileTreeTransformOptions} */
29
+ const opts = options || {}
30
+
31
+ const targetPath = opts.src || '.'
32
+ const maxDepth = opts.maxDepth ? Number(opts.maxDepth) : 3
33
+ const includeFiles = opts.includeFiles !== false
34
+ const exclude = opts.exclude || []
35
+ const showSize = opts.showSize === true
36
+ const format = opts.format || 'tree'
37
+
38
+ // Resolve the target path relative to the source file
39
+ const fileDir = path.dirname(srcPath)
40
+ const resolvedPath = path.resolve(fileDir, targetPath)
41
+
42
+ try {
43
+ const tree = generateFileTree(resolvedPath, {
44
+ maxDepth,
45
+ includeFiles,
46
+ exclude,
47
+ showSize,
48
+ currentDepth: 0
49
+ })
50
+
51
+ if (format === 'list') {
52
+ return formatAsList(tree)
53
+ }
54
+
55
+ return formatAsTree(tree)
56
+ } catch (error) {
57
+ console.error(`Error generating file tree for ${resolvedPath}:`, error.message)
58
+ return `<!-- Error: Could not generate file tree for ${targetPath} -->`
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Generate file tree structure
64
+ * @param {string} dirPath - Directory path to scan
65
+ * @param {Object} options - Options for tree generation
66
+ * @returns {Object} Tree structure
67
+ */
68
+ function generateFileTree(dirPath, options) {
69
+ const { maxDepth, includeFiles, exclude, showSize, currentDepth } = options
70
+
71
+ if (currentDepth >= maxDepth) {
72
+ return { type: 'directory', name: path.basename(dirPath), children: [], truncated: true }
73
+ }
74
+
75
+ let items
76
+ try {
77
+ items = fs.readdirSync(dirPath)
78
+ } catch (error) {
79
+ return { type: 'directory', name: path.basename(dirPath), children: [], error: true }
80
+ }
81
+
82
+ // Filter out excluded items
83
+ items = items.filter(item => {
84
+ // Skip hidden files and common ignored directories
85
+ if (item.startsWith('.') && !item.match(/\.(md|txt|json)$/)) {
86
+ return false
87
+ }
88
+ if (['node_modules', '.git', '.DS_Store', 'dist', 'build'].includes(item)) {
89
+ return false
90
+ }
91
+
92
+ // Apply custom exclude patterns
93
+ return !exclude.some(pattern => {
94
+ const regex = new RegExp(pattern.replace(/\*/g, '.*'))
95
+ return regex.test(item)
96
+ })
97
+ })
98
+
99
+ const children = []
100
+
101
+ for (const item of items) {
102
+ const itemPath = path.join(dirPath, item)
103
+ const stats = fs.statSync(itemPath)
104
+
105
+ if (stats.isDirectory()) {
106
+ const subTree = generateFileTree(itemPath, {
107
+ ...options,
108
+ currentDepth: currentDepth + 1
109
+ })
110
+ children.push(subTree)
111
+ } else if (includeFiles) {
112
+ children.push({
113
+ type: 'file',
114
+ name: item,
115
+ size: showSize ? stats.size : undefined
116
+ })
117
+ }
118
+ }
119
+
120
+ // Sort: directories first, then files, alphabetically
121
+ children.sort((a, b) => {
122
+ if (a.type !== b.type) {
123
+ return a.type === 'directory' ? -1 : 1
124
+ }
125
+ return a.name.localeCompare(b.name)
126
+ })
127
+
128
+ return {
129
+ type: 'directory',
130
+ name: path.basename(dirPath) || path.basename(path.resolve(dirPath)),
131
+ children
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Format tree as ASCII tree structure
137
+ * @param {Object} tree - Tree structure
138
+ * @returns {string} Formatted tree
139
+ */
140
+ function formatAsTree(tree) {
141
+ const lines = []
142
+
143
+ function traverse(node, prefix = '', isLast = true) {
144
+ const connector = isLast ? '└── ' : '├── '
145
+ const name = node.type === 'directory' ? `${node.name}/` : node.name
146
+ const size = node.size ? ` (${formatBytes(node.size)})` : ''
147
+
148
+ lines.push(`${prefix}${connector}${name}${size}`)
149
+
150
+ if (node.children && node.children.length > 0) {
151
+ const extension = isLast ? ' ' : '│ '
152
+ node.children.forEach((child, index) => {
153
+ const childIsLast = index === node.children.length - 1
154
+ traverse(child, prefix + extension, childIsLast)
155
+ })
156
+ }
157
+
158
+ if (node.truncated) {
159
+ const extension = isLast ? ' ' : '│ '
160
+ lines.push(`${prefix}${extension}...`)
161
+ }
162
+ }
163
+
164
+ traverse(tree)
165
+
166
+ return '```\n' + lines.join('\n') + '\n```'
167
+ }
168
+
169
+ /**
170
+ * Format tree as a list
171
+ * @param {Object} tree - Tree structure
172
+ * @returns {string} Formatted list
173
+ */
174
+ function formatAsList(tree) {
175
+ const lines = []
176
+
177
+ function traverse(node, depth = 0) {
178
+ const indent = ' '.repeat(depth)
179
+ const name = node.type === 'directory' ? `**${node.name}/**` : node.name
180
+ const size = node.size ? ` *(${formatBytes(node.size)})*` : ''
181
+
182
+ lines.push(`${indent}- ${name}${size}`)
183
+
184
+ if (node.children && node.children.length > 0) {
185
+ node.children.forEach(child => {
186
+ traverse(child, depth + 1)
187
+ })
188
+ }
189
+
190
+ if (node.truncated) {
191
+ lines.push(`${indent} - ...`)
192
+ }
193
+ }
194
+
195
+ traverse(tree)
196
+
197
+ return lines.join('\n')
198
+ }
199
+
200
+ /**
201
+ * Format bytes as human readable string
202
+ * @param {number} bytes - Bytes to format
203
+ * @returns {string} Formatted string
204
+ */
205
+ function formatBytes(bytes) {
206
+ if (bytes === 0) return '0 B'
207
+
208
+ const k = 1024
209
+ const sizes = ['B', 'KB', 'MB', 'GB']
210
+ const i = Math.floor(Math.log(bytes) / Math.log(k))
211
+
212
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
213
+ }
@@ -1,5 +1,6 @@
1
1
  const code = require('./code')
2
2
  const file = require('./file')
3
+ const fileTree = require('./fileTree')
3
4
  const remoteContent = require('./remote')
4
5
  const toc = require('./toc')
5
6
  const sectionToc = require('./sectionToc')
@@ -12,7 +13,7 @@ const transforms = {
12
13
  * Generate table of contents from markdown file
13
14
  *
14
15
  * **Options:**
15
- * - `firsth1` - *boolean* - (optional): Show first h1 of doc in table of contents. Default `false`
16
+ * - `firstH1` - *boolean* - (optional): Show first h1 of doc in table of contents. Default `false`
16
17
  * - `collapse` - *boolean* - (optional): Collapse the table of contents in a detail accordion. Default `false`
17
18
  * - `collapseText` - *string* - (optional): Text the toc accordion summary
18
19
  * - `excludeText` - *string* - (optional): Text to exclude in the table of contents. Default `Table of Contents`
@@ -112,6 +113,73 @@ const transforms = {
112
113
  * @return {string} Updated content to place in the content block
113
114
  */
114
115
  REMOTE: remoteContent,
116
+ /**
117
+ * ### > fileTree
118
+ *
119
+ * Generate a file tree table of contents
120
+ *
121
+ * **Options:**
122
+ * - `src` (optional): The directory path to generate the file tree for. Default `.` (current directory)
123
+ * - `maxDepth` (optional): Maximum depth to traverse in the directory tree. Default `3`
124
+ * - `includeFiles` (optional): Whether to include files in the tree or just directories. Default `true`
125
+ * - `exclude` (optional): Array of glob patterns to exclude from the tree. Default `[]`
126
+ * - `showSize` (optional): Whether to show file sizes. Default `false`
127
+ * - `format` (optional): Output format: "tree" or "list". Default `"tree"`
128
+ *
129
+ * **Example:**
130
+ * ```md
131
+ * <!-- doc-gen fileTree src="./src" maxDepth=2 -->
132
+ * file tree will be generated here
133
+ * <!-- end-doc-gen -->
134
+ * ```
135
+ *
136
+ * **Example Output (tree format):**
137
+ * ```
138
+ * └── src/
139
+ * ├── transforms/
140
+ * │ ├── code/
141
+ * │ │ ...
142
+ * │ ├── fileTree.js
143
+ * │ ├── index.js
144
+ * │ └── toc.js
145
+ * ├── utils/
146
+ * │ ├── fs.js
147
+ * │ ├── logs.js
148
+ * │ └── text.js
149
+ * └── index.js
150
+ * ```
151
+ *
152
+ * **Example Output (list format):**
153
+ * ```md
154
+ * - **src/**
155
+ * - **transforms/**
156
+ * - **code/**
157
+ * - ...
158
+ * - fileTree.js
159
+ * - index.js
160
+ * - toc.js
161
+ * - **utils/**
162
+ * - fs.js
163
+ * - logs.js
164
+ * - text.js
165
+ * - index.js
166
+ * ```
167
+ *
168
+ * **Example with file sizes:**
169
+ * ```
170
+ * └── src/
171
+ * ├── index.js (15.2 KB)
172
+ * └── package.json (552 B)
173
+ * ```
174
+ *
175
+ * Default `matchWord` is `doc-gen`
176
+ *
177
+ * ---
178
+ * @param {string} content The current content of the comment block
179
+ * @param {object} options The options passed in from the comment declaration
180
+ * @return {string} Updated content to place in the content block
181
+ */
182
+ fileTree: fileTree,
115
183
  /**
116
184
  * ### > install
117
185
  *
@@ -33,7 +33,7 @@ module.exports = async function TOC(api) {
33
33
  return sectionToc(api)
34
34
  }
35
35
 
36
- opts.firsth1 = (opts.firsth1) ? true : false
36
+ opts.firsth1 = (opts.firsth1 || opts.firstH1) ? true : false
37
37
  let contents = currentFileContent
38
38
  // console.log('contents', contents)
39
39
 
@@ -54,7 +54,7 @@ module.exports = async function TOC(api) {
54
54
  trimLeadingHeading: true,
55
55
  // maxHeaderLevel: 2, // default: 4
56
56
  // title: '**Table of Contents**',
57
- // isNotitle: true,
57
+ // isNoTitle: true,
58
58
  // isFolding: true,
59
59
  // entryPrefix: '*',
60
60
  // processAll: true,
package/src/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Allowed file syntaxes
3
- * @typedef {'md' | 'js' | 'yml' | 'yaml'} SyntaxType
3
+ * @typedef {'md' | 'js' | 'yml' | 'yaml' | 'toml' | 'sql'} SyntaxType
4
4
  */
5
5
 
6
6
  /** @type {SyntaxType} */
@@ -42,6 +42,9 @@ test('getGitignoreContents', async () => {
42
42
  'misc',
43
43
  'misc/**/**.js',
44
44
  "__misc",
45
+ 'large-table.md',
46
+ 'large-table.js',
47
+ 'large-table-data.json',
45
48
  '**/old-test/cool.md',
46
49
  'pids',
47
50
  '*.pid',
@@ -53,6 +53,30 @@ const yaml = {
53
53
  }
54
54
  }
55
55
 
56
+ const sql = {
57
+ tags: ['/*', '*/'],
58
+ pattern: [
59
+ '\/\\*+',
60
+ '\\*+/'
61
+ ],
62
+ singleLineTag: '--',
63
+ singleLinePattern: '--',
64
+ singleLine: '--.*$',
65
+ content: '[\\s\\S]*?'
66
+ }
67
+
68
+ const toml = {
69
+ tags: ['#', '#'],
70
+ pattern: [
71
+ '#+',
72
+ '#+'
73
+ ],
74
+ singleLineTag: '#',
75
+ singleLinePattern: '#+',
76
+ singleLine: '#.*$',
77
+ content: '[ \\t\\S]*?'
78
+ }
79
+
56
80
  const syntaxMap = {
57
81
  // <!-- x -->
58
82
  md: html,
@@ -66,8 +90,12 @@ const syntaxMap = {
66
90
  jsx: jsx,
67
91
  mdx: jsx,
68
92
  // ## x ##
93
+ yml: yaml,
69
94
  yaml: yaml,
70
- yml: yaml
95
+ // -- x
96
+ sql: sql,
97
+ // # x
98
+ toml: toml
71
99
  }
72
100
 
73
101
  // Additional comment syntaxes for future
package/src/utils/text.js CHANGED
@@ -188,11 +188,18 @@ function stripComments(str, syntax = 'md') {
188
188
  const [ openPattern, closePattern ] = syntaxData.pattern
189
189
  const OR = (syntaxData.singleLine) ? `|\\s?[ \\t]*${syntaxData.singleLine}` : ''
190
190
  const CONTENT = syntaxData.content || '[\\s\\S]*?'
191
- const pattern = new RegExp(`\\s?[ \\t]*${openPattern}(${CONTENT})?${closePattern}${OR}`, 'gim')
192
- // console.log('pattern', pattern)
193
- return str.replace(pattern, '')
194
- // https://regex101.com/r/XKHU18/5
195
- return str.replace(/\s?[ \t]*\/\*[\s\S]*?\*\/|\s?[ \t]*\/\/.*$|\/\*{1,}[\n\*]*(\s?[\s\S]*?)?\*+\//gm, '')
191
+
192
+ // Handle multi-line comments
193
+ const multiLinePattern = new RegExp(`\\s?[ \\t]*${openPattern}${CONTENT}${closePattern}`, 'gim')
194
+ let result = str.replace(multiLinePattern, '')
195
+
196
+ // Handle single-line comments if they exist
197
+ if (syntaxData.singleLine) {
198
+ const singleLinePattern = new RegExp(`\\s?[ \\t]*${syntaxData.singleLine}.*$`, 'gm')
199
+ result = result.replace(singleLinePattern, '')
200
+ }
201
+
202
+ return result
196
203
  }
197
204
 
198
205
 
@@ -50,7 +50,7 @@ nice
50
50
  nice={{ value: nice, cool: "true" }}
51
51
  soclose=[jdjdjd, hdhfhfhffh]
52
52
  rad="boss"
53
- cool=true notCool=false
53
+ cool=true notCool=false
54
54
  nooooo={[one, two, 3, 4]}
55
55
  numberZero=0,
56
56
  xyz=999,
@@ -72,7 +72,7 @@ actual content
72
72
  <!-- XYZ:START(cool) xxx
73
73
  hhddh=cool -->
74
74
  wowow
75
- whatever we want 
75
+ whatever we want
76
76
  <!-- XYZ:END -->
77
77
 
78
78
 
@@ -135,7 +135,7 @@ test('Remove Markdown comments', () => {
135
135
  '',
136
136
  '',
137
137
  'wowow',
138
- 'whatever we want ',
138
+ 'whatever we want ',
139
139
  '',
140
140
  '',
141
141
  'xyz',
@@ -297,6 +297,79 @@ test('Convert comment syntax', () => {
297
297
  // assert.equal(typeof parsedValue, 'string')
298
298
  })
299
299
 
300
+ test('Remove TOML comments', () => {
301
+ const parsedValue = stripComments(`
302
+ # This is a TOML comment
303
+ title = "TOML Example"
304
+ # Another comment
305
+ [owner]
306
+ name = "Tom Preston-Werner"
307
+ # Inline comment
308
+ organization = "GitHub" # This is an inline comment
309
+ # Multi-line comment
310
+ # that continues
311
+ # on multiple lines
312
+ created = 1979-05-27T07:32:00Z
313
+
314
+ [database]
315
+ server = "192.168.1.1"
316
+ ports = [ 8001, 8001, 8002 ]
317
+ connection_max = 5000
318
+ enabled = true
319
+ `, 'toml')
320
+
321
+ assert.equal(typeof parsedValue, 'string')
322
+ assert.equal(parsedValue.match(/#/), null)
323
+ assert.equal(parsedValue.split('\n'), [
324
+ '',
325
+ 'title = "TOML Example"',
326
+ '[owner]',
327
+ 'name = "Tom Preston-Werner"',
328
+ 'organization = "GitHub"',
329
+ 'created = 1979-05-27T07:32:00Z',
330
+ '',
331
+ '[database]',
332
+ 'server = "192.168.1.1"',
333
+ 'ports = [ 8001, 8001, 8002 ]',
334
+ 'connection_max = 5000',
335
+ 'enabled = true',
336
+ ''
337
+ ])
338
+ })
339
+
340
+ test('Remove SQL comments', () => {
341
+ const parsedValue = stripComments(`
342
+ -- This is a single line comment
343
+ SELECT * FROM users
344
+ -- Another single line comment
345
+ WHERE id = 1
346
+ /* This is a multi-line
347
+ comment that spans
348
+ multiple lines */
349
+
350
+ AND active = true
351
+ SELECT name -- inline comment
352
+ FROM products
353
+ WHERE price > 100 /* another inline comment */
354
+ `, 'sql')
355
+
356
+ console.log('parsedValue', parsedValue)
357
+ assert.equal(typeof parsedValue, 'string')
358
+ assert.equal(parsedValue.match(/--/), null, 'SQL comments should be removed 1')
359
+ assert.equal(parsedValue.match(/\/\*/), null, 'SQL comments should be removed 2')
360
+ assert.equal(parsedValue.match(/\*\//), null, 'SQL comments should be removed 3')
361
+ assert.equal(parsedValue.split('\n'), [
362
+ '',
363
+ 'SELECT * FROM users',
364
+ 'WHERE id = 1',
365
+ '',
366
+ 'AND active = true',
367
+ 'SELECT name',
368
+ 'FROM products',
369
+ 'WHERE price > 100',
370
+ ''
371
+ ])
372
+ })
300
373
 
301
374
  function logOutput(value) {
302
375
  console.log(value.split('\n'))