newrelic 7.1.3 → 7.3.1

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.
Files changed (45) hide show
  1. package/NEWS.md +72 -0
  2. package/THIRD_PARTY_NOTICES.md +33 -2
  3. package/bin/test-naming-rules.js +4 -4
  4. package/lib/collector/facts.js +22 -8
  5. package/lib/collector/http-agents.js +20 -7
  6. package/lib/collector/remote-method.js +18 -4
  7. package/lib/config/index.js +34 -42
  8. package/lib/feature_flags.js +6 -2
  9. package/lib/grpc/connection.js +39 -15
  10. package/lib/instrumentation/core/async_hooks.js +106 -14
  11. package/lib/instrumentation/core/http.js +5 -0
  12. package/lib/shim/shim.js +6 -1
  13. package/lib/spans/create-span-event-aggregator.js +1 -0
  14. package/lib/spans/span-event.js +6 -3
  15. package/lib/spans/streaming-span-event.js +6 -3
  16. package/lib/transaction/index.js +29 -0
  17. package/newrelic.js +1 -1
  18. package/package.json +19 -6
  19. package/CONTRIBUTING.md +0 -135
  20. package/Migration Guide.md +0 -271
  21. package/ROADMAP_Node.md +0 -24
  22. package/SECURITY.md +0 -5
  23. package/THIRD_PARTY_NOTICES_ADDENDUM.md +0 -213
  24. package/bin/ca-gen.js +0 -91
  25. package/bin/cassandra-setup.sh +0 -11
  26. package/bin/check-workflow-run.js +0 -74
  27. package/bin/clean.sh +0 -18
  28. package/bin/compare-bench-results.js +0 -172
  29. package/bin/create-github-release.js +0 -109
  30. package/bin/create-release-tag.js +0 -95
  31. package/bin/docker-env-vars.sh +0 -15
  32. package/bin/docker-services.sh +0 -49
  33. package/bin/git-commands.js +0 -110
  34. package/bin/github.js +0 -144
  35. package/bin/npm-commands.js +0 -31
  36. package/bin/prepare-release.js +0 -359
  37. package/bin/publish-docs.sh +0 -16
  38. package/bin/run-bench.js +0 -137
  39. package/bin/run-versioned-tests.sh +0 -24
  40. package/bin/smoke.sh +0 -8
  41. package/bin/ssl.sh +0 -87
  42. package/bin/update-ca-bundle.sh +0 -20
  43. package/bin/update-cats.sh +0 -8
  44. package/jsdoc-conf.json +0 -18
  45. package/third_party_manifest.json +0 -619
@@ -1,359 +0,0 @@
1
- 'use strict'
2
-
3
- const fs = require('fs')
4
-
5
- const {program, Option} = require('commander')
6
-
7
- const Github = require('./github')
8
- const git = require('./git-commands')
9
- const npm = require('./npm-commands')
10
-
11
- const FILE_NAME = 'NEWS.md'
12
- const PROPOSED_NOTES_HEADER = 'Proposed Release Notes'
13
-
14
- const FORCE_RUN_DEAFULT_REMOTE = 'origin'
15
-
16
- // Add command line options
17
- program.addOption(
18
- new Option('--release-type <releaseType>', 'release type')
19
- .choices(['patch', 'minor', 'major'])
20
- .makeOptionMandatory()
21
- )
22
- program.option('--major-release', 'create a major release. (release-type option must be set to \'major\')')
23
- program.option('--remote <remote>', 'remote to push branch to', 'origin')
24
- program.option('--branch <branch>', 'branch to generate notes from', 'main')
25
- program.option('--repo-owner <repoOwner>', 'repository owner', 'newrelic')
26
- program.option('--dry-run', 'generate notes without creating a branch or PR')
27
- program.option('--no-pr', 'generate notes and branch but do not create PR')
28
- program.option('-f --force', 'bypass validation')
29
-
30
- function stopOnError(err) {
31
- if (err) {
32
- console.error(err)
33
- }
34
-
35
- console.log('Halting execution with exit code: 1')
36
- process.exit(1)
37
- }
38
-
39
- function logStep(step) {
40
- console.log(`\n ----- [Step]: ${step} -----\n`)
41
- }
42
-
43
- async function prepareReleaseNotes() {
44
- // Parse commandline options inputs
45
- program.parse()
46
-
47
- const options = program.opts()
48
-
49
- console.log('Script running with following options: ', JSON.stringify(options))
50
-
51
- logStep('Validation')
52
-
53
- if (options.force) {
54
- console.log('--force set. Skipping validation logic')
55
- }
56
-
57
- const startingBranch = options.branch.replace('refs/heads/', '')
58
-
59
- const isValid = options.force || (
60
- await validateReleaseType(options.releaseType, options.majorRelease) &&
61
- await validateRemote(options.remote) &&
62
- await validateLocalChanges() &&
63
- await validateCurrentBranch(startingBranch)
64
- )
65
-
66
- if (!isValid) {
67
- console.log('Invalid configuration. Halting script.')
68
- stopOnError()
69
- }
70
-
71
- const remote = options.remote || FORCE_RUN_DEAFULT_REMOTE
72
- console.log('Using remote: ', remote)
73
-
74
- try {
75
- logStep('Increment Version')
76
-
77
- await npm.version(options.releaseType, false)
78
-
79
- const packagePath = '../package.json'
80
- console.log('Extracting new version from package.json here: ', )
81
- const packageInfo = require(packagePath)
82
-
83
- const version = `v${packageInfo.version}`
84
- console.log('New version is: ', version)
85
-
86
- logStep('Branch Creation')
87
-
88
- const newBranchName = `release/${version}`
89
-
90
- if (options.dryRun) {
91
- console.log('Dry run indicated (--dry-run), not creating branch.')
92
- } else {
93
- console.log('Creating and checking out new branch: ', newBranchName)
94
- await git.checkoutNewBranch(newBranchName)
95
- }
96
-
97
- logStep('Commit Package Files')
98
-
99
- if (options.dryRun) {
100
- console.log('Dry run indicated (--dry-run), not committing package files.')
101
- } else {
102
- console.log('Adding and committing package files.')
103
- await git.addAllFiles()
104
- await git.commit(`Setting version to ${version}.`)
105
- }
106
-
107
- logStep('Create Release Notes')
108
-
109
- const releaseData = await generateReleaseNotes()
110
- await updateReleaseNotesFile(FILE_NAME, version, releaseData.notes)
111
-
112
- if (options.dryRun) {
113
- console.log('\nDry run indicated (--dry-run), skipping remaining steps.')
114
- return
115
- }
116
-
117
- logStep('Commit Release Notes')
118
-
119
- console.log('Adding and committing release notes.')
120
- await git.addAllFiles()
121
- await git.commit('Adds auto-generated release notes.')
122
-
123
- logStep('Push Branch')
124
-
125
- console.log('Pushing branch to remote: ', remote)
126
- await git.pushToRemote(remote, newBranchName)
127
-
128
- logStep('Create Pull Request')
129
- if (!options.pr) {
130
- console.log('No PR creation indicated (--no-pr), skipping remaining steps.')
131
- return
132
- }
133
-
134
- if (!process.env.GITHUB_TOKEN) {
135
- console.log('GITHUB_TOKEN required to create a pull request (PR)')
136
- stopOnError()
137
- }
138
-
139
- console.log('Creating draft PR with new release notes for repo owner: ', options.repoOwner)
140
- const remoteApi = new Github(options.repoOwner)
141
- const title = 'Updates release notes for next release'
142
- const body = getFormattedPrBody(releaseData)
143
- const prOptions = {
144
- head: newBranchName,
145
- base: 'main',
146
- title,
147
- body,
148
- draft: true
149
- }
150
-
151
- await remoteApi.createPR(prOptions)
152
-
153
- console.log('*** Full Run Successful ***')
154
- } catch (err) {
155
- stopOnError(err)
156
- }
157
- }
158
-
159
- async function validateReleaseType(releaseType, majorFlag) {
160
- if (releaseType === 'major' && !majorFlag) {
161
- console.log('WARNING: you must set the \'-m\' flag to create a major release.')
162
- return false
163
- }
164
-
165
- if (majorFlag && releaseType !== 'major') {
166
- console.log(`WARNING: ignoring \'-m, --major-release\' option as release type set to ${options.rel}.`)
167
- return false
168
- }
169
-
170
- return true
171
- }
172
-
173
- async function validateRemote(remote) {
174
- try {
175
- const remotes = await git.getPushRemotes()
176
-
177
- if (!remote) {
178
- console.log('No remote configured. Please execute with --remote.')
179
- console.log('Available remotes are: ', remotes)
180
- return false
181
- }
182
-
183
- if (!remotes[remote]) {
184
- console.log(`Configured remote (${remote}) not found in ${JSON.stringify(remotes)}`)
185
- return false
186
- }
187
-
188
- return true
189
- } catch (err) {
190
- console.error(err)
191
- return false
192
- }
193
- }
194
-
195
- async function validateLocalChanges() {
196
- try {
197
- const localChanges = await git.getLocalChanges()
198
- if (localChanges.length > 0) {
199
- console.log('Local changes detected: ', localChanges)
200
- console.log('Please commit to a feature branch or stash changes and then try again.')
201
- return false
202
- }
203
-
204
- return true
205
- } catch (err) {
206
- console.error(err)
207
- return false
208
- }
209
- }
210
-
211
- async function validateCurrentBranch(branch) {
212
- try {
213
- const currentBranch = await git.getCurrentBranch()
214
-
215
- if (branch != currentBranch) {
216
- console.log(
217
- 'Current checked-out branch (%s) does not match expected (%s)',
218
- currentBranch,
219
- branch
220
- )
221
- return false
222
- }
223
-
224
- return true
225
- } catch (err) {
226
- console.error(err)
227
- return false
228
- }
229
- }
230
-
231
- async function generateReleaseNotes() {
232
- const github = new Github()
233
- const latestRelease = await github.getLatestRelease()
234
- console.log(`The latest release is: ${latestRelease.name} published: ${latestRelease.published_at}`)
235
- console.log(`Tag: ${latestRelease.tag_name}, Target: ${latestRelease.target_commitish}`)
236
-
237
- const tag = await github.getTagByName(latestRelease.tag_name)
238
- console.log('The tag commit sha is: ', tag.commit.sha)
239
-
240
- const commit = await github.getCommit(tag.commit.sha)
241
- const commitDate = commit.commit.committer.date
242
-
243
- console.log(`Finding merged pull requests since: ${commitDate}`)
244
-
245
- const mergedPullRequests = await github.getMergedPullRequestsSince(commitDate)
246
- console.log(`Found ${mergedPullRequests.length}`)
247
-
248
- const releaseNoteData = mergedPullRequests.map((pr) => {
249
- const parts = pr.body.split(/(?:^|\n)##\s*/g)
250
-
251
- // If only has one part, not in appropriate format.
252
- if (parts.length === 1) {
253
- return {
254
- notes: generateUnformattedNotes(pr.body),
255
- url: pr.html_url
256
- }
257
- }
258
-
259
- const {1: proposedReleaseNotes} = parts
260
-
261
- const titleRemoved = proposedReleaseNotes.replace(PROPOSED_NOTES_HEADER, '')
262
- return {
263
- notes: titleRemoved,
264
- url: pr.html_url
265
- }
266
- })
267
-
268
- const finalData = releaseNoteData.reduce((result, currentValue) => {
269
- const trimmedNotes = currentValue.notes.trim()
270
- if (trimmedNotes) { // avoid adding lines for empty notes
271
- result.notes += '\n\n' + trimmedNotes
272
- }
273
- result.links += `\n* PR: ${currentValue.url}`
274
- return result
275
- }, {
276
- notes: '',
277
- links: ''
278
- })
279
-
280
- return finalData
281
- }
282
-
283
- function generateUnformattedNotes(originalNotes) {
284
- let unformattedNotes = originalNotes
285
-
286
- // Drop extra snyk details and just keep high-level summary.
287
- if (originalNotes.indexOf('snyk:metadata') >= 0) {
288
- const snykParts = originalNotes.split('<hr/>')
289
- const {0: snykDescription} = snykParts
290
-
291
- unformattedNotes = snykDescription.trim()
292
- }
293
-
294
- const needsReviewNotes = [
295
- '--- NOTES NEEDS REVIEW ---',
296
- unformattedNotes,
297
- '--------------------------'
298
- ].join('\n')
299
-
300
- return needsReviewNotes
301
- }
302
-
303
- function updateReleaseNotesFile(file, version, newNotes) {
304
- const promise = new Promise((resolve, reject) => {
305
- fs.readFile(file, 'utf8', function (err, data) {
306
- if (err) {
307
- return reject(err)
308
- }
309
-
310
- if (data.startsWith(`### ${version}`)) {
311
- const errMessage = [
312
- `${file} already contains '${version}'`,
313
- `Delete existing ${version} release notes (if desired) and run again`
314
- ].join('\n')
315
-
316
- return reject(new Error(errMessage))
317
- }
318
-
319
- // toISOString() will always return UTC time
320
- const todayFormatted = new Date().toISOString().split('T')[0]
321
- const newVersionHeader = `### ${version} (${todayFormatted})`
322
-
323
- const newContent = [
324
- newVersionHeader,
325
- newNotes,
326
- '\n\n',
327
- data
328
- ].join('')
329
-
330
- fs.writeFile(file, newContent, 'utf8', function (err) {
331
- if (err) {
332
- return reject(err)
333
- }
334
-
335
- console.log(`Added new release notes to ${file} under ${newVersionHeader}`)
336
-
337
- resolve()
338
- })
339
- })
340
- })
341
-
342
- return promise
343
- }
344
-
345
- function getFormattedPrBody(data) {
346
- const body = [
347
- '## Proposed Release Notes',
348
- data.notes,
349
- '## Links',
350
- data.links,
351
- '',
352
- '## Details',
353
- ''
354
- ].join('\n')
355
-
356
- return body
357
- }
358
-
359
- prepareReleaseNotes()
@@ -1,16 +0,0 @@
1
- #! /bin/sh
2
-
3
- # Copyright 2020 New Relic Corporation. All rights reserved.
4
- # SPDX-License-Identifier: Apache-2.0
5
-
6
- PACKAGE_VERSION=$(node -e 'console.log(require("./package").version)')
7
-
8
- git checkout gh-pages
9
- git pull origin gh-pages
10
- git merge -
11
- npm run public-docs
12
- git rm -r docs
13
- mv out docs
14
- git add docs
15
- git commit -m "docs: update for ${PACKAGE_VERSION}"
16
- git push origin gh-pages && git push public gh-pages:gh-pages
package/bin/run-bench.js DELETED
@@ -1,137 +0,0 @@
1
- /*
2
- * Copyright 2020 New Relic Corporation. All rights reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- 'use strict'
7
-
8
- var a = require('async')
9
- var cp = require('child_process')
10
- var glob = require('glob')
11
- var path = require('path')
12
-
13
-
14
- var cwd = path.resolve(__dirname, '..')
15
- var benchpath = path.resolve(cwd, 'test/benchmark')
16
-
17
- var tests = []
18
- var globs = []
19
- var opts = Object.create(null)
20
-
21
- process.argv.slice(2).forEach(function forEachFileArg(file) {
22
- if (/^--/.test(file)) {
23
- opts[file.substr(2)] = true
24
- } else if (/[*]/.test(file)) {
25
- globs.push(path.join(benchpath, file))
26
- } else if (/\.bench\.js$/.test(file)) {
27
- tests.push(path.join(benchpath, file))
28
- } else {
29
- globs.push(
30
- path.join(benchpath, file, '*.bench.js'),
31
- path.join(benchpath, file + '*.bench.js'),
32
- path.join(benchpath, file, '**/*.bench.js')
33
- )
34
- }
35
- })
36
-
37
- if (tests.length === 0 && globs.length === 0) {
38
- globs.push(
39
- path.join(benchpath, '*.bench.js'),
40
- path.join(benchpath, '**/*.bench.js')
41
- )
42
- }
43
-
44
- class ConsolePrinter {
45
- /* eslint-disable no-console */
46
- addTest(name, child) {
47
- console.log(name)
48
- child.stdout.on('data', (d) => process.stdout.write(d))
49
- child.stderr.on('data', (d) => process.stderr.write(d))
50
- child.once('exit', () => console.log(''))
51
- }
52
-
53
- finish() {
54
- console.log('')
55
- }
56
- /* eslint-enable no-console */
57
- }
58
-
59
- class JSONPrinter {
60
- constructor() {
61
- this._tests = Object.create(null)
62
- }
63
-
64
- addTest(name, child) {
65
- let output = ''
66
- this._tests[name] = null
67
- child.stdout.on('data', (d) => output += d.toString())
68
- child.stdout.on('end', () => this._tests[name] = JSON.parse(output))
69
- child.stderr.on('data', (d) => process.stderr.write(d))
70
- }
71
-
72
- finish() {
73
- /* eslint-disable no-console */
74
- console.log(JSON.stringify(this._tests, null, 2))
75
- /* eslint-enable no-console */
76
- }
77
- }
78
-
79
- run()
80
-
81
- function run() {
82
- const printer = opts.json ? new JSONPrinter() : new ConsolePrinter()
83
-
84
- a.series([
85
- function resolveGlobs(cb) {
86
- if (!globs.length) {
87
- return cb()
88
- }
89
-
90
- a.map(globs, glob, function afterGlobbing(err, resolved) {
91
- if (err) {
92
- console.error('Failed to glob:', err)
93
- process.exitCode = -1
94
- return cb(err)
95
- }
96
- resolved.forEach(function mergeResolved(files) {
97
- files.forEach(function mergeFile(file) {
98
- if (tests.indexOf(file) === -1) {
99
- tests.push(file)
100
- }
101
- })
102
- })
103
- cb()
104
- })
105
- },
106
- function runBenchmarks(cb) {
107
- tests.sort()
108
- a.eachSeries(tests, function spawnEachFile(file, cb) {
109
- var test = path.relative(benchpath, file)
110
-
111
- var args = [file]
112
- if (opts.inspect) {
113
- args.unshift('--inspect-brk')
114
- }
115
- var child = cp.spawn('node', args, {cwd: cwd, stdio: 'pipe'})
116
- printer.addTest(test, child)
117
-
118
- child.on('error', cb)
119
- child.on('exit', function onChildExit(code) {
120
- if (code) {
121
- return cb(new Error('Benchmark exited with code ' + code))
122
- }
123
- cb()
124
- })
125
- }, function afterSpawnEachFile(err) {
126
- if (err) {
127
- console.error('Spawning failed:', err)
128
- process.exitCode = -2
129
- return cb(err)
130
- }
131
- cb()
132
- })
133
- }
134
- ], () => {
135
- printer.finish()
136
- })
137
- }
@@ -1,24 +0,0 @@
1
- #! /bin/bash
2
-
3
- # Copyright 2020 New Relic Corporation. All rights reserved.
4
- # SPDX-License-Identifier: Apache-2.0
5
-
6
- set -x
7
-
8
- VERSIONED_MODE="${VERSIONED_MODE:---major}"
9
- if [[ $TRAVIS_BRANCH == `git describe --tags --always HEAD` ]]; then
10
- VERSIONED_MODE=--minor
11
- fi
12
-
13
- set -f
14
- directories=()
15
- if [[ "$1" != '' ]]; then
16
- directories=(
17
- "test/versioned/${1}"
18
- "node_modules/@newrelic/${1}/tests/versioned"
19
- )
20
- fi
21
-
22
- export AGENT_PATH=`pwd`
23
-
24
- time ./node_modules/.bin/versioned-tests $VERSIONED_MODE -i 2 ${directories[@]}
package/bin/smoke.sh DELETED
@@ -1,8 +0,0 @@
1
- #! /bin/sh
2
-
3
- # Copyright 2020 New Relic Corporation. All rights reserved.
4
- # SPDX-License-Identifier: Apache-2.0
5
-
6
- npm install --production --loglevel warn --no-package-lock
7
- npm --prefix test/smoke install --no-package-lock
8
- time node test/smoke/*.tap.js
package/bin/ssl.sh DELETED
@@ -1,87 +0,0 @@
1
- #! /bin/sh
2
-
3
- # Copyright 2020 New Relic Corporation. All rights reserved.
4
- # SPDX-License-Identifier: Apache-2.0
5
-
6
- # https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
7
- set -e # exit if any command fails
8
- set -x # be chatty and show the lines we're running
9
-
10
- # LibreSSL fails on the openssl ca step for reasons
11
- # that are mysterious and not understood, so let
12
- # bail early if we detect that's the case
13
- ENGINE_OPENSSL=`openssl version | awk '{print $(1)}'`
14
- if [ "$ENGINE_OPENSSL" = "LibreSSL" ]
15
- then
16
- echo "LibreSSL is not supported, please install a stock openssl and \n"
17
- echo "make sure that openssl binary is in your PATH"
18
- exit 1
19
- fi
20
-
21
- # CACONFIG is the only non-generated file
22
- CACONFIG="test/lib/test-ca.conf"
23
- SSLKEY="test/lib/test-key.key"
24
- CACERT="test/lib/ca-certificate.crt"
25
- CAINDEX="test/lib/ca-index"
26
- CASERIAL="test/lib/ca-serial"
27
- CERTIFICATE="test/lib/self-signed-test-certificate.crt"
28
-
29
- # USAGE: ./bin/ssl.sh clear
30
- # a sub command to remove all the generated files and start over
31
- if [ "$1" = "clear" ]
32
- then
33
- rm $SSLKEY
34
- rm $CACERT
35
- rm $CAINDEX
36
- rm $CASERIAL
37
- rm $CERTIFICATE
38
- exit 0
39
- fi
40
-
41
- # if there's already a certificate, then exit, but
42
- # exit with a success code so build continue
43
- if [ -e $CERTIFICATE ]; then
44
- exit 0;
45
- fi
46
-
47
- # generates an RSA key
48
- openssl genrsa -out $SSLKEY 1024
49
-
50
- # ca-index is the "certificate authority" database
51
- # and ca-serial is a file that openssl will read
52
- # "the next serial number for the ca-index entry"
53
- # from.
54
- touch $CAINDEX
55
- echo 000a > $CASERIAL
56
-
57
- # this generates a certificate for the
58
- # certificate authority
59
- openssl req \
60
- -new \
61
- -subj "/O=testsuite/OU=New Relic CA/CN=Node.js test CA" \
62
- -key $SSLKEY \
63
- -days 3650 \
64
- -x509 \
65
- -out $CACERT
66
-
67
- # this generates a "certificate signing request" file
68
- openssl req \
69
- -new \
70
- -subj "/O=testsuite/OU=Node.js agent team/CN=ssl.lvh.me" \
71
- -key $SSLKEY \
72
- -out server.csr
73
-
74
- # using the files generated above, this tells the
75
- # certificate authority about the request for a certificate,
76
- # which generates the self-signed-test-certificate.crt file.
77
- # This is the file used by the web server
78
- openssl ca \
79
- -batch \
80
- -cert $CACERT \
81
- -config $CACONFIG \
82
- -keyfile $SSLKEY \
83
- -in server.csr \
84
- -out $CERTIFICATE
85
-
86
- # remove the signing request now that we're done with it
87
- rm -f server.csr
@@ -1,20 +0,0 @@
1
- #!/bin/sh
2
-
3
- # Copyright 2020 New Relic Corporation. All rights reserved.
4
- # SPDX-License-Identifier: Apache-2.0
5
-
6
- set -e
7
-
8
- start_dir=`pwd`
9
-
10
- # needs to be checked out in the parent directory of the agent
11
- # (https://github.com/newrelic/SSL_CA_cert_bundle only available to NR staff)
12
- ca_store="../SSL_CA_cert_bundle"
13
- bundle_generator="./bin/ca-gen.js"
14
-
15
- if [ -d $ca_store ]; then
16
- cd $ca_store
17
- git pull --rebase origin master
18
- cd $start_dir
19
- node $bundle_generator
20
- fi
@@ -1,8 +0,0 @@
1
- #! /bin/sh
2
-
3
- # Copyright 2020 New Relic Corporation. All rights reserved.
4
- # SPDX-License-Identifier: Apache-2.0
5
-
6
- rm -rf test/lib/cross_agent_tests
7
- git clone git@source.datanerd.us:newrelic/cross_agent_tests.git test/lib/cross_agent_tests
8
- rm -rf test/lib/cross_agent_tests/.git
package/jsdoc-conf.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "opts": {
3
- "destination": "out/",
4
- "readme": "./README.md",
5
- "template": "./node_modules/minami"
6
- },
7
- "source": {
8
- "exclude": ["node_modules", "test"],
9
- "includePattern": ".+\\.js(doc)?$"
10
- },
11
- "plugins": [
12
- "plugins/markdown"
13
- ],
14
- "templates": {
15
- "cleverLinks": true,
16
- "showInheritedInNav": false
17
- }
18
- }