@flowscripter/dynamic-cli-framework 12.0.1 → 12.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/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/src/cli/BaseCLI.d.ts.map +1 -1
- package/dist/src/cli/BaseCLI.js +3 -1
- package/dist/src/cli/BaseCLIFeatureOptions.d.ts +6 -0
- package/dist/src/cli/BaseCLIFeatureOptions.d.ts.map +1 -1
- package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts +11 -3
- package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts.map +1 -1
- package/dist/src/service/configuration/ConfigurationServiceProvider.js +28 -11
- package/dist/src/service/configuration/format/ConfigFormat.d.ts +42 -0
- package/dist/src/service/configuration/format/ConfigFormat.d.ts.map +1 -0
- package/dist/src/service/configuration/format/ConfigFormat.js +0 -0
- package/dist/src/service/configuration/format/JsonConfigFormat.d.ts +7 -0
- package/dist/src/service/configuration/format/JsonConfigFormat.d.ts.map +1 -0
- package/dist/src/service/configuration/format/JsonConfigFormat.js +17 -0
- package/dist/src/service/configuration/format/TomlConfigFormat.d.ts +10 -0
- package/dist/src/service/configuration/format/TomlConfigFormat.d.ts.map +1 -0
- package/dist/src/service/configuration/format/TomlConfigFormat.js +78 -0
- package/dist/src/service/configuration/format/YamlConfigFormat.d.ts +9 -0
- package/dist/src/service/configuration/format/YamlConfigFormat.d.ts.map +1 -0
- package/dist/src/service/configuration/format/YamlConfigFormat.js +63 -0
- package/dist/toml.d.ts +2 -0
- package/dist/toml.d.ts.map +1 -0
- package/dist/toml.js +1 -0
- package/dist/yaml.d.ts +2 -0
- package/dist/yaml.d.ts.map +1 -0
- package/dist/yaml.js +1 -0
- package/index.ts +3 -0
- package/package.json +27 -3
- package/src/cli/BaseCLI.ts +3 -0
- package/src/cli/BaseCLIFeatureOptions.ts +6 -0
- package/src/service/configuration/ConfigurationServiceProvider.ts +36 -10
- package/src/service/configuration/format/ConfigFormat.ts +42 -0
- package/src/service/configuration/format/JsonConfigFormat.ts +22 -0
- package/src/service/configuration/format/TomlConfigFormat.ts +92 -0
- package/src/service/configuration/format/YamlConfigFormat.ts +72 -0
- package/toml.ts +1 -0
- package/yaml.ts +1 -0
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,9 @@ export { default as DefaultSecretService } from "./src/service/configuration/Def
|
|
|
36
36
|
export type { SecretsApi } from "./src/service/configuration/DefaultSecretService.ts";
|
|
37
37
|
export { default as ConfigCommand } from "./src/service/configuration/command/ConfigCommand.ts";
|
|
38
38
|
export { default as ConfigurationServiceProvider, type KeyValueServiceScopeType, } from "./src/service/configuration/ConfigurationServiceProvider.ts";
|
|
39
|
+
export type { default as ConfigFormat } from "./src/service/configuration/format/ConfigFormat.ts";
|
|
40
|
+
export type { ConfigData } from "./src/service/configuration/format/ConfigFormat.ts";
|
|
41
|
+
export { default as jsonFormat } from "./src/service/configuration/format/JsonConfigFormat.ts";
|
|
39
42
|
export { default as KeyValueServiceProvider } from "./src/service/configuration/KeyValueServiceProvider.ts";
|
|
40
43
|
export { PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
41
44
|
export type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACxE,YAAY,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,wBAAwB,EACxB,eAAe,EACf,kBAAkB,GACnB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC9F,YAAY,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,oCAAoC,EAAE,MAAM,yCAAyC,CAAC;AAC/F,YAAY,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,2BAA2B,EAAE,MAAM,yCAAyC,CAAC;AACtF,YAAY,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,YAAY,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAG1E,YAAY,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,YAAY,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,YAAY,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,YAAY,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,YAAY,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,YAAY,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAG5E,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAG5F,YAAY,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,YAAY,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAGvF,OAAO,EAAE,iCAAiC,EAAE,MAAM,yCAAyC,CAAC;AAC5F,YAAY,EAAE,2BAA2B,EAAE,MAAM,yCAAyC,CAAC;AAC3F,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,kCAAkC,EAAE,MAAM,0EAA0E,CAAC;AACzI,OAAO,EAAE,OAAO,IAAI,mCAAmC,EAAE,MAAM,2EAA2E,CAAC;AAC3I,OAAO,EAAE,OAAO,IAAI,qCAAqC,EAAE,MAAM,mFAAmF,CAAC;AACrJ,YAAY,EACV,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,mFAAmF,CAAC;AAE3F,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAE/F,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACnF,YAAY,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,YAAY,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,YAAY,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC1G,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,qDAAqD,CAAC;AACtG,YAAY,EAAE,UAAU,EAAE,MAAM,qDAAqD,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,sDAAsD,CAAC;AAChG,OAAO,EACL,OAAO,IAAI,4BAA4B,EACvC,KAAK,wBAAwB,GAC9B,MAAM,6DAA6D,CAAC;AACrE,YAAY,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oDAAoD,CAAC;AAClG,YAAY,EAAE,UAAU,EAAE,MAAM,oDAAoD,CAAC;AACrF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wDAAwD,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,wDAAwD,CAAC;AAE5G,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,YAAY,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AACnG,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,iDAAiD,CAAC;AAEpG,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AACrG,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAEvG,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,YAAY,EACV,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,eAAe,GAChB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,iDAAiD,CAAC;AAEpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC1F,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAC5F,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AAE9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,YAAY,EACV,YAAY,EACZ,WAAW,EACX,YAAY,GACb,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAC5F,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AAE9F,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AACxF,YAAY,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACxF,YAAY,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,oEAAoE,CAAC;AAChI,OAAO,EAAE,OAAO,IAAI,gCAAgC,EAAE,MAAM,qEAAqE,CAAC;AAElI,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,YAAY,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,4DAA4D,CAAC;AACpH,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,6DAA6D,CAAC;AAEtH,OAAO,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACnF,YAAY,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AACjH,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,2DAA2D,CAAC;AAEnH,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,YAAY,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,YAAY,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,wDAAwD,CAAC;AAC9G,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,yDAAyD,CAAC;AAEhH,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AACrF,YAAY,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,EACL,KAAK,EACL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,yCAAyC,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,8DAA8D,CAAC;AACvH,OAAO,EAAE,OAAO,IAAI,6BAA6B,EAAE,MAAM,+DAA+D,CAAC;AAEzH,OAAO,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAC;AACzF,YAAY,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EACL,KAAK,cAAc,EACnB,UAAU,EACV,KAAK,sBAAsB,GAC5B,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,oEAAoE,CAAC;AAChI,OAAO,EAAE,OAAO,IAAI,gCAAgC,EAAE,MAAM,qEAAqE,CAAC;AAElI,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,KAAK,cAAc,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,sDAAsD,CAAC;AAC3G,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,uDAAuD,CAAC;AAE7G,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,YAAY,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EACL,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,UAAU,GACX,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AACrG,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,GAC3B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAEvG,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,YAAY,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AACvF,YAAY,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,kEAAkE,CAAC;AAC7H,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,mEAAmE,CAAC;AAG/H,YAAY,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,YAAY,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,yCAAyC,CAAC;AAC1F,YAAY,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3F,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,YAAY,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AAGnE,OAAO,EACL,iCAAiC,EACjC,8BAA8B,GAC/B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,6CAA6C,CAAC;AAGrD,YAAY,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,qDAAqD,EAAE,MAAM,yCAAyC,CAAC;AAChH,YAAY,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACtF,OAAO,EAAE,8DAA8D,EAAE,MAAM,yCAAyC,CAAC;AACzH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,YAAY,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AAGjG,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,8BAA8B,EAC9B,0BAA0B,EAC1B,wBAAwB,EACxB,yBAAyB,EACzB,gCAAgC,EAChC,kCAAkC,EAClC,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,mCAAmC,EACnC,8BAA8B,EAC9B,uBAAuB,EACvB,kCAAkC,EAClC,2BAA2B,EAC3B,8BAA8B,EAC9B,sCAAsC,GACvC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAG9E,YAAY,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtE,YAAY,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,OAAO,IAAI,SAAS,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGzE,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export { default as DefaultKeyValueService } from "./src/service/configuration/D
|
|
|
14
14
|
export { default as DefaultSecretService } from "./src/service/configuration/DefaultSecretService.js";
|
|
15
15
|
export { default as ConfigCommand } from "./src/service/configuration/command/ConfigCommand.js";
|
|
16
16
|
export { default as ConfigurationServiceProvider, } from "./src/service/configuration/ConfigurationServiceProvider.js";
|
|
17
|
+
export { default as jsonFormat } from "./src/service/configuration/format/JsonConfigFormat.js";
|
|
17
18
|
export { default as KeyValueServiceProvider } from "./src/service/configuration/KeyValueServiceProvider.js";
|
|
18
19
|
export { PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
19
20
|
export { Icon, Level, ProgressStyle, SpinnerStyle } from "@flowscripter/dynamic-cli-framework-api";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsBzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsBzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAW3E,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAEhD,OAAO,KAAK,SAAS,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AAqCpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,YAAW,GAAG;;IAazC,YACE,SAAS,EAAE,SAAS,EACpB,oBAAoB,EAAE,cAAc,EACpC,oBAAoB,EAAE,cAAc,EACpC,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,OAAO,EACtB,cAAc,EAAE,QAAQ,EACxB,cAAc,EAAE,QAAQ,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,OAAO,CAAC,EAAE,qBAAqB,EAwEhC;IAED;;;;;;;OAOG;IACI,kBAAkB,CAAC,eAAe,EAAE,eAAe,QAEzD;IAED;;;;;;;;OAQG;IACH;;;;;OAKG;IACI,cAAc,CAAC,IAAI,EAAE,WAAW,QAEtC;IAEM,UAAU,CAAC,OAAO,EAAE,OAAO,QAQjC;IAEK,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CA4QzD;CACF"}
|
package/dist/src/cli/BaseCLI.js
CHANGED
|
@@ -12,6 +12,7 @@ import CommandValidator from "../runtime/command/CommandValidator.js";
|
|
|
12
12
|
import ShutdownServiceProvider from "../service/shutdown/ShutdownServiceProvider.js";
|
|
13
13
|
import StartupServiceProvider from "../service/startup/StartupServiceProvider.js";
|
|
14
14
|
import { shutdownState } from "../service/shutdown/ShutdownState.js";
|
|
15
|
+
import jsonFormat from "../service/configuration/format/JsonConfigFormat.js";
|
|
15
16
|
import ConfigurationServiceProvider from "../service/configuration/ConfigurationServiceProvider.js";
|
|
16
17
|
import KeyValueServiceProvider from "../service/configuration/KeyValueServiceProvider.js";
|
|
17
18
|
import PrinterServiceProvider from "../service/printer/PrinterServiceProvider.js";
|
|
@@ -100,6 +101,7 @@ export default class BaseCLI {
|
|
|
100
101
|
}
|
|
101
102
|
this.#cliConfig = cliConfig;
|
|
102
103
|
this.#options = {
|
|
104
|
+
configFormat: jsonFormat,
|
|
103
105
|
configFileSupportEnabled: false,
|
|
104
106
|
envVarsSupportEnabled: false,
|
|
105
107
|
keyValueServiceEnabled: false,
|
|
@@ -245,7 +247,7 @@ export default class BaseCLI {
|
|
|
245
247
|
if (this.#options.pluginServiceEnabled) {
|
|
246
248
|
this.addServiceProvider(new PluginServiceProvider(PLUGIN_SERVICE_PRIORITY, this.#options.pluginServiceRemoteConfig, this.#options.pluginServiceLocalConfig, this.#commandRegistry, this.#serviceProviderRegistry));
|
|
247
249
|
}
|
|
248
|
-
const configurationServiceProvider = new ConfigurationServiceProvider(CONFIGURATION_SERVICE_PRIORITY, this.#options.envVarsSupportEnabled, this.#options.configFileSupportEnabled, this.#options.secretServiceEnabled);
|
|
250
|
+
const configurationServiceProvider = new ConfigurationServiceProvider(CONFIGURATION_SERVICE_PRIORITY, this.#options.envVarsSupportEnabled, this.#options.configFileSupportEnabled, this.#options.secretServiceEnabled, this.#options.configFormat);
|
|
249
251
|
this.addServiceProvider(configurationServiceProvider);
|
|
250
252
|
const keyValueServiceProvider = new KeyValueServiceProvider(KEY_VALUE_SERVICE_PRIORITY, configurationServiceProvider, this.#options.keyValueServiceEnabled, this.#options.secretServiceEnabled);
|
|
251
253
|
this.addServiceProvider(keyValueServiceProvider);
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import type ConfigFormat from "../service/configuration/format/ConfigFormat.ts";
|
|
1
2
|
import type { UpgradeLocationsConfig } from "../service/upgrade/UpgradeLocationsConfig.ts";
|
|
2
3
|
import type { NpmjsPluginRepositoryConfig, NpmPluginRepositoryConfig } from "@flowscripter/dynamic-plugin-framework";
|
|
3
4
|
export default interface BaseCLIFeatureOptions {
|
|
4
5
|
readonly configFileSupportEnabled?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* The syntax of the configuration file. Defaults to JSON. YAML and TOML are available from the
|
|
8
|
+
* `@flowscripter/dynamic-cli-framework/yaml` and `@flowscripter/dynamic-cli-framework/toml` entry points.
|
|
9
|
+
*/
|
|
10
|
+
readonly configFormat?: ConfigFormat;
|
|
5
11
|
readonly envVarsSupportEnabled?: boolean;
|
|
6
12
|
readonly keyValueServiceEnabled?: boolean;
|
|
7
13
|
readonly secretServiceEnabled?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseCLIFeatureOptions.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLIFeatureOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAC3F,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,wCAAwC,CAAC;AAEhD,MAAM,CAAC,OAAO,WAAW,qBAAqB;IAC5C,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAClD,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IACzD;;;OAGG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAC3C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;IACjE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,yBAAyB,CAAC;IAC9D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC"}
|
|
1
|
+
{"version":3,"file":"BaseCLIFeatureOptions.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLIFeatureOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iDAAiD,CAAC;AAChF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAC3F,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAC1B,MAAM,wCAAwC,CAAC;AAEhD,MAAM,CAAC,OAAO,WAAW,qBAAqB;IAC5C,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAClD,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IACzD;;;OAGG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAC3C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,2BAA2B,CAAC;IACjE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,yBAAyB,CAAC;IAC9D,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC"}
|
|
@@ -2,6 +2,7 @@ import type { ServiceInfo, ServiceProvider } from "@flowscripter/dynamic-cli-fra
|
|
|
2
2
|
import type { SingleValueType, Values, ValueNode, PopulatedValues, PopulatedValueType } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
4
|
import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
|
+
import type ConfigFormat from "./format/ConfigFormat.ts";
|
|
5
6
|
import type { Command } from "@flowscripter/dynamic-cli-framework-api";
|
|
6
7
|
import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
|
|
7
8
|
export type KeyValueServiceScopeType = "command" | "service";
|
|
@@ -26,7 +27,7 @@ export type KeyValueServiceScopeType = "command" | "service";
|
|
|
26
27
|
*
|
|
27
28
|
* *Configuration File*
|
|
28
29
|
*
|
|
29
|
-
* A JSON
|
|
30
|
+
* A file (JSON by default, see {@link ConfigFormat}) where the structure matches {@link Values} and the defaults are stored
|
|
30
31
|
* under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
|
|
31
32
|
* (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
|
|
32
33
|
* command {@link Values}. As an example:
|
|
@@ -57,7 +58,12 @@ export type KeyValueServiceScopeType = "command" | "service";
|
|
|
57
58
|
* }
|
|
58
59
|
* ```
|
|
59
60
|
*
|
|
60
|
-
* The
|
|
61
|
+
* The syntax of the file is set by the `configFormat` constructor argument: JSON (the default), or YAML or TOML
|
|
62
|
+
* from the `yaml` and `toml` entry points of this package. The format is never inferred from the file name or
|
|
63
|
+
* extension and existing files are not migrated between formats. For YAML and TOML, comments and layout in the
|
|
64
|
+
* existing file are preserved when it is written back.
|
|
65
|
+
*
|
|
66
|
+
* The default location of the configuration file is `$HOME/.<application_name>.<format extension>`. If `$HOME` is not defined no
|
|
61
67
|
* default configuration will be used. The location of the configuration file can be modified via the
|
|
62
68
|
* {@link ConfigCommand}.
|
|
63
69
|
*
|
|
@@ -113,6 +119,7 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
113
119
|
readonly envVarsEnabled: boolean;
|
|
114
120
|
readonly configEnabled: boolean;
|
|
115
121
|
readonly secretServiceEnabled: boolean;
|
|
122
|
+
readonly configFormat: ConfigFormat;
|
|
116
123
|
configLocation: string | undefined;
|
|
117
124
|
defaultsData: Map<string, Values | SingleValueType>;
|
|
118
125
|
/**
|
|
@@ -123,8 +130,9 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
123
130
|
* @param configEnabled optionally enable configuration file support for default argument values.
|
|
124
131
|
* @param secretServiceEnabled optionally enable OS-native secret storage via Bun.secrets for resolving
|
|
125
132
|
* secrets embedded in default argument values: `configEnabled` must be true in this case
|
|
133
|
+
* @param configFormat optionally set the syntax of the configuration file, defaults to JSON.
|
|
126
134
|
*/
|
|
127
|
-
constructor(servicePriority: number, envVarsEnabled?: boolean, configEnabled?: boolean, secretServiceEnabled?: boolean);
|
|
135
|
+
constructor(servicePriority: number, envVarsEnabled?: boolean, configEnabled?: boolean, secretServiceEnabled?: boolean, configFormat?: ConfigFormat);
|
|
128
136
|
getServiceInfo(cliConfig: CLIConfig): Promise<ServiceInfo>;
|
|
129
137
|
setConfigLocation(configLocation: string): void;
|
|
130
138
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigurationServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/configuration/ConfigurationServiceProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE5F,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,eAAe,EACf,kBAAkB,EACnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"ConfigurationServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/configuration/ConfigurationServiceProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE5F,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,eAAe,EACf,kBAAkB,EACnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAS5E,OAAO,KAAK,YAAY,MAAM,0BAA0B,CAAC;AAIzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAOvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,CAAC;AAkB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA6B,YAAW,eAAe;;IAC1E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAA4B;IACtD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,SAAgB,cAAc,EAAE,OAAO,CAAC;IACxC,SAAgB,aAAa,EAAE,OAAO,CAAC;IACvC,SAAgB,oBAAoB,EAAE,OAAO,CAAC;IAC9C,SAAgB,YAAY,EAAE,YAAY,CAAC;IAGpC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAQnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,CAAa;IAqBvE;;;;;;;;;OASG;IACH,YACE,eAAe,EAAE,MAAM,EACvB,cAAc,UAAQ,EACtB,aAAa,UAAQ,EACrB,oBAAoB,UAAQ,EAC5B,YAAY,GAAE,YAAyB,EAYxC;IAEM,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAiBhE;IAEM,iBAAiB,CAAC,cAAc,EAAE,MAAM,QAE9C;IAED;;;;;;;;;OASG;IACU,wBAAwB,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAC,CAsD3D;IAED;;;;;;OAMG;IACI,eAAe,CACpB,SAAS,EAAE,wBAAwB,EACnC,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAOxB;IAED;;;;;;OAMG;IACU,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzD;IAEY,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6CxD;IAgEM,eAAe,IAAI,MAAM,CAE/B;CAmCF"}
|
|
@@ -8,6 +8,7 @@ import ConfigDumpSubCommand from "./command/ConfigDumpSubCommand.js";
|
|
|
8
8
|
import ConfigGroupCommand from "./command/ConfigGroupCommand.js";
|
|
9
9
|
import { CONFIGURATION_SERVICE_ID, SECRET_SENTINEL_PREFIX, } from "@flowscripter/dynamic-cli-framework-api";
|
|
10
10
|
import DefaultSecretService from "./DefaultSecretService.js";
|
|
11
|
+
import jsonFormat from "./format/JsonConfigFormat.js";
|
|
11
12
|
import resolveSecrets from "./resolveSecrets.js";
|
|
12
13
|
import argumentValueMerge from "../../runtime/values/argumentValueMerge.js";
|
|
13
14
|
import { isGlobalCommand, isGlobalModifierCommand, isSubCommand, } from "../../runtime/command/CommandTypeGuards.js";
|
|
@@ -46,7 +47,7 @@ class ConfigurationServiceImpl {
|
|
|
46
47
|
*
|
|
47
48
|
* *Configuration File*
|
|
48
49
|
*
|
|
49
|
-
* A JSON
|
|
50
|
+
* A file (JSON by default, see {@link ConfigFormat}) where the structure matches {@link Values} and the defaults are stored
|
|
50
51
|
* under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
|
|
51
52
|
* (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
|
|
52
53
|
* command {@link Values}. As an example:
|
|
@@ -77,7 +78,12 @@ class ConfigurationServiceImpl {
|
|
|
77
78
|
* }
|
|
78
79
|
* ```
|
|
79
80
|
*
|
|
80
|
-
* The
|
|
81
|
+
* The syntax of the file is set by the `configFormat` constructor argument: JSON (the default), or YAML or TOML
|
|
82
|
+
* from the `yaml` and `toml` entry points of this package. The format is never inferred from the file name or
|
|
83
|
+
* extension and existing files are not migrated between formats. For YAML and TOML, comments and layout in the
|
|
84
|
+
* existing file are preserved when it is written back.
|
|
85
|
+
*
|
|
86
|
+
* The default location of the configuration file is `$HOME/.<application_name>.<format extension>`. If `$HOME` is not defined no
|
|
81
87
|
* default configuration will be used. The location of the configuration file can be modified via the
|
|
82
88
|
* {@link ConfigCommand}.
|
|
83
89
|
*
|
|
@@ -132,8 +138,11 @@ export default class ConfigurationServiceProvider {
|
|
|
132
138
|
envVarsEnabled;
|
|
133
139
|
configEnabled;
|
|
134
140
|
secretServiceEnabled;
|
|
141
|
+
configFormat;
|
|
135
142
|
// the location of the currently managed configuration data
|
|
136
143
|
configLocation;
|
|
144
|
+
// the format specific handle for the text last read or written, used to preserve comments and layout on write
|
|
145
|
+
#configHandle;
|
|
137
146
|
// the configuration data to be used by the CLI runner implementation when setting command defaults.
|
|
138
147
|
// SingleValueType is for GlobalCommandArgument values, Values is for
|
|
139
148
|
// SubCommandArgument values.
|
|
@@ -162,8 +171,9 @@ export default class ConfigurationServiceProvider {
|
|
|
162
171
|
* @param configEnabled optionally enable configuration file support for default argument values.
|
|
163
172
|
* @param secretServiceEnabled optionally enable OS-native secret storage via Bun.secrets for resolving
|
|
164
173
|
* secrets embedded in default argument values: `configEnabled` must be true in this case
|
|
174
|
+
* @param configFormat optionally set the syntax of the configuration file, defaults to JSON.
|
|
165
175
|
*/
|
|
166
|
-
constructor(servicePriority, envVarsEnabled = false, configEnabled = false, secretServiceEnabled = false) {
|
|
176
|
+
constructor(servicePriority, envVarsEnabled = false, configEnabled = false, secretServiceEnabled = false, configFormat = jsonFormat) {
|
|
167
177
|
if (!configEnabled && secretServiceEnabled) {
|
|
168
178
|
throw new Error("configEnabled must be true if secretServiceEnabled is true");
|
|
169
179
|
}
|
|
@@ -171,6 +181,7 @@ export default class ConfigurationServiceProvider {
|
|
|
171
181
|
this.envVarsEnabled = envVarsEnabled;
|
|
172
182
|
this.configEnabled = configEnabled;
|
|
173
183
|
this.secretServiceEnabled = secretServiceEnabled;
|
|
184
|
+
this.configFormat = configFormat;
|
|
174
185
|
this.#configurationService = new ConfigurationServiceImpl(this);
|
|
175
186
|
}
|
|
176
187
|
getServiceInfo(cliConfig) {
|
|
@@ -284,10 +295,10 @@ export default class ConfigurationServiceProvider {
|
|
|
284
295
|
let isDefault = false;
|
|
285
296
|
if (this.configLocation === undefined) {
|
|
286
297
|
isDefault = true;
|
|
287
|
-
// default to `$HOME/.<application_name
|
|
298
|
+
// default to `$HOME/.<application_name>.<format extension>`
|
|
288
299
|
const home = process.env["HOME"];
|
|
289
300
|
if (home) {
|
|
290
|
-
this.configLocation = path.join(home, `.${context.cliConfig.name.replace(/\W/g, "")}.
|
|
301
|
+
this.configLocation = path.join(home, `.${context.cliConfig.name.replace(/\W/g, "")}.${this.configFormat.fileExtension}`);
|
|
291
302
|
}
|
|
292
303
|
}
|
|
293
304
|
if (this.configLocation === undefined) {
|
|
@@ -316,10 +327,8 @@ export default class ConfigurationServiceProvider {
|
|
|
316
327
|
try {
|
|
317
328
|
logger.debug("Reading config from: %s", location);
|
|
318
329
|
const data = await fs.readFile(location);
|
|
319
|
-
const config =
|
|
320
|
-
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
330
|
+
const { data: config, handle } = this.configFormat.parse(data.toString());
|
|
331
|
+
this.#configHandle = handle;
|
|
323
332
|
this.defaultsData.clear();
|
|
324
333
|
this.#commandKeyValueData.clear();
|
|
325
334
|
this.#serviceKeyValueData.clear();
|
|
@@ -355,13 +364,21 @@ export default class ConfigurationServiceProvider {
|
|
|
355
364
|
async #writeConfig(location) {
|
|
356
365
|
logger.debug("Writing config to: %s", location);
|
|
357
366
|
try {
|
|
358
|
-
|
|
367
|
+
const config = this.#getConfigData();
|
|
368
|
+
const text = this.#configHandle === undefined
|
|
369
|
+
? this.configFormat.serialize(config)
|
|
370
|
+
: this.configFormat.apply(this.#configHandle, config);
|
|
371
|
+
await fs.writeFile(location, text);
|
|
372
|
+
this.#configHandle = this.configFormat.parse(text).handle;
|
|
359
373
|
}
|
|
360
374
|
catch (err) {
|
|
361
375
|
throw new Error(`Failed to write config at location: '${this.configLocation}': ${err}`);
|
|
362
376
|
}
|
|
363
377
|
}
|
|
364
378
|
getConfigString() {
|
|
379
|
+
return this.configFormat.serialize(this.#getConfigData());
|
|
380
|
+
}
|
|
381
|
+
#getConfigData() {
|
|
365
382
|
const config = {};
|
|
366
383
|
if (this.defaultsData.size > 0) {
|
|
367
384
|
config.defaults = Object.fromEntries(this.defaultsData);
|
|
@@ -385,6 +402,6 @@ export default class ConfigurationServiceProvider {
|
|
|
385
402
|
}
|
|
386
403
|
}
|
|
387
404
|
}
|
|
388
|
-
return
|
|
405
|
+
return config;
|
|
389
406
|
}
|
|
390
407
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The top level structure of a configuration file: `defaults` and `key-values` objects.
|
|
3
|
+
*/
|
|
4
|
+
export type ConfigData = Record<string, any>;
|
|
5
|
+
/**
|
|
6
|
+
* Defines the on-disk syntax of the CLI configuration file.
|
|
7
|
+
*
|
|
8
|
+
* The built-in implementation is JSON (the default). YAML and TOML implementations are available
|
|
9
|
+
* from the `@flowscripter/dynamic-cli-framework/yaml` and `@flowscripter/dynamic-cli-framework/toml`
|
|
10
|
+
* entry points. Third party formats can be supplied by implementing this interface.
|
|
11
|
+
*/
|
|
12
|
+
export default interface ConfigFormat {
|
|
13
|
+
/**
|
|
14
|
+
* The extension (without the leading dot) used for the default configuration file name,
|
|
15
|
+
* e.g. `json`.
|
|
16
|
+
*/
|
|
17
|
+
readonly fileExtension: string;
|
|
18
|
+
/**
|
|
19
|
+
* Parse configuration file text.
|
|
20
|
+
*
|
|
21
|
+
* @returns the parsed `data` and an opaque `handle` retaining whatever the format needs to write
|
|
22
|
+
* changes back while preserving comments and layout (`undefined` if the format has nothing to retain).
|
|
23
|
+
* @throws if the text is not valid for this format.
|
|
24
|
+
*/
|
|
25
|
+
parse(text: string): {
|
|
26
|
+
data: ConfigData;
|
|
27
|
+
handle: unknown;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Produce updated file text from a `handle` returned by {@link parse}.
|
|
31
|
+
*
|
|
32
|
+
* @param handle the handle returned by {@link parse} for the text being updated.
|
|
33
|
+
* @param changes the complete updated configuration data. The format reconciles the existing text
|
|
34
|
+
* with it, leaving unchanged content (including comments) untouched.
|
|
35
|
+
*/
|
|
36
|
+
apply(handle: unknown, changes: ConfigData): string;
|
|
37
|
+
/**
|
|
38
|
+
* Produce new file text from scratch.
|
|
39
|
+
*/
|
|
40
|
+
serialize(data: ConfigData): string;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=ConfigFormat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigFormat.d.ts","sourceRoot":"","sources":["../../../../../src/service/configuration/format/ConfigFormat.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,WAAW,YAAY;IACnC;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAE3D;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,MAAM,CAAC;IAEpD;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;CACrC"}
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type ConfigFormat from "./ConfigFormat.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The built-in JSON {@link ConfigFormat}. The file is regenerated on write: JSON has no comments to preserve.
|
|
4
|
+
*/
|
|
5
|
+
declare const jsonFormat: ConfigFormat;
|
|
6
|
+
export default jsonFormat;
|
|
7
|
+
//# sourceMappingURL=JsonConfigFormat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonConfigFormat.d.ts","sourceRoot":"","sources":["../../../../../src/service/configuration/format/JsonConfigFormat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAOlD;;GAEG;AACH,QAAA,MAAM,UAAU,EAAE,YASjB,CAAC;eAEa,UAAU"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function serialize(data) {
|
|
2
|
+
return JSON.stringify(data, null, 2);
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* The built-in JSON {@link ConfigFormat}. The file is regenerated on write: JSON has no comments to preserve.
|
|
6
|
+
*/
|
|
7
|
+
const jsonFormat = {
|
|
8
|
+
fileExtension: "json",
|
|
9
|
+
parse(text) {
|
|
10
|
+
return { data: JSON.parse(text), handle: undefined };
|
|
11
|
+
},
|
|
12
|
+
apply(_handle, changes) {
|
|
13
|
+
return serialize(changes);
|
|
14
|
+
},
|
|
15
|
+
serialize,
|
|
16
|
+
};
|
|
17
|
+
export default jsonFormat;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type ConfigFormat from "./ConfigFormat.ts";
|
|
2
|
+
/**
|
|
3
|
+
* A TOML {@link ConfigFormat} which preserves comments, whitespace and layout when writing changes back.
|
|
4
|
+
* Dates and times are not supported as configuration values.
|
|
5
|
+
*
|
|
6
|
+
* Requires the optional `@decimalturn/toml-patch` peer dependency.
|
|
7
|
+
*/
|
|
8
|
+
declare const tomlFormat: ConfigFormat;
|
|
9
|
+
export default tomlFormat;
|
|
10
|
+
//# sourceMappingURL=TomlConfigFormat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TomlConfigFormat.d.ts","sourceRoot":"","sources":["../../../../../src/service/configuration/format/TomlConfigFormat.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAoElD;;;;;GAKG;AACH,QAAA,MAAM,UAAU,EAAE,YAajB,CAAC;eAEa,UAAU"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
import { parse, patch, stringify } from "@decimalturn/toml-patch";
|
|
3
|
+
// new tables nested deeper than this (e.g. `defaults.<command>.<option>`) are left to patch() to
|
|
4
|
+
// lay out as inline tables
|
|
5
|
+
const MAX_TABLE_HEADER_DEPTH = 3;
|
|
6
|
+
function isPlainObject(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function formatKey(key) {
|
|
10
|
+
return /^[A-Za-z0-9_-]+$/.test(key) ? key : JSON.stringify(key);
|
|
11
|
+
}
|
|
12
|
+
function collectNewTables(existing, updated, path, newTables) {
|
|
13
|
+
for (const [key, value] of Object.entries(updated)) {
|
|
14
|
+
if (!isPlainObject(value) || path.length + 1 > MAX_TABLE_HEADER_DEPTH) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const childPath = [...path, key];
|
|
18
|
+
const existingChild = isPlainObject(existing) ? existing[key] : undefined;
|
|
19
|
+
if (existingChild === undefined) {
|
|
20
|
+
newTables.push(childPath);
|
|
21
|
+
}
|
|
22
|
+
collectNewTables(existingChild, value, childPath, newTables);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// parse() results do not share prototypes with plain objects
|
|
26
|
+
function plain(value) {
|
|
27
|
+
return JSON.parse(JSON.stringify(value));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Append an empty `[table]` header for every new table, so that patch() fills it in at the end
|
|
31
|
+
* of the file rather than hoisting it to the top as a dotted key. Returns the original text if the
|
|
32
|
+
* result is not equivalent to it plus the empty tables (e.g. the parent is an inline table which
|
|
33
|
+
* cannot be extended).
|
|
34
|
+
*/
|
|
35
|
+
function addNewTableHeaders(text, existing, changes) {
|
|
36
|
+
const newTables = [];
|
|
37
|
+
collectNewTables(existing, changes, [], newTables);
|
|
38
|
+
if (newTables.length === 0) {
|
|
39
|
+
return text;
|
|
40
|
+
}
|
|
41
|
+
const expected = structuredClone(existing);
|
|
42
|
+
for (const tablePath of newTables) {
|
|
43
|
+
let node = expected;
|
|
44
|
+
for (const key of tablePath.slice(0, -1)) {
|
|
45
|
+
node = (node[key] ??= {});
|
|
46
|
+
}
|
|
47
|
+
node[tablePath[tablePath.length - 1]] ??= {};
|
|
48
|
+
}
|
|
49
|
+
const headers = newTables.map((tablePath) => `[${tablePath.map(formatKey).join(".")}]`);
|
|
50
|
+
const withHeaders = `${text.trimEnd()}\n\n${headers.join("\n\n")}\n`;
|
|
51
|
+
try {
|
|
52
|
+
return isDeepStrictEqual(plain(parse(withHeaders)), plain(expected)) ? withHeaders : text;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return text;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A TOML {@link ConfigFormat} which preserves comments, whitespace and layout when writing changes back.
|
|
60
|
+
* Dates and times are not supported as configuration values.
|
|
61
|
+
*
|
|
62
|
+
* Requires the optional `@decimalturn/toml-patch` peer dependency.
|
|
63
|
+
*/
|
|
64
|
+
const tomlFormat = {
|
|
65
|
+
fileExtension: "toml",
|
|
66
|
+
parse(text) {
|
|
67
|
+
return { data: parse(text), handle: text };
|
|
68
|
+
},
|
|
69
|
+
apply(handle, changes) {
|
|
70
|
+
const text = handle;
|
|
71
|
+
const existing = parse(text);
|
|
72
|
+
return patch(addNewTableHeaders(text, existing, changes), changes);
|
|
73
|
+
},
|
|
74
|
+
serialize(data) {
|
|
75
|
+
return stringify(data);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
export default tomlFormat;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type ConfigFormat from "./ConfigFormat.ts";
|
|
2
|
+
/**
|
|
3
|
+
* A YAML {@link ConfigFormat} which preserves comments, blank lines and key order when writing changes back.
|
|
4
|
+
*
|
|
5
|
+
* Requires the optional `yaml` peer dependency.
|
|
6
|
+
*/
|
|
7
|
+
declare const yamlFormat: ConfigFormat;
|
|
8
|
+
export default yamlFormat;
|
|
9
|
+
//# sourceMappingURL=YamlConfigFormat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YamlConfigFormat.d.ts","sourceRoot":"","sources":["../../../../../src/service/configuration/format/YamlConfigFormat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAC;AAqClD;;;;GAIG;AACH,QAAA,MAAM,UAAU,EAAE,YA0BjB,CAAC;eAEa,UAAU"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Document, isMap, isSeq, parseDocument, stringify } from "yaml";
|
|
2
|
+
function isPlainObject(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function reconcile(doc, path, existing, updated) {
|
|
6
|
+
if (isPlainObject(existing) && isPlainObject(updated)) {
|
|
7
|
+
for (const key of Object.keys(existing)) {
|
|
8
|
+
if (!(key in updated)) {
|
|
9
|
+
doc.deleteIn([...path, key]);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
for (const key of Object.keys(updated)) {
|
|
13
|
+
if (key in existing) {
|
|
14
|
+
reconcile(doc, [...path, key], existing[key], updated[key]);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
doc.setIn([...path, key], updated[key]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else if (Array.isArray(existing) &&
|
|
22
|
+
Array.isArray(updated) &&
|
|
23
|
+
existing.length === updated.length) {
|
|
24
|
+
updated.forEach((value, index) => reconcile(doc, [...path, index], existing[index], value));
|
|
25
|
+
}
|
|
26
|
+
else if (JSON.stringify(existing) !== JSON.stringify(updated)) {
|
|
27
|
+
doc.setIn(path, updated);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A YAML {@link ConfigFormat} which preserves comments, blank lines and key order when writing changes back.
|
|
32
|
+
*
|
|
33
|
+
* Requires the optional `yaml` peer dependency.
|
|
34
|
+
*/
|
|
35
|
+
const yamlFormat = {
|
|
36
|
+
fileExtension: "yaml",
|
|
37
|
+
parse(text) {
|
|
38
|
+
const doc = parseDocument(text);
|
|
39
|
+
if (doc.errors.length > 0) {
|
|
40
|
+
throw new Error(doc.errors.map((error) => error.message).join("; "));
|
|
41
|
+
}
|
|
42
|
+
const data = doc.toJS() ?? {};
|
|
43
|
+
if (!isPlainObject(data)) {
|
|
44
|
+
throw new Error("top level YAML value must be a mapping");
|
|
45
|
+
}
|
|
46
|
+
return { data, handle: doc };
|
|
47
|
+
},
|
|
48
|
+
apply(handle, changes) {
|
|
49
|
+
const doc = handle;
|
|
50
|
+
const existing = doc.toJS() ?? {};
|
|
51
|
+
if (!isMap(doc.contents) && !isSeq(doc.contents)) {
|
|
52
|
+
doc.contents = doc.createNode(changes);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
reconcile(doc, [], existing, changes);
|
|
56
|
+
}
|
|
57
|
+
return doc.toString();
|
|
58
|
+
},
|
|
59
|
+
serialize(data) {
|
|
60
|
+
return stringify(data);
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
export default yamlFormat;
|
package/dist/toml.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toml.d.ts","sourceRoot":"","sources":["../toml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wDAAwD,CAAC"}
|
package/dist/toml.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as tomlFormat } from "./src/service/configuration/format/TomlConfigFormat.js";
|
package/dist/yaml.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../yaml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wDAAwD,CAAC"}
|
package/dist/yaml.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as yamlFormat } from "./src/service/configuration/format/YamlConfigFormat.js";
|
package/index.ts
CHANGED
|
@@ -68,6 +68,9 @@ export {
|
|
|
68
68
|
default as ConfigurationServiceProvider,
|
|
69
69
|
type KeyValueServiceScopeType,
|
|
70
70
|
} from "./src/service/configuration/ConfigurationServiceProvider.ts";
|
|
71
|
+
export type { default as ConfigFormat } from "./src/service/configuration/format/ConfigFormat.ts";
|
|
72
|
+
export type { ConfigData } from "./src/service/configuration/format/ConfigFormat.ts";
|
|
73
|
+
export { default as jsonFormat } from "./src/service/configuration/format/JsonConfigFormat.ts";
|
|
71
74
|
export { default as KeyValueServiceProvider } from "./src/service/configuration/KeyValueServiceProvider.ts";
|
|
72
75
|
|
|
73
76
|
export { PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowscripter/dynamic-cli-framework",
|
|
3
|
-
"version": "12.0
|
|
3
|
+
"version": "12.1.0",
|
|
4
4
|
"description": "A framework for developing CLI applications which supports dynamic discovery and installation of new commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"src",
|
|
23
23
|
"index.ts",
|
|
24
24
|
"cli-plugin.ts",
|
|
25
|
+
"yaml.ts",
|
|
26
|
+
"toml.ts",
|
|
25
27
|
"README.md",
|
|
26
28
|
"LICENSE"
|
|
27
29
|
],
|
|
@@ -40,6 +42,16 @@
|
|
|
40
42
|
"bun": "./cli-plugin.ts",
|
|
41
43
|
"types": "./dist/cli-plugin.d.ts",
|
|
42
44
|
"default": "./dist/cli-plugin.js"
|
|
45
|
+
},
|
|
46
|
+
"./yaml": {
|
|
47
|
+
"bun": "./yaml.ts",
|
|
48
|
+
"types": "./dist/yaml.d.ts",
|
|
49
|
+
"default": "./dist/yaml.js"
|
|
50
|
+
},
|
|
51
|
+
"./toml": {
|
|
52
|
+
"bun": "./toml.ts",
|
|
53
|
+
"types": "./dist/toml.d.ts",
|
|
54
|
+
"default": "./dist/toml.js"
|
|
43
55
|
}
|
|
44
56
|
},
|
|
45
57
|
"publishConfig": {
|
|
@@ -61,14 +73,26 @@
|
|
|
61
73
|
"supports-terminal-graphics": "^0.1.0"
|
|
62
74
|
},
|
|
63
75
|
"devDependencies": {
|
|
76
|
+
"@decimalturn/toml-patch": "^3.3.1",
|
|
64
77
|
"@types/bun": "^1.4.3",
|
|
65
78
|
"@types/node": "^26.6.5",
|
|
66
79
|
"@types/semver": "^7.8.0",
|
|
67
80
|
"oxfmt": "0.74.0",
|
|
68
|
-
"oxlint": "1.89.0"
|
|
81
|
+
"oxlint": "1.89.0",
|
|
82
|
+
"yaml": "^2.9.1"
|
|
69
83
|
},
|
|
70
84
|
"peerDependencies": {
|
|
71
|
-
"
|
|
85
|
+
"@decimalturn/toml-patch": "^3.3.1",
|
|
86
|
+
"typescript": "^7.0.2",
|
|
87
|
+
"yaml": "^2.9.1"
|
|
88
|
+
},
|
|
89
|
+
"peerDependenciesMeta": {
|
|
90
|
+
"yaml": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"@decimalturn/toml-patch": {
|
|
94
|
+
"optional": true
|
|
95
|
+
}
|
|
72
96
|
},
|
|
73
97
|
"typedocOptions": {
|
|
74
98
|
"readme": "none",
|
package/src/cli/BaseCLI.ts
CHANGED
|
@@ -31,6 +31,7 @@ import ShutdownServiceProvider from "../service/shutdown/ShutdownServiceProvider
|
|
|
31
31
|
import StartupServiceProvider from "../service/startup/StartupServiceProvider.ts";
|
|
32
32
|
import type { StartupTask } from "@flowscripter/dynamic-cli-framework-api";
|
|
33
33
|
import { shutdownState } from "../service/shutdown/ShutdownState.ts";
|
|
34
|
+
import jsonFormat from "../service/configuration/format/JsonConfigFormat.ts";
|
|
34
35
|
import ConfigurationServiceProvider from "../service/configuration/ConfigurationServiceProvider.ts";
|
|
35
36
|
import KeyValueServiceProvider from "../service/configuration/KeyValueServiceProvider.ts";
|
|
36
37
|
import PrinterServiceProvider from "../service/printer/PrinterServiceProvider.ts";
|
|
@@ -162,6 +163,7 @@ export default class BaseCLI implements CLI {
|
|
|
162
163
|
}
|
|
163
164
|
this.#cliConfig = cliConfig;
|
|
164
165
|
this.#options = {
|
|
166
|
+
configFormat: jsonFormat,
|
|
165
167
|
configFileSupportEnabled: false,
|
|
166
168
|
envVarsSupportEnabled: false,
|
|
167
169
|
keyValueServiceEnabled: false,
|
|
@@ -392,6 +394,7 @@ export default class BaseCLI implements CLI {
|
|
|
392
394
|
this.#options.envVarsSupportEnabled,
|
|
393
395
|
this.#options.configFileSupportEnabled,
|
|
394
396
|
this.#options.secretServiceEnabled,
|
|
397
|
+
this.#options.configFormat,
|
|
395
398
|
);
|
|
396
399
|
this.addServiceProvider(configurationServiceProvider);
|
|
397
400
|
const keyValueServiceProvider = new KeyValueServiceProvider(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type ConfigFormat from "../service/configuration/format/ConfigFormat.ts";
|
|
1
2
|
import type { UpgradeLocationsConfig } from "../service/upgrade/UpgradeLocationsConfig.ts";
|
|
2
3
|
import type {
|
|
3
4
|
NpmjsPluginRepositoryConfig,
|
|
@@ -6,6 +7,11 @@ import type {
|
|
|
6
7
|
|
|
7
8
|
export default interface BaseCLIFeatureOptions {
|
|
8
9
|
readonly configFileSupportEnabled?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* The syntax of the configuration file. Defaults to JSON. YAML and TOML are available from the
|
|
12
|
+
* `@flowscripter/dynamic-cli-framework/yaml` and `@flowscripter/dynamic-cli-framework/toml` entry points.
|
|
13
|
+
*/
|
|
14
|
+
readonly configFormat?: ConfigFormat;
|
|
9
15
|
readonly envVarsSupportEnabled?: boolean;
|
|
10
16
|
readonly keyValueServiceEnabled?: boolean;
|
|
11
17
|
readonly secretServiceEnabled?: boolean;
|
|
@@ -22,6 +22,9 @@ import {
|
|
|
22
22
|
} from "@flowscripter/dynamic-cli-framework-api";
|
|
23
23
|
import type { ConfigurationService } from "@flowscripter/dynamic-cli-framework-api";
|
|
24
24
|
import DefaultSecretService from "./DefaultSecretService.ts";
|
|
25
|
+
import type ConfigFormat from "./format/ConfigFormat.ts";
|
|
26
|
+
import type { ConfigData } from "./format/ConfigFormat.ts";
|
|
27
|
+
import jsonFormat from "./format/JsonConfigFormat.ts";
|
|
25
28
|
import resolveSecrets from "./resolveSecrets.ts";
|
|
26
29
|
import type { Command } from "@flowscripter/dynamic-cli-framework-api";
|
|
27
30
|
import argumentValueMerge from "../../runtime/values/argumentValueMerge.ts";
|
|
@@ -77,7 +80,7 @@ class ConfigurationServiceImpl implements ConfigurationService {
|
|
|
77
80
|
*
|
|
78
81
|
* *Configuration File*
|
|
79
82
|
*
|
|
80
|
-
* A JSON
|
|
83
|
+
* A file (JSON by default, see {@link ConfigFormat}) where the structure matches {@link Values} and the defaults are stored
|
|
81
84
|
* under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
|
|
82
85
|
* (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
|
|
83
86
|
* command {@link Values}. As an example:
|
|
@@ -108,7 +111,12 @@ class ConfigurationServiceImpl implements ConfigurationService {
|
|
|
108
111
|
* }
|
|
109
112
|
* ```
|
|
110
113
|
*
|
|
111
|
-
* The
|
|
114
|
+
* The syntax of the file is set by the `configFormat` constructor argument: JSON (the default), or YAML or TOML
|
|
115
|
+
* from the `yaml` and `toml` entry points of this package. The format is never inferred from the file name or
|
|
116
|
+
* extension and existing files are not migrated between formats. For YAML and TOML, comments and layout in the
|
|
117
|
+
* existing file are preserved when it is written back.
|
|
118
|
+
*
|
|
119
|
+
* The default location of the configuration file is `$HOME/.<application_name>.<format extension>`. If `$HOME` is not defined no
|
|
112
120
|
* default configuration will be used. The location of the configuration file can be modified via the
|
|
113
121
|
* {@link ConfigCommand}.
|
|
114
122
|
*
|
|
@@ -164,10 +172,14 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
164
172
|
public readonly envVarsEnabled: boolean;
|
|
165
173
|
public readonly configEnabled: boolean;
|
|
166
174
|
public readonly secretServiceEnabled: boolean;
|
|
175
|
+
public readonly configFormat: ConfigFormat;
|
|
167
176
|
|
|
168
177
|
// the location of the currently managed configuration data
|
|
169
178
|
public configLocation: string | undefined;
|
|
170
179
|
|
|
180
|
+
// the format specific handle for the text last read or written, used to preserve comments and layout on write
|
|
181
|
+
#configHandle: unknown;
|
|
182
|
+
|
|
171
183
|
// the configuration data to be used by the CLI runner implementation when setting command defaults.
|
|
172
184
|
// SingleValueType is for GlobalCommandArgument values, Values is for
|
|
173
185
|
// SubCommandArgument values.
|
|
@@ -200,12 +212,14 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
200
212
|
* @param configEnabled optionally enable configuration file support for default argument values.
|
|
201
213
|
* @param secretServiceEnabled optionally enable OS-native secret storage via Bun.secrets for resolving
|
|
202
214
|
* secrets embedded in default argument values: `configEnabled` must be true in this case
|
|
215
|
+
* @param configFormat optionally set the syntax of the configuration file, defaults to JSON.
|
|
203
216
|
*/
|
|
204
217
|
public constructor(
|
|
205
218
|
servicePriority: number,
|
|
206
219
|
envVarsEnabled = false,
|
|
207
220
|
configEnabled = false,
|
|
208
221
|
secretServiceEnabled = false,
|
|
222
|
+
configFormat: ConfigFormat = jsonFormat,
|
|
209
223
|
) {
|
|
210
224
|
if (!configEnabled && secretServiceEnabled) {
|
|
211
225
|
throw new Error("configEnabled must be true if secretServiceEnabled is true");
|
|
@@ -214,6 +228,7 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
214
228
|
this.envVarsEnabled = envVarsEnabled;
|
|
215
229
|
this.configEnabled = configEnabled;
|
|
216
230
|
this.secretServiceEnabled = secretServiceEnabled;
|
|
231
|
+
this.configFormat = configFormat;
|
|
217
232
|
|
|
218
233
|
this.#configurationService = new ConfigurationServiceImpl(this);
|
|
219
234
|
}
|
|
@@ -355,10 +370,13 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
355
370
|
let isDefault = false;
|
|
356
371
|
if (this.configLocation === undefined) {
|
|
357
372
|
isDefault = true;
|
|
358
|
-
// default to `$HOME/.<application_name
|
|
373
|
+
// default to `$HOME/.<application_name>.<format extension>`
|
|
359
374
|
const home = process.env["HOME"];
|
|
360
375
|
if (home) {
|
|
361
|
-
this.configLocation = path.join(
|
|
376
|
+
this.configLocation = path.join(
|
|
377
|
+
home,
|
|
378
|
+
`.${context.cliConfig.name.replace(/\W/g, "")}.${this.configFormat.fileExtension}`,
|
|
379
|
+
);
|
|
362
380
|
}
|
|
363
381
|
}
|
|
364
382
|
if (this.configLocation === undefined) {
|
|
@@ -396,11 +414,9 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
396
414
|
logger.debug("Reading config from: %s", location);
|
|
397
415
|
|
|
398
416
|
const data = await fs.readFile(location);
|
|
399
|
-
const config =
|
|
417
|
+
const { data: config, handle } = this.configFormat.parse(data.toString());
|
|
418
|
+
this.#configHandle = handle;
|
|
400
419
|
|
|
401
|
-
if (config === undefined) {
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
420
|
this.defaultsData.clear();
|
|
405
421
|
this.#commandKeyValueData.clear();
|
|
406
422
|
this.#serviceKeyValueData.clear();
|
|
@@ -443,13 +459,23 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
443
459
|
logger.debug("Writing config to: %s", location);
|
|
444
460
|
|
|
445
461
|
try {
|
|
446
|
-
|
|
462
|
+
const config = this.#getConfigData();
|
|
463
|
+
const text =
|
|
464
|
+
this.#configHandle === undefined
|
|
465
|
+
? this.configFormat.serialize(config)
|
|
466
|
+
: this.configFormat.apply(this.#configHandle, config);
|
|
467
|
+
await fs.writeFile(location, text);
|
|
468
|
+
this.#configHandle = this.configFormat.parse(text).handle;
|
|
447
469
|
} catch (err) {
|
|
448
470
|
throw new Error(`Failed to write config at location: '${this.configLocation}': ${err}`);
|
|
449
471
|
}
|
|
450
472
|
}
|
|
451
473
|
|
|
452
474
|
public getConfigString(): string {
|
|
475
|
+
return this.configFormat.serialize(this.#getConfigData());
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
#getConfigData(): ConfigData {
|
|
453
479
|
const config: {
|
|
454
480
|
defaults?: Record<string, Values | SingleValueType>;
|
|
455
481
|
"key-values"?: {
|
|
@@ -480,6 +506,6 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
|
|
|
480
506
|
}
|
|
481
507
|
}
|
|
482
508
|
}
|
|
483
|
-
return
|
|
509
|
+
return config;
|
|
484
510
|
}
|
|
485
511
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The top level structure of a configuration file: `defaults` and `key-values` objects.
|
|
3
|
+
*/
|
|
4
|
+
export type ConfigData = Record<string, any>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Defines the on-disk syntax of the CLI configuration file.
|
|
8
|
+
*
|
|
9
|
+
* The built-in implementation is JSON (the default). YAML and TOML implementations are available
|
|
10
|
+
* from the `@flowscripter/dynamic-cli-framework/yaml` and `@flowscripter/dynamic-cli-framework/toml`
|
|
11
|
+
* entry points. Third party formats can be supplied by implementing this interface.
|
|
12
|
+
*/
|
|
13
|
+
export default interface ConfigFormat {
|
|
14
|
+
/**
|
|
15
|
+
* The extension (without the leading dot) used for the default configuration file name,
|
|
16
|
+
* e.g. `json`.
|
|
17
|
+
*/
|
|
18
|
+
readonly fileExtension: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Parse configuration file text.
|
|
22
|
+
*
|
|
23
|
+
* @returns the parsed `data` and an opaque `handle` retaining whatever the format needs to write
|
|
24
|
+
* changes back while preserving comments and layout (`undefined` if the format has nothing to retain).
|
|
25
|
+
* @throws if the text is not valid for this format.
|
|
26
|
+
*/
|
|
27
|
+
parse(text: string): { data: ConfigData; handle: unknown };
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Produce updated file text from a `handle` returned by {@link parse}.
|
|
31
|
+
*
|
|
32
|
+
* @param handle the handle returned by {@link parse} for the text being updated.
|
|
33
|
+
* @param changes the complete updated configuration data. The format reconciles the existing text
|
|
34
|
+
* with it, leaving unchanged content (including comments) untouched.
|
|
35
|
+
*/
|
|
36
|
+
apply(handle: unknown, changes: ConfigData): string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Produce new file text from scratch.
|
|
40
|
+
*/
|
|
41
|
+
serialize(data: ConfigData): string;
|
|
42
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type ConfigFormat from "./ConfigFormat.ts";
|
|
2
|
+
import type { ConfigData } from "./ConfigFormat.ts";
|
|
3
|
+
|
|
4
|
+
function serialize(data: ConfigData): string {
|
|
5
|
+
return JSON.stringify(data, null, 2);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The built-in JSON {@link ConfigFormat}. The file is regenerated on write: JSON has no comments to preserve.
|
|
10
|
+
*/
|
|
11
|
+
const jsonFormat: ConfigFormat = {
|
|
12
|
+
fileExtension: "json",
|
|
13
|
+
parse(text: string) {
|
|
14
|
+
return { data: JSON.parse(text) as ConfigData, handle: undefined };
|
|
15
|
+
},
|
|
16
|
+
apply(_handle: unknown, changes: ConfigData): string {
|
|
17
|
+
return serialize(changes);
|
|
18
|
+
},
|
|
19
|
+
serialize,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default jsonFormat;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
import { parse, patch, stringify } from "@decimalturn/toml-patch";
|
|
3
|
+
import type ConfigFormat from "./ConfigFormat.ts";
|
|
4
|
+
import type { ConfigData } from "./ConfigFormat.ts";
|
|
5
|
+
|
|
6
|
+
// new tables nested deeper than this (e.g. `defaults.<command>.<option>`) are left to patch() to
|
|
7
|
+
// lay out as inline tables
|
|
8
|
+
const MAX_TABLE_HEADER_DEPTH = 3;
|
|
9
|
+
|
|
10
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function formatKey(key: string): string {
|
|
15
|
+
return /^[A-Za-z0-9_-]+$/.test(key) ? key : JSON.stringify(key);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function collectNewTables(
|
|
19
|
+
existing: unknown,
|
|
20
|
+
updated: Record<string, unknown>,
|
|
21
|
+
path: Array<string>,
|
|
22
|
+
newTables: Array<Array<string>>,
|
|
23
|
+
): void {
|
|
24
|
+
for (const [key, value] of Object.entries(updated)) {
|
|
25
|
+
if (!isPlainObject(value) || path.length + 1 > MAX_TABLE_HEADER_DEPTH) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const childPath = [...path, key];
|
|
29
|
+
const existingChild = isPlainObject(existing) ? existing[key] : undefined;
|
|
30
|
+
if (existingChild === undefined) {
|
|
31
|
+
newTables.push(childPath);
|
|
32
|
+
}
|
|
33
|
+
collectNewTables(existingChild, value, childPath, newTables);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// parse() results do not share prototypes with plain objects
|
|
38
|
+
function plain(value: unknown): unknown {
|
|
39
|
+
return JSON.parse(JSON.stringify(value));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Append an empty `[table]` header for every new table, so that patch() fills it in at the end
|
|
44
|
+
* of the file rather than hoisting it to the top as a dotted key. Returns the original text if the
|
|
45
|
+
* result is not equivalent to it plus the empty tables (e.g. the parent is an inline table which
|
|
46
|
+
* cannot be extended).
|
|
47
|
+
*/
|
|
48
|
+
function addNewTableHeaders(text: string, existing: ConfigData, changes: ConfigData): string {
|
|
49
|
+
const newTables: Array<Array<string>> = [];
|
|
50
|
+
collectNewTables(existing, changes, [], newTables);
|
|
51
|
+
if (newTables.length === 0) {
|
|
52
|
+
return text;
|
|
53
|
+
}
|
|
54
|
+
const expected = structuredClone(existing);
|
|
55
|
+
for (const tablePath of newTables) {
|
|
56
|
+
let node = expected;
|
|
57
|
+
for (const key of tablePath.slice(0, -1)) {
|
|
58
|
+
node = (node[key] ??= {}) as ConfigData;
|
|
59
|
+
}
|
|
60
|
+
node[tablePath[tablePath.length - 1]!] ??= {};
|
|
61
|
+
}
|
|
62
|
+
const headers = newTables.map((tablePath) => `[${tablePath.map(formatKey).join(".")}]`);
|
|
63
|
+
const withHeaders = `${text.trimEnd()}\n\n${headers.join("\n\n")}\n`;
|
|
64
|
+
try {
|
|
65
|
+
return isDeepStrictEqual(plain(parse(withHeaders)), plain(expected)) ? withHeaders : text;
|
|
66
|
+
} catch {
|
|
67
|
+
return text;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* A TOML {@link ConfigFormat} which preserves comments, whitespace and layout when writing changes back.
|
|
73
|
+
* Dates and times are not supported as configuration values.
|
|
74
|
+
*
|
|
75
|
+
* Requires the optional `@decimalturn/toml-patch` peer dependency.
|
|
76
|
+
*/
|
|
77
|
+
const tomlFormat: ConfigFormat = {
|
|
78
|
+
fileExtension: "toml",
|
|
79
|
+
parse(text: string) {
|
|
80
|
+
return { data: parse(text) as ConfigData, handle: text };
|
|
81
|
+
},
|
|
82
|
+
apply(handle: unknown, changes: ConfigData): string {
|
|
83
|
+
const text = handle as string;
|
|
84
|
+
const existing = parse(text) as ConfigData;
|
|
85
|
+
return patch(addNewTableHeaders(text, existing, changes), changes);
|
|
86
|
+
},
|
|
87
|
+
serialize(data: ConfigData): string {
|
|
88
|
+
return stringify(data);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default tomlFormat;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Document, isMap, isSeq, parseDocument, stringify } from "yaml";
|
|
2
|
+
import type ConfigFormat from "./ConfigFormat.ts";
|
|
3
|
+
import type { ConfigData } from "./ConfigFormat.ts";
|
|
4
|
+
|
|
5
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
6
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function reconcile(
|
|
10
|
+
doc: Document,
|
|
11
|
+
path: Array<string | number>,
|
|
12
|
+
existing: unknown,
|
|
13
|
+
updated: unknown,
|
|
14
|
+
): void {
|
|
15
|
+
if (isPlainObject(existing) && isPlainObject(updated)) {
|
|
16
|
+
for (const key of Object.keys(existing)) {
|
|
17
|
+
if (!(key in updated)) {
|
|
18
|
+
doc.deleteIn([...path, key]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
for (const key of Object.keys(updated)) {
|
|
22
|
+
if (key in existing) {
|
|
23
|
+
reconcile(doc, [...path, key], existing[key], updated[key]);
|
|
24
|
+
} else {
|
|
25
|
+
doc.setIn([...path, key], updated[key]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} else if (
|
|
29
|
+
Array.isArray(existing) &&
|
|
30
|
+
Array.isArray(updated) &&
|
|
31
|
+
existing.length === updated.length
|
|
32
|
+
) {
|
|
33
|
+
updated.forEach((value, index) => reconcile(doc, [...path, index], existing[index], value));
|
|
34
|
+
} else if (JSON.stringify(existing) !== JSON.stringify(updated)) {
|
|
35
|
+
doc.setIn(path, updated);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A YAML {@link ConfigFormat} which preserves comments, blank lines and key order when writing changes back.
|
|
41
|
+
*
|
|
42
|
+
* Requires the optional `yaml` peer dependency.
|
|
43
|
+
*/
|
|
44
|
+
const yamlFormat: ConfigFormat = {
|
|
45
|
+
fileExtension: "yaml",
|
|
46
|
+
parse(text: string) {
|
|
47
|
+
const doc = parseDocument(text);
|
|
48
|
+
if (doc.errors.length > 0) {
|
|
49
|
+
throw new Error(doc.errors.map((error) => error.message).join("; "));
|
|
50
|
+
}
|
|
51
|
+
const data = doc.toJS() ?? {};
|
|
52
|
+
if (!isPlainObject(data)) {
|
|
53
|
+
throw new Error("top level YAML value must be a mapping");
|
|
54
|
+
}
|
|
55
|
+
return { data, handle: doc };
|
|
56
|
+
},
|
|
57
|
+
apply(handle: unknown, changes: ConfigData): string {
|
|
58
|
+
const doc = handle as Document;
|
|
59
|
+
const existing = doc.toJS() ?? {};
|
|
60
|
+
if (!isMap(doc.contents) && !isSeq(doc.contents)) {
|
|
61
|
+
doc.contents = doc.createNode(changes);
|
|
62
|
+
} else {
|
|
63
|
+
reconcile(doc, [], existing, changes);
|
|
64
|
+
}
|
|
65
|
+
return doc.toString();
|
|
66
|
+
},
|
|
67
|
+
serialize(data: ConfigData): string {
|
|
68
|
+
return stringify(data);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default yamlFormat;
|
package/toml.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as tomlFormat } from "./src/service/configuration/format/TomlConfigFormat.ts";
|
package/yaml.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as yamlFormat } from "./src/service/configuration/format/YamlConfigFormat.ts";
|