From ff4b00401f46b87846820683632c5fa5e88ea89c Mon Sep 17 00:00:00 2001 From: Andy Dixon Date: Sat, 11 Oct 2025 18:48:08 +0200 Subject: [PATCH] Readding missing files, fix SVG spacing --- .config/.cprc.json | 3 + .config/.prettierrc.js | 16 ++ .config/Dockerfile | 54 +++++ .config/README.md | 176 +++++++++++++++ .config/bundler/externals.ts | 43 ++++ .config/docker-compose-base.yaml | 25 +++ .config/entrypoint.sh | 18 ++ .config/eslint.config.mjs | 38 ++++ .config/jest-setup.js | 28 +++ .config/jest.config.js | 44 ++++ .config/jest/mocks/react-inlinesvg.tsx | 25 +++ .config/jest/utils.js | 37 ++++ .config/supervisord/supervisord.conf | 15 ++ .config/tsconfig.json | 26 +++ .config/types/bundler-rules.d.ts | 37 ++++ .config/types/webpack-plugins.d.ts | 83 ++++++++ .config/webpack/BuildModeWebpackPlugin.ts | 33 +++ .config/webpack/constants.ts | 2 + .config/webpack/utils.ts | 68 ++++++ .config/webpack/webpack.config.ts | 247 ++++++++++++++++++++++ .cprc.json | 7 + .github/workflows/bundle-stats.yml | 27 +++ .github/workflows/ci.yml | 241 +++++++++++++++++++++ .github/workflows/cp-update.yml | 26 +++ .github/workflows/is-compatible.yml | 37 ++++ .github/workflows/release.yml | 29 +++ .gitignore | 58 +++-- .nvmrc | 1 + .prettierrc.js | 4 + CHANGELOG.md | 5 + docker-compose.yaml | 5 + eslint.config.mjs | 39 ++++ jest-setup.js | 2 + jest.config.js | 8 + package.json | 2 +- playwright.config.ts | 53 +++++ provisioning/README.md | 1 + provisioning/dashboards/.gitkeep | 0 provisioning/dashboards/dashboard.json | 104 +++++++++ provisioning/dashboards/default.yaml | 7 + provisioning/datasources/datasources.yml | 7 + src/README.md | 2 +- src/components/ChargeVizPanel.tsx | 46 ++-- src/plugin.json | 4 +- tests/panel.spec.ts | 35 +++ tsconfig.json | 3 + 46 files changed, 1731 insertions(+), 40 deletions(-) create mode 100644 .config/.cprc.json create mode 100644 .config/.prettierrc.js create mode 100644 .config/Dockerfile create mode 100644 .config/README.md create mode 100644 .config/bundler/externals.ts create mode 100644 .config/docker-compose-base.yaml create mode 100644 .config/entrypoint.sh create mode 100644 .config/eslint.config.mjs create mode 100644 .config/jest-setup.js create mode 100644 .config/jest.config.js create mode 100644 .config/jest/mocks/react-inlinesvg.tsx create mode 100644 .config/jest/utils.js create mode 100644 .config/supervisord/supervisord.conf create mode 100644 .config/tsconfig.json create mode 100644 .config/types/bundler-rules.d.ts create mode 100644 .config/types/webpack-plugins.d.ts create mode 100644 .config/webpack/BuildModeWebpackPlugin.ts create mode 100644 .config/webpack/constants.ts create mode 100644 .config/webpack/utils.ts create mode 100644 .config/webpack/webpack.config.ts create mode 100644 .cprc.json create mode 100644 .github/workflows/bundle-stats.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/cp-update.yml create mode 100644 .github/workflows/is-compatible.yml create mode 100644 .github/workflows/release.yml create mode 100644 .nvmrc create mode 100644 .prettierrc.js create mode 100644 CHANGELOG.md create mode 100644 docker-compose.yaml create mode 100644 eslint.config.mjs create mode 100644 jest-setup.js create mode 100644 jest.config.js create mode 100644 playwright.config.ts create mode 100644 provisioning/README.md create mode 100644 provisioning/dashboards/.gitkeep create mode 100644 provisioning/dashboards/dashboard.json create mode 100644 provisioning/dashboards/default.yaml create mode 100644 provisioning/datasources/datasources.yml create mode 100644 tests/panel.spec.ts create mode 100644 tsconfig.json diff --git a/.config/.cprc.json b/.config/.cprc.json new file mode 100644 index 0000000..bbd6e10 --- /dev/null +++ b/.config/.cprc.json @@ -0,0 +1,3 @@ +{ + "version": "6.1.0" +} diff --git a/.config/.prettierrc.js b/.config/.prettierrc.js new file mode 100644 index 0000000..bf506f5 --- /dev/null +++ b/.config/.prettierrc.js @@ -0,0 +1,16 @@ +/* + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in .config/README.md + */ + +module.exports = { + endOfLine: 'auto', + printWidth: 120, + trailingComma: 'es5', + semi: true, + jsxSingleQuote: false, + singleQuote: true, + useTabs: false, + tabWidth: 2, +}; diff --git a/.config/Dockerfile b/.config/Dockerfile new file mode 100644 index 0000000..c55d9e1 --- /dev/null +++ b/.config/Dockerfile @@ -0,0 +1,54 @@ +ARG grafana_version=latest +ARG grafana_image=grafana-enterprise + +FROM grafana/${grafana_image}:${grafana_version} + +ARG anonymous_auth_enabled=true +ARG development=false +ARG TARGETARCH + + +ENV DEV "${development}" + +# Make it as simple as possible to access the grafana instance for development purposes +# Do NOT enable these settings in a public facing / production grafana instance +ENV GF_AUTH_ANONYMOUS_ORG_ROLE "Admin" +ENV GF_AUTH_ANONYMOUS_ENABLED "${anonymous_auth_enabled}" +ENV GF_AUTH_BASIC_ENABLED "false" +# Set development mode so plugins can be loaded without the need to sign +ENV GF_DEFAULT_APP_MODE "development" + + +LABEL maintainer="Grafana Labs " + +ENV GF_PATHS_HOME="/usr/share/grafana" +WORKDIR $GF_PATHS_HOME + +USER root + +# Installing supervisor and inotify-tools +RUN if [ "${development}" = "true" ]; then \ + if grep -i -q alpine /etc/issue; then \ + apk add supervisor inotify-tools git; \ + elif grep -i -q ubuntu /etc/issue; then \ + DEBIAN_FRONTEND=noninteractive && \ + apt-get update && \ + apt-get install -y supervisor inotify-tools git && \ + rm -rf /var/lib/apt/lists/*; \ + else \ + echo 'ERROR: Unsupported base image' && /bin/false; \ + fi \ + fi + +COPY supervisord/supervisord.conf /etc/supervisor.d/supervisord.ini +COPY supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf + + + +# Inject livereload script into grafana index.html +RUN sed -i 's|||g' /usr/share/grafana/public/views/index.html + + +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] diff --git a/.config/README.md b/.config/README.md new file mode 100644 index 0000000..1ec4b41 --- /dev/null +++ b/.config/README.md @@ -0,0 +1,176 @@ +# Default build configuration by Grafana + +**This is an auto-generated directory and is not intended to be changed! ⚠️** + +The `.config/` directory holds basic configuration for the different tools +that are used to develop, test and build the project. In order to make it updates easier we ask you to +not edit files in this folder to extend configuration. + +## How to extend the basic configs? + +Bear in mind that you are doing it at your own risk, and that extending any of the basic configuration can lead +to issues around working with the project. + +### Extending the ESLint config + +Edit the `eslint.config.mjs` file in the project root to extend the ESLint configuration. The following example disables deprecation notices for source files. + +**Example:** + +```javascript +import { defineConfig } from 'eslint/config'; +import baseConfig from './.config/eslint.config.mjs'; + +export default defineConfig([ + { + ignores: [ + //... + ], + }, + ...baseConfig, + { + files: ['src/**/*.{ts,tsx}'], + rules: { + '@typescript-eslint/no-deprecated': 'off', + }, + }, +]); +``` + +--- + +### Extending the Prettier config + +Edit the `.prettierrc.js` file in the project root in order to extend the Prettier configuration. + +**Example:** + +```javascript +module.exports = { + // Prettier configuration provided by Grafana scaffolding + ...require('./.config/.prettierrc.js'), + + semi: false, +}; +``` + +--- + +### Extending the Jest config + +There are two configuration in the project root that belong to Jest: `jest-setup.js` and `jest.config.js`. + +**`jest-setup.js`:** A file that is run before each test file in the suite is executed. We are using it to +set up the Jest DOM for the testing library and to apply some polyfills. ([link to Jest docs](https://jestjs.io/docs/configuration#setupfilesafterenv-array)) + +**`jest.config.js`:** The main Jest configuration file that extends the Grafana recommended setup. ([link to Jest docs](https://jestjs.io/docs/configuration)) + +#### ESM errors with Jest + +A common issue with the current jest config involves importing an npm package that only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this, we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be, this can be extended in the following way: + +```javascript +process.env.TZ = 'UTC'; +const { grafanaESModules, nodeModulesToTransform } = require('./config/jest/utils'); + +module.exports = { + // Jest configuration provided by Grafana + ...require('./.config/jest.config'), + // Inform jest to only transform specific node_module packages. + transformIgnorePatterns: [nodeModulesToTransform([...grafanaESModules, 'packageName'])], +}; +``` + +--- + +### Extending the TypeScript config + +Edit the `tsconfig.json` file in the project root in order to extend the TypeScript configuration. + +**Example:** + +```json +{ + "extends": "./.config/tsconfig.json", + "compilerOptions": { + "preserveConstEnums": true + } +} +``` + +--- + +### Extending the Webpack config + +Follow these steps to extend the basic Webpack configuration that lives under `.config/`: + +#### 1. Create a new Webpack configuration file + +Create a new config file that is going to extend the basic one provided by Grafana. +It can live in the project root, e.g. `webpack.config.ts`. + +#### 2. Merge the basic config provided by Grafana and your custom setup + +We are going to use [`webpack-merge`](https://github.com/survivejs/webpack-merge) for this. + +```typescript +// webpack.config.ts +import type { Configuration } from 'webpack'; +import { merge } from 'webpack-merge'; +import grafanaConfig, { type Env } from './.config/webpack/webpack.config'; + +const config = async (env: Env): Promise => { + const baseConfig = await grafanaConfig(env); + + return merge(baseConfig, { + // Add custom config here... + output: { + asyncChunks: true, + }, + }); +}; + +export default config; +``` + +#### 3. Update the `package.json` to use the new Webpack config + +We need to update the `scripts` in the `package.json` to use the extended Webpack configuration. + +**Update for `build`:** + +```diff +-"build": "webpack -c ./.config/webpack/webpack.config.ts --env production", ++"build": "webpack -c ./webpack.config.ts --env production", +``` + +**Update for `dev`:** + +```diff +-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development", ++"dev": "webpack -w -c ./webpack.config.ts --env development", +``` + +### Configure grafana image to use when running docker + +By default, `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behavior, simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`. + +**Example:** + +```yaml +version: '3.7' + +services: + grafana: + extends: + file: .config/docker-compose-base.yaml + service: grafana + build: + args: + grafana_version: ${GRAFANA_VERSION:-9.1.2} + grafana_image: ${GRAFANA_IMAGE:-grafana} +``` + +In this example, we assign the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will allow you to set the value while running the docker compose commands, which might be convenient in some scenarios. + +--- diff --git a/.config/bundler/externals.ts b/.config/bundler/externals.ts new file mode 100644 index 0000000..3a287d5 --- /dev/null +++ b/.config/bundler/externals.ts @@ -0,0 +1,43 @@ +import type { Configuration, ExternalItemFunctionData } from 'webpack'; + +type ExternalsType = Configuration['externals']; + +export const externals: ExternalsType = [ + // Required for dynamic publicPath resolution + { 'amd-module': 'module' }, + 'lodash', + 'jquery', + 'moment', + 'slate', + 'emotion', + '@emotion/react', + '@emotion/css', + 'prismjs', + 'slate-plain-serializer', + '@grafana/slate-react', + 'react', + 'react-dom', + 'react-redux', + 'redux', + 'rxjs', + 'i18next', + 'react-router', + 'd3', + 'angular', + /^@grafana\/ui/i, + /^@grafana\/runtime/i, + /^@grafana\/data/i, + + // Mark legacy SDK imports as external if their name starts with the "grafana/" prefix + ({ request }: ExternalItemFunctionData, callback: (error?: Error, result?: string) => void) => { + const prefix = 'grafana/'; + const hasPrefix = (request: string) => request.indexOf(prefix) === 0; + const stripPrefix = (request: string) => request.slice(prefix.length); + + if (request && hasPrefix(request)) { + return callback(undefined, stripPrefix(request)); + } + + callback(); + }, +]; diff --git a/.config/docker-compose-base.yaml b/.config/docker-compose-base.yaml new file mode 100644 index 0000000..4cfe7a7 --- /dev/null +++ b/.config/docker-compose-base.yaml @@ -0,0 +1,25 @@ +services: + grafana: + user: root + container_name: 'andydixon-chargevizbattery-panel' + + build: + context: . + args: + grafana_image: ${GRAFANA_IMAGE:-grafana-enterprise} + grafana_version: ${GRAFANA_VERSION:-12.2.0} + development: ${DEVELOPMENT:-false} + anonymous_auth_enabled: ${ANONYMOUS_AUTH_ENABLED:-true} + ports: + - 3000:3000/tcp + volumes: + - ../dist:/var/lib/grafana/plugins/andydixon-chargevizbattery-panel + - ../provisioning:/etc/grafana/provisioning + - ..:/root/andydixon-chargevizbattery-panel + + environment: + NODE_ENV: development + GF_LOG_FILTERS: plugin.andydixon-chargevizbattery-panel:debug + GF_LOG_LEVEL: debug + GF_DATAPROXY_LOGGING: 1 + GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: andydixon-chargevizbattery-panel diff --git a/.config/entrypoint.sh b/.config/entrypoint.sh new file mode 100644 index 0000000..00c69f2 --- /dev/null +++ b/.config/entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +if [ "${DEV}" = "false" ]; then + echo "Starting test mode" + exec /run.sh +fi + +echo "Starting development mode" + +if grep -i -q alpine /etc/issue; then + exec /usr/bin/supervisord -c /etc/supervisord.conf +elif grep -i -q ubuntu /etc/issue; then + exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf +else + echo 'ERROR: Unsupported base image' + exit 1 +fi + diff --git a/.config/eslint.config.mjs b/.config/eslint.config.mjs new file mode 100644 index 0000000..bafeaf5 --- /dev/null +++ b/.config/eslint.config.mjs @@ -0,0 +1,38 @@ +/* + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in + * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-eslint-config + */ + +import { defineConfig } from 'eslint/config'; +import grafanaConfig from '@grafana/eslint-config/flat.js'; + +export default defineConfig([ + ...grafanaConfig, + { + rules: { + 'react/prop-types': 'off', + }, + }, + { + files: ['src/**/*.{ts,tsx}'], + + languageOptions: { + parserOptions: { + project: './tsconfig.json', + }, + }, + + rules: { + '@typescript-eslint/no-deprecated': 'warn', + }, + }, + { + files: ['./tests/**/*'], + + rules: { + 'react-hooks/rules-of-hooks': 'off', + }, + }, +]); diff --git a/.config/jest-setup.js b/.config/jest-setup.js new file mode 100644 index 0000000..7b1771e --- /dev/null +++ b/.config/jest-setup.js @@ -0,0 +1,28 @@ +/* + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in + * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-jest-config + */ + +import '@testing-library/jest-dom'; +import { TextEncoder, TextDecoder } from 'util'; + +Object.assign(global, { TextDecoder, TextEncoder }); + +// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom +Object.defineProperty(global, 'matchMedia', { + writable: true, + value: (query) => ({ + matches: false, + media: query, + onchange: null, + addListener: jest.fn(), // deprecated + removeListener: jest.fn(), // deprecated + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + }), +}); + +HTMLCanvasElement.prototype.getContext = () => {}; diff --git a/.config/jest.config.js b/.config/jest.config.js new file mode 100644 index 0000000..efe1938 --- /dev/null +++ b/.config/jest.config.js @@ -0,0 +1,44 @@ +/* + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in + * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-jest-config + */ + +const path = require('path'); +const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils'); + +module.exports = { + moduleNameMapper: { + '\\.(css|scss|sass)$': 'identity-obj-proxy', + 'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'), + }, + modulePaths: ['/src'], + setupFilesAfterEnv: ['/jest-setup.js'], + testEnvironment: 'jest-environment-jsdom', + testMatch: [ + '/src/**/__tests__/**/*.{js,jsx,ts,tsx}', + '/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', + '/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}', + ], + transform: { + '^.+\\.(t|j)sx?$': [ + '@swc/jest', + { + sourceMaps: 'inline', + jsc: { + parser: { + syntax: 'typescript', + tsx: true, + decorators: false, + dynamicImport: true, + }, + }, + }, + ], + }, + // Jest will throw `Cannot use import statement outside module` if it tries to load an + // ES module without it being transformed first. ./config/README.md#esm-errors-with-jest + transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)], + watchPathIgnorePatterns: ['/node_modules', '/dist'], +}; diff --git a/.config/jest/mocks/react-inlinesvg.tsx b/.config/jest/mocks/react-inlinesvg.tsx new file mode 100644 index 0000000..d540f3a --- /dev/null +++ b/.config/jest/mocks/react-inlinesvg.tsx @@ -0,0 +1,25 @@ +// Due to the grafana/ui Icon component making fetch requests to +// `/public/img/icon/.svg` we need to mock react-inlinesvg to prevent +// the failed fetch requests from displaying errors in console. + +import React from 'react'; + +type Callback = (...args: any[]) => void; + +export interface StorageItem { + content: string; + queue: Callback[]; + status: string; +} + +export const cacheStore: { [key: string]: StorageItem } = Object.create(null); + +const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/; + +const InlineSVG = ({ src }: { src: string }) => { + // testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`) + const testId = src.replace(SVG_FILE_NAME_REGEX, '$2'); + return ; +}; + +export default InlineSVG; diff --git a/.config/jest/utils.js b/.config/jest/utils.js new file mode 100644 index 0000000..55d9cb6 --- /dev/null +++ b/.config/jest/utils.js @@ -0,0 +1,37 @@ +/* + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in .config/README.md + */ + +/* + * This utility function is useful in combination with jest `transformIgnorePatterns` config + * to transform specific packages (e.g.ES modules) in a projects node_modules folder. + */ +const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!.*(${moduleNames.join('|')})\/.*)`; + +// Array of known nested grafana package dependencies that only bundle an ESM version +const grafanaESModules = [ + '.pnpm', // Support using pnpm symlinked packages + '@grafana/schema', + '@wojtekmaj/date-utils', + 'd3', + 'd3-color', + 'd3-force', + 'd3-interpolate', + 'd3-scale-chromatic', + 'get-user-locale', + 'marked', + 'memoize', + 'mimic-function', + 'ol', + 'react-calendar', + 'react-colorful', + 'rxjs', + 'uuid', +]; + +module.exports = { + nodeModulesToTransform, + grafanaESModules, +}; diff --git a/.config/supervisord/supervisord.conf b/.config/supervisord/supervisord.conf new file mode 100644 index 0000000..47624f0 --- /dev/null +++ b/.config/supervisord/supervisord.conf @@ -0,0 +1,15 @@ +[supervisord] +nodaemon=true +user=root + +[program:grafana] +user=root +directory=/var/lib/grafana +command=/run.sh +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 +redirect_stderr=true +killasgroup=true +stopasgroup=true +autostart=true + diff --git a/.config/tsconfig.json b/.config/tsconfig.json new file mode 100644 index 0000000..c0fc6d4 --- /dev/null +++ b/.config/tsconfig.json @@ -0,0 +1,26 @@ +/* + * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️ + * + * In order to extend the configuration follow the steps in + * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-typescript-config + */ +{ + "compilerOptions": { + "alwaysStrict": true, + "declaration": false, + "rootDir": "../src", + "baseUrl": "../src", + "typeRoots": ["../node_modules/@types"], + "resolveJsonModule": true + }, + "ts-node": { + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "esModuleInterop": true + }, + "transpileOnly": true + }, + "include": ["../src", "./types"], + "extends": "@grafana/tsconfig" +} diff --git a/.config/types/bundler-rules.d.ts b/.config/types/bundler-rules.d.ts new file mode 100644 index 0000000..e67197c --- /dev/null +++ b/.config/types/bundler-rules.d.ts @@ -0,0 +1,37 @@ +// Image declarations +declare module '*.gif' { + const src: string; + export default src; +} + +declare module '*.jpg' { + const src: string; + export default src; +} + +declare module '*.jpeg' { + const src: string; + export default src; +} + +declare module '*.png' { + const src: string; + export default src; +} + +declare module '*.webp' { + const src: string; + export default src; +} + +declare module '*.svg' { + const src: string; + export default src; +} + +// Font declarations +declare module '*.woff'; +declare module '*.woff2'; +declare module '*.eot'; +declare module '*.ttf'; +declare module '*.otf'; diff --git a/.config/types/webpack-plugins.d.ts b/.config/types/webpack-plugins.d.ts new file mode 100644 index 0000000..6dbab10 --- /dev/null +++ b/.config/types/webpack-plugins.d.ts @@ -0,0 +1,83 @@ +declare module 'replace-in-file-webpack-plugin' { + import { Compiler, Plugin } from 'webpack'; + + interface ReplaceRule { + search: string | RegExp; + replace: string | ((match: string) => string); + } + + interface ReplaceOption { + dir?: string; + files?: string[]; + test?: RegExp | RegExp[]; + rules: ReplaceRule[]; + } + + class ReplaceInFilePlugin extends Plugin { + constructor(options?: ReplaceOption[]); + options: ReplaceOption[]; + apply(compiler: Compiler): void; + } + + export = ReplaceInFilePlugin; +} + +declare module 'webpack-livereload-plugin' { + import { ServerOptions } from 'https'; + import { Compiler, Plugin, Stats, Compilation } from 'webpack'; + + interface Options extends Pick { + /** + * protocol for livereload `