adapt-cli 3.0.6 → 3.0.8

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/api.js CHANGED
@@ -19,6 +19,7 @@ import Plugin from './integration/Plugin.js'
19
19
  import Project from './integration/Project.js'
20
20
  import fs from 'fs-extra'
21
21
  import async from 'async'
22
+ import './econnreset.js'
22
23
 
23
24
  // TODO: api, check no interactivity, should be sorted, will fail silently if it absolutely cannot do what you've asked
24
25
  // TODO: api, console and error output, error on fail when isInteractive: false? or something else? return Targets?
@@ -36,17 +37,20 @@ class API {
36
37
  async installFramework ({
37
38
  version = null,
38
39
  repository = ADAPT_FRAMEWORK,
39
- cwd = process.cwd()
40
+ cwd = process.cwd(),
41
+ logger
40
42
  } = {}) {
41
43
  if (!version) version = await getLatestVersion({ repository })
42
44
  await erase({
43
45
  isInteractive: false,
44
- cwd
46
+ cwd,
47
+ logger
45
48
  })
46
49
  await download({
47
50
  repository,
48
51
  branch: version,
49
- cwd
52
+ cwd,
53
+ logger
50
54
  })
51
55
  await deleteSrcCourse({
52
56
  cwd
@@ -55,7 +59,8 @@ class API {
55
59
  cwd
56
60
  })
57
61
  await npmInstall({
58
- cwd
62
+ cwd,
63
+ logger
59
64
  })
60
65
  }
61
66
 
@@ -87,7 +92,8 @@ class API {
87
92
  cache = true,
88
93
  outputDir = null,
89
94
  cachePath = './build/.cache',
90
- cwd = process.cwd()
95
+ cwd = process.cwd(),
96
+ logger
91
97
  } = {}) {
92
98
  await build({
93
99
  sourceMaps,
@@ -95,7 +101,8 @@ class API {
95
101
  cache,
96
102
  cwd,
97
103
  outputDir,
98
- cachePath
104
+ cachePath,
105
+ logger
99
106
  })
100
107
  }
101
108
 
@@ -109,12 +116,14 @@ class API {
109
116
  */
110
117
  async installPlugins ({
111
118
  plugins = null,
112
- cwd = process.cwd()
119
+ cwd = process.cwd(),
120
+ logger
113
121
  } = {}) {
114
122
  return await install({
115
123
  plugins,
116
124
  isInteractive: false,
117
- cwd
125
+ cwd,
126
+ logger
118
127
  })
119
128
  }
120
129
 
@@ -127,12 +136,14 @@ class API {
127
136
  */
128
137
  async uninstallPlugins ({
129
138
  plugins = null,
130
- cwd = process.cwd()
139
+ cwd = process.cwd(),
140
+ logger
131
141
  } = {}) {
132
142
  return await uninstall({
133
143
  plugins,
134
144
  isInteractive: false,
135
- cwd
145
+ cwd,
146
+ logger
136
147
  })
137
148
  }
138
149
 
@@ -146,12 +157,14 @@ class API {
146
157
  */
147
158
  async updatePlugins ({
148
159
  plugins = null,
149
- cwd = process.cwd()
160
+ cwd = process.cwd(),
161
+ logger
150
162
  } = {}) {
151
163
  return await update({
152
164
  plugins,
153
165
  isInteractive: false,
154
- cwd
166
+ cwd,
167
+ logger
155
168
  })
156
169
  }
157
170
 
package/lib/cli.js CHANGED
@@ -12,6 +12,7 @@ import unregister from './commands/unregister.js'
12
12
  import update from './commands/update.js'
13
13
  import version from './commands/version.js'
14
14
  import logger from './logger.js'
15
+ import './econnreset.js'
15
16
 
16
17
  const commands = {
17
18
  authenticate,
@@ -1,9 +1,35 @@
1
1
  import chalk from 'chalk'
2
+ import _ from 'lodash'
2
3
  import Project from '../integration/Project.js'
4
+ import { eachOfLimitProgress } from '../util/promises.js'
3
5
 
4
6
  export default async function ls (logger) {
5
7
  const project = new Project({ logger })
8
+ const frameworkVersion = project.version
6
9
  project.tryThrowInvalidPath()
7
- const installTargets = await project.getInstallTargets()
8
- installTargets.forEach(p => logger?.log(`${chalk.cyan(p.name || p.sourcePath)} ${p.sourcePath || p.requestedVersion}`))
10
+ const installTargets = (await project.getInstallTargets())
11
+ const installTargetsIndex = installTargets.reduce((hash, p) => {
12
+ const name = (p.name || p.sourcePath)
13
+ hash[name] = p
14
+ return hash
15
+ }, {})
16
+ const installedPlugins = await project.getInstalledPlugins();
17
+ const notInstalled = _.difference(installTargets.map(p => (p.name || p.sourcePath)), installedPlugins.map(p => (p.name || p.sourcePath)))
18
+ const plugins = installedPlugins.concat(notInstalled.map(name => installTargetsIndex[name]))
19
+ await eachOfLimitProgress(
20
+ plugins,
21
+ async (target) => {
22
+ await target.fetchProjectInfo()
23
+ await target.fetchSourceInfo()
24
+ await target.findCompatibleVersion(frameworkVersion)
25
+ },
26
+ percentage => logger?.logProgress?.(`${chalk.bold.cyan('<info>')} Getting plugin info ${percentage}% complete`)
27
+ )
28
+ logger?.log(`${chalk.bold.cyan('<info>')} Getting plugin info 100% complete`)
29
+ plugins
30
+ .sort((a, b) => a.name.localeCompare(b.name))
31
+ .forEach(p => {
32
+ const name = (p.name || p.sourcePath)
33
+ logger?.log(`${chalk.cyan(p.name || p.sourcePath)} ${chalk.green('adapt.json')}: ${installTargetsIndex[name]?.requestedVersion || 'n/a'} ${chalk.green('installed')}: ${p.sourcePath || p.projectVersion || 'n/a'} ${chalk.green('latest')}: ${p.sourcePath || p.latestCompatibleSourceVersion || 'n/a'}`)
34
+ })
9
35
  }
@@ -0,0 +1,7 @@
1
+ // guard against ECONNRESET issues https://github.com/adaptlearning/adapt-cli/issues/169
2
+ process.on('uncaughtException', (error, origin) => {
3
+ if (error?.code === 'ECONNRESET') return
4
+ console.error('UNCAUGHT EXCEPTION')
5
+ console.error(error)
6
+ console.error(origin)
7
+ })
@@ -1,4 +1,4 @@
1
- import request from 'request'
1
+ import fetch from 'node-fetch'
2
2
  import semver from 'semver'
3
3
  import gh from 'parse-github-url'
4
4
  import { ADAPT_DEFAULT_USER_AGENT, ADAPT_FRAMEWORK, ADAPT_ALLOW_PRERELEASE } from '../../util/constants.js'
@@ -29,24 +29,19 @@ export default async function getLatestVersion ({ versionLimit, repository = ADA
29
29
  return links
30
30
  }
31
31
  const processPage = async () => {
32
- const [response, body] = await new Promise((resolve, reject) => {
33
- request({
34
- headers: {
35
- 'User-Agent': ADAPT_DEFAULT_USER_AGENT
36
- },
37
- uri: nextPage,
38
- method: 'GET'
39
- }, (error, response, body) => {
40
- if (error) return reject(error)
41
- resolve([response, body])
42
- })
32
+ const response = await fetch(nextPage, {
33
+ headers: {
34
+ 'User-Agent': ADAPT_DEFAULT_USER_AGENT
35
+ },
36
+ method: 'GET'
43
37
  })
44
- if (response?.statusCode === 403 && response?.headers['x-ratelimit-remaining'] === '0') {
38
+ const body = await response.text()
39
+ if (response?.status === 403 && response?.headers['x-ratelimit-remaining'] === '0') {
45
40
  // we've exceeded the API limit
46
41
  const reqsReset = new Date(response.headers['x-ratelimit-reset'] * 1000)
47
42
  throw new Error(`Couldn't check latest version of ${NAME}. You have exceeded GitHub's request limit of ${response.headers['x-ratelimit-limit']} requests per hour. Please wait until at least ${reqsReset.toTimeString()} before trying again.`)
48
43
  }
49
- if (response?.statusCode !== 200) {
44
+ if (response?.status !== 200) {
50
45
  throw new Error(`Couldn't check latest version of ${NAME}. GitubAPI did not respond with a 200 status code.`)
51
46
  }
52
47
  nextPage = parseLinkHeader(response.headers.link).next
@@ -1,6 +1,6 @@
1
1
  import chalk from 'chalk'
2
2
  import inquirer from 'inquirer'
3
- import request from 'request'
3
+ import fetch from 'node-fetch'
4
4
  import getBowerRegistryConfig from '../getBowerRegistryConfig.js'
5
5
  import path from 'path'
6
6
 
@@ -36,21 +36,12 @@ export default async function authenticate ({
36
36
  ({ pluginName } = confirmation)
37
37
  }
38
38
  const { username, token } = confirmation
39
- return new Promise((resolve, reject) => {
40
- request({
41
- uri: `${BOWER_REGISTRY_CONFIG.register}authenticate/${username}/${pluginName}?access_token=${token}`,
42
- method: 'GET',
43
- headers: { 'User-Agent': 'adapt-cli' },
44
- followRedirect: false
45
- }, (err, res, body) => {
46
- if (err) return reject(err)
47
- if (res.statusCode !== 200) reject(new Error(`The server responded with ${res.statusCode}`))
48
- try {
49
- const bodyJSON = JSON.parse(body)
50
- resolve({ username, token, pluginName, ...bodyJSON })
51
- } catch (err) {
52
- reject(err)
53
- }
54
- })
39
+ const response = await fetch(`${BOWER_REGISTRY_CONFIG.register}authenticate/${username}/${pluginName}?access_token=${token}`, {
40
+ headers: { 'User-Agent': 'adapt-cli' },
41
+ followRedirect: false,
42
+ method: 'GET'
55
43
  })
44
+ if (response.status !== 200) throw new Error(`The server responded with ${response.status}`)
45
+ const body = await response.json()
46
+ return { username, token, pluginName, ...body }
56
47
  }
@@ -131,7 +131,7 @@ async function conflictResolution ({ logger, targets, isInteractive, dev }) {
131
131
  ? { name: `latest compatible version [${target.latestCompatibleSourceVersion}]`, value: 'l' }
132
132
  : target.latestSourceVersion
133
133
  ? { name: `latest version [${target.latestSourceVersion}]`, value: 'l' }
134
- : { name: `master [master]`, value: 'm' },
134
+ : { name: 'master [master]', value: 'm' },
135
135
  { name: 'skip', value: 's' }
136
136
  ].filter(Boolean)
137
137
  const result = await createPromptTask({ message: chalk.reset(target.packageName), choices, type: 'list', default: 's' })
@@ -3,7 +3,7 @@ import authenticate from './autenticate.js'
3
3
  import bower from 'bower'
4
4
  import chalk from 'chalk'
5
5
  import inquirer from 'inquirer'
6
- import request from 'request'
6
+ import fetch from 'node-fetch'
7
7
  import path from 'path'
8
8
  import Plugin from '../Plugin.js'
9
9
 
@@ -68,18 +68,12 @@ async function renameInBowerRepo ({
68
68
  }) {
69
69
  const path = 'packages/rename/' + username + '/' + oldName + '/' + newName
70
70
  const query = '?access_token=' + token
71
- return new Promise((resolve, reject) => {
72
- request({
73
- url: BOWER_REGISTRY_CONFIG.register + path + query,
74
- method: 'GET',
75
- headers: { 'User-Agent': 'adapt-cli' },
76
- followRedirect: false
77
- }, (err, res) => {
78
- if (err) return reject(err)
79
- if (res.statusCode !== 201) reject(new Error(`The server responded with ${res.statusCode}`))
80
- resolve()
81
- })
71
+ const response = await fetch(BOWER_REGISTRY_CONFIG.register + path + query, {
72
+ method: 'GET',
73
+ headers: { 'User-Agent': 'adapt-cli' },
74
+ followRedirect: false
82
75
  })
76
+ if (response.status !== 201) throw new Error(`The server responded with ${response.status}`)
83
77
  }
84
78
 
85
79
  /**
@@ -1,6 +1,6 @@
1
1
  import getBowerRegistryConfig from '../getBowerRegistryConfig.js'
2
2
  import chalk from 'chalk'
3
- import request from 'request'
3
+ import fetch from 'node-fetch'
4
4
  import path from 'path'
5
5
 
6
6
  export default async function search ({
@@ -14,22 +14,13 @@ export default async function search ({
14
14
  const uniqueResults = {}
15
15
  for (const serverURI of BOWER_REGISTRY_CONFIG.search) {
16
16
  try {
17
- const immediateResults = await new Promise((resolve, reject) => {
18
- request({
19
- uri: `${serverURI}packages/search/${searchTerm}`,
20
- method: 'GET',
21
- headers: { 'User-Agent': 'adapt-cli' },
22
- followRedirect: false
23
- }, (err, res, body) => {
24
- if (err) return reject(err)
25
- if (res.statusCode !== 200) reject(new Error(`The server responded with ${res.statusCode}`))
26
- try {
27
- resolve(JSON.parse(body))
28
- } catch (err) {
29
- reject(err)
30
- }
31
- })
17
+ const response = await fetch(`${serverURI}packages/search/${searchTerm}`, {
18
+ method: 'GET',
19
+ headers: { 'User-Agent': 'adapt-cli' },
20
+ followRedirect: false
32
21
  })
22
+ if (response.status !== 200) throw new Error(`The server responded with ${response.status}`)
23
+ const immediateResults = await response.json()
33
24
  immediateResults?.forEach(result => (uniqueResults[result.name] = uniqueResults[result.name] ?? result))
34
25
  } catch (err) {}
35
26
  }
@@ -6,7 +6,7 @@ import chalk from 'chalk'
6
6
  import inquirer from 'inquirer'
7
7
  import { readValidateJSON } from '../../util/JSONReadValidate.js'
8
8
  import Plugin from '../Plugin.js'
9
- import request from 'request'
9
+ import fetch from 'node-fetch'
10
10
 
11
11
  export default async function unregister ({
12
12
  logger,
@@ -82,20 +82,10 @@ async function unregisterInBowerRepo ({
82
82
  BOWER_REGISTRY_CONFIG
83
83
  }) {
84
84
  const uri = `${BOWER_REGISTRY_CONFIG.register}packages/${username}/${pluginName}?access_token=${token}`
85
- return new Promise((resolve, reject) => {
86
- request({
87
- uri,
88
- method: 'DELETE',
89
- headers: { 'User-Agent': 'adapt-cli' },
90
- followRedirect: false
91
- }, (err, res, body) => {
92
- if (err) return reject(err)
93
- if (res.statusCode !== 204) reject(new Error(`The server responded with ${res.statusCode}`))
94
- try {
95
- resolve()
96
- } catch (err) {
97
- reject(err)
98
- }
99
- })
85
+ const response = await fetch(uri, {
86
+ method: 'DELETE',
87
+ headers: { 'User-Agent': 'adapt-cli' },
88
+ followRedirect: false
100
89
  })
90
+ if (response.status !== 204) throw new Error(`The server responded with ${response.status}`)
101
91
  }
@@ -1,5 +1,5 @@
1
1
  import chalk from 'chalk'
2
- import uuid from 'uuid'
2
+ import { v4 as uuid } from 'uuid'
3
3
  import fs from 'fs-extra'
4
4
  import path from 'path'
5
5
  import urljoin from 'url-join'
@@ -17,7 +17,7 @@ export default async function download ({
17
17
  if (!branch && !repository) throw new Error('Repository details are required.')
18
18
  const repositoryName = gh(repository).name
19
19
  logger?.write(chalk.cyan(`downloading ${repositoryName} to ${cwd}\t`))
20
- tmp = (tmp || path.join(HOME_DIRECTORY, '.adapt', 'tmp', uuid.v1()))
20
+ tmp = (tmp || path.join(HOME_DIRECTORY, '.adapt', 'tmp', uuid()))
21
21
  const downloadFileName = await new Promise((resolve, reject) => {
22
22
  let downloadFileName = ''
23
23
  const url = urljoin(repository, 'archive', branch + '.zip')
@@ -1,4 +1,4 @@
1
- import uuid from 'uuid'
1
+ import { v4 as uuid } from 'uuid'
2
2
  import path from 'path'
3
3
  import decompress from 'decompress'
4
4
  import { HOME_DIRECTORY } from './constants.js'
@@ -7,7 +7,7 @@ export default async function extract ({
7
7
  sourcePath,
8
8
  cwd
9
9
  } = {}) {
10
- const rootPath = path.join(HOME_DIRECTORY, '.adapt', 'tmp', uuid.v1()).replace(/\\/g, '/')
10
+ const rootPath = path.join(HOME_DIRECTORY, '.adapt', 'tmp', uuid()).replace(/\\/g, '/')
11
11
  const files = await decompress(path.join(cwd, sourcePath), rootPath, {
12
12
  filter: file => !file.path.endsWith('/')
13
13
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adapt-cli",
3
- "version": "3.0.6",
3
+ "version": "3.0.8",
4
4
  "description": "Command line tools for Adapt",
5
5
  "main": "./lib/api.js",
6
6
  "type": "module",
@@ -17,12 +17,12 @@
17
17
  "inquirer": "^7.3.3",
18
18
  "json-lint": "^0.1.0",
19
19
  "lodash-es": "^4.17.21",
20
+ "node-fetch": "^3.2.10",
20
21
  "parse-github-url": "^1.0.2",
21
- "request": "^2.88.0",
22
22
  "semver": "^7.3.5",
23
23
  "speakingurl": "^14.0.1",
24
24
  "url-join": "^4.0.0",
25
- "uuid": "^3.3.2"
25
+ "uuid": "^8.3.2"
26
26
  },
27
27
  "license": "GPL-3.0",
28
28
  "preferGlobal": true,