@antora/playbook-builder 3.0.0-alpha.7 → 3.0.0-beta.2

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
@@ -4,7 +4,7 @@ The Playbook Builder is the configuration component for Antora.
4
4
  It's responsible for building a playbook object from user input that's then used for configuring components in an Antora generator pipeline.
5
5
 
6
6
  [Antora](https://antora.org) is a modular static site generator designed for creating documentation sites from AsciiDoc documents.
7
- Its site generator pipeline aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
7
+ Its site generator aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
8
8
 
9
9
  ## Copyright and License
10
10
 
@@ -1,10 +1,9 @@
1
1
  'use strict'
2
2
 
3
3
  const camelCaseKeys = require('camelcase-keys')
4
- const { configureLogger } = require('@antora/logger')
5
4
  const convict = require('./solitary-convict')
5
+ const defaultSchema = require('./config/schema')
6
6
  const fs = require('fs')
7
- const { hasOwnProperty } = Object.prototype
8
7
  const ospath = require('path')
9
8
 
10
9
  /**
@@ -22,14 +21,15 @@ const ospath = require('path')
22
21
  * option flags and switches. Should begin with the first flag or switch.
23
22
  * @param {Object} [env={}] - A map of environment variables.
24
23
  * @param {Object} [schema=undefined] - A convict configuration schema.
24
+ * @param {Function} [beforeValidate=undefined] - A function to invoke on the
25
+ * config before validating it.
25
26
  *
26
27
  * @returns {Object} A playbook object containing a hierarchical structure that
27
28
  * mirrors the configuration schema. With the exception of the top-level asciidoc
28
29
  * key and its descendants, all keys in the playbook are camelCased.
29
30
  */
30
- function buildPlaybook (args = [], env = {}, schema = undefined) {
31
+ function buildPlaybook (args = [], env = {}, schema = undefined, beforeValidate = undefined) {
31
32
  const config = loadConvictConfig(args, env, schema)
32
-
33
33
  const relSpecFilePath = config.get('playbook')
34
34
  if (relSpecFilePath) {
35
35
  let absSpecFilePath = ospath.resolve(relSpecFilePath)
@@ -57,47 +57,50 @@ function buildPlaybook (args = [], env = {}, schema = undefined) {
57
57
  config.loadFile(absSpecFilePath)
58
58
  if (relSpecFilePath !== absSpecFilePath) config.set('playbook', absSpecFilePath)
59
59
  }
60
-
61
- config.validate({ allowed: 'strict' })
62
-
63
- return exportModel(config)
60
+ const beforeValidateFromSchema = config._def[Symbol.for('convict.beforeValidate')]
61
+ if (beforeValidateFromSchema) beforeValidateFromSchema(config)
62
+ if (beforeValidate) beforeValidate(config)
63
+ return config.getModel()
64
64
  }
65
65
 
66
66
  function loadConvictConfig (args, env, customSchema) {
67
- return convict(customSchema || require('./config/schema'), { args, env })
67
+ return Object.assign(convict(customSchema || defaultSchema, { args, env }), { getModel })
68
68
  }
69
69
 
70
- function freeze (o) {
71
- let v
72
- for (const k in o) hasOwnProperty.call(o, k) && (Object.isFrozen((v = o[k])) || freeze(v))
73
- return Object.freeze(o)
70
+ function getModel (name = '') {
71
+ let config = this
72
+ const data = config.get(name)
73
+ let schema = config._schema
74
+ if (name) {
75
+ schema = name.split('.').reduce((accum, key) => accum._cvtProperties[key], schema)
76
+ config = Object.assign(convict(name.split('.').reduce((def, key) => def[key], config._def)), { _instance: data })
77
+ }
78
+ config.validate({ allowed: 'strict' })
79
+ const model = camelCaseKeys(data, { deep: true, stopPaths: getStopPaths(schema._cvtProperties) })
80
+ if (!name) {
81
+ Object.defineProperty(model, 'env', { value: config.getEnv() })
82
+ model.dir = model.playbook ? ospath.dirname((model.file = model.playbook)) : process.cwd()
83
+ delete model.playbook
84
+ }
85
+ return deepFreeze(model)
74
86
  }
75
87
 
76
- function exportModel (config) {
77
- const schemaProperties = config._schema._cvtProperties
78
- const data = config.getProperties()
79
- if (
80
- 'site' in schemaProperties &&
81
- 'keys' in schemaProperties.site._cvtProperties &&
82
- '__private__google_analytics_key' in schemaProperties.site._cvtProperties
83
- ) {
84
- const site = data.site
85
- if (site.__private__google_analytics_key != null) site.keys.google_analytics = site.__private__google_analytics_key
86
- delete site.__private__google_analytics_key
87
- }
88
- const playbook = camelCaseKeys(data, { deep: true, stopPaths: ['asciidoc'] })
89
- playbook.dir = playbook.playbook ? ospath.dirname((playbook.file = playbook.playbook)) : process.cwd()
90
- const runtime = (playbook.runtime || false).constructor === Object && playbook.runtime
91
- if (runtime) {
92
- const log = (runtime.log || false).constructor === Object && runtime.log
93
- if (runtime.silent) {
94
- if (runtime.quiet === false) runtime.quiet = true
95
- if (log && 'level' in log) log.level = 'silent'
88
+ function getStopPaths (schemaProperties, schemaPath = [], stopPaths = []) {
89
+ for (const [key, { preserve, _cvtProperties }] of Object.entries(schemaProperties)) {
90
+ if (preserve) {
91
+ Array.isArray(preserve)
92
+ ? preserve.forEach((it) => stopPaths.push(schemaPath.concat(key, it).join('.')))
93
+ : stopPaths.push(schemaPath.concat(key).join('.'))
94
+ } else if (_cvtProperties) {
95
+ stopPaths.push(...getStopPaths(_cvtProperties, schemaPath.concat(key)))
96
96
  }
97
- if (log) configureLogger(log, playbook.dir)
98
97
  }
99
- delete playbook.playbook
100
- return freeze(playbook)
98
+ return stopPaths
99
+ }
100
+
101
+ function deepFreeze (o) {
102
+ for (const v of Object.values(o)) Object.isFrozen(v) || deepFreeze(v)
103
+ return Object.freeze(o)
101
104
  }
102
105
 
103
- module.exports = buildPlaybook
106
+ module.exports = Object.assign(buildPlaybook, { defaultSchema })
@@ -7,6 +7,23 @@ module.exports = {
7
7
  default: undefined,
8
8
  arg: 'playbook',
9
9
  },
10
+ antora: {
11
+ generator: {
12
+ doc: 'A require request for the generator package name or script to use.',
13
+ format: String,
14
+ default: '@antora/site-generator-default',
15
+ arg: 'generator',
16
+ },
17
+ extensions: {
18
+ doc:
19
+ 'A list of extensions that listen for lifecycle events. ' +
20
+ 'Each extension is specified as a require request string or an object with a require key.',
21
+ format: 'require-array',
22
+ default: [],
23
+ arg: 'extension',
24
+ preserve: ['data'],
25
+ },
26
+ },
10
27
  site: {
11
28
  start_page: {
12
29
  doc: 'The start page for the site, redirected from the site index.',
@@ -54,7 +71,7 @@ module.exports = {
54
71
  branches: {
55
72
  doc: 'The default branch pattern to use when no specific pattern is provided.',
56
73
  format: Array,
57
- default: ['HEAD', 'v*'],
74
+ default: ['HEAD', 'v{0..9}*'],
58
75
  },
59
76
  edit_url: {
60
77
  doc: 'The default edit URL setting when no specific setting is provided.',
@@ -62,9 +79,10 @@ module.exports = {
62
79
  default: true,
63
80
  },
64
81
  sources: {
65
- doc: 'The list of git repositories + branch patterns to use.',
82
+ doc: 'The list of git repository urls, references, and start paths to use as content sources.',
66
83
  format: Array,
67
84
  default: [],
85
+ preserve: ['version'],
68
86
  },
69
87
  tags: {
70
88
  doc: 'The default tag pattern to use when no specific pattern is provided.',
@@ -113,9 +131,12 @@ module.exports = {
113
131
  format: 'map',
114
132
  default: {},
115
133
  arg: 'attribute',
134
+ preserve: true,
116
135
  },
117
136
  extensions: {
118
- doc: 'A list of require paths for registering extensions per instance of the AsciiDoc processor.',
137
+ doc:
138
+ 'A list of extensions to register either globally or per instance of the AsciiDoc processor. ' +
139
+ 'Each extension is specified as a require request string.',
119
140
  format: Array,
120
141
  default: [],
121
142
  },
@@ -147,6 +168,23 @@ module.exports = {
147
168
  format: Boolean,
148
169
  default: true,
149
170
  },
171
+ fetch_concurrency: {
172
+ doc: 'The maximum number of fetch or clone operations that are permitted to run at once. Use 0 for unlimited.',
173
+ format: 'int',
174
+ default: 0,
175
+ },
176
+ plugins: {
177
+ credential_manager: {
178
+ doc: 'A require request for a plugin to replace the built-in credential manager used by the git client.',
179
+ format: String,
180
+ default: undefined,
181
+ },
182
+ http: {
183
+ doc: 'A require request for a plugin to replace the built-in HTTP client used by the git client.',
184
+ format: String,
185
+ default: undefined,
186
+ },
187
+ },
150
188
  },
151
189
  network: {
152
190
  http_proxy: {
@@ -249,7 +287,7 @@ module.exports = {
249
287
  },
250
288
  buffer_size: {
251
289
  doc: 'The size of the log buffer that must be exceeded before writing a chunk to the destination.',
252
- format: Number,
290
+ format: 'int',
253
291
  default: 0,
254
292
  },
255
293
  sync: {
@@ -284,7 +322,7 @@ module.exports = {
284
322
  },
285
323
  redirect_facility: {
286
324
  doc: 'The facility for handling page alias and start page redirections.',
287
- format: ['disabled', 'httpd', 'netlify', 'nginx', 'static'],
325
+ format: ['disabled', 'gitlab', 'httpd', 'netlify', 'nginx', 'static'],
288
326
  default: 'static',
289
327
  arg: 'redirect-facility',
290
328
  },
@@ -308,4 +346,15 @@ module.exports = {
308
346
  default: undefined,
309
347
  },
310
348
  },
349
+ [Symbol.for('convict.beforeValidate')]: ({ _schema: schema, _instance: data }) => {
350
+ const runtime = data.runtime
351
+ if (runtime.silent) {
352
+ if (runtime.quiet === false) runtime.quiet = true
353
+ if (runtime.log.level !== 'silent') runtime.log.level = 'silent'
354
+ }
355
+ const site = data.site
356
+ if (site.__private__google_analytics_key != null) site.keys.google_analytics = site.__private__google_analytics_key
357
+ delete site.__private__google_analytics_key
358
+ delete schema._cvtProperties.site._cvtProperties.__private__google_analytics_key
359
+ },
311
360
  }
@@ -85,6 +85,25 @@ function registerFormats (convict) {
85
85
  return accum
86
86
  },
87
87
  })
88
+ convict.addFormat({
89
+ name: 'require-array',
90
+ validate: (val) => {
91
+ if (!Array.isArray(val)) throw new Error('must be of type Array')
92
+ },
93
+ coerce: (val, config, name) => {
94
+ const accum = config && config.has(name) ? config.get(name) : []
95
+ val.split(',').forEach((v) => {
96
+ if (~accum.indexOf(v)) return
97
+ const match = accum.find((it) => it.constructor === Object && it.id === v)
98
+ if (match) {
99
+ if (match.enabled === false) match.enabled = true
100
+ } else {
101
+ accum.push(v)
102
+ }
103
+ })
104
+ return accum
105
+ },
106
+ })
88
107
  convict.addFormat({
89
108
  name: 'boolean-or-string',
90
109
  validate: (val) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/playbook-builder",
3
- "version": "3.0.0-alpha.7",
3
+ "version": "3.0.0-beta.2",
4
4
  "description": "Builds a playbook object from user input for configuring successive documentation components in an Antora pipeline.",
5
5
  "license": "MPL-2.0",
6
6
  "author": "OpenDevise Inc. (https://opendevise.com)",
@@ -16,15 +16,14 @@
16
16
  },
17
17
  "main": "lib/index.js",
18
18
  "dependencies": {
19
- "@antora/logger": "3.0.0-alpha.7",
20
19
  "@iarna/toml": "~2.2",
21
- "camelcase-keys": "~6.2",
22
- "convict": "~6.1",
20
+ "camelcase-keys": "~7.0",
21
+ "convict": "~6.2",
23
22
  "js-yaml": "~4.1",
24
23
  "json5": "~2.2"
25
24
  },
26
25
  "engines": {
27
- "node": ">=10.17.0"
26
+ "node": ">=12.21.0"
28
27
  },
29
28
  "files": [
30
29
  "lib/"
@@ -37,5 +36,5 @@
37
36
  "static site",
38
37
  "web publishing"
39
38
  ],
40
- "gitHead": "fbd597b3680474f2083cda8a7facf1e2848c08e0"
39
+ "gitHead": "5cd3f9cc70622e465cb44daf1aa2035ed5a35f54"
41
40
  }