From 5e532147a607d65394b43c9c77660701874ace23 Mon Sep 17 00:00:00 2001 From: "Krzysztof \"Bushee\" Nowaczyk" Date: Fri, 5 Apr 2019 15:27:12 +0200 Subject: [PATCH 1/2] feat: Equals-exported interface instead of series of consts --- index.js | 17 +++++++++-------- .../__snapshots__/emit-declaration.test.js.snap | 10 +++++++--- .../verify-invalid-declaration.test.js.snap | 10 +++++++--- test/verify-invalid-declaration/index.css.d.ts | 8 ++++++-- test/verify-valid-declaration/index.css.d.ts | 10 +++++++--- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/index.js b/index.js index db5b061..a1c1f9a 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,8 @@ const LineDiff = require('line-diff'); const bannerMessage = '// This file is automatically generated.\n// Please do not change this file!'; +const cssModuleExport = 'declare var cssExports: CssExports;\nexport = cssExports;\n'; + const getNoDeclarationFileError = ({ filename }) => new Error( `Generated type declaration does not exist. Run webpack and commit the type declaration for '${filename}'` @@ -19,12 +21,13 @@ const getTypeMismatchError = ({ filename, expected, actual }) => { ); }; -const cssModuleToNamedExports = cssModuleKeys => { - return cssModuleKeys +const cssModuleToInterface = (cssModuleKeys) => { + const interfaceFields = cssModuleKeys .sort() - .map(key => `export const ${key}: string;`) - .join('\n') - .concat('\n'); + .map(key => ` ${key}: string;`) + .join('\n'); + + return `interface CssExports {\n${interfaceFields}\n}`; }; const filenameToTypingsFilename = filename => { @@ -70,9 +73,7 @@ module.exports = function(content, ...rest) { } } - const cssModuleDefinition = `${bannerMessage}\n${cssModuleToNamedExports( - cssModuleKeys - )}`; + const cssModuleDefinition = `${bannerMessage}\n${cssModuleToInterface(cssModuleKeys)}\n${cssModuleExport}`; if (mode === 'verify') { read((err, fileContents) => { diff --git a/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap b/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap index ffd40cc..9f9b300 100644 --- a/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap +++ b/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap @@ -3,8 +3,12 @@ exports[`Can emit valid declaration 1`] = ` "// This file is automatically generated. // Please do not change this file! -export const otherClass: string; -export const someClass: string; -export const validClass: string; +interface CssExports { + otherClass: string; + someClass: string; + validClass: string; +} +declare var cssExports: CssExports; +export = cssExports; " `; diff --git a/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap b/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap index 3269778..8c531b8 100644 --- a/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap +++ b/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap @@ -5,9 +5,13 @@ exports[`Can error on invalid declaration 1`] = ` // This file is automatically generated. // Please do not change this file! - export const classInBothFiles: string; - - export const classInTypeScriptFile: string; - + export const classInCssFile: string; + interface CssExports { + classInBothFiles: string; + - classInTypeScriptFile: string; + + classInCssFile: string; + } + declare var cssExports: CssExports; + export = cssExports; " diff --git a/test/verify-invalid-declaration/index.css.d.ts b/test/verify-invalid-declaration/index.css.d.ts index 574d3f9..8ae234b 100644 --- a/test/verify-invalid-declaration/index.css.d.ts +++ b/test/verify-invalid-declaration/index.css.d.ts @@ -1,4 +1,8 @@ // This file is automatically generated. // Please do not change this file! -export const classInBothFiles: string; -export const classInTypeScriptFile: string; +interface CssExports { + classInBothFiles: string; + classInTypeScriptFile: string; +} +declare var cssExports: CssExports; +export = cssExports; diff --git a/test/verify-valid-declaration/index.css.d.ts b/test/verify-valid-declaration/index.css.d.ts index 3114b85..aa66da9 100644 --- a/test/verify-valid-declaration/index.css.d.ts +++ b/test/verify-valid-declaration/index.css.d.ts @@ -1,5 +1,9 @@ // This file is automatically generated. // Please do not change this file! -export const otherClass: string; -export const someClass: string; -export const validClass: string; +interface CssExports { + otherClass: string; + someClass: string; + validClass: string; +} +declare var cssExports: CssExports; +export = cssExports; From 46e365383d56947fa62d35affb35d0976fbce85d Mon Sep 17 00:00:00 2001 From: "Krzysztof \"Bushee\" Nowaczyk" Date: Fri, 5 Apr 2019 15:46:37 +0200 Subject: [PATCH 2/2] feat: Putting classnames in apostrophes to enable any possible classname --- README.md | 2 -- index.js | 2 +- .../__snapshots__/emit-declaration.test.js.snap | 6 +++--- .../__snapshots__/verify-invalid-declaration.test.js.snap | 6 +++--- test/verify-invalid-declaration/index.css.d.ts | 4 ++-- test/verify-valid-declaration/index.css | 5 +++++ test/verify-valid-declaration/index.css.d.ts | 8 +++++--- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b92e0ea..36fc6c5 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ There are currently a lot of [solutions to this problem](https://www.npmjs.com/s - Ensures committed TypeScript declarations are in sync with the code that generated them via the [`verify` mode](#verify-mode). -- Doesn't silently ignore invalid TypeScript identifiers. If a class name is not valid TypeScript (e.g. `.foo-bar`, instead of `.fooBar`), `tsc` should report an error. - ## Usage Place `css-modules-typescript-loader` directly after `css-loader` in your webpack config. diff --git a/index.js b/index.js index a1c1f9a..a424ffd 100644 --- a/index.js +++ b/index.js @@ -24,7 +24,7 @@ const getTypeMismatchError = ({ filename, expected, actual }) => { const cssModuleToInterface = (cssModuleKeys) => { const interfaceFields = cssModuleKeys .sort() - .map(key => ` ${key}: string;`) + .map(key => ` '${key}': string;`) .join('\n'); return `interface CssExports {\n${interfaceFields}\n}`; diff --git a/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap b/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap index 9f9b300..2a22a3b 100644 --- a/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap +++ b/test/emit-declaration/__snapshots__/emit-declaration.test.js.snap @@ -4,9 +4,9 @@ exports[`Can emit valid declaration 1`] = ` "// This file is automatically generated. // Please do not change this file! interface CssExports { - otherClass: string; - someClass: string; - validClass: string; + 'otherClass': string; + 'someClass': string; + 'validClass': string; } declare var cssExports: CssExports; export = cssExports; diff --git a/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap b/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap index 8c531b8..06b3ea9 100644 --- a/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap +++ b/test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap @@ -6,9 +6,9 @@ exports[`Can error on invalid declaration 1`] = ` // This file is automatically generated. // Please do not change this file! interface CssExports { - classInBothFiles: string; - - classInTypeScriptFile: string; - + classInCssFile: string; + 'classInBothFiles': string; + - 'classInTypeScriptFile': string; + + 'classInCssFile': string; } declare var cssExports: CssExports; export = cssExports; diff --git a/test/verify-invalid-declaration/index.css.d.ts b/test/verify-invalid-declaration/index.css.d.ts index 8ae234b..6c60747 100644 --- a/test/verify-invalid-declaration/index.css.d.ts +++ b/test/verify-invalid-declaration/index.css.d.ts @@ -1,8 +1,8 @@ // This file is automatically generated. // Please do not change this file! interface CssExports { - classInBothFiles: string; - classInTypeScriptFile: string; + 'classInBothFiles': string; + 'classInTypeScriptFile': string; } declare var cssExports: CssExports; export = cssExports; diff --git a/test/verify-valid-declaration/index.css b/test/verify-valid-declaration/index.css index 8bdba1f..a7d4cdf 100644 --- a/test/verify-valid-declaration/index.css +++ b/test/verify-valid-declaration/index.css @@ -9,3 +9,8 @@ .otherClass { display: block; } + +.hyphened-classname, +.underscored_classname { + color: papayawhip; +} diff --git a/test/verify-valid-declaration/index.css.d.ts b/test/verify-valid-declaration/index.css.d.ts index aa66da9..2808c59 100644 --- a/test/verify-valid-declaration/index.css.d.ts +++ b/test/verify-valid-declaration/index.css.d.ts @@ -1,9 +1,11 @@ // This file is automatically generated. // Please do not change this file! interface CssExports { - otherClass: string; - someClass: string; - validClass: string; + 'hyphened-classname': string; + 'otherClass': string; + 'someClass': string; + 'underscored_classname': string; + 'validClass': string; } declare var cssExports: CssExports; export = cssExports;