@jesscss/plugin-less 2.0.0-alpha.6 → 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 CHANGED
@@ -27,12 +27,27 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
27
  let _jesscss_core = require("@jesscss/core");
28
28
  let _jesscss_fns = require("@jesscss/fns");
29
29
  _jesscss_fns = __toESM(_jesscss_fns);
30
- let _jesscss_less_parser = require("@jesscss/less-parser");
30
+ let _jesscss_less_parser_jess = require("@jesscss/less-parser/jess");
31
31
  let node_path = require("node:path");
32
32
  node_path = __toESM(node_path);
33
33
  let node_module = require("node:module");
34
34
  let _jesscss_style_resolver = require("@jesscss/style-resolver");
35
35
  //#region src/index.ts
36
+ /**
37
+ * The Less plugin's default option values — the single source of truth for the
38
+ * v5 defaults. The `LessPlugin` constructor fills any unset option from here,
39
+ * and the `lessc` CLI imports the same object so its defaults can never drift
40
+ * from the engine's. Note `collapseNesting: false` — v5 preserves nesting by
41
+ * default (Less 4.x flattened; that is now an explicit opt-in).
42
+ */
43
+ const lessPluginDefaults = {
44
+ mathMode: "parens-division",
45
+ unitMode: "preserve",
46
+ equalityMode: "less",
47
+ leakyScope: true,
48
+ bubbleRootAtRules: true,
49
+ collapseNesting: false
50
+ };
36
51
  var LessPlugin = class extends _jesscss_core.AbstractPlugin {
37
52
  name = "less";
38
53
  supportedExtensions = [".less"];
@@ -40,7 +55,7 @@ var LessPlugin = class extends _jesscss_core.AbstractPlugin {
40
55
  mathMode;
41
56
  unitMode;
42
57
  equalityMode;
43
- leakyRules;
58
+ leakyScope;
44
59
  bubbleRootAtRules;
45
60
  collapseNesting;
46
61
  constructor(opts = {}) {
@@ -52,25 +67,43 @@ var LessPlugin = class extends _jesscss_core.AbstractPlugin {
52
67
  else if (opts.math === 1 || opts.math === "parens-division") mathMode = "parens-division";
53
68
  else if (opts.math === 2 || opts.math === "parens" || opts.math === "strict") mathMode = "parens";
54
69
  else mathMode = "parens";
55
- else mathMode = "parens-division";
70
+ else mathMode = lessPluginDefaults.mathMode;
56
71
  this.mathMode = mathMode;
57
72
  let unitMode;
58
73
  if (opts.unitMode !== void 0) unitMode = opts.unitMode;
59
74
  else if (opts.strictUnits === true) unitMode = "strict";
60
- else unitMode = "preserve";
75
+ else unitMode = lessPluginDefaults.unitMode;
61
76
  this.unitMode = unitMode;
62
- this.equalityMode = opts.equalityMode ?? "coerce";
63
- this.leakyRules = opts.leakyRules ?? true;
64
- this.bubbleRootAtRules = opts.bubbleRootAtRules ?? true;
65
- this.collapseNesting = opts.collapseNesting ?? false;
66
- this.parser = new _jesscss_less_parser.Parser();
77
+ this.equalityMode = opts.equalityMode ?? lessPluginDefaults.equalityMode;
78
+ this.leakyScope = opts.leakyScope ?? lessPluginDefaults.leakyScope;
79
+ this.bubbleRootAtRules = opts.bubbleRootAtRules ?? lessPluginDefaults.bubbleRootAtRules;
80
+ this.collapseNesting = opts.collapseNesting ?? lessPluginDefaults.collapseNesting;
81
+ this.parser = new _jesscss_less_parser_jess.Parser();
82
+ }
83
+ createTreeContext(filePath, source) {
84
+ return new _jesscss_core.TreeContext({
85
+ file: {
86
+ name: node_path.default.basename(filePath),
87
+ path: node_path.default.dirname(filePath),
88
+ fullPath: filePath,
89
+ source
90
+ },
91
+ mathMode: this.mathMode,
92
+ unitMode: this.unitMode,
93
+ equalityMode: this.equalityMode,
94
+ plugin: this,
95
+ allowExtendSelectors: this.opts.allowExtendSelectors,
96
+ collapseNesting: this.collapseNesting,
97
+ leakyScope: this.leakyScope,
98
+ bubbleRootAtRules: this.bubbleRootAtRules
99
+ });
67
100
  }
68
101
  _registerFunctions(tree) {
69
102
  const registeredNames = [];
70
103
  for (const [key, value] of Object.entries(_jesscss_fns)) {
71
104
  if (typeof value !== "function") continue;
72
105
  const runtimeName = value.name || key;
73
- tree.register("function", new _jesscss_core.JsFunction({
106
+ tree.setFunctionBinding(runtimeName, new _jesscss_core.JsFunction({
74
107
  name: runtimeName,
75
108
  fn: value
76
109
  }));
@@ -123,29 +156,18 @@ var LessPlugin = class extends _jesscss_core.AbstractPlugin {
123
156
  }
124
157
  return out;
125
158
  }
126
- safeParse(filePath, source, parseOptions) {
127
- const context = new _jesscss_core.TreeContext({
128
- file: {
129
- name: node_path.default.basename(filePath),
130
- path: node_path.default.dirname(filePath),
131
- fullPath: filePath,
132
- source
133
- },
134
- mathMode: this.mathMode,
135
- unitMode: this.unitMode,
136
- equalityMode: this.equalityMode,
137
- plugin: this,
138
- allowExtendSelectors: this.opts.allowExtendSelectors,
139
- collapseNesting: this.collapseNesting,
140
- leakyRules: this.leakyRules,
141
- bubbleRootAtRules: this.bubbleRootAtRules
142
- });
159
+ safeParse(filePath, source, _parseOptions) {
160
+ const context = this.createTreeContext(filePath, source);
143
161
  const errors = [];
144
162
  const warnings = [];
145
163
  let tree;
146
164
  try {
147
- const parseResult = this.parser.parse(source, "stylesheet", { context });
165
+ const parseResult = this.parser.parse(source, "Stylesheet", { context });
148
166
  tree = parseResult.tree;
167
+ const parsedContext = parseResult.context ?? context;
168
+ if (tree) tree._treeContext = parsedContext;
169
+ context.opts.trivia = parseResult.trivia;
170
+ context.opts.liftedCommentRanges = parseResult.liftedCommentRanges;
149
171
  if ("warnings" in parseResult && parseResult.warnings) for (const warning of parseResult.warnings) {
150
172
  const line = warning.token?.startLine ?? 1;
151
173
  const column = warning.token?.startColumn ?? 1;
@@ -162,21 +184,12 @@ var LessPlugin = class extends _jesscss_core.AbstractPlugin {
162
184
  lines: (0, _jesscss_core.extractRelevantLines)(source, line)
163
185
  });
164
186
  }
165
- if (parseResult.errors.length || parseResult.lexerResult?.errors?.length) {
166
- for (const error of parseResult.errors) {
167
- const line = error.token?.startLine ?? 1;
168
- const diagnostic = (0, _jesscss_core.toDiagnostic)((0, _jesscss_core.getErrorFromParser)([error], void 0, filePath, source, { file: context.file }));
169
- if (!diagnostic.lines) diagnostic.lines = (0, _jesscss_core.extractRelevantLines)(source, line);
170
- if ("errors" in diagnostic) errors.push(diagnostic);
171
- else warnings.push(diagnostic);
172
- }
173
- if (parseResult.lexerResult?.errors) for (const lexError of parseResult.lexerResult.errors) {
174
- const line = typeof lexError.line === "number" ? lexError.line : 1;
175
- const diagnostic = (0, _jesscss_core.toDiagnostic)((0, _jesscss_core.getErrorFromParser)([], [lexError], filePath, source, { file: context.file }));
176
- if (!diagnostic.lines) diagnostic.lines = (0, _jesscss_core.extractRelevantLines)(source, line);
177
- if ("errors" in diagnostic) errors.push(diagnostic);
178
- else warnings.push(diagnostic);
179
- }
187
+ if (parseResult.errors.length) for (const error of parseResult.errors) {
188
+ const line = error.token?.startLine ?? 1;
189
+ const diagnostic = (0, _jesscss_core.toDiagnostic)((0, _jesscss_core.getErrorFromParser)([error], void 0, filePath, source, { file: context.file }));
190
+ if (!diagnostic.lines) diagnostic.lines = (0, _jesscss_core.extractRelevantLines)(source, line);
191
+ if ("errors" in diagnostic) errors.push(diagnostic);
192
+ else warnings.push(diagnostic);
180
193
  }
181
194
  } catch (error) {
182
195
  if (error instanceof _jesscss_core.JessError) {
@@ -217,3 +230,4 @@ const lessPlugin = ((opts) => {
217
230
  //#endregion
218
231
  exports.LessPlugin = LessPlugin;
219
232
  exports.default = lessPlugin;
233
+ exports.lessPluginDefaults = lessPluginDefaults;
package/lib/index.d.ts CHANGED
@@ -1,27 +1,40 @@
1
- import { AbstractPlugin, ISafeParseResult } from "@jesscss/core";
2
- import { Parser } from "@jesscss/less-parser";
3
- import { EqualityMode, LessOptions, LessOptions as LessOptions$1, MathMode, UnitMode } from "styles-config";
4
-
5
- //#region src/index.d.ts
6
- declare class LessPlugin extends AbstractPlugin {
7
- opts: LessOptions$1;
8
- name: string;
9
- supportedExtensions: string[];
10
- parser: Parser;
11
- mathMode: MathMode;
12
- unitMode: UnitMode;
13
- equalityMode: EqualityMode;
14
- leakyRules: boolean;
15
- bubbleRootAtRules: boolean;
16
- collapseNesting: boolean;
17
- constructor(opts?: LessOptions$1);
18
- private _registerFunctions;
19
- expandImport(importPath: string, currentDir: string): string[];
20
- resolve(filePath: string | string[], currentDir: string, searchPaths: string[]): string[];
21
- safeParse(filePath: string, source: string, parseOptions?: {
22
- compilerOptions?: Record<string, any>;
23
- }): ISafeParseResult;
1
+ import { AbstractPlugin, type ISafeParseResult, type SafeParseOptions } from '@jesscss/core';
2
+ import type { EqualityMode, MathMode, UnitMode, LessOptions } from 'styles-config';
3
+ import { Parser } from '@jesscss/less-parser/jess';
4
+ export type LessPluginOptions = LessOptions;
5
+ /**
6
+ * The Less plugin's default option values — the single source of truth for the
7
+ * v5 defaults. The `LessPlugin` constructor fills any unset option from here,
8
+ * and the `lessc` CLI imports the same object so its defaults can never drift
9
+ * from the engine's. Note `collapseNesting: false` — v5 preserves nesting by
10
+ * default (Less 4.x flattened; that is now an explicit opt-in).
11
+ */
12
+ export declare const lessPluginDefaults: {
13
+ readonly mathMode: MathMode;
14
+ readonly unitMode: UnitMode;
15
+ readonly equalityMode: EqualityMode;
16
+ readonly leakyScope: true;
17
+ readonly bubbleRootAtRules: true;
18
+ readonly collapseNesting: false;
19
+ };
20
+ export declare class LessPlugin extends AbstractPlugin {
21
+ opts: LessPluginOptions;
22
+ name: string;
23
+ supportedExtensions: string[];
24
+ parser: Parser;
25
+ mathMode: MathMode;
26
+ unitMode: UnitMode;
27
+ equalityMode: EqualityMode;
28
+ leakyScope: boolean;
29
+ bubbleRootAtRules: boolean;
30
+ collapseNesting: boolean;
31
+ constructor(opts?: LessPluginOptions);
32
+ private createTreeContext;
33
+ private _registerFunctions;
34
+ expandImport(importPath: string, currentDir: string): string[];
35
+ resolve(filePath: string | string[], currentDir: string, searchPaths: string[]): string[];
36
+ safeParse(filePath: string, source: string, _parseOptions?: SafeParseOptions): ISafeParseResult;
24
37
  }
25
- declare const lessPlugin: (opts?: LessOptions$1) => LessPlugin;
26
- //#endregion
27
- export { type LessOptions, LessPlugin, lessPlugin as default };
38
+ export type { LessOptions } from 'styles-config';
39
+ declare const lessPlugin: (opts?: LessPluginOptions) => LessPlugin;
40
+ export default lessPlugin;
package/lib/index.js CHANGED
@@ -1,10 +1,25 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { AbstractPlugin, JessError, JsFunction, TreeContext, extractRelevantLines, getErrorFromParser, toDiagnostic } from "@jesscss/core";
3
3
  import * as lessFunctions from "@jesscss/fns";
4
- import { Parser } from "@jesscss/less-parser";
4
+ import { Parser } from "@jesscss/less-parser/jess";
5
5
  import path from "node:path";
6
6
  import { expandLessImportCandidates } from "@jesscss/style-resolver";
7
7
  //#region src/index.ts
8
+ /**
9
+ * The Less plugin's default option values — the single source of truth for the
10
+ * v5 defaults. The `LessPlugin` constructor fills any unset option from here,
11
+ * and the `lessc` CLI imports the same object so its defaults can never drift
12
+ * from the engine's. Note `collapseNesting: false` — v5 preserves nesting by
13
+ * default (Less 4.x flattened; that is now an explicit opt-in).
14
+ */
15
+ const lessPluginDefaults = {
16
+ mathMode: "parens-division",
17
+ unitMode: "preserve",
18
+ equalityMode: "less",
19
+ leakyScope: true,
20
+ bubbleRootAtRules: true,
21
+ collapseNesting: false
22
+ };
8
23
  var LessPlugin = class extends AbstractPlugin {
9
24
  name = "less";
10
25
  supportedExtensions = [".less"];
@@ -12,7 +27,7 @@ var LessPlugin = class extends AbstractPlugin {
12
27
  mathMode;
13
28
  unitMode;
14
29
  equalityMode;
15
- leakyRules;
30
+ leakyScope;
16
31
  bubbleRootAtRules;
17
32
  collapseNesting;
18
33
  constructor(opts = {}) {
@@ -24,25 +39,43 @@ var LessPlugin = class extends AbstractPlugin {
24
39
  else if (opts.math === 1 || opts.math === "parens-division") mathMode = "parens-division";
25
40
  else if (opts.math === 2 || opts.math === "parens" || opts.math === "strict") mathMode = "parens";
26
41
  else mathMode = "parens";
27
- else mathMode = "parens-division";
42
+ else mathMode = lessPluginDefaults.mathMode;
28
43
  this.mathMode = mathMode;
29
44
  let unitMode;
30
45
  if (opts.unitMode !== void 0) unitMode = opts.unitMode;
31
46
  else if (opts.strictUnits === true) unitMode = "strict";
32
- else unitMode = "preserve";
47
+ else unitMode = lessPluginDefaults.unitMode;
33
48
  this.unitMode = unitMode;
34
- this.equalityMode = opts.equalityMode ?? "coerce";
35
- this.leakyRules = opts.leakyRules ?? true;
36
- this.bubbleRootAtRules = opts.bubbleRootAtRules ?? true;
37
- this.collapseNesting = opts.collapseNesting ?? false;
49
+ this.equalityMode = opts.equalityMode ?? lessPluginDefaults.equalityMode;
50
+ this.leakyScope = opts.leakyScope ?? lessPluginDefaults.leakyScope;
51
+ this.bubbleRootAtRules = opts.bubbleRootAtRules ?? lessPluginDefaults.bubbleRootAtRules;
52
+ this.collapseNesting = opts.collapseNesting ?? lessPluginDefaults.collapseNesting;
38
53
  this.parser = new Parser();
39
54
  }
55
+ createTreeContext(filePath, source) {
56
+ return new TreeContext({
57
+ file: {
58
+ name: path.basename(filePath),
59
+ path: path.dirname(filePath),
60
+ fullPath: filePath,
61
+ source
62
+ },
63
+ mathMode: this.mathMode,
64
+ unitMode: this.unitMode,
65
+ equalityMode: this.equalityMode,
66
+ plugin: this,
67
+ allowExtendSelectors: this.opts.allowExtendSelectors,
68
+ collapseNesting: this.collapseNesting,
69
+ leakyScope: this.leakyScope,
70
+ bubbleRootAtRules: this.bubbleRootAtRules
71
+ });
72
+ }
40
73
  _registerFunctions(tree) {
41
74
  const registeredNames = [];
42
75
  for (const [key, value] of Object.entries(lessFunctions)) {
43
76
  if (typeof value !== "function") continue;
44
77
  const runtimeName = value.name || key;
45
- tree.register("function", new JsFunction({
78
+ tree.setFunctionBinding(runtimeName, new JsFunction({
46
79
  name: runtimeName,
47
80
  fn: value
48
81
  }));
@@ -95,29 +128,18 @@ var LessPlugin = class extends AbstractPlugin {
95
128
  }
96
129
  return out;
97
130
  }
98
- safeParse(filePath, source, parseOptions) {
99
- const context = new TreeContext({
100
- file: {
101
- name: path.basename(filePath),
102
- path: path.dirname(filePath),
103
- fullPath: filePath,
104
- source
105
- },
106
- mathMode: this.mathMode,
107
- unitMode: this.unitMode,
108
- equalityMode: this.equalityMode,
109
- plugin: this,
110
- allowExtendSelectors: this.opts.allowExtendSelectors,
111
- collapseNesting: this.collapseNesting,
112
- leakyRules: this.leakyRules,
113
- bubbleRootAtRules: this.bubbleRootAtRules
114
- });
131
+ safeParse(filePath, source, _parseOptions) {
132
+ const context = this.createTreeContext(filePath, source);
115
133
  const errors = [];
116
134
  const warnings = [];
117
135
  let tree;
118
136
  try {
119
- const parseResult = this.parser.parse(source, "stylesheet", { context });
137
+ const parseResult = this.parser.parse(source, "Stylesheet", { context });
120
138
  tree = parseResult.tree;
139
+ const parsedContext = parseResult.context ?? context;
140
+ if (tree) tree._treeContext = parsedContext;
141
+ context.opts.trivia = parseResult.trivia;
142
+ context.opts.liftedCommentRanges = parseResult.liftedCommentRanges;
121
143
  if ("warnings" in parseResult && parseResult.warnings) for (const warning of parseResult.warnings) {
122
144
  const line = warning.token?.startLine ?? 1;
123
145
  const column = warning.token?.startColumn ?? 1;
@@ -134,21 +156,12 @@ var LessPlugin = class extends AbstractPlugin {
134
156
  lines: extractRelevantLines(source, line)
135
157
  });
136
158
  }
137
- if (parseResult.errors.length || parseResult.lexerResult?.errors?.length) {
138
- for (const error of parseResult.errors) {
139
- const line = error.token?.startLine ?? 1;
140
- const diagnostic = toDiagnostic(getErrorFromParser([error], void 0, filePath, source, { file: context.file }));
141
- if (!diagnostic.lines) diagnostic.lines = extractRelevantLines(source, line);
142
- if ("errors" in diagnostic) errors.push(diagnostic);
143
- else warnings.push(diagnostic);
144
- }
145
- if (parseResult.lexerResult?.errors) for (const lexError of parseResult.lexerResult.errors) {
146
- const line = typeof lexError.line === "number" ? lexError.line : 1;
147
- const diagnostic = toDiagnostic(getErrorFromParser([], [lexError], filePath, source, { file: context.file }));
148
- if (!diagnostic.lines) diagnostic.lines = extractRelevantLines(source, line);
149
- if ("errors" in diagnostic) errors.push(diagnostic);
150
- else warnings.push(diagnostic);
151
- }
159
+ if (parseResult.errors.length) for (const error of parseResult.errors) {
160
+ const line = error.token?.startLine ?? 1;
161
+ const diagnostic = toDiagnostic(getErrorFromParser([error], void 0, filePath, source, { file: context.file }));
162
+ if (!diagnostic.lines) diagnostic.lines = extractRelevantLines(source, line);
163
+ if ("errors" in diagnostic) errors.push(diagnostic);
164
+ else warnings.push(diagnostic);
152
165
  }
153
166
  } catch (error) {
154
167
  if (error instanceof JessError) {
@@ -187,4 +200,4 @@ const lessPlugin = ((opts) => {
187
200
  return new LessPlugin(opts);
188
201
  });
189
202
  //#endregion
190
- export { LessPlugin, lessPlugin as default };
203
+ export { LessPlugin, lessPlugin as default, lessPluginDefaults };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @deprecated Import LessOptions from 'styles-config' instead.
3
+ * This type is kept for backward compatibility but will be removed in a future version.
4
+ */
5
+ export type { LessOptions } from 'styles-config';
package/package.json CHANGED
@@ -5,13 +5,12 @@
5
5
  "access": "public"
6
6
  },
7
7
  "description": "A Less stylesheet engine for Jess",
8
- "version": "2.0.0-alpha.6",
8
+ "version": "2.0.0-alpha.7",
9
9
  "main": "lib/index.cjs",
10
10
  "types": "lib/index.d.ts",
11
11
  "exports": {
12
12
  ".": {
13
13
  "types": "./lib/index.d.ts",
14
- "source": "./src/index.ts",
15
14
  "import": "./lib/index.js",
16
15
  "require": "./lib/index.cjs"
17
16
  },
@@ -21,11 +20,11 @@
21
20
  "lib"
22
21
  ],
23
22
  "dependencies": {
24
- "@jesscss/core": "2.0.0-alpha.6",
25
- "@jesscss/fns": "2.0.0-alpha.6",
26
- "@jesscss/less-parser": "2.0.0-alpha.6",
27
- "@jesscss/style-resolver": "2.0.0-alpha.6",
28
- "styles-config": "2.0.0-alpha.6"
23
+ "@jesscss/core": "2.0.0-alpha.7",
24
+ "@jesscss/fns": "2.0.0-alpha.7",
25
+ "@jesscss/less-parser": "2.0.0-alpha.7",
26
+ "@jesscss/style-resolver": "2.0.0-alpha.7",
27
+ "styles-config": "2.0.0-alpha.7"
29
28
  },
30
29
  "devDependencies": {},
31
30
  "author": "Matthew Dean <matthew-dean@users.noreply.github.com>",
@@ -38,7 +37,7 @@
38
37
  "scripts": {
39
38
  "ci": "pnpm build && pnpm test",
40
39
  "build": "pnpm compile",
41
- "compile": "tsdown --tsconfig tsconfig.build.json",
40
+ "compile": "tsdown --tsconfig tsconfig.build.json --no-dts && tsc -p tsconfig.build.json --emitDeclarationOnly --noCheck",
42
41
  "test": "vitest --run --passWithNoTests",
43
42
  "lint:fix": "eslint --fix '**/*.{js,ts}'",
44
43
  "lint": "eslint '**/*.{js,ts}'"
package/lib/index.d.cts DELETED
@@ -1,27 +0,0 @@
1
- import { AbstractPlugin, ISafeParseResult } from "@jesscss/core";
2
- import { EqualityMode, LessOptions, LessOptions as LessOptions$1, MathMode, UnitMode } from "styles-config";
3
- import { Parser } from "@jesscss/less-parser";
4
-
5
- //#region src/index.d.ts
6
- declare class LessPlugin extends AbstractPlugin {
7
- opts: LessOptions$1;
8
- name: string;
9
- supportedExtensions: string[];
10
- parser: Parser;
11
- mathMode: MathMode;
12
- unitMode: UnitMode;
13
- equalityMode: EqualityMode;
14
- leakyRules: boolean;
15
- bubbleRootAtRules: boolean;
16
- collapseNesting: boolean;
17
- constructor(opts?: LessOptions$1);
18
- private _registerFunctions;
19
- expandImport(importPath: string, currentDir: string): string[];
20
- resolve(filePath: string | string[], currentDir: string, searchPaths: string[]): string[];
21
- safeParse(filePath: string, source: string, parseOptions?: {
22
- compilerOptions?: Record<string, any>;
23
- }): ISafeParseResult;
24
- }
25
- declare const lessPlugin: (opts?: LessOptions$1) => LessPlugin;
26
- //#endregion
27
- export { type LessOptions, LessPlugin, lessPlugin as default };