@najemi-software/typed-scss-modules 10.3.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +437 -0
  3. package/dist/lib/cli.d.ts +2 -0
  4. package/dist/lib/cli.js +123 -0
  5. package/dist/lib/core/alerts.d.ts +14 -0
  6. package/dist/lib/core/alerts.js +25 -0
  7. package/dist/lib/core/generate.d.ts +8 -0
  8. package/dist/lib/core/generate.js +18 -0
  9. package/dist/lib/core/index.d.ts +6 -0
  10. package/dist/lib/core/index.js +5 -0
  11. package/dist/lib/core/list-different.d.ts +3 -0
  12. package/dist/lib/core/list-different.js +42 -0
  13. package/dist/lib/core/list-files-and-perform-sanity-checks.d.ts +9 -0
  14. package/dist/lib/core/list-files-and-perform-sanity-checks.js +22 -0
  15. package/dist/lib/core/remove-file.d.ts +7 -0
  16. package/dist/lib/core/remove-file.js +28 -0
  17. package/dist/lib/core/types.d.ts +21 -0
  18. package/dist/lib/core/types.js +1 -0
  19. package/dist/lib/core/watch.d.ts +8 -0
  20. package/dist/lib/core/watch.js +34 -0
  21. package/dist/lib/core/write-file.d.ts +8 -0
  22. package/dist/lib/core/write-file.js +62 -0
  23. package/dist/lib/implementations/compilers.d.ts +14 -0
  24. package/dist/lib/implementations/compilers.js +49 -0
  25. package/dist/lib/implementations/implementations.d.ts +27 -0
  26. package/dist/lib/implementations/implementations.js +54 -0
  27. package/dist/lib/implementations/index.d.ts +2 -0
  28. package/dist/lib/implementations/index.js +2 -0
  29. package/dist/lib/index.d.ts +3 -0
  30. package/dist/lib/index.js +2 -0
  31. package/dist/lib/load.d.ts +20 -0
  32. package/dist/lib/load.js +87 -0
  33. package/dist/lib/main.d.ts +2 -0
  34. package/dist/lib/main.js +34 -0
  35. package/dist/lib/prettier/can-resolve.d.ts +1 -0
  36. package/dist/lib/prettier/can-resolve.js +12 -0
  37. package/dist/lib/prettier/index.d.ts +8 -0
  38. package/dist/lib/prettier/index.js +44 -0
  39. package/dist/lib/sass/file-to-class-names.d.ts +25 -0
  40. package/dist/lib/sass/file-to-class-names.js +55 -0
  41. package/dist/lib/sass/importer.d.ts +29 -0
  42. package/dist/lib/sass/importer.js +37 -0
  43. package/dist/lib/sass/index.d.ts +1 -0
  44. package/dist/lib/sass/index.js +1 -0
  45. package/dist/lib/sass/source-to-class-names.d.ts +6 -0
  46. package/dist/lib/sass/source-to-class-names.js +16 -0
  47. package/dist/lib/typescript/class-names-to-type-definition.d.ts +20 -0
  48. package/dist/lib/typescript/class-names-to-type-definition.js +64 -0
  49. package/dist/lib/typescript/get-type-definition-path.d.ts +8 -0
  50. package/dist/lib/typescript/get-type-definition-path.js +25 -0
  51. package/dist/lib/typescript/index.d.ts +3 -0
  52. package/dist/lib/typescript/index.js +3 -0
  53. package/package.json +120 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Spencer Miskoviak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,437 @@
1
+ # 🎁 typed-scss-modules
2
+
3
+ **note:** This package (`@najemi-software/typed-scss-modules`) is a fork of [@tsjam/typed-scss-modules](https://github.com/am0wa/tsjam-typed-scss-modules) by [am0wa](https://github.com/am0wa), which in turn derived from [typed-css-modules-sass](https://www.npmjs.com/package/typed-scss-modules) which seems no longer maintained. All credit for the original work goes to the upstream authors.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@najemi-software/typed-scss-modules.svg?style=flat)](https://www.npmjs.com/package/@najemi-software/typed-scss-modules)
6
+
7
+ Generate TypeScript definitions (`.d.ts`) files for CSS Modules that are written in SCSS (`.scss`). Check out [this post to learn more](https://skovy.dev/generating-typescript-definitions-for-css-modules-using-sass/) about the rationale and inspiration behind this package.
8
+
9
+ ![Example](/docs/typed-scss-modules-example.gif)
10
+
11
+ For example, given the following SCSS:
12
+
13
+ ```scss
14
+ @use "variables";
15
+
16
+ .text {
17
+ color: variables.$blue;
18
+
19
+ &-highlighted {
20
+ color: variables.$yellow;
21
+ }
22
+ }
23
+ ```
24
+
25
+ The following type definitions will be generated:
26
+
27
+ ```typescript
28
+ export declare const text: string;
29
+ export declare const textHighlighted: string;
30
+ ```
31
+
32
+ ## Basic Usage
33
+
34
+ Install and run as a `devDependency`:
35
+
36
+ ```bash
37
+ yarn add -D @najemi-software/typed-scss-modules
38
+ yarn typed-scss-modules src
39
+ ```
40
+
41
+ Or, install globally:
42
+
43
+ ```bash
44
+ yarn global add @najemi-software/typed-scss-modules
45
+ typed-scss-modules src
46
+ ```
47
+
48
+ Or, with npm:
49
+
50
+ ```bash
51
+ npm install -D @najemi-software/typed-scss-modules
52
+ npx typed-scss-modules src
53
+ ```
54
+
55
+ ## CLI Options
56
+
57
+ For all possible commands, run `typed-scss-modules --help`.
58
+
59
+ The only required argument is the directory where all SCSS files are located. Running `typed-scss-modules src` will search for all files matching `src/**/*.scss`. This can be overridden by providing a [glob](https://github.com/isaacs/node-glob#glob-primer) pattern instead of a directory. For example, `typed-scss-modules src/*.scss`
60
+
61
+ ### `--watch` (`-w`)
62
+
63
+ - **Type**: `boolean`
64
+ - **Default**: `false`
65
+ - **Example**: `typed-scss-modules src --watch`
66
+
67
+ Watch for files that get added or are changed and generate the corresponding type definitions.
68
+
69
+ ### `--ignoreInitial`
70
+
71
+ - **Type**: `boolean`
72
+ - **Default**: `false`
73
+ - **Example**: `typed-scss-modules src --watch --ignoreInitial`
74
+
75
+ Skips the initial build when passing the watch flag. Use this when running concurrently with another watch, but the initial build should happen first. You would run without watch first, then start off the concurrent runs after.
76
+
77
+ ### `--ignore`
78
+
79
+ - **Type**: `string[]`
80
+ - **Default**: `[]`
81
+ - **Example**: `typed-scss-modules src --watch --ignore "**/secret.scss"`
82
+
83
+ A pattern or an array of glob patterns to exclude files that match and avoid generating type definitions.
84
+
85
+ ### `--loadPaths` (`-i`)
86
+
87
+ - **Type**: `string[]`
88
+ - **Default**: `[]`
89
+ - **Example**: `typed-scss-modules src --loadPaths src/core`
90
+
91
+ Paths in which to look for stylesheets loaded by rules like `@use` and `@import`.. This example will search the `src/core` directory when resolving imports.
92
+ [Sass loadPaths ref](https://sass-lang.com/documentation/js-api/interfaces/options/#loadPaths)
93
+
94
+ ### `--implementation`
95
+
96
+ - **Type**: `"sass-embedded" | "sass"`
97
+ - **Default**: If an option is passed, it will always use the provided package implementation. If an option is not passed, it will first check if `sass` is installed. If it is, it will be used. Otherwise, it will then check if `sass-embedded` is installed. If it is, it will be used. Finally, falling back to `sass` if all checks and validations fail.
98
+ - **Example**: `typed-scss-modules src --implementation sass`
99
+
100
+ ### `--async`
101
+
102
+ - **Type**: `boolean`
103
+ - **Default**: If an option is passed, it will always use `compileAsync`. By default, sass synchronous `compile` method is used.
104
+ - **Example**: `typed-scss-modules src --async --implementation sass-embedded`
105
+
106
+ **Heads up!** it's recommended by Sass to use `async` with `sass-embedded` and synchronous compile with `sass` for best performance.
107
+
108
+ [Sass compileAsync spec](https://sass-lang.com/documentation/js-api/functions/compileasync/)
109
+
110
+ ### `--aliases` (`-a`)
111
+
112
+ - **Type**: `object`
113
+ - **Default**: `{}`
114
+ - **Example**: `typed-scss-modules src --aliases.~some-alias src/core/variables`
115
+
116
+ An object of aliases to map to their corresponding paths. This example will replace any `@import '~alias'` with `@import 'src/core/variables'`.
117
+
118
+ ### `--aliasPrefixes` (`-p`)
119
+
120
+ - **Type**: `object`
121
+ - **Default**: `{}`
122
+ - **Example**: `typed-scss-modules src --aliasPrefixes.~ node_modules/`
123
+
124
+ An object of prefix strings to replace with their corresponding paths. This example will replace any `@import '~bootstrap/lib/bootstrap'` with `@import 'node_modules/bootstrap/lib/bootstrap'`.
125
+ This matches the common use-case for importing scss files from node_modules when `sass-loader` will be used with `webpack` to compile the project.
126
+
127
+ ### `--nameFormat` (`-n`)
128
+
129
+ - **Type**: `"all" | "camel" | "kebab" | "param" | "snake" | "dashes" | "none"`
130
+ - **Default**: `"camel"`
131
+ - **Examples**:
132
+ - `typed-scss-modules src --nameFormat camel`
133
+ - `typed-scss-modules src --nameFormat kebab --nameFormat dashes --exportType default`. In order to use multiple formatters, you must use `--exportType default`.
134
+
135
+ The class naming format to use when converting the classes to type definitions.
136
+
137
+ - **all**: makes use of all formatters (except `all` and `none`) and converts all class names to their respective formats, with no duplication. In order to use this option, you must use `--exportType default`.
138
+ - **camel**: convert all class names to camel-case, e.g. `App-Logo` => `appLogo`.
139
+ - **kebab**/**param**: convert all class names to kebab/param case, e.g. `App-Logo` => `app-logo` (all lower case with '-' separators).
140
+ - **dashes**: only convert class names containing dashes to camel-case, leave others alone, e.g. `App` => `App`, `App-Logo` => `appLogo`. Matches the webpack [css-loader camelCase 'dashesOnly'](https://github.com/webpack-contrib/css-loader#camelcase) option.
141
+ - **snake**: convert all class names to lower case with underscores between words.
142
+ - **none**: do not modify the given class names (you should use `--exportType default` when using `--nameFormat none` as any classes with a `-` in them are invalid as normal variable names).
143
+ Note: If you are using create-react-app v2.x and have NOT ejected, `--nameFormat none --exportType default` matches the class names that are generated in CRA's webpack's config.
144
+
145
+ ### `--listDifferent` (`-l`)
146
+
147
+ - **Type**: `boolean`
148
+ - **Default**: `false`
149
+ - **Example**: `typed-scss-modules src --listDifferent`
150
+
151
+ List any type definition files that are different than those that would be generated. If any are different, exit with a status code `1`.
152
+
153
+ ### `--exportType` (`-e`)
154
+
155
+ - **Type**: `"named" | "default"`
156
+ - **Default**: `"named"`
157
+ - **Example**: `typed-scss-modules src --exportType default`
158
+
159
+ The export type to use when generating type definitions.
160
+
161
+ #### `named`
162
+
163
+ Given the following SCSS:
164
+
165
+ ```scss
166
+ .text {
167
+ color: blue;
168
+
169
+ &-highlighted {
170
+ color: yellow;
171
+ }
172
+ }
173
+ ```
174
+
175
+ The following type definitions will be generated:
176
+
177
+ ```typescript
178
+ export declare const text: string;
179
+ export declare const textHighlighted: string;
180
+ ```
181
+
182
+ #### `default`
183
+
184
+ Given the following SCSS:
185
+
186
+ ```scss
187
+ .text {
188
+ color: blue;
189
+
190
+ &-highlighted {
191
+ color: yellow;
192
+ }
193
+ }
194
+ ```
195
+
196
+ The following type definitions will be generated:
197
+
198
+ ```typescript
199
+ export type Styles = {
200
+ text: string;
201
+ textHighlighted: string;
202
+ };
203
+
204
+ export type ClassNames = keyof Styles;
205
+
206
+ declare const styles: Styles;
207
+
208
+ export default styles;
209
+ ```
210
+
211
+ This export type is useful when using kebab (param) cased class names since variables with a `-` are not valid variables and will produce invalid types or when a class name is a TypeScript keyword (eg: `while` or `delete`). Additionally, the `Styles` and `ClassNames` types are exported which can be useful for properly typing variables, functions, etc. when working with dynamic class names.
212
+
213
+ ### `--exportTypeName`
214
+
215
+ - **Type**: `string`
216
+ - **Default**: `"ClassNames"`
217
+ - **Example**: `typed-scss-modules src --exportType default --exportTypeName ClassesType`
218
+
219
+ Customize the type name exported in the generated file when `--exportType` is set to `"default"`.
220
+ Only default exports are affected by this command. This example will change the export type line to:
221
+
222
+ ```typescript
223
+ export type ClassesType = keyof Styles;
224
+ ```
225
+
226
+ ### `--exportTypeInterface`
227
+
228
+ - **Type**: `string`
229
+ - **Default**: `"Styles"`
230
+ - **Example**: `typed-scss-modules src --exportType default --exportTypeInterface IStyles`
231
+
232
+ Customize the interface name exported in the generated file when `--exportType` is set to `"default"`.
233
+ Only default exports are affected by this command. This example will change the export interface line to:
234
+
235
+ ```typescript
236
+ export type IStyles = {
237
+ // ...
238
+ };
239
+ ```
240
+
241
+ ### `--quoteType` (`-q`)
242
+
243
+ - **Type**: `"single" | "double"`
244
+ - **Default**: `"single"`
245
+ - **Example**: `typed-scss-modules src --exportType default --quoteType double`
246
+
247
+ Specify a quote type to match your TypeScript configuration. Only default exports are affected by this command. This example will wrap class names with double quotes ("). If [Prettier](https://prettier.io) is installed and configured in the project, it will be used and is likely to override the effect of this setting.
248
+
249
+ ### `--updateStaleOnly` (`-u`)
250
+
251
+ - **Type**: `boolean`
252
+ - **Default**: `false`
253
+ - **Example**: `typed-scss-modules src --updateStaleOnly`
254
+
255
+ Overwrite generated files only if the source file has more recent changes. This can be useful if you want to avoid extraneous file updates, which can cause watcher processes to trigger unnecessarily (e.g. `tsc --watch`). This is done by first checking if the generated file was modified more recently than the source file, and secondly by comparing the existing file contents to the generated file contents.
256
+
257
+ Caveat: If a generated type definition file is updated manually, it won't be re-generated until the corresponding scss file is also updated.
258
+
259
+ ### `--logLevel` (`-L`)
260
+
261
+ - **Type**: `"verbose" | "error" | "info" | "silent"`
262
+ - **Default**: `"verbose"`
263
+ - **Example**: `typed-scss-modules src --logLevel error`
264
+
265
+ Sets verbosity level of console output.
266
+
267
+ #### `verbose`
268
+
269
+ Print all messages
270
+
271
+ #### `error`
272
+
273
+ Print only errors
274
+
275
+ #### `info`
276
+
277
+ Print only some messages
278
+
279
+ #### `silent`
280
+
281
+ Print nothing
282
+
283
+ ### `--banner`
284
+
285
+ - **Type**: `string`
286
+ - **Default**: `undefined`
287
+ - **Example**: `typed-scss-modules src --banner '// This is an example banner\n'`
288
+
289
+ Will prepend a string to the top of your output files
290
+
291
+ ```typescript
292
+ // This is an example banner
293
+ export type Styles = {
294
+ // ...
295
+ };
296
+ ```
297
+
298
+ ### `--outputFolder` (`-o`)
299
+
300
+ - **Type**: `string`
301
+ - **Default**: _none_
302
+ - **Example**: `typed-scss-modules src --outputFolder __generated__`
303
+
304
+ Set a relative folder to output the generated type definitions. Instead of writing the type definitions directly next to each SCSS module (sibling file), it will write to the output folder with the same path.
305
+
306
+ It will use the relative path to the SCSS module from where this tool is executed. This same path (including any directories) will be constructed in the output folder. This is important for this to work properly with TypeScript.
307
+
308
+ **Important**: for this to work as expected the `tsconfig.json` needs to have [`rootDirs`](https://www.typescriptlang.org/tsconfig#rootDirs) added with the same output folder. This will allow TypeScript to pick up these type definitions and map them to the actual SCSS modules.
309
+
310
+ ```json
311
+ {
312
+ "compilerOptions": {
313
+ "rootDirs": [".", "__generated__"]
314
+ }
315
+ }
316
+ ```
317
+
318
+ ### `--style` (`-s`)
319
+
320
+ - **Type**: `expanded` | `compressed`
321
+ - **Default**: _expanded_
322
+ - **Example**: `typed-scss-modules src --style 'compressed'`
323
+
324
+ The [OutputStyle](https://sass-lang.com/documentation/js-api/types/outputstyle/) of the compiled CSS.
325
+
326
+ ## Config options
327
+
328
+ All options above are also supported as a configuration file in the root of the project. The following configuration file names are supported:
329
+
330
+ - `typed-scss-modules.config.ts`
331
+ - `typed-scss-modules.config.js`
332
+
333
+ The file can provide either a named `config` export or a default export.
334
+
335
+ ```js
336
+ // Example of a named export with some of the options sets.
337
+ export const config = {
338
+ banner: "// customer banner",
339
+ exportType: "default",
340
+ exportTypeName: "TheClasses",
341
+ logLevel: "error",
342
+ };
343
+
344
+ // Example of a default export with some of the options sets.
345
+ export default {
346
+ banner: "// customer banner",
347
+ exportType: "default",
348
+ exportTypeName: "TheClasses",
349
+ logLevel: "error",
350
+ silenceDeprecations: ["import"],
351
+ };
352
+ ```
353
+
354
+ > Note: the configuration options are the same as the CLI options without the leading dashes (`--`). Only the full option name is supported (not aliases) in the configuration file.
355
+
356
+ CLI options will take precedence over configuration file options.
357
+
358
+ In addition to all CLI options, the following are options only available with the configuration file:
359
+
360
+ ### `importer`
361
+
362
+ - **Type**: `Importer | Importer[]`
363
+ - **Default**: _none_
364
+
365
+ Define a [single custom SASS importer or an array of SASS importers](https://github.com/sass/sass/blob/f355f602fc15f55b0a0a795ebe6eb819963e08a5/js-api-doc/legacy/importer.d.ts#L51-L149). This should only be necessary if custom SASS importers are already being used in the build process. This is used internally to implement `aliases` and `aliasPrefixes`.
366
+
367
+ Refer to [`lib/sass/importer.ts`](/blob/master/lib/sass/importer.ts) for more details and `sass` importer type definitions.
368
+
369
+ ### `silenceDeprecations`
370
+
371
+ A set of active deprecations to ignore.
372
+ If a deprecation warning of any provided type is encountered during compilation, the compiler will ignore it instead
373
+
374
+ [Sass deprecations](https://sass-lang.com/documentation/js-api/interfaces/deprecations/)
375
+
376
+ ### `--allowArbitraryExtensions`
377
+
378
+ - **Type**: `boolean`
379
+ - **Default**: `false`
380
+ - **Example**: `typed-scss-modules src --allowArbitraryExtensions`
381
+
382
+ Output filenames that will be compatible with the "arbitrary file extensions" feature that was introduced in TypeScript 5.0. See [the docs](https://www.typescriptlang.org/tsconfig#allowArbitraryExtensions) for more info.
383
+
384
+ In essence, the `*.scss.d.ts` extension now becomes `*.d.scss.ts` so that you can import SCSS modules in projects using ESM module resolution.
385
+
386
+ ## Examples
387
+
388
+ For examples of how this tool can be used and configured, see the `examples` directory:
389
+
390
+ - [Basic example](/examples/basic)
391
+ - [Default export example](/examples/default-export)
392
+ - [Config file (with custom importer) example](/examples/config-file)
393
+
394
+ ## Contributors ✨
395
+
396
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
397
+
398
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
399
+ <!-- prettier-ignore-start -->
400
+ <!-- markdownlint-disable -->
401
+ <table>
402
+ <tbody>
403
+ <tr>
404
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/dawnmist"><img src="https://avatars3.githubusercontent.com/u/5810277?v=4?s=100" width="100px;" alt="Janeene Beeforth"/><br /><sub><b>Janeene Beeforth</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/issues?q=author%3Adawnmist" title="Bug reports">🐛</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=dawnmist" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=dawnmist" title="Documentation">📖</a></td>
405
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/ericbf"><img src="https://avatars0.githubusercontent.com/u/2483476?v=4?s=100" width="100px;" alt="Eric Ferreira"/><br /><sub><b>Eric Ferreira</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=ericbf" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=ericbf" title="Documentation">📖</a></td>
406
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/lkarmelo"><img src="https://avatars2.githubusercontent.com/u/20393808?v=4?s=100" width="100px;" alt="Luis Lopes"/><br /><sub><b>Luis Lopes</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=lkarmelo" title="Code">💻</a></td>
407
+ <td align="center" valign="top" width="14.28%"><a href="https://nostalg.io"><img src="https://avatars0.githubusercontent.com/u/5139752?v=4?s=100" width="100px;" alt="Josh Wedekind"/><br /><sub><b>Josh Wedekind</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=halfnibble" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=halfnibble" title="Documentation">📖</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=halfnibble" title="Tests">⚠️</a></td>
408
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/peanutbother"><img src="https://avatars3.githubusercontent.com/u/6437182?v=4?s=100" width="100px;" alt="Jared Gesser"/><br /><sub><b>Jared Gesser</b></sub></a><br /><a href="#ideas-peanutbother" title="Ideas, Planning, & Feedback">🤔</a></td>
409
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/raphael-leger"><img src="https://avatars1.githubusercontent.com/u/12732777?v=4?s=100" width="100px;" alt="Raphaël L"/><br /><sub><b>Raphaël L</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=raphael-leger" title="Code">💻</a> <a href="#ideas-raphael-leger" title="Ideas, Planning, & Feedback">🤔</a></td>
410
+ <td align="center" valign="top" width="14.28%"><a href="https://NickTheSick.com"><img src="https://avatars1.githubusercontent.com/u/1852538?v=4?s=100" width="100px;" alt="Nick Perez"/><br /><sub><b>Nick Perez</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/issues?q=author%3Anperez0111" title="Bug reports">🐛</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=nperez0111" title="Code">💻</a></td>
411
+ </tr>
412
+ <tr>
413
+ <td align="center" valign="top" width="14.28%"><a href="https://alander.org"><img src="https://avatars3.githubusercontent.com/u/1771462?v=4?s=100" width="100px;" alt="Even Alander"/><br /><sub><b>Even Alander</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=deificx" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=deificx" title="Tests">⚠️</a> <a href="#ideas-deificx" title="Ideas, Planning, & Feedback">🤔</a></td>
414
+ <td align="center" valign="top" width="14.28%"><a href="http://inkblotty.github.io"><img src="https://avatars3.githubusercontent.com/u/14206003?v=4?s=100" width="100px;" alt="Katie Foster"/><br /><sub><b>Katie Foster</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=inkblotty" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=inkblotty" title="Tests">⚠️</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=inkblotty" title="Documentation">📖</a></td>
415
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/ccortezaguilera"><img src="https://avatars3.githubusercontent.com/u/10718803?v=4?s=100" width="100px;" alt="Carlos Aguilera"/><br /><sub><b>Carlos Aguilera</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=ccortezaguilera" title="Code">💻</a></td>
416
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/craigrmccown"><img src="https://avatars1.githubusercontent.com/u/2373979?v=4?s=100" width="100px;" alt="Craig McCown"/><br /><sub><b>Craig McCown</b></sub></a><br /><a href="#ideas-craigrmccown" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=craigrmccown" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=craigrmccown" title="Tests">⚠️</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=craigrmccown" title="Documentation">📖</a></td>
417
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/capsuleman"><img src="https://avatars.githubusercontent.com/u/34281913?v=4?s=100" width="100px;" alt="Guillaume Vagner"/><br /><sub><b>Guillaume Vagner</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=capsuleman" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=capsuleman" title="Tests">⚠️</a> <a href="https://github.com/skovy/typed-scss-modules/issues?q=author%3Acapsuleman" title="Bug reports">🐛</a></td>
418
+ <td align="center" valign="top" width="14.28%"><a href="https://dev.to/srmagura"><img src="https://avatars.githubusercontent.com/u/801549?v=4?s=100" width="100px;" alt="Sam Magura"/><br /><sub><b>Sam Magura</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/commits?author=srmagura" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=srmagura" title="Tests">⚠️</a></td>
419
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/MichaelGregory"><img src="https://avatars.githubusercontent.com/u/1435960?v=4?s=100" width="100px;" alt="Mike Gregory"/><br /><sub><b>Mike Gregory</b></sub></a><br /><a href="https://github.com/skovy/typed-scss-modules/issues?q=author%3AMichaelGregory" title="Bug reports">🐛</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=MichaelGregory" title="Code">💻</a> <a href="https://github.com/skovy/typed-scss-modules/commits?author=MichaelGregory" title="Tests">⚠️</a></td>
420
+ </tr>
421
+ </tbody>
422
+ </table>
423
+
424
+ <!-- markdownlint-restore -->
425
+ <!-- prettier-ignore-end -->
426
+
427
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
428
+
429
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
430
+
431
+ ## Alternatives
432
+
433
+ This package derived from [typed-css-modules-sass](https://www.npmjs.com/package/typed-scss-modules) which seems no longer maintained.
434
+
435
+ This package was heavily influenced on [typed-css-modules](https://github.com/Quramy/typed-css-modules) which generates TypeScript definitions (`.d.ts`) files for CSS Modules that are written in CSS (`.css`).
436
+
437
+ This package is currently used as a CLI. There are also [packages that generate types as a webpack loader](https://github.com/Jimdo/typings-for-css-modules-loader).
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env node
2
+ import yargs from "yargs";
3
+ import { hideBin } from "yargs/helpers";
4
+ import { IMPLEMENTATIONS } from "./implementations/index.js";
5
+ import { main } from "./main.js";
6
+ import { NAME_FORMATS } from "./sass/index.js";
7
+ import { EXPORT_TYPES, LOG_LEVELS, QUOTE_TYPES } from "./typescript/index.js";
8
+ /*
9
+ hideBin is a shorthand for process.argv.slice(2).
10
+ It has the benefit that it takes into account variations in some environments
11
+ */
12
+ const { _: patterns, ...rest } = yargs(hideBin(process.argv))
13
+ .usage("Generate .scss.d.ts from CSS module .scss files.\nUsage: $0 <glob pattern> [options]")
14
+ .example("$0 src", "All .scss files at any level in the src directory")
15
+ .example("$0 src/**/*.scss", "All .scss files at any level in the src directory")
16
+ .example("$0 src/**/*.scss --watch", "Watch all .scss files at any level in the src directory that are added or changed")
17
+ .example("$0 src/**/*.scss --includePaths src/core src/variables", 'Search the "core" and "variables" directory when resolving imports')
18
+ .example("$0 src/**/*.scss --aliases.~name variables", 'Replace all imports for "~name" with "variables"')
19
+ .example("$0 src/**/*.scss --aliasPrefixes.~ ./node_modules/", 'Replace the "~" prefix with "./node_modules/" for all imports beginning with "~"')
20
+ .example("$0 src/**/*.scss --ignore **/secret.scss", 'Ignore any file names "secret.scss"')
21
+ .example("$0 src/**/*.scss --implementation sass", "Use the Dart SASS package")
22
+ .example("$0 src/**/*.scss -e default --quoteType double", "Use double quotes around class name definitions rather than single quotes.")
23
+ .example("$0 src/**/*.scss --logLevel error", "Output only errors")
24
+ .demandCommand(1)
25
+ .option("style", {
26
+ choices: ["compressed", "expanded"],
27
+ alias: "s",
28
+ describe: "Whether output is compressed or expanded.",
29
+ })
30
+ .option("aliases", {
31
+ coerce: (obj) => obj,
32
+ alias: "a",
33
+ describe: "Alias any import to any other value.",
34
+ })
35
+ .option("aliasPrefixes", {
36
+ coerce: (obj) => obj,
37
+ alias: "p",
38
+ describe: "A prefix for any import to rewrite to another value.",
39
+ })
40
+ .option("nameFormat", {
41
+ alias: "n",
42
+ array: true,
43
+ string: true,
44
+ choices: NAME_FORMATS,
45
+ describe: "The name format that should be used to transform class names.",
46
+ })
47
+ .option("implementation", {
48
+ choices: IMPLEMENTATIONS,
49
+ describe: "The SASS package to used to compile. This will default to the sass implementation you have installed.",
50
+ })
51
+ .option("async", {
52
+ boolean: true,
53
+ describe: "The SASS package compile method to use (compile | compileAsync). By default the synchronous 'compile' method is used.",
54
+ })
55
+ .option("exportType", {
56
+ choices: EXPORT_TYPES,
57
+ alias: "e",
58
+ describe: "The type of export used for defining the type definitions.",
59
+ })
60
+ .option("exportTypeName", {
61
+ string: true,
62
+ describe: 'Set a custom type name for styles when --exportType is "default."',
63
+ })
64
+ .option("exportTypeInterface", {
65
+ string: true,
66
+ describe: 'Set a custom interface name for styles when --exportType is "default."',
67
+ })
68
+ .option("watch", {
69
+ boolean: true,
70
+ alias: "w",
71
+ describe: "Watch for added or changed files and (re-)generate the type definitions.",
72
+ })
73
+ .option("ignoreInitial", {
74
+ boolean: true,
75
+ describe: "Skips the initial build when passing the watch flag.",
76
+ })
77
+ .option("listDifferent", {
78
+ boolean: true,
79
+ alias: "l",
80
+ describe: "List any type definitions that are different than those that would be generated.",
81
+ })
82
+ .option("loadPaths", {
83
+ array: true,
84
+ string: true,
85
+ alias: "i",
86
+ describe: "Include paths to check when trying to resolve imports.",
87
+ })
88
+ .option("ignore", {
89
+ string: true,
90
+ array: true,
91
+ describe: "Add a pattern or an array of glob patterns to exclude matches.",
92
+ })
93
+ .option("outputFolder", {
94
+ string: true,
95
+ alias: "o",
96
+ describe: "Define a (relative) folder to output the generated type definitions. Note this requires adding the output folder to tsconfig.json `rootDirs`.",
97
+ })
98
+ .options("quoteType", {
99
+ choices: QUOTE_TYPES,
100
+ alias: "q",
101
+ describe: "Specify the quote type so that generated files adhere to your TypeScript rules.",
102
+ })
103
+ .options("updateStaleOnly", {
104
+ boolean: true,
105
+ alias: "u",
106
+ describe: "Overwrite generated files only if the source file has more recent changes.",
107
+ })
108
+ .option("logLevel", {
109
+ choices: LOG_LEVELS,
110
+ alias: "L",
111
+ describe: "Verbosity level of console output",
112
+ })
113
+ .options("banner", {
114
+ string: true,
115
+ describe: "Inserts text at the top of every output file for documentation purposes.",
116
+ })
117
+ .options("allowArbitraryExtensions", {
118
+ boolean: true,
119
+ describe: 'Output filenames that will be compatible with the "arbitrary file extensions" feature that was introduced in TypeScript 5.0.',
120
+ })
121
+ .parseSync();
122
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
123
+ main(patterns[0], { ...rest });
@@ -0,0 +1,14 @@
1
+ export declare const LOG_LEVELS: readonly ["verbose", "error", "info", "silent"];
2
+ export type LogLevel = (typeof LOG_LEVELS)[number];
3
+ export declare const logLevelDefault: LogLevel;
4
+ export declare const setAlertsLogLevel: (logLevel: LogLevel) => void;
5
+ type CbFunc = (...args: any[]) => void;
6
+ type WrappedCbFunc<T extends CbFunc> = (...args: Parameters<T>) => ReturnType<T> | void;
7
+ export declare const alerts: {
8
+ error: WrappedCbFunc<(message: string) => void>;
9
+ warn: WrappedCbFunc<(message: string) => void>;
10
+ notice: WrappedCbFunc<(message: string) => void>;
11
+ info: WrappedCbFunc<(message: string) => void>;
12
+ success: WrappedCbFunc<(message: string) => void>;
13
+ };
14
+ export {};
@@ -0,0 +1,25 @@
1
+ import chalk from "chalk";
2
+ export const LOG_LEVELS = ["verbose", "error", "info", "silent"];
3
+ export const logLevelDefault = "verbose";
4
+ let currentLogLevel;
5
+ export const setAlertsLogLevel = (logLevel) => {
6
+ currentLogLevel = logLevel;
7
+ };
8
+ /**
9
+ * wraps a callback and only calls it if currentLogLevel is undefined or included in permittedLogLevels
10
+ * @param permittedLogLevels list of log levels. callbacks will only be called if current log level is listed here
11
+ * @param cb callback
12
+ */
13
+ const withLogLevelsRestriction = (permittedLogLevels, cb) => (...args) => {
14
+ const shouldCall = !currentLogLevel || permittedLogLevels.includes(currentLogLevel);
15
+ if (shouldCall) {
16
+ return cb(...args);
17
+ }
18
+ };
19
+ const error = withLogLevelsRestriction(["verbose", "error", "info"], (message) => log(chalk.red(message)));
20
+ const warn = withLogLevelsRestriction(["verbose"], (message) => log(chalk.yellowBright(message)));
21
+ const notice = withLogLevelsRestriction(["verbose", "info"], (message) => log(chalk.gray(message)));
22
+ const info = withLogLevelsRestriction(["verbose", "info"], (message) => log(chalk.blueBright(message)));
23
+ const success = withLogLevelsRestriction(["verbose", "info"], (message) => log(chalk.green(message)));
24
+ const log = (message) => console.log(message);
25
+ export const alerts = { error, warn, notice, info, success };
@@ -0,0 +1,8 @@
1
+ import type { ConfigOptions } from "./types.js";
2
+ /**
3
+ * Given a file glob generate the corresponding types once.
4
+ *
5
+ * @param pattern the file pattern to generate type definitions for
6
+ * @param options the CLI options
7
+ */
8
+ export declare const generate: (pattern: string, options: ConfigOptions) => Promise<void>;
@@ -0,0 +1,18 @@
1
+ import { alerts } from "./alerts.js";
2
+ import { listFilesAndPerformSanityChecks } from "./list-files-and-perform-sanity-checks.js";
3
+ import { writeFile } from "./write-file.js";
4
+ /**
5
+ * Given a file glob generate the corresponding types once.
6
+ *
7
+ * @param pattern the file pattern to generate type definitions for
8
+ * @param options the CLI options
9
+ */
10
+ export const generate = async (pattern, options) => {
11
+ const files = listFilesAndPerformSanityChecks(pattern, options);
12
+ if (files.length === 0) {
13
+ return;
14
+ }
15
+ alerts.success(`Found ${files.length} file${files.length === 1 ? `` : `s`}. Generating type definitions...`);
16
+ // Wait for all the type definitions to be written.
17
+ await Promise.all(files.map((file) => writeFile(file, options)));
18
+ };