Repository: seek-oss/css-modules-typescript-loader
Branch: master
Commit: bb4892a5cae1
Files: 35
Total size: 16.0 KB
Directory structure:
gitextract_rb2bm0ye/
├── .editorconfig
├── .gitignore
├── .npmrc
├── .nvmrc
├── .travis.yml
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
├── compiler.js
├── emit-declaration/
│ ├── .gitignore
│ ├── __snapshots__/
│ │ └── emit-declaration.test.js.snap
│ ├── common.css
│ ├── emit-declaration.test.js
│ ├── index.css
│ └── index.js
├── emit-empty-declaration/
│ ├── .gitignore
│ ├── __snapshots__/
│ │ └── emit-empty-declaration.test.js.snap
│ ├── emit-empty-declaration.test.js
│ ├── index.css
│ └── index.js
├── getErrorMessage.js
├── verify-invalid-declaration/
│ ├── __snapshots__/
│ │ └── verify-invalid-declaration.test.js.snap
│ ├── index.css
│ ├── index.css.d.ts
│ ├── index.js
│ └── verify-invalid-declaration.test.js
├── verify-missing-declaration/
│ ├── __snapshots__/
│ │ └── verify-missing-declaration.test.js.snap
│ ├── index.css
│ ├── index.js
│ └── verify-missing-declaration.test.js
└── verify-valid-declaration/
├── index.css
├── index.css.d.ts
├── index.js
└── verify-valid-declaration.test.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .gitignore
================================================
node_modules/
*.log
yarn.lock
package-lock.json
================================================
FILE: .npmrc
================================================
package-lock=false
================================================
FILE: .nvmrc
================================================
lts/*
================================================
FILE: .travis.yml
================================================
language: node_js
cache:
directories:
- node_modules
notifications:
email: false
before_script:
- npm prune
script:
- npm test
after_success:
- npm run travis-deploy-once "npm run semantic-release"
branches:
except:
- /^v\d+\.\d+\.\d+$/
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 SEEK
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
[](http://travis-ci.org/seek-oss/css-modules-typescript-loader) [](https://www.npmjs.com/package/css-modules-typescript-loader) [](https://github.com/semantic-release/semantic-release) [](http://commitizen.github.io/cz-cli/)
# css-modules-typescript-loader
[Webpack](https://webpack.js.org/) loader to create [TypeScript](https://www.typescriptlang.org/) declarations for [CSS Modules](https://github.com/css-modules/css-modules).
Emits TypeScript declaration files matching your CSS Modules in the same location as your source files, e.g. `src/Component.css` will generate `src/Component.css.d.ts`.
## Why?
There are currently a lot of [solutions to this problem](https://www.npmjs.com/search?q=css%20modules%20typescript%20loader). However, this package differs in the following ways:
- Encourages generated TypeScript declarations to be checked into source control, which allows `webpack` and `tsc` commands to be run in parallel in CI.
- Ensures committed TypeScript declarations are in sync with the code that generated them via the [`verify` mode](#verify-mode).
## Usage
Place `css-modules-typescript-loader` directly after `css-loader` in your webpack config.
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'css-modules-typescript-loader',
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
};
```
### Verify Mode
Since the TypeScript declarations are generated by `webpack`, they may potentially be out of date by the time you run `tsc`. To ensure your types are up to date, you can run the loader in `verify` mode, which is particularly useful in CI.
For example:
```js
{
loader: 'css-modules-typescript-loader',
options: {
mode: process.env.CI ? 'verify' : 'emit'
}
}
```
Instead of emitting new TypeScript declarations, this will throw an error if a generated declaration doesn't match the committed one. This allows `tsc` and `webpack` to run in parallel in CI, if desired.
This workflow is similar to using the [Prettier](https://github.com/prettier/prettier) [`--list-different` option](https://prettier.io/docs/en/cli.html#list-different).
## With Thanks
This package borrows heavily from [typings-for-css-modules-loader](https://github.com/Jimdo/typings-for-css-modules-loader).
## License
MIT.
================================================
FILE: index.js
================================================
const fs = require('fs');
const path = require('path');
const loaderUtils = require('loader-utils');
const LineDiff = require('line-diff');
const bannerMessage =
'// This file is automatically generated.\n// Please do not change this file!';
const cssModuleExport = 'export const cssExports: CssExports;\nexport default cssExports;\n';
const getNoDeclarationFileError = ({ filename }) =>
new Error(
`Generated type declaration does not exist. Run webpack and commit the type declaration for '${filename}'`
);
const getTypeMismatchError = ({ filename, expected, actual }) => {
const diff = new LineDiff(enforceLFLineSeparators(actual), expected).toString();
return new Error(
`Generated type declaration file is outdated. Run webpack and commit the updated type declaration for '${filename}'\n\n${diff}`
);
};
const cssModuleToInterface = (cssModuleKeys) => {
const interfaceFields = cssModuleKeys
.sort()
.map(key => ` '${key}': string;`)
.join('\n');
return `interface CssExports {\n${interfaceFields}\n}`;
};
const filenameToTypingsFilename = filename => {
const dirName = path.dirname(filename);
const baseName = path.basename(filename);
return path.join(dirName, `${baseName}.d.ts`);
};
const enforceLFLineSeparators = text => {
if (text) {
// replace all CRLFs (Windows) by LFs (Unix)
return text.replace(/\r\n/g, "\n");
} else {
return text;
}
};
const compareText = (contentA, contentB) => {
return enforceLFLineSeparators(contentA) === enforceLFLineSeparators(contentB);
};
const validModes = ['emit', 'verify'];
const isFileNotFound = err => err && err.code === 'ENOENT';
const makeDoneHandlers = (callback, content, rest) => ({
failed: e => callback(e),
success: () => callback(null, content, ...rest)
});
const makeFileHandlers = filename => ({
read: handler => fs.readFile(filename, { encoding: 'utf-8' }, handler),
write: (content, handler) =>
fs.writeFile(filename, content, { encoding: 'utf-8' }, handler)
});
const extractLocalExports = (content) => {
let localExports = content.split('exports.locals')[1];
if (!localExports) {
localExports = content.split('___CSS_LOADER_EXPORT___.locals')[1];
}
return localExports;
}
module.exports = function(content, ...rest) {
const { failed, success } = makeDoneHandlers(this.async(), content, rest);
const filename = this.resourcePath;
const { mode = 'emit' } = loaderUtils.getOptions(this) || {};
if (!validModes.includes(mode)) {
return failed(new Error(`Invalid mode option: ${mode}`));
}
const cssModuleInterfaceFilename = filenameToTypingsFilename(filename);
const { read, write } = makeFileHandlers(cssModuleInterfaceFilename);
const keyRegex = /"([^\\"]+)":/g;
let match;
const cssModuleKeys = [];
const localExports = extractLocalExports(content);
while ((match = keyRegex.exec(localExports))) {
if (cssModuleKeys.indexOf(match[1]) < 0) {
cssModuleKeys.push(match[1]);
}
}
const cssModuleDefinition = `${bannerMessage}\n${cssModuleToInterface(cssModuleKeys)}\n${cssModuleExport}`;
if (mode === 'verify') {
read((err, fileContents) => {
if (isFileNotFound(err)) {
return failed(
getNoDeclarationFileError({
filename: cssModuleInterfaceFilename
})
);
}
if (err) {
return failed(err);
}
if (!compareText(cssModuleDefinition, fileContents)) {
return failed(
getTypeMismatchError({
filename: cssModuleInterfaceFilename,
expected: cssModuleDefinition,
actual: fileContents
})
);
}
return success();
});
} else {
read((_, fileContents) => {
if (!compareText(cssModuleDefinition, fileContents)) {
write(cssModuleDefinition, err => {
if (err) {
failed(err);
} else {
success();
}
});
} else {
success();
}
});
}
};
================================================
FILE: package.json
================================================
{
"name": "css-modules-typescript-loader",
"version": "0.0.0-development",
"description": "Webpack loader to create TypeScript declarations for CSS Modules",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/seek-oss/css-modules-typescript-loader.git"
},
"author": "SEEK",
"license": "MIT",
"bugs": {
"url": "https://github.com/seek-oss/css-modules-typescript-loader/issues"
},
"scripts": {
"commit": "git-cz",
"travis-deploy-once": "travis-deploy-once",
"semantic-release": "semantic-release",
"test": "jest"
},
"jest": {
"testEnvironment": "node"
},
"husky": {
"hooks": {
"commit-msg": "commitlint --edit --extends seek"
}
},
"homepage": "https://github.com/seek-oss/css-modules-typescript-loader#readme",
"dependencies": {
"line-diff": "^2.0.1",
"loader-utils": "^1.2.3"
},
"devDependencies": {
"@commitlint/cli": "^7.2.1",
"commitizen": "^3.0.2",
"commitlint-config-seek": "^1.0.0",
"css-loader": "^4.2.1",
"cz-conventional-changelog": "^2.1.0",
"husky": "^1.1.2",
"jest": "^24.7.1",
"memory-fs": "^0.4.1",
"semantic-release": "^15.9.17",
"travis-deploy-once": "^5.0.9",
"webpack": "^4.21.0"
},
"release": {
"success": false
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
================================================
FILE: test/compiler.js
================================================
const path = require('path');
const webpack = require('webpack');
const memoryfs = require('memory-fs');
module.exports = (entry, options = {}) => {
const { sourceMap, ...loaderOptions } = options;
const compiler = webpack({
context: path.dirname(entry),
entry,
output: {
path: path.dirname(entry),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: require.resolve('../index.js'),
options: loaderOptions
},
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: !!sourceMap
}
}
]
}
]
}
});
compiler.outputFileSystem = new memoryfs();
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err || stats.hasErrors()) {
reject({
failed: true,
errors: err || stats.toJson().errors
});
}
resolve(stats);
});
});
};
================================================
FILE: test/emit-declaration/.gitignore
================================================
index.css.d.ts
================================================
FILE: test/emit-declaration/__snapshots__/emit-declaration.test.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Can emit valid declaration with sourceMap 1`] = `
"// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'composedClass': string;
'otherClass': string;
'someClass': string;
'validClass': string;
}
export const cssExports: CssExports;
export default cssExports;
"
`;
exports[`Can emit valid declaration without sourceMaps 1`] = `
"// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'composedClass': string;
'otherClass': string;
'someClass': string;
'validClass': string;
}
export const cssExports: CssExports;
export default cssExports;
"
`;
================================================
FILE: test/emit-declaration/common.css
================================================
.baseClass {
position: relative;
}
================================================
FILE: test/emit-declaration/emit-declaration.test.js
================================================
const fs = require('fs');
const compiler = require('../compiler.js');
test('Can emit valid declaration without sourceMaps', async () => {
await compiler(require.resolve('./index.js'));
const declaration = fs.readFileSync(
require.resolve('./index.css.d.ts'),
'utf-8'
);
expect(declaration).toMatchSnapshot();
});
test('Can emit valid declaration with sourceMap', async () => {
await compiler(require.resolve('./index.js'), { sourceMap: true });
const declaration = fs.readFileSync(
require.resolve('./index.css.d.ts'),
'utf-8'
);
expect(declaration).toMatchSnapshot();
});
================================================
FILE: test/emit-declaration/index.css
================================================
.validClass {
position: relative;
}
.someClass {
position: relative;
}
.otherClass {
display: block;
}
.composedClass {
composes: baseClass from './common.css';
color: cornflowerblue;
}
================================================
FILE: test/emit-declaration/index.js
================================================
import styles from './index.css';
================================================
FILE: test/emit-empty-declaration/.gitignore
================================================
index.css.d.ts
================================================
FILE: test/emit-empty-declaration/__snapshots__/emit-empty-declaration.test.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Can emit valid declaration without classes 1`] = `
"// This file is automatically generated.
// Please do not change this file!
interface CssExports {
}
export const cssExports: CssExports;
export default cssExports;
"
`;
================================================
FILE: test/emit-empty-declaration/emit-empty-declaration.test.js
================================================
const fs = require('fs');
const compiler = require('../compiler.js');
test('Can emit valid declaration without classes', async () => {
await compiler(require.resolve('./index.js'));
const declaration = fs.readFileSync(
require.resolve('./index.css.d.ts'),
'utf-8'
);
expect(declaration).toMatchSnapshot();
});
================================================
FILE: test/emit-empty-declaration/index.css
================================================
html {
/* No class selectors in this file ... */
}
================================================
FILE: test/emit-empty-declaration/index.js
================================================
import "./index.css";
================================================
FILE: test/getErrorMessage.js
================================================
module.exports = error => error
.split(process.cwd())
.join('')
.match(/(Error: .*?)\s{4}at /s)[1];
================================================
FILE: test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Can error on invalid declaration 1`] = `
"Error: Generated type declaration file is outdated. Run webpack and commit the updated type declaration for '/test/verify-invalid-declaration/index.css.d.ts'
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'classInBothFiles': string;
- 'classInTypeScriptFile': string;
+ 'classInCssFile': string;
}
export const cssExports: CssExports;
export default cssExports;
"
`;
================================================
FILE: test/verify-invalid-declaration/index.css
================================================
.classInBothFiles {
position: relative;
}
.classInCssFile {
display: block;
}
================================================
FILE: test/verify-invalid-declaration/index.css.d.ts
================================================
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'classInBothFiles': string;
'classInTypeScriptFile': string;
}
export const cssExports: CssExports;
export default cssExports;
================================================
FILE: test/verify-invalid-declaration/index.js
================================================
import styles from './index.css';
================================================
FILE: test/verify-invalid-declaration/verify-invalid-declaration.test.js
================================================
const compiler = require('../compiler.js');
const getErrorMessage = require('../getErrorMessage');
test('Can error on invalid declaration', async () => {
expect.assertions(1);
try {
await compiler(require.resolve('./index.js'), {
mode: 'verify'
});
} catch (err) {
// make test robust for Windows by replacing backslashes in the file path with slashes
let errorMessage = getErrorMessage(err.errors[0]).replace(/(?<=Error:.*)\\/g, "/");
expect(errorMessage).toMatchSnapshot();
}
});
================================================
FILE: test/verify-missing-declaration/__snapshots__/verify-missing-declaration.test.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Can error on invalid declaration 1`] = `
"Error: Generated type declaration does not exist. Run webpack and commit the type declaration for '/test/verify-missing-declaration/index.css.d.ts'
"
`;
================================================
FILE: test/verify-missing-declaration/index.css
================================================
.someClass {
position: relative;
}
.otherClass {
display: block;
}
================================================
FILE: test/verify-missing-declaration/index.js
================================================
import styles from './index.css';
================================================
FILE: test/verify-missing-declaration/verify-missing-declaration.test.js
================================================
const compiler = require('../compiler.js');
const getErrorMessage = require('../getErrorMessage');
test('Can error on invalid declaration', async () => {
expect.assertions(1);
try {
await compiler(require.resolve('./index.js'), {
mode: 'verify'
});
} catch (err) {
// make test robust for Windows by replacing backslashes in the file path with slashes
let errorMessage = getErrorMessage(err.errors[0]).replace(/(?<=Error:.*)\\/g, "/");
expect(errorMessage).toMatchSnapshot();
}
});
================================================
FILE: test/verify-valid-declaration/index.css
================================================
.validClass {
position: relative;
}
.someClass {
position: relative;
}
.otherClass {
display: block;
}
.hyphened-classname,
.underscored_classname {
color: papayawhip;
}
================================================
FILE: test/verify-valid-declaration/index.css.d.ts
================================================
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'hyphened-classname': string;
'otherClass': string;
'someClass': string;
'underscored_classname': string;
'validClass': string;
}
export const cssExports: CssExports;
export default cssExports;
================================================
FILE: test/verify-valid-declaration/index.js
================================================
import styles from './index.css';
================================================
FILE: test/verify-valid-declaration/verify-valid-declaration.test.js
================================================
const compiler = require('../compiler.js');
test('Can verify valid declaration', async () => {
// just validate webpack build passes
await compiler(require.resolve('./index.js'), {
mode: 'verify'
});
});
gitextract_rb2bm0ye/
├── .editorconfig
├── .gitignore
├── .npmrc
├── .nvmrc
├── .travis.yml
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
├── compiler.js
├── emit-declaration/
│ ├── .gitignore
│ ├── __snapshots__/
│ │ └── emit-declaration.test.js.snap
│ ├── common.css
│ ├── emit-declaration.test.js
│ ├── index.css
│ └── index.js
├── emit-empty-declaration/
│ ├── .gitignore
│ ├── __snapshots__/
│ │ └── emit-empty-declaration.test.js.snap
│ ├── emit-empty-declaration.test.js
│ ├── index.css
│ └── index.js
├── getErrorMessage.js
├── verify-invalid-declaration/
│ ├── __snapshots__/
│ │ └── verify-invalid-declaration.test.js.snap
│ ├── index.css
│ ├── index.css.d.ts
│ ├── index.js
│ └── verify-invalid-declaration.test.js
├── verify-missing-declaration/
│ ├── __snapshots__/
│ │ └── verify-missing-declaration.test.js.snap
│ ├── index.css
│ ├── index.js
│ └── verify-missing-declaration.test.js
└── verify-valid-declaration/
├── index.css
├── index.css.d.ts
├── index.js
└── verify-valid-declaration.test.js
SYMBOL INDEX (2 symbols across 2 files)
FILE: test/verify-invalid-declaration/index.css.d.ts
type CssExports (line 3) | interface CssExports {
FILE: test/verify-valid-declaration/index.css.d.ts
type CssExports (line 3) | interface CssExports {
Condensed preview — 35 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (19K chars).
[
{
"path": ".editorconfig",
"chars": 207,
"preview": "# editorconfig.org\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_"
},
{
"path": ".gitignore",
"chars": 48,
"preview": "node_modules/\n*.log\nyarn.lock\npackage-lock.json\n"
},
{
"path": ".npmrc",
"chars": 19,
"preview": "package-lock=false\n"
},
{
"path": ".nvmrc",
"chars": 6,
"preview": "lts/*\n"
},
{
"path": ".travis.yml",
"chars": 257,
"preview": "language: node_js\ncache:\n directories:\n - node_modules\nnotifications:\n email: false\nbefore_script:\n - npm prune\nsc"
},
{
"path": "LICENSE",
"chars": 1061,
"preview": "MIT License\n\nCopyright (c) 2018 SEEK\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof th"
},
{
"path": "README.md",
"chars": 2837,
"preview": "[](htt"
},
{
"path": "index.js",
"chars": 4018,
"preview": "const fs = require('fs');\nconst path = require('path');\nconst loaderUtils = require('loader-utils');\nconst LineDiff = re"
},
{
"path": "package.json",
"chars": 1411,
"preview": "{\n \"name\": \"css-modules-typescript-loader\",\n \"version\": \"0.0.0-development\",\n \"description\": \"Webpack loader to creat"
},
{
"path": "test/compiler.js",
"chars": 1089,
"preview": "const path = require('path');\nconst webpack = require('webpack');\nconst memoryfs = require('memory-fs');\n\nmodule.exports"
},
{
"path": "test/emit-declaration/.gitignore",
"chars": 15,
"preview": "index.css.d.ts\n"
},
{
"path": "test/emit-declaration/__snapshots__/emit-declaration.test.js.snap",
"chars": 705,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Can emit valid declaration with sourceMap 1`] = `\n\"// This file is "
},
{
"path": "test/emit-declaration/common.css",
"chars": 37,
"preview": ".baseClass {\n position: relative;\n}\n"
},
{
"path": "test/emit-declaration/emit-declaration.test.js",
"chars": 612,
"preview": "const fs = require('fs');\nconst compiler = require('../compiler.js');\n\ntest('Can emit valid declaration without sourceMa"
},
{
"path": "test/emit-declaration/index.css",
"chars": 199,
"preview": ".validClass {\n position: relative;\n}\n\n.someClass {\n position: relative;\n}\n\n.otherClass {\n display: block;\n}\n\n.compose"
},
{
"path": "test/emit-declaration/index.js",
"chars": 34,
"preview": "import styles from './index.css';\n"
},
{
"path": "test/emit-empty-declaration/.gitignore",
"chars": 15,
"preview": "index.css.d.ts\n"
},
{
"path": "test/emit-empty-declaration/__snapshots__/emit-empty-declaration.test.js.snap",
"chars": 276,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Can emit valid declaration without classes 1`] = `\n\"// This file is"
},
{
"path": "test/emit-empty-declaration/emit-empty-declaration.test.js",
"chars": 331,
"preview": "const fs = require('fs');\nconst compiler = require('../compiler.js');\n\ntest('Can emit valid declaration without classes'"
},
{
"path": "test/emit-empty-declaration/index.css",
"chars": 53,
"preview": "html {\n /* No class selectors in this file ... */\n}\n"
},
{
"path": "test/emit-empty-declaration/index.js",
"chars": 22,
"preview": "import \"./index.css\";\n"
},
{
"path": "test/getErrorMessage.js",
"chars": 106,
"preview": "module.exports = error => error\n .split(process.cwd())\n .join('')\n .match(/(Error: .*?)\\s{4}at /s)[1];\n"
},
{
"path": "test/verify-invalid-declaration/__snapshots__/verify-invalid-declaration.test.js.snap",
"chars": 549,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Can error on invalid declaration 1`] = `\n\"Error: Generated type dec"
},
{
"path": "test/verify-invalid-declaration/index.css",
"chars": 83,
"preview": ".classInBothFiles {\n position: relative;\n}\n\n.classInCssFile {\n display: block;\n}\n"
},
{
"path": "test/verify-invalid-declaration/index.css.d.ts",
"chars": 230,
"preview": "// This file is automatically generated.\n// Please do not change this file!\ninterface CssExports {\n 'classInBothFiles':"
},
{
"path": "test/verify-invalid-declaration/index.js",
"chars": 34,
"preview": "import styles from './index.css';\n"
},
{
"path": "test/verify-invalid-declaration/verify-invalid-declaration.test.js",
"chars": 519,
"preview": "const compiler = require('../compiler.js');\nconst getErrorMessage = require('../getErrorMessage');\n\ntest('Can error on i"
},
{
"path": "test/verify-missing-declaration/__snapshots__/verify-missing-declaration.test.js.snap",
"chars": 248,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Can error on invalid declaration 1`] = `\n\"Error: Generated type dec"
},
{
"path": "test/verify-missing-declaration/index.css",
"chars": 72,
"preview": ".someClass {\n position: relative;\n}\n\n.otherClass {\n display: block;\n}\n"
},
{
"path": "test/verify-missing-declaration/index.js",
"chars": 34,
"preview": "import styles from './index.css';\n"
},
{
"path": "test/verify-missing-declaration/verify-missing-declaration.test.js",
"chars": 519,
"preview": "const compiler = require('../compiler.js');\nconst getErrorMessage = require('../getErrorMessage');\n\ntest('Can error on i"
},
{
"path": "test/verify-valid-declaration/index.css",
"chars": 181,
"preview": ".validClass {\n position: relative;\n}\n\n.someClass {\n position: relative;\n}\n\n.otherClass {\n display: block;\n}\n\n.hyphene"
},
{
"path": "test/verify-valid-declaration/index.css.d.ts",
"chars": 303,
"preview": "// This file is automatically generated.\n// Please do not change this file!\ninterface CssExports {\n 'hyphened-classname"
},
{
"path": "test/verify-valid-declaration/index.js",
"chars": 34,
"preview": "import styles from './index.css';\n"
},
{
"path": "test/verify-valid-declaration/verify-valid-declaration.test.js",
"chars": 215,
"preview": "const compiler = require('../compiler.js');\n\ntest('Can verify valid declaration', async () => {\n // just validate webpa"
}
]
About this extraction
This page contains the full source code of the seek-oss/css-modules-typescript-loader GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 35 files (16.0 KB), approximately 5.1k tokens, and a symbol index with 2 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.