@gtkx/config 0.21.0 → 1.0.0-rc.1
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 +137 -82
- package/dist/config.d.ts +76 -35
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +76 -83
- package/dist/config.js.map +1 -1
- package/dist/element-props.d.ts +180 -0
- package/dist/element-props.d.ts.map +1 -0
- package/dist/element-props.js +154 -0
- package/dist/element-props.js.map +1 -0
- package/dist/index.d.ts +3 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -8
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +3 -0
- package/dist/internal.js.map +1 -0
- package/dist/loader.d.ts +19 -15
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +25 -39
- package/dist/loader.js.map +1 -1
- package/dist/virtual.d.ts +2 -4
- package/dist/virtual.d.ts.map +1 -1
- package/dist/virtual.js +2 -14
- package/dist/virtual.js.map +1 -1
- package/dist/vite-plugin.d.ts +16 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +32 -0
- package/dist/vite-plugin.js.map +1 -0
- package/env.d.ts +4 -22
- package/package.json +20 -7
- package/src/config.ts +134 -144
- package/src/element-props.ts +248 -0
- package/src/index.ts +14 -82
- package/src/internal.ts +2 -0
- package/src/loader.ts +36 -56
- package/src/virtual.ts +3 -32
- package/src/vite-plugin.ts +37 -0
- package/dist/bundled-modules.d.ts +0 -2
- package/dist/bundled-modules.d.ts.map +0 -1
- package/dist/bundled-modules.js +0 -2
- package/dist/bundled-modules.js.map +0 -1
- package/dist/data-dir.d.ts +0 -4
- package/dist/data-dir.d.ts.map +0 -1
- package/dist/data-dir.js +0 -37
- package/dist/data-dir.js.map +0 -1
- package/dist/plugin.d.ts +0 -9
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -24
- package/dist/plugin.js.map +0 -1
- package/dist/runtime.d.ts +0 -22
- package/dist/runtime.d.ts.map +0 -1
- package/dist/runtime.js +0 -22
- package/dist/runtime.js.map +0 -1
- package/dist/table-rules-ir.d.ts +0 -36
- package/dist/table-rules-ir.d.ts.map +0 -1
- package/dist/table-rules-ir.js +0 -2
- package/dist/table-rules-ir.js.map +0 -1
- package/dist/table-schema.d.ts +0 -107
- package/dist/table-schema.d.ts.map +0 -1
- package/dist/table-schema.js +0 -199
- package/dist/table-schema.js.map +0 -1
- package/dist/validators.d.ts +0 -4
- package/dist/validators.d.ts.map +0 -1
- package/dist/validators.js +0 -10
- package/dist/validators.js.map +0 -1
- package/dist/wrapper-protocol.d.ts +0 -12
- package/dist/wrapper-protocol.d.ts.map +0 -1
- package/dist/wrapper-protocol.js +0 -12
- package/dist/wrapper-protocol.js.map +0 -1
- package/src/bundled-modules.ts +0 -1
- package/src/data-dir.ts +0 -39
- package/src/plugin.ts +0 -30
- package/src/table-rules-ir.ts +0 -42
- package/src/table-schema.ts +0 -342
- package/src/validators.ts +0 -15
- package/src/wrapper-protocol.ts +0 -21
package/dist/virtual.js
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
1
|
export const GTKX_CONFIG_VIRTUAL_ID = "virtual:gtkx-config";
|
|
2
2
|
export const RESOLVED_GTKX_CONFIG_VIRTUAL_ID = `\0${GTKX_CONFIG_VIRTUAL_ID}`;
|
|
3
3
|
const METADATA_SPECIFIER = "@gtkx/jsx/metadata";
|
|
4
|
-
const
|
|
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) => [
|
|
4
|
+
export const renderConfigModule = (config) => [
|
|
17
5
|
`export * from ${JSON.stringify(METADATA_SPECIFIER)};`,
|
|
18
|
-
|
|
6
|
+
`export const applicationId = ${JSON.stringify(config.applicationId)};`,
|
|
19
7
|
].join("\n");
|
|
20
8
|
//# sourceMappingURL=virtual.js.map
|
package/dist/virtual.js.map
CHANGED
|
@@ -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;
|
|
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,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAsB,EAAU,EAAE,CACjE;IACI,iBAAiB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,GAAG;IACtD,gCAAgC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG;CAC1E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["import type { ResolvedConfig } from \"./config.js\";\n\nexport const GTKX_CONFIG_VIRTUAL_ID = \"virtual:gtkx-config\";\n\nexport const RESOLVED_GTKX_CONFIG_VIRTUAL_ID: string = `\\0${GTKX_CONFIG_VIRTUAL_ID}`;\n\nconst METADATA_SPECIFIER = \"@gtkx/jsx/metadata\";\n\nexport const renderConfigModule = (config: ResolvedConfig): string =>\n [\n `export * from ${JSON.stringify(METADATA_SPECIFIER)};`,\n `export const applicationId = ${JSON.stringify(config.applicationId)};`,\n ].join(\"\\n\");\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;AAGpE;;;;;;GAMG;AACH,QAAA,MAAM,kBAAkB,YAAa;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,MAmBH,CAAC;eAEa,kBAAkB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createConfigLoader } from "./loader.js";
|
|
2
|
+
import { GTKX_CONFIG_VIRTUAL_ID, RESOLVED_GTKX_CONFIG_VIRTUAL_ID, renderConfigModule } from "./virtual.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
|
+
const createConfigPlugin = (options) => {
|
|
11
|
+
const loadConfig = options.loadConfig ?? createConfigLoader();
|
|
12
|
+
let root;
|
|
13
|
+
return {
|
|
14
|
+
name: options.name,
|
|
15
|
+
config(config) {
|
|
16
|
+
root = config.root ?? root;
|
|
17
|
+
return options.config?.();
|
|
18
|
+
},
|
|
19
|
+
resolveId(id) {
|
|
20
|
+
if (id === GTKX_CONFIG_VIRTUAL_ID)
|
|
21
|
+
return RESOLVED_GTKX_CONFIG_VIRTUAL_ID;
|
|
22
|
+
return undefined;
|
|
23
|
+
},
|
|
24
|
+
async load(id) {
|
|
25
|
+
if (id !== RESOLVED_GTKX_CONFIG_VIRTUAL_ID)
|
|
26
|
+
return undefined;
|
|
27
|
+
return renderConfigModule(await loadConfig(root ?? process.cwd()));
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export default createConfigPlugin;
|
|
32
|
+
//# 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,+BAA+B,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE3G;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAG,CAAC,OAI3B,EAAU,EAAE;IACT,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,kBAAkB,EAAE,CAAC;IAC9D,IAAI,IAAwB,CAAC;IAE7B,OAAO;QACH,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,CAAC,MAAkB;YACrB,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;YAC3B,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9B,CAAC;QACD,SAAS,CAAC,EAAU;YAChB,IAAI,EAAE,KAAK,sBAAsB;gBAAE,OAAO,+BAA+B,CAAC;YAC1E,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAU;YACjB,IAAI,EAAE,KAAK,+BAA+B;gBAAE,OAAO,SAAS,CAAC;YAC7D,OAAO,kBAAkB,CAAC,MAAM,UAAU,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACvE,CAAC;KACJ,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, RESOLVED_GTKX_CONFIG_VIRTUAL_ID, renderConfigModule } from \"./virtual.js\";\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 let root: string | undefined;\n\n return {\n name: options.name,\n config(config: UserConfig) {\n root = config.root ?? root;\n return options.config?.();\n },\n resolveId(id: string) {\n if (id === GTKX_CONFIG_VIRTUAL_ID) return RESOLVED_GTKX_CONFIG_VIRTUAL_ID;\n return undefined;\n },\n async load(id: string) {\n if (id !== RESOLVED_GTKX_CONFIG_VIRTUAL_ID) return undefined;\n return renderConfigModule(await loadConfig(root ?? process.cwd()));\n },\n };\n};\n\nexport default createConfigPlugin;\n"]}
|
package/env.d.ts
CHANGED
|
@@ -1,26 +1,8 @@
|
|
|
1
1
|
declare module "virtual:gtkx-config" {
|
|
2
|
-
export const SIGNALS:
|
|
2
|
+
export const SIGNALS: Record<string, Record<string, string>>;
|
|
3
3
|
export const CONSTRUCT_ONLY_PROPS: Record<string, Set<string>>;
|
|
4
4
|
export const CONSTRUCT_PROPS: Record<string, Set<string>>;
|
|
5
|
-
export const DEFAULT_PROPS:
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const OBJECT_PROPS: import("@gtkx/config").PerElementPropRows<import("@gtkx/config").ObjectPropRow>;
|
|
9
|
-
export const VIRTUAL_PROPS: import("@gtkx/config").PerElementPropRows<import("@gtkx/config").VirtualPropRow>;
|
|
10
|
-
export const PROP_RULES: Record<string, import("@gtkx/config").PropRule[]>;
|
|
11
|
-
export const TOP_LEVEL_TYPES: string[];
|
|
12
|
-
export const DEFAULT_BLOCKABLE_TYPES: string[];
|
|
13
|
-
export const META_OBJECT_ADD_METHODS: Record<string, import("@gtkx/config").AddMethodRule[]>;
|
|
14
|
-
export const PAGE_META_SETTERS: import("@gtkx/config").PageMetaSetter[];
|
|
15
|
-
export const CONTAINER_PROPS: import("@gtkx/config").PerElementPropRows<import("@gtkx/config").ContainerPropRow>;
|
|
16
|
-
export const ATTACH_SHAPES: import("@gtkx/config").AttachShapeTable;
|
|
17
|
-
export const libraries: import("@gtkx/config").ResolvedGtkxConfig["libraries"];
|
|
18
|
-
export const girPath: import("@gtkx/config").ResolvedGtkxConfig["girPath"];
|
|
19
|
-
export const applicationId: import("@gtkx/config").ResolvedGtkxConfig["applicationId"];
|
|
20
|
-
export const containerProps: import("@gtkx/config").ResolvedGtkxConfig["containerProps"];
|
|
21
|
-
export const arrayProps: import("@gtkx/config").ResolvedGtkxConfig["arrayProps"];
|
|
22
|
-
export const objectProps: import("@gtkx/config").ResolvedGtkxConfig["objectProps"];
|
|
23
|
-
export const virtualProps: import("@gtkx/config").ResolvedGtkxConfig["virtualProps"];
|
|
24
|
-
export const elementMap: import("@gtkx/config").ResolvedGtkxConfig["elementMap"];
|
|
25
|
-
export const reactCompiler: import("@gtkx/config").ResolvedGtkxConfig["reactCompiler"];
|
|
5
|
+
export const DEFAULT_PROPS: Record<string, Record<string, unknown>>;
|
|
6
|
+
export const ELEMENT_PROPS: Record<string, import("@gtkx/config").ElementProp[]>;
|
|
7
|
+
export const applicationId: import("@gtkx/config").ResolvedConfig["applicationId"];
|
|
26
8
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gtkx/config",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "gtkx.config.ts schema,
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
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,12 +27,19 @@
|
|
|
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
33
|
"./env": {
|
|
35
34
|
"types": "./env.d.ts"
|
|
35
|
+
},
|
|
36
|
+
"./internal": {
|
|
37
|
+
"types": "./dist/internal.d.ts",
|
|
38
|
+
"default": "./dist/internal.js"
|
|
39
|
+
},
|
|
40
|
+
"./vite-plugin": {
|
|
41
|
+
"types": "./dist/vite-plugin.d.ts",
|
|
42
|
+
"default": "./dist/vite-plugin.js"
|
|
36
43
|
}
|
|
37
44
|
},
|
|
38
45
|
"sideEffects": false,
|
|
@@ -41,12 +48,18 @@
|
|
|
41
48
|
"src",
|
|
42
49
|
"env.d.ts"
|
|
43
50
|
],
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=24"
|
|
53
|
+
},
|
|
44
54
|
"dependencies": {
|
|
45
55
|
"c12": "^3.3.4",
|
|
46
|
-
"
|
|
47
|
-
"
|
|
56
|
+
"defu": "^6.1.7",
|
|
57
|
+
"vite": "^8.1.4",
|
|
58
|
+
"zod": "^4.4.3"
|
|
48
59
|
},
|
|
49
60
|
"scripts": {
|
|
50
|
-
"build": "tsc -b"
|
|
61
|
+
"build": "tsc -b tsconfig.lib.json",
|
|
62
|
+
"typecheck": "tsc -b --emitDeclarationOnly",
|
|
63
|
+
"release": "tsx ../../scripts/release-package.ts"
|
|
51
64
|
}
|
|
52
65
|
}
|
package/src/config.ts
CHANGED
|
@@ -1,191 +1,181 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type ElementMapRule,
|
|
6
|
-
type ObjectPropRow,
|
|
7
|
-
type PerElementPropRows,
|
|
8
|
-
type UserTableRows,
|
|
9
|
-
type VirtualPropRow,
|
|
10
|
-
validateArrayPropRows,
|
|
11
|
-
validateContainerPropRows,
|
|
12
|
-
validateElementMap,
|
|
13
|
-
validateObjectPropRows,
|
|
14
|
-
validateVirtualPropRows,
|
|
15
|
-
} from "./table-schema.js";
|
|
1
|
+
import { createDefineConfig, type DefineConfig } from "c12";
|
|
2
|
+
import { defu } from "defu";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { configError, elementPropsSchema, isRecord, rawIssue } from "./element-props.js";
|
|
16
5
|
|
|
17
6
|
export const LIBRARIES_WILDCARD = "*";
|
|
18
7
|
|
|
19
|
-
export const
|
|
8
|
+
export const GIR_LIBRARY_PATTERN: RegExp = /^[A-Za-z][A-Za-z0-9]*-\d+(?:\.\d+)*$/;
|
|
20
9
|
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
const APPLICATION_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_-]*(\.[A-Za-z_][A-Za-z0-9_-]*)+$/;
|
|
11
|
+
const APPLICATION_ID_MAX_LENGTH = 255;
|
|
23
12
|
|
|
24
|
-
|
|
13
|
+
export const isValidApplicationId = (applicationId: string): boolean => {
|
|
14
|
+
if (applicationId.length === 0 || applicationId.length > APPLICATION_ID_MAX_LENGTH) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return APPLICATION_ID_PATTERN.test(applicationId);
|
|
18
|
+
};
|
|
25
19
|
|
|
26
|
-
|
|
20
|
+
const COMPILATION_MODES = ["infer", "syntax", "annotation", "all"] as const;
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
};
|
|
22
|
+
const PANIC_THRESHOLDS = ["none", "critical_errors", "all_errors"] as const;
|
|
30
23
|
|
|
31
|
-
|
|
24
|
+
type ReactCompilerCompilationMode = (typeof COMPILATION_MODES)[number];
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
type ReactCompilerPanicThreshold = (typeof PANIC_THRESHOLDS)[number];
|
|
34
27
|
|
|
35
|
-
|
|
28
|
+
type ReactCompilerOptions = {
|
|
36
29
|
compilationMode?: ReactCompilerCompilationMode;
|
|
37
30
|
panicThreshold?: ReactCompilerPanicThreshold;
|
|
38
31
|
};
|
|
39
32
|
|
|
33
|
+
/**
|
|
34
|
+
* React Compiler options resolved for the build, with the compilation target
|
|
35
|
+
* fixed to React 19.
|
|
36
|
+
*/
|
|
40
37
|
export type ResolvedReactCompilerOptions = ReactCompilerOptions & {
|
|
41
38
|
target: "19";
|
|
42
39
|
};
|
|
43
40
|
|
|
44
41
|
const REACT_COMPILER_TARGET = "19";
|
|
45
42
|
|
|
46
|
-
export const resolveReactCompilerOptions = (
|
|
47
|
-
setting: GtkxConfig["reactCompiler"],
|
|
48
|
-
): ResolvedReactCompilerOptions | null => {
|
|
43
|
+
export const resolveReactCompilerOptions = (setting: Config["reactCompiler"]): ResolvedReactCompilerOptions | null => {
|
|
49
44
|
if (setting === false) return null;
|
|
50
45
|
const overrides = setting === undefined || setting === true ? {} : setting;
|
|
51
46
|
return { ...overrides, target: REACT_COMPILER_TARGET };
|
|
52
47
|
};
|
|
53
48
|
|
|
54
|
-
const
|
|
55
|
-
|
|
49
|
+
const COMPILATION_MODE_SET: Set<string> = new Set(COMPILATION_MODES);
|
|
50
|
+
|
|
51
|
+
const PANIC_THRESHOLD_SET: Set<string> = new Set(PANIC_THRESHOLDS);
|
|
52
|
+
|
|
53
|
+
const librariesSchema = z.custom<typeof LIBRARIES_WILDCARD | string[]>().check((ctx) => {
|
|
54
|
+
const value = ctx.value;
|
|
55
|
+
if (value === LIBRARIES_WILDCARD) return;
|
|
56
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
57
|
+
ctx.issues.push(rawIssue(value, [], `must be "${LIBRARIES_WILDCARD}", a non-empty string array, or omitted`));
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
value.forEach((entry, index) => {
|
|
61
|
+
if (typeof entry === "string" && GIR_LIBRARY_PATTERN.test(entry)) return;
|
|
62
|
+
if (entry === LIBRARIES_WILDCARD) {
|
|
63
|
+
ctx.issues.push(
|
|
64
|
+
rawIssue(
|
|
65
|
+
value,
|
|
66
|
+
[index],
|
|
67
|
+
`to generate every library, set \`libraries: "${LIBRARIES_WILDCARD}"\` as a bare string, not an array entry`,
|
|
68
|
+
true,
|
|
69
|
+
),
|
|
70
|
+
);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
ctx.issues.push(
|
|
74
|
+
rawIssue(
|
|
75
|
+
value,
|
|
76
|
+
[index],
|
|
77
|
+
`invalid library identifier "${String(entry)}", must be of the form "Name-Version" (e.g. "Gtk-4.0")`,
|
|
78
|
+
true,
|
|
79
|
+
),
|
|
61
80
|
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
`gtkx.config.ts: invalid library identifier "${String(library)}" — must be of the form "Name-Version" (e.g. "Gtk-4.0")`,
|
|
65
|
-
);
|
|
66
|
-
};
|
|
81
|
+
});
|
|
82
|
+
});
|
|
67
83
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
const applicationIdSchema = z.custom<string>().check((ctx) => {
|
|
85
|
+
const value = ctx.value;
|
|
86
|
+
if (typeof value !== "string" || !isValidApplicationId(value)) {
|
|
87
|
+
ctx.issues.push(
|
|
88
|
+
rawIssue(
|
|
89
|
+
value,
|
|
90
|
+
[],
|
|
91
|
+
`invalid \`applicationId\` "${String(value)}", must satisfy g_application_id_is_valid (e.g. "org.example.MyApp")`,
|
|
92
|
+
true,
|
|
93
|
+
),
|
|
94
|
+
);
|
|
77
95
|
}
|
|
78
|
-
};
|
|
96
|
+
});
|
|
79
97
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
98
|
+
const reactCompilerSchema = z.custom<boolean | ReactCompilerOptions>().check((ctx) => {
|
|
99
|
+
const value = ctx.value;
|
|
100
|
+
if (typeof value === "boolean") return;
|
|
101
|
+
if (!isRecord(value)) {
|
|
102
|
+
ctx.issues.push(rawIssue(value, [], "must be a boolean or an options object"));
|
|
103
|
+
return;
|
|
83
104
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
105
|
+
const compilationMode = value.compilationMode;
|
|
106
|
+
if (
|
|
107
|
+
compilationMode !== undefined &&
|
|
108
|
+
!(typeof compilationMode === "string" && COMPILATION_MODE_SET.has(compilationMode))
|
|
109
|
+
) {
|
|
110
|
+
ctx.issues.push(
|
|
111
|
+
rawIssue(
|
|
112
|
+
value,
|
|
113
|
+
[],
|
|
114
|
+
`invalid \`reactCompiler.compilationMode\` "${String(compilationMode)}", must be one of ${COMPILATION_MODES.join(", ")}`,
|
|
115
|
+
true,
|
|
116
|
+
),
|
|
92
117
|
);
|
|
93
118
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
119
|
+
const panicThreshold = value.panicThreshold;
|
|
120
|
+
if (
|
|
121
|
+
panicThreshold !== undefined &&
|
|
122
|
+
!(typeof panicThreshold === "string" && PANIC_THRESHOLD_SET.has(panicThreshold))
|
|
123
|
+
) {
|
|
124
|
+
ctx.issues.push(
|
|
125
|
+
rawIssue(
|
|
126
|
+
value,
|
|
127
|
+
[],
|
|
128
|
+
`invalid \`reactCompiler.panicThreshold\` "${String(panicThreshold)}", must be one of ${PANIC_THRESHOLDS.join(", ")}`,
|
|
129
|
+
true,
|
|
130
|
+
),
|
|
104
131
|
);
|
|
105
132
|
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const validateReactCompiler = (reactCompiler: GtkxConfig["reactCompiler"]): void => {
|
|
109
|
-
if (reactCompiler === undefined || typeof reactCompiler === "boolean") return;
|
|
110
|
-
if (typeof reactCompiler !== "object" || reactCompiler === null || Array.isArray(reactCompiler)) {
|
|
111
|
-
throw new Error("gtkx.config.ts: `reactCompiler` must be a boolean or an options object");
|
|
112
|
-
}
|
|
113
|
-
validateReactCompilerEnum(reactCompiler.compilationMode, REACT_COMPILER_COMPILATION_MODES, "compilationMode");
|
|
114
|
-
validateReactCompilerEnum(reactCompiler.panicThreshold, REACT_COMPILER_PANIC_THRESHOLDS, "panicThreshold");
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
export const validateGtkxConfig = (config: GtkxConfig): void => {
|
|
118
|
-
validateLibraries(config.libraries);
|
|
119
|
-
validateGirPath(config.girPath);
|
|
120
|
-
validateApplicationId(config.applicationId);
|
|
121
|
-
validateContainerPropRows(config.containerProps);
|
|
122
|
-
validateArrayPropRows(config.arrayProps);
|
|
123
|
-
validateObjectPropRows(config.objectProps);
|
|
124
|
-
validateVirtualPropRows(config.virtualProps);
|
|
125
|
-
validateElementMap(config.elementMap);
|
|
126
|
-
validateReactCompiler(config.reactCompiler);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
export type GtkxConfigEnv = {
|
|
130
|
-
mode?: string;
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export type GtkxConfigFn = (env: GtkxConfigEnv) => GtkxConfig;
|
|
134
|
-
|
|
135
|
-
export type GtkxConfigFnPromise = (env: GtkxConfigEnv) => Promise<GtkxConfig>;
|
|
136
|
-
|
|
137
|
-
export type GtkxConfigExport = GtkxConfig | Promise<GtkxConfig> | GtkxConfigFn | GtkxConfigFnPromise;
|
|
133
|
+
});
|
|
138
134
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
135
|
+
const configSchema = z.object({
|
|
136
|
+
libraries: librariesSchema.optional(),
|
|
137
|
+
girPath: z.array(z.string(), { error: "must be an array of strings if provided" }).optional(),
|
|
138
|
+
applicationId: applicationIdSchema,
|
|
139
|
+
elementProps: elementPropsSchema.optional(),
|
|
140
|
+
reactCompiler: reactCompilerSchema.optional(),
|
|
141
|
+
codegen: z.boolean({ error: "must be a boolean" }).optional(),
|
|
142
|
+
});
|
|
147
143
|
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
/**
|
|
145
|
+
* User-facing configuration for a GTKX project, as authored in `gtkx.config.ts`:
|
|
146
|
+
* the GIR libraries to bind, extra `.gir` search paths, the GApplication id,
|
|
147
|
+
* custom element prop mappings, and the React Compiler and codegen settings.
|
|
148
|
+
*/
|
|
149
|
+
export type Config = z.infer<typeof configSchema>;
|
|
150
150
|
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
if (
|
|
154
|
-
if (Array.isArray(base) && Array.isArray(override)) return [...base, ...override];
|
|
155
|
-
if (isMergeableObject(base) && isMergeableObject(override)) {
|
|
156
|
-
const merged: Record<string, unknown> = { ...base };
|
|
157
|
-
for (const key of Object.keys(override)) {
|
|
158
|
-
merged[key] = mergeConfigValue(base[key], override[key]);
|
|
159
|
-
}
|
|
160
|
-
return merged;
|
|
161
|
-
}
|
|
162
|
-
return override;
|
|
151
|
+
export const validateConfig = (config: Config): void => {
|
|
152
|
+
const result = configSchema.safeParse(config);
|
|
153
|
+
if (!result.success) throw configError(result.error);
|
|
163
154
|
};
|
|
164
155
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Identity helper that returns the given configuration typed as {@link Config},
|
|
158
|
+
* enabling editor autocompletion and type checking in `gtkx.config.ts`.
|
|
159
|
+
*/
|
|
160
|
+
export const defineConfig: DefineConfig<Config> = createDefineConfig<Config>();
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Deep-merges two configurations, with `override` taking precedence over `base`.
|
|
164
|
+
* @param base The lower-priority configuration.
|
|
165
|
+
* @param override The higher-priority configuration whose values win on conflict.
|
|
166
|
+
*/
|
|
167
|
+
export const mergeConfig = (base: Config, override: Config): Config => defu(override, base);
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Configuration reduced to the values needed at runtime: the GApplication
|
|
171
|
+
* identifier and the resolved React Compiler options (`null` when disabled).
|
|
172
|
+
*/
|
|
173
|
+
export type ResolvedConfig = {
|
|
174
|
+
applicationId: string;
|
|
177
175
|
reactCompiler: ResolvedReactCompilerOptions | null;
|
|
178
176
|
};
|
|
179
177
|
|
|
180
|
-
export const
|
|
181
|
-
libraries: config.libraries ?? [],
|
|
182
|
-
girPath: config.girPath ?? [],
|
|
178
|
+
export const resolveConfig = (config: Config): ResolvedConfig => ({
|
|
183
179
|
applicationId: config.applicationId,
|
|
184
|
-
containerProps: config.containerProps ?? {},
|
|
185
|
-
arrayProps: config.arrayProps ?? {},
|
|
186
|
-
objectProps: config.objectProps ?? {},
|
|
187
|
-
virtualProps: config.virtualProps ?? {},
|
|
188
|
-
elementMap: config.elementMap ?? [],
|
|
189
180
|
reactCompiler: resolveReactCompilerOptions(config.reactCompiler),
|
|
190
181
|
});
|
|
191
|
-
|