@gtkx/config 0.21.0 → 1.0.0-rc.2

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 (82) hide show
  1. package/README.md +137 -82
  2. package/dist/config-error.d.ts +16 -0
  3. package/dist/config-error.d.ts.map +1 -0
  4. package/dist/config-error.js +45 -0
  5. package/dist/config-error.js.map +1 -0
  6. package/dist/config.d.ts +73 -37
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +123 -82
  9. package/dist/config.js.map +1 -1
  10. package/dist/index.d.ts +2 -10
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -8
  13. package/dist/index.js.map +1 -1
  14. package/dist/internal.d.ts +3 -0
  15. package/dist/internal.d.ts.map +1 -0
  16. package/dist/internal.js +3 -0
  17. package/dist/internal.js.map +1 -0
  18. package/dist/loader.d.ts +21 -16
  19. package/dist/loader.d.ts.map +1 -1
  20. package/dist/loader.js +26 -38
  21. package/dist/loader.js.map +1 -1
  22. package/dist/user-event-signals.d.ts +4 -0
  23. package/dist/user-event-signals.d.ts.map +1 -0
  24. package/dist/user-event-signals.js +54 -0
  25. package/dist/user-event-signals.js.map +1 -0
  26. package/dist/virtual.d.ts +9 -6
  27. package/dist/virtual.d.ts.map +1 -1
  28. package/dist/virtual.js +26 -18
  29. package/dist/virtual.js.map +1 -1
  30. package/dist/vite-plugin.d.ts +16 -0
  31. package/dist/vite-plugin.d.ts.map +1 -0
  32. package/dist/vite-plugin.js +31 -0
  33. package/dist/vite-plugin.js.map +1 -0
  34. package/package.json +18 -11
  35. package/src/config-error.ts +67 -0
  36. package/src/config.ts +227 -145
  37. package/src/index.ts +3 -83
  38. package/src/internal.ts +2 -0
  39. package/src/loader.ts +44 -55
  40. package/src/user-event-signals.ts +57 -0
  41. package/src/virtual.ts +28 -34
  42. package/src/vite-plugin.ts +51 -0
  43. package/dist/bundled-modules.d.ts +0 -2
  44. package/dist/bundled-modules.d.ts.map +0 -1
  45. package/dist/bundled-modules.js +0 -2
  46. package/dist/bundled-modules.js.map +0 -1
  47. package/dist/data-dir.d.ts +0 -4
  48. package/dist/data-dir.d.ts.map +0 -1
  49. package/dist/data-dir.js +0 -37
  50. package/dist/data-dir.js.map +0 -1
  51. package/dist/plugin.d.ts +0 -9
  52. package/dist/plugin.d.ts.map +0 -1
  53. package/dist/plugin.js +0 -24
  54. package/dist/plugin.js.map +0 -1
  55. package/dist/runtime.d.ts +0 -22
  56. package/dist/runtime.d.ts.map +0 -1
  57. package/dist/runtime.js +0 -22
  58. package/dist/runtime.js.map +0 -1
  59. package/dist/table-rules-ir.d.ts +0 -36
  60. package/dist/table-rules-ir.d.ts.map +0 -1
  61. package/dist/table-rules-ir.js +0 -2
  62. package/dist/table-rules-ir.js.map +0 -1
  63. package/dist/table-schema.d.ts +0 -107
  64. package/dist/table-schema.d.ts.map +0 -1
  65. package/dist/table-schema.js +0 -199
  66. package/dist/table-schema.js.map +0 -1
  67. package/dist/validators.d.ts +0 -4
  68. package/dist/validators.d.ts.map +0 -1
  69. package/dist/validators.js +0 -10
  70. package/dist/validators.js.map +0 -1
  71. package/dist/wrapper-protocol.d.ts +0 -12
  72. package/dist/wrapper-protocol.d.ts.map +0 -1
  73. package/dist/wrapper-protocol.js +0 -12
  74. package/dist/wrapper-protocol.js.map +0 -1
  75. package/env.d.ts +0 -26
  76. package/src/bundled-modules.ts +0 -1
  77. package/src/data-dir.ts +0 -39
  78. package/src/plugin.ts +0 -30
  79. package/src/table-rules-ir.ts +0 -42
  80. package/src/table-schema.ts +0 -342
  81. package/src/validators.ts +0 -15
  82. package/src/wrapper-protocol.ts +0 -21
package/dist/virtual.js CHANGED
@@ -1,20 +1,28 @@
1
- export const GTKX_CONFIG_VIRTUAL_ID = "virtual:gtkx-config";
2
- export const RESOLVED_GTKX_CONFIG_VIRTUAL_ID = `\0${GTKX_CONFIG_VIRTUAL_ID}`;
1
+ const GTKX_CONFIG_VIRTUAL_ID = "virtual:gtkx-config";
2
+ const RESOLVED_GTKX_CONFIG_VIRTUAL_ID = `\0${GTKX_CONFIG_VIRTUAL_ID}`;
3
3
  const METADATA_SPECIFIER = "@gtkx/jsx/metadata";
4
- const serializeConfigValue = (value) => (value === undefined ? "undefined" : JSON.stringify(value));
5
- export const serializeGtkxConfig = (config) => ({
6
- libraries: config.libraries,
7
- girPath: config.girPath,
8
- applicationId: config.applicationId,
9
- containerProps: config.containerProps,
10
- arrayProps: config.arrayProps,
11
- objectProps: config.objectProps,
12
- virtualProps: config.virtualProps,
13
- elementMap: config.elementMap,
14
- reactCompiler: config.reactCompiler,
15
- });
16
- export const renderGtkxConfigModule = (config) => [
17
- `export * from ${JSON.stringify(METADATA_SPECIFIER)};`,
18
- ...Object.entries(serializeGtkxConfig(config)).map(([key, value]) => `export const ${key} = ${serializeConfigValue(value)};`),
19
- ].join("\n");
4
+ const lazyElementConfig = (lazyElements) => Object.fromEntries(lazyElements.map((type) => [type, { lazy: true }]));
5
+ /**
6
+ * The runtime element config is the app's static per-element config (currently its lazy flags) merged
7
+ * with its behaviors module, so a single `elements` map is registered.
8
+ */
9
+ const renderConfigModule = (config) => {
10
+ const lazyJson = JSON.stringify(lazyElementConfig(config.lazyElements));
11
+ const behaviorImports = config.elements === null
12
+ ? []
13
+ : [
14
+ "import { mergeElementConfigs } from \"@gtkx/react/config\";",
15
+ `import __elementBehaviors from ${JSON.stringify(config.elements)};`,
16
+ ];
17
+ return [
18
+ ...behaviorImports,
19
+ `export * from ${JSON.stringify(METADATA_SPECIFIER)};`,
20
+ `export const applicationId = ${JSON.stringify(config.applicationId)};`,
21
+ `export const userEventSignals = ${JSON.stringify(config.userEventSignals)};`,
22
+ config.elements === null
23
+ ? `export const elements = ${lazyJson};`
24
+ : `export const elements = mergeElementConfigs(__elementBehaviors, ${lazyJson});`,
25
+ ].join("\n");
26
+ };
27
+ export { GTKX_CONFIG_VIRTUAL_ID, RESOLVED_GTKX_CONFIG_VIRTUAL_ID, renderConfigModule };
20
28
  //# sourceMappingURL=virtual.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtual.js","sourceRoot":"","sources":["../src/virtual.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AAE5D,MAAM,CAAC,MAAM,+BAA+B,GAAW,KAAK,sBAAsB,EAAE,CAAC;AAErF,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAehD,MAAM,oBAAoB,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAErH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAA0B,EAAwB,EAAE,CAAC,CAAC;IACtF,SAAS,EAAE,MAAM,CAAC,SAAS;IAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;IACvB,aAAa,EAAE,MAAM,CAAC,aAAa;IACnC,cAAc,EAAE,MAAM,CAAC,cAAc;IACrC,UAAU,EAAE,MAAM,CAAC,UAAU;IAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;IAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;IACjC,UAAU,EAAE,MAAM,CAAC,UAAU;IAC7B,aAAa,EAAE,MAAM,CAAC,aAAa;CACtC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAA0B,EAAU,EAAE,CACzE;IACI,iBAAiB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG;IACtD,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAC9C,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,gBAAgB,GAAG,MAAM,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAC5E;CACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"virtual.js","sourceRoot":"","sources":["../src/virtual.ts"],"names":[],"mappings":"AAEA,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AACrD,MAAM,+BAA+B,GAAG,KAAK,sBAAsB,EAAE,CAAC;AACtE,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEhD,MAAM,iBAAiB,GAAG,CAAC,YAAsB,EAAkC,EAAE,CACjF,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAE3E;;;GAGG;AACH,MAAM,kBAAkB,GAAG,CAAC,MAAsB,EAAU,EAAE;IAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IAExE,MAAM,eAAe,GACjB,MAAM,CAAC,QAAQ,KAAK,IAAI;QACpB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC;YACM,6DAA6D;YAC7D,kCAAkC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG;SACvE,CAAC;IAEd,OAAO;QACH,GAAG,eAAe;QAClB,iBAAiB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG;QACtD,gCAAgC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG;QACvE,mCAAmC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG;QAC7E,MAAM,CAAC,QAAQ,KAAK,IAAI;YACpB,CAAC,CAAC,2BAA2B,QAAQ,GAAG;YACxC,CAAC,CAAC,mEAAmE,QAAQ,IAAI;KACxF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,+BAA+B,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["import type { ResolvedConfig } from \"./config.js\";\n\nconst GTKX_CONFIG_VIRTUAL_ID = \"virtual:gtkx-config\";\nconst RESOLVED_GTKX_CONFIG_VIRTUAL_ID = `\\0${GTKX_CONFIG_VIRTUAL_ID}`;\nconst METADATA_SPECIFIER = \"@gtkx/jsx/metadata\";\n\nconst lazyElementConfig = (lazyElements: string[]): Record<string, { lazy: true }> =>\n Object.fromEntries(lazyElements.map((type) => [type, { lazy: true }]));\n\n/**\n * The runtime element config is the app's static per-element config (currently its lazy flags) merged\n * with its behaviors module, so a single `elements` map is registered.\n */\nconst renderConfigModule = (config: ResolvedConfig): string => {\n const lazyJson = JSON.stringify(lazyElementConfig(config.lazyElements));\n\n const behaviorImports =\n config.elements === null\n ? []\n : [\n \"import { mergeElementConfigs } from \\\"@gtkx/react/config\\\";\",\n `import __elementBehaviors from ${JSON.stringify(config.elements)};`,\n ];\n\n return [\n ...behaviorImports,\n `export * from ${JSON.stringify(METADATA_SPECIFIER)};`,\n `export const applicationId = ${JSON.stringify(config.applicationId)};`,\n `export const userEventSignals = ${JSON.stringify(config.userEventSignals)};`,\n config.elements === null\n ? `export const elements = ${lazyJson};`\n : `export const elements = mergeElementConfigs(__elementBehaviors, ${lazyJson});`,\n ].join(\"\\n\");\n};\n\nexport { GTKX_CONFIG_VIRTUAL_ID, RESOLVED_GTKX_CONFIG_VIRTUAL_ID, renderConfigModule };\n"]}
@@ -0,0 +1,16 @@
1
+ import type { Plugin, UserConfig } from "vite";
2
+ import { type ConfigLoader } from "./loader.js";
3
+ /**
4
+ * Creates the Vite plugin that resolves and serves the `virtual:gtkx-config`
5
+ * module, exposing the JSX metadata and the resolved application ID from the
6
+ * project's configuration.
7
+ * @param options Plugin name, an optional custom {@link ConfigLoader}, and an
8
+ * optional hook returning extra Vite user config.
9
+ */
10
+ declare const createConfigPlugin: (options: {
11
+ name: string;
12
+ loadConfig?: ConfigLoader;
13
+ config?: () => Omit<UserConfig, "plugins">;
14
+ }) => Plugin;
15
+ export default createConfigPlugin;
16
+ //# sourceMappingURL=vite-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,aAAa,CAAC;AAsBpE;;;;;;GAMG;AACH,QAAA,MAAM,kBAAkB,GAAI,SAAS;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;CAC9C,KAAG,MAcH,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { createConfigLoader } from "./loader.js";
2
+ import { GTKX_CONFIG_VIRTUAL_ID, renderConfigModule, RESOLVED_GTKX_CONFIG_VIRTUAL_ID } from "./virtual.js";
3
+ const resolveVirtualId = (id) => id === GTKX_CONFIG_VIRTUAL_ID ? RESOLVED_GTKX_CONFIG_VIRTUAL_ID : null;
4
+ const loadVirtualModule = async (id, loadConfig, state) => {
5
+ if (id !== RESOLVED_GTKX_CONFIG_VIRTUAL_ID) {
6
+ return undefined;
7
+ }
8
+ return renderConfigModule(await loadConfig(state.root ?? process.cwd()));
9
+ };
10
+ /**
11
+ * Creates the Vite plugin that resolves and serves the `virtual:gtkx-config`
12
+ * module, exposing the JSX metadata and the resolved application ID from the
13
+ * project's configuration.
14
+ * @param options Plugin name, an optional custom {@link ConfigLoader}, and an
15
+ * optional hook returning extra Vite user config.
16
+ */
17
+ const createConfigPlugin = (options) => {
18
+ const loadConfig = options.loadConfig ?? createConfigLoader();
19
+ const state = { root: undefined };
20
+ return {
21
+ name: options.name,
22
+ config(config) {
23
+ state.root = config.root ?? state.root;
24
+ return options.config?.();
25
+ },
26
+ resolveId: (id) => resolveVirtualId(id),
27
+ load: (id) => loadVirtualModule(id, loadConfig, state),
28
+ };
29
+ };
30
+ export default createConfigPlugin;
31
+ //# sourceMappingURL=vite-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AAM3G,MAAM,gBAAgB,GAAG,CAAC,EAAU,EAAiB,EAAE,CACnD,EAAE,KAAK,sBAAsB,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC;AAE3E,MAAM,iBAAiB,GAAG,KAAK,EAC3B,EAAU,EACV,UAAwB,EACxB,KAAkB,EACS,EAAE;IAC7B,IAAI,EAAE,KAAK,+BAA+B,EAAE,CAAC;QACzC,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,OAAO,kBAAkB,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAC7E,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAG,CAAC,OAI3B,EAAU,EAAE;IACT,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,kBAAkB,EAAE,CAAC;IAC9D,MAAM,KAAK,GAAgB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAE/C,OAAO;QACH,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,CAAC,MAAkB;YACrB,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;YAEvC,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9B,CAAC;QACD,SAAS,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC/C,IAAI,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC;KACjE,CAAC;AACN,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC","sourcesContent":["import type { Plugin, UserConfig } from \"vite\";\nimport { type ConfigLoader, createConfigLoader } from \"./loader.js\";\nimport { GTKX_CONFIG_VIRTUAL_ID, renderConfigModule, RESOLVED_GTKX_CONFIG_VIRTUAL_ID } from \"./virtual.js\";\n\ntype PluginState = {\n root: string | undefined;\n};\n\nconst resolveVirtualId = (id: string): string | null =>\n id === GTKX_CONFIG_VIRTUAL_ID ? RESOLVED_GTKX_CONFIG_VIRTUAL_ID : null;\n\nconst loadVirtualModule = async (\n id: string,\n loadConfig: ConfigLoader,\n state: PluginState,\n): Promise<string | undefined> => {\n if (id !== RESOLVED_GTKX_CONFIG_VIRTUAL_ID) {\n return undefined;\n }\n\n return renderConfigModule(await loadConfig(state.root ?? process.cwd()));\n};\n\n/**\n * Creates the Vite plugin that resolves and serves the `virtual:gtkx-config`\n * module, exposing the JSX metadata and the resolved application ID from the\n * project's configuration.\n * @param options Plugin name, an optional custom {@link ConfigLoader}, and an\n * optional hook returning extra Vite user config.\n */\nconst createConfigPlugin = (options: {\n name: string;\n loadConfig?: ConfigLoader;\n config?: () => Omit<UserConfig, \"plugins\">;\n}): Plugin => {\n const loadConfig = options.loadConfig ?? createConfigLoader();\n const state: PluginState = { root: undefined };\n\n return {\n name: options.name,\n config(config: UserConfig) {\n state.root = config.root ?? state.root;\n\n return options.config?.();\n },\n resolveId: (id: string) => resolveVirtualId(id),\n load: (id: string) => loadVirtualModule(id, loadConfig, state),\n };\n};\n\nexport default createConfigPlugin;\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gtkx/config",
3
- "version": "0.21.0",
4
- "description": "gtkx.config.ts schema, validation, and loader shared by the GTKX toolchain",
3
+ "version": "1.0.0-rc.2",
4
+ "description": "gtkx.config.ts schema, loader, and the element-prop mapping language shared across the GTKX toolchain",
5
5
  "keywords": [
6
6
  "gtkx",
7
7
  "gtk",
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "https://github.com/gtkx-org/gtkx.git",
21
+ "url": "git+https://github.com/gtkx-org/gtkx.git",
22
22
  "directory": "packages/config"
23
23
  },
24
24
  "license": "MPL-2.0",
@@ -27,26 +27,33 @@
27
27
  "exports": {
28
28
  "./package.json": "./package.json",
29
29
  ".": {
30
- "source": "./src/index.ts",
31
30
  "types": "./dist/index.d.ts",
32
31
  "default": "./dist/index.js"
33
32
  },
34
- "./env": {
35
- "types": "./env.d.ts"
33
+ "./internal": {
34
+ "types": "./dist/internal.d.ts",
35
+ "default": "./dist/internal.js"
36
+ },
37
+ "./vite-plugin": {
38
+ "types": "./dist/vite-plugin.d.ts",
39
+ "default": "./dist/vite-plugin.js"
36
40
  }
37
41
  },
38
42
  "sideEffects": false,
39
43
  "files": [
40
44
  "dist",
41
- "src",
42
- "env.d.ts"
45
+ "src"
43
46
  ],
47
+ "engines": {
48
+ "node": ">=24"
49
+ },
44
50
  "dependencies": {
45
51
  "c12": "^3.3.4",
46
- "vite": "^8.0.16",
47
- "@gtkx/utils": "0.21.0"
52
+ "defu": "^6.1.7",
53
+ "vite": "^8.1.5",
54
+ "zod": "^4.4.3"
48
55
  },
49
56
  "scripts": {
50
- "build": "tsc -b"
57
+ "release": "tsx ../../scripts/release-package.ts"
51
58
  }
52
59
  }
@@ -0,0 +1,67 @@
1
+ import type { z } from "zod";
2
+
3
+ type IssuePath = (string | number)[];
4
+
5
+ const CONFIG_PREFIX = "gtkx.config.ts:";
6
+
7
+ const isRecord = (value: unknown): value is Record<string, unknown> =>
8
+ typeof value === "object" && value !== null && !Array.isArray(value);
9
+
10
+ const rawIssue = (input: unknown, path: IssuePath, message: string, isStandalone = false) => ({
11
+ code: "custom" as const,
12
+ input,
13
+ path,
14
+ message,
15
+ continue: true as const,
16
+ ...(isStandalone && { params: { standalone: true } }),
17
+ });
18
+
19
+ const appendSegment = (path: string, segment: PropertyKey): string => {
20
+ if (typeof segment === "number") {
21
+ return `${path}[${String(segment)}]`;
22
+ }
23
+
24
+ return path === "" ? String(segment) : `${path}.${String(segment)}`;
25
+ };
26
+
27
+ const dottedPath = (segments: PropertyKey[]): string => {
28
+ let path = "";
29
+
30
+ for (const segment of segments) {
31
+ path = appendSegment(path, segment);
32
+ }
33
+
34
+ return path;
35
+ };
36
+
37
+ const isStandaloneIssue = (issue: z.core.$ZodIssue): boolean =>
38
+ "params" in issue && isRecord(issue.params) && issue.params.standalone === true;
39
+
40
+ const formatIssue = (issue: z.core.$ZodIssue, fullPath: PropertyKey[]): string => {
41
+ if (issue.code === "unrecognized_keys") {
42
+ const [key] = issue.keys;
43
+ const path = dottedPath(key === undefined ? fullPath : [...fullPath, key]);
44
+
45
+ return `${CONFIG_PREFIX} \`${path}\` is not a recognized key`;
46
+ }
47
+
48
+ if (isStandaloneIssue(issue)) {
49
+ return `${CONFIG_PREFIX} ${issue.message}`;
50
+ }
51
+
52
+ const path = dottedPath(fullPath);
53
+
54
+ return path === "" ? `${CONFIG_PREFIX} ${issue.message}` : `${CONFIG_PREFIX} \`${path}\` ${issue.message}`;
55
+ };
56
+
57
+ const configError = (error: z.ZodError): Error => {
58
+ const issue = error.issues[0];
59
+
60
+ if (issue === undefined) {
61
+ return new Error(`${CONFIG_PREFIX} invalid configuration`);
62
+ }
63
+
64
+ return new Error(formatIssue(issue, issue.path));
65
+ };
66
+
67
+ export { isRecord, rawIssue, configError };