zcb 0.3.3 → 0.3.5

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 (98) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/cli.cjs +1 -1
  3. package/dist/cjs/cli.cjs.map +1 -1
  4. package/dist/cjs/index.cjs +1 -1
  5. package/dist/cjs/index.cjs.map +1 -1
  6. package/dist/cjs/templates/config.ts.hbs +1 -1
  7. package/dist/esm/cli.mjs +1 -1
  8. package/dist/esm/cli.mjs.map +1 -1
  9. package/dist/esm/index.mjs +1 -1
  10. package/dist/esm/index.mjs.map +1 -1
  11. package/dist/esm/templates/config.ts.hbs +1 -1
  12. package/dist/production.analysis.txt +24 -24
  13. package/dist/types/cjs/cli.d.cts +7 -1
  14. package/dist/types/cjs/cli.d.cts.map +1 -1
  15. package/dist/types/cjs/createConfigBuilder.d.cts +3 -3
  16. package/dist/types/cjs/createConfigBuilder.d.cts.map +1 -1
  17. package/dist/types/cjs/createConfigParser.d.cts.map +1 -1
  18. package/dist/types/cjs/transformers/runExperiments.d.cts.map +1 -1
  19. package/dist/types/cjs/utils/arrayHasInvalidDefaults.d.cts +2 -2
  20. package/dist/types/cjs/utils/arrayHasInvalidDefaults.d.cts.map +1 -1
  21. package/dist/types/cjs/utils/collateDefaultValues.d.cts +2 -2
  22. package/dist/types/cjs/utils/collateDefaultValues.d.cts.map +1 -1
  23. package/dist/types/cjs/utils/collateObjectPropertyDefaults.d.cts +2 -2
  24. package/dist/types/cjs/utils/collateObjectPropertyDefaults.d.cts.map +1 -1
  25. package/dist/types/cjs/utils/importValidateTransformWriteConfig.d.cts +2 -2
  26. package/dist/types/cjs/utils/importValidateTransformWriteConfig.d.cts.map +1 -1
  27. package/dist/types/cjs/utils/isInvalidPropertyOverride.d.cts.map +1 -1
  28. package/dist/types/cjs/utils/isPropertyReservedWord.d.cts.map +1 -1
  29. package/dist/types/cjs/utils/isSchemaValid.d.cts +2 -2
  30. package/dist/types/cjs/utils/isSchemaValid.d.cts.map +1 -1
  31. package/dist/types/cjs/utils/isValidPropertyDefinition.d.cts +2 -2
  32. package/dist/types/cjs/utils/isValidPropertyDefinition.d.cts.map +1 -1
  33. package/dist/types/cjs/utils/objectPropertyHasDefaults.d.cts +2 -2
  34. package/dist/types/cjs/utils/objectPropertyHasDefaults.d.cts.map +1 -1
  35. package/dist/types/cjs/utils/recordHasInvalidDefaults.d.cts +2 -2
  36. package/dist/types/cjs/utils/recordHasInvalidDefaults.d.cts.map +1 -1
  37. package/dist/types/cjs/utils/transformConfig.d.cts.map +1 -1
  38. package/dist/types/cjs/utils/transformWriteConfig.d.cts.map +1 -1
  39. package/dist/types/esm/cli.d.ts +7 -1
  40. package/dist/types/esm/cli.d.ts.map +1 -1
  41. package/dist/types/esm/createConfigBuilder.d.ts +3 -3
  42. package/dist/types/esm/createConfigBuilder.d.ts.map +1 -1
  43. package/dist/types/esm/createConfigParser.d.ts.map +1 -1
  44. package/dist/types/esm/transformers/runExperiments.d.ts.map +1 -1
  45. package/dist/types/esm/utils/arrayHasInvalidDefaults.d.ts +2 -2
  46. package/dist/types/esm/utils/arrayHasInvalidDefaults.d.ts.map +1 -1
  47. package/dist/types/esm/utils/collateDefaultValues.d.ts +2 -2
  48. package/dist/types/esm/utils/collateDefaultValues.d.ts.map +1 -1
  49. package/dist/types/esm/utils/collateObjectPropertyDefaults.d.ts +2 -2
  50. package/dist/types/esm/utils/collateObjectPropertyDefaults.d.ts.map +1 -1
  51. package/dist/types/esm/utils/importValidateTransformWriteConfig.d.ts +2 -2
  52. package/dist/types/esm/utils/importValidateTransformWriteConfig.d.ts.map +1 -1
  53. package/dist/types/esm/utils/isInvalidPropertyOverride.d.ts.map +1 -1
  54. package/dist/types/esm/utils/isPropertyReservedWord.d.ts.map +1 -1
  55. package/dist/types/esm/utils/isSchemaValid.d.ts +2 -2
  56. package/dist/types/esm/utils/isSchemaValid.d.ts.map +1 -1
  57. package/dist/types/esm/utils/isValidPropertyDefinition.d.ts +2 -2
  58. package/dist/types/esm/utils/isValidPropertyDefinition.d.ts.map +1 -1
  59. package/dist/types/esm/utils/objectPropertyHasDefaults.d.ts +2 -2
  60. package/dist/types/esm/utils/objectPropertyHasDefaults.d.ts.map +1 -1
  61. package/dist/types/esm/utils/recordHasInvalidDefaults.d.ts +2 -2
  62. package/dist/types/esm/utils/recordHasInvalidDefaults.d.ts.map +1 -1
  63. package/dist/types/esm/utils/transformConfig.d.ts.map +1 -1
  64. package/dist/types/esm/utils/transformWriteConfig.d.ts.map +1 -1
  65. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  66. package/package.json +48 -43
  67. package/pnpm-workspace.yaml +4 -0
  68. package/src/__testUtils__/builtConfig.ts +1 -1
  69. package/src/__testUtils__/configBuilder.ts +28 -22
  70. package/src/__testUtils__/schema.ts +2 -2
  71. package/src/cli.ts +9 -3
  72. package/src/createConfigBuilder.test.ts +157 -38
  73. package/src/createConfigBuilder.ts +44 -41
  74. package/src/createConfigParser.ts +1 -1
  75. package/src/createConfigReader.ts +2 -2
  76. package/src/templates/config.ts.hbs +1 -1
  77. package/src/transformers/cloneNonEnumerableValues.ts +1 -1
  78. package/src/transformers/runExperiments.ts +16 -5
  79. package/src/utils/arrayHasInvalidDefaults.ts +3 -3
  80. package/src/utils/collateDefaultValues.ts +5 -5
  81. package/src/utils/collateObjectPropertyDefaults.ts +4 -2
  82. package/src/utils/importValidateTransformWriteConfig.ts +25 -13
  83. package/src/utils/isInvalidPropertyOverride.ts +1 -1
  84. package/src/utils/isPropertyReservedWord.ts +1 -1
  85. package/src/utils/isSchemaValid.ts +2 -2
  86. package/src/utils/isValidPropertyDefinition.ts +3 -3
  87. package/src/utils/objectPropertyHasDefaults.ts +3 -3
  88. package/src/utils/recordHasInvalidDefaults.ts +3 -3
  89. package/src/utils/transformConfig.test.ts +14 -0
  90. package/src/utils/transformConfig.ts +16 -4
  91. package/src/utils/transformWriteConfig.test.ts +111 -0
  92. package/src/utils/transformWriteConfig.ts +15 -8
  93. package/dist/types/cjs/utils/jsonStringifyReplacer.d.cts +0 -109
  94. package/dist/types/cjs/utils/jsonStringifyReplacer.d.cts.map +0 -1
  95. package/dist/types/esm/utils/jsonStringifyReplacer.d.ts +0 -109
  96. package/dist/types/esm/utils/jsonStringifyReplacer.d.ts.map +0 -1
  97. package/src/__snapshots__/createConfigBuilder.test.ts.snap +0 -30
  98. package/src/utils/jsonStringifyReplacer.ts +0 -6
package/package.json CHANGED
@@ -1,19 +1,25 @@
1
1
  {
2
2
  "name": "zcb",
3
3
  "description": "Build configs with type safety from zod schema.",
4
- "version": "0.3.3",
4
+ "version": "0.3.5",
5
5
  "author": "miami-man",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/badbatch/zod-config-builder",
8
- "repository": "badbatch/zod-config-builder",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "badbatch/zod-config-builder"
11
+ },
9
12
  "bugs": "https://github.com/badbatch/zod-config-builder/issues",
10
13
  "type": "module",
11
14
  "bin": {
12
15
  "zcb": "./bin/zcb.js"
13
16
  },
14
- "main": "./dist/cjs/index.cjs",
17
+ "main": "./dist/cjs/index.mjs",
15
18
  "module": "./dist/esm/index.mjs",
16
- "types": "./dist/types/cjs/index.d.cts",
19
+ "types": "./dist/types/cjs/index.d.ts",
20
+ "imports": {
21
+ "#*": "./src/*"
22
+ },
17
23
  "exports": {
18
24
  ".": {
19
25
  "types": {
@@ -39,56 +45,55 @@
39
45
  "@types/fs-extra": "^11.0.4",
40
46
  "@types/json-schema": "^7.0.15",
41
47
  "@types/lodash-es": "^4.17.12",
42
- "@types/shelljs": "^0.8.17",
43
- "@types/uuid": "^10.0.0",
44
- "@types/yargs": "^17.0.33",
45
- "core-js": "^3.45.0",
46
- "fs-extra": "^11.3.1",
47
- "handlebars": "^4.7.8",
48
+ "@types/shelljs": "^0.10.0",
49
+ "@types/uuid": "^11.0.0",
50
+ "@types/yargs": "^17.0.35",
51
+ "core-js": "^3.49.0",
52
+ "fs-extra": "^11.3.6",
53
+ "handlebars": "^4.7.9",
48
54
  "json-schema": "^0.4.0",
49
- "lodash-es": "^4.17.21",
55
+ "lodash-es": "^4.18.1",
50
56
  "shelljs": "^0.10.0",
51
57
  "ts-node": "^10.9.2",
52
58
  "ts-toolbelt": "^9.6.0",
53
- "type-fest": "^4.41.0",
54
- "uuid": "^11.1.0",
59
+ "type-fest": "^5.8.0",
60
+ "uuid": "^14.0.1",
55
61
  "yargs": "^18.0.0",
56
- "zod": "^3.25.76",
57
- "zod-to-json-schema": "^3.24.6"
62
+ "zod": "^4.4.3",
63
+ "zod-to-json-schema": "^3.25.2"
58
64
  },
59
65
  "devDependencies": {
60
- "@commitlint/cli": "^19.8.1",
61
- "@jest/globals": "^29.7.0",
62
- "@repodog/cli": "^1.6.45",
63
- "@repodog/commitlint-config": "^19.0.5",
64
- "@repodog/eslint-config": "^9.0.18",
65
- "@repodog/eslint-config-jest": "^9.0.6",
66
- "@repodog/jest-config": "^29.0.5",
67
- "@repodog/markdownlint-config": "^1.2.5",
68
- "@repodog/prettier-config": "^3.0.3",
69
- "@repodog/rollup-config": "^4.0.11",
70
- "@repodog/swc-config": "^1.0.12",
71
- "@repodog/syncpack-config": "^13.0.4",
72
- "@repodog/ts-config": "^5.0.5",
73
- "@rollup/plugin-swc": "^0.3.0",
74
- "@swc/core": "^1.13.3",
66
+ "@commitlint/cli": "^21.2.1",
67
+ "@jest/globals": "^30.4.1",
68
+ "@repodog/cli": "^1.6.59",
69
+ "@repodog/commitlint-config": "^21.0.2",
70
+ "@repodog/eslint-config": "^9.0.29",
71
+ "@repodog/eslint-config-jest": "^9.0.9",
72
+ "@repodog/jest-config": "^30.0.4",
73
+ "@repodog/markdownlint-config": "^1.2.7",
74
+ "@repodog/prettier-config": "^3.0.5",
75
+ "@repodog/rollup-config": "^4.0.17",
76
+ "@repodog/swc-config": "^1.0.15",
77
+ "@repodog/syncpack-config": "^15.0.3",
78
+ "@repodog/ts-config": "^6.0.3",
79
+ "@rollup/plugin-swc": "^0.4.1",
80
+ "@swc/core": "^1.15.43",
75
81
  "@swc/jest": "^0.2.39",
76
- "@types/jest": "^29.5.13",
82
+ "@types/jest": "^30.0.0",
77
83
  "@types/node": "^24.2.1",
78
- "cts-types": "^0.0.10",
79
- "del-cli": "^6.0.0",
80
- "eslint": "^9.33.0",
84
+ "cts-types": "^0.0.11",
85
+ "del-cli": "^7.0.0",
86
+ "eslint": "^9.39.4",
81
87
  "generate-changelog": "^1.8.0",
82
88
  "husky": "^9.1.7",
83
- "jest": "^29.7.0",
84
- "jest-environment-jsdom": "^29.7.0",
85
- "jest-environment-node": "^29.7.0",
86
- "markdownlint-cli2": "^0.18.1",
87
- "prettier": "^3.6.2",
88
- "rollup": "^4.46.2",
89
+ "jest": "^30.4.2",
90
+ "jest-environment-node": "^30.4.1",
91
+ "markdownlint-cli2": "^0.23.0",
92
+ "prettier": "^3.9.5",
93
+ "rollup": "^4.62.2",
89
94
  "suppress-experimental-warnings": "^2.0.0",
90
- "syncpack": "^13.0.4",
91
- "typescript": "^5.9.2"
95
+ "syncpack": "^15.3.2",
96
+ "typescript": "^6.0.3"
92
97
  },
93
98
  "keywords": [
94
99
  "config",
@@ -110,7 +115,7 @@
110
115
  "lint:code": "eslint .",
111
116
  "lint:docs": "markdownlint-cli2 --config \".markdownlint.json\" \"**/*.md\" \"!**/node_modules/**\"",
112
117
  "repodog": "repodog",
113
- "syncpack": "syncpack format && syncpack list-mismatches && syncpack lint-semver-ranges",
118
+ "syncpack": "syncpack format --check && syncpack lint",
114
119
  "test": "COMPILER=swc node --require=suppress-experimental-warnings --experimental-vm-modules node_modules/jest/bin/jest.js",
115
120
  "type-check": "tsc --noEmit",
116
121
  "validate": "pnpm run syncpack && pnpm run build && pnpm run lint && pnpm run type-check && pnpm run test",
@@ -0,0 +1,4 @@
1
+ allowBuilds:
2
+ '@swc/core': false
3
+ core-js: false
4
+ unrs-resolver: false
@@ -1,4 +1,4 @@
1
- /* eslint-disable prettier/prettier, import-x/no-default-export, unicorn/numeric-separators-style, unicorn/no-null */
1
+ /* eslint-disable import-x/no-default-export, unicorn/numeric-separators-style, unicorn/no-null */
2
2
  /* This file is autogenerated, do not edit directly, your changes will not perist. */
3
3
 
4
4
  export default {
@@ -17,6 +17,32 @@ const pageBuilder = createConfigBuilder<PageType>(pageSchema);
17
17
  const sectionBuilder = createConfigBuilder<SectionType>(sectionSchema);
18
18
  const subsectionBuilder = sectionBuilder.$fork();
19
19
 
20
+ const contactDetailsPage = pageBuilder
21
+ .name('contactDetails')
22
+ .sections([
23
+ sectionBuilder.name('header').$flush(),
24
+ sectionBuilder
25
+ .name('body')
26
+ .sections([subsectionBuilder.name('main').$flush(), subsectionBuilder.name('sidebar').$flush()])
27
+ .$flush(),
28
+ sectionBuilder.name('footer').$flush(),
29
+ ])
30
+ .$flush();
31
+
32
+ const personalDetailPage = pageBuilder
33
+ .name('personalDetails')
34
+ .sections([
35
+ sectionBuilder.name('header').$flush(),
36
+ sectionBuilder
37
+ .name('body')
38
+ .sections([subsectionBuilder.name('main').$flush(), subsectionBuilder.name('sidebar').$flush()])
39
+ .$flush(),
40
+ sectionBuilder.name('footer').$flush(),
41
+ ])
42
+ .$flush();
43
+
44
+ // Required for how builder is executed
45
+ // eslint-disable-next-line unicorn/no-top-level-side-effects
20
46
  configBuilder
21
47
  .countryCode('GB')
22
48
  // Want to test using null value
@@ -29,28 +55,8 @@ configBuilder
29
55
  languageCodes?.length && countryCode ? languageCodes.map(code => `${code}_${countryCode}`) : [],
30
56
  )
31
57
  .pages({
32
- contactDetails: pageBuilder
33
- .name('contactDetails')
34
- .sections([
35
- sectionBuilder.name('header').$flush(),
36
- sectionBuilder
37
- .name('body')
38
- .sections([subsectionBuilder.name('main').$flush(), subsectionBuilder.name('sidebar').$flush()])
39
- .$flush(),
40
- sectionBuilder.name('footer').$flush(),
41
- ])
42
- .$flush(),
43
- personalDetails: pageBuilder
44
- .name('personalDetails')
45
- .sections([
46
- sectionBuilder.name('header').$flush(),
47
- sectionBuilder
48
- .name('body')
49
- .sections([subsectionBuilder.name('main').$flush(), subsectionBuilder.name('sidebar').$flush()])
50
- .$flush(),
51
- sectionBuilder.name('footer').$flush(),
52
- ])
53
- .$flush(),
58
+ contactDetails: contactDetailsPage,
59
+ personalDetails: personalDetailPage,
54
60
  })
55
61
  .routes([routeBuilder.page('personalDetails').$flush(), routeBuilder.page('contactDetails').$flush()])
56
62
  .timeouts({ apollo: 10_000 })
@@ -48,9 +48,9 @@ export const configSchema = z.object({
48
48
  languageCodes: z.array(z.enum(languageCodes)).optional(),
49
49
  locales: z.array(z.string().regex(/[a-z]{2}_[A-Z]{2}/)).optional(),
50
50
  name: z.string().optional(),
51
- pages: z.record(pageSchema).optional(),
51
+ pages: z.record(z.string(), pageSchema).optional(),
52
52
  routes: z.array(routeSchema).optional(),
53
- timeouts: z.record(z.number()).optional(),
53
+ timeouts: z.record(z.string(), z.number()).optional(),
54
54
  timezone: z.enum(timezones).optional(),
55
55
  });
56
56
 
package/src/cli.ts CHANGED
@@ -5,9 +5,15 @@ import yargs, { type Argv } from 'yargs';
5
5
  import { hideBin } from 'yargs/helpers';
6
6
  import { importValidateTransformWriteConfig } from './utils/importValidateTransformWriteConfig.ts';
7
7
 
8
- export type Commands = 'build' | 'watch';
8
+ export type CliCommands = 'build' | 'watch';
9
9
 
10
- const generateArguments = (cmdYargs: Argv) =>
10
+ export type CliArguments = Argv<{
11
+ 'experiments-callback-file'?: string;
12
+ 'input-file': string;
13
+ 'output-file': string;
14
+ }>;
15
+
16
+ const generateArguments = (cmdYargs: Argv): CliArguments =>
11
17
  cmdYargs
12
18
  .positional('input-file', {
13
19
  demandOption: true,
@@ -24,7 +30,7 @@ const generateArguments = (cmdYargs: Argv) =>
24
30
  type: 'string',
25
31
  });
26
32
 
27
- export const cli = () => {
33
+ export const cli = (): void => {
28
34
  // yargs does not provide a way to pass generic to type args.
29
35
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
30
36
  const argv = yargs(hideBin(process.argv)) as Argv<{
@@ -1,5 +1,5 @@
1
1
  import { kebabCase } from 'lodash-es';
2
- import { ZodType, z } from 'zod';
2
+ import { z } from 'zod';
3
3
  import {
4
4
  type ConfigType,
5
5
  type PageType,
@@ -62,7 +62,11 @@ describe('createConfigBuilder', () => {
62
62
  it('should copy over all values to the new config', async () => {
63
63
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
64
64
  const config = createConfigBuilder<ConfigType>(configSchema);
65
- const route = createConfigBuilder<RouteType>(routeSchema, undefined, { path: ({ page }) => kebabCase(page) });
65
+
66
+ const route = createConfigBuilder<RouteType>(routeSchema, undefined, {
67
+ path: ({ page }) => kebabCase(page),
68
+ });
69
+
66
70
  const page = createConfigBuilder<PageType>(pageSchema);
67
71
 
68
72
  config
@@ -85,13 +89,19 @@ describe('createConfigBuilder', () => {
85
89
  it('should copy over all experiments to the new config', async () => {
86
90
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
87
91
  const config = createConfigBuilder<ConfigType>(configSchema);
88
- const route = createConfigBuilder<RouteType>(routeSchema, undefined, { path: ({ page }) => kebabCase(page) });
92
+
93
+ const route = createConfigBuilder<RouteType>(routeSchema, undefined, {
94
+ path: ({ page }) => kebabCase(page),
95
+ });
96
+
89
97
  const page = createConfigBuilder<PageType>(pageSchema);
90
98
 
91
99
  config
92
100
  .$experiment('FEAT_ALPHA@0.0.1')
93
101
  .name('alpha')
94
- .pages({ contactDetails: page.$experiment('FEAT_BRAVO@0.0.1').name('contactDetails').$flush() })
102
+ .pages({
103
+ contactDetails: page.$experiment('FEAT_BRAVO@0.0.1').name('contactDetails').$flush(),
104
+ })
95
105
  .routes([route.$experiment('FEAT_CHARLIE@0.0.1').page('contactDetails').$flush()]);
96
106
 
97
107
  const childConfig = createConfigBuilder<ConfigType>(configSchema);
@@ -102,13 +112,14 @@ describe('createConfigBuilder', () => {
102
112
  __experiment: 'FEAT_ALPHA@0.0.1',
103
113
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
104
114
  pages: expect.objectContaining({
105
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
115
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, unicorn/max-nested-calls
106
116
  contactDetails: expect.objectContaining({
107
117
  __experiment: 'FEAT_BRAVO@0.0.1',
108
118
  }),
109
119
  }),
110
120
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
111
121
  routes: expect.arrayContaining([
122
+ // eslint-disable-next-line unicorn/max-nested-calls
112
123
  expect.objectContaining({
113
124
  __experiment: 'FEAT_CHARLIE@0.0.1',
114
125
  }),
@@ -120,13 +131,19 @@ describe('createConfigBuilder', () => {
120
131
  it('should copy over all disabled flags to the new config', async () => {
121
132
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
122
133
  const config = createConfigBuilder<ConfigType>(configSchema);
123
- const route = createConfigBuilder<RouteType>(routeSchema, undefined, { path: ({ page }) => kebabCase(page) });
134
+
135
+ const route = createConfigBuilder<RouteType>(routeSchema, undefined, {
136
+ path: ({ page }) => kebabCase(page),
137
+ });
138
+
124
139
  const page = createConfigBuilder<PageType>(pageSchema);
125
140
 
126
141
  config
127
142
  .$disable()
128
143
  .name('alpha')
129
- .pages({ contactDetails: page.$disable().name('contactDetails').$flush() })
144
+ .pages({
145
+ contactDetails: page.$disable().name('contactDetails').$flush(),
146
+ })
130
147
  .routes([route.$disable().page('contactDetails').$flush()]);
131
148
 
132
149
  const childConfig = createConfigBuilder<ConfigType>(configSchema);
@@ -137,13 +154,14 @@ describe('createConfigBuilder', () => {
137
154
  __disabled: true,
138
155
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
139
156
  pages: expect.objectContaining({
140
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
157
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, unicorn/max-nested-calls
141
158
  contactDetails: expect.objectContaining({
142
159
  __disabled: true,
143
160
  }),
144
161
  }),
145
162
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
146
163
  routes: expect.arrayContaining([
164
+ // eslint-disable-next-line unicorn/max-nested-calls
147
165
  expect.objectContaining({
148
166
  __disabled: true,
149
167
  }),
@@ -154,12 +172,20 @@ describe('createConfigBuilder', () => {
154
172
 
155
173
  it('should copy over all derived value callbacks to the new config builder', async () => {
156
174
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
157
- const route = createConfigBuilder<RouteType>(routeSchema, undefined, { path: ({ page }) => kebabCase(page) });
175
+
176
+ const route = createConfigBuilder<RouteType>(routeSchema, undefined, {
177
+ path: ({ page }) => kebabCase(page),
178
+ });
179
+
158
180
  route.page('personalDetails');
159
181
  const childRoute = createConfigBuilder<RouteType>(routeSchema);
160
182
  childRoute.$extend(route);
161
183
  childRoute.page('contactDetails', true);
162
- expect(childRoute.$values()).toEqual({ page: 'contactDetails', path: 'contact-details' });
184
+
185
+ expect(childRoute.$values()).toEqual({
186
+ page: 'contactDetails',
187
+ path: 'contact-details',
188
+ });
163
189
  });
164
190
  });
165
191
 
@@ -174,7 +200,23 @@ describe('createConfigBuilder', () => {
174
200
  });
175
201
 
176
202
  const config = createConfigBuilder<z.infer<typeof extendedSchema>>(extendedSchema);
177
- expect(config.$values()).toEqual({ description: 'This is the description.' });
203
+
204
+ expect(config.$values()).toMatchInlineSnapshot(`
205
+ {
206
+ "countryCode": undefined,
207
+ "countryName": undefined,
208
+ "description": "This is the description.",
209
+ "distanceUnit": undefined,
210
+ "enabled": undefined,
211
+ "languageCodes": undefined,
212
+ "locales": undefined,
213
+ "name": undefined,
214
+ "pages": undefined,
215
+ "routes": undefined,
216
+ "timeouts": undefined,
217
+ "timezone": undefined,
218
+ }
219
+ `);
178
220
  });
179
221
  });
180
222
 
@@ -183,11 +225,31 @@ describe('createConfigBuilder', () => {
183
225
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
184
226
 
185
227
  const extendedSchema = configSchema.extend({
186
- flags: z.record(z.boolean()).optional().default({ alpha: true, bravo: false, charlie: false }),
228
+ flags: z.record(z.string(), z.boolean()).optional().default({ alpha: true, bravo: false, charlie: false }),
187
229
  });
188
230
 
189
231
  const config = createConfigBuilder<z.infer<typeof extendedSchema>>(extendedSchema);
190
- expect(config.$values()).toEqual({ flags: { alpha: true, bravo: false, charlie: false } });
232
+
233
+ expect(config.$values()).toMatchInlineSnapshot(`
234
+ {
235
+ "countryCode": undefined,
236
+ "countryName": undefined,
237
+ "distanceUnit": undefined,
238
+ "enabled": undefined,
239
+ "flags": {
240
+ "alpha": true,
241
+ "bravo": false,
242
+ "charlie": false,
243
+ },
244
+ "languageCodes": undefined,
245
+ "locales": undefined,
246
+ "name": undefined,
247
+ "pages": undefined,
248
+ "routes": undefined,
249
+ "timeouts": undefined,
250
+ "timezone": undefined,
251
+ }
252
+ `);
191
253
  });
192
254
  });
193
255
 
@@ -200,7 +262,28 @@ describe('createConfigBuilder', () => {
200
262
  });
201
263
 
202
264
  const config = createConfigBuilder<z.infer<typeof extendedSchema>>(extendedSchema);
203
- expect(config.$values()).toEqual({ colors: ['red', 'yellow', 'pink', 'green'] });
265
+
266
+ expect(config.$values()).toMatchInlineSnapshot(`
267
+ {
268
+ "colors": [
269
+ "red",
270
+ "yellow",
271
+ "pink",
272
+ "green",
273
+ ],
274
+ "countryCode": undefined,
275
+ "countryName": undefined,
276
+ "distanceUnit": undefined,
277
+ "enabled": undefined,
278
+ "languageCodes": undefined,
279
+ "locales": undefined,
280
+ "name": undefined,
281
+ "pages": undefined,
282
+ "routes": undefined,
283
+ "timeouts": undefined,
284
+ "timezone": undefined,
285
+ }
286
+ `);
204
287
  });
205
288
  });
206
289
 
@@ -218,7 +301,26 @@ describe('createConfigBuilder', () => {
218
301
  });
219
302
 
220
303
  const config = createConfigBuilder<z.infer<typeof extendedSchema>>(extendedSchema);
221
- expect(config.$values()).toEqual({ flags: { alpha: true, bravo: true } });
304
+
305
+ expect(config.$values()).toMatchInlineSnapshot(`
306
+ {
307
+ "countryCode": undefined,
308
+ "countryName": undefined,
309
+ "distanceUnit": undefined,
310
+ "enabled": undefined,
311
+ "flags": {
312
+ "alpha": true,
313
+ "bravo": true,
314
+ },
315
+ "languageCodes": undefined,
316
+ "locales": undefined,
317
+ "name": undefined,
318
+ "pages": undefined,
319
+ "routes": undefined,
320
+ "timeouts": undefined,
321
+ "timezone": undefined,
322
+ }
323
+ `);
222
324
  });
223
325
  });
224
326
  });
@@ -229,7 +331,7 @@ describe('createConfigBuilder', () => {
229
331
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
230
332
 
231
333
  const extendedSchema = configSchema.extend({
232
- flags: z.record(z.boolean().default(true)).optional(),
334
+ flags: z.record(z.string(), z.boolean().default(true)).optional(),
233
335
  });
234
336
 
235
337
  expect(() => createConfigBuilder<z.infer<typeof extendedSchema>>(extendedSchema)).toThrow(
@@ -399,7 +501,11 @@ describe('createConfigBuilder', () => {
399
501
  it('should add the value to the config', async () => {
400
502
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
401
503
  const config = createConfigBuilder<ConfigType>(configSchema);
402
- const route = createConfigBuilder<RouteType>(routeSchema, undefined, { path: ({ page }) => kebabCase(page) });
504
+
505
+ const route = createConfigBuilder<RouteType>(routeSchema, undefined, {
506
+ path: ({ page }) => kebabCase(page),
507
+ });
508
+
403
509
  const subRoute = route.$fork();
404
510
 
405
511
  config.routes([
@@ -428,7 +534,10 @@ describe('createConfigBuilder', () => {
428
534
  it('should be a valid config', async () => {
429
535
  const { createConfigBuilder } = await import('./createConfigBuilder.ts');
430
536
  const config = createConfigBuilder<ConfigType>(configSchema);
431
- const route = createConfigBuilder<RouteType>(routeSchema, undefined, { path: ({ page }) => kebabCase(page) });
537
+
538
+ const route = createConfigBuilder<RouteType>(routeSchema, undefined, {
539
+ path: ({ page }) => kebabCase(page),
540
+ });
432
541
 
433
542
  config.routes([
434
543
  route.page('personalDetails').$flush(),
@@ -483,7 +592,11 @@ describe('createConfigBuilder', () => {
483
592
  languageCodes?.length && countryCode ? languageCodes.map(code => `${code}_${countryCode}` as const) : [],
484
593
  );
485
594
 
486
- expect(config.$values()).toEqual({ countryCode: 'GB', languageCodes: ['en'], locales: ['en_GB'] });
595
+ expect(config.$values()).toEqual({
596
+ countryCode: 'GB',
597
+ languageCodes: ['en'],
598
+ locales: ['en_GB'],
599
+ });
487
600
  });
488
601
 
489
602
  it('should update the value to the config automatically', async () => {
@@ -499,7 +612,11 @@ describe('createConfigBuilder', () => {
499
612
  )
500
613
  .languageCodes(['fr'], true);
501
614
 
502
- expect(config.$values()).toEqual({ countryCode: 'GB', languageCodes: ['fr'], locales: ['fr_GB'] });
615
+ expect(config.$values()).toEqual({
616
+ countryCode: 'GB',
617
+ languageCodes: ['fr'],
618
+ locales: ['fr_GB'],
619
+ });
503
620
  });
504
621
 
505
622
  it('should be a valid config', async () => {
@@ -520,27 +637,29 @@ describe('createConfigBuilder', () => {
520
637
  });
521
638
 
522
639
  describe('when a user stringifies the config', () => {
523
- describe('when a config value is a zod schema', () => {
524
- it('should stringify the value to JSON schema correctly', async () => {
525
- const { createConfigBuilder } = await import('./createConfigBuilder.ts');
526
-
527
- const extendedSchema = configSchema.extend({
528
- schema: z.instanceof(ZodType),
529
- });
530
-
531
- const config = createConfigBuilder<z.infer<typeof extendedSchema>>(extendedSchema);
640
+ it('should stringify the value to JSON correctly', async () => {
641
+ const { createConfigBuilder } = await import('./createConfigBuilder.ts');
642
+ const config = createConfigBuilder<ConfigType>(configSchema);
532
643
 
533
- config.schema(
534
- z
535
- .object({
536
- alpha: z.string(),
537
- bravo: z.boolean(),
538
- })
539
- .optional(),
644
+ config
645
+ .countryCode('GB')
646
+ .languageCodes(['en'])
647
+ .locales(({ countryCode, languageCodes }) =>
648
+ // eslint-disable-next-line jest/no-conditional-in-test
649
+ languageCodes?.length && countryCode ? languageCodes.map(code => `${code}_${countryCode}`) : [],
540
650
  );
541
651
 
542
- expect(config.$toJson()).toMatchSnapshot();
543
- });
652
+ expect(config.$toJson()).toMatchInlineSnapshot(`
653
+ "{
654
+ "countryCode": "GB",
655
+ "languageCodes": [
656
+ "en"
657
+ ],
658
+ "locales": [
659
+ "en_GB"
660
+ ]
661
+ }"
662
+ `);
544
663
  });
545
664
  });
546
665
  });