@zamatica/configuration 0.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.
@@ -0,0 +1,190 @@
1
+ import type { z } from 'zod';
2
+ import type {
3
+ ConfigurationParameterDefinition,
4
+ ConfigurationValueConstructor,
5
+ ConfigurationValuePrimitive,
6
+ DirectoryConfigurationParameterDefinition,
7
+ SimpleConfigurationParameterDefinition,
8
+ YamlConfigurationParameterDefinition,
9
+ } from './parameter-types.js';
10
+
11
+ const ENV_VAR_NAME_REGEX = /^[A-Z]([A-Z0-9_]*[A-Z0-9])?$/;
12
+
13
+ function assertValidConfigurationKey(key: string): void {
14
+ if (!ENV_VAR_NAME_REGEX.test(key)) {
15
+ throw new Error(
16
+ `Invalid configuration key '${key}': must match SCREAMING_SNAKE_CASE (env-var convention).`,
17
+ );
18
+ }
19
+ }
20
+
21
+ interface BaseState {
22
+ key: string;
23
+ description: string;
24
+ required: boolean;
25
+ default: ConfigurationValuePrimitive | undefined;
26
+ }
27
+
28
+ /**
29
+ * Common methods shared by every parameter builder. Subclasses add type-specific
30
+ * methods (e.g. `requireWritable()` on directory builders) and implement `build()`.
31
+ *
32
+ * The builder mutates `this.state` and returns `this` for chaining; subclasses
33
+ * preserve that pattern so chains compose cleanly.
34
+ */
35
+ abstract class ParameterBuilderBase<TSelf extends ParameterBuilderBase<TSelf, TDef>, TDef> {
36
+ protected state: BaseState;
37
+
38
+ protected constructor(state: BaseState) {
39
+ this.state = state;
40
+ }
41
+
42
+ description(text: string): TSelf {
43
+ this.state = { ...this.state, description: text };
44
+ return this as unknown as TSelf;
45
+ }
46
+
47
+ default(value: ConfigurationValuePrimitive): TSelf {
48
+ this.state = { ...this.state, default: value };
49
+ return this as unknown as TSelf;
50
+ }
51
+
52
+ required(): TSelf {
53
+ this.state = { ...this.state, required: true };
54
+ return this as unknown as TSelf;
55
+ }
56
+
57
+ optional(): TSelf {
58
+ this.state = { ...this.state, required: false };
59
+ return this as unknown as TSelf;
60
+ }
61
+
62
+ abstract build(): TDef;
63
+ }
64
+
65
+ class SimpleParameterBuilder extends ParameterBuilderBase<
66
+ SimpleParameterBuilder,
67
+ SimpleConfigurationParameterDefinition
68
+ > {
69
+ constructor(state: BaseState, private readonly constructorFn: ConfigurationValueConstructor) {
70
+ super(state);
71
+ }
72
+
73
+ build(): SimpleConfigurationParameterDefinition {
74
+ return {
75
+ kind: 'simple',
76
+ configurationKey: this.state.key,
77
+ description: this.state.description,
78
+ required: this.state.required,
79
+ default: this.state.default,
80
+ constructor: this.constructorFn,
81
+ };
82
+ }
83
+ }
84
+
85
+ class DirectoryParameterBuilder extends ParameterBuilderBase<
86
+ DirectoryParameterBuilder,
87
+ DirectoryConfigurationParameterDefinition
88
+ > {
89
+ private requireWritableFlag = false;
90
+ private createIfMissingFlag = false;
91
+
92
+ constructor(state: BaseState) {
93
+ super(state);
94
+ }
95
+
96
+ requireWritable(): this {
97
+ this.requireWritableFlag = true;
98
+ return this;
99
+ }
100
+
101
+ createIfMissing(): this {
102
+ this.createIfMissingFlag = true;
103
+ return this;
104
+ }
105
+
106
+ build(): DirectoryConfigurationParameterDefinition {
107
+ return {
108
+ kind: 'directory',
109
+ configurationKey: this.state.key,
110
+ description: this.state.description,
111
+ required: this.state.required,
112
+ default: this.state.default,
113
+ constructor: String,
114
+ requireWritable: this.requireWritableFlag,
115
+ createIfMissing: this.createIfMissingFlag,
116
+ };
117
+ }
118
+ }
119
+
120
+ class YamlParameterBuilder<TSchema extends z.ZodTypeAny = z.ZodTypeAny> extends ParameterBuilderBase<
121
+ YamlParameterBuilder<TSchema>,
122
+ YamlConfigurationParameterDefinition<TSchema>
123
+ > {
124
+ private schemaValue: TSchema | undefined;
125
+
126
+ constructor(state: BaseState) {
127
+ super(state);
128
+ }
129
+
130
+ schema<TNewSchema extends z.ZodTypeAny>(schema: TNewSchema): YamlParameterBuilder<TNewSchema> {
131
+ const next = new YamlParameterBuilder<TNewSchema>(this.state);
132
+ next.schemaValue = schema;
133
+ return next;
134
+ }
135
+
136
+ build(): YamlConfigurationParameterDefinition<TSchema> {
137
+ return {
138
+ kind: 'yaml',
139
+ configurationKey: this.state.key,
140
+ description: this.state.description,
141
+ required: this.state.required,
142
+ default: this.state.default,
143
+ constructor: String,
144
+ schema: this.schemaValue,
145
+ };
146
+ }
147
+ }
148
+
149
+ class ParameterTypeSelector {
150
+ constructor(private readonly state: BaseState) {}
151
+
152
+ string(): SimpleParameterBuilder {
153
+ return new SimpleParameterBuilder(this.state, String);
154
+ }
155
+
156
+ number(): SimpleParameterBuilder {
157
+ return new SimpleParameterBuilder(this.state, Number);
158
+ }
159
+
160
+ boolean(): SimpleParameterBuilder {
161
+ return new SimpleParameterBuilder(this.state, Boolean);
162
+ }
163
+
164
+ directory(): DirectoryParameterBuilder {
165
+ return new DirectoryParameterBuilder(this.state);
166
+ }
167
+
168
+ yaml(): YamlParameterBuilder {
169
+ return new YamlParameterBuilder(this.state);
170
+ }
171
+ }
172
+
173
+ export const ConfigurationParameter = {
174
+ named(key: string): ParameterTypeSelector {
175
+ assertValidConfigurationKey(key);
176
+ return new ParameterTypeSelector({
177
+ key,
178
+ description: '',
179
+ required: false,
180
+ default: undefined,
181
+ });
182
+ },
183
+ };
184
+
185
+ export type AnyConfigurationParameterBuilder =
186
+ | SimpleParameterBuilder
187
+ | DirectoryParameterBuilder
188
+ | YamlParameterBuilder;
189
+
190
+ export type AnyConfigurationParameterDefinition = ConfigurationParameterDefinition;
@@ -0,0 +1,41 @@
1
+ import type { z } from 'zod';
2
+
3
+ export type ConfigurationValuePrimitive = string | number | boolean;
4
+
5
+ export type ConfigurationValueConstructor =
6
+ | StringConstructor
7
+ | NumberConstructor
8
+ | BooleanConstructor;
9
+
10
+ export interface ConfigurationParameterDefinitionBase {
11
+ configurationKey: string;
12
+ description: string;
13
+ required: boolean;
14
+ default: ConfigurationValuePrimitive | undefined;
15
+ }
16
+
17
+ export interface SimpleConfigurationParameterDefinition
18
+ extends ConfigurationParameterDefinitionBase {
19
+ kind: 'simple';
20
+ constructor: ConfigurationValueConstructor;
21
+ }
22
+
23
+ export interface DirectoryConfigurationParameterDefinition
24
+ extends ConfigurationParameterDefinitionBase {
25
+ kind: 'directory';
26
+ constructor: StringConstructor;
27
+ requireWritable: boolean;
28
+ createIfMissing: boolean;
29
+ }
30
+
31
+ export interface YamlConfigurationParameterDefinition<TSchema extends z.ZodTypeAny = z.ZodTypeAny>
32
+ extends ConfigurationParameterDefinitionBase {
33
+ kind: 'yaml';
34
+ constructor: StringConstructor;
35
+ schema: TSchema | undefined;
36
+ }
37
+
38
+ export type ConfigurationParameterDefinition =
39
+ | SimpleConfigurationParameterDefinition
40
+ | DirectoryConfigurationParameterDefinition
41
+ | YamlConfigurationParameterDefinition;