@mochi-css/config 3.0.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 ADDED
@@ -0,0 +1,136 @@
1
+ # 🧁 Mochi-CSS/config
2
+
3
+ This package is part of the [Mochi-CSS project](https://github.com/Niikelion/mochi-css).
4
+ It provides the shared configuration layer - types, config file loading, and config resolution - used by all Mochi-CSS integrations (Vite, PostCSS, Next.js).
5
+
6
+ ---
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm i @mochi-css/config --save-dev
12
+ ```
13
+
14
+ ---
15
+
16
+ ## `mochi.config.ts`
17
+
18
+ Place a `mochi.config.mts` (or `.cts`, `.ts`, `.mjs`, `.cjs`, `.js`) file in your project root to configure all Mochi-CSS integrations in one place.
19
+
20
+ ```typescript
21
+ // mochi.config.mts
22
+ import { defineConfig } from "@mochi-css/config"
23
+
24
+ export default defineConfig({
25
+ roots: ["src"],
26
+ splitCss: true,
27
+ })
28
+ ```
29
+
30
+ All Mochi-CSS integrations automatically load this file - you don't need to pass the same options to each plugin separately.
31
+
32
+ ---
33
+
34
+ ## API
35
+
36
+ ### `defineConfig`
37
+
38
+ Identity helper that provides full type inference for your config file.
39
+
40
+ ```typescript
41
+ function defineConfig(config: MochiConfig): MochiConfig
42
+ ```
43
+
44
+ ---
45
+
46
+ ### `loadConfig`
47
+
48
+ Finds and loads the nearest `mochi.config.*` file. Returns `{}` if no file is found.
49
+
50
+ ```typescript
51
+ async function loadConfig(cwd?: string): Promise<MochiConfig>
52
+ ```
53
+
54
+ Searched file names (in order): `mochi.config.mts`, `mochi.config.cts`, `mochi.config.ts`, `mochi.config.mjs`, `mochi.config.cjs`, `mochi.config.js`.
55
+
56
+ ---
57
+
58
+ ### `resolveConfig`
59
+
60
+ Merges a file config, inline plugin options, and defaults into a fully resolved config.
61
+ Runs all `MochiPlugin.onConfigResolved` hooks in order.
62
+
63
+ ```typescript
64
+ async function resolveConfig(
65
+ fileConfig: MochiConfig,
66
+ inlineOpts?: MochiConfig,
67
+ defaults?: Partial<ResolvedConfig>,
68
+ ): Promise<ResolvedConfig>
69
+ ```
70
+
71
+ **Merge behaviour:**
72
+ - Arrays (`roots`, `extractors`, `esbuildPlugins`): file config + inline options concatenated, falling back to defaults
73
+ - Scalar values (`splitCss`, `tmpDir`): inline options take precedence over file config, then defaults
74
+ - Callbacks (`onDiagnostic`): both callbacks are called when both are provided
75
+
76
+ ---
77
+
78
+ ## Types
79
+
80
+ ### `MochiConfig`
81
+
82
+ The user-facing config. All fields are optional.
83
+
84
+ | Field | Type | Description |
85
+ |------------------|--------------------|-----------------------------------------------------------|
86
+ | `roots` | `RootEntry[]` | Directories scanned for source files (default: `["src"]`) |
87
+ | `extractors` | `StyleExtractor[]` | Style extractors - merged with defaults from integrations |
88
+ | `splitCss` | `boolean` | Emit per-source-file CSS instead of one global file |
89
+ | `onDiagnostic` | `OnDiagnostic` | Callback for warnings and non-fatal errors |
90
+ | `esbuildPlugins` | `EsbuildPlugin[]` | esbuild plugins forwarded to the bundler |
91
+ | `plugins` | `MochiPlugin[]` | Mochi plugins - run after config is resolved |
92
+ | `tmpDir` | `string` | Manifest/styles output directory |
93
+
94
+ ### `ResolvedConfig`
95
+
96
+ Same as `MochiConfig` but with required fields and no `plugins` key. Produced by `resolveConfig`.
97
+
98
+ ### `MochiPlugin`
99
+
100
+ Hook interface for extending the resolved config.
101
+
102
+ ```typescript
103
+ interface MochiPlugin {
104
+ name: string
105
+ onConfigResolved?: (config: ResolvedConfig) => Promise<ResolvedConfig> | ResolvedConfig
106
+ }
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Writing a Plugin
112
+
113
+ ```typescript
114
+ import type { MochiPlugin } from "@mochi-css/config"
115
+ import { myExtractor } from "./myExtractor"
116
+
117
+ export const myPlugin: MochiPlugin = {
118
+ name: "my-plugin",
119
+ onConfigResolved(config) {
120
+ return {
121
+ ...config,
122
+ extractors: [...config.extractors, myExtractor],
123
+ }
124
+ },
125
+ }
126
+ ```
127
+
128
+ ```typescript
129
+ // mochi.config.ts
130
+ import { defineConfig } from "@mochi-css/config"
131
+ import { myPlugin } from "./myPlugin"
132
+
133
+ export default defineConfig({
134
+ plugins: [myPlugin],
135
+ })
136
+ ```
@@ -0,0 +1,93 @@
1
+ import { AstPostProcessor, OnDiagnostic, OnDiagnostic as OnDiagnostic$1, RootEntry, RootEntry as RootEntry$1, StyleExtractor, StyleExtractor as StyleExtractor$1 } from "@mochi-css/builder";
2
+
3
+ //#region src/merge.d.ts
4
+ declare function mergeArrays<T>(a: T[] | undefined, b: T[] | undefined): T[] | undefined;
5
+ type Callback<T extends unknown[]> = (...args: T) => void;
6
+ declare function mergeCallbacks<T extends unknown[]>(a: Callback<T> | undefined, b: Callback<T> | undefined): Callback<T> | undefined;
7
+ //#endregion
8
+ //#region src/plugin/TransformationPipeline.d.ts
9
+ type Transformation<T, Args extends unknown[]> = (value: T, ...args: Args) => T | Promise<T>;
10
+ interface TransformationHookProvider<T, Args extends unknown[] = [], Data = void> {
11
+ registerTransformation(transformation: Transformation<T, Args>, data: Data): void;
12
+ }
13
+ interface TransformationUser<T, Args extends unknown[] = []> {
14
+ transform(value: T, ...args: Args): Promise<T>;
15
+ }
16
+ declare class TransformationPipeline<T, Args extends unknown[] = []> implements TransformationHookProvider<T, Args>, TransformationUser<T, Args> {
17
+ private readonly transformations;
18
+ registerTransformation(transformation: Transformation<T, Args>): void;
19
+ transform(value: T, ...args: Args): Promise<T>;
20
+ getTransformations(): Transformation<T, Args>[];
21
+ }
22
+ type TransformationWithContext<T, Args extends unknown[], Data> = {
23
+ fn: Transformation<T, Args>;
24
+ ctx: Data;
25
+ };
26
+ type TransformationFilter<Data, Args extends unknown[]> = (this: void, data: Data, ...args: Args) => boolean;
27
+ declare class FilteredTransformationPipeline<T, Data, Args extends unknown[] = []> implements TransformationHookProvider<T, Args, Data>, TransformationUser<T, Args> {
28
+ private filter;
29
+ private readonly transformations;
30
+ constructor(filter: TransformationFilter<Data, Args>);
31
+ registerTransformation(transformation: Transformation<T, Args>, data: Data): void;
32
+ transform(value: T, ...args: Args): Promise<T>;
33
+ getTransformations(): TransformationWithContext<T, Args, Data>[];
34
+ }
35
+ //#endregion
36
+ //#region src/plugin/Context.d.ts
37
+ type FileTransformOptions = {
38
+ filePath: string;
39
+ };
40
+ type FileTransformData = {
41
+ filter?: string;
42
+ };
43
+ type FileTransformationHookProvider = TransformationHookProvider<string, [FileTransformOptions], FileTransformData>;
44
+ interface AnalysisTransformHookProvider {
45
+ register(hook: AstPostProcessor): void;
46
+ }
47
+ declare class AnalysisHookCollector implements AnalysisTransformHookProvider {
48
+ private readonly hooks;
49
+ register(hook: AstPostProcessor): void;
50
+ getHooks(): AstPostProcessor[];
51
+ }
52
+ interface PluginContext {
53
+ readonly sourceTransform: FileTransformationHookProvider;
54
+ readonly analysisTransform: AnalysisTransformHookProvider;
55
+ }
56
+ declare class FullContext implements PluginContext {
57
+ readonly sourceTransform: FilteredTransformationPipeline<string, FileTransformData, [FileTransformOptions]>;
58
+ readonly analysisTransform: AnalysisHookCollector;
59
+ getAnalysisHooks(): AstPostProcessor[];
60
+ }
61
+ //#endregion
62
+ //#region src/plugin/Plugin.d.ts
63
+ interface Plugin<Config$1 extends object> {
64
+ name: string;
65
+ onConfigResolved?(this: void, config: Config$1): Promise<Config$1> | Config$1;
66
+ onLoad?(context: PluginContext): void;
67
+ }
68
+ //#endregion
69
+ //#region src/config/index.d.ts
70
+ interface Config {
71
+ roots: RootEntry$1[];
72
+ extractors: StyleExtractor$1[];
73
+ splitCss: boolean;
74
+ onDiagnostic?: OnDiagnostic$1;
75
+ plugins: Plugin<Config>[];
76
+ tmpDir?: string;
77
+ debug?: boolean;
78
+ }
79
+ type MochiPlugin = Plugin<Config>;
80
+ declare function defineConfig(config: Partial<Config>): Partial<Config>;
81
+ declare function resolveConfig(fileConfig: Partial<Config>, inlineConfig?: Partial<Config>, defaults?: Partial<Config>): Promise<Config>;
82
+ declare function loadConfig(cwd?: string): Promise<Partial<Config>>;
83
+ //#endregion
84
+ //#region src/styledIdPlugin.d.ts
85
+ /**
86
+ * Returns a MochiPlugin that injects stable `s-` class IDs into every `styled()` call.
87
+ * - Registers a `sourceTransform` for runtime source injection (Vite/Next `transform` hook).
88
+ * - Registers an `analysisTransform` for CSS extraction via direct AST mutation.
89
+ */
90
+ declare function styledIdPlugin(): MochiPlugin;
91
+ //#endregion
92
+ export { type AnalysisTransformHookProvider, Config, FullContext, MochiPlugin, type OnDiagnostic, type PluginContext, type RootEntry, type StyleExtractor, type TransformationHookProvider, TransformationPipeline, type TransformationUser, defineConfig, loadConfig, mergeArrays, mergeCallbacks, resolveConfig, styledIdPlugin };
93
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,93 @@
1
+ import { AstPostProcessor, OnDiagnostic, OnDiagnostic as OnDiagnostic$1, RootEntry, RootEntry as RootEntry$1, StyleExtractor, StyleExtractor as StyleExtractor$1 } from "@mochi-css/builder";
2
+
3
+ //#region src/merge.d.ts
4
+ declare function mergeArrays<T>(a: T[] | undefined, b: T[] | undefined): T[] | undefined;
5
+ type Callback<T extends unknown[]> = (...args: T) => void;
6
+ declare function mergeCallbacks<T extends unknown[]>(a: Callback<T> | undefined, b: Callback<T> | undefined): Callback<T> | undefined;
7
+ //#endregion
8
+ //#region src/plugin/TransformationPipeline.d.ts
9
+ type Transformation<T, Args extends unknown[]> = (value: T, ...args: Args) => T | Promise<T>;
10
+ interface TransformationHookProvider<T, Args extends unknown[] = [], Data = void> {
11
+ registerTransformation(transformation: Transformation<T, Args>, data: Data): void;
12
+ }
13
+ interface TransformationUser<T, Args extends unknown[] = []> {
14
+ transform(value: T, ...args: Args): Promise<T>;
15
+ }
16
+ declare class TransformationPipeline<T, Args extends unknown[] = []> implements TransformationHookProvider<T, Args>, TransformationUser<T, Args> {
17
+ private readonly transformations;
18
+ registerTransformation(transformation: Transformation<T, Args>): void;
19
+ transform(value: T, ...args: Args): Promise<T>;
20
+ getTransformations(): Transformation<T, Args>[];
21
+ }
22
+ type TransformationWithContext<T, Args extends unknown[], Data> = {
23
+ fn: Transformation<T, Args>;
24
+ ctx: Data;
25
+ };
26
+ type TransformationFilter<Data, Args extends unknown[]> = (this: void, data: Data, ...args: Args) => boolean;
27
+ declare class FilteredTransformationPipeline<T, Data, Args extends unknown[] = []> implements TransformationHookProvider<T, Args, Data>, TransformationUser<T, Args> {
28
+ private filter;
29
+ private readonly transformations;
30
+ constructor(filter: TransformationFilter<Data, Args>);
31
+ registerTransformation(transformation: Transformation<T, Args>, data: Data): void;
32
+ transform(value: T, ...args: Args): Promise<T>;
33
+ getTransformations(): TransformationWithContext<T, Args, Data>[];
34
+ }
35
+ //#endregion
36
+ //#region src/plugin/Context.d.ts
37
+ type FileTransformOptions = {
38
+ filePath: string;
39
+ };
40
+ type FileTransformData = {
41
+ filter?: string;
42
+ };
43
+ type FileTransformationHookProvider = TransformationHookProvider<string, [FileTransformOptions], FileTransformData>;
44
+ interface AnalysisTransformHookProvider {
45
+ register(hook: AstPostProcessor): void;
46
+ }
47
+ declare class AnalysisHookCollector implements AnalysisTransformHookProvider {
48
+ private readonly hooks;
49
+ register(hook: AstPostProcessor): void;
50
+ getHooks(): AstPostProcessor[];
51
+ }
52
+ interface PluginContext {
53
+ readonly sourceTransform: FileTransformationHookProvider;
54
+ readonly analysisTransform: AnalysisTransformHookProvider;
55
+ }
56
+ declare class FullContext implements PluginContext {
57
+ readonly sourceTransform: FilteredTransformationPipeline<string, FileTransformData, [FileTransformOptions]>;
58
+ readonly analysisTransform: AnalysisHookCollector;
59
+ getAnalysisHooks(): AstPostProcessor[];
60
+ }
61
+ //#endregion
62
+ //#region src/plugin/Plugin.d.ts
63
+ interface Plugin<Config$1 extends object> {
64
+ name: string;
65
+ onConfigResolved?(this: void, config: Config$1): Promise<Config$1> | Config$1;
66
+ onLoad?(context: PluginContext): void;
67
+ }
68
+ //#endregion
69
+ //#region src/config/index.d.ts
70
+ interface Config {
71
+ roots: RootEntry$1[];
72
+ extractors: StyleExtractor$1[];
73
+ splitCss: boolean;
74
+ onDiagnostic?: OnDiagnostic$1;
75
+ plugins: Plugin<Config>[];
76
+ tmpDir?: string;
77
+ debug?: boolean;
78
+ }
79
+ type MochiPlugin = Plugin<Config>;
80
+ declare function defineConfig(config: Partial<Config>): Partial<Config>;
81
+ declare function resolveConfig(fileConfig: Partial<Config>, inlineConfig?: Partial<Config>, defaults?: Partial<Config>): Promise<Config>;
82
+ declare function loadConfig(cwd?: string): Promise<Partial<Config>>;
83
+ //#endregion
84
+ //#region src/styledIdPlugin.d.ts
85
+ /**
86
+ * Returns a MochiPlugin that injects stable `s-` class IDs into every `styled()` call.
87
+ * - Registers a `sourceTransform` for runtime source injection (Vite/Next `transform` hook).
88
+ * - Registers an `analysisTransform` for CSS extraction via direct AST mutation.
89
+ */
90
+ declare function styledIdPlugin(): MochiPlugin;
91
+ //#endregion
92
+ export { type AnalysisTransformHookProvider, Config, FullContext, MochiPlugin, type OnDiagnostic, type PluginContext, type RootEntry, type StyleExtractor, type TransformationHookProvider, TransformationPipeline, type TransformationUser, defineConfig, loadConfig, mergeArrays, mergeCallbacks, resolveConfig, styledIdPlugin };
93
+ //# sourceMappingURL=index.d.ts.map