├── .eslintignore
├── .eslintrc.js
├── .github
└── workflows
│ ├── deploy.yml
│ └── verify.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── babel.config.json
├── fixtures
├── composee.css
├── composer.css
├── empty.css
├── errorCss.css
├── example.css
└── invalidComposer.scss
├── lerna.json
├── package.json
├── packages
├── css-modules-flow-types-cli
│ ├── README.md
│ ├── babel.config.json
│ ├── bin
│ │ └── cli.js
│ ├── package.json
│ ├── src
│ │ ├── __test__
│ │ │ └── converter.test.js
│ │ ├── cli.js
│ │ ├── converter.js
│ │ ├── css-modules
│ │ │ └── fileSystemLoader.js
│ │ └── writer.js
│ └── yarn.lock
├── css-modules-flow-types-loader
│ ├── README.md
│ ├── __mocks__
│ │ └── fs.js
│ ├── __test__
│ │ └── index.test.js
│ ├── babel.config.json
│ ├── index.js
│ └── package.json
└── css-modules-flow-types-printer
│ ├── README.md
│ ├── __test__
│ └── index.test.js
│ ├── babel.config.json
│ ├── index.js
│ └── package.json
├── publish.sh
└── yarn.lock
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bin
3 | dist
4 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['eslint:recommended', 'prettier'],
3 | parser: 'babel-eslint',
4 | plugins: ['import', 'prettier'],
5 | env: {
6 | node: true,
7 | es6: true,
8 | },
9 | root: true,
10 | rules: {
11 | 'prettier/prettier': [
12 | 'error',
13 | { trailingComma: 'es5', singleQuote: true, tabWidth: 2, },
14 | ],
15 |
16 | 'prefer-const': 'error',
17 | 'import/order': [
18 | 'error',
19 | {
20 | groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
21 | },
22 | ],
23 | 'no-unused-vars': ['error', { vars: 'all', args: 'none' }],
24 | 'no-underscore-dangle': 'off',
25 | 'no-param-reassign': 'off',
26 | 'no-console': 'off',
27 | 'no-warning-comments': ['warn', { terms: ['fixme'], location: 'start' }],
28 | },
29 | parserOptions: {
30 | sourceType: "module"
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Publish changes
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | deploy:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v2
13 |
14 | - uses: actions/setup-node@v1
15 | with:
16 | node-version: 12
17 | registry-url: https://registry.npmjs.org/
18 |
19 | - run: |
20 | git config --local user.email "kenneth.skovhus@gmail.com"
21 | git config --local user.name "skovhus"
22 | name: Configure for pushing git tags
23 |
24 | - run: bash publish.sh
25 | name: Publish changes
26 | env:
27 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
28 |
--------------------------------------------------------------------------------
/.github/workflows/verify.yml:
--------------------------------------------------------------------------------
1 | name: Verify changes
2 |
3 | on: [pull_request]
4 |
5 | jobs:
6 | verify:
7 |
8 | runs-on: ubuntu-latest
9 |
10 |
11 | steps:
12 | - uses: actions/checkout@v2
13 |
14 | - uses: actions/setup-node@v1
15 | with:
16 | node-version: 12
17 | registry-url: https://registry.npmjs.org/
18 |
19 | - run: yarn install
20 | name: Install dependencies
21 |
22 | - run: yarn verify:bail
23 | name: Verify changes
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | *.log
4 | coverage
5 | dist
6 | .idea
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | # [2.0.0](https://github.com/skovhus/css-modules-flow-types/compare/v1.4.1...v2.0.0) (2020-08-12)
3 |
4 | ### Features
5 | * Security fix for [trim-newlines CVE](https://github.com/advisories/GHSA-7p7h-4mm5-852v) by upgrading `meow` dependency in `css-modules-flow-flow-types-cli`
6 | * Change minimum Node version to 8 as latest version of `meow` requires Node 8 or newer
7 |
8 |
9 | # [1.4.1](https://github.com/skovhus/css-modules-flow-types/compare/v1.3.0...v1.4.1) (2020-08-12)
10 |
11 | ### Features
12 | * Support for css-loader 4.x (https://github.com/skovhus/css-modules-flow-types/pull/48)
13 | * Various security fixes
14 |
15 |
16 |
17 | # [1.3.0](https://github.com/skovhus/css-modules-flow-types/compare/v1.2.0...v1.3.0) (2019-05-27)
18 |
19 | ### Features
20 | * Change delimiter from `;` to `,` for improved syntax highlighting (https://github.com/skovhus/css-modules-flow-types/pull/25)
21 |
22 |
23 | # [1.2.0](https://github.com/skovhus/css-modules-flow-types/compare/v1.1.1...v1.2.0) (2019-04-12)
24 |
25 | ### Features
26 | * Added end of line detection (https://github.com/skovhus/css-modules-flow-types/pull/26)
27 |
28 |
29 |
30 | # [1.1.1](https://github.com/skovhus/css-modules-flow-types/compare/v1.1.0...v1.1.1) (2018-09-17)
31 |
32 | ### Features
33 | * Change header to 'flow strict' ([e38ad5a](https://github.com/skovhus/css-modules-flow-types/commit/e38ad5a))
34 |
35 |
36 |
37 |
38 | # [1.1.0](https://github.com/skovhus/css-modules-flow-types/compare/v1.0.1...v1.1.0) (2017-10-15)
39 |
40 |
41 | ### Features
42 |
43 | * silence non-error log output ([46b3366](https://github.com/skovhus/css-modules-flow-types/commit/46b3366))
44 |
45 |
46 |
47 |
48 | ## [1.0.1](https://github.com/skovhus/css-modules-flow-types/compare/v1.0.0...v1.0.1) (2017-10-13)
49 |
50 |
51 | ### Bug Fixes
52 |
53 | * update yarn.lock files (lerna did not do this) ([f835591](https://github.com/skovhus/css-modules-flow-types/commit/f835591))
54 |
55 |
56 |
57 |
58 | # [1.0.0](https://github.com/skovhus/css-modules-flow-types/compare/v0.3.1...v1.0.0) (2017-10-13)
59 |
60 |
61 | ### Features
62 |
63 | * rewrite loader tokenization to account for external `composes` rules, change printer to accept tokens as [] instad of {} (fixes [#5](https://github.com/skovhus/css-modules-flow-types/issues/5)) ([b3e2747](https://github.com/skovhus/css-modules-flow-types/commit/b3e2747))
64 |
65 |
66 |
67 |
68 | ## [0.3.1](https://github.com/skovhus/css-modules-flow-types/compare/v0.3.0...v0.3.1) (2017-06-20)
69 |
70 |
71 | ### Bug Fixes
72 |
73 | * correct webpack setup ([9e0f3f0](https://github.com/skovhus/css-modules-flow-types/commit/9e0f3f0))
74 |
75 |
76 |
77 |
78 | # [0.3.0](https://github.com/skovhus/css-modules-flow-types/compare/v0.2.2...v0.3.0) (2017-06-19)
79 |
80 |
81 | ### Features
82 |
83 | * detect dangling .flow files ([d006402](https://github.com/skovhus/css-modules-flow-types/commit/d006402))
84 |
85 |
86 |
87 |
88 | ## [0.2.2](https://github.com/skovhus/css-modules-flow-types/compare/v0.2.1...v0.2.2) (2017-06-18)
89 |
90 |
91 | ### Bug Fixes
92 |
93 | * spelling and flow pragma on top ([286fd58](https://github.com/skovhus/css-modules-flow-types/commit/286fd58))
94 |
95 |
96 |
97 |
98 | ## [0.2.1](https://github.com/skovhus/css-modules-flow-types/compare/v0.2.0...v0.2.1) (2017-06-18)
99 |
100 |
101 |
102 |
103 | # [0.2.0](https://github.com/skovhus/css-modules-flow-types/compare/v0.1.3...v0.2.0) (2017-06-18)
104 |
105 |
106 | ### Bug Fixes
107 |
108 | * also emit empty .css.flow files (closes [#2](https://github.com/skovhus/css-modules-flow-types/issues/2)) ([ed07c60](https://github.com/skovhus/css-modules-flow-types/commit/ed07c60))
109 |
110 |
111 |
112 |
113 | ## [0.1.3](https://github.com/skovhus/css-modules-flow-types/compare/v0.1.2...v0.1.3) (2017-06-18)
114 |
115 |
116 | ### Bug Fixes
117 |
118 | * correct cli binary path ([fa26038](https://github.com/skovhus/css-modules-flow-types/commit/fa26038))
119 |
120 |
121 |
122 |
123 | ## [0.1.2](https://github.com/skovhus/css-modules-flow-types/compare/v0.1.1...v0.1.2) (2017-06-16)
124 |
125 |
126 | ### Bug Fixes
127 |
128 | * webpack loader cannot use emitFile when running in dev mode ([2ac51b0](https://github.com/skovhus/css-modules-flow-types/commit/2ac51b0))
129 |
130 |
131 |
132 |
133 | ## [0.1.1](https://github.com/skovhus/css-modules-flow-types/compare/v0.1.0...v0.1.1) (2017-06-16)
134 |
135 |
136 |
137 |
138 | # 0.1.0 (2017-06-16)
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Kenneth Skovhus
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
css-modules-flow-types
3 |
4 | [](https://github.com/skovhus/css-modules-flow-types-loader/blob/master/LICENSE)
5 | [](http://makeapullrequest.com)
6 |
7 |
8 | CLI and Webpack loader for creating [Flow](https://flow.org/) type definitions based on [CSS Modules](https://github.com/css-modules/css-modules) files.
9 |
10 | This gives you:
11 | - auto-completing for css files in most editors
12 | - flow type safety showing usage of non existing classes
13 |
14 | Read more about the background in this blog post: ["Type safe CSS Modules with Flow"](https://hackernoon.com/type-safe-css-modules-with-flow-dd95e761bbe5).
15 |
16 |
17 | ## Example
18 |
19 | Given the following css file using CSS Modules:
20 | ```css
21 | @value primary: red;
22 |
23 | .myClass {
24 | color: primary;
25 | }
26 | ```
27 |
28 | `css-modules-flow-types` creates the following .flow file next to it:
29 |
30 | ```javascript
31 | // @flow
32 | /* This file is automatically generated by css-modules-flow-types */
33 | declare module.exports: {|
34 | +'myClass': string;
35 | +'primary': string;
36 | |};
37 | ```
38 |
39 |
40 | ## Usage (Webpack loader)
41 |
42 | ### style-loader
43 | The `css-modules-flow-types-loader` need to be added right after after `style-loader`:
44 |
45 | ```sh
46 | $ npm install --dev css-modules-flow-types-loader
47 | $ yarn add -D css-modules-flow-types-loader
48 | ```
49 |
50 | ```javascript
51 | {
52 | test: /\.css$/, // or the file format you are using for your CSS Modules
53 | use: [
54 | 'style-loader',
55 | 'css-modules-flow-types-loader',
56 | // Other loaders like css-loader after this:
57 | {
58 | ...
59 | }
60 | ]
61 | }
62 | ```
63 |
64 | ### css-loader
65 |
66 | For `css-loader`, `css-modules-flow-types-loader` needs to come _before_
67 | `css-loader`.
68 |
69 | ```javascript
70 | {
71 | test: /\.css$/, // or the file format you are using for your CSS Modules
72 | use: [
73 | ExtractTextPlugin.extract({
74 | use: [
75 | 'css-modules-flow-types-loader',
76 | {
77 | loader: 'css-loader',
78 | options: {}, // Any options for css-loader
79 | }
80 | ]
81 | })
82 | ]
83 | }
84 | ```
85 |
86 | ## Usage (CLI)
87 |
88 | ```sh
89 | $ npm install --dev css-modules-flow-types-cli
90 | $ yarn add -D css-modules-flow-types-cli
91 | ```
92 |
93 | This installs the runner as `css-modules-flow-types`.
94 |
95 | And run `css-modules-flow-types ` command.
96 |
97 | For example, if you have .css files under `src` directory, exec the following:
98 |
99 | Running,
100 |
101 | ```sh
102 | css-modules-flow-types src
103 | ```
104 |
105 | Creates `*.css.flow` files next to all css files.
106 |
107 | ```text
108 | (your project root)
109 | - src/
110 | | myStyle.css
111 | | myStyle.css.flow [created]
112 | ```
113 |
114 |
115 |
116 | ## Troubleshooting
117 |
118 | ### Support for other file extensions
119 |
120 | To support `.scss`, `.sass`, `.scss.module` or similar files extensions
121 | you need to update your `.flowconfig` file with the following section:
122 |
123 | ```
124 | [options]
125 |
126 | ; Extensions
127 | module.file_ext=.js
128 | module.file_ext=.jsx
129 | module.file_ext=.json
130 | module.file_ext=.css
131 | module.file_ext=.scss
132 | module.file_ext=.sass
133 | module.file_ext=.scss.module
134 | // other files used by flow
135 | ```
136 |
137 | Without this Flow might error out with `Required module not found`.
138 |
139 | ### Dynamic imports in Webpack
140 |
141 | In some cases, attempting to load imports using dynamic references could choke webpack as it attempts to parse `.flow` files and encounters unknown syntax. The solution is to exclude `.flow` files with a `webpackExclude` directive in the import statement.
142 |
143 | If you have an import like this:
144 |
145 | ```javascript
146 | import(
147 | /* webpackChunkName: "[request]" */
148 | `/Path/To/Components/${ getComponent()}`
149 | )
150 | ```
151 |
152 | Add `webpackExclude` like this:
153 |
154 | ```javascript
155 | import(
156 | /* webpackChunkName: "[request]" */
157 | /* webpackExclude: /\.flow$/ */
158 | `/Path/To/Components/${ getComponent()}`
159 | )
160 | ```
161 |
162 | ## Inspiration
163 |
164 | - https://github.com/Quramy/typed-css-modules
165 | - https://github.com/Jimdo/typings-for-css-modules-loader
166 |
167 |
168 | ## Contributing
169 |
170 | To get started, run:
171 |
172 | yarn
173 |
174 | When developing:
175 |
176 | yarn verify # (runs lint and unit test)
177 | yarn lint
178 | yarn test
179 | yarn test:cov
180 | yarn test:watch
181 |
182 |
183 | ## Deployment
184 |
185 | On a new branch run:
186 |
187 | yarn lerna version --no-git-tag-version
188 | # update the CHANGELOG.md file
189 | git add -p
190 | git commit -m 'chore: bump version to x.x'
191 |
192 | Once the branch is merged, the new version is deployed.
193 |
194 | ## License
195 | This software is released under the MIT License.
196 |
--------------------------------------------------------------------------------
/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "4"
8 | }
9 | }
10 | ]
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/fixtures/composee.css:
--------------------------------------------------------------------------------
1 | .box {
2 | padding: 0;
3 | }
4 |
--------------------------------------------------------------------------------
/fixtures/composer.css:
--------------------------------------------------------------------------------
1 | .root {
2 | composes: box from "./composee.css";
3 | color: red;
4 | }
5 |
--------------------------------------------------------------------------------
/fixtures/empty.css:
--------------------------------------------------------------------------------
1 | /*
2 | .box {
3 | padding: 0;
4 | }
5 | */
6 |
--------------------------------------------------------------------------------
/fixtures/errorCss.css:
--------------------------------------------------------------------------------
1 |
2 | .class {
3 |
--------------------------------------------------------------------------------
/fixtures/example.css:
--------------------------------------------------------------------------------
1 | @value primary: red;
2 |
3 | .myClass {color: red;}
4 |
5 | .while {
6 | color: red;
7 | }
8 |
9 | .my-class {
10 | color: red;
11 | }
12 |
13 | .a {}
14 |
--------------------------------------------------------------------------------
/fixtures/invalidComposer.scss:
--------------------------------------------------------------------------------
1 | .myClass {
2 | composes: something from 'path/that/cant/be/found.scss';
3 | background: red;
4 | }
5 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "lerna": "3.22.1",
4 | "npmClient": "yarn",
5 | "packages": [
6 | "packages/*"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "build": "lerna run build",
5 | "verify": "yarn run lint && yarn run test:cov",
6 | "verify:bail": "eslint packages && yarn run test:cov",
7 | "clean": "rm -rf coverage *.log packages/*/dist && lerna clean --yes",
8 | "lint": "eslint --fix packages",
9 | "prepublishOnly": "yarn run build && yarn run verify:bail",
10 | "postinstall": "lerna run build && lerna bootstrap --concurrency=1",
11 | "ci": "yarn run verify:bail",
12 | "test:cov": "yarn run test --coverage",
13 | "test:watch": "yarn run test --watch",
14 | "test": "jest --runInBand"
15 | },
16 | "devDependencies": {
17 | "@babel/cli": "^7.10.5",
18 | "@babel/core": "^7.11.1",
19 | "@babel/preset-env": "^7.11.0",
20 | "babel-eslint": "^10.1.0",
21 | "babel-jest": "^26.3.0",
22 | "eslint": "^7.6.0",
23 | "eslint-config-prettier": "^6.11.0",
24 | "eslint-plugin-import": "^2.22.0",
25 | "eslint-plugin-prettier": "^3.1.4",
26 | "jest": "^26.3.0",
27 | "lerna": "^3.22.1",
28 | "prettier": "^2.0.5"
29 | },
30 | "jest": {
31 | "collectCoverageFrom": [
32 | "packages/**/*.js"
33 | ],
34 | "coverageReporters": [
35 | "text",
36 | "html"
37 | ],
38 | "coveragePathIgnorePatterns": [
39 | "/node_modules/",
40 | ".json",
41 | "/dist/"
42 | ],
43 | "testEnvironment": "node"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/README.md:
--------------------------------------------------------------------------------
1 | # css-modules-flow-types-cli [](http://badge.fury.io/js/css-modules-flow-types-cli)
2 |
3 | CLI for creating [Flow](https://flow.org/) type definitions based on [CSS Modules](https://github.com/css-modules/css-modules) files.
4 |
5 | This gives you:
6 | - auto-completing for css files in most editors
7 | - flow type safety showing usage of non existing classes
8 |
9 |
10 | ## Example
11 |
12 | Given the following css file using CSS Modules:
13 | ```css
14 | @value primary: red;
15 |
16 | .myClass {
17 | color: primary;
18 | }
19 | ```
20 |
21 | `css-modules-flow-types` creates the following .flow file next to it:
22 |
23 | ```javascript
24 | // @flow
25 | /* This file is automatically generated by css-modules-flow-types */
26 | declare module.exports: {|
27 | +'myClass': string;
28 | +'primary': string;
29 | |};
30 | ```
31 |
32 |
33 | ## Usage
34 |
35 | ```sh
36 | $ npm install --dev css-modules-flow-types-cli
37 | $ yarn install -D css-modules-flow-types-cli
38 | ```
39 |
40 | This installs the runner as `css-modules-flow-types`.
41 |
42 | And run `css-modules-flow-types ` command.
43 |
44 | For example, if you have .css files under `src` directory, exec the following:
45 |
46 | Running,
47 |
48 | ```sh
49 | css-modules-flow-types src
50 | ```
51 |
52 | Creates `*.css.flow` files next to all css files.
53 |
54 | ```text
55 | (your project root)
56 | - src/
57 | | myStyle.css
58 | | myStyle.css.flow [created]
59 | ```
60 |
61 |
62 | ## Inspiration
63 | - https://github.com/Quramy/typed-css-modules
64 | - https://github.com/Jimdo/typings-for-css-modules-loader
65 |
66 |
67 | ## License
68 | This software is released under the MIT License.
69 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "4"
8 | }
9 | }
10 | ]
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/bin/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | require('../dist/cli');
3 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-modules-flow-types-cli",
3 | "version": "2.0.0",
4 | "description": "CLI for creating flow definitions from CSS Modules files",
5 | "author": "skovhus",
6 | "license": "MIT",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/skovhus/css-modules-flow-types.git"
10 | },
11 | "main": "dist/converter.js",
12 | "bin": {
13 | "css-modules-flow-types": "bin/cli.js"
14 | },
15 | "engines": {
16 | "node": ">=8"
17 | },
18 | "scripts": {
19 | "build": "babel src -d dist --ignore *.test.js",
20 | "prepublishOnly": "cd ../../ && npm run prepublishOnly"
21 | },
22 | "files": [
23 | "bin",
24 | "dist"
25 | ],
26 | "keywords": [
27 | "css-modules",
28 | "types",
29 | "flow"
30 | ],
31 | "dependencies": {
32 | "chalk": "^1.1.3",
33 | "css-modules-flow-types-printer": "^2.0.0",
34 | "css-modules-loader-core": "^1.0.0",
35 | "gaze": "^1.1.1",
36 | "globby": "^6.1.0",
37 | "meow": "^6.0.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/src/__test__/converter.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env jest */
2 | import { EOL, HEADER } from 'css-modules-flow-types-printer';
3 | import Converter from '../converter';
4 |
5 | const converter = new Converter('./fixtures', EOL.LF);
6 |
7 | it('returns sorted content from simple css', () => {
8 | return converter.convert('./example.css').then((content) => {
9 | expect(content).toBe(`${HEADER}
10 | declare module.exports: {|
11 | +'a': string,
12 | +'my-class': string,
13 | +'myClass': string,
14 | +'primary': string,
15 | +'while': string,
16 | |};
17 | `);
18 | });
19 | });
20 |
21 | it('returns content from empty css files', () => {
22 | return converter.convert('./empty.css').then((content) => {
23 | expect(content).toBe(`${HEADER}
24 | declare module.exports: {|
25 |
26 | |};
27 | `);
28 | });
29 | });
30 |
31 | it('rejects invalid CSS', () => {
32 | expect.assertions(1);
33 | return converter.convert('./errorCss.css').catch((err) => {
34 | expect(err.name).toBe('CssSyntaxError');
35 | });
36 | });
37 |
38 | it('returns content from composing css', () => {
39 | return converter.convert('./composer.css').then((content) => {
40 | expect(content).toBe(`${HEADER}
41 | declare module.exports: {|
42 | +'root': string,
43 | |};
44 | `);
45 | });
46 | });
47 |
48 | it('returns content from composing css whose has invalid import/composes', () => {
49 | return converter.convert('./invalidComposer.scss').then((content) => {
50 | expect(content).toBe(`${HEADER}
51 | declare module.exports: {|
52 | +'myClass': string,
53 | |};
54 | `);
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/src/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict';
3 |
4 | import path from 'path';
5 |
6 | import chalk from 'chalk';
7 | import gaze from 'gaze';
8 | import globby from 'globby';
9 | import meow from 'meow';
10 |
11 | import Converter from './converter';
12 | import writeFile from './writer';
13 |
14 | const cli = meow(
15 | {
16 | description: 'Creates .flow type definition files from CSS Modules files',
17 | help: `
18 | Usage
19 | $ css-modules-flow-types [] [options]
20 |
21 | path directory to search for CSS Modules (or concrete files to convert)
22 |
23 | Options
24 | --watch, -w Run in watch mode
25 | --extension, -e File extension (defaults to "css")
26 | --silent, -s Silences all output except errors
27 | `,
28 | inferType: true,
29 | },
30 | {
31 | flags: {
32 | _: {
33 | type: 'string',
34 | },
35 | extension: {
36 | alias: 'e',
37 | },
38 | help: {
39 | alias: 'h',
40 | },
41 | silent: {
42 | alias: 's',
43 | type: 'boolean',
44 | },
45 | watch: {
46 | alias: 'w',
47 | type: 'boolean',
48 | },
49 | },
50 | }
51 | );
52 |
53 | function detectDanlingFlowFiles(filesPattern, cssFiles) {
54 | const flowFiles = globby.sync(filesPattern + '.flow');
55 | const cssFilesSet = new Set(cssFiles);
56 | const danglingFlowFiles = flowFiles.filter(
57 | (f) => !cssFilesSet.has(f.replace('.flow', ''))
58 | );
59 |
60 | if (danglingFlowFiles.length > 0) {
61 | console.error(
62 | chalk.red(
63 | `Detected ${danglingFlowFiles.length} dangling .flow file(s), that can be removed:`
64 | )
65 | );
66 | danglingFlowFiles.forEach((f) => {
67 | console.error(chalk.red(`- ${f}`));
68 | });
69 | }
70 | }
71 |
72 | const main = () => {
73 | const { watch, silent } = cli.flags;
74 |
75 | if (!cli.input || cli.input.length === 0) {
76 | return cli.showHelp();
77 | }
78 |
79 | const extension = cli.flags.extension || 'css';
80 |
81 | const filesList = cli.input.length > 1 ? cli.input : null;
82 | const filePath = cli.input.length === 1 ? cli.input[0] : null;
83 | const filesPattern = filePath && path.join(filePath, `**/*.${extension}`);
84 |
85 | const rootDir = process.cwd();
86 | const converter = new Converter(rootDir);
87 |
88 | function handleFile(filePath) {
89 | const f = path.resolve(filePath);
90 | converter
91 | .convert(f)
92 | .then((content) => {
93 | const outputFilePath = path.join(f + '.flow');
94 | return writeFile(outputFilePath, content);
95 | })
96 | .then((outputFilePath) => {
97 | if (!silent) {
98 | console.log('Wrote ' + chalk.green(outputFilePath));
99 | }
100 | })
101 | .catch((reason) => console.error(chalk.red('[Error] ' + reason)));
102 | }
103 |
104 | if (!watch) {
105 | const cssFiles = filesList ? filesList : globby.sync(filesPattern);
106 | cssFiles.forEach(handleFile);
107 |
108 | if (!filesList) {
109 | detectDanlingFlowFiles(filesPattern, cssFiles);
110 | }
111 | } else {
112 | if (!filePath) {
113 | console.error(
114 | chalk.red(`Watch mode requires a single path... Not ${filesList}`)
115 | );
116 | return;
117 | }
118 | gaze(filesPattern, function (err, files) {
119 | this.on('changed', handleFile);
120 | this.on('added', handleFile);
121 | });
122 | }
123 | };
124 |
125 | main();
126 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/src/converter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import printFlowDefinition, {
4 | getLineSeparator,
5 | } from 'css-modules-flow-types-printer';
6 | import FileSystemLoader from './css-modules/fileSystemLoader';
7 |
8 | export default class Converter {
9 | constructor(rootDir, eol) {
10 | this.loader = new FileSystemLoader(rootDir);
11 | this.eol = eol;
12 | }
13 |
14 | convert(filePath) {
15 | return new Promise((resolve, reject) => {
16 | // TODO: benchmark this (maybe this should only be cleared when watching)
17 | this.loader.tokensByFile = {};
18 |
19 | this.loader
20 | .fetch(filePath, '/', undefined, undefined)
21 | .then((res) => {
22 | if (res) {
23 | const tokens = Object.keys(res);
24 | const content = printFlowDefinition(
25 | tokens,
26 | this.eol || getLineSeparator(tokens[0])
27 | );
28 | resolve(content);
29 | } else {
30 | reject(res);
31 | }
32 | })
33 | .catch((err) => reject(err));
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/src/css-modules/fileSystemLoader.js:
--------------------------------------------------------------------------------
1 | /*
2 | Notice:
3 |
4 | This file was originally forked from: https://raw.githubusercontent.com/css-modules/css-modules-loader-core/master/src/file-system-loader.js
5 |
6 | See:
7 | https://github.com/Quramy/typed-css-modules/blob/master/src/fileSystemLoader.js
8 | */
9 | /* this file is forked from https://raw.githubusercontent.com/css-modules/css-modules-loader-core/master/src/file-system-loader.js */
10 | /* eslint-disable prefer-const, no-empty, prettier/prettier */
11 | // prettier-ignore
12 |
13 | import fs from 'fs';
14 | import path from 'path';
15 |
16 | import Core from 'css-modules-loader-core';
17 |
18 | export default class FileSystemLoader {
19 | constructor(root, plugins) {
20 | this.root = root;
21 | this.sources = {};
22 | this.importNr = 0;
23 | this.core = new Core(plugins);
24 | this.tokensByFile = {};
25 | }
26 |
27 | fetch(_newPath, relativeTo, _trace, initialContents) {
28 | let newPath = _newPath.replace(/^["']|["']$/g, ''),
29 | trace = _trace || String.fromCharCode(this.importNr++);
30 | return new Promise((resolve, reject) => {
31 | let relativeDir = path.dirname(relativeTo),
32 | rootRelativePath = path.resolve(relativeDir, newPath),
33 | fileRelativePath = path.resolve(
34 | path.join(this.root, relativeDir),
35 | newPath
36 | );
37 |
38 | // if the path is not relative or absolute, try to resolve it in node_modules
39 | if (newPath[0] !== '.' && newPath[0] !== '/') {
40 | try {
41 | fileRelativePath = require.resolve(newPath);
42 | } catch (e) {}
43 | }
44 |
45 | if (!initialContents) {
46 | const tokens = this.tokensByFile[fileRelativePath];
47 | if (tokens) {
48 | return resolve(tokens);
49 | }
50 |
51 | fs.readFile(fileRelativePath, 'utf-8', (err, source) => {
52 | if (err && relativeTo && relativeTo !== '/') {
53 | resolve([]);
54 | } else if (err && (!relativeTo || relativeTo === '/')) {
55 | reject(err);
56 | } else {
57 | this.core
58 | .load(source, rootRelativePath, trace, this.fetch.bind(this))
59 | .then(({ injectableSource, exportTokens }) => {
60 | this.sources[trace] = injectableSource;
61 | this.tokensByFile[fileRelativePath] = exportTokens;
62 | resolve(exportTokens);
63 | }, reject);
64 | }
65 | });
66 | } else {
67 | this.core
68 | .load(initialContents, rootRelativePath, trace, this.fetch.bind(this))
69 | .then(({ injectableSource, exportTokens }) => {
70 | this.sources[trace] = injectableSource;
71 | this.tokensByFile[fileRelativePath] = exportTokens;
72 | resolve(exportTokens);
73 | }, reject);
74 | }
75 | });
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/src/writer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import fs from 'fs';
4 |
5 | export default function writeFile(outputFilePath, content) {
6 | return new Promise((resolve, reject) => {
7 | fs.writeFile(outputFilePath, content, 'utf8', (err) => {
8 | if (err) {
9 | reject(err);
10 | } else {
11 | resolve(outputFilePath);
12 | }
13 | });
14 | });
15 | }
16 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-cli/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/code-frame@^7.0.0":
6 | version "7.14.5"
7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
8 | integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
9 | dependencies:
10 | "@babel/highlight" "^7.14.5"
11 |
12 | "@babel/helper-validator-identifier@^7.14.5":
13 | version "7.14.5"
14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8"
15 | integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==
16 |
17 | "@babel/highlight@^7.14.5":
18 | version "7.14.5"
19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
20 | integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
21 | dependencies:
22 | "@babel/helper-validator-identifier" "^7.14.5"
23 | chalk "^2.0.0"
24 | js-tokens "^4.0.0"
25 |
26 | "@types/minimist@^1.2.0":
27 | version "1.2.1"
28 | resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
29 | integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
30 |
31 | "@types/normalize-package-data@^2.4.0":
32 | version "2.4.0"
33 | resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
34 | integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
35 |
36 | ansi-regex@^2.0.0:
37 | version "2.1.1"
38 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
39 |
40 | ansi-styles@^2.2.1:
41 | version "2.2.1"
42 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
43 |
44 | ansi-styles@^3.2.1:
45 | version "3.2.1"
46 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
47 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
48 | dependencies:
49 | color-convert "^1.9.0"
50 |
51 | array-union@^1.0.1:
52 | version "1.0.2"
53 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
54 | dependencies:
55 | array-uniq "^1.0.1"
56 |
57 | array-uniq@^1.0.1:
58 | version "1.0.3"
59 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
60 |
61 | arrify@^1.0.1:
62 | version "1.0.1"
63 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
64 | integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
65 |
66 | balanced-match@^1.0.0:
67 | version "1.0.2"
68 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
69 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
70 |
71 | brace-expansion@^1.1.7:
72 | version "1.1.11"
73 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
74 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
75 | dependencies:
76 | balanced-match "^1.0.0"
77 | concat-map "0.0.1"
78 |
79 | camelcase-keys@^6.2.2:
80 | version "6.2.2"
81 | resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0"
82 | integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==
83 | dependencies:
84 | camelcase "^5.3.1"
85 | map-obj "^4.0.0"
86 | quick-lru "^4.0.1"
87 |
88 | camelcase@^5.0.0, camelcase@^5.3.1:
89 | version "5.3.1"
90 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
91 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
92 |
93 | chalk@^1.1.3:
94 | version "1.1.3"
95 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
96 | dependencies:
97 | ansi-styles "^2.2.1"
98 | escape-string-regexp "^1.0.2"
99 | has-ansi "^2.0.0"
100 | strip-ansi "^3.0.0"
101 | supports-color "^2.0.0"
102 |
103 | chalk@^2.0.0:
104 | version "2.4.2"
105 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
106 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
107 | dependencies:
108 | ansi-styles "^3.2.1"
109 | escape-string-regexp "^1.0.5"
110 | supports-color "^5.3.0"
111 |
112 | color-convert@^1.9.0:
113 | version "1.9.3"
114 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
115 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
116 | dependencies:
117 | color-name "1.1.3"
118 |
119 | color-name@1.1.3:
120 | version "1.1.3"
121 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
122 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
123 |
124 | concat-map@0.0.1:
125 | version "0.0.1"
126 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
127 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
128 |
129 | css-modules-flow-types-printer@^2.0.0:
130 | version "2.0.0"
131 | resolved "https://registry.yarnpkg.com/css-modules-flow-types-printer/-/css-modules-flow-types-printer-2.0.0.tgz#f3308c4a81169dd9a933ccb0e76e3a49bf58c4dc"
132 | integrity sha512-OJXluvPgEzifS0IO/cSaHrVpZL9Cz1wqYv58WIpD4tB8so+a43xhnoiZWx28Rr6zyqQdsW5IoS5aCPZl66AKFg==
133 |
134 | css-modules-loader-core@^1.0.0:
135 | version "1.1.0"
136 | resolved "https://registry.yarnpkg.com/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz#5908668294a1becd261ae0a4ce21b0b551f21d16"
137 | dependencies:
138 | icss-replace-symbols "1.1.0"
139 | postcss "6.0.1"
140 | postcss-modules-extract-imports "1.1.0"
141 | postcss-modules-local-by-default "1.2.0"
142 | postcss-modules-scope "1.1.0"
143 | postcss-modules-values "1.3.0"
144 |
145 | css-selector-tokenizer@^0.7.0:
146 | version "0.7.0"
147 | resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86"
148 | dependencies:
149 | cssesc "^0.1.0"
150 | fastparse "^1.1.1"
151 | regexpu-core "^1.0.0"
152 |
153 | cssesc@^0.1.0:
154 | version "0.1.0"
155 | resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
156 |
157 | decamelize-keys@^1.1.0:
158 | version "1.1.0"
159 | resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
160 | integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=
161 | dependencies:
162 | decamelize "^1.1.0"
163 | map-obj "^1.0.0"
164 |
165 | decamelize@^1.1.0, decamelize@^1.2.0:
166 | version "1.2.0"
167 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
168 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
169 |
170 | error-ex@^1.3.1:
171 | version "1.3.2"
172 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
173 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
174 | dependencies:
175 | is-arrayish "^0.2.1"
176 |
177 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
178 | version "1.0.5"
179 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
180 |
181 | fastparse@^1.1.1:
182 | version "1.1.1"
183 | resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
184 |
185 | find-up@^4.1.0:
186 | version "4.1.0"
187 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
188 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
189 | dependencies:
190 | locate-path "^5.0.0"
191 | path-exists "^4.0.0"
192 |
193 | fs.realpath@^1.0.0:
194 | version "1.0.0"
195 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
196 |
197 | function-bind@^1.1.1:
198 | version "1.1.1"
199 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
200 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
201 |
202 | gaze@^1.1.1:
203 | version "1.1.2"
204 | resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105"
205 | dependencies:
206 | globule "^1.0.0"
207 |
208 | glob@^7.0.3, glob@~7.1.1:
209 | version "7.1.2"
210 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
211 | dependencies:
212 | fs.realpath "^1.0.0"
213 | inflight "^1.0.4"
214 | inherits "2"
215 | minimatch "^3.0.4"
216 | once "^1.3.0"
217 | path-is-absolute "^1.0.0"
218 |
219 | globby@^6.1.0:
220 | version "6.1.0"
221 | resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c"
222 | dependencies:
223 | array-union "^1.0.1"
224 | glob "^7.0.3"
225 | object-assign "^4.0.1"
226 | pify "^2.0.0"
227 | pinkie-promise "^2.0.0"
228 |
229 | globule@^1.0.0:
230 | version "1.2.0"
231 | resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09"
232 | dependencies:
233 | glob "~7.1.1"
234 | lodash "~4.17.4"
235 | minimatch "~3.0.2"
236 |
237 | hard-rejection@^2.1.0:
238 | version "2.1.0"
239 | resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883"
240 | integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==
241 |
242 | has-ansi@^2.0.0:
243 | version "2.0.0"
244 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
245 | dependencies:
246 | ansi-regex "^2.0.0"
247 |
248 | has-flag@^1.0.0:
249 | version "1.0.0"
250 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
251 |
252 | has-flag@^3.0.0:
253 | version "3.0.0"
254 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
255 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
256 |
257 | has@^1.0.3:
258 | version "1.0.3"
259 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
260 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
261 | dependencies:
262 | function-bind "^1.1.1"
263 |
264 | hosted-git-info@^2.1.4:
265 | version "2.8.9"
266 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
267 | integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
268 |
269 | icss-replace-symbols@1.1.0, icss-replace-symbols@^1.1.0:
270 | version "1.1.0"
271 | resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
272 |
273 | indent-string@^4.0.0:
274 | version "4.0.0"
275 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
276 | integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
277 |
278 | inflight@^1.0.4:
279 | version "1.0.6"
280 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
281 | dependencies:
282 | once "^1.3.0"
283 | wrappy "1"
284 |
285 | inherits@2:
286 | version "2.0.3"
287 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
288 |
289 | is-arrayish@^0.2.1:
290 | version "0.2.1"
291 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
292 |
293 | is-core-module@^2.2.0:
294 | version "2.4.0"
295 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
296 | integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
297 | dependencies:
298 | has "^1.0.3"
299 |
300 | is-plain-obj@^1.1.0:
301 | version "1.1.0"
302 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
303 | integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
304 |
305 | js-tokens@^4.0.0:
306 | version "4.0.0"
307 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
308 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
309 |
310 | jsesc@~0.5.0:
311 | version "0.5.0"
312 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
313 |
314 | json-parse-even-better-errors@^2.3.0:
315 | version "2.3.1"
316 | resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
317 | integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
318 |
319 | kind-of@^6.0.3:
320 | version "6.0.3"
321 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
322 | integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
323 |
324 | lines-and-columns@^1.1.6:
325 | version "1.1.6"
326 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
327 | integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
328 |
329 | locate-path@^5.0.0:
330 | version "5.0.0"
331 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
332 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
333 | dependencies:
334 | p-locate "^4.1.0"
335 |
336 | lodash@~4.17.4:
337 | version "4.17.21"
338 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
339 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
340 |
341 | map-obj@^1.0.0:
342 | version "1.0.1"
343 | resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
344 |
345 | map-obj@^4.0.0:
346 | version "4.2.1"
347 | resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.1.tgz#e4ea399dbc979ae735c83c863dd31bdf364277b7"
348 | integrity sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==
349 |
350 | meow@^6.0.0:
351 | version "6.1.1"
352 | resolved "https://registry.yarnpkg.com/meow/-/meow-6.1.1.tgz#1ad64c4b76b2a24dfb2f635fddcadf320d251467"
353 | integrity sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==
354 | dependencies:
355 | "@types/minimist" "^1.2.0"
356 | camelcase-keys "^6.2.2"
357 | decamelize-keys "^1.1.0"
358 | hard-rejection "^2.1.0"
359 | minimist-options "^4.0.2"
360 | normalize-package-data "^2.5.0"
361 | read-pkg-up "^7.0.1"
362 | redent "^3.0.0"
363 | trim-newlines "^3.0.0"
364 | type-fest "^0.13.1"
365 | yargs-parser "^18.1.3"
366 |
367 | min-indent@^1.0.0:
368 | version "1.0.1"
369 | resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
370 | integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
371 |
372 | minimatch@^3.0.4, minimatch@~3.0.2:
373 | version "3.0.8"
374 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1"
375 | integrity sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==
376 | dependencies:
377 | brace-expansion "^1.1.7"
378 |
379 | minimist-options@^4.0.2:
380 | version "4.1.0"
381 | resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
382 | integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==
383 | dependencies:
384 | arrify "^1.0.1"
385 | is-plain-obj "^1.1.0"
386 | kind-of "^6.0.3"
387 |
388 | normalize-package-data@^2.5.0:
389 | version "2.5.0"
390 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
391 | integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
392 | dependencies:
393 | hosted-git-info "^2.1.4"
394 | resolve "^1.10.0"
395 | semver "2 || 3 || 4 || 5"
396 | validate-npm-package-license "^3.0.1"
397 |
398 | object-assign@^4.0.1:
399 | version "4.1.1"
400 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
401 |
402 | once@^1.3.0:
403 | version "1.4.0"
404 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
405 | dependencies:
406 | wrappy "1"
407 |
408 | p-limit@^2.2.0:
409 | version "2.3.0"
410 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
411 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
412 | dependencies:
413 | p-try "^2.0.0"
414 |
415 | p-locate@^4.1.0:
416 | version "4.1.0"
417 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
418 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
419 | dependencies:
420 | p-limit "^2.2.0"
421 |
422 | p-try@^2.0.0:
423 | version "2.2.0"
424 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
425 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
426 |
427 | parse-json@^5.0.0:
428 | version "5.2.0"
429 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
430 | integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
431 | dependencies:
432 | "@babel/code-frame" "^7.0.0"
433 | error-ex "^1.3.1"
434 | json-parse-even-better-errors "^2.3.0"
435 | lines-and-columns "^1.1.6"
436 |
437 | path-exists@^4.0.0:
438 | version "4.0.0"
439 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
440 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
441 |
442 | path-is-absolute@^1.0.0:
443 | version "1.0.1"
444 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
445 |
446 | path-parse@^1.0.6:
447 | version "1.0.7"
448 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
449 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
450 |
451 | pify@^2.0.0:
452 | version "2.3.0"
453 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
454 |
455 | pinkie-promise@^2.0.0:
456 | version "2.0.1"
457 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
458 | dependencies:
459 | pinkie "^2.0.0"
460 |
461 | pinkie@^2.0.0:
462 | version "2.0.4"
463 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
464 |
465 | postcss-modules-extract-imports@1.1.0:
466 | version "1.1.0"
467 | resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz#b614c9720be6816eaee35fb3a5faa1dba6a05ddb"
468 | dependencies:
469 | postcss "^6.0.1"
470 |
471 | postcss-modules-local-by-default@1.2.0:
472 | version "1.2.0"
473 | resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069"
474 | dependencies:
475 | css-selector-tokenizer "^0.7.0"
476 | postcss "^6.0.1"
477 |
478 | postcss-modules-scope@1.1.0:
479 | version "1.1.0"
480 | resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90"
481 | dependencies:
482 | css-selector-tokenizer "^0.7.0"
483 | postcss "^6.0.1"
484 |
485 | postcss-modules-values@1.3.0:
486 | version "1.3.0"
487 | resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20"
488 | dependencies:
489 | icss-replace-symbols "^1.1.0"
490 | postcss "^6.0.1"
491 |
492 | postcss@6.0.1, postcss@^6.0.1:
493 | version "6.0.1"
494 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.1.tgz#000dbd1f8eef217aa368b9a212c5fc40b2a8f3f2"
495 | dependencies:
496 | chalk "^1.1.3"
497 | source-map "^0.5.6"
498 | supports-color "^3.2.3"
499 |
500 | quick-lru@^4.0.1:
501 | version "4.0.1"
502 | resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
503 | integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
504 |
505 | read-pkg-up@^7.0.1:
506 | version "7.0.1"
507 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
508 | integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==
509 | dependencies:
510 | find-up "^4.1.0"
511 | read-pkg "^5.2.0"
512 | type-fest "^0.8.1"
513 |
514 | read-pkg@^5.2.0:
515 | version "5.2.0"
516 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
517 | integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
518 | dependencies:
519 | "@types/normalize-package-data" "^2.4.0"
520 | normalize-package-data "^2.5.0"
521 | parse-json "^5.0.0"
522 | type-fest "^0.6.0"
523 |
524 | redent@^3.0.0:
525 | version "3.0.0"
526 | resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"
527 | integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==
528 | dependencies:
529 | indent-string "^4.0.0"
530 | strip-indent "^3.0.0"
531 |
532 | regenerate@^1.2.1:
533 | version "1.3.2"
534 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
535 |
536 | regexpu-core@^1.0.0:
537 | version "1.0.0"
538 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b"
539 | dependencies:
540 | regenerate "^1.2.1"
541 | regjsgen "^0.2.0"
542 | regjsparser "^0.1.4"
543 |
544 | regjsgen@^0.2.0:
545 | version "0.2.0"
546 | resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
547 |
548 | regjsparser@^0.1.4:
549 | version "0.1.5"
550 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
551 | dependencies:
552 | jsesc "~0.5.0"
553 |
554 | resolve@^1.10.0:
555 | version "1.20.0"
556 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
557 | integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
558 | dependencies:
559 | is-core-module "^2.2.0"
560 | path-parse "^1.0.6"
561 |
562 | "semver@2 || 3 || 4 || 5":
563 | version "5.3.0"
564 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
565 |
566 | source-map@^0.5.6:
567 | version "0.5.6"
568 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
569 |
570 | spdx-correct@~1.0.0:
571 | version "1.0.2"
572 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
573 | dependencies:
574 | spdx-license-ids "^1.0.2"
575 |
576 | spdx-expression-parse@~1.0.0:
577 | version "1.0.4"
578 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c"
579 |
580 | spdx-license-ids@^1.0.2:
581 | version "1.2.2"
582 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57"
583 |
584 | strip-ansi@^3.0.0:
585 | version "3.0.1"
586 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
587 | dependencies:
588 | ansi-regex "^2.0.0"
589 |
590 | strip-indent@^3.0.0:
591 | version "3.0.0"
592 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001"
593 | integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
594 | dependencies:
595 | min-indent "^1.0.0"
596 |
597 | supports-color@^2.0.0:
598 | version "2.0.0"
599 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
600 |
601 | supports-color@^3.2.3:
602 | version "3.2.3"
603 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
604 | dependencies:
605 | has-flag "^1.0.0"
606 |
607 | supports-color@^5.3.0:
608 | version "5.5.0"
609 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
610 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
611 | dependencies:
612 | has-flag "^3.0.0"
613 |
614 | trim-newlines@^3.0.0:
615 | version "3.0.1"
616 | resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144"
617 | integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
618 |
619 | type-fest@^0.13.1:
620 | version "0.13.1"
621 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
622 | integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
623 |
624 | type-fest@^0.6.0:
625 | version "0.6.0"
626 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
627 | integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
628 |
629 | type-fest@^0.8.1:
630 | version "0.8.1"
631 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
632 | integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
633 |
634 | validate-npm-package-license@^3.0.1:
635 | version "3.0.1"
636 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc"
637 | dependencies:
638 | spdx-correct "~1.0.0"
639 | spdx-expression-parse "~1.0.0"
640 |
641 | wrappy@1:
642 | version "1.0.2"
643 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
644 |
645 | yargs-parser@^18.1.3:
646 | version "18.1.3"
647 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
648 | integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
649 | dependencies:
650 | camelcase "^5.0.0"
651 | decamelize "^1.2.0"
652 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-loader/README.md:
--------------------------------------------------------------------------------
1 | # css-modules-flow-types-loader [](http://badge.fury.io/js/css-modules-flow-types-loader)
2 |
3 | Webpack loader for creating [Flow](https://flow.org/) type definitions based on [CSS Modules](https://github.com/css-modules/css-modules) files.
4 |
5 | This gives you:
6 | - auto-completing for css files in most editors
7 | - flow type safety showing usage of non existing classes
8 |
9 |
10 | ## Example
11 |
12 | Given the following css file using CSS Modules:
13 | ```css
14 | @value primary: red;
15 |
16 | .myClass {
17 | color: primary;
18 | }
19 | ```
20 |
21 | `css-modules-flow-types` creates the following .flow file next to it:
22 |
23 | ```javascript
24 | // @flow
25 | /* This file is automatically generated by css-modules-flow-types */
26 | declare module.exports: {|
27 | +'myClass': string;
28 | +'primary': string;
29 | |};
30 | ```
31 |
32 |
33 | ## Usage
34 |
35 | The `css-modules-flow-types-loader` need to be added right after after `style-loader`:
36 |
37 | ```sh
38 | $ npm install --dev css-modules-flow-types-loader
39 | $ yarn install -D css-modules-flow-types-loader
40 | ```
41 |
42 | ```javascript
43 | {
44 | test: /\.css$/, // or the file format you are using for your CSS Modules
45 | use: [
46 | 'style-loader',
47 | 'css-modules-flow-types-loader',
48 | // Other loaders like css-loader after this:
49 | {
50 | ...
51 | }
52 | ]
53 | }
54 | ```
55 |
56 |
57 | ## Inspiration
58 | - https://github.com/Quramy/typed-css-modules
59 | - https://github.com/Jimdo/typings-for-css-modules-loader
60 |
61 |
62 | ## License
63 | This software is released under the MIT License.
64 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-loader/__mocks__/fs.js:
--------------------------------------------------------------------------------
1 | /* eslint-env jest */
2 |
3 | const fs = jest.genMockFromModule('fs');
4 | module.exports = fs;
5 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-loader/__test__/index.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env jest */
2 | jest.mock('fs');
3 |
4 | import fs from 'fs';
5 | import { HEADER } from 'css-modules-flow-types-printer';
6 | import loader from '../index';
7 |
8 | const getStyleLoaderOutput = (exports = '') => `
9 | // imports
10 |
11 |
12 | // module
13 | exports.push([module.id, ".btn__app-components-Page-styles__2BmYx {\n background: #FFF;\n}\n", "", {"version":3,"sources":["/./app/components/Page/styles.css"],"names":[],"mappings":"AAAA;EACE,iBAAiB;CAClB","file":"styles.css","sourcesContent":[".btn {\n background: #FFF;\n}\n"],"sourceRoot":"webpack://"}]);
14 |
15 | // exports
16 | ${exports}
17 | `;
18 |
19 | const STYLE_LOADER_OUTPUT_LEGACY = getStyleLoaderOutput(`
20 | exports.locals = {
21 | "btn": "btn__app-components-Page-styles__2BmYx"
22 | };
23 | `);
24 |
25 | const STYLE_LOADER_OUTPUT = getStyleLoaderOutput(`
26 | ___CSS_LOADER_EXPORT___.locals = {
27 | "btn": "btn__app-components-Page-styles__2BmYx"
28 | };
29 | `);
30 |
31 | const STYLE_LOADER_OUTPUT_WITH_JS = getStyleLoaderOutput(`
32 | ___CSS_LOADER_EXPORT___.locals = {
33 | "foo": "bar" + require("-!css-loader!styles/baz.scss").locals["xyz"] + "",
34 | "foo2": "bar" + new String('lorem lipsum') + ""
35 | };
36 | `);
37 |
38 | const EMPTY_STYLE_LOADER_OUTPUT = getStyleLoaderOutput();
39 |
40 | describe('webpack loader', () => {
41 | beforeEach(() => {
42 | fs.writeFile.mockReset();
43 | });
44 |
45 | it('emits a css.flow file for a non-empty CSS file with css-loader < v4', () => {
46 | loader.call(
47 | {
48 | resourcePath: 'test.css',
49 | },
50 | STYLE_LOADER_OUTPUT_LEGACY
51 | );
52 |
53 | expect(fs.writeFile.mock.calls.length).toBe(1);
54 | expect(fs.writeFile.mock.calls[0][0]).toBe('test.css.flow');
55 |
56 | expect(fs.writeFile.mock.calls[0][1]).toBe(
57 | `${HEADER}
58 | declare module.exports: {|
59 | +'btn': string,
60 | |};
61 | `
62 | );
63 | });
64 |
65 | it('emits a css.flow file for a non-empty CSS file with css-loader v4', () => {
66 | loader.call(
67 | {
68 | resourcePath: 'test.css',
69 | },
70 | STYLE_LOADER_OUTPUT
71 | );
72 |
73 | expect(fs.writeFile.mock.calls.length).toBe(1);
74 | expect(fs.writeFile.mock.calls[0][0]).toBe('test.css.flow');
75 |
76 | expect(fs.writeFile.mock.calls[0][1]).toBe(
77 | `${HEADER}
78 | declare module.exports: {|
79 | +'btn': string,
80 | |};
81 | `
82 | );
83 | });
84 |
85 | it('emits a css.flow file for an empty css file', () => {
86 | loader.call(
87 | {
88 | resourcePath: 'test.css',
89 | },
90 | EMPTY_STYLE_LOADER_OUTPUT
91 | );
92 |
93 | expect(fs.writeFile.mock.calls.length).toBe(1);
94 | expect(fs.writeFile.mock.calls[0][1]).toBe(
95 | `${HEADER}
96 | declare module.exports: {|
97 |
98 | |};
99 | `
100 | );
101 | });
102 |
103 | it('returns same content as given', () => {
104 | const emitFile = jest.fn();
105 | const returnedContent = loader.call(
106 | {
107 | resourcePath: 'test.css',
108 | emitFile,
109 | },
110 | STYLE_LOADER_OUTPUT
111 | );
112 | expect(returnedContent).toBe(STYLE_LOADER_OUTPUT);
113 | });
114 |
115 | it('does not fail on arbitrary javascript in the ICSS value', () => {
116 | loader.call({ resourcePath: 'test.css' }, STYLE_LOADER_OUTPUT_WITH_JS);
117 |
118 | expect(fs.writeFile.mock.calls[0][1]).toBe(
119 | `${HEADER}
120 | declare module.exports: {|
121 | +'foo': string,
122 | +'foo2': string,
123 | |};
124 | `
125 | );
126 | });
127 | });
128 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-loader/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "4"
8 | }
9 | }
10 | ]
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-loader/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import fs from 'fs';
4 | import printFlowDefinition, {
5 | getLineSeparator,
6 | } from 'css-modules-flow-types-printer';
7 |
8 | function getTokens(content) {
9 | const tokens = [];
10 |
11 | // Only `locals` export is desired
12 | // css-loader v4 uses ___CSS_LOADER_EXPORT___.locals
13 | // css-loader v3 used exports.locals
14 | const locals = content.match(
15 | /(?:exports|___CSS_LOADER_EXPORT___)\.locals = ([\s\S]*);/
16 | );
17 |
18 | if (!locals) return tokens;
19 | let match;
20 |
21 | // RegExp.exec is state-full, so we need to initialize new one for each run
22 | const re = /"(.*?)":.*\n/g;
23 | while ((match = re.exec(locals[1])) !== null) tokens.push(match[1]);
24 |
25 | return tokens;
26 | }
27 |
28 | module.exports = function cssModulesFlowTypesLoader(content) {
29 | const tokens = getTokens(content);
30 |
31 | // NOTE: We cannot use .emitFile as people might use this with devServer
32 | // (e.g. in memory storage).
33 | const outputPath = this.resourcePath + '.flow';
34 | fs.writeFile(
35 | outputPath,
36 | printFlowDefinition(tokens, getLineSeparator(content)),
37 | {},
38 | function () {}
39 | );
40 |
41 | return content;
42 | };
43 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-loader/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-modules-flow-types-loader",
3 | "version": "2.0.0",
4 | "description": "Webpack loader creating Flow type definitions from CSS Modules files",
5 | "author": "skovhus",
6 | "license": "MIT",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/skovhus/css-modules-flow-types.git"
10 | },
11 | "main": "dist/index.js",
12 | "engines": {
13 | "node": ">=8"
14 | },
15 | "scripts": {
16 | "build": "babel *.js -d dist --ignore *.test.js",
17 | "prepublishOnly": "cd ../../ && npm run prepublishOnly"
18 | },
19 | "files": [
20 | "dist"
21 | ],
22 | "keywords": [
23 | "css-modules",
24 | "types",
25 | "flow",
26 | "webpack",
27 | "webpack loader"
28 | ],
29 | "dependencies": {
30 | "css-modules-flow-types-printer": "^2.0.0"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-printer/README.md:
--------------------------------------------------------------------------------
1 | # css-modules-flow-types-printer [](http://badge.fury.io/js/css-modules-flow-types-printer)
2 |
3 | Just a small printer taking [CSS Modules](https://github.com/css-modules/css-modules) tokens
4 | and prints out [Flow](https://flow.org/) type definitions.
5 |
6 | See usage of this package at https://github.com/skovhus/css-modules-flow-types
7 |
8 |
9 | ## License
10 | This software is released under the MIT License.
11 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-printer/__test__/index.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env jest */
2 | import printer, { EOL, HEADER } from '../index';
3 |
4 | describe('printer', () => {
5 | it('prints given tokens', () => {
6 | const result = printer(['btn1', 'btn2'], EOL.LF);
7 | expect(result).toBe(
8 | `${HEADER}
9 | declare module.exports: {|
10 | +'btn1': string,
11 | +'btn2': string,
12 | |};
13 | `
14 | );
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-printer/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "4"
8 | }
9 | }
10 | ]
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-printer/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import os from 'os';
4 |
5 | export const HEADER = `// @flow strict
6 | /* This file is automatically generated by css-modules-flow-types */`;
7 |
8 | export const EOL = {
9 | LF: '\n',
10 | CRLF: '\r\n',
11 | };
12 |
13 | export function getLineSeparator(content) {
14 | if (typeof content !== 'string') return os.EOL;
15 | if (content.includes(EOL.CRLF)) return EOL.CRLF;
16 | if (content.includes(EOL.LF)) return EOL.LF;
17 | return os.EOL;
18 | }
19 |
20 | export default function printFlowDefinition(
21 | tokensArray,
22 | eol = os.EOL,
23 | indent = ' '
24 | ) {
25 | const props = tokensArray
26 | .sort()
27 | .map((key) => `${indent}+'${key}': string,`)
28 | .join(eol);
29 |
30 | return `${HEADER}
31 | declare module.exports: {|
32 | ${props}
33 | |};
34 | `;
35 | }
36 |
--------------------------------------------------------------------------------
/packages/css-modules-flow-types-printer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-modules-flow-types-printer",
3 | "version": "2.0.0",
4 | "description": "Prints CSS Modules tokens as a flow definition",
5 | "author": "skovhus",
6 | "license": "MIT",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/skovhus/css-modules-flow-types.git"
10 | },
11 | "main": "dist/index.js",
12 | "engines": {
13 | "node": ">=8"
14 | },
15 | "scripts": {
16 | "build": "babel *.js -d dist --ignore *.test.js",
17 | "prepublishOnly": "cd ../../ && npm run prepublishOnly"
18 | },
19 | "files": [
20 | "dist"
21 | ],
22 | "keywords": [
23 | "css-modules",
24 | "types",
25 | "flow",
26 | "printer"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/publish.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 |
5 | version=$(cat lerna.json | jq -r .version)
6 | tag="v${version}"
7 |
8 | publishedVersion=$(yarn info css-modules-flow-types-cli --json | jq -r .data.\"dist-tags\".latest)
9 |
10 | if [ "$version" = "$publishedVersion" ]; then
11 | echo "Newest version is already deployed."
12 | exit 0
13 | fi
14 |
15 | yarn install
16 | yarn run verify:bail
17 |
18 | # Until we enforce semantic commits (and can use lerna publish), we need to publish in the right order
19 | cd packages/css-modules-flow-types-printer && npm publish && cd ../../
20 | cd packages/css-modules-flow-types-cli && npm publish && cd ../../
21 | cd packages/css-modules-flow-types-loader && npm publish && cd ../../
22 |
23 | git tag -a "${tag}" -m "${tag}"
24 | git push origin "${tag}"
25 |
--------------------------------------------------------------------------------