@thegetty/quire-cli 1.0.0-rc.17 → 1.0.0-rc.18

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/CHANGELOG.md CHANGED
@@ -12,11 +12,32 @@ Changelog entries are classified using the following labels:
12
12
  - `Fixed`: for any bug fixes
13
13
  - `Removed`: for deprecated features removed in this release
14
14
 
15
+ ## [1.0.0-rc.18]
16
+
17
+ ### Added
18
+
19
+ - Quire CLI configuration management using the `conf` package
20
+ - `quire conf` command to manage cli configuration properties
21
+
22
+ ## [1.0.0-rc.17]
23
+
24
+ ### Bumped
25
+
26
+ - `install-npm-version` patch version
27
+
28
+ ### Changed
29
+
30
+ - update patch `install-npm-version`
31
+
15
32
  ## [1.0.0-rc.16]
16
33
 
34
+ ### Added
35
+
36
+ - Patch for `install-npm-version`; see https://nodejs.org/en/blog/vulnerability/april-2024-security-releases-2
37
+
17
38
  ### Changed
18
39
 
19
- - Patch for `install-npm-version@8.0.0`; see https://nodejs.org/en/blog/vulnerability/april-2024-security-releases-2
40
+ **Nota bene** installing `quire-cli` as a _local package_ requires running `npm install` with the `--install-strategy=nested` flag; installing `quire-cli` as a global node module has not changed.
20
41
 
21
42
  ### Fixed
22
43
 
package/bin/cli.js CHANGED
@@ -1,28 +1,35 @@
1
1
  #!/usr/bin/env -S node --no-warnings
2
2
 
3
3
  import cli from '#src/main.js'
4
+ import config from '#src/lib/conf/config.js'
4
5
  import packageConfig from '#root/package.json' assert { type: 'json' }
5
6
  import updateNotifier from 'update-notifier'
6
7
 
7
8
  process.removeAllListeners('warning')
8
9
 
10
+ /**
11
+ * Interval constants in milliseconds
12
+ */
9
13
  const INTERVAL = Object.freeze({
10
- MINUTES: 1000 * 60 * 1,
14
+ MINUTE: 1000 * 60 * 1,
11
15
  HOURLY: 1000 * 60 * 60,
12
16
  DAILY: 1000 * 60 * 60 * 24,
13
17
  WEEKLY: 1000 * 60 * 60 * 24 * 7
14
18
  })
15
19
 
20
+ const updateChannel = config.get('updateChannel')
21
+ const updateIterval = config.get('updateIterval')
22
+
16
23
  /**
17
- * Check for quire-cli updates
24
+ * Create a notifier to Check for quire-cli updates
18
25
  * @see https://github.com/yeoman/update-notifier#usage
19
26
  *
20
- * @todo user configuration of choosen update interval
27
+ * @todo refactor to check multiple channels
21
28
  */
22
29
  const notifier = updateNotifier({
23
- distTag: 'latest',
30
+ distTag: updateChannel,
24
31
  pkg: packageConfig,
25
- updateCheckInterval: INTERVAL.DAILY,
32
+ updateCheckInterval: INTERVAL[updateIterval],
26
33
  })
27
34
 
28
35
  notifier.notify({ defer: false })
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@thegetty/quire-cli",
3
3
  "description": "Quire command-line interface",
4
- "version": "1.0.0-rc.17",
4
+ "version": "1.0.0-rc.18",
5
5
  "author": "Getty Digital",
6
6
  "license": "SEE LICENSE IN https://github.com/thegetty/quire/blob/main/LICENSE",
7
7
  "bugs": {
@@ -51,7 +51,7 @@
51
51
  "boxen": "^7.0.1",
52
52
  "chalk": "^5.2.0",
53
53
  "commander": "^10.0.0",
54
- "conf": "^11.0.1",
54
+ "conf": "^13.1.0",
55
55
  "cross-env": "^7.0.3",
56
56
  "del": "^7.0.0",
57
57
  "epubjs-cli": "^0.1.6",
@@ -69,7 +69,7 @@
69
69
  "pagedjs-cli": "^0.4.3",
70
70
  "semver": "^7.3.8",
71
71
  "simple-git": "^3.16.0",
72
- "update-notifier": "^6.0.2"
72
+ "update-notifier": "^7.3.1"
73
73
  },
74
74
  "devDependencies": {
75
75
  "eslint": "^8.32.0"
package/src/Command.js CHANGED
@@ -1,3 +1,5 @@
1
+ import config from '#src/lib/conf/config.js'
2
+
1
3
  /**
2
4
  * Command
3
5
  * @abstract
@@ -12,6 +14,7 @@ export default class Command {
12
14
  /**
13
15
  * @typedef CommandDefinition
14
16
  * @property {String} name
17
+ * @property {String} alias
15
18
  * @property {Array<String>} aliases
16
19
  * @property {String} descriptions
17
20
  * @property {Array<CommandArgument>} args
@@ -24,6 +27,8 @@ export default class Command {
24
27
  /**
25
28
  * Constructs a new instance
26
29
  *
30
+ * Nota bene: Only the first command alias is displayed in the help.
31
+ *
27
32
  * @param {CommandDefinition} definition The definition
28
33
  */
29
34
  constructor(definition) {
@@ -31,6 +36,15 @@ export default class Command {
31
36
  throw new Error('Command is an *abstract* class')
32
37
  }
33
38
 
39
+ this.config = config // quire-cli configuration
40
+
41
+ /**
42
+ * Merge and deduplicate command definition alias and aliases
43
+ * Nota bene: Only the first command alias is displayed in the help.
44
+ */
45
+ // let aliases = Array.isArray(definition.aliases) ? definition.aliases || []
46
+ // aliases = new Set([ definition.alias, ...aliases ])
47
+
34
48
  this.name = definition.name
35
49
  this.aliases = definition.aliases
36
50
  this.description = definition.description
@@ -0,0 +1,43 @@
1
+ import Command from '#src/Command.js'
2
+
3
+ /**
4
+ * Quire CLI `conf` Command
5
+ *
6
+ * @class ConfCommand
7
+ * @extends {Command}
8
+ */
9
+ export default class ConfCommand extends Command {
10
+ static definition = {
11
+ name: 'conf',
12
+ aliases: ['config', 'configure'],
13
+ description: 'Manage the Quire CLI configuration.',
14
+ summary: 'read/write quire-cli configuration options',
15
+ version: '1.0.0',
16
+ options: [
17
+ [ '--debug', 'run command in debug mode' ],
18
+ ],
19
+ }
20
+
21
+ constructor() {
22
+ super(ConfCommand.definition)
23
+ }
24
+
25
+ /**
26
+ * @param {Object} options
27
+ * @return {Promise}
28
+ */
29
+ async action(key, value, options = {}) {
30
+ if (options.debug) {
31
+ console.info('Command \'%s\' called with options %o', this.name(), options)
32
+ }
33
+
34
+ // this.outputHelp()
35
+
36
+ console.info('quire-cli configuration %s', this.config.path)
37
+
38
+ for (const [ key, value ] of Object.entries(this.config.store)) {
39
+ if (key.startsWith('__internal__') && !options.debug) continue
40
+ console.info('%s: %O', key, value)
41
+ }
42
+ }
43
+ }
@@ -45,6 +45,8 @@ export default class CreateCommand extends Command {
45
45
  console.info('Command \'%s\' called with options %o', CreateCommand.name, options)
46
46
  }
47
47
 
48
+ starter = starter || this.config.get('projectTemplate')
49
+
48
50
  if (!projectPath && !starter) {
49
51
  // @TODO implement this case of interactively selecting starter templates
50
52
  // from available subtrees in `lib/quire` module
@@ -5,8 +5,6 @@ import os from 'node:os'
5
5
  import path from 'path'
6
6
  import testcwd from '#helpers/test-cwd.js'
7
7
 
8
- const VERSION_FILE = '.quire'
9
-
10
8
  /**
11
9
  * Quire CLI `info` Command
12
10
  *
@@ -22,7 +20,9 @@ export default class InfoCommand extends Command {
22
20
  summary: 'list info',
23
21
  version: '1.0.0',
24
22
  args: [],
25
- options: [['--debug', 'include os versions in output']],
23
+ options: [
24
+ ['--debug', 'include os versions in output']
25
+ ],
26
26
  }
27
27
 
28
28
  constructor() {
@@ -40,15 +40,18 @@ export default class InfoCommand extends Command {
40
40
  console.debug('[CLI] Command \'%s\' called', this.name())
41
41
  }
42
42
 
43
- let versionFile = fs.readFileSync(VERSION_FILE, { encoding: 'utf8' })
43
+ const versionFileName = this.config.get('versionFile')
44
+
44
45
  try {
45
- versionFile = JSON.parse(versionFile)
46
+ // the quire version file is always local to the project root
47
+ let fileData = fs.readFileSync(versionFileName, { encoding: 'utf8' })
48
+ versionInfo = JSON.parse(fileData)
46
49
  } catch (error) {
47
50
  console.warn(
48
51
  `This project was generated with the quire-cli prior to version 1.0.0.rc-8. Updating the version file to the new format, though this project's version file will not contain specific starter version information.`
49
52
  )
50
- versionFile = { cli: '<=1.0.0.rc-7' }
51
- fs.writeFileSync(VERSION_FILE, JSON.stringify(versionFile))
53
+ versionInfo = { cli: '<=1.0.0.rc-7' }
54
+ fs.writeFileSync(versionFileName, JSON.stringify(versionInfo))
52
55
  }
53
56
 
54
57
  const { name: projectDirectory } = path.parse(process.cwd())
@@ -59,7 +62,7 @@ export default class InfoCommand extends Command {
59
62
  items: [
60
63
  {
61
64
  name: 'quire-cli',
62
- get: () => versionFile.cli,
65
+ get: () => versionInfo.cli,
63
66
  },
64
67
  {
65
68
  name: 'quire-11ty',
@@ -70,7 +73,7 @@ export default class InfoCommand extends Command {
70
73
  },
71
74
  {
72
75
  name: 'starter',
73
- get: () => versionFile.starter,
76
+ get: () => versionInfo.starter,
74
77
  },
75
78
  ],
76
79
  },
@@ -0,0 +1,104 @@
1
+ ## CLI Configuration Manager
2
+
3
+ This `quire-cli/lib/config` module manages reading and writing (persisting) options for the Quire CLI using the [`conf`](https://github.com/sindresorhus/conf) package.
4
+
5
+ `conf` stores the config in the system default [user config directory](https://github.com/sindresorhus/env-paths#pathsconfig). For example, on macOS, the config file will be stored in the `~/Library/Preferences/@thegetty/quire-cli` directory.
6
+
7
+ > Changes are written to disk atomically, so if the process crashes during a write, it will not corrupt the existing config.
8
+
9
+ ### Configuration
10
+
11
+ `logLevel` The default logging level for the Quire CLI output; default `'info'`.
12
+
13
+ `projectTemplate` A default project starter template to use when creating new projects; default `'quire-starter-default'`.
14
+
15
+ `quirePath` The relative path to `quire-11ty` installed in the project directory; default `./11ty`. When set to `null`, `quire-11ty` is installed to the CLI `lib/quire/versions/<version>/` directory.
16
+
17
+ ```sh
18
+ ❯ quire config quire-path '.'
19
+ ```
20
+
21
+ `quireVersion` The default version of `quire-11ty` to install when creating new Quire projects; default `'latest'`.
22
+
23
+ ```sh
24
+ ❯ quire config quire-version '1.0.0'
25
+ ```
26
+
27
+ `telemetry` Send anonymous data about Quire usage; default `false`.
28
+
29
+ ```sh
30
+ ❯ quire config telemetry --enabled
31
+ ```
32
+
33
+ ```sh
34
+ ❯ quire config telemetry --disabled
35
+ ```
36
+
37
+ `updateChannels` A list of distribution tags to use when checking for version updates; default `['latest']`. To show notifications for pre-releases version updates include `'pre-release'` in the array of channels. This can be set using the configuration `--pre-release` command flag.
38
+
39
+ ```sh
40
+ ❯ quire config update-channels
41
+ Quire configured to check for updates tagged 'latest'
42
+ ```
43
+
44
+ ```sh
45
+ ❯ quire config update-channels --add 'pre-release'
46
+ Quire configured to check for updates tagged 'latest', 'pre-release'
47
+ ```
48
+
49
+ ```sh
50
+ ❯ quire config update-channels --rm 'pre-release'
51
+ Quire configured to check for updates tagged 'latest'
52
+ ```
53
+
54
+ `updateInterval` Interval at which to check for updates to the Quire CLI and project's `quire-11ty` version; default `'DAILY'`.
55
+
56
+ ```sh
57
+ ❯ quire config update-interval
58
+ Quire configured to check for updates DAILY
59
+ ```
60
+
61
+ ```sh
62
+ ❯ quire config update-interval WEEKLY
63
+ ```
64
+
65
+ `versionFile ['.quire-version']` The default file name for the `quire-11ty` version file.
66
+
67
+ ```sh
68
+ ❯ quire config version-file '.blargh'
69
+ ```
70
+
71
+ ### Quire CLI `config` Command
72
+
73
+ Running the `config` command without any arguments will start an interactive prompt to configure Quire.
74
+
75
+ To view an individual configuration value and its default value use:
76
+
77
+ ```sh
78
+ ❯ quire config [key]
79
+ ```
80
+
81
+ To view the current `logLevel` setting for example:
82
+
83
+ ```sh
84
+ ❯ quire config logLevel
85
+ loglevel: 'debug' (default 'info')
86
+ ```
87
+
88
+ To set an individual configuration value, use the `set` argument:
89
+
90
+ ```sh
91
+ ❯ quire config set <key> <value>
92
+ ```
93
+
94
+ To reset *all* keys to their default values, use the `reset` argument:
95
+
96
+ ```sh
97
+ ❯ quire config reset
98
+ ```
99
+
100
+ To reset an individual key to its default value:
101
+
102
+ ```sh
103
+ ❯ quire config reset [key]
104
+ ```
@@ -0,0 +1,35 @@
1
+ import Conf from 'conf'
2
+ import defaults from './defaults.js'
3
+ import migrations from './migrations.js'
4
+ import schema from './schema.js'
5
+ import packageConfig from '#root/package.json' assert { type: 'json' }
6
+
7
+ const { name, version } = packageConfig
8
+
9
+ const beforeEachMigration = (store, context) => {
10
+ const { fromVersion, toVersion } = context
11
+ console.info(`quire-cli migrating config from ${fromVersion} → ${toVersion}`)
12
+ }
13
+
14
+ /**
15
+ * Create quire-cli configuration instance
16
+ * @see https://github.com/sindresorhus/conf#confoptions
17
+ *
18
+ * @todo support yaml configuration files
19
+ * https://github.com/sindresorhus/conf?tab=readme-ov-file#can-i-use-yaml-or-another-serialization-format
20
+ *
21
+ * @type {Conf}
22
+ */
23
+ const config = new Conf({
24
+ beforeEachMigration,
25
+ clearInvalidConfig: true,
26
+ defaults,
27
+ migrations,
28
+ projectName: name,
29
+ projectSuffix: '',
30
+ projectVersion: version,
31
+ schema,
32
+ watch: true,
33
+ })
34
+
35
+ export default config
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Default values for Quire configuration properties
3
+ *
4
+ * Nota bene: these values will overwrite schema default values
5
+ * @see https://github.com/sindresorhus/conf#defaults
6
+ */
7
+ export default {
8
+ /**
9
+ * Logging level for the Quire CLI output.
10
+ */
11
+ logLevel: 'info',
12
+ /**
13
+ * Project starter template to use when creating new projects.
14
+ */
15
+ projectTemplate: 'https://github.com/thegetty/quire-starter-default',
16
+ /**
17
+ * Relative path to quire-11ty installed in the project directory.
18
+ */
19
+ quire11tyPath: '.',
20
+ /**
21
+ * Version of quire-11ty to install when creating new projects.
22
+ */
23
+ quireVersion: 'latest',
24
+ /**
25
+ * Npm distribution tag to use when checking for version updates
26
+ */
27
+ updateChannel: 'rc',
28
+ /**
29
+ * Interval at which to check for updates to the Quire CLI
30
+ * and to quire-11ty version for a prject.
31
+ */
32
+ updateInterval: 'DAILY',
33
+ /**
34
+ * File name for the quire-11ty version file.
35
+ */
36
+ versionFile: '.quire',
37
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Quire configuration migrations
3
+ * @see https://github.com/sindresorhus/conf#migrations
4
+ */
5
+ const migrations = {
6
+ '1.0.0': (store) => {
7
+ store.set('updateChannel', 'latest')
8
+ }
9
+ }
10
+
11
+ export default migrations
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Quire configuration schema
3
+ * @see https://github.com/sindresorhus/conf#schema
4
+ *
5
+ * Nota bene: schema default values will are overwritten by `defaults.js` values
6
+ * @see https://github.com/sindresorhus/conf#defaults
7
+ */
8
+ export default {
9
+ logLevel: {
10
+ type: 'string'
11
+ },
12
+ projectTemplate: {
13
+ type: 'string'
14
+ },
15
+ quire11tyPath: {
16
+ type: 'string'
17
+ },
18
+ quireVersion: {
19
+ type: 'string'
20
+ },
21
+ updateChannel: {
22
+ type: 'string'
23
+ },
24
+ updateInterval: {
25
+ type: 'string'
26
+ },
27
+ versionFile: {
28
+ type: 'string'
29
+ }
30
+ }
@@ -89,8 +89,6 @@ async function initStarter (starter, projectPath, options) {
89
89
  return
90
90
  }
91
91
 
92
- starter = starter || 'https://github.com/thegetty/quire-starter-default'
93
-
94
92
  console.debug('[CLI:quire] init-starter',
95
93
  `\n project root: "${projectPath}"`,
96
94
  `\n starter: "${starter}"`
package/src/main.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Argument, Command, Option } from 'commander'
2
- import commands from './commands/index.js'
2
+ import commands from '#src/commands/index.js'
3
+ import config from '#lib/conf/config.js'
3
4
  import packageConfig from '../package.json' assert { type: 'json' }
4
5
 
5
6
  /**
@@ -12,7 +13,7 @@ import packageConfig from '../package.json' assert { type: 'json' }
12
13
  const program = new Command()
13
14
 
14
15
  program
15
- .name('quire-cli')
16
+ .name('quire')
16
17
  .description('Quire command-line interface')
17
18
  .version(packageConfig.version, '-v, --version', 'output quire version number')
18
19
  .configureHelp({
@@ -23,9 +24,12 @@ program
23
24
 
24
25
  /**
25
26
  * Register each command as a subcommand of this program
27
+ *
28
+ * @todo refactor command definition to allow for per-command custom help text
29
+ * @see https://github.com/tj/commander.js?tab=readme-ov-file#automated-help
26
30
  */
27
31
  commands.forEach((command) => {
28
- const { action, aliases, args, description, name, options } = command
32
+ const { action, alias, aliases, args, description, name, options } = command
29
33
 
30
34
  const subCommand = program
31
35
  .command(name)
@@ -33,8 +37,12 @@ commands.forEach((command) => {
33
37
  .addHelpCommand()
34
38
  .showHelpAfterError()
35
39
 
40
+ if (alias instanceof String) {
41
+ subCommand.alias(alias)
42
+ }
43
+
36
44
  if (Array.isArray(aliases)) {
37
- aliases.forEach((alias) => subCommand.alias(alias))
45
+ subCommand.aliases(aliases)
38
46
  }
39
47
 
40
48
  /**
@@ -103,6 +111,11 @@ commands.forEach((command) => {
103
111
 
104
112
  // subCommand.action((args) => action.apply(command, args))
105
113
  subCommand.action(action)
114
+
115
+ /**
116
+ * Inject the CLI configuration into commands
117
+ */
118
+ subCommand.config = config
106
119
  })
107
120
 
108
121
  /**
@@ -1,3 +0,0 @@
1
- ## CLI Configuration Manager
2
-
3
- This `quire-cli/lib/config` module orchestrates creation of new projects and management of existing project configuration.
@@ -1 +0,0 @@
1
- import semver from 'semver'