Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions examples/1-basic/generated/src/a.module.css.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// @ts-nocheck
function blockErrorType<T>(val: T): [0] extends [(1 & T)] ? {} : T;
declare const styles = {
a_1: '' as readonly string,
a_2: '' as readonly string,
a_2: '' as readonly string,
a_3: '' as readonly string,
a_4: '' as readonly string,
'a_1': '' as readonly string,
'a_2': '' as readonly string,
'a_2': '' as readonly string,
'a_3': '' as readonly string,
'a_4': '' as readonly string,
'a-1': '' as readonly string,
...blockErrorType((await import('./b.module.css')).default),
c_1: (await import('./c.module.css')).default.c_1,
c_alias: (await import('./c.module.css')).default.c_2,
'c_1': (await import('./c.module.css')).default['c_1'],
'c_alias': (await import('./c.module.css')).default['c_2'],
};
export default styles;
4 changes: 2 additions & 2 deletions examples/1-basic/generated/src/b.module.css.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-nocheck
declare const styles = {
b_1: '' as readonly string,
b_2: '' as readonly string,
'b_1': '' as readonly string,
'b_2': '' as readonly string,
};
export default styles;
4 changes: 2 additions & 2 deletions examples/1-basic/generated/src/c.module.css.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-nocheck
declare const styles = {
c_1: '' as readonly string,
c_2: '' as readonly string,
'c_1': '' as readonly string,
'c_2': '' as readonly string,
};
export default styles;
2 changes: 2 additions & 0 deletions examples/1-basic/src/a.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@
100% { transform: translateY(-100%); }
}

.a-1 {color: red;}

@import './b.module.css';
@value c_1, c_2 as c_alias from './c.module.css';
1 change: 1 addition & 0 deletions examples/1-basic/src/a.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ styles.b_1;
styles.b_2;
styles.c_1;
styles.c_alias;
styles['a-1'];
styles.unknown; // Expected TS2339 error

const jsx = (
Expand Down
12 changes: 6 additions & 6 deletions packages/codegen/e2e-test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ test('generates .d.ts', async () => {
"// @ts-nocheck
function blockErrorType<T>(val: T): [0] extends [(1 & T)] ? {} : T;
declare const styles = {
a1: '' as readonly string,
'a1': '' as readonly string,
...blockErrorType((await import('./b.module.css')).default),
...blockErrorType((await import('./unmatched.module.css')).default),
};
Expand All @@ -58,15 +58,15 @@ test('generates .d.ts', async () => {
expect(await iff.readFile('generated/src/b.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
b1: '' as readonly string,
'b1': '' as readonly string,
};
export default styles;
"
`);
expect(await iff.readFile('generated/src/c.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
c1: '' as readonly string,
'c1': '' as readonly string,
};
export default styles;
"
Expand Down Expand Up @@ -158,7 +158,7 @@ test('generates .d.ts with circular import', async () => {
"// @ts-nocheck
function blockErrorType<T>(val: T): [0] extends [(1 & T)] ? {} : T;
declare const styles = {
a1: '' as readonly string,
'a1': '' as readonly string,
...blockErrorType((await import('./b.module.css')).default),
};
export default styles;
Expand All @@ -168,7 +168,7 @@ test('generates .d.ts with circular import', async () => {
"// @ts-nocheck
function blockErrorType<T>(val: T): [0] extends [(1 & T)] ? {} : T;
declare const styles = {
b1: '' as readonly string,
'b1': '' as readonly string,
...blockErrorType((await import('./a.module.css')).default),
};
export default styles;
Expand All @@ -178,7 +178,7 @@ test('generates .d.ts with circular import', async () => {
"// @ts-nocheck
function blockErrorType<T>(val: T): [0] extends [(1 & T)] ? {} : T;
declare const styles = {
c1: '' as readonly string,
'c1': '' as readonly string,
...blockErrorType((await import('./c.module.css')).default),
};
export default styles;
Expand Down
8 changes: 4 additions & 4 deletions packages/codegen/src/project.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ describe('updateFile', () => {
expect(await iff.readFile('generated/src/a.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
a_1: '' as readonly string,
'a_1': '' as readonly string,
};
export default styles;
"
Expand Down Expand Up @@ -537,15 +537,15 @@ describe('emitDtsFiles', () => {
expect(await iff.readFile('generated/src/a.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
a1: '' as readonly string,
'a1': '' as readonly string,
};
export default styles;
"
`);
expect(await iff.readFile('generated/src/b.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
b1: '' as readonly string,
'b1': '' as readonly string,
};
export default styles;
"
Expand All @@ -562,7 +562,7 @@ describe('emitDtsFiles', () => {
expect(await iff.readFile('generated/src/a.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
a1: '' as readonly string,
'a1': '' as readonly string,
};
export default styles;
"
Expand Down
8 changes: 4 additions & 4 deletions packages/codegen/src/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ describe('runCMK', () => {
expect(await iff.readFile('generated/src/a.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
a_1: '' as readonly string,
'a_1': '' as readonly string,
};
export default styles;
"
`);
expect(await iff.readFile('generated/src/b.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
b_1: '' as readonly string,
'b_1': '' as readonly string,
};
export default styles;
"
Expand Down Expand Up @@ -133,15 +133,15 @@ describe('runCMKInWatchMode', () => {
expect(await iff.readFile('generated/src/a.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
a_1: '' as readonly string,
'a_1': '' as readonly string,
};
export default styles;
"
`);
expect(await iff.readFile('generated/src/b.module.css.d.ts')).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
b_1: '' as readonly string,
'b_1': '' as readonly string,
};
export default styles;
"
Expand Down
27 changes: 21 additions & 6 deletions packages/core/src/checker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function prepareChecker(args?: Partial<CheckerArgs>): Checker {
}

describe('checkCSSModule', () => {
test('report diagnostics for invalid name as js identifier', async () => {
test('do not report diagnostics for invalid name as js identifier when namedExports is false', async () => {
const iff = await createIFF({
'a.module.css': dedent`
.a-1 { color: red; }
Expand All @@ -47,7 +47,22 @@ describe('checkCSSModule', () => {
@value b-2: red;
`,
});
const check = prepareChecker();
const check = prepareChecker({ config: fakeConfig({ namedExports: false }) });
const diagnostics = check(readAndParseCSSModule(iff.paths['a.module.css'])!);
expect(diagnostics).toEqual([]);
});
test('report diagnostics for invalid name as js identifier when namedExports is true', async () => {
const iff = await createIFF({
'a.module.css': dedent`
.a-1 { color: red; }
@value b-1, b-2 as a-2 from './b.module.css';
`,
'b.module.css': dedent`
@value b-1: red;
@value b-2: red;
`,
});
const check = prepareChecker({ config: fakeConfig({ namedExports: true }) });
const diagnostics = check(readAndParseCSSModule(iff.paths['a.module.css'])!);
expect(formatDiagnostics(diagnostics, iff.rootDir)).toMatchInlineSnapshot(`
[
Expand All @@ -59,7 +74,7 @@ describe('checkCSSModule', () => {
"column": 2,
"line": 1,
},
"text": "css-modules-kit does not support invalid names as JavaScript identifiers.",
"text": "css-modules-kit does not support invalid names as JavaScript identifiers when \`cmkOptions.namedExports\` is set to \`true\`.",
},
{
"category": "error",
Expand All @@ -69,7 +84,7 @@ describe('checkCSSModule', () => {
"column": 8,
"line": 2,
},
"text": "css-modules-kit does not support invalid names as JavaScript identifiers.",
"text": "css-modules-kit does not support invalid names as JavaScript identifiers when \`cmkOptions.namedExports\` is set to \`true\`.",
},
{
"category": "error",
Expand All @@ -79,7 +94,7 @@ describe('checkCSSModule', () => {
"column": 13,
"line": 2,
},
"text": "css-modules-kit does not support invalid names as JavaScript identifiers.",
"text": "css-modules-kit does not support invalid names as JavaScript identifiers when \`cmkOptions.namedExports\` is set to \`true\`.",
},
{
"category": "error",
Expand All @@ -89,7 +104,7 @@ describe('checkCSSModule', () => {
"column": 20,
"line": 2,
},
"text": "css-modules-kit does not support invalid names as JavaScript identifiers.",
"text": "css-modules-kit does not support invalid names as JavaScript identifiers when \`cmkOptions.namedExports\` is set to \`true\`.",
},
]
`);
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function checkCSSModule(cssModule: CSSModule, args: CheckerArgs): Diagnos

for (const token of cssModule.localTokens) {
// Reject special names as they may break .d.ts files
if (!isValidAsJSIdentifier(token.name)) {
if (config.namedExports && !isValidAsJSIdentifier(token.name)) {
diagnostics.push(createInvalidNameAsJSIdentifiersDiagnostic(cssModule, token.loc));
}
if (token.name === '__proto__') {
Expand Down Expand Up @@ -54,10 +54,10 @@ export function checkCSSModule(cssModule: CSSModule, args: CheckerArgs): Diagnos
if (!exportRecord.allTokens.includes(value.name)) {
diagnostics.push(createModuleHasNoExportedTokenDiagnostic(cssModule, tokenImporter, value));
}
if (!isValidAsJSIdentifier(value.name)) {
if (config.namedExports && !isValidAsJSIdentifier(value.name)) {
diagnostics.push(createInvalidNameAsJSIdentifiersDiagnostic(cssModule, value.loc));
}
if (value.localName && !isValidAsJSIdentifier(value.localName)) {
if (value.localName && config.namedExports && !isValidAsJSIdentifier(value.localName)) {
diagnostics.push(createInvalidNameAsJSIdentifiersDiagnostic(cssModule, value.localLoc!));
}
if (value.name === '__proto__') {
Expand Down Expand Up @@ -106,7 +106,7 @@ function createModuleHasNoExportedTokenDiagnostic(

function createInvalidNameAsJSIdentifiersDiagnostic(cssModule: CSSModule, loc: Location): Diagnostic {
return {
text: `css-modules-kit does not support invalid names as JavaScript identifiers.`,
text: `css-modules-kit does not support invalid names as JavaScript identifiers when \`cmkOptions.namedExports\` is set to \`true\`.`,
category: 'error',
file: { fileName: cssModule.fileName, text: cssModule.text },
start: { line: loc.start.line, column: loc.start.column },
Expand Down
45 changes: 33 additions & 12 deletions packages/core/src/dts-generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ describe('generateDts', () => {
expect(generateDts(readAndParseCSSModule(iff.paths['test.module.css'])!, options).text).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
local1: '' as readonly string,
local2: '' as readonly string,
'local1': '' as readonly string,
'local2': '' as readonly string,
};
export default styles;
"
Expand All @@ -52,34 +52,37 @@ describe('generateDts', () => {
function blockErrorType<T>(val: T): [0] extends [(1 & T)] ? {} : T;
declare const styles = {
...blockErrorType((await import('./a.module.css')).default),
imported1: (await import('./b.module.css')).default.imported1,
aliasedImported2: (await import('./b.module.css')).default.imported2,
'imported1': (await import('./b.module.css')).default['imported1'],
'aliasedImported2': (await import('./b.module.css')).default['imported2'],
};
export default styles;
"
`);
});
test('does not generate types for URL token importers', async () => {
test('generates types for tokens with invalid JS identifier names', async () => {
const iff = await createIFF({
'test.module.css': dedent`
@import 'https://example.com/a.module.css';
@value imported1 from 'https://example.com/b.module.css';
.a-1 { color: red; }
@value b_1 from './b.module.css';
@value b_2 as a_2 from './b.module.css';
`,
});
expect(generateDts(readAndParseCSSModule(iff.paths['test.module.css'])!, options).text).toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
'a-1': '' as readonly string,
'b_1': (await import('./b.module.css')).default['b_1'],
'a_2': (await import('./b.module.css')).default['b_2'],
};
export default styles;
"
`);
});
test('does not generate types for invalid name as JS identifier', async () => {
test('does not generate types for URL token importers', async () => {
const iff = await createIFF({
'test.module.css': dedent`
.a-1 { color: red; }
@value b-1 from './b.module.css';
@value b_2 as a-2 from './b.module.css';
@import 'https://example.com/a.module.css';
@value imported1 from 'https://example.com/b.module.css';
`,
});
expect(generateDts(readAndParseCSSModule(iff.paths['test.module.css'])!, options).text).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -115,12 +118,30 @@ describe('generateDts', () => {
.toMatchInlineSnapshot(`
"// @ts-nocheck
declare const styles = {
default: '' as readonly string,
'default': '' as readonly string,
};
export default styles;
"
`);
});
test('does not generate types for invalid name as JS identifier when `namedExports` is true', async () => {
const iff = await createIFF({
'test.module.css': dedent`
.a-1 { color: red; }
@value b-1 from './b.module.css';
@value b_2 as a-2 from './b.module.css';
`,
});
expect(generateDts(readAndParseCSSModule(iff.paths['test.module.css'])!, { ...options, namedExports: true }).text)
.toMatchInlineSnapshot(`
"// @ts-nocheck
export {
} from './b.module.css';
export {
} from './b.module.css';
"
`);
});
test('generates d.ts file with named exports', async () => {
const iff = await createIFF({
'test.module.css': dedent`
Expand Down
Loading