├── .editorconfig
├── .gitignore
├── .npmignore
├── .tasks
├── gulp-clean.ts
├── gulp-copy.ts
└── gulp-tslint.ts
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── appveyor.yml
├── build
└── test
│ └── .eslintrc
├── fixtures
├── bar.css
├── foo.css
└── sugar.sss
├── gulpfile.ts
├── lib
└── middleware.ts
├── package.json
├── test
├── middleware.ts
└── mocha.opts
├── tsconfig.json
└── tslint.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = tab
5 | end_of_line = lf
6 | trim_trailing_whitespace = true
7 | insert_final_newline = true
8 |
9 | [{*.json,*.yml}]
10 | indent_style = space
11 | indent_size = 2
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | build/**/*.js
3 | build/**/*.ts
4 | dist/
5 | node_modules/
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .*
2 | !.d.ts
3 | *.sln*
4 | *.suo
5 | build/
6 | lib/
7 | test/
8 | !dist/lib
9 | !dist/d.ts/lib
10 | scripts/
11 | appveyor.yml
12 | gulpfile.babel.js
13 | jsconfig.json
14 | tsconfig.json
15 | tsd.json
16 | tslint.json
17 |
--------------------------------------------------------------------------------
/.tasks/gulp-clean.ts:
--------------------------------------------------------------------------------
1 | const del = require('del');
2 |
3 | export default done => {
4 | del([
5 | 'build/**/*.js',
6 | 'build/**/*.d.ts',
7 | 'dist'
8 | ], done);
9 | }
10 |
--------------------------------------------------------------------------------
/.tasks/gulp-copy.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 |
3 | export default () => {
4 | return gulp.src('build/lib/**', { base: 'build' })
5 | .pipe(gulp.dest('dist'));
6 | }
7 |
--------------------------------------------------------------------------------
/.tasks/gulp-tslint.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import * as plumber from 'gulp-plumber';
3 | import tslint from 'gulp-tslint';
4 |
5 | export default () => {
6 | return gulp.src([
7 | 'lib/**/*.ts',
8 | 'test/**/*.ts'
9 | ])
10 | .pipe(plumber())
11 | .pipe(tslint({
12 | formatter: 'verbose'
13 | }))
14 | .pipe(tslint.report());
15 | };
16 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - 'node'
5 | - '6.9.4' # LTS
6 |
7 | notifications:
8 | email:
9 | on_success: change
10 | on_failure: always
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 1.1.4
2 | - Update dependencies.
3 |
4 | ## 1.1.3
5 | - Update dependencies (fixes [`#9`](https://github.com/jedmao/postcss-middleware/issues/9)).
6 |
7 | ## 1.1.2
8 | - Fix module resolution (fixes [`#7`](https://github.com/jedmao/postcss-middleware/issues/7)).
9 |
10 | ## 1.1.1
11 | - Convert Babel code to TypeScript, fix build.
12 |
13 | ## 1.1.0
14 | - Pass PostCSS options to middleware [#5](https://github.com/jedmao/postcss-middleware/pull/5).
15 |
16 | ## 1.0.0
17 | - Supports PostCSS 5.x
18 |
19 | ## 0.0.1
20 | - Supports PostCSS 4.x
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Jed Mao
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # postcss-middleware
2 |
3 |
6 |
7 | [](https://www.npmjs.org/package/postcss-middleware)
8 | [](https://www.npmjs.org/package/postcss-middleware)
9 | [](https://travis-ci.org/jedmao/postcss-middleware)
10 | [](https://ci.appveyor.com/project/jedmao/postcss-middleware)
11 |
12 | [](https://nodei.co/npm/postcss-middleware/)
13 |
14 | [PostCSS](https://github.com/postcss/postcss) middleware for [Connect](https://github.com/senchalabs/connect#readme) and [Express][] frameworks.
15 |
16 | ## Installation
17 |
18 | ```
19 | $ npm install postcss-middleware
20 | ```
21 |
22 | ## Usage
23 |
24 | ### JavaScript
25 |
26 | ```js
27 | var postcssMiddleware = require('postcss-middleware');
28 | ```
29 |
30 | ### TypeScript
31 |
32 | ```ts
33 | import * as postcssMiddleware from 'postcss-middleware';
34 | ```
35 |
36 | ### Connect
37 |
38 | ```js
39 | const connect = require('connect');
40 | const app = connect();
41 | app.use('/css', postcssMiddleware(/* options */));
42 | ```
43 |
44 | ### Express
45 |
46 | ```js
47 | const express = require('express');
48 | const app = express();
49 | app.use('/css', postcssMiddleware(/* options */));
50 | ```
51 |
52 | ### Options
53 |
54 | #### `plugins`
55 |
56 | Type: `Array`
57 | Required: `true`
58 |
59 | An array of [PostCSS plugins](https://github.com/postcss/postcss#plugins).
60 |
61 | #### `options`
62 |
63 | Type: `Object`
64 | Required: `false`
65 |
66 | [PostCSS options](https://github.com/postcss/postcss#options) such as `syntax`, `parser` or `map`.
67 |
68 | ```js
69 | app.use(postcssMiddleware({
70 | plugins: [/* plugins */],
71 | options: {
72 | parser: require('sugarss'),
73 | map: { inline: false }
74 | }
75 | }
76 | });
77 | ```
78 |
79 | #### `src`
80 |
81 | Type: `(request) => string|string[]`
82 | Required: `false`
83 | Default: `req => path.join(__dirname, req.url)`
84 |
85 | A callback function that will be provided the [Express][] [app's](http://expressjs.com/4x/api.html#app) [request](http://expressjs.com/4x/api.html#req) object. Use this object to build the file path to the source file(s) you wish to read. The callback can return [a glob string or an array of glob strings](https://github.com/wearefractal/vinyl-fs#srcglobs-opt). All files matched will be [concatenated](https://github.com/wearefractal/gulp-concat) in the [response](http://expressjs.com/4x/api.html#res.send).
86 |
87 | ```js
88 | var path = require('path');
89 | app.use('/css', postcssMiddleware({
90 | src: function(req) {
91 | return path.join('styles', req.path);
92 | },
93 | plugins: [/* plugins */]
94 | });
95 | ```
96 |
97 | The above example will match requests to `/css`. If `/css/foo.css` were requested, the middleware would read `/styles/foo.css` in the context of your application.
98 |
99 | Using a regular expression [route path](http://expressjs.com/guide/routing.html), we can back-reference a capture group and use it as a folder name.
100 |
101 | ```js
102 | var path = require('path');
103 | app.use(/^\/css\/([a-z-]+)\.css$/, postcssMiddleware({
104 | src: function(req) {
105 | var folder = req.params[0];
106 | return path.join('styles', folder, '*.css');
107 | },
108 | plugins: [/* plugins */]
109 | });
110 | ```
111 |
112 | If you were to request `/css/foo-bar.css` in the above example, the middleware would concatenate all CSS files in the `/styles/foo-bar` folder in the response.
113 |
114 | #### `inlineSourcemaps`
115 |
116 | Type: `Boolean`
117 | Required: `false`
118 | Default: `undefined`
119 |
120 | Generate inlined [sourcemaps](https://github.com/floridoo/gulp-sourcemaps).
121 |
122 | [Express]: http://expressjs.com/
123 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # http://www.appveyor.com/docs/appveyor-yml
2 |
3 | environment:
4 | nodejs_version: "6"
5 |
6 | version: "{build}"
7 | build: off
8 | deploy: off
9 |
10 | install:
11 | - ps: Install-Product node $env:nodejs_version
12 | - npm install
13 |
14 | test_script:
15 | - node --version
16 | - npm --version
17 | - npm test
18 |
--------------------------------------------------------------------------------
/build/test/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "mocha": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/fixtures/bar.css:
--------------------------------------------------------------------------------
1 | body{bar:baz}
2 |
--------------------------------------------------------------------------------
/fixtures/foo.css:
--------------------------------------------------------------------------------
1 | body{foo:bar}
2 |
--------------------------------------------------------------------------------
/fixtures/sugar.sss:
--------------------------------------------------------------------------------
1 | body
2 | foo: bar
3 |
--------------------------------------------------------------------------------
/gulpfile.ts:
--------------------------------------------------------------------------------
1 | import * as gulp from 'gulp';
2 | import clean from './.tasks/gulp-clean';
3 | import tslint from './.tasks/gulp-tslint';
4 | import copy from './.tasks/gulp-copy';
5 |
6 | gulp.task('default', ['tslint']);
7 | gulp.task('clean', clean);
8 | gulp.task('tslint', tslint);
9 | gulp.task('copy', copy);
10 |
--------------------------------------------------------------------------------
/lib/middleware.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as vfs from 'vinyl-fs';
3 | import * as sourcemaps from 'gulp-sourcemaps';
4 | import * as plumber from 'gulp-plumber';
5 | import * as postcss from 'gulp-postcss';
6 | import * as concat from 'gulp-concat';
7 | import * as tap from 'gulp-tap';
8 | import * as gulpif from 'gulp-if';
9 |
10 | const ERROR_PREFIX = '[postcss-middleware]';
11 |
12 | function PostCssMiddleware(options: PostCssMiddleware.Options = {}) {
13 |
14 | if (!options.plugins) {
15 | throw new Error(`${ERROR_PREFIX} missing required option: plugins`);
16 | }
17 |
18 | if (!Array.isArray(options.plugins)) {
19 | throw new TypeError(`${ERROR_PREFIX} plugins option must be an array`);
20 | }
21 |
22 | if (options.src && typeof options.src !== 'function') {
23 | throw new TypeError(`${ERROR_PREFIX} src option must be a function`);
24 | }
25 |
26 | if (options.options && typeof options.options !== 'object') {
27 | throw new TypeError(`${ERROR_PREFIX} options option must be an object`);
28 | }
29 |
30 | const src = options.src || (req => path.join(__dirname, req.url));
31 |
32 | return (req, res, next: Function) => {
33 | if (req.method !== 'GET' && req.method !== 'HEAD') {
34 | next();
35 | return;
36 | }
37 |
38 | const globs = src(req);
39 | if (typeof globs !== 'string' && !Array.isArray(globs)) {
40 | next(new TypeError(`${ERROR_PREFIX} src callback must return a glob string or array`));
41 | return;
42 | }
43 |
44 | let isFileFound = false;
45 | vfs.src(globs, { allowEmpty: false })
46 | .on('error', err => {
47 | if (err.message.match(/File not found/i)) {
48 | return next();
49 | }
50 | return next(err);
51 | })
52 | .pipe(plumber({ errorHandler: err => next(err) }))
53 | .pipe(gulpif(options.inlineSourcemaps, sourcemaps.init()))
54 | .pipe(postcss(options.plugins, options.options))
55 | .pipe(concat('.css'))
56 | .pipe(gulpif(options.inlineSourcemaps, sourcemaps.write()))
57 | .pipe(tap(file => {
58 | isFileFound = true;
59 | res.writeHead(200, {
60 | 'Content-Type': 'text/css'
61 | });
62 | res.end(file.contents);
63 | }))
64 | .on('end', () => {
65 | if (!isFileFound) {
66 | next();
67 | }
68 | });
69 | };
70 | }
71 |
72 | module PostCssMiddleware {
73 | export interface Options {
74 | /**
75 | * An array of PostCSS plugins.
76 | */
77 | plugins: Function[];
78 | /**
79 | * PostCSS options
80 | */
81 | options?: Object;
82 | /**
83 | * Build the file path to the source file(s) you wish to read.
84 | */
85 | src?:
86 | /**
87 | * @param request The Express app's request object.
88 | * @returns A glob string or an array of glob strings. All files matched
89 | * will be concatenated in the response.
90 | */
91 | (request: any) => string|string[];
92 | /**
93 | * Generate inlined sourcemaps.
94 | */
95 | inlineSourcemaps?: boolean;
96 | }
97 | }
98 |
99 | export = PostCssMiddleware;
100 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "postcss-middleware",
3 | "version": "1.1.4",
4 | "description": "PostCSS middleware for Connect and Express frameworks.",
5 | "main": "dist/lib/middleware.js",
6 | "types": "dist/lib/middleware.d.ts",
7 | "scripts": {
8 | "prepublish": "gulp && npm run tsc && gulp copy",
9 | "tsc": "tsc",
10 | "test": "gulp && npm run tsc && mocha",
11 | "mocha": "mocha",
12 | "watch": "mocha --watch"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/jedmao/postcss-middleware.git"
17 | },
18 | "keywords": [
19 | "postcss",
20 | "middleware",
21 | "connect",
22 | "express"
23 | ],
24 | "author": "Jed Mao ",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/jedmao/postcss-middleware/issues"
28 | },
29 | "homepage": "https://github.com/jedmao/postcss-middleware#readme",
30 | "devDependencies": {
31 | "@types/chai": "^4.0.4",
32 | "@types/connect": "^3.4.30",
33 | "@types/gulp": "^3.8.33",
34 | "@types/gulp-concat": "0.0.31",
35 | "@types/gulp-if": "0.0.32",
36 | "@types/gulp-plumber": "0.0.31",
37 | "@types/gulp-sourcemaps": "0.0.31",
38 | "@types/gulp-tslint": "^3.6.30",
39 | "@types/mocha": "^2.2.38",
40 | "@types/supertest": "^2.0.0",
41 | "@types/vinyl-fs": "2.4.7",
42 | "chai": "^4.1.2",
43 | "connect": "^3.5.0",
44 | "del": "^3.0.0",
45 | "gulp": "^3.9.1",
46 | "gulp-tslint": "^8.1.2",
47 | "mocha": "^4.0.1",
48 | "sugarss": "^1.0.0",
49 | "supertest": "^3.0.0",
50 | "ts-node": "^3.3.0",
51 | "tslint": "^5.8.0",
52 | "typescript": "^2.1.5"
53 | },
54 | "dependencies": {
55 | "gulp-concat": "^2.6.1",
56 | "gulp-if": "^2.0.2",
57 | "gulp-plumber": "^1.1.0",
58 | "gulp-postcss": "^7.0.0",
59 | "gulp-sourcemaps": "^2.4.0",
60 | "gulp-tap": "^1.0.1",
61 | "vinyl-fs": "^2.4.4"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/test/middleware.ts:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai';
2 | import * as connect from 'connect';
3 | import { join } from 'path';
4 | import * as request from 'supertest';
5 | import * as sugarss from 'sugarss';
6 | import * as middleware from '../lib/middleware';
7 |
8 | const ERROR_PREFIX = '[postcss-middleware]';
9 |
10 | describe('creating middleware', () => {
11 |
12 | it('throws an error when plugins option is not provided', () => {
13 | expect(middleware).to.throw(`${ERROR_PREFIX} missing required option: plugins`);
14 | });
15 |
16 | it('throws an error when plugins option is a string', () => {
17 | expect(() => {
18 | middleware({ plugins: 'foo' });
19 | }).to.throw(TypeError, `${ERROR_PREFIX} plugins option must be an array`);
20 | });
21 |
22 | it('remains silent when plugins option is an empty array', () => {
23 | expect(() => {
24 | middleware({ plugins: [] });
25 | }).not.to.throw(Error);
26 | });
27 |
28 | it('throws an error when src option is a string', () => {
29 | expect(() => {
30 | middleware({
31 | plugins: [],
32 | src: 'foo'
33 | });
34 | }).to.throw(TypeError, `${ERROR_PREFIX} src option must be a function`);
35 | });
36 |
37 | it('throws an error when options option is a string', () => {
38 | expect(() => {
39 | middleware({
40 | plugins: [],
41 | options: 'foo'
42 | });
43 | }).to.throw(TypeError, `${ERROR_PREFIX} options option must be an object`);
44 | });
45 |
46 | });
47 |
48 | describe('the request',() => {
49 |
50 | it('moves to the next middleware when request method is POST', done => {
51 | request(createServer({ plugins: [] }))
52 | .post('/foo.css')
53 | .expect(res => {
54 | if (!res.error.message.match(/Cannot POST \/foo\.css/i)) {
55 | throw new Error(res.error.message);
56 | }
57 | })
58 | .expect(404, done);
59 | });
60 |
61 | it('sends an error to the next middleware when src returns undefined', done => {
62 | request(createServer({
63 | plugins: [],
64 | src: () => void 0
65 | }))
66 | .get('/foo.css')
67 | .expect(`${ERROR_PREFIX} src callback must return a glob string or array`)
68 | .expect(500, done);
69 | });
70 |
71 | it('moves to the next middleware when the file is not found', done => {
72 | request(createServer({ plugins: [] }))
73 | .get('/does-not-exist.css')
74 | .expect(res => {
75 | if (!res.error.message.match(/Cannot GET \/does-not-exist.css/i)) {
76 | throw new Error(res.error.message);
77 | }
78 | })
79 | .expect(404, done);
80 | });
81 |
82 | it('resolves src path relative to __dirname by default', done => {
83 | request(connect().use(middleware({ plugins: [] })))
84 | .get('/../../fixtures/foo.css')
85 | .expect(200, done);
86 | });
87 |
88 | it('serves a file with 200 Content-Type: text/css', done => {
89 | request(createServer({ plugins: [] }))
90 | .get('/foo.css')
91 | .set('Accept', 'text/css')
92 | .expect('Content-Type', 'text/css')
93 | .expect(200, done);
94 | });
95 |
96 | it('concatenates a glob src into one file', done => {
97 | request(createServer({
98 | plugins: [],
99 | src: () => {
100 | return join('fixtures', '*.css');
101 | }
102 | }))
103 | .get('/foo.css')
104 | .expect('body{bar:baz}\n\nbody{foo:bar}\n')
105 | .expect(200, done);
106 | });
107 |
108 | it('inlines sourcemaps when inlineSourcemaps option is true', done => {
109 | request(createServer({
110 | plugins: [],
111 | src: () => {
112 | return join('fixtures', '*.css');
113 | },
114 | inlineSourcemaps: true
115 | }))
116 | .get('/foo.css')
117 | .expect(/\/*# sourceMappingURL=data:application\/json;charset=utf8;base64,/)
118 | .expect(200, done);
119 | });
120 |
121 | it('serves a file without modification when plugins array is empty', done => {
122 | request(createServer({ plugins: [] }))
123 | .get('/foo.css')
124 | .expect('body{foo:bar}\n')
125 | .expect(200, done);
126 | });
127 |
128 | it('serves a file processed by all plugins defined in options', done => {
129 | request(createServer({
130 | plugins: [
131 | css => {
132 | css.walkDecls('foo', declaration => {
133 | declaration.prop = 'baz';
134 | });
135 | },
136 | css => {
137 | css.walkDecls('baz', declaration => {
138 | declaration.value = 'qux';
139 | });
140 | }
141 | ]
142 | }))
143 | .get('/foo.css')
144 | .expect('body{baz:qux}\n')
145 | .expect(200, done);
146 | });
147 |
148 | it('sends a plugin error to the next middleware', done => {
149 | request(createServer({
150 | plugins: [
151 | () => {
152 | throw new Error('foo');
153 | }
154 | ]
155 | }))
156 | .get('/foo.css')
157 | .expect('foo')
158 | .expect(500, done);
159 | });
160 |
161 | it('applies a postcss options', done => {
162 | request(createServer({
163 | plugins: [],
164 | options: {
165 | parser: sugarss
166 | }
167 | }))
168 | .get('/sugar.sss')
169 | .expect('body {\n\tfoo: bar\n}\n')
170 | .expect(200, done);
171 | });
172 |
173 | });
174 |
175 | function createServer(options: middleware.Options) {
176 | options.src = options.src || (req => {
177 | return join('fixtures', req.url);
178 | });
179 | /*eslint-disable no-unused-vars */
180 | return connect()
181 | .use(middleware(options))
182 | .use((err, req, res, next) => {
183 | res.statusCode = 500;
184 | res.end(err.message);
185 | });
186 | /*eslint-enable no-unused-vars */
187 | }
188 |
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --inline-diffs
2 | --reporter spec
3 | --compilers ts:ts-node/register
4 | build/test/middleware.js
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "moduleResolution": "node",
5 | "target": "es5",
6 | "declaration": true,
7 | "newLine": "LF",
8 | "outDir": "build",
9 | "rootDir": ".",
10 | "lib": [
11 | "es2015",
12 | "dom"
13 | ]
14 | },
15 | "files": [
16 | "lib/middleware.ts",
17 | "test/middleware.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "class-name": true,
4 | "curly": true,
5 | "eofline": true,
6 | "forin": true,
7 | "label-position": true,
8 | "max-line-length": [true, 120],
9 | "no-arg": true,
10 | "no-bitwise": true,
11 | "no-console": [true,
12 | "debug",
13 | "info",
14 | "time",
15 | "timeEnd",
16 | "trace"
17 | ],
18 | "no-construct": true,
19 | "no-debugger": true,
20 | "no-duplicate-variable": true,
21 | "no-empty": true,
22 | "no-eval": true,
23 | "no-string-literal": true,
24 | "no-trailing-whitespace": true,
25 | "one-line": [true,
26 | "check-open-brace",
27 | "check-catch",
28 | "check-else",
29 | "check-whitespace"
30 | ],
31 | "quotemark": [false],
32 | "radix": true,
33 | "semicolon": [true],
34 | "triple-equals": [true, "allow-null-check"],
35 | "variable-name": false,
36 | "whitespace": [true,
37 | "check-branch",
38 | "check-decl",
39 | "check-operator",
40 | "check-type"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------