zcb 0.2.5 → 0.2.7
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/README.md +14 -2
- package/bin/zcb.js +1 -1
- package/dist/cjs/cli.cjs +1 -1
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/templates/config.ts.hbs +1 -1
- package/dist/esm/cli.mjs +1 -1
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/templates/config.ts.hbs +1 -1
- package/dist/production.analysis.txt +35 -35
- package/dist/types/cjs/cli.d.cts.map +1 -1
- package/dist/types/cjs/createConfigBuilder.d.cts +1 -1
- package/dist/types/cjs/createConfigBuilder.d.cts.map +1 -1
- package/dist/types/cjs/createConfigParser.d.cts.map +1 -1
- package/dist/types/cjs/createConfigReader.d.cts +4 -1
- package/dist/types/cjs/createConfigReader.d.cts.map +1 -1
- package/dist/types/cjs/transformers/cloneNonEnumerableValues.d.cts.map +1 -1
- package/dist/types/cjs/transformers/removeDisabledSlices.d.cts.map +1 -1
- package/dist/types/cjs/transformers/runExperiments.d.cts.map +1 -1
- package/dist/types/cjs/types.d.cts +4 -4
- package/dist/types/cjs/types.d.cts.map +1 -1
- package/dist/types/cjs/utils/collateDefaultValues.d.cts.map +1 -1
- package/dist/types/cjs/utils/isDerivedValueCallback.d.cts.map +1 -1
- package/dist/types/cjs/utils/isValidPropertyDefinition.d.cts.map +1 -1
- package/dist/types/cjs/utils/isValidValue.d.cts.map +1 -1
- package/dist/types/cjs/utils/jsonStringifyReplacer.d.cts +4 -2
- package/dist/types/cjs/utils/jsonStringifyReplacer.d.cts.map +1 -1
- package/dist/types/cjs/utils/transformConfig.d.cts.map +1 -1
- package/dist/types/cjs/utils/transformWriteConfig.d.cts.map +1 -1
- package/dist/types/esm/cli.d.ts.map +1 -1
- package/dist/types/esm/createConfigBuilder.d.ts +1 -1
- package/dist/types/esm/createConfigBuilder.d.ts.map +1 -1
- package/dist/types/esm/createConfigParser.d.ts.map +1 -1
- package/dist/types/esm/createConfigReader.d.ts +4 -1
- package/dist/types/esm/createConfigReader.d.ts.map +1 -1
- package/dist/types/esm/transformers/cloneNonEnumerableValues.d.ts.map +1 -1
- package/dist/types/esm/transformers/removeDisabledSlices.d.ts.map +1 -1
- package/dist/types/esm/transformers/runExperiments.d.ts.map +1 -1
- package/dist/types/esm/types.d.ts +4 -4
- package/dist/types/esm/types.d.ts.map +1 -1
- package/dist/types/esm/utils/collateDefaultValues.d.ts.map +1 -1
- package/dist/types/esm/utils/isDerivedValueCallback.d.ts.map +1 -1
- package/dist/types/esm/utils/isValidPropertyDefinition.d.ts.map +1 -1
- package/dist/types/esm/utils/isValidValue.d.ts.map +1 -1
- package/dist/types/esm/utils/jsonStringifyReplacer.d.ts +4 -2
- package/dist/types/esm/utils/jsonStringifyReplacer.d.ts.map +1 -1
- package/dist/types/esm/utils/transformConfig.d.ts.map +1 -1
- package/dist/types/esm/utils/transformWriteConfig.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +45 -77
- package/shellScripts/installActivateMise.sh +12 -0
- package/src/__testUtils__/builtConfig.ts +2 -1
- package/src/__testUtils__/configBuilder.ts +1 -2
- package/src/cli.ts +27 -17
- package/src/createConfigBuilder.test.ts +14 -16
- package/src/createConfigBuilder.ts +24 -7
- package/src/createConfigParser.ts +1 -1
- package/src/createConfigReader.test.ts +28 -0
- package/src/createConfigReader.ts +27 -3
- package/src/templates/config.ts.hbs +1 -1
- package/src/transformers/cloneNonEnumerableValues.ts +2 -3
- package/src/transformers/removeDisabledSlices.ts +1 -2
- package/src/transformers/runExperiments.ts +3 -1
- package/src/types.ts +15 -11
- package/src/utils/collateDefaultValues.ts +12 -6
- package/src/utils/importValidateTransformWriteConfig.ts +1 -1
- package/src/utils/isValidPropertyDefinition.ts +1 -1
- package/src/utils/isValidValue.ts +2 -0
- package/src/utils/transformConfig.ts +15 -4
- package/src/utils/transformWriteConfig.ts +3 -3
|
@@ -10,11 +10,13 @@ export const runExperiments =
|
|
|
10
10
|
(callback: RunExperimentsCallback): TransformConfigHandler =>
|
|
11
11
|
async <Config extends AnyRecord>(clone: Config, config: Config) => {
|
|
12
12
|
if (NonEmumeralProperties.EXPERIMENT in config && typeof config.__experiment === 'object') {
|
|
13
|
+
// As __experiment is private property, Typescript doesn't know what type is.
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
13
15
|
const { buckets, id } = config.__experiment as { buckets: Buckets<Config>; id: string };
|
|
14
16
|
const bucket = await callback(id);
|
|
15
17
|
|
|
16
18
|
if (bucket && bucket in buckets && buckets[bucket]) {
|
|
17
|
-
return buckets[bucket]
|
|
19
|
+
return buckets[bucket];
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
|
package/src/types.ts
CHANGED
|
@@ -33,17 +33,17 @@ export type Scope<Config extends object> = Join<Paths<Config>, '.'>;
|
|
|
33
33
|
export type SetupExperimentsCallback = <Config extends AnyRecord>(
|
|
34
34
|
id: string,
|
|
35
35
|
clone: Config,
|
|
36
|
-
config: Config
|
|
36
|
+
config: Config,
|
|
37
37
|
) => Promise<Buckets<Config>>;
|
|
38
38
|
|
|
39
39
|
export type TransformConfigHandler = <Config extends AnyRecord>(
|
|
40
40
|
clone: Config,
|
|
41
|
-
config: Config
|
|
41
|
+
config: Config,
|
|
42
42
|
) => TransformConfigHandlerReturnType<Config> | Promise<TransformConfigHandlerReturnType<Config>>;
|
|
43
43
|
|
|
44
44
|
export type TransformConfigHandlerSync = <Config extends AnyRecord>(
|
|
45
45
|
clone: Config,
|
|
46
|
-
config: Config
|
|
46
|
+
config: Config,
|
|
47
47
|
) => TransformConfigHandlerReturnType<Config>;
|
|
48
48
|
|
|
49
49
|
export enum TransformConfigHandlerAction {
|
|
@@ -61,17 +61,21 @@ export interface WriteConfigOptions {
|
|
|
61
61
|
outputFile: string;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export type Leaves<T, LeafPath extends string[] = []> = T extends string
|
|
64
|
+
export type Leaves<T, LeafPath extends string[] = [], Depth extends number = 0> = T extends string
|
|
65
65
|
? LeafPath
|
|
66
|
-
:
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
: Depth extends 15
|
|
67
|
+
? LeafPath
|
|
68
|
+
: {
|
|
69
|
+
[K in keyof T & string]: Leaves<T[K], [...LeafPath, K], LeafPath['length']>;
|
|
70
|
+
}[keyof T & string];
|
|
69
71
|
|
|
70
|
-
export type Paths<T, LeafPath extends string[] = []> = T extends string
|
|
72
|
+
export type Paths<T, LeafPath extends string[] = [], Depth extends number = 0> = T extends string
|
|
71
73
|
? LeafPath
|
|
72
|
-
:
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
: Depth extends 15
|
|
75
|
+
? LeafPath
|
|
76
|
+
: {
|
|
77
|
+
[K in keyof T & string]: T[K] extends object ? Paths<T[K], [...LeafPath, K], LeafPath['length']> : LeafPath;
|
|
78
|
+
}[keyof T & string];
|
|
75
79
|
|
|
76
80
|
export type LeavesScopeDiffs<T1 extends readonly string[][], T2 extends string[]> = {
|
|
77
81
|
[K1 in keyof T1]: List.Length<List.Intersect<T1[K1], T2, '<-contains'>> extends 1
|
|
@@ -6,30 +6,34 @@ import { isValidPropertyDefinition } from './isValidPropertyDefinition.ts';
|
|
|
6
6
|
import { recordHasInvalidDefaults } from './recordHasInvalidDefaults.ts';
|
|
7
7
|
|
|
8
8
|
export const collateDefaultValues = <Config>(jsonSchema: JSONSchema7) => {
|
|
9
|
-
const defaultValues = {}
|
|
9
|
+
const defaultValues: Partial<Config> = {};
|
|
10
10
|
|
|
11
11
|
for (const propertyName in jsonSchema.properties) {
|
|
12
12
|
if (isPropertyReservedWord(propertyName)) {
|
|
13
13
|
throw new Error(
|
|
14
14
|
`"${propertyName}" is a reserved keyword within the config builder. Please use a different property name. The full list of reserved keywords is: ${[
|
|
15
15
|
...RESERVED_KEYWORDS,
|
|
16
|
-
].join(', ')}
|
|
16
|
+
].join(', ')}`,
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// Typescript not inferring property is key of Config.
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
20
22
|
const castPropertyName = propertyName as keyof Config;
|
|
21
23
|
const propertyDefinition = jsonSchema.properties[propertyName];
|
|
22
24
|
|
|
23
25
|
if (isValidPropertyDefinition(propertyDefinition)) {
|
|
24
26
|
if (propertyDefinition.default) {
|
|
27
|
+
// Typescript not inferring propertyDefinition.default is Config value.
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
25
29
|
defaultValues[castPropertyName] = propertyDefinition.default as Config[keyof Config];
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
if (propertyDefinition.type === 'array' && arrayHasInvalidDefaults(propertyDefinition)) {
|
|
29
33
|
throw new Error(
|
|
30
34
|
`When setting schema array defaults for the array assigned to "${String(
|
|
31
|
-
castPropertyName
|
|
32
|
-
)}", set them on the array and not the item
|
|
35
|
+
castPropertyName,
|
|
36
|
+
)}", set them on the array and not the item.`,
|
|
33
37
|
);
|
|
34
38
|
}
|
|
35
39
|
|
|
@@ -37,14 +41,16 @@ export const collateDefaultValues = <Config>(jsonSchema: JSONSchema7) => {
|
|
|
37
41
|
if (recordHasInvalidDefaults(propertyDefinition)) {
|
|
38
42
|
throw new Error(
|
|
39
43
|
`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
|
|
44
|
+
castPropertyName,
|
|
45
|
+
)}", set them on the record and not the value.`,
|
|
42
46
|
);
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
const propertyDefaults = collateObjectPropertyDefaults(propertyDefinition);
|
|
46
50
|
|
|
47
51
|
if (propertyDefaults) {
|
|
52
|
+
// Typescript not inferring propertyDefaults is Config value.
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
48
54
|
defaultValues[castPropertyName] = propertyDefaults as Config[keyof Config];
|
|
49
55
|
}
|
|
50
56
|
}
|
|
@@ -9,7 +9,7 @@ export const importValidateTransformWriteConfig = (
|
|
|
9
9
|
inputFile: string,
|
|
10
10
|
outputFile: string,
|
|
11
11
|
command: Commands,
|
|
12
|
-
experimentCallbackFile?: string
|
|
12
|
+
experimentCallbackFile?: string,
|
|
13
13
|
) => {
|
|
14
14
|
import(resolve(process.cwd(), inputFile))
|
|
15
15
|
.then(({ default: configBuilder }: { default: ConfigBuilder<object> }) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type JSONSchema7, type JSONSchema7Definition } from 'json-schema';
|
|
2
2
|
|
|
3
3
|
export const isValidPropertyDefinition = (
|
|
4
|
-
propertyDefinition: JSONSchema7Definition | undefined
|
|
4
|
+
propertyDefinition: JSONSchema7Definition | undefined,
|
|
5
5
|
): propertyDefinition is JSONSchema7 => typeof propertyDefinition === 'object';
|
|
@@ -2,6 +2,8 @@ import { isPlainObject } from 'lodash-es';
|
|
|
2
2
|
|
|
3
3
|
export const isValidValue = (value: unknown, depth = 0): boolean => {
|
|
4
4
|
if (isPlainObject(value)) {
|
|
5
|
+
// isPlainObject not a type guard.
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
5
7
|
const object = value as Record<string, unknown>;
|
|
6
8
|
|
|
7
9
|
if (object.__zcb === true) {
|
|
@@ -15,19 +15,20 @@ const transformArray = (list: any[], handler: TransformConfigHandler | Transform
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
if (Array.isArray(entry)) {
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
19
18
|
return transformArray(entry, handler);
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
23
22
|
return entry;
|
|
24
|
-
})
|
|
23
|
+
}),
|
|
25
24
|
);
|
|
26
25
|
|
|
27
26
|
export const transformConfig = async <Config extends AnyRecord>(
|
|
28
27
|
config: Config,
|
|
29
|
-
handler: TransformConfigHandler | TransformConfigHandler[] = []
|
|
28
|
+
handler: TransformConfigHandler | TransformConfigHandler[] = [],
|
|
30
29
|
): Promise<Config> => {
|
|
30
|
+
// Typing gets too complicated without casting.
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
31
32
|
let transform = {} as Config;
|
|
32
33
|
const handlers = castArray(handler);
|
|
33
34
|
|
|
@@ -35,6 +36,8 @@ export const transformConfig = async <Config extends AnyRecord>(
|
|
|
35
36
|
const result = await Promise.resolve(callback(transform, config));
|
|
36
37
|
|
|
37
38
|
if (result.action === TransformConfigHandlerAction.DELETE_NODE) {
|
|
39
|
+
// Typing gets too complicated without casting.
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
38
41
|
return {} as Config;
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -53,6 +56,8 @@ export const transformConfig = async <Config extends AnyRecord>(
|
|
|
53
56
|
if (isPlainObject(value)) {
|
|
54
57
|
transform[key] = await transformConfig(value, handler);
|
|
55
58
|
} else if (Array.isArray(value)) {
|
|
59
|
+
// transformArraySync returns an any type.
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
56
61
|
transform[key] = (await transformArray(value, handler)) as Config[Extract<keyof Config, string>];
|
|
57
62
|
} else {
|
|
58
63
|
transform[key] = value;
|
|
@@ -81,8 +86,10 @@ const transformArraySync = (list: any[], handler: TransformConfigHandlerSync | T
|
|
|
81
86
|
|
|
82
87
|
export const transformConfigSync = <Config extends AnyRecord>(
|
|
83
88
|
config: Config,
|
|
84
|
-
handler: TransformConfigHandlerSync | TransformConfigHandlerSync[] = []
|
|
89
|
+
handler: TransformConfigHandlerSync | TransformConfigHandlerSync[] = [],
|
|
85
90
|
): Config => {
|
|
91
|
+
// Typing gets too complicated without casting.
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
86
93
|
let transform = {} as Config;
|
|
87
94
|
const handlers = castArray(handler);
|
|
88
95
|
|
|
@@ -90,6 +97,8 @@ export const transformConfigSync = <Config extends AnyRecord>(
|
|
|
90
97
|
const result = callback(transform, config);
|
|
91
98
|
|
|
92
99
|
if (result.action === TransformConfigHandlerAction.DELETE_NODE) {
|
|
100
|
+
// Typing gets too complicated without casting.
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
93
102
|
return {} as Config;
|
|
94
103
|
}
|
|
95
104
|
|
|
@@ -108,6 +117,8 @@ export const transformConfigSync = <Config extends AnyRecord>(
|
|
|
108
117
|
if (isPlainObject(value)) {
|
|
109
118
|
transform[key] = transformConfigSync(value, handler);
|
|
110
119
|
} else if (Array.isArray(value)) {
|
|
120
|
+
// transformArraySync returns an any type.
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
111
122
|
transform[key] = transformArraySync(value, handler) as Config[Extract<keyof Config, string>];
|
|
112
123
|
} else {
|
|
113
124
|
transform[key] = value;
|
|
@@ -11,7 +11,7 @@ import { transformConfig } from './transformConfig.ts';
|
|
|
11
11
|
|
|
12
12
|
export const transformWriteConfig = async <Config extends object>(
|
|
13
13
|
config: Config,
|
|
14
|
-
{ experimentsCallback, outputFile }: WriteConfigOptions
|
|
14
|
+
{ experimentsCallback, outputFile }: WriteConfigOptions,
|
|
15
15
|
) => {
|
|
16
16
|
const handlers: TransformConfigHandler[] = [removeDisabledSlices];
|
|
17
17
|
|
|
@@ -20,12 +20,12 @@ export const transformWriteConfig = async <Config extends object>(
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const template = Handlebars.compile(
|
|
23
|
-
readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), './templates/config.ts.hbs'), { encoding: 'utf8' })
|
|
23
|
+
readFileSync(resolve(dirname(fileURLToPath(import.meta.url)), './templates/config.ts.hbs'), { encoding: 'utf8' }),
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
const output = template({ config: JSON.stringify(await transformConfig(config, handlers), undefined, 2) }).replaceAll(
|
|
27
27
|
/"([A-Za-z][\dA-Za-z]+)":/g,
|
|
28
|
-
'$1:'
|
|
28
|
+
'$1:',
|
|
29
29
|
);
|
|
30
30
|
|
|
31
31
|
shelljs.echo(`zcd watch => writing to file: ${outputFile}`);
|