@tooee/config 0.1.0
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 +5 -0
- package/dist/context.d.ts +10 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +24 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/load.d.ts +4 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +73 -0
- package/dist/load.js.map +1 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -0
- package/src/context.tsx +35 -0
- package/src/index.ts +3 -0
- package/src/load.ts +75 -0
- package/src/types.ts +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { TooeeConfig } from "./types.js";
|
|
3
|
+
export declare function ConfigProvider({ overrides, children, }: {
|
|
4
|
+
overrides?: Partial<TooeeConfig>;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}): ReactNode;
|
|
7
|
+
export declare function useConfig(): TooeeConfig;
|
|
8
|
+
export declare function useThemeConfig(): TooeeConfig["theme"];
|
|
9
|
+
export declare function useKeymapConfig(): Record<string, string>;
|
|
10
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAY7C,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAChC,QAAQ,EAAE,SAAS,CAAA;CACpB,aAGA;AAED,wBAAgB,SAAS,IAAI,WAAW,CAEvC;AAED,wBAAgB,cAAc,IAAI,WAAW,CAAC,OAAO,CAAC,CAErD;AAED,wBAAgB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExD"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@opentui/react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useMemo } from "react";
|
|
3
|
+
import { loadConfig } from "./load.js";
|
|
4
|
+
const DEFAULTS = {
|
|
5
|
+
theme: {
|
|
6
|
+
name: "tokyonight",
|
|
7
|
+
mode: "dark",
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
const ConfigContext = createContext(DEFAULTS);
|
|
11
|
+
export function ConfigProvider({ overrides, children, }) {
|
|
12
|
+
const config = useMemo(() => loadConfig(overrides), [overrides]);
|
|
13
|
+
return _jsx(ConfigContext.Provider, { value: config, children: children });
|
|
14
|
+
}
|
|
15
|
+
export function useConfig() {
|
|
16
|
+
return useContext(ConfigContext);
|
|
17
|
+
}
|
|
18
|
+
export function useThemeConfig() {
|
|
19
|
+
return useConfig().theme;
|
|
20
|
+
}
|
|
21
|
+
export function useKeymapConfig() {
|
|
22
|
+
return useConfig().keys ?? {};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAA;AAE1E,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC,MAAM,QAAQ,GAAgB;IAC5B,KAAK,EAAE;QACL,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,MAAM;KACb;CACF,CAAA;AAED,MAAM,aAAa,GAAG,aAAa,CAAc,QAAQ,CAAC,CAAA;AAE1D,MAAM,UAAU,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,GAIT;IACC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;IAChE,OAAO,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YAAG,QAAQ,GAA0B,CAAA;AACnF,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,UAAU,CAAC,aAAa,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,SAAS,EAAE,CAAC,KAAK,CAAA;AAC1B,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,SAAS,EAAE,CAAC,IAAI,IAAI,EAAE,CAAA;AAC/B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/load.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAmD7C,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAQxE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAWrE"}
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { readFileSync, mkdirSync, writeFileSync, existsSync } from "fs";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
|
+
const DEFAULTS = {
|
|
4
|
+
theme: {
|
|
5
|
+
name: "tokyonight",
|
|
6
|
+
mode: "dark",
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
function deepMerge(target, source) {
|
|
10
|
+
const result = { ...target };
|
|
11
|
+
for (const key of Object.keys(source)) {
|
|
12
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
13
|
+
result[key] = deepMerge(result[key] ?? {}, source[key]);
|
|
14
|
+
}
|
|
15
|
+
else if (source[key] !== undefined) {
|
|
16
|
+
result[key] = source[key];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
function readJsonFile(path) {
|
|
22
|
+
try {
|
|
23
|
+
if (!existsSync(path))
|
|
24
|
+
return {};
|
|
25
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function getGlobalConfigPath() {
|
|
32
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join(process.env.HOME ?? "", ".config");
|
|
33
|
+
return join(xdg, "tooee", "config.json");
|
|
34
|
+
}
|
|
35
|
+
function findProjectConfig() {
|
|
36
|
+
let dir = process.cwd();
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
while (dir && !seen.has(dir)) {
|
|
39
|
+
seen.add(dir);
|
|
40
|
+
const configPath = join(dir, ".tooee", "config.json");
|
|
41
|
+
if (existsSync(configPath)) {
|
|
42
|
+
return readJsonFile(configPath);
|
|
43
|
+
}
|
|
44
|
+
const parent = dirname(dir);
|
|
45
|
+
if (parent === dir)
|
|
46
|
+
break;
|
|
47
|
+
dir = parent;
|
|
48
|
+
}
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
export function loadConfig(overrides) {
|
|
52
|
+
let config = { ...DEFAULTS };
|
|
53
|
+
config = deepMerge(config, readJsonFile(getGlobalConfigPath()));
|
|
54
|
+
config = deepMerge(config, findProjectConfig());
|
|
55
|
+
if (overrides) {
|
|
56
|
+
config = deepMerge(config, overrides);
|
|
57
|
+
}
|
|
58
|
+
return config;
|
|
59
|
+
}
|
|
60
|
+
export function writeGlobalConfig(partial) {
|
|
61
|
+
const path = getGlobalConfigPath();
|
|
62
|
+
const dir = dirname(path);
|
|
63
|
+
try {
|
|
64
|
+
const existing = readJsonFile(path);
|
|
65
|
+
const merged = deepMerge(existing, partial);
|
|
66
|
+
mkdirSync(dir, { recursive: true });
|
|
67
|
+
writeFileSync(path, JSON.stringify(merged, null, 2) + "\n");
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// ignore write errors
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=load.js.map
|
package/dist/load.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,OAAO,CAAA;AAEnC,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,IAAI,CAAA;KACZ,CAAA;IACD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,OAAO,CAAA;QACd,MAAM,CAAC,EAAE,OAAO,CAAA;KACjB,CAAA;CACF"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tooee/config",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Layered configuration system for Tooee apps",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Gareth Andrew",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/gingerhendrix/tooee.git",
|
|
10
|
+
"directory": "packages/config"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/gingerhendrix/tooee",
|
|
13
|
+
"bugs": "https://github.com/gingerhendrix/tooee/issues",
|
|
14
|
+
"keywords": ["tui", "terminal", "cli", "opentui", "configuration"],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": {
|
|
19
|
+
"@tooee/source": "./src/index.ts",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": ["dist", "src"],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"typecheck": "tsc --noEmit"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@opentui/react": "^0.1.67",
|
|
30
|
+
"@types/bun": "^1.3.5",
|
|
31
|
+
"@types/react": "^19.1.10",
|
|
32
|
+
"typescript": "^5.8.3"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/context.tsx
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo, type ReactNode } from "react"
|
|
2
|
+
import type { TooeeConfig } from "./types.js"
|
|
3
|
+
import { loadConfig } from "./load.js"
|
|
4
|
+
|
|
5
|
+
const DEFAULTS: TooeeConfig = {
|
|
6
|
+
theme: {
|
|
7
|
+
name: "tokyonight",
|
|
8
|
+
mode: "dark",
|
|
9
|
+
},
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const ConfigContext = createContext<TooeeConfig>(DEFAULTS)
|
|
13
|
+
|
|
14
|
+
export function ConfigProvider({
|
|
15
|
+
overrides,
|
|
16
|
+
children,
|
|
17
|
+
}: {
|
|
18
|
+
overrides?: Partial<TooeeConfig>
|
|
19
|
+
children: ReactNode
|
|
20
|
+
}) {
|
|
21
|
+
const config = useMemo(() => loadConfig(overrides), [overrides])
|
|
22
|
+
return <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function useConfig(): TooeeConfig {
|
|
26
|
+
return useContext(ConfigContext)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function useThemeConfig(): TooeeConfig["theme"] {
|
|
30
|
+
return useConfig().theme
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function useKeymapConfig(): Record<string, string> {
|
|
34
|
+
return useConfig().keys ?? {}
|
|
35
|
+
}
|
package/src/index.ts
ADDED
package/src/load.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readFileSync, mkdirSync, writeFileSync, existsSync } from "fs"
|
|
2
|
+
import { join, dirname } from "path"
|
|
3
|
+
import type { TooeeConfig } from "./types.js"
|
|
4
|
+
|
|
5
|
+
const DEFAULTS: TooeeConfig = {
|
|
6
|
+
theme: {
|
|
7
|
+
name: "tokyonight",
|
|
8
|
+
mode: "dark",
|
|
9
|
+
},
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function deepMerge(target: any, source: any): any {
|
|
13
|
+
const result = { ...target }
|
|
14
|
+
for (const key of Object.keys(source)) {
|
|
15
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
16
|
+
result[key] = deepMerge(result[key] ?? {}, source[key])
|
|
17
|
+
} else if (source[key] !== undefined) {
|
|
18
|
+
result[key] = source[key]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function readJsonFile(path: string): Partial<TooeeConfig> {
|
|
25
|
+
try {
|
|
26
|
+
if (!existsSync(path)) return {}
|
|
27
|
+
return JSON.parse(readFileSync(path, "utf-8")) as Partial<TooeeConfig>
|
|
28
|
+
} catch {
|
|
29
|
+
return {}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getGlobalConfigPath(): string {
|
|
34
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join(process.env.HOME ?? "", ".config")
|
|
35
|
+
return join(xdg, "tooee", "config.json")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function findProjectConfig(): Partial<TooeeConfig> {
|
|
39
|
+
let dir = process.cwd()
|
|
40
|
+
const seen = new Set<string>()
|
|
41
|
+
while (dir && !seen.has(dir)) {
|
|
42
|
+
seen.add(dir)
|
|
43
|
+
const configPath = join(dir, ".tooee", "config.json")
|
|
44
|
+
if (existsSync(configPath)) {
|
|
45
|
+
return readJsonFile(configPath)
|
|
46
|
+
}
|
|
47
|
+
const parent = dirname(dir)
|
|
48
|
+
if (parent === dir) break
|
|
49
|
+
dir = parent
|
|
50
|
+
}
|
|
51
|
+
return {}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function loadConfig(overrides?: Partial<TooeeConfig>): TooeeConfig {
|
|
55
|
+
let config: TooeeConfig = { ...DEFAULTS }
|
|
56
|
+
config = deepMerge(config, readJsonFile(getGlobalConfigPath()))
|
|
57
|
+
config = deepMerge(config, findProjectConfig())
|
|
58
|
+
if (overrides) {
|
|
59
|
+
config = deepMerge(config, overrides)
|
|
60
|
+
}
|
|
61
|
+
return config
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function writeGlobalConfig(partial: Partial<TooeeConfig>): void {
|
|
65
|
+
const path = getGlobalConfigPath()
|
|
66
|
+
const dir = dirname(path)
|
|
67
|
+
try {
|
|
68
|
+
const existing = readJsonFile(path)
|
|
69
|
+
const merged = deepMerge(existing, partial)
|
|
70
|
+
mkdirSync(dir, { recursive: true })
|
|
71
|
+
writeFileSync(path, JSON.stringify(merged, null, 2) + "\n")
|
|
72
|
+
} catch {
|
|
73
|
+
// ignore write errors
|
|
74
|
+
}
|
|
75
|
+
}
|