@gesslar/sassy 0.20.2 → 0.21.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/package.json +12 -8
- package/src/BuildCommand.js +8 -9
- package/src/Cache.js +1 -0
- package/src/Colour.js +8 -2
- package/src/Command.js +92 -32
- package/src/Compiler.js +62 -36
- package/src/Data.js +24 -14
- package/src/Evaluator.js +8 -4
- package/src/File.js +14 -2
- package/src/LintCommand.js +381 -103
- package/src/ResolveCommand.js +44 -27
- package/src/Sass.js +2 -1
- package/src/Session.js +200 -36
- package/src/Term.js +7 -7
- package/src/Theme.js +378 -53
- package/src/ThemePool.js +1 -1
- package/src/ThemeToken.js +1 -0
- package/src/Type.js +11 -10
- package/src/Util.js +2 -2
- package/src/Valid.js +1 -1
- package/src/cli.js +27 -15
package/src/Theme.js
CHANGED
|
@@ -22,6 +22,20 @@ import Term from "./Term.js"
|
|
|
22
22
|
import ThemePool from "./ThemePool.js"
|
|
23
23
|
import Util from "./Util.js"
|
|
24
24
|
|
|
25
|
+
const outputFileExtension = "color-theme.json"
|
|
26
|
+
const obviouslyASentinelYouCantMissSoShutUpAboutIt = "kakadoodoo"
|
|
27
|
+
|
|
28
|
+
// Symbol enums for magic values
|
|
29
|
+
const WriteStatus = {
|
|
30
|
+
DRY_RUN: Symbol("dry-run"),
|
|
31
|
+
SKIPPED: Symbol("skipped"),
|
|
32
|
+
WRITTEN: Symbol("written")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const PropertyKey = {
|
|
36
|
+
CONFIG: Symbol("config")
|
|
37
|
+
}
|
|
38
|
+
|
|
25
39
|
/**
|
|
26
40
|
* Theme class: manages the lifecycle of a theme compilation unit.
|
|
27
41
|
* See file-level docstring for responsibilities.
|
|
@@ -30,7 +44,13 @@ export default class Theme {
|
|
|
30
44
|
#sourceFile = null
|
|
31
45
|
#source = null
|
|
32
46
|
#options = null
|
|
33
|
-
|
|
47
|
+
/**
|
|
48
|
+
* The dependencies of this theme.
|
|
49
|
+
*
|
|
50
|
+
* @type {Set<Dependency>}
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
#dependencies = new Set()
|
|
34
54
|
#lookup = null
|
|
35
55
|
#pool = null
|
|
36
56
|
#cache = null
|
|
@@ -54,7 +74,7 @@ export default class Theme {
|
|
|
54
74
|
constructor(themeFile, cwd, options) {
|
|
55
75
|
this.#sourceFile = themeFile
|
|
56
76
|
this.#name = themeFile.module
|
|
57
|
-
this.#outputFileName = `${this.#name}
|
|
77
|
+
this.#outputFileName = `${this.#name}.${outputFileExtension}`
|
|
58
78
|
this.#options = options
|
|
59
79
|
this.#cwd = cwd
|
|
60
80
|
}
|
|
@@ -71,75 +91,223 @@ export default class Theme {
|
|
|
71
91
|
this.#pool = null
|
|
72
92
|
}
|
|
73
93
|
|
|
74
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Gets the current working directory.
|
|
96
|
+
*
|
|
97
|
+
* @returns {DirectoryObject} The current working directory
|
|
98
|
+
*/
|
|
99
|
+
getCwd() {
|
|
75
100
|
return this.#cwd
|
|
76
101
|
}
|
|
77
102
|
|
|
78
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Gets the compilation options.
|
|
105
|
+
*
|
|
106
|
+
* @returns {object} The compilation options object
|
|
107
|
+
*/
|
|
108
|
+
getOptions() {
|
|
79
109
|
return this.#options
|
|
80
110
|
}
|
|
81
111
|
|
|
82
|
-
|
|
83
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Gets a specific compilation option.
|
|
114
|
+
*
|
|
115
|
+
* @param {string} option - The option name to retrieve
|
|
116
|
+
* @returns {*} The option value or undefined if not set
|
|
117
|
+
*/
|
|
118
|
+
getOption(option) {
|
|
119
|
+
return this.#options?.[option] ?? undefined
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Sets the cache instance for theme compilation.
|
|
124
|
+
*
|
|
125
|
+
* @param {Cache} cache - The cache instance to use for file operations
|
|
126
|
+
* @returns {this} Returns this instance for method chaining
|
|
127
|
+
*/
|
|
128
|
+
setCache(cache) {
|
|
129
|
+
if(!this.#cache)
|
|
84
130
|
this.#cache=cache
|
|
131
|
+
|
|
132
|
+
return this
|
|
85
133
|
}
|
|
86
134
|
|
|
87
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Gets the cache instance.
|
|
137
|
+
*
|
|
138
|
+
* @returns {Cache|null} The cache instance or null if not set
|
|
139
|
+
*/
|
|
140
|
+
getCache() {
|
|
88
141
|
return this.#cache
|
|
89
142
|
}
|
|
90
143
|
|
|
91
|
-
|
|
144
|
+
/**
|
|
145
|
+
* Gets the theme name.
|
|
146
|
+
*
|
|
147
|
+
* @returns {string} The theme name derived from the source file
|
|
148
|
+
*/
|
|
149
|
+
getName() {
|
|
92
150
|
return this.#name
|
|
93
151
|
}
|
|
94
152
|
|
|
153
|
+
/**
|
|
154
|
+
* Gets the output file name for the compiled theme.
|
|
155
|
+
*
|
|
156
|
+
* @returns {string} The output file name with extension
|
|
157
|
+
*/
|
|
158
|
+
getOutputFileName() {
|
|
159
|
+
return this.#outputFileName
|
|
160
|
+
}
|
|
161
|
+
|
|
95
162
|
/**
|
|
96
163
|
* Gets the source file object.
|
|
97
164
|
*
|
|
98
165
|
* @returns {FileObject} The source theme file
|
|
99
166
|
*/
|
|
100
|
-
|
|
167
|
+
getSourceFile() {
|
|
101
168
|
return this.#sourceFile
|
|
102
169
|
}
|
|
103
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Sets the compiled theme output object and updates derived JSON and hash.
|
|
173
|
+
*
|
|
174
|
+
* @param {object} data - The compiled theme output object
|
|
175
|
+
* @returns {this} Returns this instance for method chaining
|
|
176
|
+
*/
|
|
177
|
+
setOutput(data) {
|
|
178
|
+
this.#output = data
|
|
179
|
+
this.#outputJson = JSON.stringify(data, null, 2) + "\n"
|
|
180
|
+
this.#outputHash = Util.hashOf(this.#outputJson)
|
|
181
|
+
|
|
182
|
+
return this
|
|
183
|
+
}
|
|
184
|
+
|
|
104
185
|
/**
|
|
105
186
|
* Gets the compiled theme output object.
|
|
106
187
|
*
|
|
107
188
|
* @returns {object|null} The compiled theme output
|
|
108
189
|
*/
|
|
109
|
-
|
|
190
|
+
getOutput() {
|
|
110
191
|
return this.#output
|
|
111
192
|
}
|
|
112
193
|
|
|
113
194
|
/**
|
|
114
|
-
*
|
|
195
|
+
* Checks if the source has colors defined.
|
|
115
196
|
*
|
|
116
|
-
* @
|
|
197
|
+
* @returns {boolean} True if source has theme colors
|
|
117
198
|
*/
|
|
118
|
-
|
|
119
|
-
this.#
|
|
120
|
-
|
|
121
|
-
|
|
199
|
+
sourceHasColors() {
|
|
200
|
+
return !!this.#source?.theme?.colors
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Checks if the source has token colors defined.
|
|
205
|
+
*
|
|
206
|
+
* @returns {boolean} True if source has theme token colors
|
|
207
|
+
*/
|
|
208
|
+
sourceHasTokenColors() {
|
|
209
|
+
return !!this.#source?.theme?.tokenColors
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Checks if the source has semantic token colors defined.
|
|
214
|
+
*
|
|
215
|
+
* @returns {boolean} True if source has theme semantic token colors
|
|
216
|
+
*/
|
|
217
|
+
sourceHasSemanticTokenColors() {
|
|
218
|
+
return !!this.#source?.theme?.semanticTokenColors
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Checks if the source has theme configuration.
|
|
223
|
+
*
|
|
224
|
+
* @returns {boolean} True if source has theme data
|
|
225
|
+
*/
|
|
226
|
+
sourceHasTheme() {
|
|
227
|
+
return !!this.#source?.theme
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Checks if the source has variables.
|
|
232
|
+
*
|
|
233
|
+
* @returns {boolean} True if source has vars section
|
|
234
|
+
*/
|
|
235
|
+
sourceHasVars() {
|
|
236
|
+
return !!this.#source?.vars
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Checks if the source has config section.
|
|
241
|
+
*
|
|
242
|
+
* @returns {boolean} True if source has config
|
|
243
|
+
*/
|
|
244
|
+
sourceHasConfig() {
|
|
245
|
+
return !!this.#source?.config
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Gets the source colors data.
|
|
250
|
+
*
|
|
251
|
+
* @returns {object|null} The colors object or null if not defined
|
|
252
|
+
*/
|
|
253
|
+
getSourceColors() {
|
|
254
|
+
if(!this.sourceHasColors())
|
|
255
|
+
return null
|
|
256
|
+
|
|
257
|
+
return this.#source.theme.colors
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Gets the source token colors data.
|
|
262
|
+
*
|
|
263
|
+
* @returns {Array|null} The token colors array or null if not defined
|
|
264
|
+
*/
|
|
265
|
+
getSourceTokenColors() {
|
|
266
|
+
if(!this.sourceHasTokenColors())
|
|
267
|
+
return null
|
|
268
|
+
|
|
269
|
+
return this.#source.theme.tokenColors
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Gets the source semantic token colors data.
|
|
274
|
+
*
|
|
275
|
+
* @returns {object|null} The semantic token colors object or null if not defined
|
|
276
|
+
*/
|
|
277
|
+
getSourceSemanticTokenColors() {
|
|
278
|
+
if(!this.sourceHasSemanticTokenColors())
|
|
279
|
+
return null
|
|
280
|
+
|
|
281
|
+
return this.#source.theme.semanticTokenColors
|
|
122
282
|
}
|
|
123
283
|
|
|
124
284
|
/**
|
|
125
285
|
* Gets the array of file dependencies.
|
|
126
286
|
*
|
|
127
|
-
* @returns {
|
|
287
|
+
* @returns {Set<Dependency>} Array of dependency files
|
|
128
288
|
*/
|
|
129
|
-
|
|
289
|
+
getDependencies() {
|
|
130
290
|
return this.#dependencies
|
|
131
291
|
}
|
|
132
292
|
|
|
133
293
|
/**
|
|
134
|
-
*
|
|
294
|
+
* Adds a dependency to the theme with its source data.
|
|
135
295
|
*
|
|
136
|
-
* @param {FileObject
|
|
296
|
+
* @param {FileObject} file - The dependency file object
|
|
297
|
+
* @param {object} source - The parsed source data from the file
|
|
298
|
+
* @returns {this} Returns this instance for method chaining
|
|
137
299
|
*/
|
|
138
|
-
|
|
139
|
-
this.#dependencies
|
|
300
|
+
addDependency(file, source) {
|
|
301
|
+
this.#dependencies.add(
|
|
302
|
+
new Dependency()
|
|
303
|
+
.setSourceFile(file)
|
|
304
|
+
.setSource(source))
|
|
305
|
+
|
|
306
|
+
return this
|
|
307
|
+
}
|
|
140
308
|
|
|
141
|
-
|
|
142
|
-
|
|
309
|
+
hasDependencies() {
|
|
310
|
+
return this.#dependencies.size > 0
|
|
143
311
|
}
|
|
144
312
|
|
|
145
313
|
/**
|
|
@@ -147,7 +315,7 @@ export default class Theme {
|
|
|
147
315
|
*
|
|
148
316
|
* @returns {object|null} The parsed source data
|
|
149
317
|
*/
|
|
150
|
-
|
|
318
|
+
getSource() {
|
|
151
319
|
return this.#source
|
|
152
320
|
}
|
|
153
321
|
|
|
@@ -156,7 +324,7 @@ export default class Theme {
|
|
|
156
324
|
*
|
|
157
325
|
* @returns {object|null} The lookup data object
|
|
158
326
|
*/
|
|
159
|
-
|
|
327
|
+
getLookup() {
|
|
160
328
|
return this.#lookup
|
|
161
329
|
}
|
|
162
330
|
|
|
@@ -164,9 +332,12 @@ export default class Theme {
|
|
|
164
332
|
* Sets the variable lookup data for theme compilation.
|
|
165
333
|
*
|
|
166
334
|
* @param {object} data - The lookup data object
|
|
335
|
+
* @returns {this} Returns this instance for method chaining
|
|
167
336
|
*/
|
|
168
|
-
|
|
337
|
+
setLookup(data) {
|
|
169
338
|
this.#lookup = data
|
|
339
|
+
|
|
340
|
+
return this
|
|
170
341
|
}
|
|
171
342
|
|
|
172
343
|
/**
|
|
@@ -175,7 +346,7 @@ export default class Theme {
|
|
|
175
346
|
*
|
|
176
347
|
* @returns {ThemePool|null} The pool for this theme.
|
|
177
348
|
*/
|
|
178
|
-
|
|
349
|
+
getPool() {
|
|
179
350
|
return this.#pool
|
|
180
351
|
}
|
|
181
352
|
|
|
@@ -186,13 +357,14 @@ export default class Theme {
|
|
|
186
357
|
* @see reset
|
|
187
358
|
*
|
|
188
359
|
* @param {ThemePool} pool - The pool to assign to this theme
|
|
189
|
-
* @throws If there is already a pool.
|
|
360
|
+
* @throws {Error} If there is already a pool.
|
|
361
|
+
* @returns {this} Returns this instance for method chaining
|
|
190
362
|
*/
|
|
191
|
-
|
|
192
|
-
if(this.#pool)
|
|
193
|
-
|
|
363
|
+
setPool(pool) {
|
|
364
|
+
if(!this.#pool)
|
|
365
|
+
this.#pool = pool
|
|
194
366
|
|
|
195
|
-
this
|
|
367
|
+
return this
|
|
196
368
|
}
|
|
197
369
|
|
|
198
370
|
/**
|
|
@@ -204,36 +376,115 @@ export default class Theme {
|
|
|
204
376
|
return this.#pool instanceof ThemePool
|
|
205
377
|
}
|
|
206
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Checks if the theme has compiled output.
|
|
381
|
+
*
|
|
382
|
+
* @returns {boolean} True if theme has been compiled
|
|
383
|
+
*/
|
|
384
|
+
hasOutput() {
|
|
385
|
+
return this.#output !== null
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Checks if the theme has loaded source data.
|
|
390
|
+
*
|
|
391
|
+
* @returns {boolean} True if source data is available
|
|
392
|
+
*/
|
|
393
|
+
hasSource() {
|
|
394
|
+
return this.#source !== null
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Checks if the theme has a cache instance.
|
|
399
|
+
*
|
|
400
|
+
* @returns {boolean} True if cache is available
|
|
401
|
+
*/
|
|
402
|
+
hasCache() {
|
|
403
|
+
return this.#cache !== null
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Checks if the theme has lookup data.
|
|
408
|
+
*
|
|
409
|
+
* @returns {boolean} True if lookup data exists
|
|
410
|
+
*/
|
|
411
|
+
hasLookup() {
|
|
412
|
+
return this.#lookup !== null
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Checks if the theme is ready to be compiled.
|
|
417
|
+
* Requires source data and cache to be available.
|
|
418
|
+
*
|
|
419
|
+
* @returns {boolean} True if theme can be compiled
|
|
420
|
+
*/
|
|
421
|
+
isReady() {
|
|
422
|
+
return this.hasSource() && this.hasCache()
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Checks if the theme has been fully compiled.
|
|
427
|
+
* Requires output, pool, and lookup data to be present.
|
|
428
|
+
*
|
|
429
|
+
* @returns {boolean} True if theme is fully compiled
|
|
430
|
+
*/
|
|
431
|
+
isCompiled() {
|
|
432
|
+
return this.hasOutput() && this.hasPool() && this.hasLookup()
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Checks if the theme can be built/compiled.
|
|
437
|
+
* Same as isReady() but with more semantic naming.
|
|
438
|
+
*
|
|
439
|
+
* @returns {boolean} True if build can proceed
|
|
440
|
+
*/
|
|
441
|
+
canBuild() {
|
|
442
|
+
return this.isReady()
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Checks if the theme can be written to output.
|
|
447
|
+
* Requires the theme to be compiled.
|
|
448
|
+
*
|
|
449
|
+
* @returns {boolean} True if write can proceed
|
|
450
|
+
*/
|
|
451
|
+
canWrite() {
|
|
452
|
+
return this.hasOutput()
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Checks if the theme is in a valid state for operation.
|
|
457
|
+
* Basic validation that core properties are set.
|
|
458
|
+
*
|
|
459
|
+
* @returns {boolean} True if theme state is valid
|
|
460
|
+
*/
|
|
461
|
+
isValid() {
|
|
462
|
+
return this.#sourceFile !== null && this.#name !== null
|
|
463
|
+
}
|
|
464
|
+
|
|
207
465
|
/**
|
|
208
466
|
* Loads and parses the theme source file.
|
|
209
467
|
* Validates that the source contains required configuration.
|
|
468
|
+
* Skips loading if no cache is available (extension use case).
|
|
210
469
|
*
|
|
211
470
|
* @returns {Promise<this>} Returns this instance for method chaining
|
|
212
471
|
* @throws {Sass} If source file lacks required 'config' property
|
|
213
472
|
*/
|
|
214
473
|
async load() {
|
|
474
|
+
// Skip loading if no cache (extension use case)
|
|
475
|
+
if(!this.#cache)
|
|
476
|
+
return this
|
|
477
|
+
|
|
215
478
|
const source = await this.#cache.loadCachedData(this.#sourceFile)
|
|
216
479
|
|
|
217
|
-
if(!source.
|
|
480
|
+
if(!source[PropertyKey.CONFIG.description])
|
|
218
481
|
throw Sass.new(
|
|
219
|
-
`Source file does not contain '
|
|
482
|
+
`Source file does not contain '${PropertyKey.CONFIG.description}' property: ${this.#sourceFile.path}`
|
|
220
483
|
)
|
|
221
484
|
|
|
222
485
|
this.#source = source
|
|
223
|
-
}
|
|
224
486
|
|
|
225
|
-
|
|
226
|
-
* Adds a file dependency to the theme.
|
|
227
|
-
*
|
|
228
|
-
* @param {FileObject} file - The file to add as a dependency
|
|
229
|
-
* @returns {this} Returns this instance for method chaining
|
|
230
|
-
* @throws {Sass} If the file parameter is not a valid file
|
|
231
|
-
*/
|
|
232
|
-
addDependency(file) {
|
|
233
|
-
if(!file.isFile)
|
|
234
|
-
throw Sass.new("File must be a dependency.")
|
|
235
|
-
|
|
236
|
-
this.#dependencies.push(file)
|
|
487
|
+
this.addDependency(this.#sourceFile, this.#source)
|
|
237
488
|
|
|
238
489
|
return this
|
|
239
490
|
}
|
|
@@ -242,11 +493,14 @@ export default class Theme {
|
|
|
242
493
|
* Builds the theme by compiling source data into final output.
|
|
243
494
|
* Main entry point for theme compilation process.
|
|
244
495
|
*
|
|
245
|
-
* @returns {Promise<
|
|
496
|
+
* @returns {Promise<this>} Returns this instance for method chaining
|
|
246
497
|
*/
|
|
247
498
|
async build() {
|
|
248
499
|
const compiler = new Compiler()
|
|
500
|
+
|
|
249
501
|
await compiler.compile(this)
|
|
502
|
+
|
|
503
|
+
return this
|
|
250
504
|
}
|
|
251
505
|
|
|
252
506
|
/**
|
|
@@ -264,7 +518,7 @@ export default class Theme {
|
|
|
264
518
|
if(this.#options.dryRun) {
|
|
265
519
|
Term.log(this.#outputJson)
|
|
266
520
|
|
|
267
|
-
return {status:
|
|
521
|
+
return {status: WriteStatus.DRY_RUN, file}
|
|
268
522
|
}
|
|
269
523
|
|
|
270
524
|
// Skip identical bytes
|
|
@@ -272,10 +526,10 @@ export default class Theme {
|
|
|
272
526
|
const nextHash = this.#outputHash
|
|
273
527
|
const lastHash = await file.exists
|
|
274
528
|
? Util.hashOf(await File.readFile(file))
|
|
275
|
-
:
|
|
529
|
+
: obviouslyASentinelYouCantMissSoShutUpAboutIt
|
|
276
530
|
|
|
277
531
|
if(lastHash === nextHash)
|
|
278
|
-
return {status:
|
|
532
|
+
return {status: WriteStatus.SKIPPED, file}
|
|
279
533
|
}
|
|
280
534
|
|
|
281
535
|
// Real write (timed)
|
|
@@ -284,6 +538,77 @@ export default class Theme {
|
|
|
284
538
|
|
|
285
539
|
await File.writeFile(file, output)
|
|
286
540
|
|
|
287
|
-
return {status:
|
|
541
|
+
return {status: WriteStatus.WRITTEN, bytes: output.length, file}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
export class Dependency {
|
|
546
|
+
#sourceFile = null
|
|
547
|
+
#source = null
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Sets the file object for this dependency.
|
|
551
|
+
*
|
|
552
|
+
* @param {FileObject} file - The file object of this dependency.
|
|
553
|
+
* @returns {this} This.
|
|
554
|
+
*/
|
|
555
|
+
setSourceFile(file) {
|
|
556
|
+
if(!this.#sourceFile)
|
|
557
|
+
this.#sourceFile = file
|
|
558
|
+
|
|
559
|
+
return this
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Get the file object for this depenency.
|
|
564
|
+
*
|
|
565
|
+
* @returns {FileObject} The file object of this dependency.
|
|
566
|
+
*/
|
|
567
|
+
getSourceFile() {
|
|
568
|
+
return this.#sourceFile
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Sets the source object for this dependency.
|
|
573
|
+
*
|
|
574
|
+
* @param {object} source - The parsed JSON from the file after loading.
|
|
575
|
+
* @returns {this} This.
|
|
576
|
+
*/
|
|
577
|
+
setSource(source) {
|
|
578
|
+
if(!this.#source)
|
|
579
|
+
this.#source = source
|
|
580
|
+
|
|
581
|
+
return this
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
getSource() {
|
|
585
|
+
return this.#source
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Checks if the dependency has a source file.
|
|
590
|
+
*
|
|
591
|
+
* @returns {boolean} True if source file is set
|
|
592
|
+
*/
|
|
593
|
+
hasSourceFile() {
|
|
594
|
+
return this.#sourceFile !== null
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Checks if the dependency has parsed source data.
|
|
599
|
+
*
|
|
600
|
+
* @returns {boolean} True if source data is available
|
|
601
|
+
*/
|
|
602
|
+
hasSource() {
|
|
603
|
+
return this.#source !== null
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Checks if the dependency is fully initialized.
|
|
608
|
+
*
|
|
609
|
+
* @returns {boolean} True if both file and source are set
|
|
610
|
+
*/
|
|
611
|
+
isComplete() {
|
|
612
|
+
return this.hasSourceFile() && this.hasSource()
|
|
288
613
|
}
|
|
289
614
|
}
|
package/src/ThemePool.js
CHANGED
package/src/ThemeToken.js
CHANGED
package/src/Type.js
CHANGED
|
@@ -60,7 +60,7 @@ export default class TypeSpec {
|
|
|
60
60
|
/**
|
|
61
61
|
* Executes a provided function once for each type specification.
|
|
62
62
|
*
|
|
63
|
-
* @param {
|
|
63
|
+
* @param {function(unknown): void} callback - Function to execute for each spec
|
|
64
64
|
*/
|
|
65
65
|
forEach(callback) {
|
|
66
66
|
this.#specs.forEach(callback)
|
|
@@ -69,7 +69,7 @@ export default class TypeSpec {
|
|
|
69
69
|
/**
|
|
70
70
|
* Tests whether all type specifications pass the provided test function.
|
|
71
71
|
*
|
|
72
|
-
* @param {
|
|
72
|
+
* @param {function(unknown): boolean} callback - Function to test each spec
|
|
73
73
|
* @returns {boolean} True if all specs pass the test
|
|
74
74
|
*/
|
|
75
75
|
every(callback) {
|
|
@@ -79,7 +79,7 @@ export default class TypeSpec {
|
|
|
79
79
|
/**
|
|
80
80
|
* Tests whether at least one type specification passes the provided test function.
|
|
81
81
|
*
|
|
82
|
-
* @param {
|
|
82
|
+
* @param {function(unknown): boolean} callback - Function to test each spec
|
|
83
83
|
* @returns {boolean} True if at least one spec passes the test
|
|
84
84
|
*/
|
|
85
85
|
some(callback) {
|
|
@@ -89,7 +89,7 @@ export default class TypeSpec {
|
|
|
89
89
|
/**
|
|
90
90
|
* Creates a new array with all type specifications that pass the provided test function.
|
|
91
91
|
*
|
|
92
|
-
* @param {
|
|
92
|
+
* @param {function(unknown): boolean} callback - Function to test each spec
|
|
93
93
|
* @returns {Array} New array with filtered specs
|
|
94
94
|
*/
|
|
95
95
|
filter(callback) {
|
|
@@ -99,7 +99,7 @@ export default class TypeSpec {
|
|
|
99
99
|
/**
|
|
100
100
|
* Creates a new array populated with the results of calling the provided function on every spec.
|
|
101
101
|
*
|
|
102
|
-
* @param {
|
|
102
|
+
* @param {function(unknown): unknown} callback - Function to call on each spec
|
|
103
103
|
* @returns {Array} New array with mapped values
|
|
104
104
|
*/
|
|
105
105
|
map(callback) {
|
|
@@ -109,9 +109,9 @@ export default class TypeSpec {
|
|
|
109
109
|
/**
|
|
110
110
|
* Executes a reducer function on each spec, resulting in a single output value.
|
|
111
111
|
*
|
|
112
|
-
* @param {
|
|
113
|
-
* @param {
|
|
114
|
-
* @returns {
|
|
112
|
+
* @param {function(unknown, unknown): unknown} callback - Function to execute on each spec
|
|
113
|
+
* @param {unknown} initialValue - Initial value for the accumulator
|
|
114
|
+
* @returns {unknown} The final accumulated value
|
|
115
115
|
*/
|
|
116
116
|
reduce(callback, initialValue) {
|
|
117
117
|
return this.#specs.reduce(callback, initialValue)
|
|
@@ -120,7 +120,7 @@ export default class TypeSpec {
|
|
|
120
120
|
/**
|
|
121
121
|
* Returns the first type specification that satisfies the provided testing function.
|
|
122
122
|
*
|
|
123
|
-
* @param {
|
|
123
|
+
* @param {function(unknown): boolean} callback - Function to test each spec
|
|
124
124
|
* @returns {object|undefined} The first spec that matches, or undefined
|
|
125
125
|
*/
|
|
126
126
|
find(callback) {
|
|
@@ -131,7 +131,7 @@ export default class TypeSpec {
|
|
|
131
131
|
* Tests whether a value matches any of the type specifications.
|
|
132
132
|
* Handles array types, union types, and empty value validation.
|
|
133
133
|
*
|
|
134
|
-
* @param {
|
|
134
|
+
* @param {unknown} value - The value to test against the type specifications
|
|
135
135
|
* @param {object} options - Validation options
|
|
136
136
|
* @param {boolean} options.allowEmpty - Whether empty values are allowed
|
|
137
137
|
* @returns {boolean} True if the value matches any type specification
|
|
@@ -191,6 +191,7 @@ export default class TypeSpec {
|
|
|
191
191
|
|
|
192
192
|
this.#specs = parts.map(part => {
|
|
193
193
|
const typeMatches = /(\w+)(\[\])?/.exec(part)
|
|
194
|
+
|
|
194
195
|
if(!typeMatches || typeMatches.length !== 3)
|
|
195
196
|
throw Sass.new(`Invalid type: ${part}`)
|
|
196
197
|
|
package/src/Util.js
CHANGED
|
@@ -102,7 +102,7 @@ export default class Util {
|
|
|
102
102
|
* Wrapper around Promise.all for consistency with other utility methods.
|
|
103
103
|
*
|
|
104
104
|
* @param {Promise[]} promises - Array of promises to await
|
|
105
|
-
* @returns {Promise<
|
|
105
|
+
* @returns {Promise<unknown[]>} Results of all promises
|
|
106
106
|
*/
|
|
107
107
|
static async awaitAll(promises) {
|
|
108
108
|
return await Promise.all(promises)
|
|
@@ -124,7 +124,7 @@ export default class Util {
|
|
|
124
124
|
* Wrapper around Promise.race for consistency with other utility methods.
|
|
125
125
|
*
|
|
126
126
|
* @param {Promise[]} promises - Array of promises to race
|
|
127
|
-
* @returns {Promise<
|
|
127
|
+
* @returns {Promise<unknown>} Result of the first settled promise
|
|
128
128
|
*/
|
|
129
129
|
static async race(promises) {
|
|
130
130
|
return await Promise.race(promises)
|