-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.ts
73 lines (64 loc) 路 2.43 KB
/
config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import {join} from 'node:path';
import {CONFIG_PATH, paths} from './paths.js';
import create_default_config from './gro.config.default.js';
import type {Create_Config_Plugins} from './plugin.js';
import {exists} from './fs.js';
import type {Map_Package_Json} from './package_json.js';
export interface Gro_Config {
plugins: Create_Config_Plugins;
/**
* Maps the project's `package.json` before writing it to the filesystem.
* The `package_json` argument may be mutated, but the return value is what's used by the caller.
* Returning `null` is a no-op for the caller.
*/
map_package_json: Map_Package_Json | null;
}
export interface Create_Gro_Config {
(base_config: Gro_Config): Gro_Config | Promise<Gro_Config>;
}
export const create_empty_config = (): Gro_Config => ({
plugins: () => [],
// TODO maybe disable if no SvelteKit `lib` directory? or other detection to improve defaults
map_package_json: default_map_package_json,
});
const default_map_package_json: Map_Package_Json = async (package_json) => {
if (package_json.exports) {
package_json.exports = Object.fromEntries(
Object.entries(package_json.exports).filter(([k]) => !DEFAULT_EXPORTS_EXCLUDER.test(k)),
);
}
return package_json;
};
export const DEFAULT_EXPORTS_EXCLUDER = /(\.md|\.(test|ignore)\.|\/(test|fixtures|ignore)\/)/u;
export interface Gro_Config_Module {
readonly default: Gro_Config | Create_Gro_Config;
}
export const load_config = async (dir = paths.root): Promise<Gro_Config> => {
const default_config = await create_default_config(create_empty_config());
const config_path = join(dir, CONFIG_PATH);
let config: Gro_Config;
if (await exists(config_path)) {
const config_module = await import(config_path);
validate_config_module(config_module, config_path);
config =
typeof config_module.default === 'function'
? await config_module.default(default_config)
: config_module.default;
} else {
config = default_config;
}
return config;
};
export const validate_config_module: (
config_module: any,
config_path: string,
) => asserts config_module is Gro_Config_Module = (config_module, config_path) => {
const config = config_module.default;
if (!config) {
throw Error(`Invalid Gro config module at ${config_path}: expected a default export`);
} else if (!(typeof config === 'function' || typeof config === 'object')) {
throw Error(
`Invalid Gro config module at ${config_path}: the default export must be a function or object`,
);
}
};