zcb 0.0.6
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/LICENSE +21 -0
- package/README.md +8 -0
- package/bin/zcb.mjs +3 -0
- package/package.json +129 -0
- package/src/__testUtils__/builtConfig.ts +74 -0
- package/src/__testUtils__/config.ts +32 -0
- package/src/__testUtils__/configBuilder.ts +58 -0
- package/src/__testUtils__/schema.ts +56 -0
- package/src/cli.ts +86 -0
- package/src/createConfigBuilder.test.ts +523 -0
- package/src/createConfigBuilder.ts +234 -0
- package/src/createConfigReader.test.ts +45 -0
- package/src/createConfigReader.ts +12 -0
- package/src/data/countryCodes.ts +247 -0
- package/src/data/countryNames.ts +207 -0
- package/src/data/distanceUnits.ts +1 -0
- package/src/data/languageCodes.ts +185 -0
- package/src/data/timezones.ts +419 -0
- package/src/index.ts +6 -0
- package/src/templates/config.ts.hbs +3 -0
- package/src/transformers/cloneNonEnumerableValues.ts +24 -0
- package/src/transformers/removeDisabledSlices.ts +17 -0
- package/src/transformers/setupExperiments.ts +24 -0
- package/src/types.ts +58 -0
- package/src/utils/__snapshots__/transformConfig.test.ts.snap +151 -0
- package/src/utils/arrayHasInvalidDefaults.ts +6 -0
- package/src/utils/isDerivedValueCallback.ts +3 -0
- package/src/utils/isInvalidPropertyOverride.ts +3 -0
- package/src/utils/isPropertyReservedWord.ts +3 -0
- package/src/utils/isSchemaValid.ts +3 -0
- package/src/utils/isValidPropertyDefinition.ts +5 -0
- package/src/utils/isValidValue.ts +27 -0
- package/src/utils/objectHasInvalidDefaults.ts +5 -0
- package/src/utils/recordHasInvalidDefaults.ts +6 -0
- package/src/utils/transformConfig.test.ts +19 -0
- package/src/utils/transformConfig.ts +119 -0
- package/src/utils/writeConfig.ts +34 -0
- package/tsconfig.build.json +13 -0
- package/tsconfig.json +9 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 dylanaubrey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# zod-config-builder
|
|
2
|
+
|
|
3
|
+
Build configs with type safety from zod schema.
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/js/%40zod-config-builder)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
**WORK IN PROGRESS**
|
package/bin/zcb.mjs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zcb",
|
|
3
|
+
"description": "Build configs with type safety from zod schema.",
|
|
4
|
+
"version": "0.0.6",
|
|
5
|
+
"author": "Dylan Aubrey",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/badbatch/zod-config-builder",
|
|
8
|
+
"repository": "badbatch/zod-config-builder",
|
|
9
|
+
"bugs": "https://github.com/badbatch/zod-config-builder/issues",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"bin": {
|
|
12
|
+
"zcb": "./bin/zcb.mjs"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/main/index.mjs",
|
|
15
|
+
"types": "./dist/types/index.d.ts",
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"fs-extra": "^11.1.1",
|
|
21
|
+
"handlebars": "^4.7.7",
|
|
22
|
+
"json-schema": "^0.4.0",
|
|
23
|
+
"shelljs": "^0.8.4",
|
|
24
|
+
"ts-node": "^10.9.1",
|
|
25
|
+
"yargs": "^15.1.0",
|
|
26
|
+
"zod": "^3.21.4",
|
|
27
|
+
"zod-to-json-schema": "^3.21.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"@babel/runtime": "<8",
|
|
31
|
+
"core-js": "<4",
|
|
32
|
+
"lodash": "<5"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@babel/cli": "^7.21.5",
|
|
36
|
+
"@babel/core": "^7.21.8",
|
|
37
|
+
"@babel/eslint-parser": "^7.21.8",
|
|
38
|
+
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
39
|
+
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",
|
|
40
|
+
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
41
|
+
"@babel/plugin-syntax-import-assertions": "^7.20.0",
|
|
42
|
+
"@babel/plugin-transform-runtime": "^7.21.4",
|
|
43
|
+
"@babel/preset-env": "^7.21.5",
|
|
44
|
+
"@babel/preset-react": "^7.18.6",
|
|
45
|
+
"@babel/preset-typescript": "^7.21.5",
|
|
46
|
+
"@babel/runtime": "^7.21.5",
|
|
47
|
+
"@commitlint/cli": "^17.6.3",
|
|
48
|
+
"@commitlint/config-conventional": "^17.6.3",
|
|
49
|
+
"@commitlint/prompt-cli": "^17.6.3",
|
|
50
|
+
"@jest/globals": "^29.5.0",
|
|
51
|
+
"@repodog/babel-config": "^1.0.0",
|
|
52
|
+
"@repodog/cli": "^1.1.1",
|
|
53
|
+
"@repodog/commitlint-config": "^1.0.0",
|
|
54
|
+
"@repodog/eslint-config": "^1.0.0",
|
|
55
|
+
"@repodog/jest-config": "^1.0.0",
|
|
56
|
+
"@repodog/markdownlint-config": "^1.0.0",
|
|
57
|
+
"@repodog/prettier-config": "^1.0.0",
|
|
58
|
+
"@repodog/rollup-config": "^1.0.0",
|
|
59
|
+
"@repodog/syncpack-config": "1.0.0",
|
|
60
|
+
"@repodog/ts-config": "^1.0.0",
|
|
61
|
+
"@rollup/plugin-babel": "^6.0.3",
|
|
62
|
+
"@rollup/plugin-image": "^3.0.2",
|
|
63
|
+
"@rollup/plugin-json": "^6.0.0",
|
|
64
|
+
"@rollup/plugin-node-resolve": "^15.0.2",
|
|
65
|
+
"@rollup/plugin-terser": "^0.4.1",
|
|
66
|
+
"@types/fs-extra": "^11.0.1",
|
|
67
|
+
"@types/jest": "^29.5.1",
|
|
68
|
+
"@types/json-schema": "^7.0.11",
|
|
69
|
+
"@types/lodash": "^4.14.191",
|
|
70
|
+
"@types/node": "^18.11.18",
|
|
71
|
+
"@types/shelljs": "^0.8.11",
|
|
72
|
+
"@types/yargs": "^15.0.4",
|
|
73
|
+
"@typescript-eslint/eslint-plugin": "^5.59.5",
|
|
74
|
+
"@typescript-eslint/parser": "^5.59.5",
|
|
75
|
+
"babel-jest": "^29.5.0",
|
|
76
|
+
"babel-plugin-codegen": "^4.1.5",
|
|
77
|
+
"babel-plugin-macros": "^3.1.0",
|
|
78
|
+
"core-js": "^3.27.2",
|
|
79
|
+
"del-cli": "^3.0.0",
|
|
80
|
+
"eslint": "^8.40.0",
|
|
81
|
+
"eslint-config-prettier": "^8.8.0",
|
|
82
|
+
"eslint-import-resolver-typescript": "^3.5.5",
|
|
83
|
+
"eslint-plugin-import": "^2.27.5",
|
|
84
|
+
"eslint-plugin-jest": "^27.2.1",
|
|
85
|
+
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
86
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
87
|
+
"eslint-plugin-react": "^7.32.2",
|
|
88
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
89
|
+
"eslint-plugin-sort-class-members": "^1.18.0",
|
|
90
|
+
"eslint-plugin-sort-destructure-keys": "^1.5.0",
|
|
91
|
+
"eslint-plugin-sort-keys-fix": "^1.1.2",
|
|
92
|
+
"eslint-plugin-typescript-sort-keys": "^2.3.0",
|
|
93
|
+
"eslint-plugin-unicorn": "^47.0.0",
|
|
94
|
+
"generate-changelog": "^1.8.0",
|
|
95
|
+
"husky": "^8.0.3",
|
|
96
|
+
"identity-obj-proxy": "^3.0.0",
|
|
97
|
+
"jest": "^29.5.0",
|
|
98
|
+
"lodash": "^4.17.21",
|
|
99
|
+
"markdownlint-cli": "^0.34.0",
|
|
100
|
+
"prettier": "^2.8.8",
|
|
101
|
+
"rollup": "^3.21.6",
|
|
102
|
+
"rollup-plugin-analyzer": "^4.0.0",
|
|
103
|
+
"rollup-plugin-copy": "^3.4.0",
|
|
104
|
+
"rollup-plugin-sourcemaps": "^0.6.3",
|
|
105
|
+
"suppress-experimental-warnings": "^1.1.17",
|
|
106
|
+
"syncpack": "^9.8.6",
|
|
107
|
+
"ts-toolbelt": "^9.6.0",
|
|
108
|
+
"type-fest": "^3.10.0",
|
|
109
|
+
"typescript": "^5.0.3"
|
|
110
|
+
},
|
|
111
|
+
"scripts": {
|
|
112
|
+
"build": "pnpm run clean:dist && pnpm run compile",
|
|
113
|
+
"clean:deps": "del-cli ./node_modules",
|
|
114
|
+
"clean:dist": "del-cli ./dist",
|
|
115
|
+
"commit": "commit",
|
|
116
|
+
"compile": "pnpm run /^compile:.*/",
|
|
117
|
+
"compile:main": "rollup -c ./rollup.config.cjs",
|
|
118
|
+
"compile:types": "tsc --project ./tsconfig.json",
|
|
119
|
+
"cut:changelog": "changelog",
|
|
120
|
+
"cut:post-version": "pnpm run build",
|
|
121
|
+
"lint": "eslint . --ext .ts,.cjs",
|
|
122
|
+
"repodog": "repodog",
|
|
123
|
+
"syncpack": "syncpack",
|
|
124
|
+
"test": "node --require=suppress-experimental-warnings --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
125
|
+
"type-check": "tsc --noEmit",
|
|
126
|
+
"validate": "syncpack format && syncpack lint-semver-ranges && pnpm run build && pnpm run lint && pnpm run type-check && pnpm run test",
|
|
127
|
+
"zcb:watch": "NODE_OPTIONS=\"--loader ts-node/esm\" node ./bin/zcb.mjs watch ./src/__testUtils__/configBuilder.ts ./src/__testUtils__/builtConfig.ts"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* eslint-disable prettier/prettier, import/no-default-export, unicorn/numeric-separators-style */
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
countryCode: "GB",
|
|
5
|
+
countryName: "United Kingdom",
|
|
6
|
+
distanceUnit: "km",
|
|
7
|
+
languageCodes: [
|
|
8
|
+
"en"
|
|
9
|
+
],
|
|
10
|
+
locales: [
|
|
11
|
+
"en_GB"
|
|
12
|
+
],
|
|
13
|
+
name: "alpha",
|
|
14
|
+
pages: {
|
|
15
|
+
contactDetails: {
|
|
16
|
+
name: "contactDetails",
|
|
17
|
+
sections: [
|
|
18
|
+
{
|
|
19
|
+
name: "header"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: "body",
|
|
23
|
+
sections: [
|
|
24
|
+
{
|
|
25
|
+
name: "main"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "sidebar"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "footer"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
personalDetails: {
|
|
38
|
+
name: "personalDetails",
|
|
39
|
+
sections: [
|
|
40
|
+
{
|
|
41
|
+
name: "header"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "body",
|
|
45
|
+
sections: [
|
|
46
|
+
{
|
|
47
|
+
name: "main"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "sidebar"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "footer"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
routes: [
|
|
61
|
+
{
|
|
62
|
+
page: "personalDetails",
|
|
63
|
+
path: "personal-details"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
page: "contactDetails",
|
|
67
|
+
path: "contact-details"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
timeouts: {
|
|
71
|
+
apollo: 10000
|
|
72
|
+
},
|
|
73
|
+
timezone: "Europe/London"
|
|
74
|
+
} as const;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const config = {
|
|
2
|
+
countryCode: 'GB',
|
|
3
|
+
countryName: 'United Kingdom',
|
|
4
|
+
distanceUnit: 'km',
|
|
5
|
+
languageCodes: ['en'],
|
|
6
|
+
locales: ['en_GB'],
|
|
7
|
+
name: 'alpha',
|
|
8
|
+
pages: {
|
|
9
|
+
contactDetails: {
|
|
10
|
+
name: 'contactDetails',
|
|
11
|
+
sections: [
|
|
12
|
+
{ name: 'header' },
|
|
13
|
+
{ name: 'body', sections: [{ name: 'main' }, { name: 'sidebar' }] },
|
|
14
|
+
{ name: 'footer' },
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
personalDetails: {
|
|
18
|
+
name: 'personalDetails',
|
|
19
|
+
sections: [
|
|
20
|
+
{ name: 'header' },
|
|
21
|
+
{ name: 'body', sections: [{ name: 'main' }, { name: 'sidebar' }] },
|
|
22
|
+
{ name: 'footer' },
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
routes: [
|
|
27
|
+
{ page: 'personalDetails', path: 'personal-details' },
|
|
28
|
+
{ page: 'contactDetails', path: 'contact-details' },
|
|
29
|
+
],
|
|
30
|
+
timeouts: { apollo: 10_000 },
|
|
31
|
+
timezone: 'Europe/London',
|
|
32
|
+
} as const;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import kebabCase from 'lodash/kebabCase.js';
|
|
2
|
+
import { createConfigBuilder } from '../createConfigBuilder.ts';
|
|
3
|
+
import {
|
|
4
|
+
type ConfigType,
|
|
5
|
+
type PageType,
|
|
6
|
+
type RouteType,
|
|
7
|
+
type SectionType,
|
|
8
|
+
configSchema,
|
|
9
|
+
pageSchema,
|
|
10
|
+
routeSchema,
|
|
11
|
+
sectionSchema,
|
|
12
|
+
} from './schema.ts';
|
|
13
|
+
|
|
14
|
+
const configBuilder = createConfigBuilder<ConfigType>(configSchema);
|
|
15
|
+
const routeBuilder = createConfigBuilder<RouteType>(routeSchema, { path: ({ page }) => kebabCase(page) });
|
|
16
|
+
const pageBuilder = createConfigBuilder<PageType>(pageSchema);
|
|
17
|
+
const sectionBuilder = createConfigBuilder<SectionType>(sectionSchema);
|
|
18
|
+
const subsectionBuilder = sectionBuilder.fork();
|
|
19
|
+
|
|
20
|
+
configBuilder
|
|
21
|
+
.countryCode('GB')
|
|
22
|
+
.countryName('United Kingdom')
|
|
23
|
+
.distanceUnit('km')
|
|
24
|
+
.languageCodes(['en'])
|
|
25
|
+
.locales(({ countryCode, languageCodes }) =>
|
|
26
|
+
languageCodes?.length && countryCode ? languageCodes.map(code => `${code}_${countryCode}`) : []
|
|
27
|
+
)
|
|
28
|
+
.name('alpha')
|
|
29
|
+
.pages({
|
|
30
|
+
contactDetails: pageBuilder
|
|
31
|
+
.name('contactDetails')
|
|
32
|
+
.sections([
|
|
33
|
+
sectionBuilder.name('header').flush(),
|
|
34
|
+
sectionBuilder
|
|
35
|
+
.name('body')
|
|
36
|
+
.sections([subsectionBuilder.name('main').flush(), subsectionBuilder.name('sidebar').flush()])
|
|
37
|
+
.flush(),
|
|
38
|
+
sectionBuilder.name('footer').flush(),
|
|
39
|
+
])
|
|
40
|
+
.flush(),
|
|
41
|
+
personalDetails: pageBuilder
|
|
42
|
+
.name('personalDetails')
|
|
43
|
+
.sections([
|
|
44
|
+
sectionBuilder.name('header').flush(),
|
|
45
|
+
sectionBuilder
|
|
46
|
+
.name('body')
|
|
47
|
+
.sections([subsectionBuilder.name('main').flush(), subsectionBuilder.name('sidebar').flush()])
|
|
48
|
+
.flush(),
|
|
49
|
+
sectionBuilder.name('footer').flush(),
|
|
50
|
+
])
|
|
51
|
+
.flush(),
|
|
52
|
+
})
|
|
53
|
+
.routes([routeBuilder.page('personalDetails').flush(), routeBuilder.page('contactDetails').flush()])
|
|
54
|
+
.timeouts({ apollo: 10_000 })
|
|
55
|
+
.timezone('Europe/London');
|
|
56
|
+
|
|
57
|
+
// eslint-disable-next-line import/no-default-export
|
|
58
|
+
export default configBuilder;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { countryCodes } from '../data/countryCodes.ts';
|
|
3
|
+
import { countryNames } from '../data/countryNames.ts';
|
|
4
|
+
import { distanceUnits } from '../data/distanceUnits.ts';
|
|
5
|
+
import { languageCodes } from '../data/languageCodes.ts';
|
|
6
|
+
import { timezones } from '../data/timezones.ts';
|
|
7
|
+
|
|
8
|
+
export const baseSectionSchema = z.object({
|
|
9
|
+
name: z.string(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type SectionType = z.infer<typeof baseSectionSchema> & {
|
|
13
|
+
sections?: SectionType[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const sectionSchema: z.ZodType<SectionType> = baseSectionSchema.extend({
|
|
17
|
+
sections: z.lazy(() => sectionSchema.array()).optional(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const pageSchema = z.object({
|
|
21
|
+
name: z.string(),
|
|
22
|
+
path: z.string().optional(),
|
|
23
|
+
queryParams: z.array(z.string()).optional(),
|
|
24
|
+
sections: z.array(sectionSchema).optional(),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type PageType = z.infer<typeof pageSchema>;
|
|
28
|
+
|
|
29
|
+
const baseRouteSchema = z.object({
|
|
30
|
+
aliases: z.array(z.string()).optional(),
|
|
31
|
+
page: z.string(),
|
|
32
|
+
path: z.string(),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export type RouteType = z.infer<typeof baseRouteSchema> & {
|
|
36
|
+
routes?: RouteType[];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const routeSchema: z.ZodType<RouteType> = baseRouteSchema.extend({
|
|
40
|
+
routes: z.lazy(() => routeSchema.array()).optional(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const configSchema = z.object({
|
|
44
|
+
countryCode: z.enum(countryCodes).optional(),
|
|
45
|
+
countryName: z.enum(countryNames).optional(),
|
|
46
|
+
distanceUnit: z.enum(distanceUnits).optional(),
|
|
47
|
+
languageCodes: z.array(z.enum(languageCodes)).optional(),
|
|
48
|
+
locales: z.array(z.string().regex(/[a-z]{2}_[A-Z]{2}/)).optional(),
|
|
49
|
+
name: z.string().optional(),
|
|
50
|
+
pages: z.record(pageSchema).optional(),
|
|
51
|
+
routes: z.array(routeSchema).optional(),
|
|
52
|
+
timeouts: z.record(z.number()).optional(),
|
|
53
|
+
timezone: z.enum(timezones).optional(),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export type ConfigType = z.infer<typeof configSchema>;
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { watchFile } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import shelljs from 'shelljs';
|
|
4
|
+
import yargs from 'yargs';
|
|
5
|
+
import type { ExperimentsCallback } from './types.ts';
|
|
6
|
+
import { writeConfig } from './utils/writeConfig.ts';
|
|
7
|
+
|
|
8
|
+
export const cli = () => {
|
|
9
|
+
yargs
|
|
10
|
+
.command(
|
|
11
|
+
'watch <inputFile> <outputFile>',
|
|
12
|
+
'watch a config builder and write ',
|
|
13
|
+
cmdYargs =>
|
|
14
|
+
cmdYargs
|
|
15
|
+
.positional('inputFile', {
|
|
16
|
+
demandOption: true,
|
|
17
|
+
desc: 'The relative path to the config builder root file',
|
|
18
|
+
type: 'string',
|
|
19
|
+
})
|
|
20
|
+
.positional('outputFile', {
|
|
21
|
+
demandOption: true,
|
|
22
|
+
desc: 'The relative path to the output config file',
|
|
23
|
+
type: 'string',
|
|
24
|
+
})
|
|
25
|
+
.option('experiments-callback', {
|
|
26
|
+
desc: 'The relative path to the experiment callback file',
|
|
27
|
+
type: 'string',
|
|
28
|
+
}),
|
|
29
|
+
argv => {
|
|
30
|
+
const fullWatchFilePath = resolve(process.cwd(), argv.inputFile);
|
|
31
|
+
shelljs.echo(`zcd watch => watching file: ${argv.inputFile}`);
|
|
32
|
+
|
|
33
|
+
watchFile(fullWatchFilePath, () => {
|
|
34
|
+
import(fullWatchFilePath)
|
|
35
|
+
.then(
|
|
36
|
+
({
|
|
37
|
+
default: configBuilder,
|
|
38
|
+
}: {
|
|
39
|
+
default: ReturnType<typeof import('./createConfigBuilder.ts')['createConfigBuilder']>;
|
|
40
|
+
}) => {
|
|
41
|
+
shelljs.echo('zcd watch => file change detected');
|
|
42
|
+
|
|
43
|
+
if (!configBuilder.validate()) {
|
|
44
|
+
shelljs.echo('zcd watch => invalid config');
|
|
45
|
+
shelljs.echo(`zcd watch => errors:\n${JSON.stringify(configBuilder.errors(), undefined, 2)}\n`);
|
|
46
|
+
shelljs.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
shelljs.echo('zcd watch => valid config');
|
|
50
|
+
shelljs.echo(`zcd watch => config values:\n${configBuilder.toJson()}\n`);
|
|
51
|
+
|
|
52
|
+
if (argv['experiments-callback']) {
|
|
53
|
+
import(resolve(process.cwd(), argv['experiments-callback']))
|
|
54
|
+
.then(({ default: experimentsCallback }: { default: ExperimentsCallback }) => {
|
|
55
|
+
void writeConfig(configBuilder.values(), { experimentsCallback, outputFile: argv.outputFile });
|
|
56
|
+
})
|
|
57
|
+
.catch((error: unknown) => {
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
shelljs.echo(`zcd watch => error message: ${error.message}`);
|
|
60
|
+
|
|
61
|
+
if (error.stack) {
|
|
62
|
+
shelljs.echo(`zcd watch => error stack:\n${error.stack}\n`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
void writeConfig(configBuilder.values(), { outputFile: argv.outputFile });
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
.catch((error: unknown) => {
|
|
74
|
+
if (error instanceof Error) {
|
|
75
|
+
shelljs.echo(`zcd watch => error message: ${error.message}`);
|
|
76
|
+
|
|
77
|
+
if (error.stack) {
|
|
78
|
+
shelljs.echo(`zcd watch => error stack:\n${error.stack}\n`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
.help().argv;
|
|
86
|
+
};
|