@css-modules-kit/ts-plugin 0.1.1 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,MAAM,iDA4CV,CAAC;AAEH,SAAS,MAAM,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,QAAA,MAAM,MAAM,iDA6CV,CAAC;AAEH,SAAS,MAAM,CAAC"}
package/dist/index.js CHANGED
@@ -34,9 +34,9 @@ const plugin = (0, createLanguageServicePlugin_js_1.createLanguageServicePlugin)
34
34
  const resolver = (0, core_1.createResolver)(config.compilerOptions, moduleResolutionCache);
35
35
  const matchesPattern = (0, core_1.createMatchesPattern)(config);
36
36
  return {
37
- languagePlugins: [(0, language_plugin_js_1.createCSSLanguagePlugin)(resolver, matchesPattern)],
37
+ languagePlugins: [(0, language_plugin_js_1.createCSSLanguagePlugin)(resolver, matchesPattern, config)],
38
38
  setup: (language) => {
39
- info.languageService = (0, proxy_js_1.proxyLanguageService)(language, info.languageService, info.project, resolver, matchesPattern);
39
+ info.languageService = (0, proxy_js_1.proxyLanguageService)(language, info.languageService, info.project, resolver, matchesPattern, config);
40
40
  },
41
41
  };
42
42
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,gDAA6F;AAC7F,gDAAkE;AAClE,oHAA8G;AAC9G,6DAA+D;AAC/D,0DAAmE;AAEnE,MAAM,MAAM,GAAG,IAAA,4DAA2B,EAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE;IACtD,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QACxG,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,MAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,IAAA,qBAAc,EAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QACvD,2BAA2B;QAC3B,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CACrC,4DAA4D,MAAM,CAAC,cAAc,GAAG,CACrF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uDAAuD;QACvD,IAAI,KAAK,YAAY,gCAAyB,EAAE,CAAC;YAC/C,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,GAAG,8DAA8D,CAAC;YACzE,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,GAAG,IAAI,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC9B,GAAG,IAAI,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7C,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,qBAAqB,GAAG,IAAI,CAAC,mBAAmB,CAAC,wBAAwB,EAAE,EAAE,CAAC;IACpF,MAAM,QAAQ,GAAG,IAAA,qBAAc,EAAC,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC,CAAC;IAC/E,MAAM,cAAc,GAAG,IAAA,2BAAoB,EAAC,MAAM,CAAC,CAAC;IAEpD,OAAO;QACL,eAAe,EAAE,CAAC,IAAA,4CAAuB,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACpE,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE;YAClB,IAAI,CAAC,eAAe,GAAG,IAAA,+BAAoB,EACzC,QAAQ,EACR,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,EACZ,QAAQ,EACR,cAAc,CACf,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,iBAAS,MAAM,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,gDAA6F;AAC7F,gDAAkE;AAClE,oHAA8G;AAC9G,6DAA+D;AAC/D,0DAAmE;AAEnE,MAAM,MAAM,GAAG,IAAA,4DAA2B,EAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE;IACtD,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAClE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QACxG,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,MAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,IAAA,qBAAc,EAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QACvD,2BAA2B;QAC3B,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CACrC,4DAA4D,MAAM,CAAC,cAAc,GAAG,CACrF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uDAAuD;QACvD,IAAI,KAAK,YAAY,gCAAyB,EAAE,CAAC;YAC/C,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,GAAG,8DAA8D,CAAC;YACzE,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,GAAG,IAAI,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC9B,GAAG,IAAI,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7C,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,qBAAqB,GAAG,IAAI,CAAC,mBAAmB,CAAC,wBAAwB,EAAE,EAAE,CAAC;IACpF,MAAM,QAAQ,GAAG,IAAA,qBAAc,EAAC,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC,CAAC;IAC/E,MAAM,cAAc,GAAG,IAAA,2BAAoB,EAAC,MAAM,CAAC,CAAC;IAEpD,OAAO;QACL,eAAe,EAAE,CAAC,IAAA,4CAAuB,EAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;QAC5E,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE;YAClB,IAAI,CAAC,eAAe,GAAG,IAAA,+BAAoB,EACzC,QAAQ,EACR,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,OAAO,EACZ,QAAQ,EACR,cAAc,EACd,MAAM,CACP,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,iBAAS,MAAM,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { CSSModule, DiagnosticWithLocation, MatchesPattern, Resolver } from '@css-modules-kit/core';
1
+ import type { CMKConfig, CSSModule, DiagnosticWithLocation, MatchesPattern, Resolver } from '@css-modules-kit/core';
2
2
  import type { LanguagePlugin, SourceScript, VirtualCode } from '@volar/language-core';
3
3
  export declare const LANGUAGE_ID = "css";
4
4
  export declare const CMK_DATA_KEY: unique symbol;
@@ -13,7 +13,7 @@ export interface CSSModuleScript extends SourceScript<string> {
13
13
  root: CSSModuleVirtualCode;
14
14
  };
15
15
  }
16
- export declare function createCSSLanguagePlugin(resolver: Resolver, matchesPattern: MatchesPattern): LanguagePlugin<string, VirtualCode>;
16
+ export declare function createCSSLanguagePlugin(resolver: Resolver, matchesPattern: MatchesPattern, config: CMKConfig): LanguagePlugin<string, VirtualCode>;
17
17
  export declare function isCSSModuleScript(script: SourceScript<string> | undefined): script is CSSModuleScript;
18
18
  export {};
19
19
  //# sourceMappingURL=language-plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"language-plugin.d.ts","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEzG,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAItF,eAAO,MAAM,WAAW,QAAQ,CAAC;AAEjC,eAAO,MAAM,YAAY,eAAiC,CAAC;AAE3D,UAAU,oBAAqB,SAAQ,WAAW;IAChD,CAAC,YAAY,CAAC,EAAE;QACd,SAAS,EAAE,SAAS,CAAC;QACrB,oBAAoB,EAAE,sBAAsB,EAAE,CAAC;KAChD,CAAC;CACH;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY,CAAC,MAAM,CAAC;IAC3D,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,GAAG;QAC7C,IAAI,EAAE,oBAAoB,CAAC;KAC5B,CAAC;CACH;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,GAC7B,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,CAgErC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,IAAI,eAAe,CAIrG"}
1
+ {"version":3,"file":"language-plugin.d.ts","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,sBAAsB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEpH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAItF,eAAO,MAAM,WAAW,QAAQ,CAAC;AAEjC,eAAO,MAAM,YAAY,eAAiC,CAAC;AAE3D,UAAU,oBAAqB,SAAQ,WAAW;IAChD,CAAC,YAAY,CAAC,EAAE;QACd,SAAS,EAAE,SAAS,CAAC;QACrB,oBAAoB,EAAE,sBAAsB,EAAE,CAAC;KAChD,CAAC;CACH;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY,CAAC,MAAM,CAAC;IAC3D,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,GAAG;QAC7C,IAAI,EAAE,oBAAoB,CAAC;KAC5B,CAAC;CACH;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,SAAS,GAChB,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,CAyErC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,IAAI,eAAe,CAIrG"}
@@ -10,7 +10,7 @@ const core_1 = require("@css-modules-kit/core");
10
10
  const typescript_1 = __importDefault(require("typescript"));
11
11
  exports.LANGUAGE_ID = 'css';
12
12
  exports.CMK_DATA_KEY = Symbol('css-modules-kit-data');
13
- function createCSSLanguagePlugin(resolver, matchesPattern) {
13
+ function createCSSLanguagePlugin(resolver, matchesPattern, config) {
14
14
  return {
15
15
  getLanguageId(scriptId) {
16
16
  if (!scriptId.endsWith('.css'))
@@ -39,7 +39,16 @@ function createCSSLanguagePlugin(resolver, matchesPattern) {
39
39
  // So, ts-plugin uses a fault-tolerant Parser to parse CSS.
40
40
  safe: true,
41
41
  });
42
- const { text, mapping, linkedCodeMapping } = (0, core_1.createDts)(cssModule, { resolver, matchesPattern });
42
+ // eslint-disable-next-line prefer-const
43
+ let { text, mapping, linkedCodeMapping } = (0, core_1.createDts)(cssModule, {
44
+ resolver,
45
+ matchesPattern,
46
+ namedExports: config.namedExports,
47
+ });
48
+ if (config.namedExports && !config.prioritizeNamedImports) {
49
+ // Export `styles` to appear in code completion suggestions
50
+ text += 'declare const styles: {};\nexport default styles;\n';
51
+ }
43
52
  return {
44
53
  id: 'main',
45
54
  languageId: exports.LANGUAGE_ID,
@@ -1 +1 @@
1
- {"version":3,"file":"language-plugin.js","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"language-plugin.js","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
+ import type { CMKConfig, Resolver } from '@css-modules-kit/core';
1
2
  import type { Language } from '@volar/language-core';
2
3
  import ts from 'typescript';
4
+ export declare const CANNOT_FIND_NAME_ERROR_CODE = 2304;
3
5
  export declare const PROPERTY_DOES_NOT_EXIST_ERROR_CODE = 2339;
4
- export declare function getCodeFixesAtPosition(language: Language<string>, languageService: ts.LanguageService, project: ts.server.Project): ts.LanguageService['getCodeFixesAtPosition'];
6
+ export declare function getCodeFixesAtPosition(language: Language<string>, languageService: ts.LanguageService, project: ts.server.Project, resolver: Resolver, config: CMKConfig): ts.LanguageService['getCodeFixesAtPosition'];
5
7
  //# sourceMappingURL=code-fix.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"code-fix.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/code-fix.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,MAAM,YAAY,CAAC;AAI5B,eAAO,MAAM,kCAAkC,OAAO,CAAC;AAEvD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,GACzB,EAAE,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAuB9C"}
1
+ {"version":3,"file":"code-fix.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/code-fix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,MAAM,YAAY,CAAC;AAK5B,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,kCAAkC,OAAO,CAAC;AAEvD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAC1B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,SAAS,GAChB,EAAE,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAmC9C"}
@@ -3,17 +3,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.PROPERTY_DOES_NOT_EXIST_ERROR_CODE = void 0;
6
+ exports.PROPERTY_DOES_NOT_EXIST_ERROR_CODE = exports.CANNOT_FIND_NAME_ERROR_CODE = void 0;
7
7
  exports.getCodeFixesAtPosition = getCodeFixesAtPosition;
8
8
  const core_1 = require("@css-modules-kit/core");
9
9
  const typescript_1 = __importDefault(require("typescript"));
10
10
  const language_plugin_js_1 = require("../../language-plugin.js");
11
- // ref: https://github.com/microsoft/TypeScript/blob/220706eb0320ff46fad8bf80a5e99db624ee7dfb/src/compiler/diagnosticMessages.json#L2051-L2054
11
+ const util_js_1 = require("../../util.js");
12
+ // ref: https://github.com/microsoft/TypeScript/blob/220706eb0320ff46fad8bf80a5e99db624ee7dfb/src/compiler/diagnosticMessages.json
13
+ exports.CANNOT_FIND_NAME_ERROR_CODE = 2304;
12
14
  exports.PROPERTY_DOES_NOT_EXIST_ERROR_CODE = 2339;
13
- function getCodeFixesAtPosition(language, languageService, project) {
15
+ function getCodeFixesAtPosition(language, languageService, project, resolver, config) {
14
16
  // eslint-disable-next-line max-params
15
17
  return (fileName, start, end, errorCodes, formatOptions, preferences) => {
16
- const prior = Array.from(languageService.getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences) ?? []);
18
+ const prior = Array.from(languageService.getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, (0, util_js_1.createPreferencesForCompletion)(preferences, config)));
19
+ if (config.namedExports && !config.prioritizeNamedImports) {
20
+ (0, util_js_1.convertDefaultImportsToNamespaceImports)(prior, fileName, resolver);
21
+ excludeNamedImports(prior, fileName, resolver);
22
+ }
17
23
  if ((0, core_1.isComponentFileName)(fileName)) {
18
24
  // If a user is trying to use a non-existent token (e.g. `styles.nonExistToken`), provide a code fix to add the token.
19
25
  if (errorCodes.includes(exports.PROPERTY_DOES_NOT_EXIST_ERROR_CODE)) {
@@ -27,9 +33,29 @@ function getCodeFixesAtPosition(language, languageService, project) {
27
33
  }
28
34
  }
29
35
  }
30
- return prior;
36
+ return prior.filter((codeFix) => codeFix.changes.length > 0);
31
37
  };
32
38
  }
39
+ /**
40
+ * Exclude code fixes that add named imports (e.g. `import { foo } from './a.module.css'`)
41
+ */
42
+ function excludeNamedImports(codeFixes, fileName, resolver) {
43
+ for (const codeFix of codeFixes) {
44
+ if (codeFix.fixName !== 'import')
45
+ continue;
46
+ const match = codeFix.description.match(/^Add import from "(.*)"$/u);
47
+ if (!match)
48
+ continue;
49
+ const specifier = match[1];
50
+ const resolved = resolver(specifier, { request: fileName });
51
+ if (!resolved || !(0, core_1.isCSSModuleFile)(resolved))
52
+ continue;
53
+ for (const change of codeFix.changes) {
54
+ change.textChanges = change.textChanges.filter((textChange) => !textChange.newText.startsWith(`import {`));
55
+ }
56
+ codeFix.changes = codeFix.changes.filter((change) => change.textChanges.length > 0);
57
+ }
58
+ }
33
59
  /**
34
60
  * Get the token consumer at the specified position.
35
61
  * If the position is at `styles.foo`, it returns `{ tokenName: 'foo', from: '/path/to/a.module.css' }`.
@@ -1 +1 @@
1
- {"version":3,"file":"code-fix.js","sourceRoot":"","sources":["../../../src/language-service/feature/code-fix.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-fix.js","sourceRoot":"","sources":["../../../src/language-service/feature/code-fix.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import type { CMKConfig, Resolver } from '@css-modules-kit/core';
1
2
  import ts from 'typescript';
2
- export declare function getCompletionsAtPosition(languageService: ts.LanguageService): ts.LanguageService['getCompletionsAtPosition'];
3
+ export declare function getCompletionsAtPosition(languageService: ts.LanguageService, config: CMKConfig): ts.LanguageService['getCompletionsAtPosition'];
4
+ export declare function getCompletionEntryDetails(languageService: ts.LanguageService, resolver: Resolver, config: CMKConfig): ts.LanguageService['getCompletionEntryDetails'];
3
5
  //# sourceMappingURL=completion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/completion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,EAAE,CAAC,eAAe,GAClC,EAAE,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAmBhD"}
1
+ {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/completion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,MAAM,EAAE,SAAS,GAChB,EAAE,CAAC,eAAe,CAAC,0BAA0B,CAAC,CAwChD;AA0CD,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,SAAS,GAChB,EAAE,CAAC,eAAe,CAAC,2BAA2B,CAAC,CAmBjD"}
@@ -4,15 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getCompletionsAtPosition = getCompletionsAtPosition;
7
+ exports.getCompletionEntryDetails = getCompletionEntryDetails;
7
8
  const core_1 = require("@css-modules-kit/core");
8
9
  const typescript_1 = __importDefault(require("typescript"));
9
- function getCompletionsAtPosition(languageService) {
10
+ const util_js_1 = require("../../util.js");
11
+ function getCompletionsAtPosition(languageService, config) {
10
12
  return (fileName, position, options, formattingSettings) => {
11
- const prior = languageService.getCompletionsAtPosition(fileName, position, options, formattingSettings);
12
- if ((0, core_1.isComponentFileName)(fileName) && prior) {
13
+ const prior = languageService.getCompletionsAtPosition(fileName, position, (0, util_js_1.createPreferencesForCompletion)(options ?? {}, config), formattingSettings);
14
+ if (!prior)
15
+ return;
16
+ if ((0, core_1.isComponentFileName)(fileName)) {
13
17
  const cssModuleFileName = (0, core_1.getCssModuleFileName)(fileName);
14
18
  for (const entry of prior.entries) {
15
- if (isStylesEntryForCSSModuleFile(entry, cssModuleFileName)) {
19
+ if (isDefaultExportedStylesEntry(entry) && entry.data.fileName === cssModuleFileName) {
16
20
  // Prioritize the completion of the `styles' import for the current .ts file for usability.
17
21
  // NOTE: This is a hack to make the completion item appear at the top
18
22
  entry.sortText = '0';
@@ -23,19 +27,43 @@ function getCompletionsAtPosition(languageService) {
23
27
  }
24
28
  }
25
29
  }
30
+ if (config.namedExports && !config.prioritizeNamedImports) {
31
+ // When `namedExports` is enabled, you can write code as follows:
32
+ // ```tsx
33
+ // import { button } from './a.module.css';
34
+ // const Button = () => <button className={button}>Click me!</button>;
35
+ // ```
36
+ // However, it is more common to use namespace imports for styles.
37
+ // ```tsx
38
+ // import * as styles from './a.module.css';
39
+ // const Button = () => <button className={styles.button}>Click me!</button>;
40
+ // ```
41
+ // Therefore, completion for tokens like `button` is disabled.
42
+ prior.entries = prior.entries.filter((entry) => !isNamedExportedTokenEntry(entry));
43
+ }
26
44
  return prior;
27
45
  };
28
46
  }
29
47
  /**
30
- * Check if the completion entry is the `styles` entry for the CSS module file.
48
+ * Check if the completion entry is the default exported `styles` entry.
31
49
  */
32
- function isStylesEntryForCSSModuleFile(entry, cssModuleFileName) {
50
+ function isDefaultExportedStylesEntry(entry) {
33
51
  return (entry.name === core_1.STYLES_EXPORT_NAME &&
34
- entry.data &&
52
+ entry.data !== undefined &&
35
53
  // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
36
54
  entry.data.exportName === typescript_1.default.InternalSymbolName.Default &&
37
- entry.data.fileName &&
38
- entry.data.fileName === cssModuleFileName);
55
+ entry.data.fileName !== undefined &&
56
+ (0, core_1.isCSSModuleFile)(entry.data.fileName));
57
+ }
58
+ /**
59
+ * Check if the completion entry is a named exported token entry.
60
+ */
61
+ function isNamedExportedTokenEntry(entry) {
62
+ return (entry.data !== undefined &&
63
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
64
+ entry.data.exportName !== typescript_1.default.InternalSymbolName.Default &&
65
+ entry.data.fileName !== undefined &&
66
+ (0, core_1.isCSSModuleFile)(entry.data.fileName));
39
67
  }
40
68
  function isClassNamePropEntry(entry) {
41
69
  return (entry.name === 'className' &&
@@ -43,4 +71,16 @@ function isClassNamePropEntry(entry) {
43
71
  (entry.insertText === 'className="$1"' || entry.insertText === "className='$1'") &&
44
72
  entry.isSnippet);
45
73
  }
74
+ function getCompletionEntryDetails(languageService, resolver, config) {
75
+ // eslint-disable-next-line max-params
76
+ return (fileName, position, entryName, formatOptions, source, preferences, data) => {
77
+ const details = languageService.getCompletionEntryDetails(fileName, position, entryName, formatOptions, source, preferences, data);
78
+ if (!details)
79
+ return undefined;
80
+ if (config.namedExports && !config.prioritizeNamedImports && details.codeActions) {
81
+ (0, util_js_1.convertDefaultImportsToNamespaceImports)(details.codeActions, fileName, resolver);
82
+ }
83
+ return details;
84
+ };
85
+ }
46
86
  //# sourceMappingURL=completion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/language-service/feature/completion.ts"],"names":[],"mappings":";;;;;AAGA,4DAqBC;AAxBD,gDAAsG;AACtG,4DAA4B;AAE5B,SAAgB,wBAAwB,CACtC,eAAmC;IAEnC,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE;QACzD,MAAM,KAAK,GAAG,eAAe,CAAC,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC;QAExG,IAAI,IAAA,0BAAmB,EAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC;YAC3C,MAAM,iBAAiB,GAAG,IAAA,2BAAoB,EAAC,QAAQ,CAAC,CAAC;YACzD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,6BAA6B,CAAC,KAAK,EAAE,iBAAiB,CAAC,EAAE,CAAC;oBAC5D,2FAA2F;oBAC3F,qEAAqE;oBACrE,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC;gBACvB,CAAC;qBAAM,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;oBACvC,yEAAyE;oBACzE,KAAK,CAAC,UAAU,GAAG,gBAAgB,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,6BAA6B,CAAC,KAAyB,EAAE,iBAAyB;IACzF,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,yBAAkB;QACjC,KAAK,CAAC,IAAI;QACV,wEAAwE;QACxE,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,oBAAE,CAAC,kBAAkB,CAAC,OAAO;QACvD,KAAK,CAAC,IAAI,CAAC,QAAQ;QACnB,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,iBAAiB,CAC1C,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAyB;IACrD,OAAO,CACL,KAAK,CAAC,IAAI,KAAK,WAAW;QAC1B,KAAK,CAAC,IAAI,KAAK,oBAAE,CAAC,iBAAiB,CAAC,qBAAqB;QACzD,CAAC,KAAK,CAAC,UAAU,KAAK,gBAAgB,IAAI,KAAK,CAAC,UAAU,KAAK,gBAAgB,CAAC;QAChF,KAAK,CAAC,SAAS,CAChB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"completion.js","sourceRoot":"","sources":["../../../src/language-service/feature/completion.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
+ import type { CMKConfig } from '@css-modules-kit/core';
1
2
  import { type MatchesPattern, type Resolver } from '@css-modules-kit/core';
2
3
  import type { Language } from '@volar/language-core';
3
4
  import type ts from 'typescript';
4
- export declare function proxyLanguageService(language: Language<string>, languageService: ts.LanguageService, project: ts.server.Project, resolver: Resolver, matchesPattern: MatchesPattern): ts.LanguageService;
5
+ export declare function proxyLanguageService(language: Language<string>, languageService: ts.LanguageService, project: ts.server.Project, resolver: Resolver, matchesPattern: MatchesPattern, config: CMKConfig): ts.LanguageService;
5
6
  //# sourceMappingURL=proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAQjC,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAC1B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,GAC7B,EAAE,CAAC,eAAe,CAkCpB"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAuB,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AASjC,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAC1B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,SAAS,GAChB,EAAE,CAAC,eAAe,CAmCpB"}
@@ -8,7 +8,8 @@ const completion_js_1 = require("./feature/completion.js");
8
8
  const refactor_js_1 = require("./feature/refactor.js");
9
9
  const semantic_diagnostic_js_1 = require("./feature/semantic-diagnostic.js");
10
10
  const syntactic_diagnostic_js_1 = require("./feature/syntactic-diagnostic.js");
11
- function proxyLanguageService(language, languageService, project, resolver, matchesPattern) {
11
+ // eslint-disable-next-line max-params
12
+ function proxyLanguageService(language, languageService, project, resolver, matchesPattern, config) {
12
13
  const proxy = Object.create(null);
13
14
  for (const k of Object.keys(languageService)) {
14
15
  const x = languageService[k];
@@ -28,8 +29,9 @@ function proxyLanguageService(language, languageService, project, resolver, matc
28
29
  proxy.getSemanticDiagnostics = (0, semantic_diagnostic_js_1.getSemanticDiagnostics)(language, languageService, exportBuilder, resolver, matchesPattern, getCSSModule);
29
30
  proxy.getApplicableRefactors = (0, refactor_js_1.getApplicableRefactors)(languageService, project);
30
31
  proxy.getEditsForRefactor = (0, refactor_js_1.getEditsForRefactor)(languageService);
31
- proxy.getCompletionsAtPosition = (0, completion_js_1.getCompletionsAtPosition)(languageService);
32
- proxy.getCodeFixesAtPosition = (0, code_fix_js_1.getCodeFixesAtPosition)(language, languageService, project);
32
+ proxy.getCompletionsAtPosition = (0, completion_js_1.getCompletionsAtPosition)(languageService, config);
33
+ proxy.getCompletionEntryDetails = (0, completion_js_1.getCompletionEntryDetails)(languageService, resolver, config);
34
+ proxy.getCodeFixesAtPosition = (0, code_fix_js_1.getCodeFixesAtPosition)(language, languageService, project, resolver, config);
33
35
  return proxy;
34
36
  }
35
37
  //# sourceMappingURL=proxy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":";;AAUA,oDAwCC;AAlDD,gDAAgG;AAGhG,8DAAwE;AACxE,uDAA+D;AAC/D,2DAAmE;AACnE,uDAAoF;AACpF,6EAA0E;AAC1E,+EAA4E;AAE5E,SAAgB,oBAAoB,CAClC,QAA0B,EAC1B,eAAmC,EACnC,OAA0B,EAC1B,QAAkB,EAClB,cAA8B;IAE9B,MAAM,KAAK,GAAuB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAiC,EAAE,CAAC;QAC7E,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAE,CAAC;QAC9B,yEAAyE;QACzE,mEAAmE;QACnE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAU,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,IAAA,sCAAiB,EAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,iCAAY,CAAC,CAAC,SAAS,CAAC;QACvD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,MAAM,aAAa,GAAG,IAAA,0BAAmB,EAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IAEtF,KAAK,CAAC,uBAAuB,GAAG,IAAA,iDAAuB,EAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACnF,KAAK,CAAC,sBAAsB,GAAG,IAAA,+CAAsB,EACnD,QAAQ,EACR,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,EACd,YAAY,CACb,CAAC;IACF,KAAK,CAAC,sBAAsB,GAAG,IAAA,oCAAsB,EAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAChF,KAAK,CAAC,mBAAmB,GAAG,IAAA,iCAAmB,EAAC,eAAe,CAAC,CAAC;IACjE,KAAK,CAAC,wBAAwB,GAAG,IAAA,wCAAwB,EAAC,eAAe,CAAC,CAAC;IAC3E,KAAK,CAAC,sBAAsB,GAAG,IAAA,oCAAsB,EAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IAE1F,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":";;AAYA,oDA0CC;AArDD,gDAAgG;AAGhG,8DAAwE;AACxE,uDAA+D;AAC/D,2DAA8F;AAC9F,uDAAoF;AACpF,6EAA0E;AAC1E,+EAA4E;AAE5E,sCAAsC;AACtC,SAAgB,oBAAoB,CAClC,QAA0B,EAC1B,eAAmC,EACnC,OAA0B,EAC1B,QAAkB,EAClB,cAA8B,EAC9B,MAAiB;IAEjB,MAAM,KAAK,GAAuB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAiC,EAAE,CAAC;QAC7E,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAE,CAAC;QAC9B,yEAAyE;QACzE,mEAAmE;QACnE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAU,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,IAAA,sCAAiB,EAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,iCAAY,CAAC,CAAC,SAAS,CAAC;QACvD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,MAAM,aAAa,GAAG,IAAA,0BAAmB,EAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IAEtF,KAAK,CAAC,uBAAuB,GAAG,IAAA,iDAAuB,EAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACnF,KAAK,CAAC,sBAAsB,GAAG,IAAA,+CAAsB,EACnD,QAAQ,EACR,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,EACd,YAAY,CACb,CAAC;IACF,KAAK,CAAC,sBAAsB,GAAG,IAAA,oCAAsB,EAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAChF,KAAK,CAAC,mBAAmB,GAAG,IAAA,iCAAmB,EAAC,eAAe,CAAC,CAAC;IACjE,KAAK,CAAC,wBAAwB,GAAG,IAAA,wCAAwB,EAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACnF,KAAK,CAAC,yBAAyB,GAAG,IAAA,yCAAyB,EAAC,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/F,KAAK,CAAC,sBAAsB,GAAG,IAAA,oCAAsB,EAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE5G,OAAO,KAAK,CAAC;AACf,CAAC"}
package/dist/util.d.ts CHANGED
@@ -1,5 +1,12 @@
1
+ import { type CMKConfig, type Resolver } from '@css-modules-kit/core';
1
2
  import ts from 'typescript';
2
3
  /** The error code used by tsserver to display the css-modules-kit error in the editor. */
3
4
  export declare const TS_ERROR_CODE_FOR_CMK_ERROR = 0;
4
5
  export declare function convertErrorCategory(category: 'error' | 'warning' | 'suggestion'): ts.DiagnosticCategory;
6
+ export declare function createPreferencesForCompletion<T extends ts.UserPreferences>(preferences: T, config: CMKConfig): T;
7
+ /**
8
+ * Convert default imports to namespace imports for CSS modules.
9
+ * For example, convert `import styles from './styles.module.css'` to `import * as styles from './styles.module.css'`.
10
+ */
11
+ export declare function convertDefaultImportsToNamespaceImports(codeFixes: ts.CodeFixAction[] | ts.CodeAction[], fileName: string, resolver: Resolver): void;
5
12
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,0FAA0F;AAG1F,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,EAAE,CAAC,kBAAkB,CAWxG"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAmB,KAAK,QAAQ,EAAsB,MAAM,uBAAuB,CAAC;AAC3G,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,0FAA0F;AAG1F,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,EAAE,CAAC,kBAAkB,CAWxG;AAED,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,GAAG,CAAC,CAOjH;AACD;;;GAGG;AACH,wBAAgB,uCAAuC,CACrD,SAAS,EAAE,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,EAC/C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,GACjB,IAAI,CAoBN"}
package/dist/util.js CHANGED
@@ -5,6 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TS_ERROR_CODE_FOR_CMK_ERROR = void 0;
7
7
  exports.convertErrorCategory = convertErrorCategory;
8
+ exports.createPreferencesForCompletion = createPreferencesForCompletion;
9
+ exports.convertDefaultImportsToNamespaceImports = convertDefaultImportsToNamespaceImports;
10
+ const core_1 = require("@css-modules-kit/core");
8
11
  const typescript_1 = __importDefault(require("typescript"));
9
12
  /** The error code used by tsserver to display the css-modules-kit error in the editor. */
10
13
  // NOTE: Use any other number than 1002 or later, as they are reserved by TypeScript's built-in errors.
@@ -22,4 +25,36 @@ function convertErrorCategory(category) {
22
25
  throw new Error(`Unknown category: ${String(category)}`);
23
26
  }
24
27
  }
28
+ function createPreferencesForCompletion(preferences, config) {
29
+ // By default, files in `generated/` are included in the completion candidates.
30
+ // To exclude them, we add the `dtsOutDir` to the `autoImportFileExcludePatterns`.
31
+ return {
32
+ ...preferences,
33
+ autoImportFileExcludePatterns: [...(preferences.autoImportFileExcludePatterns ?? []), config.dtsOutDir],
34
+ };
35
+ }
36
+ /**
37
+ * Convert default imports to namespace imports for CSS modules.
38
+ * For example, convert `import styles from './styles.module.css'` to `import * as styles from './styles.module.css'`.
39
+ */
40
+ function convertDefaultImportsToNamespaceImports(codeFixes, fileName, resolver) {
41
+ for (const codeFix of codeFixes) {
42
+ if ('fixName' in codeFix && codeFix.fixName !== 'import')
43
+ continue;
44
+ // Check if the code fix is to add an import for a CSS module.
45
+ const match = codeFix.description.match(/^Add import from "(.*)"$/u);
46
+ if (!match)
47
+ continue;
48
+ const specifier = match[1];
49
+ const resolved = resolver(specifier, { request: fileName });
50
+ if (!resolved || !(0, core_1.isCSSModuleFile)(resolved))
51
+ continue;
52
+ // If the specifier is a CSS module, convert the import to a namespace import.
53
+ for (const change of codeFix.changes) {
54
+ for (const textChange of change.textChanges) {
55
+ textChange.newText = textChange.newText.replace(`import ${core_1.STYLES_EXPORT_NAME} from`, `import * as ${core_1.STYLES_EXPORT_NAME} from`);
56
+ }
57
+ }
58
+ }
59
+ }
25
60
  //# sourceMappingURL=util.js.map
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;;;;AAOA,oDAWC;AAlBD,4DAA4B;AAE5B,0FAA0F;AAC1F,uGAAuG;AACvG,kIAAkI;AACrH,QAAA,2BAA2B,GAAG,CAAC,CAAC;AAE7C,SAAgB,oBAAoB,CAAC,QAA4C;IAC/E,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,oBAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC;QACrC,KAAK,SAAS;YACZ,OAAO,oBAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC;QACvC,KAAK,YAAY;YACf,OAAO,oBAAE,CAAC,kBAAkB,CAAC,UAAU,CAAC;QAC1C;YACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;;;;AAQA,oDAWC;AAED,wEAOC;AAKD,0FAwBC;AAzDD,gDAA2G;AAC3G,4DAA4B;AAE5B,0FAA0F;AAC1F,uGAAuG;AACvG,kIAAkI;AACrH,QAAA,2BAA2B,GAAG,CAAC,CAAC;AAE7C,SAAgB,oBAAoB,CAAC,QAA4C;IAC/E,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,oBAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC;QACrC,KAAK,SAAS;YACZ,OAAO,oBAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC;QACvC,KAAK,YAAY;YACf,OAAO,oBAAE,CAAC,kBAAkB,CAAC,UAAU,CAAC;QAC1C;YACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,SAAgB,8BAA8B,CAA+B,WAAc,EAAE,MAAiB;IAC5G,+EAA+E;IAC/E,kFAAkF;IAClF,OAAO;QACL,GAAG,WAAW;QACd,6BAA6B,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,6BAA6B,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC;KACxG,CAAC;AACJ,CAAC;AACD;;;GAGG;AACH,SAAgB,uCAAuC,CACrD,SAA+C,EAC/C,QAAgB,EAChB,QAAkB;IAElB,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,SAAS,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,KAAK,QAAQ;YAAE,SAAS;QACnE,8DAA8D;QAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,sBAAe,EAAC,QAAQ,CAAC;YAAE,SAAS;QAEtD,8EAA8E;QAC9E,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC5C,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAC7C,UAAU,yBAAkB,OAAO,EACnC,eAAe,yBAAkB,OAAO,CACzC,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@css-modules-kit/ts-plugin",
3
3
  "description": "A TypeScript Language Service Plugin for CSS Modules",
4
- "version": "0.1.1",
4
+ "version": "0.2.0",
5
5
  "type": "commonjs",
6
6
  "sideEffects": false,
7
7
  "repository": {
@@ -17,7 +17,7 @@
17
17
  "build": "tsc -b tsconfig.build.json"
18
18
  },
19
19
  "engines": {
20
- "node": ">=22.0.0"
20
+ "node": ">=20.19.0"
21
21
  },
22
22
  "publishConfig": {
23
23
  "access": "public",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@volar/language-core": "^2.4.11",
41
41
  "@volar/typescript": "^2.4.11",
42
- "@css-modules-kit/core": "^0.2.0"
42
+ "@css-modules-kit/core": "^0.3.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "typescript": ">=5.6.3"
package/src/index.ts CHANGED
@@ -38,7 +38,7 @@ const plugin = createLanguageServicePlugin((ts, info) => {
38
38
  const matchesPattern = createMatchesPattern(config);
39
39
 
40
40
  return {
41
- languagePlugins: [createCSSLanguagePlugin(resolver, matchesPattern)],
41
+ languagePlugins: [createCSSLanguagePlugin(resolver, matchesPattern, config)],
42
42
  setup: (language) => {
43
43
  info.languageService = proxyLanguageService(
44
44
  language,
@@ -46,6 +46,7 @@ const plugin = createLanguageServicePlugin((ts, info) => {
46
46
  info.project,
47
47
  resolver,
48
48
  matchesPattern,
49
+ config,
49
50
  );
50
51
  },
51
52
  };
@@ -1,4 +1,4 @@
1
- import type { CSSModule, DiagnosticWithLocation, MatchesPattern, Resolver } from '@css-modules-kit/core';
1
+ import type { CMKConfig, CSSModule, DiagnosticWithLocation, MatchesPattern, Resolver } from '@css-modules-kit/core';
2
2
  import { createDts, parseCSSModule } from '@css-modules-kit/core';
3
3
  import type { LanguagePlugin, SourceScript, VirtualCode } from '@volar/language-core';
4
4
  import type {} from '@volar/typescript';
@@ -24,6 +24,7 @@ export interface CSSModuleScript extends SourceScript<string> {
24
24
  export function createCSSLanguagePlugin(
25
25
  resolver: Resolver,
26
26
  matchesPattern: MatchesPattern,
27
+ config: CMKConfig,
27
28
  ): LanguagePlugin<string, VirtualCode> {
28
29
  return {
29
30
  getLanguageId(scriptId) {
@@ -52,7 +53,16 @@ export function createCSSLanguagePlugin(
52
53
  // So, ts-plugin uses a fault-tolerant Parser to parse CSS.
53
54
  safe: true,
54
55
  });
55
- const { text, mapping, linkedCodeMapping } = createDts(cssModule, { resolver, matchesPattern });
56
+ // eslint-disable-next-line prefer-const
57
+ let { text, mapping, linkedCodeMapping } = createDts(cssModule, {
58
+ resolver,
59
+ matchesPattern,
60
+ namedExports: config.namedExports,
61
+ });
62
+ if (config.namedExports && !config.prioritizeNamedImports) {
63
+ // Export `styles` to appear in code completion suggestions
64
+ text += 'declare const styles: {};\nexport default styles;\n';
65
+ }
56
66
  return {
57
67
  id: 'main',
58
68
  languageId: LANGUAGE_ID,
@@ -1,22 +1,39 @@
1
- import { isComponentFileName } from '@css-modules-kit/core';
1
+ import type { CMKConfig, Resolver } from '@css-modules-kit/core';
2
+ import { isComponentFileName, isCSSModuleFile } from '@css-modules-kit/core';
2
3
  import type { Language } from '@volar/language-core';
3
4
  import ts from 'typescript';
4
5
  import { isCSSModuleScript } from '../../language-plugin.js';
6
+ import { convertDefaultImportsToNamespaceImports, createPreferencesForCompletion } from '../../util.js';
5
7
 
6
- // ref: https://github.com/microsoft/TypeScript/blob/220706eb0320ff46fad8bf80a5e99db624ee7dfb/src/compiler/diagnosticMessages.json#L2051-L2054
8
+ // ref: https://github.com/microsoft/TypeScript/blob/220706eb0320ff46fad8bf80a5e99db624ee7dfb/src/compiler/diagnosticMessages.json
9
+ export const CANNOT_FIND_NAME_ERROR_CODE = 2304;
7
10
  export const PROPERTY_DOES_NOT_EXIST_ERROR_CODE = 2339;
8
11
 
9
12
  export function getCodeFixesAtPosition(
10
13
  language: Language<string>,
11
14
  languageService: ts.LanguageService,
12
15
  project: ts.server.Project,
16
+ resolver: Resolver,
17
+ config: CMKConfig,
13
18
  ): ts.LanguageService['getCodeFixesAtPosition'] {
14
19
  // eslint-disable-next-line max-params
15
20
  return (fileName, start, end, errorCodes, formatOptions, preferences) => {
16
21
  const prior = Array.from(
17
- languageService.getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences) ?? [],
22
+ languageService.getCodeFixesAtPosition(
23
+ fileName,
24
+ start,
25
+ end,
26
+ errorCodes,
27
+ formatOptions,
28
+ createPreferencesForCompletion(preferences, config),
29
+ ),
18
30
  );
19
31
 
32
+ if (config.namedExports && !config.prioritizeNamedImports) {
33
+ convertDefaultImportsToNamespaceImports(prior, fileName, resolver);
34
+ excludeNamedImports(prior, fileName, resolver);
35
+ }
36
+
20
37
  if (isComponentFileName(fileName)) {
21
38
  // If a user is trying to use a non-existent token (e.g. `styles.nonExistToken`), provide a code fix to add the token.
22
39
  if (errorCodes.includes(PROPERTY_DOES_NOT_EXIST_ERROR_CODE)) {
@@ -31,10 +48,29 @@ export function getCodeFixesAtPosition(
31
48
  }
32
49
  }
33
50
 
34
- return prior;
51
+ return prior.filter((codeFix) => codeFix.changes.length > 0);
35
52
  };
36
53
  }
37
54
 
55
+ /**
56
+ * Exclude code fixes that add named imports (e.g. `import { foo } from './a.module.css'`)
57
+ */
58
+ function excludeNamedImports(codeFixes: ts.CodeFixAction[], fileName: string, resolver: Resolver): void {
59
+ for (const codeFix of codeFixes) {
60
+ if (codeFix.fixName !== 'import') continue;
61
+ const match = codeFix.description.match(/^Add import from "(.*)"$/u);
62
+ if (!match) continue;
63
+ const specifier = match[1]!;
64
+ const resolved = resolver(specifier, { request: fileName });
65
+ if (!resolved || !isCSSModuleFile(resolved)) continue;
66
+
67
+ for (const change of codeFix.changes) {
68
+ change.textChanges = change.textChanges.filter((textChange) => !textChange.newText.startsWith(`import {`));
69
+ }
70
+ codeFix.changes = codeFix.changes.filter((change) => change.textChanges.length > 0);
71
+ }
72
+ }
73
+
38
74
  interface TokenConsumer {
39
75
  /** The token name (e.g. `foo` in `styles.foo`) */
40
76
  tokenName: string;
@@ -1,16 +1,26 @@
1
- import { getCssModuleFileName, isComponentFileName, STYLES_EXPORT_NAME } from '@css-modules-kit/core';
1
+ import type { CMKConfig, Resolver } from '@css-modules-kit/core';
2
+ import { getCssModuleFileName, isComponentFileName, isCSSModuleFile, STYLES_EXPORT_NAME } from '@css-modules-kit/core';
2
3
  import ts from 'typescript';
4
+ import { convertDefaultImportsToNamespaceImports, createPreferencesForCompletion } from '../../util.js';
3
5
 
4
6
  export function getCompletionsAtPosition(
5
7
  languageService: ts.LanguageService,
8
+ config: CMKConfig,
6
9
  ): ts.LanguageService['getCompletionsAtPosition'] {
7
10
  return (fileName, position, options, formattingSettings) => {
8
- const prior = languageService.getCompletionsAtPosition(fileName, position, options, formattingSettings);
11
+ const prior = languageService.getCompletionsAtPosition(
12
+ fileName,
13
+ position,
14
+ createPreferencesForCompletion(options ?? {}, config),
15
+ formattingSettings,
16
+ );
9
17
 
10
- if (isComponentFileName(fileName) && prior) {
18
+ if (!prior) return;
19
+
20
+ if (isComponentFileName(fileName)) {
11
21
  const cssModuleFileName = getCssModuleFileName(fileName);
12
22
  for (const entry of prior.entries) {
13
- if (isStylesEntryForCSSModuleFile(entry, cssModuleFileName)) {
23
+ if (isDefaultExportedStylesEntry(entry) && entry.data.fileName === cssModuleFileName) {
14
24
  // Prioritize the completion of the `styles' import for the current .ts file for usability.
15
25
  // NOTE: This is a hack to make the completion item appear at the top
16
26
  entry.sortText = '0';
@@ -20,21 +30,52 @@ export function getCompletionsAtPosition(
20
30
  }
21
31
  }
22
32
  }
33
+ if (config.namedExports && !config.prioritizeNamedImports) {
34
+ // When `namedExports` is enabled, you can write code as follows:
35
+ // ```tsx
36
+ // import { button } from './a.module.css';
37
+ // const Button = () => <button className={button}>Click me!</button>;
38
+ // ```
39
+ // However, it is more common to use namespace imports for styles.
40
+ // ```tsx
41
+ // import * as styles from './a.module.css';
42
+ // const Button = () => <button className={styles.button}>Click me!</button>;
43
+ // ```
44
+ // Therefore, completion for tokens like `button` is disabled.
45
+ prior.entries = prior.entries.filter((entry) => !isNamedExportedTokenEntry(entry));
46
+ }
23
47
  return prior;
24
48
  };
25
49
  }
26
50
 
51
+ type DefaultExportedStylesEntry = ts.CompletionEntry & {
52
+ data: ts.CompletionEntryData;
53
+ };
54
+
27
55
  /**
28
- * Check if the completion entry is the `styles` entry for the CSS module file.
56
+ * Check if the completion entry is the default exported `styles` entry.
29
57
  */
30
- function isStylesEntryForCSSModuleFile(entry: ts.CompletionEntry, cssModuleFileName: string) {
58
+ function isDefaultExportedStylesEntry(entry: ts.CompletionEntry): entry is DefaultExportedStylesEntry {
31
59
  return (
32
60
  entry.name === STYLES_EXPORT_NAME &&
33
- entry.data &&
61
+ entry.data !== undefined &&
34
62
  // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
35
63
  entry.data.exportName === ts.InternalSymbolName.Default &&
36
- entry.data.fileName &&
37
- entry.data.fileName === cssModuleFileName
64
+ entry.data.fileName !== undefined &&
65
+ isCSSModuleFile(entry.data.fileName)
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Check if the completion entry is a named exported token entry.
71
+ */
72
+ function isNamedExportedTokenEntry(entry: ts.CompletionEntry): boolean {
73
+ return (
74
+ entry.data !== undefined &&
75
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
76
+ entry.data.exportName !== ts.InternalSymbolName.Default &&
77
+ entry.data.fileName !== undefined &&
78
+ isCSSModuleFile(entry.data.fileName)
38
79
  );
39
80
  }
40
81
 
@@ -46,3 +87,28 @@ function isClassNamePropEntry(entry: ts.CompletionEntry) {
46
87
  entry.isSnippet
47
88
  );
48
89
  }
90
+
91
+ export function getCompletionEntryDetails(
92
+ languageService: ts.LanguageService,
93
+ resolver: Resolver,
94
+ config: CMKConfig,
95
+ ): ts.LanguageService['getCompletionEntryDetails'] {
96
+ // eslint-disable-next-line max-params
97
+ return (fileName, position, entryName, formatOptions, source, preferences, data) => {
98
+ const details = languageService.getCompletionEntryDetails(
99
+ fileName,
100
+ position,
101
+ entryName,
102
+ formatOptions,
103
+ source,
104
+ preferences,
105
+ data,
106
+ );
107
+ if (!details) return undefined;
108
+
109
+ if (config.namedExports && !config.prioritizeNamedImports && details.codeActions) {
110
+ convertDefaultImportsToNamespaceImports(details.codeActions, fileName, resolver);
111
+ }
112
+ return details;
113
+ };
114
+ }
@@ -1,19 +1,22 @@
1
+ import type { CMKConfig } from '@css-modules-kit/core';
1
2
  import { createExportBuilder, type MatchesPattern, type Resolver } from '@css-modules-kit/core';
2
3
  import type { Language } from '@volar/language-core';
3
4
  import type ts from 'typescript';
4
5
  import { CMK_DATA_KEY, isCSSModuleScript } from '../language-plugin.js';
5
6
  import { getCodeFixesAtPosition } from './feature/code-fix.js';
6
- import { getCompletionsAtPosition } from './feature/completion.js';
7
+ import { getCompletionEntryDetails, getCompletionsAtPosition } from './feature/completion.js';
7
8
  import { getApplicableRefactors, getEditsForRefactor } from './feature/refactor.js';
8
9
  import { getSemanticDiagnostics } from './feature/semantic-diagnostic.js';
9
10
  import { getSyntacticDiagnostics } from './feature/syntactic-diagnostic.js';
10
11
 
12
+ // eslint-disable-next-line max-params
11
13
  export function proxyLanguageService(
12
14
  language: Language<string>,
13
15
  languageService: ts.LanguageService,
14
16
  project: ts.server.Project,
15
17
  resolver: Resolver,
16
18
  matchesPattern: MatchesPattern,
19
+ config: CMKConfig,
17
20
  ): ts.LanguageService {
18
21
  const proxy: ts.LanguageService = Object.create(null);
19
22
 
@@ -44,8 +47,9 @@ export function proxyLanguageService(
44
47
  );
45
48
  proxy.getApplicableRefactors = getApplicableRefactors(languageService, project);
46
49
  proxy.getEditsForRefactor = getEditsForRefactor(languageService);
47
- proxy.getCompletionsAtPosition = getCompletionsAtPosition(languageService);
48
- proxy.getCodeFixesAtPosition = getCodeFixesAtPosition(language, languageService, project);
50
+ proxy.getCompletionsAtPosition = getCompletionsAtPosition(languageService, config);
51
+ proxy.getCompletionEntryDetails = getCompletionEntryDetails(languageService, resolver, config);
52
+ proxy.getCodeFixesAtPosition = getCodeFixesAtPosition(language, languageService, project, resolver, config);
49
53
 
50
54
  return proxy;
51
55
  }
package/src/util.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { type CMKConfig, isCSSModuleFile, type Resolver, STYLES_EXPORT_NAME } from '@css-modules-kit/core';
1
2
  import ts from 'typescript';
2
3
 
3
4
  /** The error code used by tsserver to display the css-modules-kit error in the editor. */
@@ -17,3 +18,41 @@ export function convertErrorCategory(category: 'error' | 'warning' | 'suggestion
17
18
  throw new Error(`Unknown category: ${String(category)}`);
18
19
  }
19
20
  }
21
+
22
+ export function createPreferencesForCompletion<T extends ts.UserPreferences>(preferences: T, config: CMKConfig): T {
23
+ // By default, files in `generated/` are included in the completion candidates.
24
+ // To exclude them, we add the `dtsOutDir` to the `autoImportFileExcludePatterns`.
25
+ return {
26
+ ...preferences,
27
+ autoImportFileExcludePatterns: [...(preferences.autoImportFileExcludePatterns ?? []), config.dtsOutDir],
28
+ };
29
+ }
30
+ /**
31
+ * Convert default imports to namespace imports for CSS modules.
32
+ * For example, convert `import styles from './styles.module.css'` to `import * as styles from './styles.module.css'`.
33
+ */
34
+ export function convertDefaultImportsToNamespaceImports(
35
+ codeFixes: ts.CodeFixAction[] | ts.CodeAction[],
36
+ fileName: string,
37
+ resolver: Resolver,
38
+ ): void {
39
+ for (const codeFix of codeFixes) {
40
+ if ('fixName' in codeFix && codeFix.fixName !== 'import') continue;
41
+ // Check if the code fix is to add an import for a CSS module.
42
+ const match = codeFix.description.match(/^Add import from "(.*)"$/u);
43
+ if (!match) continue;
44
+ const specifier = match[1]!;
45
+ const resolved = resolver(specifier, { request: fileName });
46
+ if (!resolved || !isCSSModuleFile(resolved)) continue;
47
+
48
+ // If the specifier is a CSS module, convert the import to a namespace import.
49
+ for (const change of codeFix.changes) {
50
+ for (const textChange of change.textChanges) {
51
+ textChange.newText = textChange.newText.replace(
52
+ `import ${STYLES_EXPORT_NAME} from`,
53
+ `import * as ${STYLES_EXPORT_NAME} from`,
54
+ );
55
+ }
56
+ }
57
+ }
58
+ }