@corellium/corellium-cli 1.2.0 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. package/.gitlab-ci.yml +46 -1
  2. package/ci/gitlab-build.sh +1 -1
  3. package/coverage/cobertura-coverage.xml +9 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +87 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +101 -0
  8. package/coverage/lcov-report/prettify.css +1 -0
  9. package/coverage/lcov-report/prettify.js +2 -0
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/sorter.js +196 -0
  12. package/coverage/lcov.info +0 -0
  13. package/index.js +2 -0
  14. package/node_modules/@babel/cli/node_modules/commander/package.json +22 -57
  15. package/node_modules/@babel/cli/node_modules/make-dir/package.json +57 -92
  16. package/node_modules/@babel/cli/node_modules/pify/package.json +49 -84
  17. package/node_modules/@babel/cli/node_modules/semver/package.json +15 -50
  18. package/node_modules/@babel/cli/node_modules/slash/package.json +32 -67
  19. package/node_modules/@babel/cli/package.json +33 -69
  20. package/node_modules/@corellium/client-api/package.json +10 -39
  21. package/node_modules/@jridgewell/resolve-uri/package.json +35 -74
  22. package/node_modules/@jridgewell/sourcemap-codec/package.json +38 -73
  23. package/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs +91 -57
  24. package/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map +1 -1
  25. package/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js +90 -56
  26. package/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map +1 -1
  27. package/node_modules/@jridgewell/trace-mapping/dist/types/trace-mapping.d.ts +5 -5
  28. package/node_modules/@jridgewell/trace-mapping/dist/types/types.d.ts +12 -5
  29. package/node_modules/@jridgewell/trace-mapping/package.json +34 -71
  30. package/node_modules/@nicolo-ribaudo/chokidar-2/package.json +17 -54
  31. package/node_modules/ansi-regex/package.json +53 -88
  32. package/node_modules/ansi-styles/package.json +54 -94
  33. package/node_modules/anymatch/package.json +23 -55
  34. package/node_modules/asynckit/package.json +40 -73
  35. package/node_modules/axios/package.json +41 -71
  36. package/node_modules/balanced-match/package.json +17 -48
  37. package/node_modules/binary-extensions/package.json +36 -72
  38. package/node_modules/brace-expansion/package.json +18 -49
  39. package/node_modules/braces/package.json +25 -75
  40. package/node_modules/call-bind/package.json +78 -124
  41. package/node_modules/chokidar/package.json +35 -73
  42. package/node_modules/cliui/package.json +48 -86
  43. package/node_modules/color-convert/package.json +20 -58
  44. package/node_modules/color-name/package.json +28 -60
  45. package/node_modules/combined-stream/package.json +14 -51
  46. package/node_modules/component-emitter/package.json +12 -44
  47. package/node_modules/concat-map/package.json +40 -88
  48. package/node_modules/convert-source-map/package.json +23 -54
  49. package/node_modules/cookiejar/package.json +11 -43
  50. package/node_modules/debug/package.json +32 -86
  51. package/node_modules/delayed-stream/package.json +14 -52
  52. package/node_modules/dotenv/package.json +32 -63
  53. package/node_modules/emoji-regex/package.json +27 -57
  54. package/node_modules/escalade/package.json +23 -58
  55. package/node_modules/fast-safe-stringify/package.json +28 -72
  56. package/node_modules/fill-range/package.json +23 -71
  57. package/node_modules/follow-redirects/package.json +37 -76
  58. package/node_modules/form-data/package.json +37 -73
  59. package/node_modules/formidable/package.json +17 -51
  60. package/node_modules/fs-readdir-recursive/package.json +15 -49
  61. package/node_modules/fs.realpath/package.json +16 -52
  62. package/node_modules/function-bind/package.json +23 -60
  63. package/node_modules/get-caller-file/package.json +22 -52
  64. package/node_modules/get-intrinsic/package.json +86 -123
  65. package/node_modules/glob/package.json +29 -67
  66. package/node_modules/glob-parent/package.json +22 -69
  67. package/node_modules/has/package.json +21 -54
  68. package/node_modules/has-symbols/package.json +99 -132
  69. package/node_modules/inflight/package.json +15 -47
  70. package/node_modules/inherits/package.json +12 -53
  71. package/node_modules/is-binary-path/package.json +38 -74
  72. package/node_modules/is-extglob/package.json +17 -51
  73. package/node_modules/is-fullwidth-code-point/package.json +40 -78
  74. package/node_modules/is-glob/package.json +21 -67
  75. package/node_modules/is-number/package.json +21 -64
  76. package/node_modules/lru-cache/package.json +22 -60
  77. package/node_modules/methods/package.json +17 -63
  78. package/node_modules/mime/package.json +15 -47
  79. package/node_modules/mime-db/package.json +20 -66
  80. package/node_modules/mime-types/package.json +15 -63
  81. package/node_modules/minimatch/package.json +20 -60
  82. package/node_modules/ms/package.json +19 -57
  83. package/node_modules/multi-progress/package.json +15 -45
  84. package/node_modules/normalize-path/package.json +20 -62
  85. package/node_modules/object-inspect/package.json +48 -80
  86. package/node_modules/once/package.json +14 -55
  87. package/node_modules/path-is-absolute/package.json +11 -46
  88. package/node_modules/picomatch/package.json +23 -59
  89. package/node_modules/progress/package.json +16 -64
  90. package/node_modules/qs/package.json +73 -104
  91. package/node_modules/readdirp/package.json +42 -82
  92. package/node_modules/require-directory/package.json +24 -56
  93. package/node_modules/safe-buffer/package.json +5 -37
  94. package/node_modules/semver/package.json +31 -69
  95. package/node_modules/side-channel/package.json +65 -97
  96. package/node_modules/string-width/package.json +54 -96
  97. package/node_modules/string_decoder/package.json +13 -46
  98. package/node_modules/strip-ansi/package.json +52 -93
  99. package/node_modules/superagent/node_modules/form-data/package.json +37 -73
  100. package/node_modules/superagent/node_modules/readable-stream/package.json +27 -59
  101. package/node_modules/superagent/package.json +8 -58
  102. package/node_modules/to-regex-range/package.json +20 -60
  103. package/node_modules/util-deprecate/package.json +14 -48
  104. package/node_modules/uuid/package.json +69 -101
  105. package/node_modules/wrap-ansi/package.json +60 -96
  106. package/node_modules/wrappy/package.json +16 -49
  107. package/node_modules/y18n/package.json +38 -72
  108. package/node_modules/yallist/package.json +15 -54
  109. package/node_modules/yargs/package.json +67 -98
  110. package/node_modules/yargs-parser/package.json +47 -82
  111. package/package.json +62 -64
  112. package/src/clients/Instance.js +4 -0
  113. package/src/commands/extensions/delete.js +2 -1
  114. package/src/commands/extensions/list.js +3 -2
  115. package/src/commands/firmware/list.js +3 -2
  116. package/src/commands/images/create.js +2 -2
  117. package/src/commands/images/delete.js +1 -0
  118. package/src/commands/images/list.js +3 -2
  119. package/src/commands/index.js +0 -2
  120. package/src/commands/{agent → instances}/apps/index.js +3 -3
  121. package/src/commands/instances/create.js +9 -3
  122. package/src/commands/{agent → instances}/file.js +2 -2
  123. package/src/commands/instances/index.js +6 -1
  124. package/src/commands/instances/input.js +52 -0
  125. package/src/commands/instances/list.js +3 -2
  126. package/src/commands/instances/upgrade.js +2 -2
  127. package/src/commands/projects/create.js +2 -2
  128. package/src/commands/projects/delete.js +2 -1
  129. package/src/commands/projects/list.js +3 -2
  130. package/src/commands/webplayer/create.js +2 -2
  131. package/src/commands/webplayer/list.js +2 -2
  132. package/src/error.js +12 -6
  133. package/src/table.js +1 -1
  134. package/src/utils.js +19 -40
  135. package/node_modules/@jridgewell/trace-mapping/src/any-map.ts +0 -166
  136. package/node_modules/@jridgewell/trace-mapping/src/binary-search.ts +0 -115
  137. package/node_modules/@jridgewell/trace-mapping/src/by-source.ts +0 -64
  138. package/node_modules/@jridgewell/trace-mapping/src/resolve.ts +0 -10
  139. package/node_modules/@jridgewell/trace-mapping/src/sort.ts +0 -45
  140. package/node_modules/@jridgewell/trace-mapping/src/sourcemap-segment.ts +0 -23
  141. package/node_modules/@jridgewell/trace-mapping/src/strip-filename.ts +0 -8
  142. package/node_modules/@jridgewell/trace-mapping/src/trace-mapping.ts +0 -405
  143. package/node_modules/@jridgewell/trace-mapping/src/types.ts +0 -90
  144. package/node_modules/generate-password/.eslintrc.yml +0 -18
  145. package/node_modules/generate-password/.github/workflows/nodejs.yml +0 -33
  146. package/node_modules/generate-password/CHANGELOG.md +0 -79
  147. package/node_modules/generate-password/LICENSE +0 -21
  148. package/node_modules/generate-password/README.md +0 -61
  149. package/node_modules/generate-password/example.js +0 -28
  150. package/node_modules/generate-password/main.js +0 -1
  151. package/node_modules/generate-password/package.json +0 -68
  152. package/node_modules/generate-password/src/generate.d.ts +0 -51
  153. package/node_modules/generate-password/src/generate.js +0 -152
  154. package/node_modules/generate-password/test/coverage.sh +0 -17
  155. package/node_modules/generate-password/test/esm.mjs +0 -13
  156. package/node_modules/generate-password/test/generator.js +0 -164
  157. package/src/clients/TrialAccount.js +0 -76
  158. package/src/commands/agent/index.js +0 -27
  159. package/src/commands/signup.js +0 -104
  160. package/test.sh +0 -2
  161. /package/src/commands/{agent → instances}/apps/install.js +0 -0
  162. /package/src/commands/{agent → instances}/ready.js +0 -0
@@ -1,13 +1,11 @@
1
1
  module.exports = [
2
2
  require('./login'),
3
3
  require('./logout'),
4
- require('./signup'),
5
4
  require('./extensions'),
6
5
  require('./instances'),
7
6
  require('./firmware'),
8
7
  require('./images'),
9
8
  require('./projects'),
10
- require('./agent'),
11
9
  require('./webplayer'),
12
10
  require('./mast')
13
11
  ]
@@ -21,16 +21,16 @@ async function builder (yargs) {
21
21
  demandOption: true,
22
22
  string: true,
23
23
  validateNonEmpty
24
- }).option('loadIcons', {
24
+ }).option('load-icons', {
25
25
  type: 'input',
26
26
  describe: 'Toggle loading of icons',
27
27
  demandOption: false,
28
28
  boolean: true
29
29
  }).option('format', {
30
30
  type: 'input',
31
- describe: 'Output format (default is table) e.g. json',
31
+ describe: 'Output format (default is json) e.g. table',
32
32
  string: true,
33
- choices: ['json', 'csv']
33
+ choices: ['table', 'json', 'csv']
34
34
  }).command(InstallCommand)
35
35
  }
36
36
 
@@ -1,5 +1,9 @@
1
1
  const { handleError } = require('../../error')
2
- const { getApi, waitForState } = require('../../utils')
2
+ const {
3
+ getApi, waitForState,
4
+ waitForAgentReady
5
+ } = require('../../utils')
6
+ const AgentCLI = require('../../clients/Agent')
3
7
 
4
8
  async function builder (yargs) {
5
9
  yargs
@@ -10,9 +14,9 @@ async function builder (yargs) {
10
14
  })
11
15
  .option('format', {
12
16
  type: 'input',
13
- describe: 'Output format (default is table) e.g. json',
17
+ describe: 'Output format (default is json) e.g. table',
14
18
  string: true,
15
- choices: ['json', 'csv']
19
+ choices: ['table', 'json', 'csv']
16
20
  })
17
21
  .positional('flavor', {
18
22
  type: 'string',
@@ -53,6 +57,8 @@ async function handler (argv) {
53
57
  // Wait 360 attempts for the instance to be created (30 minutes)
54
58
  if (argv.wait) {
55
59
  await waitForState(instance.id, api.v1GetInstance.bind(api), 'on', 360)
60
+ const agent = new AgentCLI({ instance: instance.id })
61
+ await waitForAgentReady(agent, 360)
56
62
  }
57
63
  console.log(instance.id)
58
64
  } catch (err) {
@@ -22,9 +22,9 @@ async function builder (yargs) {
22
22
  validateNonEmpty
23
23
  }).option('format', {
24
24
  type: 'input',
25
- describe: 'Output format (default is table) e.g. json',
25
+ describe: 'Output format (default is json) e.g. table',
26
26
  string: true,
27
- choices: ['json', 'csv']
27
+ choices: ['table', 'json', 'csv']
28
28
  })
29
29
  }
30
30
 
@@ -6,7 +6,11 @@ const subcommands = [
6
6
  require('./start'),
7
7
  require('./upgrade'),
8
8
  require('./netmon'),
9
- require('./restoreBackup')
9
+ require('./restoreBackup'),
10
+ require('./ready'),
11
+ require('./file'),
12
+ require('./apps'),
13
+ require('./input')
10
14
  ]
11
15
 
12
16
  let _yargs
@@ -17,3 +21,4 @@ module.exports = {
17
21
  command: 'instance',
18
22
  describe: 'Instance related commands'
19
23
  }
24
+ module.exports.subcommands = subcommands
@@ -0,0 +1,52 @@
1
+
2
+ const { readFile } = require('node:fs/promises')
3
+ const InstanceCLI = require('../../clients/Instance')
4
+ const { handleError } = require('../../error')
5
+ const chalk = require('chalk')
6
+
7
+ /**
8
+ * Upload input to a device.
9
+ *
10
+ * @param yargs
11
+ * @returns {Promise<void>}
12
+ */
13
+ async function builder (yargs) {
14
+ yargs
15
+ .positional('instance', {
16
+ type: 'string',
17
+ demandOption: true,
18
+ describe: 'virtual device id',
19
+ default: process.env.INSTANCE
20
+ })
21
+ .positional('file', {
22
+ type: 'string',
23
+ demandOption: true,
24
+ describe: 'JSON file of device inputs'
25
+ // Input specification https://app.corellium.com/api/docs#post-/v1/instances/-instanceId-/input
26
+ })
27
+ .option('verbose', {
28
+ alias: 'v',
29
+ type: 'boolean',
30
+ describe: 'console will receive verbose error output',
31
+ default: false
32
+ })
33
+ }
34
+
35
+ async function handler (argv) {
36
+ const { file, verbose } = argv
37
+ const client = new InstanceCLI(argv)
38
+ try {
39
+ const json = JSON.parse((await readFile(file)).toString())
40
+ await client.input(json)
41
+ console.log(chalk.green('Successfully uploaded inputs'))
42
+ } catch (error) {
43
+ handleError(error, 'input failed', verbose)
44
+ }
45
+ }
46
+
47
+ module.exports = {
48
+ builder,
49
+ handler,
50
+ command: 'input <instance> <file>',
51
+ describe: 'Upload a series of inputs to a device.'
52
+ }
@@ -12,9 +12,9 @@ async function builder (yargs) {
12
12
  describe: 'Optionally filter by project name'
13
13
  }).option('format', {
14
14
  type: 'input',
15
- describe: 'Output format (default is table) e.g. json',
15
+ describe: 'Output format (default is json) e.g. table',
16
16
  string: true,
17
- choices: ['json', 'csv']
17
+ choices: ['table', 'json', 'csv']
18
18
  })
19
19
  }
20
20
 
@@ -42,5 +42,6 @@ module.exports = {
42
42
  builder,
43
43
  handler,
44
44
  command: 'list',
45
+ aliases: ['ls'],
45
46
  describe: 'List instances'
46
47
  }
@@ -30,9 +30,9 @@ async function builder (yargs) {
30
30
  })
31
31
  .option('format', {
32
32
  type: 'input',
33
- describe: 'Output format (default is table) e.g. json',
33
+ describe: 'Output format (default is json) e.g. table',
34
34
  string: true,
35
- choices: ['json', 'csv'],
35
+ choices: ['table', 'json', 'csv'],
36
36
  demandOption: false
37
37
  })
38
38
  .option('wait', {
@@ -11,9 +11,9 @@ async function builder (yargs) {
11
11
  })
12
12
  .option('format', {
13
13
  type: 'input',
14
- describe: 'Output format (default is table) e.g. json',
14
+ describe: 'Output format (default is json) e.g. table',
15
15
  string: true,
16
- choices: ['json', 'csv']
16
+ choices: ['table', 'json', 'csv']
17
17
  })
18
18
  .positional('name', {
19
19
  type: 'input',
@@ -44,6 +44,7 @@ async function handler (argv) {
44
44
  module.exports = {
45
45
  builder,
46
46
  handler,
47
- command: 'delete [projectId]',
47
+ command: 'delete <projectId>',
48
+ aliases: ['rm', 'del'],
48
49
  describe: 'Delete project by id'
49
50
  }
@@ -9,9 +9,9 @@ async function builder (yargs) {
9
9
  describe: 'Console will receive verbose error output'
10
10
  }).option('format', {
11
11
  type: 'input',
12
- describe: 'Output format (default is table) e.g. json',
12
+ describe: 'Output format (default is json) e.g. table',
13
13
  string: true,
14
- choices: ['json', 'csv']
14
+ choices: ['table', 'json', 'csv']
15
15
  })
16
16
  }
17
17
 
@@ -29,5 +29,6 @@ module.exports = {
29
29
  builder,
30
30
  handler,
31
31
  command: 'list',
32
+ aliases: ['ls'],
32
33
  describe: 'List projects'
33
34
  }
@@ -40,9 +40,9 @@ async function builder (yargs) {
40
40
  validateNonEmpty
41
41
  }).option('format', {
42
42
  type: 'input',
43
- describe: 'Output format (default is json)',
43
+ describe: 'Output format (default is json) e.g. table',
44
44
  string: true,
45
- choices: ['json', 'csv']
45
+ choices: ['table', 'json', 'csv']
46
46
  })
47
47
  }
48
48
 
@@ -21,9 +21,9 @@ async function builder (yargs) {
21
21
  string: true
22
22
  }).option('format', {
23
23
  type: 'input',
24
- describe: 'Output format (default is table) e.g. json',
24
+ describe: 'Output format (default is json) e.g. table',
25
25
  string: true,
26
- choices: ['json', 'csv']
26
+ choices: ['table', 'json', 'csv']
27
27
  })
28
28
  }
29
29
 
package/src/error.js CHANGED
@@ -12,18 +12,24 @@ function getUserErrorMessage (body) {
12
12
  }
13
13
  return ''
14
14
  }
15
+
15
16
  function getErrorMessage (error) {
16
- return (error.body && error.body.error)
17
- ? `${error.body.error} ${getUserErrorMessage(error.body)}`
18
- : (error.error && error.error.message)
19
- ? error.error.message
20
- : error
17
+ const { body, response, error: errorObject } = error
18
+ if (body && body.error) {
19
+ return `${body.error} ${getUserErrorMessage(body)}`
20
+ } else if (response && response.data && response.data.error) {
21
+ return `${response.data.error} ${getUserErrorMessage(response.data)}`
22
+ } else if (errorObject && errorObject.message) {
23
+ return errorObject.message
24
+ } else {
25
+ return error.message
26
+ }
21
27
  }
22
28
 
23
29
  function handleError (error, customMessage, detailed) {
24
30
  const errorMessage = getErrorMessage(error)
25
31
  console.error(`${customMessage}: ${errorMessage}`)
26
- if (detailed) { log.error(error) }
32
+ if (detailed) { log.error(JSON.stringify(error.body || error.response?.data || error.message, null, 2)) }
27
33
  process.exit(1)
28
34
  }
29
35
 
package/src/table.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { table } = require('table')
2
2
  const log = require('./logging')
3
3
 
4
- async function displayTable (format, data, filteredFields, columnWidths) {
4
+ async function displayTable (format = 'json', data, filteredFields, columnWidths) {
5
5
  if (format === 'json') {
6
6
  const displayJson = JSON.stringify(data, null, 2)
7
7
  log.plain(displayJson)
package/src/utils.js CHANGED
@@ -1,4 +1,3 @@
1
- const generator = require('generate-password')
2
1
  const CorelliumClient = require('@corellium/client-api')
3
2
  const {
4
3
  readProfile,
@@ -11,43 +10,6 @@ const https = require('https')
11
10
 
12
11
  const waitForIntervalMilliSec = 5000
13
12
 
14
- const planOptions = (planId) => {
15
- let usageBased = false
16
- let cores, licenseType
17
- let m = /^(individual)-cloud-(\d+)-device(?:-(\d+)-month){0,1}$/.exec(planId)
18
- if (m) {
19
- licenseType = m[1]
20
- const devicesStr = m[2]
21
- cores = parseInt(devicesStr) * 2
22
- } else if (m = /^(enterprise|standard)-cloud-(\d+)-core(?:-(\d+)-month){0,1}$/.exec(planId)) { /* eslint-disable-line no-cond-assign */
23
- licenseType = m[1]
24
- const coresStr = m[2]
25
- cores = parseInt(coresStr)
26
- } else if (m = /^(enterprise|individual)-cloud-usage-based$/.exec(planId)) { /* eslint-disable-line no-cond-assign */
27
- usageBased = true
28
- if (m[1] === 'enterprise') {
29
- licenseType = 'enterprise-usage'
30
- cores = 200
31
- } else if (m[1] === 'individual') {
32
- licenseType = 'individual-usage'
33
- cores = 100
34
- }
35
- }
36
- return {
37
- licenseType: /** @type {LicenseType} */ (licenseType),
38
- cores,
39
- usageBased
40
- }
41
- }
42
-
43
- const makePassword = () => {
44
- return generator.generate({
45
- length: 15,
46
- numbers: true,
47
- excludeSimilarCharacters: true
48
- })
49
- }
50
-
51
13
  const sleep = (milliseconds) => {
52
14
  return new Promise((resolve) => setTimeout(resolve, milliseconds))
53
15
  }
@@ -63,6 +25,24 @@ const waitForState = async (instanceId, fn, state, attempts = 20, reporterFn = n
63
25
  }
64
26
  }
65
27
 
28
+ const waitForAgentReady = async (agent, attempts = 20) => {
29
+ while (attempts > 0) {
30
+ try {
31
+ const status = await agent.ready()
32
+ if (status.ready) {
33
+ return // Agent is ready, exit the function
34
+ }
35
+ } catch (error) {
36
+ // We don't need to log any errors
37
+ }
38
+ // Wait before retrying
39
+ await sleep(waitForIntervalMilliSec)
40
+ attempts--
41
+ }
42
+ // If max attempts reached and agent is still not ready, throw an error
43
+ throw new Error('Agent did not become ready within the specified number of attempts.')
44
+ }
45
+
66
46
  const waitForTaskState = async (instanceId, fn, taskState, attempts = 20) => {
67
47
  let response = await fn(instanceId)
68
48
 
@@ -162,10 +142,9 @@ async function reRequestInsecure (endpoint) {
162
142
  const validateNonEmpty = (input) => input !== ''
163
143
 
164
144
  module.exports = {
165
- planOptions,
166
- makePassword,
167
145
  waitForState,
168
146
  waitForTaskState,
147
+ waitForAgentReady,
169
148
  getApi,
170
149
  getAxios,
171
150
  validateNonEmpty,
@@ -1,166 +0,0 @@
1
- import { TraceMap, presortedDecodedMap, decodedMappings } from './trace-mapping';
2
- import {
3
- COLUMN,
4
- SOURCES_INDEX,
5
- SOURCE_LINE,
6
- SOURCE_COLUMN,
7
- NAMES_INDEX,
8
- } from './sourcemap-segment';
9
-
10
- import type {
11
- Section,
12
- SectionedSourceMap,
13
- DecodedSourceMap,
14
- SectionedSourceMapInput,
15
- } from './types';
16
- import type { SourceMapSegment } from './sourcemap-segment';
17
-
18
- type AnyMap = {
19
- new (map: SectionedSourceMapInput, mapUrl?: string | null): TraceMap;
20
- (map: SectionedSourceMapInput, mapUrl?: string | null): TraceMap;
21
- };
22
-
23
- export const AnyMap: AnyMap = function (map, mapUrl) {
24
- const parsed =
25
- typeof map === 'string' ? (JSON.parse(map) as Exclude<SectionedSourceMapInput, string>) : map;
26
-
27
- if (!('sections' in parsed)) return new TraceMap(parsed, mapUrl);
28
-
29
- const mappings: SourceMapSegment[][] = [];
30
- const sources: string[] = [];
31
- const sourcesContent: (string | null)[] = [];
32
- const names: string[] = [];
33
-
34
- recurse(parsed, mapUrl, mappings, sources, sourcesContent, names, 0, 0, Infinity, Infinity);
35
-
36
- const joined: DecodedSourceMap = {
37
- version: 3,
38
- file: parsed.file,
39
- names,
40
- sources,
41
- sourcesContent,
42
- mappings,
43
- };
44
-
45
- return presortedDecodedMap(joined);
46
- } as AnyMap;
47
-
48
- function recurse(
49
- input: SectionedSourceMap,
50
- mapUrl: string | null | undefined,
51
- mappings: SourceMapSegment[][],
52
- sources: string[],
53
- sourcesContent: (string | null)[],
54
- names: string[],
55
- lineOffset: number,
56
- columnOffset: number,
57
- stopLine: number,
58
- stopColumn: number,
59
- ) {
60
- const { sections } = input;
61
- for (let i = 0; i < sections.length; i++) {
62
- const { map, offset } = sections[i];
63
-
64
- let sl = stopLine;
65
- let sc = stopColumn;
66
- if (i + 1 < sections.length) {
67
- const nextOffset = sections[i + 1].offset;
68
- sl = Math.min(stopLine, lineOffset + nextOffset.line);
69
-
70
- if (sl === stopLine) {
71
- sc = Math.min(stopColumn, columnOffset + nextOffset.column);
72
- } else if (sl < stopLine) {
73
- sc = columnOffset + nextOffset.column;
74
- }
75
- }
76
-
77
- addSection(
78
- map,
79
- mapUrl,
80
- mappings,
81
- sources,
82
- sourcesContent,
83
- names,
84
- lineOffset + offset.line,
85
- columnOffset + offset.column,
86
- sl,
87
- sc,
88
- );
89
- }
90
- }
91
-
92
- function addSection(
93
- input: Section['map'],
94
- mapUrl: string | null | undefined,
95
- mappings: SourceMapSegment[][],
96
- sources: string[],
97
- sourcesContent: (string | null)[],
98
- names: string[],
99
- lineOffset: number,
100
- columnOffset: number,
101
- stopLine: number,
102
- stopColumn: number,
103
- ) {
104
- if ('sections' in input) return recurse(...(arguments as unknown as Parameters<typeof recurse>));
105
-
106
- const map = new TraceMap(input, mapUrl);
107
- const sourcesOffset = sources.length;
108
- const namesOffset = names.length;
109
- const decoded = decodedMappings(map);
110
- const { resolvedSources, sourcesContent: contents } = map;
111
-
112
- append(sources, resolvedSources);
113
- append(names, map.names);
114
- if (contents) append(sourcesContent, contents);
115
- else for (let i = 0; i < resolvedSources.length; i++) sourcesContent.push(null);
116
-
117
- for (let i = 0; i < decoded.length; i++) {
118
- const lineI = lineOffset + i;
119
-
120
- // We can only add so many lines before we step into the range that the next section's map
121
- // controls. When we get to the last line, then we'll start checking the segments to see if
122
- // they've crossed into the column range. But it may not have any columns that overstep, so we
123
- // still need to check that we don't overstep lines, too.
124
- if (lineI > stopLine) return;
125
-
126
- // The out line may already exist in mappings (if we're continuing the line started by a
127
- // previous section). Or, we may have jumped ahead several lines to start this section.
128
- const out = getLine(mappings, lineI);
129
- // On the 0th loop, the section's column offset shifts us forward. On all other lines (since the
130
- // map can be multiple lines), it doesn't.
131
- const cOffset = i === 0 ? columnOffset : 0;
132
-
133
- const line = decoded[i];
134
- for (let j = 0; j < line.length; j++) {
135
- const seg = line[j];
136
- const column = cOffset + seg[COLUMN];
137
-
138
- // If this segment steps into the column range that the next section's map controls, we need
139
- // to stop early.
140
- if (lineI === stopLine && column >= stopColumn) return;
141
-
142
- if (seg.length === 1) {
143
- out.push([column]);
144
- continue;
145
- }
146
-
147
- const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX];
148
- const sourceLine = seg[SOURCE_LINE];
149
- const sourceColumn = seg[SOURCE_COLUMN];
150
- out.push(
151
- seg.length === 4
152
- ? [column, sourcesIndex, sourceLine, sourceColumn]
153
- : [column, sourcesIndex, sourceLine, sourceColumn, namesOffset + seg[NAMES_INDEX]],
154
- );
155
- }
156
- }
157
- }
158
-
159
- function append<T>(arr: T[], other: T[]) {
160
- for (let i = 0; i < other.length; i++) arr.push(other[i]);
161
- }
162
-
163
- function getLine<T>(arr: T[][], index: number): T[] {
164
- for (let i = arr.length; i <= index; i++) arr[i] = [];
165
- return arr[index];
166
- }
@@ -1,115 +0,0 @@
1
- import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment';
2
- import { COLUMN } from './sourcemap-segment';
3
-
4
- export type MemoState = {
5
- lastKey: number;
6
- lastNeedle: number;
7
- lastIndex: number;
8
- };
9
-
10
- export let found = false;
11
-
12
- /**
13
- * A binary search implementation that returns the index if a match is found.
14
- * If no match is found, then the left-index (the index associated with the item that comes just
15
- * before the desired index) is returned. To maintain proper sort order, a splice would happen at
16
- * the next index:
17
- *
18
- * ```js
19
- * const array = [1, 3];
20
- * const needle = 2;
21
- * const index = binarySearch(array, needle, (item, needle) => item - needle);
22
- *
23
- * assert.equal(index, 0);
24
- * array.splice(index + 1, 0, needle);
25
- * assert.deepEqual(array, [1, 2, 3]);
26
- * ```
27
- */
28
- export function binarySearch(
29
- haystack: SourceMapSegment[] | ReverseSegment[],
30
- needle: number,
31
- low: number,
32
- high: number,
33
- ): number {
34
- while (low <= high) {
35
- const mid = low + ((high - low) >> 1);
36
- const cmp = haystack[mid][COLUMN] - needle;
37
-
38
- if (cmp === 0) {
39
- found = true;
40
- return mid;
41
- }
42
-
43
- if (cmp < 0) {
44
- low = mid + 1;
45
- } else {
46
- high = mid - 1;
47
- }
48
- }
49
-
50
- found = false;
51
- return low - 1;
52
- }
53
-
54
- export function upperBound(
55
- haystack: SourceMapSegment[] | ReverseSegment[],
56
- needle: number,
57
- index: number,
58
- ): number {
59
- for (let i = index + 1; i < haystack.length; index = i++) {
60
- if (haystack[i][COLUMN] !== needle) break;
61
- }
62
- return index;
63
- }
64
-
65
- export function lowerBound(
66
- haystack: SourceMapSegment[] | ReverseSegment[],
67
- needle: number,
68
- index: number,
69
- ): number {
70
- for (let i = index - 1; i >= 0; index = i--) {
71
- if (haystack[i][COLUMN] !== needle) break;
72
- }
73
- return index;
74
- }
75
-
76
- export function memoizedState(): MemoState {
77
- return {
78
- lastKey: -1,
79
- lastNeedle: -1,
80
- lastIndex: -1,
81
- };
82
- }
83
-
84
- /**
85
- * This overly complicated beast is just to record the last tested line/column and the resulting
86
- * index, allowing us to skip a few tests if mappings are monotonically increasing.
87
- */
88
- export function memoizedBinarySearch(
89
- haystack: SourceMapSegment[] | ReverseSegment[],
90
- needle: number,
91
- state: MemoState,
92
- key: number,
93
- ): number {
94
- const { lastKey, lastNeedle, lastIndex } = state;
95
-
96
- let low = 0;
97
- let high = haystack.length - 1;
98
- if (key === lastKey) {
99
- if (needle === lastNeedle) {
100
- found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
101
- return lastIndex;
102
- }
103
-
104
- if (needle >= lastNeedle) {
105
- // lastIndex may be -1 if the previous needle was not found.
106
- low = lastIndex === -1 ? 0 : lastIndex;
107
- } else {
108
- high = lastIndex;
109
- }
110
- }
111
- state.lastKey = key;
112
- state.lastNeedle = needle;
113
-
114
- return (state.lastIndex = binarySearch(haystack, needle, low, high));
115
- }