@konker.dev/config-o-tron 0.0.1

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.
Files changed (243) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +131 -0
  3. package/dist/api.d.ts +24 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +44 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/cli.d.ts +8 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +267 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/delete.d.ts +22 -0
  12. package/dist/commands/delete.d.ts.map +1 -0
  13. package/dist/commands/delete.js +105 -0
  14. package/dist/commands/delete.js.map +1 -0
  15. package/dist/commands/delete.test.d.ts +2 -0
  16. package/dist/commands/delete.test.d.ts.map +1 -0
  17. package/dist/commands/delete.test.js +165 -0
  18. package/dist/commands/delete.test.js.map +1 -0
  19. package/dist/commands/export.d.ts +31 -0
  20. package/dist/commands/export.d.ts.map +1 -0
  21. package/dist/commands/export.js +117 -0
  22. package/dist/commands/export.js.map +1 -0
  23. package/dist/commands/export.test.d.ts +2 -0
  24. package/dist/commands/export.test.d.ts.map +1 -0
  25. package/dist/commands/export.test.js +173 -0
  26. package/dist/commands/export.test.js.map +1 -0
  27. package/dist/commands/index.d.ts +10 -0
  28. package/dist/commands/index.d.ts.map +1 -0
  29. package/dist/commands/index.js +10 -0
  30. package/dist/commands/index.js.map +1 -0
  31. package/dist/commands/list.d.ts +37 -0
  32. package/dist/commands/list.d.ts.map +1 -0
  33. package/dist/commands/list.js +107 -0
  34. package/dist/commands/list.js.map +1 -0
  35. package/dist/commands/list.test.d.ts +2 -0
  36. package/dist/commands/list.test.d.ts.map +1 -0
  37. package/dist/commands/list.test.js +275 -0
  38. package/dist/commands/list.test.js.map +1 -0
  39. package/dist/commands/snapshot.d.ts +67 -0
  40. package/dist/commands/snapshot.d.ts.map +1 -0
  41. package/dist/commands/snapshot.js +261 -0
  42. package/dist/commands/snapshot.js.map +1 -0
  43. package/dist/commands/snapshot.test.d.ts +2 -0
  44. package/dist/commands/snapshot.test.d.ts.map +1 -0
  45. package/dist/commands/snapshot.test.js +527 -0
  46. package/dist/commands/snapshot.test.js.map +1 -0
  47. package/dist/commands/upsert.d.ts +33 -0
  48. package/dist/commands/upsert.d.ts.map +1 -0
  49. package/dist/commands/upsert.js +98 -0
  50. package/dist/commands/upsert.js.map +1 -0
  51. package/dist/commands/upsert.test.d.ts +2 -0
  52. package/dist/commands/upsert.test.d.ts.map +1 -0
  53. package/dist/commands/upsert.test.js +184 -0
  54. package/dist/commands/upsert.test.js.map +1 -0
  55. package/dist/commands/validate.d.ts +23 -0
  56. package/dist/commands/validate.d.ts.map +1 -0
  57. package/dist/commands/validate.js +138 -0
  58. package/dist/commands/validate.js.map +1 -0
  59. package/dist/commands/validate.test.d.ts +2 -0
  60. package/dist/commands/validate.test.d.ts.map +1 -0
  61. package/dist/commands/validate.test.js +210 -0
  62. package/dist/commands/validate.test.js.map +1 -0
  63. package/dist/config.d.ts +75 -0
  64. package/dist/config.d.ts.map +1 -0
  65. package/dist/config.js +212 -0
  66. package/dist/config.js.map +1 -0
  67. package/dist/errors.d.ts +107 -0
  68. package/dist/errors.d.ts.map +1 -0
  69. package/dist/errors.js +362 -0
  70. package/dist/errors.js.map +1 -0
  71. package/dist/index.d.ts +10 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +8 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/lib/flatten.d.ts +84 -0
  76. package/dist/lib/flatten.d.ts.map +1 -0
  77. package/dist/lib/flatten.js +158 -0
  78. package/dist/lib/flatten.js.map +1 -0
  79. package/dist/lib/flatten.test.d.ts +2 -0
  80. package/dist/lib/flatten.test.d.ts.map +1 -0
  81. package/dist/lib/flatten.test.js +230 -0
  82. package/dist/lib/flatten.test.js.map +1 -0
  83. package/dist/lib/format.d.ts +41 -0
  84. package/dist/lib/format.d.ts.map +1 -0
  85. package/dist/lib/format.js +182 -0
  86. package/dist/lib/format.js.map +1 -0
  87. package/dist/lib/format.test.d.ts +2 -0
  88. package/dist/lib/format.test.d.ts.map +1 -0
  89. package/dist/lib/format.test.js +317 -0
  90. package/dist/lib/format.test.js.map +1 -0
  91. package/dist/lib/index.d.ts +8 -0
  92. package/dist/lib/index.d.ts.map +1 -0
  93. package/dist/lib/index.js +8 -0
  94. package/dist/lib/index.js.map +1 -0
  95. package/dist/lib/merge.d.ts +42 -0
  96. package/dist/lib/merge.d.ts.map +1 -0
  97. package/dist/lib/merge.js +167 -0
  98. package/dist/lib/merge.js.map +1 -0
  99. package/dist/lib/merge.test.d.ts +2 -0
  100. package/dist/lib/merge.test.d.ts.map +1 -0
  101. package/dist/lib/merge.test.js +218 -0
  102. package/dist/lib/merge.test.js.map +1 -0
  103. package/dist/lib/redact.d.ts +29 -0
  104. package/dist/lib/redact.d.ts.map +1 -0
  105. package/dist/lib/redact.js +77 -0
  106. package/dist/lib/redact.js.map +1 -0
  107. package/dist/lib/redact.test.d.ts +2 -0
  108. package/dist/lib/redact.test.d.ts.map +1 -0
  109. package/dist/lib/redact.test.js +192 -0
  110. package/dist/lib/redact.test.js.map +1 -0
  111. package/dist/providers/AwsSsmProvider.d.ts +3 -0
  112. package/dist/providers/AwsSsmProvider.d.ts.map +1 -0
  113. package/dist/providers/AwsSsmProvider.js +230 -0
  114. package/dist/providers/AwsSsmProvider.js.map +1 -0
  115. package/dist/providers/AwsSsmProvider.test.d.ts +5 -0
  116. package/dist/providers/AwsSsmProvider.test.d.ts.map +1 -0
  117. package/dist/providers/AwsSsmProvider.test.js +200 -0
  118. package/dist/providers/AwsSsmProvider.test.js.map +1 -0
  119. package/dist/providers/MockProvider.d.ts +21 -0
  120. package/dist/providers/MockProvider.d.ts.map +1 -0
  121. package/dist/providers/MockProvider.js +118 -0
  122. package/dist/providers/MockProvider.js.map +1 -0
  123. package/dist/providers/MockProvider.test.d.ts +2 -0
  124. package/dist/providers/MockProvider.test.d.ts.map +1 -0
  125. package/dist/providers/MockProvider.test.js +166 -0
  126. package/dist/providers/MockProvider.test.js.map +1 -0
  127. package/dist/providers/Provider.d.ts +95 -0
  128. package/dist/providers/Provider.d.ts.map +1 -0
  129. package/dist/providers/Provider.js +49 -0
  130. package/dist/providers/Provider.js.map +1 -0
  131. package/dist/providers/Provider.test.d.ts +2 -0
  132. package/dist/providers/Provider.test.d.ts.map +1 -0
  133. package/dist/providers/Provider.test.js +136 -0
  134. package/dist/providers/Provider.test.js.map +1 -0
  135. package/dist/providers/guards.d.ts +13 -0
  136. package/dist/providers/guards.d.ts.map +1 -0
  137. package/dist/providers/guards.js +60 -0
  138. package/dist/providers/guards.js.map +1 -0
  139. package/dist/providers/guards.test.d.ts +2 -0
  140. package/dist/providers/guards.test.d.ts.map +1 -0
  141. package/dist/providers/guards.test.js +84 -0
  142. package/dist/providers/guards.test.js.map +1 -0
  143. package/dist/providers/index.d.ts +8 -0
  144. package/dist/providers/index.d.ts.map +1 -0
  145. package/dist/providers/index.js +8 -0
  146. package/dist/providers/index.js.map +1 -0
  147. package/dist/providers/registry.d.ts +27 -0
  148. package/dist/providers/registry.d.ts.map +1 -0
  149. package/dist/providers/registry.js +50 -0
  150. package/dist/providers/registry.js.map +1 -0
  151. package/dist/providers/registry.test.d.ts +5 -0
  152. package/dist/providers/registry.test.d.ts.map +1 -0
  153. package/dist/providers/registry.test.js +89 -0
  154. package/dist/providers/registry.test.js.map +1 -0
  155. package/dist/schema/index.d.ts +8 -0
  156. package/dist/schema/index.d.ts.map +1 -0
  157. package/dist/schema/index.js +8 -0
  158. package/dist/schema/index.js.map +1 -0
  159. package/dist/schema/loader.d.ts +21 -0
  160. package/dist/schema/loader.d.ts.map +1 -0
  161. package/dist/schema/loader.js +68 -0
  162. package/dist/schema/loader.js.map +1 -0
  163. package/dist/schema/loader.test.d.ts +2 -0
  164. package/dist/schema/loader.test.d.ts.map +1 -0
  165. package/dist/schema/loader.test.js +111 -0
  166. package/dist/schema/loader.test.js.map +1 -0
  167. package/dist/schema/parser.d.ts +17 -0
  168. package/dist/schema/parser.d.ts.map +1 -0
  169. package/dist/schema/parser.js +55 -0
  170. package/dist/schema/parser.js.map +1 -0
  171. package/dist/schema/parser.test.d.ts +2 -0
  172. package/dist/schema/parser.test.d.ts.map +1 -0
  173. package/dist/schema/parser.test.js +62 -0
  174. package/dist/schema/parser.test.js.map +1 -0
  175. package/dist/schema/resolver.d.ts +16 -0
  176. package/dist/schema/resolver.d.ts.map +1 -0
  177. package/dist/schema/resolver.js +41 -0
  178. package/dist/schema/resolver.js.map +1 -0
  179. package/dist/schema/resolver.test.d.ts +2 -0
  180. package/dist/schema/resolver.test.d.ts.map +1 -0
  181. package/dist/schema/resolver.test.js +77 -0
  182. package/dist/schema/resolver.test.js.map +1 -0
  183. package/dist/schema/validator.d.ts +16 -0
  184. package/dist/schema/validator.d.ts.map +1 -0
  185. package/dist/schema/validator.js +21 -0
  186. package/dist/schema/validator.js.map +1 -0
  187. package/dist/schema/validator.test.d.ts +2 -0
  188. package/dist/schema/validator.test.d.ts.map +1 -0
  189. package/dist/schema/validator.test.js +40 -0
  190. package/dist/schema/validator.test.js.map +1 -0
  191. package/dist/test/fixtures/index.d.ts +39 -0
  192. package/dist/test/fixtures/index.d.ts.map +1 -0
  193. package/dist/test/fixtures/index.js +85 -0
  194. package/dist/test/fixtures/index.js.map +1 -0
  195. package/dist/test/fixtures/schema.basic.d.ts +16 -0
  196. package/dist/test/fixtures/schema.basic.d.ts.map +1 -0
  197. package/dist/test/fixtures/schema.basic.js +16 -0
  198. package/dist/test/fixtures/schema.basic.js.map +1 -0
  199. package/dist/test/fixtures/schema.basic.zod.d.ts +58 -0
  200. package/dist/test/fixtures/schema.basic.zod.d.ts.map +1 -0
  201. package/dist/test/fixtures/schema.basic.zod.js +16 -0
  202. package/dist/test/fixtures/schema.basic.zod.js.map +1 -0
  203. package/dist/validation/effect.d.ts +3 -0
  204. package/dist/validation/effect.d.ts.map +1 -0
  205. package/dist/validation/effect.js +368 -0
  206. package/dist/validation/effect.js.map +1 -0
  207. package/dist/validation/effect.test.d.ts +2 -0
  208. package/dist/validation/effect.test.d.ts.map +1 -0
  209. package/dist/validation/effect.test.js +137 -0
  210. package/dist/validation/effect.test.js.map +1 -0
  211. package/dist/validation/hash.d.ts +2 -0
  212. package/dist/validation/hash.d.ts.map +1 -0
  213. package/dist/validation/hash.js +27 -0
  214. package/dist/validation/hash.js.map +1 -0
  215. package/dist/validation/hash.test.d.ts +2 -0
  216. package/dist/validation/hash.test.d.ts.map +1 -0
  217. package/dist/validation/hash.test.js +25 -0
  218. package/dist/validation/hash.test.js.map +1 -0
  219. package/dist/validation/index.d.ts +7 -0
  220. package/dist/validation/index.d.ts.map +1 -0
  221. package/dist/validation/index.js +11 -0
  222. package/dist/validation/index.js.map +1 -0
  223. package/dist/validation/parse.d.ts +7 -0
  224. package/dist/validation/parse.d.ts.map +1 -0
  225. package/dist/validation/parse.js +44 -0
  226. package/dist/validation/parse.js.map +1 -0
  227. package/dist/validation/parse.test.d.ts +2 -0
  228. package/dist/validation/parse.test.d.ts.map +1 -0
  229. package/dist/validation/parse.test.js +47 -0
  230. package/dist/validation/parse.test.js.map +1 -0
  231. package/dist/validation/types.d.ts +33 -0
  232. package/dist/validation/types.d.ts.map +1 -0
  233. package/dist/validation/types.js +2 -0
  234. package/dist/validation/types.js.map +1 -0
  235. package/dist/validation/zod.d.ts +3 -0
  236. package/dist/validation/zod.d.ts.map +1 -0
  237. package/dist/validation/zod.js +326 -0
  238. package/dist/validation/zod.js.map +1 -0
  239. package/dist/validation/zod.test.d.ts +2 -0
  240. package/dist/validation/zod.test.d.ts.map +1 -0
  241. package/dist/validation/zod.test.js +161 -0
  242. package/dist/validation/zod.test.js.map +1 -0
  243. package/package.json +242 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2024 Konrad Markus <mail@konker.dev>
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12
+ SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14
+ OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15
+ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # Config-o-tron
2
+
3
+ CLI tool for configuration and secrets management using AWS SSM with a pluggable validation layer (Effect Schema or Zod).
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js 18+ (or a compatible runtime)
8
+ - pnpm
9
+ - AWS credentials and region configuration for the default `aws-ssm` provider
10
+
11
+ ## Setup
12
+
13
+ Install dependencies:
14
+
15
+ ```sh
16
+ pnpm install
17
+ ```
18
+
19
+ Build the CLI:
20
+
21
+ ```sh
22
+ pnpm run build
23
+ ```
24
+
25
+ ## Configure
26
+
27
+ Config-o-tron reads configuration from `config-o-tronrc.json` or `config-o-tronrc.json5` (searches current and parent directories) and
28
+ environment variables. Both files are parsed with JSON5, so comments and trailing commas are allowed.
29
+ Validation is pluggable; set `validation` to `effect` (default) or `zod`. Your schema file must export a single
30
+ `ConfigSchema` value that matches the selected validator.
31
+
32
+ Example `config-o-tronrc.json`:
33
+
34
+ ```json
35
+ {
36
+ "env": "dev",
37
+ "provider": "aws-ssm",
38
+ "ssmPrefix": "/config-o-tron",
39
+ "schema": "src/schema.ts",
40
+ "validation": "effect",
41
+ "providerGuards": {
42
+ "aws-ssm": {
43
+ "accountId": "123456789012",
44
+ "region": "us-east-1"
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ Provider guards are provider-specific safety checks that run before any provider operation. They can be bypassed with
51
+ `CONFIG_O_TRON_IGNORE_PROVIDER_GUARDS=1` for emergencies.
52
+ For `aws-ssm`, `accountId` is resolved from `AWS_ACCOUNT_ID` or STS `GetCallerIdentity`, and `region` is resolved
53
+ from `AWS_REGION`/`AWS_DEFAULT_REGION` or the AWS SDK client configuration.
54
+
55
+ Environment overrides:
56
+
57
+ - `CONFIG_O_TRON_ENV`
58
+ - `CONFIG_O_TRON_PROVIDER`
59
+ - `CONFIG_O_TRON_SSM_PREFIX`
60
+ - `CONFIG_O_TRON_SCHEMA`
61
+ - `CONFIG_O_TRON_VALIDATION`
62
+ - `CONFIG_O_TRON_FORMAT`
63
+ - `CONFIG_O_TRON_SEPARATOR`
64
+ - `CONFIG_O_TRON_CACHE`
65
+ - `CONFIG_O_TRON_CI`
66
+ - `CONFIG_O_TRON_IGNORE_PROVIDER_GUARDS`
67
+
68
+ ## Run
69
+
70
+ Show CLI help:
71
+
72
+ ```sh
73
+ pnpm run config-o-tron -- --help
74
+ ```
75
+
76
+ List keys for a service:
77
+
78
+ ```sh
79
+ pnpm run config-o-tron list <service>
80
+ ```
81
+
82
+ Export config for a service:
83
+
84
+ ```sh
85
+ pnpm run config-o-tron export <service>
86
+ ```
87
+
88
+ Use a different provider:
89
+
90
+ ```sh
91
+ CONFIG_O_TRON_PROVIDER=mock pnpm run config-o-tron list <service>
92
+ ```
93
+
94
+ ## Programmatic API (export-only)
95
+
96
+ Config-o-tron exposes a TypeScript API for export-only usage. It resolves configuration the same way as the CLI (rc file,
97
+ env vars, defaults), but lets you override values inline.
98
+
99
+ ```ts
100
+ import { exportConfig } from '@konker.dev/config-o-tron';
101
+
102
+ const result = await exportConfig({
103
+ service: 'api',
104
+ sources: ['shared'],
105
+ format: 'json',
106
+ config: {
107
+ env: 'prod',
108
+ provider: 'aws-ssm',
109
+ ssmPrefix: '/config-o-tron',
110
+ schema: 'src/schema.ts',
111
+ validation: 'effect',
112
+ },
113
+ });
114
+
115
+ // Structured config object
116
+ console.log(result.config);
117
+ ```
118
+
119
+ ## Development
120
+
121
+ Run tests:
122
+
123
+ ```sh
124
+ pnpm run test
125
+ ```
126
+
127
+ Lint:
128
+
129
+ ```sh
130
+ pnpm run lint-check
131
+ ```
package/dist/api.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Programmatic Export API
3
+ */
4
+ import './providers/index.js';
5
+ import { type ResolvedConfig } from './config.js';
6
+ import type { MergeConflict } from './lib/merge.js';
7
+ export type ExportApiOptions = {
8
+ readonly service: string;
9
+ readonly sources?: ReadonlyArray<string> | undefined;
10
+ readonly format?: 'env' | 'json' | undefined;
11
+ readonly separator?: string | undefined;
12
+ readonly strict?: boolean | undefined;
13
+ readonly strictMerge?: boolean | undefined;
14
+ readonly warnOnOverride?: boolean | undefined;
15
+ readonly config?: Partial<ResolvedConfig> | undefined;
16
+ };
17
+ export type ExportApiResult = {
18
+ readonly config: Record<string, unknown>;
19
+ readonly formatted: string;
20
+ readonly conflicts: ReadonlyArray<MergeConflict>;
21
+ readonly warnings: ReadonlyArray<string>;
22
+ };
23
+ export declare function exportConfig(options: ExportApiOptions): Promise<ExportApiResult>;
24
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,sBAAsB,CAAC;AAM9B,OAAO,EAAkC,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC1C,CAAC;AA+BF,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAkBtF"}
package/dist/api.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Programmatic Export API
3
+ */
4
+ import './providers/index.js';
5
+ import * as Effect from 'effect/Effect';
6
+ import { pipe } from 'effect/Function';
7
+ import { executeExport } from './commands/export.js';
8
+ import { resolveConfig } from './config.js';
9
+ function buildCliOptions(options) {
10
+ const overrides = options.config;
11
+ return {
12
+ env: overrides?.env,
13
+ provider: overrides?.provider,
14
+ ssmPrefix: overrides?.ssmPrefix,
15
+ schema: overrides?.schema,
16
+ validation: overrides?.validation,
17
+ source: overrides?.sources,
18
+ format: options.format ?? overrides?.format,
19
+ separator: options.separator ?? overrides?.separator,
20
+ cache: overrides?.cache,
21
+ ci: overrides?.ci,
22
+ strict: options.strict ?? overrides?.strict,
23
+ };
24
+ }
25
+ function applyConfigOverrides(config, overrides) {
26
+ if (!overrides) {
27
+ return config;
28
+ }
29
+ return {
30
+ ...config,
31
+ providerGuards: overrides.providerGuards ?? config.providerGuards,
32
+ };
33
+ }
34
+ export async function exportConfig(options) {
35
+ const cliOptions = buildCliOptions(options);
36
+ return Effect.runPromise(pipe(resolveConfig(cliOptions), Effect.map((config) => applyConfigOverrides(config, options.config)), Effect.flatMap((config) => executeExport({
37
+ service: options.service,
38
+ sources: options.sources ?? config.sources,
39
+ config,
40
+ strictMerge: options.strictMerge,
41
+ warnOnOverride: options.warnOnOverride,
42
+ }))));
43
+ }
44
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,sBAAsB,CAAC;AAE9B,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAmB,aAAa,EAAuB,MAAM,aAAa,CAAC;AAqBlF,SAAS,eAAe,CAAC,OAAyB;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAEjC,OAAO;QACL,GAAG,EAAE,SAAS,EAAE,GAAG;QACnB,QAAQ,EAAE,SAAS,EAAE,QAAQ;QAC7B,SAAS,EAAE,SAAS,EAAE,SAAS;QAC/B,MAAM,EAAE,SAAS,EAAE,MAAM;QACzB,UAAU,EAAE,SAAS,EAAE,UAAU;QACjC,MAAM,EAAE,SAAS,EAAE,OAAO;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,MAAM;QAC3C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS,EAAE,SAAS;QACpD,KAAK,EAAE,SAAS,EAAE,KAAK;QACvB,EAAE,EAAE,SAAS,EAAE,EAAE;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,MAAM;KAC5C,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,MAAsB,EAAE,SAAmC;IACvF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO;QACL,GAAG,MAAM;QACT,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc;KAClE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAyB;IAC1D,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAE5C,OAAO,MAAM,CAAC,UAAU,CACtB,IAAI,CACF,aAAa,CAAC,UAAU,CAAC,EACzB,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EACpE,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACxB,aAAa,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO;QAC1C,MAAM;QACN,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CACH,CACF,CACF,CAAC;AACJ,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ConfigOTron CLI
4
+ *
5
+ * Configuration and secrets management tool
6
+ */
7
+ import './providers/index.js';
8
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AACH,OAAO,sBAAsB,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ConfigOTron CLI
4
+ *
5
+ * Configuration and secrets management tool
6
+ */
7
+ import './providers/index.js';
8
+ import { Command } from 'commander';
9
+ import * as Cause from 'effect/Cause';
10
+ import * as Effect from 'effect/Effect';
11
+ import * as Exit from 'effect/Exit';
12
+ import { pipe } from 'effect/Function';
13
+ import * as Option from 'effect/Option';
14
+ import { runDelete } from './commands/delete.js';
15
+ import { runExport } from './commands/export.js';
16
+ import { runList } from './commands/list.js';
17
+ import { runSnapshotRestore, runSnapshotSave } from './commands/snapshot.js';
18
+ import { runUpsert } from './commands/upsert.js';
19
+ import { runValidate } from './commands/validate.js';
20
+ import { resolveConfig } from './config.js';
21
+ import { EXIT_VALIDATION_ERROR, formatError } from './errors.js';
22
+ // --------------------------------------------------------------------------
23
+ // Error Handling
24
+ // --------------------------------------------------------------------------
25
+ const handleError = (error) => {
26
+ if (error && typeof error === 'object' && 'context' in error && '_tag' in error) {
27
+ // ConfigOTron error
28
+ console.error(formatError(error));
29
+ const exitCode = 'exitCode' in error ? error.exitCode : EXIT_VALIDATION_ERROR;
30
+ process.exit(exitCode);
31
+ }
32
+ if (error instanceof Error) {
33
+ console.error(`Error: ${error.message}`);
34
+ process.exit(EXIT_VALIDATION_ERROR);
35
+ }
36
+ console.error('Unknown error:', error);
37
+ process.exit(EXIT_VALIDATION_ERROR);
38
+ };
39
+ const runEffect = (effect) => {
40
+ Effect.runPromiseExit(effect)
41
+ .then((exit) => {
42
+ if (Exit.isSuccess(exit)) {
43
+ return;
44
+ }
45
+ const causeOpt = Exit.causeOption(exit);
46
+ const failure = pipe(causeOpt, Option.flatMap(Cause.failureOption), Option.getOrUndefined);
47
+ if (failure) {
48
+ handleError(failure);
49
+ return;
50
+ }
51
+ const prettyCause = pipe(causeOpt, Option.map(Cause.pretty), Option.getOrUndefined);
52
+ if (prettyCause) {
53
+ console.error(prettyCause);
54
+ process.exit(EXIT_VALIDATION_ERROR);
55
+ }
56
+ handleError(new Error('Unknown error'));
57
+ })
58
+ .catch(handleError);
59
+ };
60
+ // --------------------------------------------------------------------------
61
+ // CLI Setup
62
+ // --------------------------------------------------------------------------
63
+ const program = new Command();
64
+ program
65
+ .name('config-o-tron')
66
+ .description('Configuration and secrets management tool')
67
+ .version('0.0.1')
68
+ .option('--ci', 'Disable prompts; require explicit flags like --confirm')
69
+ .option('--strict', 'Treat warnings as errors');
70
+ // --------------------------------------------------------------------------
71
+ // Export Command
72
+ // --------------------------------------------------------------------------
73
+ program
74
+ .command('export <service>')
75
+ .description('Export configuration')
76
+ .option('--source <service>', 'Additional sources (repeatable)', (val, prev) => [...prev, val], [])
77
+ .option('--format <env|json>', 'Output format (default: env)')
78
+ .option('--provider <name>', 'Provider name (default: aws-ssm)')
79
+ .option('--env <environment>', 'Environment name')
80
+ .option('--separator <char>', 'Env key separator (default: _)')
81
+ .option('--strict-merge', 'Fail on type conflicts during merge')
82
+ .option('--warn-on-override', 'Log all key overrides')
83
+ .option('--cache <duration>', 'Cache provider fetches')
84
+ .option('--no-cache', 'Disable cache')
85
+ .option('--ssm-prefix <prefix>', 'SSM path prefix (default: /config-o-tron)')
86
+ .option('--schema <path>', 'Schema path')
87
+ .option('--validation <effect|zod>', 'Validation layer (default: effect)')
88
+ .action((service, options) => {
89
+ runEffect(pipe(resolveConfig({
90
+ ...options,
91
+ source: options.source,
92
+ ci: program.opts().ci,
93
+ strict: program.opts().strict,
94
+ }), Effect.flatMap((config) => runExport({
95
+ service,
96
+ sources: options.source,
97
+ config,
98
+ strictMerge: options.strictMerge,
99
+ warnOnOverride: options.warnOnOverride,
100
+ }))));
101
+ });
102
+ // --------------------------------------------------------------------------
103
+ // Upsert Command
104
+ // --------------------------------------------------------------------------
105
+ program
106
+ .command('upsert <service> <key> [value]')
107
+ .description('Upsert configuration value')
108
+ .option('--provider <name>', 'Provider name (default: aws-ssm)')
109
+ .option('--env <environment>', 'Environment name')
110
+ .option('--stdin', 'Read value from stdin')
111
+ .option('--type <auto|string|int|float|bool|json>', 'How to parse input')
112
+ .option('--skip-encryption-check', 'Skip encryption verification')
113
+ .option('--ssm-prefix <prefix>', 'SSM path prefix (default: /config-o-tron)')
114
+ .option('--schema <path>', 'Schema path')
115
+ .option('--validation <effect|zod>', 'Validation layer (default: effect)')
116
+ .action((service, key, value, options) => {
117
+ runEffect(pipe(resolveConfig({
118
+ ...options,
119
+ ci: program.opts().ci,
120
+ strict: program.opts().strict,
121
+ }), Effect.flatMap((config) => runUpsert({
122
+ service,
123
+ key,
124
+ value,
125
+ stdin: options.stdin,
126
+ type: options.type,
127
+ skipEncryptionCheck: options.skipEncryptionCheck,
128
+ config,
129
+ }))));
130
+ });
131
+ // --------------------------------------------------------------------------
132
+ // Validate Command
133
+ // --------------------------------------------------------------------------
134
+ program
135
+ .command('validate')
136
+ .description('Validate configuration file')
137
+ .requiredOption('--file <path>', 'Path to JSON or .env file')
138
+ .option('--schema <path>', 'Schema path')
139
+ .option('--format <env|json>', 'File format (auto-detected if not specified)')
140
+ .option('--validation <effect|zod>', 'Validation layer (default: effect)')
141
+ .action((options) => {
142
+ runEffect(pipe(resolveConfig({
143
+ ...options,
144
+ ci: program.opts().ci,
145
+ strict: program.opts().strict,
146
+ }), Effect.flatMap((config) => runValidate({
147
+ file: options.file,
148
+ format: options.format,
149
+ config,
150
+ })), Effect.tap((valid) => Effect.sync(() => {
151
+ if (!valid) {
152
+ process.exit(EXIT_VALIDATION_ERROR);
153
+ }
154
+ }))));
155
+ });
156
+ // --------------------------------------------------------------------------
157
+ // List Command
158
+ // --------------------------------------------------------------------------
159
+ program
160
+ .command('list <service>')
161
+ .description('List configuration keys for a service')
162
+ .option('--provider <name>', 'Provider name (default: aws-ssm)')
163
+ .option('--env <environment>', 'Environment name')
164
+ .option('--format <keys|table|json>', 'Output format (default: keys)')
165
+ .option('--show-values', 'Print secret values (TTY only)')
166
+ .option('--unsafe-show-values', 'Allow printing secrets even when stdout is not a TTY')
167
+ .option('--ssm-prefix <prefix>', 'SSM path prefix (default: /config-o-tron)')
168
+ .action((service, options) => {
169
+ runEffect(pipe(resolveConfig({
170
+ ...options,
171
+ ci: program.opts().ci,
172
+ strict: program.opts().strict,
173
+ }), Effect.flatMap((config) => runList({
174
+ service,
175
+ format: options.format,
176
+ showValues: options.showValues,
177
+ unsafeShowValues: options.unsafeShowValues,
178
+ config,
179
+ }))));
180
+ });
181
+ // --------------------------------------------------------------------------
182
+ // Delete Command
183
+ // --------------------------------------------------------------------------
184
+ program
185
+ .command('delete <service> <key>')
186
+ .description('Delete configuration value')
187
+ .option('--provider <name>', 'Provider name (default: aws-ssm)')
188
+ .option('--env <environment>', 'Environment name')
189
+ .option('--confirm', 'Skip interactive confirmation')
190
+ .option('--ssm-prefix <prefix>', 'SSM path prefix (default: /config-o-tron)')
191
+ .option('--schema <path>', 'Schema path')
192
+ .option('--validation <effect|zod>', 'Validation layer (default: effect)')
193
+ .action((service, key, options) => {
194
+ runEffect(pipe(resolveConfig({
195
+ ...options,
196
+ ci: program.opts().ci,
197
+ strict: program.opts().strict,
198
+ }), Effect.flatMap((config) => runDelete({
199
+ service,
200
+ key,
201
+ confirm: options.confirm,
202
+ config,
203
+ }))));
204
+ });
205
+ // --------------------------------------------------------------------------
206
+ // Snapshot Commands
207
+ // --------------------------------------------------------------------------
208
+ const snapshotCmd = program.command('snapshot').description('Snapshot management');
209
+ snapshotCmd
210
+ .command('save <service>')
211
+ .description('Save configuration snapshot')
212
+ .option('--source <service>', 'Additional sources (repeatable)', (val, prev) => [...prev, val], [])
213
+ .option('--provider <name>', 'Provider name (default: aws-ssm)')
214
+ .option('--env <environment>', 'Environment name')
215
+ .option('--output <path>', 'Output path')
216
+ .option('--encrypt', 'Encrypt snapshot at rest')
217
+ .option('--snapshot-key-file <path>', 'Read encryption key from file')
218
+ .option('--ssm-prefix <prefix>', 'SSM path prefix (default: /config-o-tron)')
219
+ .option('--schema <path>', 'Schema path')
220
+ .option('--validation <effect|zod>', 'Validation layer (default: effect)')
221
+ .action((service, options) => {
222
+ runEffect(pipe(resolveConfig({
223
+ ...options,
224
+ source: options.source,
225
+ ci: program.opts().ci,
226
+ strict: program.opts().strict,
227
+ }), Effect.flatMap((config) => runSnapshotSave({
228
+ service,
229
+ sources: options.source,
230
+ output: options.output,
231
+ encrypt: options.encrypt,
232
+ snapshotKeyFile: options.snapshotKeyFile,
233
+ config,
234
+ }))));
235
+ });
236
+ snapshotCmd
237
+ .command('restore <snapshot-file>')
238
+ .description('Restore configuration from snapshot')
239
+ .option('--provider <name>', 'Provider name (default: aws-ssm)')
240
+ .option('--dry-run', 'Show diff without applying changes')
241
+ .option('--force-schema-mismatch', 'Allow restore despite schema hash mismatch')
242
+ .option('--confirm', 'Skip interactive confirmation')
243
+ .option('--show-values', 'Print secret values in diff output (TTY only)')
244
+ .option('--unsafe-show-values', 'Allow printing secrets even when stdout is not a TTY')
245
+ .option('--ssm-prefix <prefix>', 'SSM path prefix (default: /config-o-tron)')
246
+ .option('--schema <path>', 'Schema path')
247
+ .option('--validation <effect|zod>', 'Validation layer (default: effect)')
248
+ .action((snapshotFile, options) => {
249
+ runEffect(pipe(resolveConfig({
250
+ ...options,
251
+ ci: program.opts().ci,
252
+ strict: program.opts().strict,
253
+ }), Effect.flatMap((config) => runSnapshotRestore({
254
+ snapshotFile,
255
+ dryRun: options.dryRun,
256
+ forceSchemaMatch: options.forceSchemaMismatch,
257
+ confirm: options.confirm,
258
+ showValues: options.showValues,
259
+ unsafeShowValues: options.unsafeShowValues,
260
+ config,
261
+ }))));
262
+ });
263
+ // --------------------------------------------------------------------------
264
+ // Parse and Run
265
+ // --------------------------------------------------------------------------
266
+ program.parse();
267
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import * as Effect from 'effect/Effect';
2
+ import { type ResolvedConfig } from '../config.js';
3
+ import { type ConfigOTronError, type ProviderError, type SystemError, type ValidationError } from '../errors.js';
4
+ export type DeleteOptions = {
5
+ readonly service: string;
6
+ readonly key: string;
7
+ readonly confirm?: boolean | undefined;
8
+ readonly config: ResolvedConfig;
9
+ };
10
+ export type DeleteResult = {
11
+ readonly canonicalKey: string;
12
+ readonly deleted: boolean;
13
+ };
14
+ /**
15
+ * Execute the delete workflow
16
+ */
17
+ export declare function executeDelete(options: DeleteOptions): Effect.Effect<DeleteResult, ProviderError | ValidationError | SystemError | ConfigOTronError>;
18
+ /**
19
+ * Run delete and print result
20
+ */
21
+ export declare function runDelete(options: DeleteOptions): Effect.Effect<boolean, ProviderError | ValidationError | SystemError | ConfigOTronError>;
22
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAWjH,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAAC;AA6BF;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,aAAa,GACrB,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,GAAG,eAAe,GAAG,WAAW,GAAG,gBAAgB,CAAC,CA+E/F;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,aAAa,GACrB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,eAAe,GAAG,WAAW,GAAG,gBAAgB,CAAC,CAU1F"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Delete Command
3
+ *
4
+ * Workflow: Input -> Validate -> Confirm -> Remove -> Audit
5
+ */
6
+ import * as readline from 'node:readline';
7
+ import * as Effect from 'effect/Effect';
8
+ import { pipe } from 'effect/Function';
9
+ import {} from '../config.js';
10
+ import {} from '../errors.js';
11
+ import { checkProviderGuards } from '../providers/guards.js';
12
+ import {} from '../providers/Provider.js';
13
+ import { getProvider } from '../providers/registry.js';
14
+ import { loadSchemaWithDefaults } from '../schema/loader.js';
15
+ import { resolvePath, validateKeyPathSegments } from '../schema/resolver.js';
16
+ // --------------------------------------------------------------------------
17
+ // Helper Functions
18
+ // --------------------------------------------------------------------------
19
+ /**
20
+ * Prompt for confirmation
21
+ */
22
+ function promptConfirmation(message) {
23
+ return Effect.promise(async () => {
24
+ const rl = readline.createInterface({
25
+ input: process.stdin,
26
+ output: process.stdout,
27
+ });
28
+ return new Promise((resolve) => {
29
+ rl.question(`${message} [y/N] `, (answer) => {
30
+ rl.close();
31
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
32
+ });
33
+ });
34
+ });
35
+ }
36
+ // --------------------------------------------------------------------------
37
+ // Delete Command
38
+ // --------------------------------------------------------------------------
39
+ /**
40
+ * Execute the delete workflow
41
+ */
42
+ export function executeDelete(options) {
43
+ return pipe(
44
+ // 1. Validate key path segments
45
+ validateKeyPathSegments(options.key),
46
+ // 2. Load schema
47
+ Effect.flatMap(() => loadSchemaWithDefaults(options.config.schema, options.config.validation)), Effect.flatMap(({ adapter, schema }) =>
48
+ // 3. Resolve the key path (may not exist in schema - warn but allow)
49
+ pipe(Effect.either(resolvePath(schema, options.key, adapter)), Effect.map((resolveResult) => {
50
+ if (resolveResult._tag === 'Left') {
51
+ // Key not in schema - warn but use the input as-is
52
+ console.warn(`[config-o-tron] Warning: Key '${options.key}' not found in schema. Proceeding with deletion anyway.`);
53
+ return options.key;
54
+ }
55
+ return resolveResult.right.canonicalPath;
56
+ }))), Effect.flatMap((canonicalKey) => {
57
+ const { config, confirm = false, service } = options;
58
+ // 4. Confirm deletion
59
+ if (!confirm && !config.ci) {
60
+ return pipe(promptConfirmation(`Delete key '${canonicalKey}' from ${config.ssmPrefix}/${config.env}/${service}?`), Effect.flatMap((confirmed) => {
61
+ if (!confirmed) {
62
+ console.log('Deletion cancelled.');
63
+ return Effect.succeed({ canonicalKey, deleted: false, shouldDelete: false });
64
+ }
65
+ return Effect.succeed({ canonicalKey, deleted: false, shouldDelete: true });
66
+ }));
67
+ }
68
+ else if (!confirm && config.ci) {
69
+ // CI mode requires explicit --confirm
70
+ console.error('Error: --confirm flag required in CI mode');
71
+ return Effect.succeed({ canonicalKey, deleted: false, shouldDelete: false });
72
+ }
73
+ return Effect.succeed({ canonicalKey, deleted: false, shouldDelete: true });
74
+ }), Effect.flatMap(({ canonicalKey, shouldDelete }) => {
75
+ if (!shouldDelete) {
76
+ return Effect.succeed({ canonicalKey, deleted: false });
77
+ }
78
+ const { config, service } = options;
79
+ const ctx = {
80
+ prefix: config.ssmPrefix,
81
+ service,
82
+ env: config.env,
83
+ };
84
+ // 5. Get provider and delete
85
+ return pipe(getProvider(config.provider), Effect.flatMap((provider) => pipe(checkProviderGuards(provider, ctx, config.providerGuards), Effect.flatMap(() => provider.delete(ctx, canonicalKey)))), Effect.map(() => {
86
+ // 6. Audit log
87
+ const timestamp = new Date().toISOString();
88
+ const user = process.env.USER ?? process.env.USERNAME ?? 'unknown';
89
+ console.error(`[${timestamp}] Deleted: ${canonicalKey} by ${user}`);
90
+ return { canonicalKey, deleted: true };
91
+ }));
92
+ }));
93
+ }
94
+ /**
95
+ * Run delete and print result
96
+ */
97
+ export function runDelete(options) {
98
+ return pipe(executeDelete(options), Effect.map((result) => {
99
+ if (result.deleted) {
100
+ console.log(`Successfully deleted ${result.canonicalKey}`);
101
+ }
102
+ return result.deleted;
103
+ }));
104
+ }
105
+ //# sourceMappingURL=delete.js.map