zcb 0.1.1 → 0.1.3
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/cjs/cli.cjs +1 -0
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/index.cjs +72 -51
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/cli.mjs +1 -0
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/index.mjs +72 -51
- package/dist/esm/index.mjs.map +1 -1
- package/dist/types/cjs/createConfigBuilder.d.cts +4 -1
- package/dist/types/cjs/createConfigBuilder.d.cts.map +1 -1
- package/dist/types/cjs/types.d.cts +1 -0
- package/dist/types/cjs/types.d.cts.map +1 -1
- package/dist/types/cjs/utils/collateDefaultValues.d.cts +3 -0
- package/dist/types/cjs/utils/collateDefaultValues.d.cts.map +1 -0
- package/dist/types/esm/createConfigBuilder.d.ts +4 -1
- package/dist/types/esm/createConfigBuilder.d.ts.map +1 -1
- package/dist/types/esm/types.d.ts +1 -0
- package/dist/types/esm/types.d.ts.map +1 -1
- package/dist/types/esm/utils/collateDefaultValues.d.ts +3 -0
- package/dist/types/esm/utils/collateDefaultValues.d.ts.map +1 -0
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/createConfigBuilder.ts +45 -65
- package/src/types.ts +1 -0
- package/src/utils/collateDefaultValues.ts +55 -0
package/package.json
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { type JSONSchema7 } from 'json-schema';
|
|
2
|
+
import { cloneDeep, merge } from 'lodash-es';
|
|
2
3
|
import { type ZodError, type z } from 'zod';
|
|
3
4
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
4
5
|
import { cloneNonEnumerableValues } from './transformers/cloneNonEnumerableValues.ts';
|
|
5
6
|
import { NonEmumeralProperties } from './types.ts';
|
|
6
|
-
import {
|
|
7
|
-
import { collateObjectPropertyDefaults } from './utils/collateObjectPropertyDefaults.ts';
|
|
7
|
+
import { collateDefaultValues } from './utils/collateDefaultValues.ts';
|
|
8
8
|
import { isDerivedValueCallback } from './utils/isDerivedValueCallback.ts';
|
|
9
9
|
import { isInvalidPropertyOverride } from './utils/isInvalidPropertyOverride.ts';
|
|
10
10
|
import { RESERVED_KEYWORDS, isPropertyReservedWord } from './utils/isPropertyReservedWord.ts';
|
|
11
11
|
import { isSchemaValid } from './utils/isSchemaValid.ts';
|
|
12
|
-
import { isValidPropertyDefinition } from './utils/isValidPropertyDefinition.ts';
|
|
13
12
|
import { isValidValue } from './utils/isValidValue.ts';
|
|
14
13
|
import { jsonStringifyReplacer } from './utils/jsonStringifyReplacer.ts';
|
|
15
|
-
import { recordHasInvalidDefaults } from './utils/recordHasInvalidDefaults.ts';
|
|
16
14
|
import { transformConfigSync } from './utils/transformConfig.ts';
|
|
17
15
|
|
|
18
16
|
export type ConfigBuilder<ZodTypes> = {
|
|
@@ -32,6 +30,10 @@ export type ConfigBuilder<ZodTypes> = {
|
|
|
32
30
|
$values: () => ZodTypes;
|
|
33
31
|
};
|
|
34
32
|
|
|
33
|
+
export type CreateConfigBuilderOptions = {
|
|
34
|
+
type?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
35
37
|
export const createConfigBuilder = <ZodTypes>(
|
|
36
38
|
zodSchema: z.ZodSchema,
|
|
37
39
|
derivedValueCallbacks: Partial<
|
|
@@ -44,21 +46,44 @@ export const createConfigBuilder = <ZodTypes>(
|
|
|
44
46
|
> = {},
|
|
45
47
|
initialValues: Partial<{
|
|
46
48
|
[Key in keyof ZodTypes]: ZodTypes[Key];
|
|
47
|
-
}> = {}
|
|
49
|
+
}> = {},
|
|
50
|
+
options: CreateConfigBuilderOptions = {}
|
|
48
51
|
): ConfigBuilder<ZodTypes> => {
|
|
49
52
|
type Config = {
|
|
50
53
|
[Key in keyof ZodTypes]: ZodTypes[Key];
|
|
51
54
|
};
|
|
52
55
|
|
|
53
56
|
type DerivedValueCallback<K extends keyof Config = keyof Config> = (c: Config) => Config[K];
|
|
54
|
-
let config = initialValues as Config;
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
58
|
+
const jsonSchema = zodToJsonSchema(zodSchema) as JSONSchema7;
|
|
59
|
+
|
|
60
|
+
if (isSchemaValid(jsonSchema)) {
|
|
61
|
+
throw new Error(`The root type of a config schema must be "object", but received "${String(jsonSchema.type)}"`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const addNonEnumeralBaseProperties = (conf: Config) => {
|
|
65
|
+
Object.defineProperty(conf, NonEmumeralProperties.ZCB, {
|
|
66
|
+
configurable: false,
|
|
67
|
+
enumerable: false,
|
|
68
|
+
value: true,
|
|
69
|
+
});
|
|
61
70
|
|
|
71
|
+
if (options.type) {
|
|
72
|
+
Object.defineProperty(conf, NonEmumeralProperties.TYPE, {
|
|
73
|
+
configurable: false,
|
|
74
|
+
enumerable: false,
|
|
75
|
+
value: options.type,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const createInitialConfig = () => {
|
|
81
|
+
const config = merge(cloneDeep(initialValues), collateDefaultValues(jsonSchema)) as Config;
|
|
82
|
+
addNonEnumeralBaseProperties(config);
|
|
83
|
+
return config;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
let config = createInitialConfig();
|
|
62
87
|
let callbacks: Partial<Record<keyof Config, DerivedValueCallback>> = { ...derivedValueCallbacks };
|
|
63
88
|
|
|
64
89
|
const configBuilder = {
|
|
@@ -95,17 +120,10 @@ export const createConfigBuilder = <ZodTypes>(
|
|
|
95
120
|
},
|
|
96
121
|
$flush: () => {
|
|
97
122
|
const values = configBuilder.$values();
|
|
98
|
-
config =
|
|
99
|
-
|
|
100
|
-
Object.defineProperty(config, NonEmumeralProperties.ZCB, {
|
|
101
|
-
configurable: false,
|
|
102
|
-
enumerable: false,
|
|
103
|
-
value: true,
|
|
104
|
-
});
|
|
105
|
-
|
|
123
|
+
config = createInitialConfig();
|
|
106
124
|
return values;
|
|
107
125
|
},
|
|
108
|
-
$fork: () => createConfigBuilder<Config>(zodSchema, derivedValueCallbacks),
|
|
126
|
+
$fork: () => createConfigBuilder<Config>(zodSchema, derivedValueCallbacks, initialValues, options),
|
|
109
127
|
$toJson: () => JSON.stringify(configBuilder.$values(), jsonStringifyReplacer, 2),
|
|
110
128
|
$validate: () => {
|
|
111
129
|
try {
|
|
@@ -135,12 +153,6 @@ export const createConfigBuilder = <ZodTypes>(
|
|
|
135
153
|
value: callbacks,
|
|
136
154
|
});
|
|
137
155
|
|
|
138
|
-
const jsonSchema = zodToJsonSchema(zodSchema) as JSONSchema7;
|
|
139
|
-
|
|
140
|
-
if (isSchemaValid(jsonSchema)) {
|
|
141
|
-
throw new Error(`The root type of a config schema must be "object", but received "${String(jsonSchema.type)}"`);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
156
|
for (const propertyName in jsonSchema.properties) {
|
|
145
157
|
if (isPropertyReservedWord(propertyName)) {
|
|
146
158
|
throw new Error(
|
|
@@ -150,45 +162,13 @@ export const createConfigBuilder = <ZodTypes>(
|
|
|
150
162
|
);
|
|
151
163
|
}
|
|
152
164
|
|
|
153
|
-
const
|
|
154
|
-
const propertyDefinition = jsonSchema.properties[propertyName];
|
|
155
|
-
|
|
156
|
-
if (isValidPropertyDefinition(propertyDefinition)) {
|
|
157
|
-
if (propertyDefinition.default) {
|
|
158
|
-
config[castProperty] = propertyDefinition.default as Config[keyof Config];
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (propertyDefinition.type === 'array' && arrayHasInvalidDefaults(propertyDefinition)) {
|
|
162
|
-
throw new Error(
|
|
163
|
-
`When setting schema array defaults for the array assigned to "${String(
|
|
164
|
-
castProperty
|
|
165
|
-
)}", set them on the array and not the item.`
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (propertyDefinition.type === 'object') {
|
|
170
|
-
if (recordHasInvalidDefaults(propertyDefinition)) {
|
|
171
|
-
throw new Error(
|
|
172
|
-
`When setting schema property defaults for the value of the record assigned to "${String(
|
|
173
|
-
castProperty
|
|
174
|
-
)}", set them on the record and not the value.`
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const propertyDefaults = collateObjectPropertyDefaults(propertyDefinition);
|
|
179
|
-
|
|
180
|
-
if (propertyDefaults) {
|
|
181
|
-
config[castProperty] = propertyDefaults as Config[keyof Config];
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
165
|
+
const castPropertyName = propertyName as keyof Config;
|
|
185
166
|
|
|
186
|
-
configBuilder[
|
|
187
|
-
|
|
188
|
-
if (isInvalidPropertyOverride(config[castProperty], override)) {
|
|
167
|
+
configBuilder[castPropertyName] = ((value: Config[keyof Config] | DerivedValueCallback, override?: boolean) => {
|
|
168
|
+
if (isInvalidPropertyOverride(config[castPropertyName], override)) {
|
|
189
169
|
throw new Error(
|
|
190
170
|
`A value already exists for "${String(
|
|
191
|
-
|
|
171
|
+
castPropertyName
|
|
192
172
|
)}". You may be trying to add a new values before flushing the old one. If you intended to override the existing value, pass in true as the second argument.`
|
|
193
173
|
);
|
|
194
174
|
}
|
|
@@ -199,19 +179,19 @@ export const createConfigBuilder = <ZodTypes>(
|
|
|
199
179
|
if (!isValidValue(value)) {
|
|
200
180
|
throw new Error(
|
|
201
181
|
`"${String(
|
|
202
|
-
|
|
182
|
+
castPropertyName
|
|
203
183
|
)}" value has a depth greater than ${MAX_DEPTH}. To pass in objects with a depth greater than ${MAX_DEPTH}, create a builder for that config slice.`
|
|
204
184
|
);
|
|
205
185
|
}
|
|
206
186
|
|
|
207
187
|
if (isDerivedValueCallback<DerivedValueCallback>(value)) {
|
|
208
|
-
callbacks[
|
|
188
|
+
callbacks[castPropertyName] = value;
|
|
209
189
|
propertyValue = value(config);
|
|
210
190
|
} else {
|
|
211
191
|
propertyValue = value;
|
|
212
192
|
}
|
|
213
193
|
|
|
214
|
-
config[
|
|
194
|
+
config[castPropertyName] = propertyValue;
|
|
215
195
|
return configBuilder;
|
|
216
196
|
}) as ConfigBuilder<Config>[keyof Config];
|
|
217
197
|
}
|
package/src/types.ts
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type JSONSchema7 } from 'json-schema';
|
|
2
|
+
import { arrayHasInvalidDefaults } from './arrayHasInvalidDefaults.ts';
|
|
3
|
+
import { collateObjectPropertyDefaults } from './collateObjectPropertyDefaults.ts';
|
|
4
|
+
import { RESERVED_KEYWORDS, isPropertyReservedWord } from './isPropertyReservedWord.ts';
|
|
5
|
+
import { isValidPropertyDefinition } from './isValidPropertyDefinition.ts';
|
|
6
|
+
import { recordHasInvalidDefaults } from './recordHasInvalidDefaults.ts';
|
|
7
|
+
|
|
8
|
+
export const collateDefaultValues = <Config>(jsonSchema: JSONSchema7) => {
|
|
9
|
+
const defaultValues = {} as Partial<Config>;
|
|
10
|
+
|
|
11
|
+
for (const propertyName in jsonSchema.properties) {
|
|
12
|
+
if (isPropertyReservedWord(propertyName)) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`"${propertyName}" is a reserved keyword within the config builder. Please use a different property name. The full list of reserved keywords is: ${[
|
|
15
|
+
...RESERVED_KEYWORDS,
|
|
16
|
+
].join(', ')}`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const castPropertyName = propertyName as keyof Config;
|
|
21
|
+
const propertyDefinition = jsonSchema.properties[propertyName];
|
|
22
|
+
|
|
23
|
+
if (isValidPropertyDefinition(propertyDefinition)) {
|
|
24
|
+
if (propertyDefinition.default) {
|
|
25
|
+
defaultValues[castPropertyName] = propertyDefinition.default as Config[keyof Config];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (propertyDefinition.type === 'array' && arrayHasInvalidDefaults(propertyDefinition)) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`When setting schema array defaults for the array assigned to "${String(
|
|
31
|
+
castPropertyName
|
|
32
|
+
)}", set them on the array and not the item.`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (propertyDefinition.type === 'object') {
|
|
37
|
+
if (recordHasInvalidDefaults(propertyDefinition)) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`When setting schema property defaults for the value of the record assigned to "${String(
|
|
40
|
+
castPropertyName
|
|
41
|
+
)}", set them on the record and not the value.`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const propertyDefaults = collateObjectPropertyDefaults(propertyDefinition);
|
|
46
|
+
|
|
47
|
+
if (propertyDefaults) {
|
|
48
|
+
defaultValues[castPropertyName] = propertyDefaults as Config[keyof Config];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return defaultValues;
|
|
55
|
+
};
|