Skip to content

Commit e1a94d9

Browse files
add options resolvers, fixes michalkvasnicak#10
1 parent 5430f51 commit e1a94d9

29 files changed

+564
-0
lines changed

src/options_resolvers/append.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { isFunction, isModulePath, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves append option for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {Function}
8+
*/
9+
export default function append(value/* , currentConfig */) {
10+
if (Array.isArray(value)) {
11+
return value.map((option, index) => {
12+
if (isFunction(option)) {
13+
return option();
14+
} else if (isModulePath(option)) {
15+
const requiredOption = requireLocalFileOrNodeModule(option);
16+
17+
if (!isFunction(requiredOption)) {
18+
throw new Error(`Configuration 'append[${index}]' module is not exporting a function`);
19+
}
20+
21+
return requiredOption();
22+
}
23+
24+
throw new Error(`Configuration 'append[${index}]' is not a function or a valid module path`);
25+
});
26+
}
27+
28+
throw new Error(`Configuration 'append' is not an array`);
29+
}

src/options_resolvers/camelCase.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { isBoolean } from '../utils';
2+
3+
/**
4+
* Resolves camelCase option for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {boolean}
8+
*/
9+
export default function camelCase(value/* , currentConfig */) {
10+
if (!isBoolean(value)) {
11+
throw new Error(`Configuration 'camelCase' is not a boolean`);
12+
}
13+
14+
return value;
15+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { isFunction, isModulePath, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves createImportedName css-modules-require-hook option
5+
*
6+
* @param {String|Function} value
7+
* @returns {Function}
8+
*/
9+
export default function createImportedName(value/* , currentConfig */) {
10+
if (isFunction(value)) {
11+
return value;
12+
} else if (isModulePath(value)) {
13+
const requiredOption = requireLocalFileOrNodeModule(value);
14+
15+
if (!isFunction(requiredOption)) {
16+
throw new Error(`Configuration file for 'createImportedName' is not exporting a function`);
17+
}
18+
19+
return requiredOption;
20+
}
21+
22+
throw new Error(`Configuration 'createImportedName' is not a function nor a valid module path`);
23+
}

src/options_resolvers/devMode.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { isBoolean } from '../utils';
2+
3+
/**
4+
* Resolves devMode option for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {boolean}
8+
*/
9+
export default function devMode(value/* , currentConfig */) {
10+
if (!isBoolean(value)) {
11+
throw new Error(`Configuration 'devMode' is not a boolean`);
12+
}
13+
14+
return value;
15+
}

src/options_resolvers/extensions.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { isString } from '../utils';
2+
3+
/**
4+
* Resolves extensions for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {Array.<String>}
8+
*/
9+
export default function extensions(value/* , currentConfig */) {
10+
if (Array.isArray(value)) {
11+
return value.map((extension, index) => {
12+
if (!isString(extension)) {
13+
throw new Error(`Configuration 'extensions[${index}]' is not a string`);
14+
}
15+
16+
return extension;
17+
});
18+
}
19+
20+
throw new Error(`Configuration 'extensions' is not an array`);
21+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { isModulePath, isFunction, isString, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves generateScopedName option for css-modules-require-hook
5+
*
6+
* @param {String|Function} value
7+
*
8+
* @returns {String|Function}
9+
*/
10+
export default function generateScopedName(value/* ,currentConfig */) {
11+
if (isModulePath(value)) {
12+
const requiredModule = requireLocalFileOrNodeModule(value);
13+
14+
if (isString(requiredModule) || isFunction(requiredModule)) {
15+
return requiredModule;
16+
}
17+
18+
throw new Error(`Configuration file for 'generateScopedName' is not exporting a string nor a function`);
19+
} else if (isString(value) || isFunction(value)) {
20+
return value;
21+
} else {
22+
throw new Error(`Configuration 'generateScopedName' is not a function, string nor valid path to module`);
23+
}
24+
}

src/options_resolvers/ignore.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { isFunction, isModulePath, isRegExp, isString, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves ignore option for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {Function|String|RegExp}
8+
*/
9+
export default function ignore(value/* , currentConfig */) {
10+
if (isFunction(value) || isRegExp(value)) {
11+
return value;
12+
} else if (isModulePath(value)) {
13+
const requiredOption = requireLocalFileOrNodeModule(value);
14+
15+
if (isFunction(requiredOption) || isString(requiredOption) || isRegExp(requiredOption)) {
16+
return requiredOption;
17+
}
18+
19+
throw new Error(`Configuration file for 'generateScopedName' is not exporting a string nor a function`);
20+
} else if (isString(value)) {
21+
return value;
22+
} else {
23+
throw new Error(`Configuration 'ignore' is not a function, string, RegExp nor valid path to module`);
24+
}
25+
}

src/options_resolvers/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export { default as append } from './append';
2+
export { default as camelCase } from './camelCase';
3+
export { default as createImportedName } from './createImportedName';
4+
export { default as devMode } from './devMode';
5+
export { default as generateScopedName } from './generateScopedName';
6+
export { default as ignore } from './ignore';
7+
export { default as mode } from './mode';
8+
export { default as prepend } from './prepend';
9+
export { default as preprocessCss } from './preprocessCss';
10+
export { default as processCss } from './processCss';
11+
export { default as processOpts } from './processOpts';
12+
export { default as rootDir } from './rootDir';
13+
export { default as use } from './use';

src/options_resolvers/mode.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { isString } from '../utils';
2+
3+
/**
4+
* Resolves mode option for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {boolean}
8+
*/
9+
export default function mode(value/* , currentConfig */) {
10+
if (!isString(value)) {
11+
throw new Error(`Configuration 'mode' is not a string`);
12+
}
13+
14+
return value;
15+
}

src/options_resolvers/prepend.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { isFunction, isModulePath, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves prepend option for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {Function}
8+
*/
9+
export default function prepend(value/* , currentConfig */) {
10+
if (Array.isArray(value)) {
11+
return value.map((option, index) => {
12+
if (isFunction(option)) {
13+
return option();
14+
} else if (isModulePath(option)) {
15+
const requiredOption = requireLocalFileOrNodeModule(option);
16+
17+
if (!isFunction(requiredOption)) {
18+
throw new Error(`Configuration 'prepend[${index}]' module is not exporting a function`);
19+
}
20+
21+
return requiredOption();
22+
}
23+
24+
throw new Error(`Configuration 'prepend[${index}]' is not a function or a valid module path`);
25+
});
26+
}
27+
28+
throw new Error(`Configuration 'prepend' is not an array`);
29+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { isModulePath, isFunction, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves preprocessCss option for css-modules-require-hook
5+
*
6+
* @param {String|Function} value
7+
*
8+
* @returns {String|Function}
9+
*/
10+
export default function preprocessCss(value/* ,currentConfig */) {
11+
if (isModulePath(value)) {
12+
const requiredModule = requireLocalFileOrNodeModule(value);
13+
14+
if (isFunction(requiredModule)) {
15+
return requiredModule;
16+
}
17+
18+
throw new Error(`Configuration file for 'preprocessCss' is not exporting a function`);
19+
} else if (isFunction(value)) {
20+
return value;
21+
} else {
22+
throw new Error(`Configuration 'preprocessCss' is not a function nor a valid path to module`);
23+
}
24+
}

src/options_resolvers/processCss.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { isModulePath, isFunction, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves processCss option for css-modules-require-hook
5+
*
6+
* @param {String|Function} value
7+
*
8+
* @returns {String|Function}
9+
*/
10+
export default function processCss(value/* ,currentConfig */) {
11+
if (isModulePath(value)) {
12+
const requiredModule = requireLocalFileOrNodeModule(value);
13+
14+
if (isFunction(requiredModule)) {
15+
return requiredModule;
16+
}
17+
18+
throw new Error(`Configuration file for 'processCss' is not exporting a function`);
19+
} else if (isFunction(value)) {
20+
return value;
21+
} else {
22+
throw new Error(`Configuration 'processCss' is not a function nor a valid path to module`);
23+
}
24+
}

src/options_resolvers/processOpts.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { isModulePath, isPlainObject, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves processOpts option for css-modules-require-hook
5+
*
6+
* @param {String|Function} value
7+
*
8+
* @returns {String|Function}
9+
*/
10+
export default function processOpts(value/* ,currentConfig */) {
11+
if (isModulePath(value)) {
12+
const requiredModule = requireLocalFileOrNodeModule(value);
13+
14+
if (isPlainObject(requiredModule)) {
15+
return requiredModule;
16+
}
17+
18+
throw new Error(`Configuration file for 'processOpts' is not exporting a plain object`);
19+
} else if (isPlainObject(value)) {
20+
return value;
21+
} else {
22+
throw new Error(`Configuration 'processOpts' is not a plain object nor a valid path to module`);
23+
}
24+
}

src/options_resolvers/rootDir.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { isAbsolute } from 'path';
2+
import { statSync } from 'fs';
3+
import { isString } from '../utils';
4+
5+
/**
6+
* Resolves mode option for css-modules-require-hook
7+
*
8+
* @param {*} value
9+
* @returns {boolean}
10+
*/
11+
export default function rootDir(value/* , currentConfig */) {
12+
if (!isString(value)) {
13+
throw new Error(`Configuration 'rootDir' is not a string`);
14+
}
15+
16+
if (!isAbsolute(value) || !statSync(value).isDirectory()) {
17+
throw new Error(`Configuration 'rootDir' is not containg a valid absolute path`);
18+
}
19+
20+
return value;
21+
}

src/options_resolvers/use.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { isFunction, isModulePath, requireLocalFileOrNodeModule } from '../utils';
2+
3+
/**
4+
* Resolves use option for css-modules-require-hook
5+
*
6+
* @param {*} value
7+
* @returns {Function}
8+
*/
9+
export default function use(value/* , currentConfig */) {
10+
if (Array.isArray(value)) {
11+
return value.map((option, index) => {
12+
if (isFunction(option)) {
13+
return option();
14+
} else if (isModulePath(option)) {
15+
const requiredOption = requireLocalFileOrNodeModule(option);
16+
17+
if (!isFunction(requiredOption)) {
18+
throw new Error(`Configuration 'use[${index}]' module is not exporting a function`);
19+
}
20+
21+
return requiredOption();
22+
}
23+
24+
throw new Error(`Configuration 'use[${index}]' is not a function or a valid module path`);
25+
});
26+
}
27+
28+
throw new Error(`Configuration 'use' is not an array`);
29+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
3+
var styles = {};

test/options_resolvers/append.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { expect } from 'chai';
2+
3+
import append from '../../src/options_resolvers/append';
4+
5+
describe('options_resolvers/append', () => {
6+
it('should throw if append is not an array', () => {
7+
expect(
8+
() => append({})
9+
).to.throw();
10+
});
11+
12+
it('should throw if append does not contain functions', () => {
13+
expect(
14+
() => append(['test/fixtures/append.module.js'])
15+
).to.throw();
16+
});
17+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expect } from 'chai';
2+
3+
import camelCase from '../../src/options_resolvers/camelCase';
4+
5+
describe('options_resolvers/camelCase', () => {
6+
it('should throw if camelCase value is not a boolean', () => {
7+
expect(
8+
() => camelCase(null)
9+
).to.throw();
10+
11+
expect(camelCase(true)).to.be.equal(true);
12+
});
13+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { expect } from 'chai';
2+
3+
import devMode from '../../src/options_resolvers/devMode';
4+
5+
describe('options_resolvers/devMode', () => {
6+
it('should throw if devMode value is not a boolean', () => {
7+
expect(
8+
() => devMode(null)
9+
).to.throw();
10+
11+
expect(devMode(true)).to.be.equal(true);
12+
});
13+
});

0 commit comments

Comments
 (0)