Skip to content

Commit 86efbdc

Browse files
authored
Merge pull request #67 from gdelmas/typescriptify
Make src TypeScript
2 parents fe0c6aa + 0112336 commit 86efbdc

File tree

10 files changed

+370
-1218
lines changed

10 files changed

+370
-1218
lines changed

.babelrc

Lines changed: 0 additions & 13 deletions
This file was deleted.

index.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

package.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
"name": "typed-css-modules",
33
"version": "0.4.2",
44
"description": "Creates .d.ts files from CSS Modules .css files",
5-
"main": "index.js",
5+
"main": "lib/index.js",
6+
"types": "lib/index.d.ts",
67
"scripts": {
7-
"build": "babel -d lib src",
8+
"build": "tsc && chmod +x lib/cli.js",
89
"test": "jest",
910
"test:watch": "jest --watch",
1011
"test:ci": "jest --coverage",
@@ -24,7 +25,7 @@
2425
"author": "quramy",
2526
"license": "MIT",
2627
"dependencies": {
27-
"camelcase": "^4.1.0",
28+
"camelcase": "^5.3.1",
2829
"chalk": "^2.1.0",
2930
"chokidar": "^2.1.2",
3031
"css-modules-loader-core": "^1.1.0",
@@ -34,12 +35,13 @@
3435
"yargs": "^8.0.2"
3536
},
3637
"devDependencies": {
37-
"babel-cli": "^6.26.0",
38-
"babel-core": "^6.26.0",
39-
"babel-env": "^2.4.1",
40-
"babel-jest": "^22.4.3",
38+
"@types/css-modules-loader-core": "^1.1.0",
39+
"@types/glob": "^7.1.1",
40+
"@types/mkdirp": "^0.5.1",
41+
"@types/node": "^12.0.3",
42+
"@types/yargs": "^8.0.2",
4143
"jest": "^23.6.0",
42-
"regenerator-runtime": "^0.11.1"
44+
"typescript": "^3.5.1"
4345
},
4446
"jest": {
4547
"transform": {}

src/cli.js renamed to src/cli.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,38 @@
11
#!/usr/bin/env node
22

3-
import path from 'path';
4-
import chokidar from 'chokidar';
3+
import * as path from 'path';
4+
import * as chokidar from 'chokidar';
55
import glob from 'glob';
6-
import yargs from 'yargs';
6+
import * as yargs from 'yargs';
77
import chalk from 'chalk';
88
import {DtsCreator} from './dtsCreator';
99

1010
let yarg = yargs.usage('Create .css.d.ts from CSS modules *.css files.\nUsage: $0 [options] <input directory>')
11-
.example('$0 src/styles')
12-
.example('$0 src -o dist')
13-
.example('$0 -p styles/**/*.icss -w')
11+
.example('$0 src/styles', '')
12+
.example('$0 src -o dist', '')
13+
.example('$0 -p styles/**/*.icss -w', '')
1414
.detectLocale(false)
1515
.demand(['_'])
1616
.alias('c', 'camelCase').describe('c', 'Convert CSS class tokens to camelcase')
1717
.alias('o', 'outDir').describe('o', 'Output directory')
1818
.alias('p', 'pattern').describe('p', 'Glob pattern with css files')
1919
.alias('w', 'watch').describe('w', 'Watch input directory\'s css files or pattern').boolean('w')
2020
.alias('d', 'dropExtension').describe('d', 'Drop the input files extension').boolean('d')
21-
.alias('s', 'silent').describe('s', 'Silent output. Do not show "files written" or warning messages').boolean('s')
21+
.alias('s', 'silent').describe('s', 'Silent output. Do not show "files written" messages').boolean('s')
2222
.alias('h', 'help').help('h')
23-
.version(() => require('../package.json').version)
23+
.version(() => require('../package.json').version);
2424
let argv = yarg.argv;
25-
let creator;
25+
let creator: DtsCreator;
2626

27-
function writeFile(f) {
28-
creator.create(f, null, !!argv.w)
27+
function writeFile(f: string) {
28+
creator.create(f, undefined, !!argv.w)
2929
.then(content => content.writeFile())
3030
.then(content => {
3131
if (!argv.s) {
3232
console.log('Wrote ' + chalk.green(content.outputFilePath));
33-
if (content.messageList && content.messageList.length) {
34-
content.messageList.forEach(message => {
35-
console.warn(chalk.yellow('[Warn] ' + message));
36-
});
37-
}
3833
}
3934
})
40-
.catch(reason => console.error(chalk.red('[Error] ' + reason)));
35+
.catch((reason: unknown) => console.error(chalk.red('[Error] ' + reason)));
4136
};
4237

4338
let main = () => {
@@ -66,7 +61,7 @@ let main = () => {
6661
});
6762

6863
if(!argv.w) {
69-
glob(filesPattern, null, (err, files) => {
64+
glob(filesPattern, {}, (err, files) => {
7065
if(err) {
7166
console.error(err);
7267
return;

src/dtsCreator.js renamed to src/dtsCreator.ts

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,56 @@
1-
'use strict';
2-
3-
import process from 'process';
4-
import fs from 'fs';
5-
import path from'path';
1+
import * as process from 'process';
2+
import * as fs from 'fs';
3+
import * as path from'path';
64

75
import isThere from 'is-there';
8-
import mkdirp from 'mkdirp';
6+
import * as mkdirp from 'mkdirp';
97
import camelcase from "camelcase"
108

119
import FileSystemLoader from './fileSystemLoader';
12-
import os from 'os';
10+
import * as os from 'os';
1311

14-
function removeExtension(filePath) {
12+
function removeExtension(filePath: string): string {
1513
const ext = path.extname(filePath);
1614
return filePath.replace(new RegExp(ext + '$'), '');
1715
}
1816

17+
interface DtsContentOptions {
18+
dropExtension: boolean;
19+
rootDir: string;
20+
searchDir: string;
21+
outDir: string;
22+
rInputPath: string;
23+
rawTokenList: string[];
24+
resultList: string[];
25+
EOL: string;
26+
}
27+
1928
class DtsContent {
20-
constructor({
21-
dropExtension,
22-
rootDir,
23-
searchDir,
24-
outDir,
25-
rInputPath,
26-
rawTokenList,
27-
resultList,
28-
EOL
29-
}) {
30-
this.dropExtension = dropExtension;
31-
this.rootDir = rootDir;
32-
this.searchDir = searchDir;
33-
this.outDir = outDir;
34-
this.rInputPath = rInputPath;
35-
this.rawTokenList = rawTokenList;
36-
this.resultList = resultList;
37-
this.EOL = EOL;
29+
private dropExtension: boolean;
30+
private rootDir: string;
31+
private searchDir: string;
32+
private outDir: string;
33+
private rInputPath: string;
34+
private rawTokenList: string[];
35+
private resultList: string[];
36+
private EOL: string;
37+
38+
constructor(options: DtsContentOptions) {
39+
this.dropExtension = options.dropExtension;
40+
this.rootDir = options.rootDir;
41+
this.searchDir = options.searchDir;
42+
this.outDir = options.outDir;
43+
this.rInputPath = options.rInputPath;
44+
this.rawTokenList = options.rawTokenList;
45+
this.resultList = options.resultList;
46+
this.EOL = options.EOL;
3847
}
3948

40-
get contents() {
49+
public get contents(): string[] {
4150
return this.resultList;
4251
}
4352

44-
get formatted() {
53+
public get formatted(): string {
4554
if(!this.resultList || !this.resultList.length) return '';
4655
return [
4756
'declare const styles: {',
@@ -52,20 +61,20 @@ class DtsContent {
5261
].join(os.EOL) + this.EOL;
5362
}
5463

55-
get tokens() {
64+
public get tokens(): string[] {
5665
return this.rawTokenList;
5766
}
5867

59-
get outputFilePath() {
68+
public get outputFilePath(): string {
6069
const outputFileName = this.dropExtension ? removeExtension(this.rInputPath) : this.rInputPath;
6170
return path.join(this.rootDir, this.outDir, outputFileName + '.d.ts');
6271
}
6372

64-
get inputFilePath() {
73+
public get inputFilePath(): string {
6574
return path.join(this.rootDir, this.searchDir, this.rInputPath);
6675
}
6776

68-
writeFile() {
77+
public writeFile(): Promise<DtsContent> {
6978
var outPathDir = path.dirname(this.outputFilePath);
7079
if(!isThere(outPathDir)) {
7180
mkdirp.sync(outPathDir);
@@ -82,8 +91,29 @@ class DtsContent {
8291
}
8392
}
8493

94+
type CamelCaseOption = boolean | 'dashes' | undefined;
95+
96+
interface DtsCreatorOptions {
97+
rootDir?: string;
98+
searchDir?: string;
99+
outDir?: string;
100+
camelCase?: CamelCaseOption;
101+
dropExtension?: boolean;
102+
EOL?: string;
103+
}
104+
85105
export class DtsCreator {
86-
constructor(options) {
106+
private rootDir: string;
107+
private searchDir: string;
108+
private outDir: string;
109+
private loader: FileSystemLoader;
110+
private inputDirectory: string;
111+
private outputDirectory: string;
112+
private camelCase: boolean | 'dashes' | undefined;
113+
private dropExtension: boolean;
114+
private EOL: string;
115+
116+
constructor(options?: DtsCreatorOptions) {
87117
if(!options) options = {};
88118
this.rootDir = options.rootDir || process.cwd();
89119
this.searchDir = options.searchDir || '';
@@ -96,9 +126,9 @@ export class DtsCreator {
96126
this.EOL = options.EOL || os.EOL;
97127
}
98128

99-
create(filePath, initialContents, clearCache = false) {
129+
create(filePath: string, initialContents?: string, clearCache: boolean = false): Promise<DtsContent> {
100130
return new Promise((resolve, reject) => {
101-
var rInputPath;
131+
let rInputPath: string;
102132
if(path.isAbsolute(filePath)) {
103133
rInputPath = path.relative(this.inputDirectory, filePath);
104134
}else{
@@ -107,7 +137,7 @@ export class DtsCreator {
107137
if(clearCache) {
108138
this.loader.tokensByFile = {};
109139
}
110-
this.loader.fetch(filePath, "/", undefined, initialContents).then(res => {
140+
this.loader.fetch(filePath, "/", undefined, initialContents).then((res) => {
111141
if(res) {
112142
var tokens = res;
113143
var keys = Object.keys(tokens);
@@ -137,7 +167,7 @@ export class DtsCreator {
137167
});
138168
}
139169

140-
getConvertKeyMethod(camelCaseOption) {
170+
private getConvertKeyMethod(camelCaseOption: CamelCaseOption): (str: string) => string {
141171
switch (camelCaseOption) {
142172
case true:
143173
return camelcase;
@@ -154,7 +184,7 @@ export class DtsCreator {
154184
* Mirrors the behaviour of the css-loader:
155185
* https://github.com/webpack-contrib/css-loader/blob/1fee60147b9dba9480c9385e0f4e581928ab9af9/lib/compile-exports.js#L3-L7
156186
*/
157-
dashesCamelCase(str) {
187+
private dashesCamelCase(str: string): string {
158188
return str.replace(/-+(\w)/g, function(match, firstLetter) {
159189
return firstLetter.toUpperCase();
160190
});

src/fileSystemLoader.js renamed to src/fileSystemLoader.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
/* this file is forked from https://raw.githubusercontent.com/css-modules/css-modules-loader-core/master/src/file-system-loader.js */
22

33
import Core from 'css-modules-loader-core'
4-
import fs from 'fs'
5-
import path from 'path'
4+
import * as fs from 'fs'
5+
import * as path from 'path'
6+
import { Plugin } from "postcss";
67

78
// Sorts dependencies in the following way:
89
// AAA comes before AA and A
@@ -11,7 +12,7 @@ import path from 'path'
1112
// This ensures that the files are always returned in the following order:
1213
// - In the order they were required, except
1314
// - After all their dependencies
14-
const traceKeySorter = ( a, b ) => {
15+
const traceKeySorter = ( a: string, b: string ): number => {
1516
if ( a.length < b.length ) {
1617
return a < b.substring( 0, a.length ) ? -1 : 1
1718
} else if ( a.length > b.length ) {
@@ -21,16 +22,26 @@ const traceKeySorter = ( a, b ) => {
2122
}
2223
};
2324

25+
export type Dictionary<T> = {
26+
[key: string]: T | undefined;
27+
};
28+
2429
export default class FileSystemLoader {
25-
constructor( root, plugins ) {
30+
private root: string;
31+
private sources: Dictionary<string>;
32+
private importNr: number;
33+
private core: Core;
34+
public tokensByFile: Dictionary<Core.ExportTokens>;
35+
36+
constructor( root: string, plugins?: Array<Plugin<any>> ) {
2637
this.root = root
2738
this.sources = {}
2839
this.importNr = 0
2940
this.core = new Core(plugins)
3041
this.tokensByFile = {};
3142
}
3243

33-
fetch( _newPath, relativeTo, _trace, initialContents ) {
44+
public fetch( _newPath: string, relativeTo: string, _trace?: string, initialContents?: string ): Promise<Core.ExportTokens> {
3445
let newPath = _newPath.replace( /^["']|["']$/g, "" ),
3546
trace = _trace || String.fromCharCode( this.importNr++ )
3647
return new Promise( ( resolve, reject ) => {
@@ -52,7 +63,7 @@ export default class FileSystemLoader {
5263

5364
fs.readFile( fileRelativePath, "utf-8", ( err, source ) => {
5465
if ( err && relativeTo && relativeTo !== '/') {
55-
resolve([]);
66+
resolve({});
5667
}else if ( err && (!relativeTo || relativeTo === '/')) {
5768
reject(err);
5869
}else{
@@ -75,12 +86,12 @@ export default class FileSystemLoader {
7586
} )
7687
}
7788

78-
get finalSource() {
89+
private get finalSource(): string {
7990
return Object.keys( this.sources ).sort( traceKeySorter ).map( s => this.sources[s] )
8091
.join( "" )
8192
}
8293

83-
clear() {
94+
private clear(): FileSystemLoader {
8495
this.tokensByFile = {};
8596
return this;
8697
}

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { DtsCreator } from './dtsCreator';
2+
export = DtsCreator;

src/is-there.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module 'is-there' {
2+
function isThere(path: string): boolean;
3+
export = isThere;
4+
}

0 commit comments

Comments
 (0)