@arbor-css/util 0.0.102 → 0.0.104
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/dist/configLoader.d.ts +50 -0
- package/dist/configLoader.d.ts.map +1 -0
- package/dist/configLoader.js +100 -0
- package/dist/configLoader.js.map +1 -0
- package/package.json +8 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The filenames Arbor recognises as config entry points, in search priority order.
|
|
3
|
+
*/
|
|
4
|
+
export declare const CONFIG_FILE_NAMES: readonly ["arbor.config.ts", "arbor.config.js", "arbor.config.mjs"];
|
|
5
|
+
export type ConfigFileName = (typeof CONFIG_FILE_NAMES)[number];
|
|
6
|
+
/**
|
|
7
|
+
* A minimal subset of the jiti `Jiti` interface that `loadConfigWithDeps`
|
|
8
|
+
* requires. Typed this way so that callers can pass either
|
|
9
|
+
* `createJiti(…)` or `createJiti` from `'jiti/static'` — both satisfy it.
|
|
10
|
+
*/
|
|
11
|
+
export interface JitiLike {
|
|
12
|
+
/** The module cache populated by jiti during require/import calls. */
|
|
13
|
+
cache: Record<string, unknown>;
|
|
14
|
+
import<T = unknown>(id: string, opts?: unknown): Promise<T>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The result of a successful config load.
|
|
18
|
+
*/
|
|
19
|
+
export interface LoadedConfigWithDeps<TPreset> {
|
|
20
|
+
/** Absolute path to the config entry-point file. */
|
|
21
|
+
configPath: string;
|
|
22
|
+
/** The default export from the config file (expected to be an ArborPreset). */
|
|
23
|
+
preset: TPreset;
|
|
24
|
+
/**
|
|
25
|
+
* All local (non-node_modules) files that were transitively imported while
|
|
26
|
+
* loading the config, including the config file itself.
|
|
27
|
+
* Use this list to set up file-watchers or PostCSS dependency messages so
|
|
28
|
+
* that changes to any imported module trigger a reload.
|
|
29
|
+
*/
|
|
30
|
+
dependencies: string[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Load an Arbor config file via a provided jiti instance and collect every
|
|
34
|
+
* local module that was transitively imported during the load.
|
|
35
|
+
*
|
|
36
|
+
* @param configPath - Absolute path to the config entry-point.
|
|
37
|
+
* @param jiti - A pre-created jiti instance (caller supplies the
|
|
38
|
+
* appropriate variant: `jiti` or `jiti/static`).
|
|
39
|
+
*
|
|
40
|
+
* @returns The loaded preset and the full dependency set, or `null` if loading fails.
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadConfigWithDeps<TPreset = unknown>(configPath: string, jiti: JitiLike): Promise<LoadedConfigWithDeps<TPreset> | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Search *only* inside `dir` (no upward traversal) for an Arbor config file.
|
|
45
|
+
* Returns the absolute path to the first match, or `null` if none is found.
|
|
46
|
+
*
|
|
47
|
+
* Used by the PostCSS plugin which is anchored to the build's `cwd`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function findConfigInDir(dir: string): Promise<string | null>;
|
|
50
|
+
//# sourceMappingURL=configLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configLoader.d.ts","sourceRoot":"","sources":["../src/configLoader.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,iBAAiB,qEAIpB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACxB,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB,CAAC,OAAO;IAC5C,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CACvB;AAgCD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,GAAG,OAAO,EACzD,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,QAAQ,GACZ,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAkC/C;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWzE"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { access } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
/**
|
|
5
|
+
* The filenames Arbor recognises as config entry points, in search priority order.
|
|
6
|
+
*/
|
|
7
|
+
export const CONFIG_FILE_NAMES = [
|
|
8
|
+
'arbor.config.ts',
|
|
9
|
+
'arbor.config.js',
|
|
10
|
+
'arbor.config.mjs',
|
|
11
|
+
];
|
|
12
|
+
/**
|
|
13
|
+
* Convert a `file://…` URL or an absolute path to a normalised absolute
|
|
14
|
+
* filesystem path. Returns `null` for non-filesystem identifiers (e.g. bare
|
|
15
|
+
* module specifiers, data: URLs).
|
|
16
|
+
*/
|
|
17
|
+
function toFsPath(id) {
|
|
18
|
+
try {
|
|
19
|
+
if (id.startsWith('file://')) {
|
|
20
|
+
return fileURLToPath(id);
|
|
21
|
+
}
|
|
22
|
+
// jiti also stores plain paths in some environments.
|
|
23
|
+
// it seems that it also uses forward slashes in Windows...
|
|
24
|
+
// stuff like '/home/user/...' and 'c:/users/...' shows up.
|
|
25
|
+
if (id.startsWith('/') || /^[A-Za-z]:[\\/]/.test(id)) {
|
|
26
|
+
return id;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// ignore malformed URLs
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns true for paths that live inside a `node_modules` directory.
|
|
36
|
+
* We only want to watch first-party source files.
|
|
37
|
+
*/
|
|
38
|
+
function isNodeModule(fsPath) {
|
|
39
|
+
return fsPath.includes('node_modules');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load an Arbor config file via a provided jiti instance and collect every
|
|
43
|
+
* local module that was transitively imported during the load.
|
|
44
|
+
*
|
|
45
|
+
* @param configPath - Absolute path to the config entry-point.
|
|
46
|
+
* @param jiti - A pre-created jiti instance (caller supplies the
|
|
47
|
+
* appropriate variant: `jiti` or `jiti/static`).
|
|
48
|
+
*
|
|
49
|
+
* @returns The loaded preset and the full dependency set, or `null` if loading fails.
|
|
50
|
+
*/
|
|
51
|
+
export async function loadConfigWithDeps(configPath, jiti) {
|
|
52
|
+
// Snapshot the keys already in jiti's cache so we can diff afterwards.
|
|
53
|
+
// We need moduleCache *enabled* during the load so that jiti populates
|
|
54
|
+
// cache as it resolves transitive imports — that's how we discover deps.
|
|
55
|
+
const cacheKeysBefore = new Set(Object.keys(jiti.cache));
|
|
56
|
+
const mod = await jiti.import(configPath);
|
|
57
|
+
const preset = (mod?.default ?? mod);
|
|
58
|
+
// Collect all cache keys that appeared during this load, then immediately
|
|
59
|
+
// evict them so the next reload re-evaluates every module from scratch
|
|
60
|
+
// (equivalent to moduleCache: false, but compatible with dep tracking).
|
|
61
|
+
const newKeys = Object.keys(jiti.cache).filter((k) => !cacheKeysBefore.has(k));
|
|
62
|
+
for (const key of newKeys) {
|
|
63
|
+
delete jiti.cache[key];
|
|
64
|
+
}
|
|
65
|
+
const dependencies = [];
|
|
66
|
+
for (const key of newKeys) {
|
|
67
|
+
const fsPath = toFsPath(key);
|
|
68
|
+
if (!fsPath)
|
|
69
|
+
continue;
|
|
70
|
+
if (isNodeModule(fsPath))
|
|
71
|
+
continue;
|
|
72
|
+
dependencies.push(fsPath);
|
|
73
|
+
}
|
|
74
|
+
// Always include the entry point itself — jiti may not cache it under the
|
|
75
|
+
// exact same string we passed (e.g. file:// URL vs plain path).
|
|
76
|
+
if (!dependencies.includes(configPath)) {
|
|
77
|
+
dependencies.unshift(configPath);
|
|
78
|
+
}
|
|
79
|
+
return { configPath, preset, dependencies };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Search *only* inside `dir` (no upward traversal) for an Arbor config file.
|
|
83
|
+
* Returns the absolute path to the first match, or `null` if none is found.
|
|
84
|
+
*
|
|
85
|
+
* Used by the PostCSS plugin which is anchored to the build's `cwd`.
|
|
86
|
+
*/
|
|
87
|
+
export async function findConfigInDir(dir) {
|
|
88
|
+
for (const candidate of CONFIG_FILE_NAMES) {
|
|
89
|
+
const resolvedPath = resolve(dir, candidate);
|
|
90
|
+
try {
|
|
91
|
+
await access(resolvedPath);
|
|
92
|
+
return resolvedPath;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=configLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configLoader.js","sourceRoot":"","sources":["../src/configLoader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arbor-css/util",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.104",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,10 +17,17 @@
|
|
|
17
17
|
"node": "./dist/index.js",
|
|
18
18
|
"types": "./dist/index.d.ts",
|
|
19
19
|
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./config-loader": {
|
|
22
|
+
"import": "./dist/configLoader.js",
|
|
23
|
+
"node": "./dist/configLoader.js",
|
|
24
|
+
"types": "./dist/configLoader.d.ts",
|
|
25
|
+
"default": "./dist/configLoader.js"
|
|
20
26
|
}
|
|
21
27
|
},
|
|
22
28
|
"sideEffects": false,
|
|
23
29
|
"devDependencies": {
|
|
30
|
+
"@types/node": "^25.9.1",
|
|
24
31
|
"typescript": "^6.0.3"
|
|
25
32
|
},
|
|
26
33
|
"dependencies": {},
|