styles-config 2.0.0-alpha.5 → 2.0.0-alpha.7

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/lib/index.cjs ADDED
@@ -0,0 +1,245 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let cosmiconfig = require("cosmiconfig");
25
+ let picomatch = require("picomatch");
26
+ picomatch = __toESM(picomatch);
27
+ let path = require("path");
28
+ path = __toESM(path);
29
+ //#region src/loader.ts
30
+ const explorer = (0, cosmiconfig.cosmiconfig)("styles", {
31
+ searchPlaces: [
32
+ "styles.config.ts",
33
+ "styles.config.js",
34
+ "styles.config.mts",
35
+ "styles.config.mjs",
36
+ "styles.config.cjs",
37
+ "styles.config.cts"
38
+ ],
39
+ loaders: {
40
+ ".mts": cosmiconfig.defaultLoadersSync[".ts"],
41
+ ".cts": cosmiconfig.defaultLoadersSync[".ts"],
42
+ ".mjs": cosmiconfig.defaultLoadersSync[".js"],
43
+ ".cjs": cosmiconfig.defaultLoadersSync[".cjs"]
44
+ }
45
+ });
46
+ const explorerSync = (0, cosmiconfig.cosmiconfigSync)("styles", {
47
+ searchPlaces: [
48
+ "styles.config.ts",
49
+ "styles.config.js",
50
+ "styles.config.mts",
51
+ "styles.config.mjs",
52
+ "styles.config.cjs",
53
+ "styles.config.cts"
54
+ ],
55
+ loaders: {
56
+ ".mts": cosmiconfig.defaultLoadersSync[".ts"],
57
+ ".cts": cosmiconfig.defaultLoadersSync[".ts"],
58
+ ".mjs": cosmiconfig.defaultLoadersSync[".js"],
59
+ ".cjs": cosmiconfig.defaultLoadersSync[".cjs"]
60
+ }
61
+ });
62
+ /**
63
+ * Load styles configuration from the file system (async)
64
+ * @param searchFrom - Directory to search from (defaults to process.cwd())
65
+ * @returns Configuration object or null if not found
66
+ */
67
+ async function loadConfig(searchFrom) {
68
+ const result = await explorer.search(searchFrom);
69
+ return result?.config ? normalizeConfig(result.config) : null;
70
+ }
71
+ /**
72
+ * Load styles configuration from the file system (sync)
73
+ * @param searchFrom - Directory to search from (defaults to process.cwd())
74
+ * @returns Configuration object or empty object if not found
75
+ */
76
+ function loadConfigSync(searchFrom) {
77
+ const result = explorerSync.search(searchFrom);
78
+ return result?.config ? normalizeConfig(result.config) : {};
79
+ }
80
+ /**
81
+ * Load styles configuration with metadata (sync).
82
+ * Includes config file path when a config file is discovered.
83
+ */
84
+ function loadConfigSyncWithMeta(searchFrom) {
85
+ const result = explorerSync.search(searchFrom);
86
+ return {
87
+ config: result?.config ? normalizeConfig(result.config) : {},
88
+ configFilePath: result?.filepath
89
+ };
90
+ }
91
+ /**
92
+ * Load styles configuration from a specific file path (async)
93
+ * @param filePath - Path to the config file
94
+ * @returns Configuration object or null if not found
95
+ */
96
+ async function loadConfigFromPath(filePath) {
97
+ const result = await explorer.load(filePath);
98
+ return result?.config ? normalizeConfig(result.config) : null;
99
+ }
100
+ /**
101
+ * Load styles configuration from a specific file path (sync)
102
+ * @param filePath - Path to the config file
103
+ * @returns Configuration object or empty object if not found
104
+ */
105
+ function loadConfigFromPathSync(filePath) {
106
+ const result = explorerSync.load(filePath);
107
+ return result?.config ? normalizeConfig(result.config) : {};
108
+ }
109
+ /**
110
+ * Normalize config object - handle default exports and ensure proper type
111
+ */
112
+ function isStylesConfig(value) {
113
+ return typeof value === "object" && value !== null;
114
+ }
115
+ function normalizeConfig(config) {
116
+ if (isStylesConfig(config) && "default" in config) return normalizeConfig(config.default);
117
+ if (isStylesConfig(config)) return config;
118
+ return {};
119
+ }
120
+ //#endregion
121
+ //#region src/options.ts
122
+ /**
123
+ * Expand the `strict` convenience preset. When `strict` is truthy, fills the
124
+ * strict bundle for any governed option left `undefined` — an explicitly set
125
+ * option always wins. Modeled after `tsconfig`'s `strict`: it only *sets*
126
+ * semantic options, it is not itself a mode. Sets the strictest value of each
127
+ * governed axis (`equalityMode: 'exact'` is the no-coercion dialect).
128
+ *
129
+ * Returns a new object (never mutates the input); a no-op when `strict` is falsy.
130
+ */
131
+ function applyStrictPreset(opts) {
132
+ if (!opts?.strict) return opts;
133
+ const filled = { ...opts };
134
+ filled.unitMode ??= "strict";
135
+ filled.equalityMode ??= "exact";
136
+ filled.leakyScope ??= false;
137
+ filled.allowOverloadedImport ??= false;
138
+ return filled;
139
+ }
140
+ /**
141
+ * Map of file extensions to language keys
142
+ */
143
+ const extensionToLanguage = new Map([
144
+ [".less", "less"],
145
+ [".scss", "scss"],
146
+ [".sass", "scss"],
147
+ [".jess", "jess"],
148
+ [".css", "css"]
149
+ ]);
150
+ /**
151
+ * Infer language from a file path's extension
152
+ */
153
+ function inferLanguage(filePath) {
154
+ if (!filePath) return;
155
+ const ext = path.default.extname(filePath).toLowerCase();
156
+ return extensionToLanguage.get(ext);
157
+ }
158
+ /**
159
+ * Check if a file path matches a pattern (exact path, relative path, or glob)
160
+ */
161
+ function matchesFile(pattern, filePath) {
162
+ if (!pattern || !filePath) return false;
163
+ const normalizedPattern = path.default.normalize(pattern);
164
+ const normalizedFile = path.default.normalize(filePath);
165
+ if (normalizedPattern === normalizedFile) return true;
166
+ if (path.default.basename(normalizedFile) === normalizedPattern) return true;
167
+ const isMatch = (0, picomatch.default)(pattern, { dot: true });
168
+ return isMatch(filePath) || isMatch(normalizedFile);
169
+ }
170
+ /**
171
+ * Get matching options from an array of file-based options.
172
+ * Returns merged options from:
173
+ * 1. All entries without a `file` property (defaults)
174
+ * 2. All entries whose `file` pattern matches the given path
175
+ *
176
+ * Later entries override earlier ones.
177
+ */
178
+ function getMatchingOptions(options, filePath) {
179
+ if (!options) return {};
180
+ const optionsArray = Array.isArray(options) ? options : [options];
181
+ let result = {};
182
+ for (const opt of optionsArray) if (!opt.file || filePath && matchesFile(opt.file, filePath)) {
183
+ const { file, ...rest } = opt;
184
+ result = {
185
+ ...result,
186
+ ...rest
187
+ };
188
+ }
189
+ return result;
190
+ }
191
+ /**
192
+ * Get merged options by combining compile, language, input, and output settings.
193
+ *
194
+ * Merge priority (later wins):
195
+ * 1. compile options (base)
196
+ * 2. language-specific options (inferred from input extension or explicitly specified)
197
+ * 3. matched input options (if input path provided and matches)
198
+ * 4. matched output options (if output path provided and matches)
199
+ *
200
+ * @param config - The styles configuration object
201
+ * @param params - Options specifying language, input file, and output file
202
+ * @returns Merged options object
203
+ *
204
+ * @example
205
+ * // Get Less options for a specific input/output (language inferred from .less extension)
206
+ * const options = getOptions(config, {
207
+ * input: 'src/styles/main.less',
208
+ * output: 'dist/main.css'
209
+ * });
210
+ *
211
+ * @example
212
+ * // Explicitly specify language
213
+ * const options = getOptions(config, { language: 'less' });
214
+ *
215
+ * @example
216
+ * // Get base options without language-specific settings
217
+ * const options = getOptions(config);
218
+ */
219
+ function getOptions(config = {}, params = {}) {
220
+ const { input: inputFile, output: outputFile } = params;
221
+ const { compile = {}, input, output, language: languageConfig = {} } = config;
222
+ const language = params.language ?? inferLanguage(inputFile);
223
+ const languageOptions = language ? languageConfig[language] ?? {} : {};
224
+ const matchedInput = getMatchingOptions(input, inputFile);
225
+ const matchedOutput = getMatchingOptions(output, outputFile);
226
+ return {
227
+ mathMode: compile.mathMode,
228
+ unitMode: compile.unitMode,
229
+ equalityMode: compile.equalityMode,
230
+ allowExtendSelectors: compile.allowExtendSelectors,
231
+ disableScriptModules: compile.disableScriptModules ?? compile.disablePluginRule,
232
+ paths: compile.searchPaths,
233
+ ...languageOptions,
234
+ ...matchedInput,
235
+ ...matchedOutput
236
+ };
237
+ }
238
+ //#endregion
239
+ exports.applyStrictPreset = applyStrictPreset;
240
+ exports.getOptions = getOptions;
241
+ exports.loadConfig = loadConfig;
242
+ exports.loadConfigFromPath = loadConfigFromPath;
243
+ exports.loadConfigFromPathSync = loadConfigFromPathSync;
244
+ exports.loadConfigSync = loadConfigSync;
245
+ exports.loadConfigSyncWithMeta = loadConfigSyncWithMeta;
package/lib/index.js CHANGED
@@ -1,4 +1,214 @@
1
- export * from './types.js';
2
- export * from './loader.js';
3
- export * from './options.js';
4
- //# sourceMappingURL=index.js.map
1
+ import { cosmiconfig, cosmiconfigSync, defaultLoadersSync } from "cosmiconfig";
2
+ import picomatch from "picomatch";
3
+ import path from "path";
4
+ //#region src/loader.ts
5
+ const explorer = cosmiconfig("styles", {
6
+ searchPlaces: [
7
+ "styles.config.ts",
8
+ "styles.config.js",
9
+ "styles.config.mts",
10
+ "styles.config.mjs",
11
+ "styles.config.cjs",
12
+ "styles.config.cts"
13
+ ],
14
+ loaders: {
15
+ ".mts": defaultLoadersSync[".ts"],
16
+ ".cts": defaultLoadersSync[".ts"],
17
+ ".mjs": defaultLoadersSync[".js"],
18
+ ".cjs": defaultLoadersSync[".cjs"]
19
+ }
20
+ });
21
+ const explorerSync = cosmiconfigSync("styles", {
22
+ searchPlaces: [
23
+ "styles.config.ts",
24
+ "styles.config.js",
25
+ "styles.config.mts",
26
+ "styles.config.mjs",
27
+ "styles.config.cjs",
28
+ "styles.config.cts"
29
+ ],
30
+ loaders: {
31
+ ".mts": defaultLoadersSync[".ts"],
32
+ ".cts": defaultLoadersSync[".ts"],
33
+ ".mjs": defaultLoadersSync[".js"],
34
+ ".cjs": defaultLoadersSync[".cjs"]
35
+ }
36
+ });
37
+ /**
38
+ * Load styles configuration from the file system (async)
39
+ * @param searchFrom - Directory to search from (defaults to process.cwd())
40
+ * @returns Configuration object or null if not found
41
+ */
42
+ async function loadConfig(searchFrom) {
43
+ const result = await explorer.search(searchFrom);
44
+ return result?.config ? normalizeConfig(result.config) : null;
45
+ }
46
+ /**
47
+ * Load styles configuration from the file system (sync)
48
+ * @param searchFrom - Directory to search from (defaults to process.cwd())
49
+ * @returns Configuration object or empty object if not found
50
+ */
51
+ function loadConfigSync(searchFrom) {
52
+ const result = explorerSync.search(searchFrom);
53
+ return result?.config ? normalizeConfig(result.config) : {};
54
+ }
55
+ /**
56
+ * Load styles configuration with metadata (sync).
57
+ * Includes config file path when a config file is discovered.
58
+ */
59
+ function loadConfigSyncWithMeta(searchFrom) {
60
+ const result = explorerSync.search(searchFrom);
61
+ return {
62
+ config: result?.config ? normalizeConfig(result.config) : {},
63
+ configFilePath: result?.filepath
64
+ };
65
+ }
66
+ /**
67
+ * Load styles configuration from a specific file path (async)
68
+ * @param filePath - Path to the config file
69
+ * @returns Configuration object or null if not found
70
+ */
71
+ async function loadConfigFromPath(filePath) {
72
+ const result = await explorer.load(filePath);
73
+ return result?.config ? normalizeConfig(result.config) : null;
74
+ }
75
+ /**
76
+ * Load styles configuration from a specific file path (sync)
77
+ * @param filePath - Path to the config file
78
+ * @returns Configuration object or empty object if not found
79
+ */
80
+ function loadConfigFromPathSync(filePath) {
81
+ const result = explorerSync.load(filePath);
82
+ return result?.config ? normalizeConfig(result.config) : {};
83
+ }
84
+ /**
85
+ * Normalize config object - handle default exports and ensure proper type
86
+ */
87
+ function isStylesConfig(value) {
88
+ return typeof value === "object" && value !== null;
89
+ }
90
+ function normalizeConfig(config) {
91
+ if (isStylesConfig(config) && "default" in config) return normalizeConfig(config.default);
92
+ if (isStylesConfig(config)) return config;
93
+ return {};
94
+ }
95
+ //#endregion
96
+ //#region src/options.ts
97
+ /**
98
+ * Expand the `strict` convenience preset. When `strict` is truthy, fills the
99
+ * strict bundle for any governed option left `undefined` — an explicitly set
100
+ * option always wins. Modeled after `tsconfig`'s `strict`: it only *sets*
101
+ * semantic options, it is not itself a mode. Sets the strictest value of each
102
+ * governed axis (`equalityMode: 'exact'` is the no-coercion dialect).
103
+ *
104
+ * Returns a new object (never mutates the input); a no-op when `strict` is falsy.
105
+ */
106
+ function applyStrictPreset(opts) {
107
+ if (!opts?.strict) return opts;
108
+ const filled = { ...opts };
109
+ filled.unitMode ??= "strict";
110
+ filled.equalityMode ??= "exact";
111
+ filled.leakyScope ??= false;
112
+ filled.allowOverloadedImport ??= false;
113
+ return filled;
114
+ }
115
+ /**
116
+ * Map of file extensions to language keys
117
+ */
118
+ const extensionToLanguage = new Map([
119
+ [".less", "less"],
120
+ [".scss", "scss"],
121
+ [".sass", "scss"],
122
+ [".jess", "jess"],
123
+ [".css", "css"]
124
+ ]);
125
+ /**
126
+ * Infer language from a file path's extension
127
+ */
128
+ function inferLanguage(filePath) {
129
+ if (!filePath) return;
130
+ const ext = path.extname(filePath).toLowerCase();
131
+ return extensionToLanguage.get(ext);
132
+ }
133
+ /**
134
+ * Check if a file path matches a pattern (exact path, relative path, or glob)
135
+ */
136
+ function matchesFile(pattern, filePath) {
137
+ if (!pattern || !filePath) return false;
138
+ const normalizedPattern = path.normalize(pattern);
139
+ const normalizedFile = path.normalize(filePath);
140
+ if (normalizedPattern === normalizedFile) return true;
141
+ if (path.basename(normalizedFile) === normalizedPattern) return true;
142
+ const isMatch = picomatch(pattern, { dot: true });
143
+ return isMatch(filePath) || isMatch(normalizedFile);
144
+ }
145
+ /**
146
+ * Get matching options from an array of file-based options.
147
+ * Returns merged options from:
148
+ * 1. All entries without a `file` property (defaults)
149
+ * 2. All entries whose `file` pattern matches the given path
150
+ *
151
+ * Later entries override earlier ones.
152
+ */
153
+ function getMatchingOptions(options, filePath) {
154
+ if (!options) return {};
155
+ const optionsArray = Array.isArray(options) ? options : [options];
156
+ let result = {};
157
+ for (const opt of optionsArray) if (!opt.file || filePath && matchesFile(opt.file, filePath)) {
158
+ const { file, ...rest } = opt;
159
+ result = {
160
+ ...result,
161
+ ...rest
162
+ };
163
+ }
164
+ return result;
165
+ }
166
+ /**
167
+ * Get merged options by combining compile, language, input, and output settings.
168
+ *
169
+ * Merge priority (later wins):
170
+ * 1. compile options (base)
171
+ * 2. language-specific options (inferred from input extension or explicitly specified)
172
+ * 3. matched input options (if input path provided and matches)
173
+ * 4. matched output options (if output path provided and matches)
174
+ *
175
+ * @param config - The styles configuration object
176
+ * @param params - Options specifying language, input file, and output file
177
+ * @returns Merged options object
178
+ *
179
+ * @example
180
+ * // Get Less options for a specific input/output (language inferred from .less extension)
181
+ * const options = getOptions(config, {
182
+ * input: 'src/styles/main.less',
183
+ * output: 'dist/main.css'
184
+ * });
185
+ *
186
+ * @example
187
+ * // Explicitly specify language
188
+ * const options = getOptions(config, { language: 'less' });
189
+ *
190
+ * @example
191
+ * // Get base options without language-specific settings
192
+ * const options = getOptions(config);
193
+ */
194
+ function getOptions(config = {}, params = {}) {
195
+ const { input: inputFile, output: outputFile } = params;
196
+ const { compile = {}, input, output, language: languageConfig = {} } = config;
197
+ const language = params.language ?? inferLanguage(inputFile);
198
+ const languageOptions = language ? languageConfig[language] ?? {} : {};
199
+ const matchedInput = getMatchingOptions(input, inputFile);
200
+ const matchedOutput = getMatchingOptions(output, outputFile);
201
+ return {
202
+ mathMode: compile.mathMode,
203
+ unitMode: compile.unitMode,
204
+ equalityMode: compile.equalityMode,
205
+ allowExtendSelectors: compile.allowExtendSelectors,
206
+ disableScriptModules: compile.disableScriptModules ?? compile.disablePluginRule,
207
+ paths: compile.searchPaths,
208
+ ...languageOptions,
209
+ ...matchedInput,
210
+ ...matchedOutput
211
+ };
212
+ }
213
+ //#endregion
214
+ export { applyStrictPreset, getOptions, loadConfig, loadConfigFromPath, loadConfigFromPathSync, loadConfigSync, loadConfigSyncWithMeta };
package/lib/options.d.ts CHANGED
@@ -1,4 +1,25 @@
1
1
  import type { StylesConfig } from './types.js';
2
+ /**
3
+ * Options bag the `strict` preset can expand. Any bag carrying a `strict` flag
4
+ * plus the semantic modes it governs.
5
+ */
6
+ export interface StrictPresetOptions {
7
+ strict?: boolean;
8
+ unitMode?: 'loose' | 'preserve' | 'strict';
9
+ equalityMode?: 'less' | 'sass' | 'exact';
10
+ leakyScope?: boolean;
11
+ allowOverloadedImport?: boolean;
12
+ }
13
+ /**
14
+ * Expand the `strict` convenience preset. When `strict` is truthy, fills the
15
+ * strict bundle for any governed option left `undefined` — an explicitly set
16
+ * option always wins. Modeled after `tsconfig`'s `strict`: it only *sets*
17
+ * semantic options, it is not itself a mode. Sets the strictest value of each
18
+ * governed axis (`equalityMode: 'exact'` is the no-coercion dialect).
19
+ *
20
+ * Returns a new object (never mutates the input); a no-op when `strict` is falsy.
21
+ */
22
+ export declare function applyStrictPreset<T extends StrictPresetOptions>(opts: T): T;
2
23
  /**
3
24
  * Options for retrieving merged configuration
4
25
  */
package/lib/types.d.ts CHANGED
@@ -7,36 +7,39 @@ export type MathMode = 'always' | 'parens-division' | 'parens' | 'strict';
7
7
  */
8
8
  export type UnitMode = 'loose' | 'preserve' | 'strict';
9
9
  /**
10
- * Equality/coercion modes for guard comparisons.
10
+ * Function-call resolution modes mirrors {@link UnitMode}. Governs an optional
11
+ * (global) function call that matched a registered function but couldn't be
12
+ * evaluated: `preserve` renders it as-is (+ warning), `error` throws.
11
13
  */
12
- export type EqualityMode = 'coerce' | 'strict';
13
- export interface JavaScriptSandboxConfig {
14
- /**
15
- * Allow network access for script execution runtime.
16
- * @default false
17
- */
18
- allowHttp?: boolean;
19
- /**
20
- * Optional host allowlist when `allowHttp` is enabled.
21
- */
22
- allowNetHosts?: string[];
23
- /**
24
- * Optional explicit filesystem root for script reads.
25
- * If omitted, compiler resolves using entry/config roots.
26
- */
27
- jsReadRoot?: string;
28
- }
29
- export type CompileJavaScriptOption = true | JavaScriptSandboxConfig;
14
+ export type FunctionMode = 'preserve' | 'error';
15
+ /**
16
+ * Equality dialects for guard comparisons — named by dialect (Less 4.x and Sass
17
+ * diverge in opposite directions), not by strictness:
18
+ * - `less`: Less 4.x equality (numeric coercion; quoted vs unquoted distinct)
19
+ * - `sass`: Dart Sass equality (unit-strict; quote-insensitive strings)
20
+ * - `exact`: no coercion — operands must be the same node type
21
+ */
22
+ export type EqualityMode = 'less' | 'sass' | 'exact';
23
+ export type ExtendSelectorKind = 'simple' | 'basic' | 'pseudo' | 'complex' | 'compound';
30
24
  /**
31
25
  * Less compiler options
32
26
  * Based on less.js default-options.js and bin/lessc
33
27
  */
34
28
  export interface LessOptions {
29
+ /**
30
+ * Restrict which selector shapes are allowed in extend targets.
31
+ * When set, any other selector kind is a parse error.
32
+ */
33
+ allowExtendSelectors?: ExtendSelectorKind[];
35
34
  /**
36
35
  * Inline Javascript - @plugin still allowed
37
36
  * @default false
38
37
  */
39
38
  javascriptEnabled?: boolean;
39
+ /**
40
+ * @deprecated Use `disableScriptModules` instead.
41
+ */
42
+ disablePluginRule?: boolean;
40
43
  /**
41
44
  * Outputs a makefile import dependency list to stdout.
42
45
  * @default false
@@ -124,11 +127,21 @@ export interface LessOptions {
124
127
  * @default 'preserve'
125
128
  */
126
129
  unitMode?: UnitMode;
130
+ /**
131
+ * How to handle an optional/global function call that matched a registered
132
+ * function but couldn't be evaluated (no matching signature, or it threw) —
133
+ * e.g. `unit(80/16)`, `color("x")`. Mirrors {@link unitMode}.
134
+ * - 'preserve': render the call as-is (like an unknown CSS function) + warn
135
+ * - 'error': throw the underlying function error (Less 4.x behavior)
136
+ * Unknown function names always render as-is regardless.
137
+ * @default 'preserve'
138
+ */
139
+ functionMode?: FunctionMode;
127
140
  /**
128
141
  * How to handle equality/coercion in guards and comparisons.
129
- * - 'coerce': Less-compatible coercion behavior
142
+ * - 'loose': Less-compatible loose (coercive) equality (JS '==')
130
143
  * - 'strict': type-strict behavior
131
- * @default 'coerce'
144
+ * @default 'loose'
132
145
  */
133
146
  equalityMode?: EqualityMode;
134
147
  /**
@@ -201,6 +214,26 @@ export interface LessOptions {
201
214
  * @default false
202
215
  */
203
216
  quiet?: boolean;
217
+ /**
218
+ * Convenience preset. When `true`, sets the strict bundle for any of the
219
+ * following left `undefined` (individual options always win):
220
+ * - `unitMode: 'strict'`
221
+ * - `equalityMode: 'exact'` (the no-coercion dialect)
222
+ * - `leakyScope: false`
223
+ * - `allowOverloadedImport: false`
224
+ *
225
+ * Modeled after `tsconfig` `strict`: it only *sets* semantic options, it is not
226
+ * itself a mode.
227
+ * @default false
228
+ */
229
+ strict?: boolean;
230
+ /**
231
+ * Whether re-importing a file/namespace may contribute *overloaded* (duplicated,
232
+ * additively-merged) definitions rather than being de-duplicated like Less's
233
+ * `@import (once)`. `strict` sets this to `false`.
234
+ * @default true
235
+ */
236
+ allowOverloadedImport?: boolean;
204
237
  /**
205
238
  * @deprecated This is legacy Less behavior.
206
239
  *
@@ -212,7 +245,7 @@ export interface LessOptions {
212
245
  * - Both mixins and detached rulesets: Mixin and VarDeclaration nodes are 'private'
213
246
  * @default true
214
247
  */
215
- leakyRules?: boolean;
248
+ leakyScope?: boolean;
216
249
  /**
217
250
  * Whether to collapse nested selectors (Less 1.x-4.x style flattening)
218
251
  * When true, nested selectors like `.parent { .child { } }` are flattened to `.parent .child { }`
@@ -228,6 +261,13 @@ export interface LessOptions {
228
261
  */
229
262
  bubbleRootAtRules?: boolean;
230
263
  }
264
+ export interface ScssOptions {
265
+ allowExtendSelectors?: ExtendSelectorKind[];
266
+ unitMode?: UnitMode;
267
+ equalityMode?: EqualityMode;
268
+ collapseNesting?: boolean;
269
+ [key: string]: any;
270
+ }
231
271
  /**
232
272
  * Base interface for file-matching options
233
273
  */
@@ -244,9 +284,17 @@ export interface FileMatchOptions {
244
284
  export interface InputOptions extends FileMatchOptions {
245
285
  mathMode?: MathMode;
246
286
  unitMode?: UnitMode;
287
+ functionMode?: FunctionMode;
247
288
  equalityMode?: EqualityMode;
289
+ strict?: boolean;
290
+ allowOverloadedImport?: boolean;
291
+ allowExtendSelectors?: ExtendSelectorKind[];
292
+ disableScriptModules?: boolean;
293
+ /**
294
+ * @deprecated Use `disableScriptModules` instead.
295
+ */
296
+ disablePluginRule?: boolean;
248
297
  searchPaths?: string[];
249
- enableJavaScript?: boolean;
250
298
  javascriptEnabled?: boolean;
251
299
  paths?: string[];
252
300
  globalVars?: Record<string, string> | null;
@@ -254,7 +302,7 @@ export interface InputOptions extends FileMatchOptions {
254
302
  strictImports?: boolean | 'error';
255
303
  rewriteUrls?: boolean | 'all' | 'local' | 'off';
256
304
  rootpath?: string;
257
- leakyRules?: boolean;
305
+ leakyScope?: boolean;
258
306
  collapseNesting?: boolean;
259
307
  bubbleRootAtRules?: boolean;
260
308
  /** Allow additional language-specific options */
@@ -292,11 +340,28 @@ export interface StylesConfig {
292
340
  */
293
341
  plugins?: Array<any | string>;
294
342
  searchPaths?: string[];
295
- enableJavaScript?: boolean;
296
- javascript?: CompileJavaScriptOption;
297
343
  mathMode?: MathMode;
298
344
  unitMode?: UnitMode;
345
+ functionMode?: FunctionMode;
299
346
  equalityMode?: EqualityMode;
347
+ /** See {@link LessOptions.strict}. Expanded onto the other compile modes. */
348
+ strict?: boolean;
349
+ /** See {@link LessOptions.allowOverloadedImport}. */
350
+ allowOverloadedImport?: boolean;
351
+ /** See {@link LessOptions.leakyScope}. */
352
+ leakyScope?: boolean;
353
+ allowExtendSelectors?: ExtendSelectorKind[];
354
+ disableScriptModules?: boolean;
355
+ /**
356
+ * @deprecated Use `disableScriptModules` instead.
357
+ */
358
+ disablePluginRule?: boolean;
359
+ /**
360
+ * Filesystem root that Less `@plugin` / script-module scripts are allowed to
361
+ * be read from. When set, it overrides the default (the entry file's
362
+ * directory). Paths outside this root are rejected by @jesscss/plugin-js.
363
+ */
364
+ jsReadRoot?: string;
300
365
  };
301
366
  /**
302
367
  * Input file options. Can be a single object for defaults, or an array
@@ -312,9 +377,9 @@ export interface StylesConfig {
312
377
  output?: OutputOptions | OutputOptions[];
313
378
  language?: {
314
379
  less?: LessOptions;
315
- scss?: Record<string, any>;
380
+ scss?: ScssOptions;
316
381
  css?: Record<string, any>;
317
382
  jess?: Record<string, any>;
318
- [key: string]: LessOptions | Record<string, any> | undefined;
383
+ [key: string]: LessOptions | ScssOptions | Record<string, any> | undefined;
319
384
  };
320
385
  }