@gesslar/bedoc 2.0.0 → 2.1.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gesslar/bedoc",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Pluggable documentation engine for any language and format",
5
5
  "publisher": "gesslar",
6
6
  "author": "gesslar",
package/src/BeDoc.js CHANGED
@@ -7,7 +7,7 @@ import Conveyor from "./Conveyor.js"
7
7
  import Discovery from "./Discovery.js"
8
8
 
9
9
  /**
10
- * @import {FileObject, Glog} from "@gesslar/toolkit"
10
+ * @import {DirectoryObject, FileObject, Glog} from "@gesslar/toolkit"
11
11
  */
12
12
 
13
13
  export default class BeDoc {
@@ -30,20 +30,50 @@ export default class BeDoc {
30
30
  }
31
31
 
32
32
  /**
33
- * Create a new instance of BeDoc.
33
+ * Resolve and validate configuration from all sources (CLI, environment,
34
+ * package.json, config file). This runs independently of any BeDoc instance
35
+ * so the resulting config object can be built first and shared with other
36
+ * consumers (e.g. CLIOutput) before a BeDoc instance exists.
34
37
  *
35
38
  * @param {object} args
36
- * @param {object} args.options - The options passed into BeDoc
39
+ * @param {object} args.options - The raw options (with sources) to resolve
37
40
  * @param {string} args.source - The environment BeDoc is running in
41
+ * @returns {Promise<object>} The validated configuration object
42
+ */
43
+ static async resolveConfig({options, source}) {
44
+ const config = new Configuration()
45
+
46
+ return await config.validate({options, source})
47
+ }
48
+
49
+ /**
50
+ * Create a new instance of BeDoc.
51
+ *
52
+ * Configuration may be supplied pre-resolved (via {@link resolveConfig}) when
53
+ * a caller needs the config object before the instance exists — e.g. the CLI
54
+ * resolves it first to share with CLIOutput. Otherwise pass raw `options` and
55
+ * `source` and BeDoc resolves them itself, so any environment can construct a
56
+ * BeDoc in a single call.
57
+ *
58
+ * @param {object} args
59
+ * @param {object} [args.config] - Pre-validated configuration (see resolveConfig)
60
+ * @param {object} [args.options] - Raw options to resolve, if config is absent
61
+ * @param {string} [args.source] - The environment BeDoc is running in
62
+ * @param {DirectoryObject} [args.basePath] - The project base path
38
63
  * @param {Glog} args.glog - The Glog logger instance
64
+ * @param {Function} args.validateBeDocSchema - The action schema validator
65
+ * @param {object} args.cliOutput - The CLI output instance
39
66
  * @returns {Promise<BeDoc>} A new instance of BeDoc
40
67
  */
41
- static async new({options, source, glog, validateBeDocSchema, cliOutput}) {
42
- const {basePath} = options
68
+ static async new({
69
+ config, options, source, basePath, glog, validateBeDocSchema, cliOutput
70
+ }) {
71
+ const resolved = config ?? await BeDoc.resolveConfig({options, source})
72
+ const base = basePath ?? resolved.basePath ?? options?.basePath
43
73
 
44
- const bedoc = new this({basePath, glog, cliOutput})
74
+ const bedoc = new this({basePath: base, glog, cliOutput})
45
75
 
46
- await bedoc.#configure({options, source, glog, validateBeDocSchema})
76
+ bedoc.#configure({config: resolved, glog, validateBeDocSchema})
47
77
 
48
78
  const discovered = await bedoc.#discover()
49
79
 
@@ -60,29 +90,27 @@ export default class BeDoc {
60
90
  }
61
91
 
62
92
  /**
63
- * Validate configuration and store as options.
93
+ * Apply validated configuration to this instance.
64
94
  *
65
- * @param {object} options - The raw options passed into BeDoc
66
- * @param {string} source - The environment BeDoc is running in
95
+ * @param {object} config - The validated configuration object
96
+ * @param {Glog} glog - The Glog logger instance
97
+ * @param {Function} validateBeDocSchema - The action schema validator
67
98
  */
68
- async #configure({options, source, glog, validateBeDocSchema}) {
99
+ #configure({config, glog, validateBeDocSchema}) {
69
100
  this.#glog = glog
70
101
  this.#validateBeDocSchema = validateBeDocSchema
71
102
 
72
- const config = new Configuration()
73
- const validConfig = await config.validate({options, source})
74
-
75
- if(validConfig.debug && validConfig.debugLevel > 0)
76
- glog.withLogLevel(validConfig.debugLevel)
103
+ if(config.debug && config.debugLevel > 0)
104
+ glog.withLogLevel(config.debugLevel)
77
105
  else
78
106
  glog.withLogLevel(0)
79
107
 
80
- if(validConfig.status === "error")
81
- throw Tantrum.new("BeDoc configuration failed", validConfig.errors)
108
+ if(config.status === "error")
109
+ throw Tantrum.new("BeDoc configuration failed", config.errors)
82
110
 
83
- glog.debug("Creating new BeDoc instance with options: `%o`", 4, validConfig)
111
+ glog.debug("Creating new BeDoc instance with options: `%o`", 4, config)
84
112
 
85
- this.#options = validConfig
113
+ this.#options = config
86
114
  }
87
115
 
88
116
  /**
package/src/CLIOutput.js CHANGED
@@ -66,9 +66,9 @@ export default class CLIOutput {
66
66
  */
67
67
  #files = new Map()
68
68
 
69
- constructor({basePath, terse = false}) {
70
- this.#basePath = basePath
71
- this.#terse = terse
69
+ constructor({config}) {
70
+ this.#basePath = config.basePath
71
+ this.#terse = Boolean(config.terse)
72
72
 
73
73
  Notify.on("conveyor-start", this.#conveyorStart)
74
74
  Notify.on("update-data", this.#updateData)
@@ -142,6 +142,7 @@ export default class Configuration {
142
142
  return {
143
143
  status: "success",
144
144
  validated: true,
145
+ basePath: base,
145
146
  ...finalOptions,
146
147
  }
147
148
  }
package/src/cli.js CHANGED
@@ -71,28 +71,33 @@ void (async() => {
71
71
  optionsWithSources[key] = element
72
72
  }
73
73
 
74
- // Create core instance with validated config
74
+ // Resolve and validate configuration up front, before constructing
75
+ // anything that depends on it. Everything downstream — CLIOutput, BeDoc,
76
+ // the logger — consumes this single validated config object.
75
77
  const prjPath = new DirectoryObject()
76
- const cliOutput = new CLIOutput({
77
- basePath: prjPath,
78
- terse: Boolean(options.terse),
79
- })
80
78
  const prjPkJsonFile = new FileObject("package.json", prjPath)
81
79
  const prjPkjJson = await prjPkJsonFile.loadData()
82
80
  const pkjBedoc = prjPkjJson?.bedoc ?? {}
81
+
82
+ const config = await BeDoc.resolveConfig({
83
+ options: {
84
+ ...optionsWithSources,
85
+ basePath: prjPath,
86
+ project: pkjBedoc,
87
+ },
88
+ source: Environment.CLI,
89
+ })
90
+
91
+ const cliOutput = new CLIOutput({config})
92
+
83
93
  const validateBeDocSchema = await loadSchemaValidator(thisPath)
84
94
 
85
95
  const bedoc = await BeDoc
86
96
  .new({
87
- options: {
88
- ...optionsWithSources,
89
- basePath: prjPath,
90
- project: pkjBedoc,
91
- },
92
- source: Environment.CLI,
97
+ config,
93
98
  glog,
94
99
  validateBeDocSchema,
95
- cliOutput
100
+ cliOutput,
96
101
  })
97
102
 
98
103
  if(!(bedoc instanceof BeDoc)) {