From 292ba1b7cb5309daa1fda23b81f42bd8d44f09d7 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Thu, 29 Apr 2021 21:06:25 +0300 Subject: [PATCH] Use TypeScript in Svelte component --- packages/svelte/package-lock.json | 244 +++++++++++++++++- packages/svelte/package.json | 5 +- packages/svelte/rollup.config.js | 27 +- .../{generate-icon.js => generate-icon.ts} | 34 ++- packages/svelte/src/{index.js => index.ts} | 0 packages/svelte/src/props.ts | 40 +++ packages/svelte/tsconfig.json | 16 ++ 7 files changed, 344 insertions(+), 22 deletions(-) rename packages/svelte/src/{generate-icon.js => generate-icon.ts} (73%) rename packages/svelte/src/{index.js => index.ts} (100%) create mode 100644 packages/svelte/src/props.ts create mode 100644 packages/svelte/tsconfig.json diff --git a/packages/svelte/package-lock.json b/packages/svelte/package-lock.json index dc03295..e87eaee 100644 --- a/packages/svelte/package-lock.json +++ b/packages/svelte/package-lock.json @@ -1,20 +1,23 @@ { "name": "@iconify/svelte", - "version": "1.0.3", + "version": "1.0.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@iconify/svelte", - "version": "1.0.3", + "version": "1.0.4", "license": "MIT", "devDependencies": { "@iconify/core": "^1.0.0-rc.3", "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-node-resolve": "^10.0.0", + "@rollup/plugin-typescript": "^8.2.1", + "@tsconfig/svelte": "^1.0.10", "rollup": "^2.33.3", "rollup-plugin-svelte": "^6.1.1", - "svelte": "^3.29.7" + "svelte": "^3.29.7", + "svelte-preprocess": "^4.7.2" } }, "node_modules/@cyberalien/redundancy": { @@ -80,6 +83,24 @@ "rollup": "^1.20.0||^2.0.0" } }, + "node_modules/@rollup/plugin-typescript": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.1.tgz", + "integrity": "sha512-Qd2E1pleDR4bwyFxqbjt4eJf+wB0UKVMLc7/BAFDGVdAXQMCsD4DUv5/7/ww47BZCYxWtJqe1Lo0KVNswBJlRw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0", + "tslib": "*", + "typescript": ">=3.7.0" + } + }, "node_modules/@rollup/pluginutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", @@ -103,6 +124,12 @@ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, + "node_modules/@tsconfig/svelte": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-1.0.10.tgz", + "integrity": "sha512-EBrpH2iXXfaf/9z81koiDYkp2mlwW2XzFcAqn6qh7VKyP8zBvHHAQzNhY+W9vH5arAjmGAm5g8ElWq6YmXm3ig==", + "dev": true + }, "node_modules/@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -115,6 +142,12 @@ "integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==", "dev": true }, + "node_modules/@types/pug": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.4.tgz", + "integrity": "sha1-h3L80EGOPNLMFxVV1zAHQVBR9LI=", + "dev": true + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -124,6 +157,15 @@ "@types/node": "*" } }, + "node_modules/@types/sass": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.16.0.tgz", + "integrity": "sha512-2XZovu4NwcqmtZtsBR5XYLw18T8cBCnU2USFHTnYLLHz9fkhnoEMoDsqShJIOFsFhn5aJHjweiUUdTrDGujegA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -170,6 +212,15 @@ "node": ">=0.10.0" } }, + "node_modules/detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -286,6 +337,15 @@ "sourcemap-codec": "^1.4.4" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -358,9 +418,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.34.2.tgz", "integrity": "sha512-mvtQLqu3cNeoctS+kZ09iOPxrc1P1/Bt1z15enuQ5feyKOdM3MJAVFjjsygurDpSWn530xB4AlA83TWIzRstXA==", "dev": true, - "dependencies": { - "fsevents": "~2.1.2" - }, "bin": { "rollup": "dist/bin/rollup" }, @@ -407,6 +464,18 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/svelte": { "version": "3.31.0", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz", @@ -416,6 +485,91 @@ "node": ">= 8" } }, + "node_modules/svelte-preprocess": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.7.2.tgz", + "integrity": "sha512-EToG+08rEsA33btv+C5g2qnRArwpTc5AoU0QBB3ZEkYagxAb2yPNsy0qsmtvbJOTBMy6o3oyijDdl3DMpMvpEg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/pug": "^2.0.4", + "@types/sass": "^1.16.0", + "detect-indent": "^6.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">= 9.11.2" + }, + "peerDependencies": { + "@babel/core": "^7.10.2", + "coffeescript": "^2.5.1", + "less": "^3.11.3", + "postcss": "^7 || ^8", + "postcss-load-config": "^2.1.0 || ^3.0.0", + "pug": "^3.0.0", + "sass": "^1.26.8", + "stylus": "^0.54.7", + "sugarss": "^2.0.0", + "svelte": "^3.23.0", + "typescript": "^3.9.5 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "coffeescript": { + "optional": true + }, + "less": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "postcss": { + "optional": true + }, + "postcss-load-config": { + "optional": true + }, + "pug": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true, + "peer": true + }, + "node_modules/typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -475,6 +629,16 @@ "resolve": "^1.17.0" } }, + "@rollup/plugin-typescript": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.1.tgz", + "integrity": "sha512-Qd2E1pleDR4bwyFxqbjt4eJf+wB0UKVMLc7/BAFDGVdAXQMCsD4DUv5/7/ww47BZCYxWtJqe1Lo0KVNswBJlRw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "resolve": "^1.17.0" + } + }, "@rollup/pluginutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", @@ -494,6 +658,12 @@ } } }, + "@tsconfig/svelte": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-1.0.10.tgz", + "integrity": "sha512-EBrpH2iXXfaf/9z81koiDYkp2mlwW2XzFcAqn6qh7VKyP8zBvHHAQzNhY+W9vH5arAjmGAm5g8ElWq6YmXm3ig==", + "dev": true + }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -506,6 +676,12 @@ "integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==", "dev": true }, + "@types/pug": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.4.tgz", + "integrity": "sha1-h3L80EGOPNLMFxVV1zAHQVBR9LI=", + "dev": true + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -515,6 +691,15 @@ "@types/node": "*" } }, + "@types/sass": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.16.0.tgz", + "integrity": "sha512-2XZovu4NwcqmtZtsBR5XYLw18T8cBCnU2USFHTnYLLHz9fkhnoEMoDsqShJIOFsFhn5aJHjweiUUdTrDGujegA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -555,6 +740,12 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true + }, "estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -652,6 +843,12 @@ "sourcemap-codec": "^1.4.4" } }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -747,12 +944,47 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, "svelte": { "version": "3.31.0", "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz", "integrity": "sha512-r+n8UJkDqoQm1b+3tA3Lh6mHXKpcfOSOuEuIo5gE2W9wQYi64RYX/qE6CZBDDsP/H4M+N426JwY7XGH4xASvGQ==", "dev": true }, + "svelte-preprocess": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.7.2.tgz", + "integrity": "sha512-EToG+08rEsA33btv+C5g2qnRArwpTc5AoU0QBB3ZEkYagxAb2yPNsy0qsmtvbJOTBMy6o3oyijDdl3DMpMvpEg==", + "dev": true, + "requires": { + "@types/pug": "^2.0.4", + "@types/sass": "^1.16.0", + "detect-indent": "^6.0.0", + "strip-indent": "^3.0.0" + } + }, + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true, + "peer": true + }, + "typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true, + "peer": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 09150ef..2e07a75 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -22,8 +22,11 @@ "@iconify/core": "^1.0.0-rc.3", "@rollup/plugin-commonjs": "^16.0.0", "@rollup/plugin-node-resolve": "^10.0.0", + "@rollup/plugin-typescript": "^8.2.1", + "@tsconfig/svelte": "^1.0.10", "rollup": "^2.33.3", "rollup-plugin-svelte": "^6.1.1", - "svelte": "^3.29.7" + "svelte": "^3.29.7", + "svelte-preprocess": "^4.7.2" } } diff --git a/packages/svelte/rollup.config.js b/packages/svelte/rollup.config.js index af1986d..367d0fc 100644 --- a/packages/svelte/rollup.config.js +++ b/packages/svelte/rollup.config.js @@ -2,6 +2,8 @@ import fs from 'fs'; import svelte from 'rollup-plugin-svelte'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import typescript from '@rollup/plugin-typescript'; +import sveltePreprocess from 'svelte-preprocess'; import pkg from './package.json'; // Copy Icon.svelte @@ -18,7 +20,7 @@ try { // Create component.mjs fs.writeFileSync( __dirname + '/dist/component.mjs', - fs.readFileSync(__dirname + '/src/index.js') + fs.readFileSync(__dirname + '/src/index.ts') ); // Create bundle @@ -30,22 +32,37 @@ const name = pkg.name export default [ // Bundle everything { - input: 'src/index.js', + input: 'src/index.ts', output: [ { file: pkg.module, format: 'es' }, { file: pkg.main, format: 'umd', name }, ], - plugins: [svelte(), resolve(), commonjs()], + plugins: [ + svelte({ + preprocess: sveltePreprocess(), + }), + resolve({ + extensions: ['.ts', '.js', '.svelte'], + }), + typescript(), + commonjs(), + ], }, // Files included in Icon.svelte as bundles without dependencies { - input: 'src/generate-icon.js', + input: 'src/generate-icon.ts', output: [ { file: 'dist/generate-icon.js', format: 'es', }, ], - plugins: [resolve(), commonjs()], + plugins: [ + resolve({ + extensions: ['.ts', '.js', '.svelte'], + }), + typescript(), + commonjs(), + ], }, ]; diff --git a/packages/svelte/src/generate-icon.js b/packages/svelte/src/generate-icon.ts similarity index 73% rename from packages/svelte/src/generate-icon.js rename to packages/svelte/src/generate-icon.ts index cda8639..e8c49b6 100644 --- a/packages/svelte/src/generate-icon.js +++ b/packages/svelte/src/generate-icon.ts @@ -8,6 +8,7 @@ import { fullIcon } from '@iconify/core/lib/icon'; import { iconToSVG } from '@iconify/core/lib/builder'; import { replaceIDs } from '@iconify/core/lib/builder/ids'; import { merge } from '@iconify/core/lib/misc/merge'; +import type { IconProps } from './props'; /** * Default SVG attributes @@ -19,10 +20,18 @@ const svgDefaults = { 'role': 'img', }; +/** + * Result + */ +export interface GenerateIconResult { + attributes: Record; + body: string; +} + /** * Generate icon from properties */ -export function generateIcon(props) { +export function generateIcon(props: IconProps): GenerateIconResult { let iconData = fullIcon(props.icon); if (!iconData) { return { @@ -31,15 +40,15 @@ export function generateIcon(props) { }; } - const customisations = merge(defaults, props); - const componentProps = merge(svgDefaults); + const customisations = merge(defaults, props as typeof defaults); + const componentProps = merge(svgDefaults) as Record; // Create style if missing let style = typeof props.style === 'string' ? props.style : ''; // Get element properties for (let key in props) { - const value = props[key]; + const value = props[key as keyof typeof props] as unknown; switch (key) { // Properties to ignore case 'icon': @@ -48,12 +57,16 @@ export function generateIcon(props) { // Flip as string: 'horizontal,vertical' case 'flip': - flipFromString(customisations, value); + if (typeof value === 'string') { + flipFromString(customisations, value); + } break; // Alignment as string case 'align': - alignmentFromString(customisations, value); + if (typeof value === 'string') { + alignmentFromString(customisations, value); + } break; // Color: copy to style @@ -63,9 +76,9 @@ export function generateIcon(props) { // Rotation as string case 'rotate': - if (typeof value !== 'number') { + if (typeof value === 'string') { customisations[key] = rotateFromString(value); - } else { + } else if (typeof value === 'number') { componentProps[key] = value; } break; @@ -80,7 +93,7 @@ export function generateIcon(props) { // Copy missing property if it does not exist in customisations default: - if (defaults[key] === void 0) { + if ((defaults as Record)[key] === void 0) { componentProps[key] = value; } } @@ -91,7 +104,8 @@ export function generateIcon(props) { // Add icon stuff for (let key in item.attributes) { - componentProps[key] = item.attributes[key]; + componentProps[key] = + item.attributes[key as keyof typeof item.attributes]; } if (item.inline) { diff --git a/packages/svelte/src/index.js b/packages/svelte/src/index.ts similarity index 100% rename from packages/svelte/src/index.js rename to packages/svelte/src/index.ts diff --git a/packages/svelte/src/props.ts b/packages/svelte/src/props.ts new file mode 100644 index 0000000..9b7ee8b --- /dev/null +++ b/packages/svelte/src/props.ts @@ -0,0 +1,40 @@ +import type { IconifyIcon } from '@iconify/types'; +import type { IconifyIconCustomisations as IconCustomisations } from '@iconify/core/lib/customisations'; + +// Allow rotation to be string +/** + * Icon customisations + */ +export type IconifyIconCustomisations = IconCustomisations & { + rotate?: string | number; +}; + +/** + * Icon properties + */ +export interface IconifyIconProps extends IconifyIconCustomisations { + // Icon object + icon: IconifyIcon; + + // Style + color?: string; + + // Shorthand properties + flip?: string; + align?: string; + + // Unique id, used as base for ids for shapes. Use it to get consistent ids for server side rendering + id?: string; +} + +/** + * Properties for element that are mentioned in generate-icon.ts + */ +interface IconifyElementProps { + style?: string; +} + +/** + * Mix of icon properties and HTMLElement properties + */ +export type IconProps = IconifyElementProps & IconifyIconProps; diff --git a/packages/svelte/tsconfig.json b/packages/svelte/tsconfig.json new file mode 100644 index 0000000..a13f11a --- /dev/null +++ b/packages/svelte/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "rootDir": "src", + "target": "es2017", + "module": "esnext", + "declaration": false, + "sourceMap": false, + "strict": true, + "types": ["node", "svelte"], + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "importsNotUsedAsValues": "error" + } +}