├── .changeset ├── README.md └── config.json ├── .github ├── dependabot.yml └── workflows │ ├── build.yml │ └── version.yml ├── .gitignore ├── .nvmrc ├── .yarn └── releases │ └── yarn-3.6.0.cjs ├── .yarnrc.yml ├── CHANGELOG.md ├── README.md ├── example ├── .gitattributes ├── .gitignore ├── README.md ├── package.json ├── src │ ├── AppClient.tsx │ ├── app │ │ ├── App.tsx │ │ └── Component1.tsx │ └── server │ │ ├── AppServer.tsx │ │ └── index.tsx ├── transformer.js ├── tsconfig.json ├── tsconfig.server.json ├── webpack │ ├── config.server.js │ ├── config.ts │ └── transformer.js └── yarn.lock ├── jest.config.json ├── package.json ├── src ├── __tests__ │ ├── baselines.test.ts │ ├── baselines │ │ ├── base │ │ │ ├── issue33.ts.baseline │ │ │ ├── sample1.ts.baseline │ │ │ ├── sample2.ts.baseline │ │ │ ├── sample3.tsx.baseline │ │ │ └── style-objects.ts.baseline │ │ ├── componentIdPrefix │ │ │ ├── issue33.ts.baseline │ │ │ ├── multiple-components.tsx.baseline │ │ │ ├── sample1.ts.baseline │ │ │ ├── sample2.ts.baseline │ │ │ ├── sample3.tsx.baseline │ │ │ └── style-objects.ts.baseline │ │ ├── minification-only │ │ │ ├── issue142.tsx.baseline │ │ │ ├── issue233.ts.baseline │ │ │ ├── issue36-extended.ts.baseline │ │ │ ├── issue36.tsx.baseline │ │ │ ├── issue40.ts.baseline │ │ │ ├── issue44.tsx.baseline │ │ │ ├── minify-css-in-helpers.ts.baseline │ │ │ ├── minify-css-to-use-with-transpilation.ts.baseline │ │ │ ├── minify-css-to-use-without-transpilation.ts.baseline │ │ │ ├── minify-single-line-comments-with-interpolations.ts.baseline │ │ │ ├── simple.ts.baseline │ │ │ └── simple2.ts.baseline │ │ ├── minification │ │ │ ├── issue142.tsx.baseline │ │ │ ├── issue233.ts.baseline │ │ │ ├── issue36-extended.ts.baseline │ │ │ ├── issue36.tsx.baseline │ │ │ ├── issue40.ts.baseline │ │ │ ├── issue44.tsx.baseline │ │ │ ├── minify-css-in-helpers.ts.baseline │ │ │ ├── minify-css-to-use-with-transpilation.ts.baseline │ │ │ ├── minify-css-to-use-without-transpilation.ts.baseline │ │ │ ├── minify-single-line-comments-with-interpolations.ts.baseline │ │ │ ├── simple.ts.baseline │ │ │ └── simple2.ts.baseline │ │ └── ssr │ │ │ ├── issue33.ts.baseline │ │ │ ├── multiple-components.tsx.baseline │ │ │ ├── sample1.ts.baseline │ │ │ ├── sample2.ts.baseline │ │ │ ├── sample3.tsx.baseline │ │ │ └── style-objects.ts.baseline │ ├── componentIdPrefix-baselines.test.ts │ ├── expectTransform.ts │ ├── fixtures │ │ ├── base │ │ │ ├── issue33.ts │ │ │ ├── sample1.ts │ │ │ ├── sample2.ts │ │ │ ├── sample3.tsx │ │ │ └── style-objects.ts │ │ ├── componentIdPrefix │ │ │ └── multiple-components.tsx │ │ ├── minification │ │ │ ├── issue142.tsx │ │ │ ├── issue233.ts │ │ │ ├── issue36-extended.ts │ │ │ ├── issue36.tsx │ │ │ ├── issue40.ts │ │ │ ├── issue44.tsx │ │ │ ├── minify-css-in-helpers.ts │ │ │ ├── minify-css-to-use-with-transpilation.ts │ │ │ ├── minify-css-to-use-without-transpilation.ts │ │ │ ├── minify-single-line-comments-with-interpolations.ts │ │ │ ├── simple.ts │ │ │ └── simple2.ts │ │ └── ssr │ │ │ └── multiple-components.tsx │ ├── minification-only.test.ts │ ├── minification.test.ts │ ├── minify.test.ts │ ├── ssr-baselines.test.ts │ └── themed-styled.ts ├── createTransformer.ts ├── hash.ts ├── index.ts ├── minify.ts ├── models │ └── Options.ts ├── runner.ts └── ts-is-kind.ts ├── tsconfig.json └── yarn.lock /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "master", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "13:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: "@types/node" 11 | versions: 12 | - 14.14.22 13 | - 14.14.25 14 | - 14.14.27 15 | - 14.14.28 16 | - 14.14.30 17 | - 14.14.31 18 | - 14.14.32 19 | - 14.14.33 20 | - 14.14.34 21 | - 14.14.35 22 | - 14.14.36 23 | - 14.14.37 24 | - 14.14.39 25 | - 14.14.41 26 | - 15.0.0 27 | - dependency-name: "@types/react" 28 | versions: 29 | - 17.0.0 30 | - 17.0.1 31 | - 17.0.2 32 | - 17.0.3 33 | - dependency-name: "@types/jest" 34 | versions: 35 | - 26.0.20 36 | - 26.0.21 37 | - 26.0.22 38 | - dependency-name: typescript 39 | versions: 40 | - 4.1.3 41 | - 4.1.4 42 | - 4.1.5 43 | - 4.2.2 44 | - 4.2.3 45 | - dependency-name: y18n 46 | versions: 47 | - 4.0.1 48 | - 4.0.2 49 | - dependency-name: "@types/styled-components" 50 | versions: 51 | - 5.1.7 52 | - 5.1.8 53 | - dependency-name: lodash 54 | versions: 55 | - 4.17.20 56 | - dependency-name: handlebars 57 | versions: 58 | - 4.7.6 59 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | pull_request: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: hmarr/debug-action@v2 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-node@v3 14 | with: 15 | cache: yarn 16 | node-version-file: '.nvmrc' 17 | - name: Install packages 18 | run: yarn --immutable 19 | - name: Build library 20 | run: yarn build 21 | unit: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: hmarr/debug-action@v2 25 | - uses: actions/checkout@v3 26 | - uses: actions/setup-node@v3 27 | with: 28 | cache: yarn 29 | node-version-file: '.nvmrc' 30 | - name: Install packages 31 | run: yarn --immutable 32 | - name: Jest 33 | run: yarn test 34 | -------------------------------------------------------------------------------- /.github/workflows/version.yml: -------------------------------------------------------------------------------- 1 | name: Version or Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | changesets: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: hmarr/debug-action@v2 15 | - uses: actions/checkout@v3 16 | - uses: actions/setup-node@v3 17 | with: 18 | cache: yarn 19 | node-version-file: '.nvmrc' 20 | - name: Install packages 21 | run: yarn --immutable 22 | - name: Build library 23 | run: yarn build 24 | - name: Create Release Pull Request or Publish 25 | uses: changesets/action@v1 26 | with: 27 | version: yarn changeset version 28 | publish: yarn changeset publish 29 | commit: Version package 30 | title: Version package 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | .vscode/ 4 | 5 | .yarn/* 6 | !.yarn/releases 7 | !.yarn/plugins 8 | !.yarn/sdks 9 | !.yarn/versions 10 | !.yarn/patches 11 | .pnp.* 12 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v14 2 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-3.6.0.cjs 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [3.0.0] 4 | 5 | - **breaking change** upgrade to TypeScript 4.8+/5.0+ in #713 6 | - Restore `componentIdPrefix` fallback to getIdFromNode by @roikoren755 in #518 7 | - GitHub Actions setup by @probablyup in #712 8 | - Update README.md by @RockinRonE in #473 9 | 10 | ## [2.0.0] 11 | 12 | - **breaking change** upgrade to TypeScript 4+ and make use of Factory API (#379) 13 | - bugfix in minification of `calc()` (fix #233 in #436) 14 | 15 | ## [1.6.0] 16 | 17 | - namespace prefix to help multiple instances of the library not clash (fix #381 in #395) 18 | 19 | ## [1.5.0] 20 | 21 | - transform anonymous default exports (fix #371 in #367) 22 | - remove deprecated `.extend` transformation pattern (fix #48 in #370) 23 | 24 | ## [1.4.4] 25 | 26 | - bugfix in minification of tabs (fix #142 in #152) 27 | 28 | ## [1.4.3] 29 | 30 | - bugfix in minification (fix #44 in #45) 31 | 32 | ## [1.4.2] 33 | 34 | - another important bugfix in minification (#40 by @Ky6uk, #41) 35 | 36 | ## [1.4.1] 37 | 38 | - important bugfix in minification (#36, #39) 39 | 40 | ## [1.4.0] 41 | 42 | - add experimental support of minification (#14, #35) 43 | - skip emitting empty `withConfig` (#37) 44 | 45 | ## [1.4.0-rc] 46 | 47 | - add experimental support of minification (#14, #35) 48 | 49 | ## [1.3.0] 50 | 51 | - improved detection of component names which fixes issues with jQuery and lodash (#33, #34) 52 | 53 | ## [1.2.0] 54 | 55 | - add support of [style objects](https://www.styled-components.com/docs/advanced#style-objects) (#30, #32) 56 | 57 | ## [1.1.0] 58 | 59 | - component id generation that helps with SSR (great contribution #21 by @fabyo82) 60 | - customizable identifiers of styled-components functions 61 | - display name generation can be turned off 62 | 63 | ## [1.1.0-rc] 64 | 65 | - component id generation that helps with SSR (great contribution #21 by @fabyo82) 66 | - customizable identifiers of `styled-components` functions 67 | - display name generation can be turned off 68 | 69 | ## [1.0.0] 70 | 71 | - The first official release! 72 | - updated `typescript` dependency to support TS 3.0+ (#17, fixed #15) 73 | - remove `ts-is-kind` dependency (#17, fixed #16) 74 | 75 | ## [0.0.7] 76 | 77 | - updated `typescript` dependency to support TS 3.0+ (#17, fixed #15) 78 | - remove `ts-is-kind` dependency (#17, fixed #16) 79 | 80 | [Unreleased]: https://github.com/igorbek/typescript-plugin-styled-components/compare/2.0.0...HEAD 81 | [2.0.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.6.0...2.0.0 82 | [1.6.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.5.0...1.6.0 83 | [1.5.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.4.4...1.5.0 84 | [1.4.4]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.4.3...1.4.4 85 | [1.4.3]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.4.2...1.4.3 86 | [1.4.2]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.4.1...1.4.2 87 | [1.4.1]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.4.0...1.4.1 88 | [1.4.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.3.0...1.4.0 89 | [1.4.0-rc]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.3.0...1.4.0-rc 90 | [1.3.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.2.0...1.3.0 91 | [1.2.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/1.1.0...1.2.0 92 | [1.1.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/v1.0.0...1.1.0 93 | [1.1.0-rc]: https://github.com/igorbek/typescript-plugin-styled-components/compare/v1.0.0...1.1.0-rc 94 | [1.0.0]: https://github.com/igorbek/typescript-plugin-styled-components/compare/v0.0.7...v1.0.0 95 | [0.0.7]: https://github.com/igorbek/typescript-plugin-styled-components/compare/v0.0.6...v0.0.7 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `typescript-plugin-styled-components` 2 | 3 | This is a TypeScript transformer that improves development experience of [`styled-components`](https://www.styled-components.com/). 4 | 5 | The main purpose is to provide compile-time information of creates styled components, such as names of these components, for the run-time, allowing to operate with proper names of such the components. 6 | 7 | The plugin was mostly inspired by great Babel's plugin [`babel-plugin-styled-components`](https://github.com/styled-components/babel-plugin-styled-components) and partially provides similar functionality for TypeScript users. 8 | 9 | If you like it, consider [](https://www.buymeacoffee.com/igorbek) 10 | 11 | Note: This transformer will be useful to you only when you are transpiling your TS code using actual TS compiler, like `tsc` `ts-loader` or `awesome-typescript-loader`. If your TS code is transpiled using [`babel-plugin-transform-typescript`](https://babeljs.io/docs/en/babel-plugin-transform-typescript), you should use [`babel-plugin-styled-components`](https://github.com/styled-components/babel-plugin-styled-components) instead. 12 | 13 | # Installation 14 | 15 | The following command adds the packages to the project as a development-time dependency: 16 | 17 |
yarn add typescript-plugin-styled-components --dev
18 |
19 | # Documentation
20 |
21 | - [Integration with `Webpack`](#Integration-with-Webpack)
22 | - [`awesome-typescript-loader`](#awesome-typescript-loader)
23 | - [`ts-loader`](#ts-loader)
24 | - [Forked process configuration](#Forked-process-configuration)
25 | - [Integration with `Rollup`](#Integration-with-Rollup)
26 | - [TypeScript compiler (CLI)](#TypeScript-compiler-CLI)
27 | - [`ttypescript` compiler](#ttypescript-compiler)
28 | - [API](#API)
29 | - [`createTransformer`](#createTransformer)
30 | - [`Options`](#Options)
31 | - [Notes](#Notes)
32 |
33 | # Integration with `Webpack`
34 |
35 | This section describes how to integrate the plugin into the build/bundling process driven by [**Webpack**](https://webpack.js.org/) and its TypeScript loaders.
36 |
37 | There are two popular TypeScript loaders that support specifying custom transformers:
38 |
39 | - [**awesome-typescript-loader**](https://github.com/s-panferov/awesome-typescript-loader), supports custom transformers since v3.1.3
40 | - [**ts-loader**](https://github.com/TypeStrong/ts-loader), supports custom transformers since v2.2.0
41 |
42 | Both loaders use the same setting `getCustomTransformers` which is an optional function that returns `{ before?: Transformer[], after?: Transformer[] }`.
43 | In order to inject the transformer into compilation, add it to `before` transformers array, like: `{ before: [styledComponentsTransformer] }`.
44 |
45 | ## `awesome-typescript-loader`
46 |
47 | In the `webpack.config.js` file in the section where **awesome-typescript-loader** is configured as a loader:
48 |
49 | ```js
50 | // 1. import default from the plugin module
51 | const createStyledComponentsTransformer = require('typescript-plugin-styled-components').default;
52 |
53 | // 2. create a transformer;
54 | // the factory additionally accepts an options object which described below
55 | const styledComponentsTransformer = createStyledComponentsTransformer();
56 |
57 | // 3. add getCustomTransformer method to the loader config
58 | var config = {
59 | ...
60 | module: {
61 | rules: [
62 | {
63 | test: /\.tsx?$/,
64 | loader: 'awesome-typescript-loader',
65 | options: {
66 | ... // other loader's options
67 | getCustomTransformers: () => ({ before: [styledComponentsTransformer] })
68 | }
69 | }
70 | ]
71 | }
72 | ...
73 | };
74 | ```
75 |
76 | Please note, that in the development mode, `awesome-typescript-loader` uses multiple separate processes to speed up compilation. In that mode the above configuration cannot work because functions, which `getCustomTransformers` is, are not transferrable between processes.
77 | To solve this please refer to [Forked process configuration](#forked-process-configuration) section.
78 |
79 | ## `ts-loader`
80 |
81 | In the `webpack.config.js` file in the section where **ts-loader** is configured as a loader:
82 |
83 | ```js
84 | // 1. import default from the plugin module
85 | const createStyledComponentsTransformer = require('typescript-plugin-styled-components').default;
86 |
87 | // 2. create a transformer;
88 | // the factory additionally accepts an options object which described below
89 | const styledComponentsTransformer = createStyledComponentsTransformer();
90 |
91 | // 3. add getCustomTransformer method to the loader config
92 | var config = {
93 | ...
94 | module: {
95 | rules: [
96 | {
97 | test: /\.tsx?$/,
98 | loader: 'ts-loader',
99 | options: {
100 | ... // other loader's options
101 | getCustomTransformers: () => ({ before: [styledComponentsTransformer] })
102 | }
103 | }
104 | ]
105 | }
106 | ...
107 | };
108 | ```
109 |
110 | Please note, when `awesome-typescript-loader` is used with `HappyPack` or `thread-loader`, they use multiple separate processes to speed up compilation. In that mode the above configuration cannot work because functions, which `getCustomTransformers` is, are not transferrable between processes.
111 | To solve this please refer to [Forked process configuration](#forked-process-configuration) section.
112 |
113 | ## Forked process configuration
114 |
115 | To configure the transformer for development mode in `awesome-typescript-loader` or `ts-loader` with `HappyPack` or `thread-loader`, you need to make `getCustomTransformers` a resolvable module name instead of the function. Since the configuration is very similar, here's an example:
116 |
117 | ### 1. Move `styledComponentsTransformer` into a separate file
118 |
119 | Let's assume it is in the same folder as your `webpack.config` and has name `webpack.ts-transformers.js`:
120 | ```js
121 | // 1. import default from the plugin module
122 | const createStyledComponentsTransformer = require('typescript-plugin-styled-components').default;
123 |
124 | // 2. create a transformer;
125 | // the factory additionally accepts an options object which described below
126 | const styledComponentsTransformer = createStyledComponentsTransformer();
127 |
128 | // 3. create getCustomTransformer function
129 | const getCustomTransformers = () => ({ before: [styledComponentsTransformer] });
130 |
131 | // 4. export getCustomTransformers
132 | module.exports = getCustomTransformers;
133 | ```
134 |
135 | ### 2. Change the loader's options to point to that file instead of explicit function
136 |
137 | ```diff
138 | -const createStyledComponentsTransformer = require('typescript-plugin-styled-components').default;
139 | -const styledComponentsTransformer = createStyledComponentsTransformer();
140 |
141 | options: {
142 | ... // other loader's options
143 | - getCustomTransformers: () => ({ before: [styledComponentsTransformer] })
144 | + getCustomTransformers: path.join(__dirname, './webpack.ts-transformers.js')
145 | }
146 | ```
147 |
148 | # Integration with `Rollup`
149 |
150 | This section describes how to integrate the plugin into the build/bundling process driven by [**Rollup**](https://rollupjs.org/guide/en/) and its TypeScript loader - [**rollup-plugin-typescript2**](https://github.com/Igorbek/typescript-plugin-styled-components).
151 |
152 | In the `rollup.config.js` file in the section where **rollup-plugin-typescript2** is configured as a loader:
153 |
154 | ```js
155 | // 1. import default from the plugin module
156 | const createStyledComponentsTransformer = require('typescript-plugin-styled-components').default;
157 |
158 | // 2. create a transformer;
159 | // the factory additionally accepts an options object which described below
160 | const styledComponentsTransformer = createStyledComponentsTransformer();
161 |
162 | // 3. add getCustomTransformer method to the loader config
163 | var config = {
164 | ...
165 | plugins: [
166 | rollupTypescript({
167 | ...
168 | transformers: [
169 | () => ({
170 | before: [styledComponentsTransformer],
171 | }),
172 | ],
173 | }),
174 | ...
175 | ],
176 | ...
177 | };
178 | ```
179 |
180 | # TypeScript compiler (CLI)
181 |
182 | TypeScript command line compiler tool (`tsc`) does not support using of pluggable modules and transformers.
183 | For that reason there are other tools created that do support pluggable transformers. See [`ttypescript` compiler](#ttypescript-compiler) section.
184 |
185 | # `ttypescript` compiler
186 |
187 | The [`ttypescript` compiler](https://github.com/cevek/ttypescript) is a CLI tool that allows to use TypeScript compiler with pluggable transformers.
188 | To use the transformer with that tool you can configure it by updating `tsconfig.json` the following way:
189 |
190 | ```js
191 | {
192 | "compilerOptions": {
193 | "plugins": [
194 | {
195 | "transform": "typescript-plugin-styled-components",
196 | "type": "config",
197 |
198 | // other typescript-plugin-styled-components options can be added here
199 | "minify": true,
200 | "ssr": true
201 | }
202 | ]
203 | }
204 | }
205 | ```
206 |
207 | # API
208 |
209 | ## `createTransformer`
210 |
211 | ```ts
212 | function createTransformer(options?: Partial= ThemedStyledProps
;
28 | export default styled;
29 | export { css, injectGlobal, keyframes, withTheme, ThemeProvider };
30 |
--------------------------------------------------------------------------------
/src/createTransformer.ts:
--------------------------------------------------------------------------------
1 | import * as path from 'path';
2 | import * as ts from 'typescript';
3 | import {
4 | isPropertyAccessExpression,
5 | isCallExpression,
6 | isIdentifier,
7 | isVariableDeclaration,
8 | isExportAssignment,
9 | isTaggedTemplateExpression,
10 | } from './ts-is-kind';
11 |
12 | import { Options, CustomStyledIdentifiers } from './models/Options';
13 | import { hash } from './hash';
14 | import { minifyTemplate } from './minify';
15 |
16 | /** Detects that a node represents a styled function
17 | * Recognizes the following patterns:
18 | *
19 | * styled.tag
20 | * Component.extend
21 | * styled(Component)
22 | * styled('tag')
23 | * styledFunction.attrs(attributes)
24 | */
25 | function isStyledFunction(
26 | node: ts.Node,
27 | identifiers: CustomStyledIdentifiers
28 | ): node is ts.PropertyAccessExpression | ts.CallExpression {
29 | if (isPropertyAccessExpression(node)) {
30 | if (isStyledObject(node.expression, identifiers)) {
31 | return true;
32 | }
33 |
34 | if (isStyledExtendIdentifier(node.name.text, identifiers) && isValidComponent(node.expression)) {
35 | return true;
36 | }
37 |
38 | return false;
39 | }
40 |
41 | if (isCallExpression(node) && node.arguments.length === 1) {
42 | if (isStyledObject(node.expression, identifiers)) {
43 | return true;
44 | }
45 |
46 | if (isStyledAttrs(node.expression, identifiers)) {
47 | return true;
48 | }
49 | }
50 |
51 | return false;
52 | }
53 |
54 | function isStyledObjectIdentifier(name: string, { styled: styledIdentifiers = ['styled'] }: CustomStyledIdentifiers) {
55 | return styledIdentifiers.indexOf(name) >= 0;
56 | }
57 |
58 | function isStyledObject(node: ts.Node, identifiers: CustomStyledIdentifiers) {
59 | return node && isIdentifier(node) && isStyledObjectIdentifier(node.text, identifiers);
60 | }
61 |
62 | function isValidComponent(node: ts.Node) {
63 | return node && isIdentifier(node) && isValidComponentName(node.text);
64 | }
65 |
66 | function isLetter(ch: string) {
67 | return ch.toLowerCase() !== ch.toUpperCase();
68 | }
69 |
70 | function isValidTagName(name: string) {
71 | return isLetter(name[0]) && name[0] === name[0].toLowerCase();
72 | }
73 |
74 | function isValidComponentName(name: string) {
75 | return isLetter(name[0]) && name[0] === name[0].toUpperCase();
76 | }
77 |
78 | function isStyledAttrsIdentifier(name: string, { attrs: attrsIdentifiers = ['attrs'] }: CustomStyledIdentifiers) {
79 | return attrsIdentifiers.indexOf(name) >= 0;
80 | }
81 |
82 | function isStyledAttrs(node: ts.Node, identifiers: CustomStyledIdentifiers) {
83 | return (
84 | node &&
85 | isPropertyAccessExpression(node) &&
86 | isStyledAttrsIdentifier(node.name.text, identifiers) &&
87 | isStyledFunction((node as ts.PropertyAccessExpression).expression, identifiers)
88 | );
89 | }
90 |
91 | function isStyledKeyframesIdentifier(name: string, { keyframes = ['keyframes'] }: CustomStyledIdentifiers) {
92 | return keyframes.indexOf(name) >= 0;
93 | }
94 |
95 | function isStyledCssIdentifier(name: string, { css = ['css'] }: CustomStyledIdentifiers) {
96 | return css.indexOf(name) >= 0;
97 | }
98 |
99 | function isStyledCreateGlobalStyleIdentifier(
100 | name: string,
101 | { createGlobalStyle = ['createGlobalStyle'] }: CustomStyledIdentifiers
102 | ) {
103 | return createGlobalStyle.indexOf(name) >= 0;
104 | }
105 |
106 | function isStyledExtendIdentifier(name: string, { extend = [] }: CustomStyledIdentifiers) {
107 | return extend.indexOf(name) >= 0;
108 | }
109 |
110 | function isMinifyableStyledFunction(node: ts.Node, identifiers: CustomStyledIdentifiers) {
111 | return (
112 | isStyledFunction(node, identifiers) ||
113 | (isIdentifier(node) &&
114 | (isStyledKeyframesIdentifier(node.text, identifiers) ||
115 | isStyledCssIdentifier(node.text, identifiers) ||
116 | isStyledCreateGlobalStyleIdentifier(node.text, identifiers)))
117 | );
118 | }
119 |
120 | function defaultGetDisplayName(filename: string, bindingName: string | undefined): string | undefined {
121 | return bindingName;
122 | }
123 |
124 | export function createTransformer(options?: Partial