diff --git a/.github/workflows/pre_commit.yaml b/.github/workflows/pre_commit.yaml index ad7cfbd..8859a85 100644 --- a/.github/workflows/pre_commit.yaml +++ b/.github/workflows/pre_commit.yaml @@ -30,8 +30,8 @@ jobs: SKIP: "no-commit-to-branch" # if not skipped, will always fail on main - name: Push changes run: | - git config --global user.name "github-actions" - git config --global user.email "github-actions@github.com" + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" git add . if git diff-index --quiet HEAD; then echo "No changes were made" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6b7559..e8fce41 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,14 +22,14 @@ repos: rev: v3.0.1 hooks: - id: prettier - files: \.md$ + files: \.(md|mdx)$ - repo: local hooks: - id: prevent-todo-comments name: prevent todo comments - entry: '\/\/ *(TODO|FIXME)\b' # matches a golang comment beginning with "TODO" or "FIXME" + entry: '[ ^](//|#| + -- Package structure standards: https://github.com/golang-standards/project-layout +- [Package structure standards](https://github.com/golang-standards/project-layout) - Use guard clauses if applicable - Try to avoid using else. Most of the time these can be replaced by just placing the else block content directly after the if or by refactoring the if block to be an additional function. - Comments on funcs/types (esp. public ones) @@ -46,17 +46,21 @@ Try to stick to golang best practices and standards: ## Issues -If applicable use the issue template. This ensures a consistent structure which makes it easier to find important details. -Issues which aren't ready for processing, can be marked as a draft by writing "Draft: " infront of the issue name. +If applicable use the issue template. +This ensures a consistent structure which makes it easier to find important details. +Issues which aren't ready for processing, can be marked as a draft by writing "Draft: " in front of the issue name. ## Pull Requests -Use the Pull Request Template. This ensures a consistent structure which makes it easier to find important details. +Use the Pull Request Template. +This ensures a consistent structure which makes it easier to find important details. Set yourself and any other collaborators as assignee. ## Pre Commit -It is recommended to install pre-commit. This insures that formatting is consistent, you don't commit to protected branches and you don't accidentally commit broken code or new functionality without changing the tests. The installation process is in the [README](README.md#setting-up-pre-commit) +It is recommended to install pre-commit. +This ensures that formatting is consistent, you don't commit to protected branches and you don't accidentally commit broken code or new functionality without changing the tests. +The installation process is on [our website](https://caas-team.github.io/GoKubeDownscaler/guides/developing#setting-up-pre-commit). ## Versioning @@ -67,7 +71,7 @@ Releases are following the semver versioning standard: Layout: `..` (example: 1.1.0) - MAJOR: increment on breaking changes -- MINOR: increment on new funcitonality/features +- MINOR: increment on new functionality/features - PATCH: increment on small bug fixes -You can find more infomration on semantic versioning here [here](https://semver.org/) +You can find more information on semantic versioning [on the official website](https://semver.org/). diff --git a/README.md b/README.md index 0650716..f50f5ac 100644 --- a/README.md +++ b/README.md @@ -1,542 +1,33 @@ # GoKubeDownscaler -GitHub Release -GitHub License -Contributers -Stars -Slack Workspace +GitHub Release +GitHub License +Contributors +Stars +Slack Workspace -A vertical autoscaler for Kubernetes workloads. +A horizontal autoscaler for Kubernetes workloads. This is a golang port of the popular [(py-)kube-downscaler](github.com/caas-team/py-kube-downscaler) with improvements and quality of life changes. - +## Documentation and Guides -## Table of contents +The Documentation and Guides can be found on [our website](https://caas-team.github.io/GoKubeDownscaler). - - - - -- [Scalable Resources](#scalable-resources) - - [CronJobs](#cronjobs) - - [DaemonSets](#daemonsets) - - [Deployments](#deployments) - - [Horizontal Pod Autoscalers (HPA)](#horizontal-pod-autoscalers) - - [Jobs](#jobs) - - [PodDisruptionBudgets](#poddisruptionbudgets) - - [ScaledObjects](#scaledobjects) - - [StatefulSets](#statefulsets) - - [Rollouts](#rollouts) - - [Stacks](#stacks) - - [Prometheuses](#prometheuses) -- [Installation](#installation) -- [Configuration](#configuration) - - [Annotations](#annotations) - - [Arguments](#arguments) - - [Environment Variables](#environment-variables) - - [Timespans](#timespans) - - [Duration](#duration) -- [Concepts](#concepts) - - [Layers](#layers) - - [Values](#values) -- [Migrating from py-kube-downscaler](#migrating-from-py-kube-downscaler) - - [Basic Migration](#basic-migration) - - [Edge Cases](#edge-cases) - - [Differences to py-kube-downscaler](#differences-to-py-kube-downscaler) - - [Missing Features](#missing-features) -- [Troubleshooting](#troubleshooting) -- [Developing](#developing) - - [Cloning the Repository](#cloning-the-repository) - - [Setting up Pre-Commit](#setting-up-pre-commit) - - [Testing the downscaler](#testing-the-downscaler) - -## Scalable Resources - -These are the resources the Downscaler can scale: - - - -- CronJobs: - - sets the cronjobs suspend property to true, halting it from running on the schedule -- Daemonsets: - - adds a label which matches none of the nodes to the nodeselector, stopping its pods from running on any node -- Deployments: - - sets the replica count to the [downscale replicas](#downscale-replicas) -- Horizontal Pod Autoscalers (HPA): - - sets the minReplicas of the HPA to the [downscale replicas](#downscale-replicas). Will throw an error if the downscale replicas is smaller than 1 -- Jobs: - - sets the jobs suspend property to true, will stop execution of the job until upscaled again -- PodDisruptionBudgets: - - sets either maxUnavailable or minAvailable to the [downscale replicas](#downscale-replicas). Will not scale if minAvailable or maxUnavailable are percentiles instead of replica counts. -- ScaledObjects: - - sets the paused replicas annotation to the [downscale replicas](#downscale-replicas) -- StatefulSets: - - sets the replica count to the [downscale replicas](#downscale-replicas) -- Rollouts: - - sets the replica count to the [downscale replicas](#downscale-replicas) -- Stacks: - - sets the replica count to the [downscale replicas](#downscale-replicas) -- Prometheuses: - - sets the replica count to the [downscale replicas](#downscale-replicas) +An Offline copy of the documentation can be found in [`website/content/docs`](./website/content/docs) and [`website/content/guides`](./website/content/guides). +In there are Markdown files which can be viewed in any text editor or inside of a Markdown Viewer. ## Installation -Installation is done via the [Helm Chart](./deployments/chart/README.md) - -## Configuration - -### Annotations - -Annotations can be applied to a [workload](#scalable-resources) or its namespace. See the [layers concept](#layers) for more details on which of the layers [values](#values) will be used. - -- downscaler/downscale-period: - - sets the [downscale-period](#downscale-period) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/downtime: - - sets the [downtime](#downtime) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/upscale-period: - - sets the [upscale-period](#upscale-period) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/uptime: - - sets the [uptime](#uptime) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/exclude: - - sets the [exclude](#exclude) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/exclude-until: - - sets the [exclude-until](#exclude-until) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/force-uptime: - - sets the [force-uptime](#force-uptime) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/force-downtime: - - sets the [force-downtime](#force-downtime) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/downscale-replicas: - - sets the [downscale-replicas](#downscale-replicas) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer -- downscaler/grace-period: - - sets the [grace-period](#grace-period) value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer - -### Arguments - -CLI arguments set [layer values](#values) and runtime configuration at the start of the program. See the [layers concept](#layers) for more details on which of the layers [values](#values) will be used. - -Layer Values: - -- --upscale-period: - - sets the [upscale-period](#upscale-period) value on the [cli layer](#cli-layer) -- --default-uptime: - - sets the [uptime](#uptime) value on the [cli layer](#cli-layer) -- --downscale-period: - - sets the [downscale-period](#downscale-period) value on the [cli layer](#cli-layer) -- --default-downtime: - - sets the [downtime](#downtime) value on the [cli layer](#cli-layer) -- --downtime-replicas: - - sets the [downscale replicas](#downscale-replicas) value on the [cli layer](#cli-layer) -- --explicit-include: - - sets the [exclude value](#exclude) on the [cli layer](#cli-layer) to true, which excludes every workload unless the exclude value on the [workload](#workload-layer) or [namespace](#namespace-layer) layer is set to false. See the [layers concept](#layers) for more details. - -Runtime Configuration: - -- --dry-run: - - boolean - - sets the downscaler into dry run mode, which makes it just print the actions it would have performed - - default: false -- --debug: - - boolean - - makes the downscaler print more/debug information on what it currently does and what happens to the workloads - - default: false -- --once: - - boolean - - makes the downscaler exit after one scan - - default: false -- --interval: - - [duration](#duration) - - sets the wait time between scans - - default: 30s -- --namespace: - - comma seperated list of namespaces (`some-ns,other-ns` or `some-ns, other-ns`) - - makes the downscaler get workloads only from the specified namespaces - - default: all namespaces -- --include-resources: - - comma seperated list of (case-insensitive) [scalable resources](#scalable-resources) (`deployments,statefulsets` or `deployments, statefulsets`) - - enables scaling of workloads with the specified resource type - - default: deployments -- --exclude-namespaces: - - comma seperated list of regex patterns matching namespaces (`some-ns,other-ns,kube-.*` or `some-ns, other-ns, kube-.*`) - - excludes the matching namespaces from being scaled - - default: kube-system, kube-downscaler -- --exclude-deployments: - - comma seperated list of regex patterns matching workload names (`some-workload,other-workload,.*kube-downscaler` or `some-workload, other-workload, .*kube-downscaler`) - - excludes the matching workloads from being scaled - - default: none -- --matching-labels: - - comma seperated list of regex patterns matching labels with their value (`some-label=val,other-label=value,another-label=.*` or `some-label=val, other-label=value, another-label=.*`) - - makes the downscaler only include workloads which have any label that machtes any of the specified labels and values - - default: none -- --time-annotation: - - string key of an annotation on the workload containing a [RFC3339 Timestamp](https://datatracker.ietf.org/doc/html/rfc3339) - - when set grace-period will use the timestamp in the annotation instead of the creation time of the workload - - default: none (uses the workloads creation time) - -### Environment Variables - -Environment Variables set [layer values](#values) on the [env layer](#env-layer) and runtime configuration at the start of the program. See the [layers concept](#layers) for more details on which of the layers [values](#values) will be used. - -Layer Values: - -- UPSCALE_PERIOD: - - sets the [upscale-period](#upscale-period) value on the [env layer](#env-layer) -- DEFAULT_UPTIME: - - sets the [uptime](#uptime) value on the [env layer](#env-layer) -- DOWNSCALE_PERIOD: - - sets the [downscale-period](#downscale-period) value on the [env layer](#env-layer) -- DEFAULT_DOWNTIME: - - sets the [downtime](#downtime) value on the [env layer](#env-layer) - -Runtime Configuration: - -- EXCLUDE_NAMESPACES: - - overwrites the value set by the [--exclude-namespaces](#--exclude-namespaces) cli argument -- EXCLUDE_DEPLOYMENTS: - - overwrites the value set by the [--exclude-deployments](#--exclude-deployments) cli argument - -### Timespans - -There are two different kinds of Timespans: - -- Absolute Timespans: a timespan defined by two [RFC3339 Timestamps](https://datatracker.ietf.org/doc/html/rfc3339) -- Relative Timespans: reoccuring on a schedule - -#### Configuration of an Absolute Timespan - -```text -- -or - - -``` - -example: `2024-07-29T08:30:00Z - 2024-07-29T16:00:00+02:00` - -See [RFC3339 Timestamps](https://datatracker.ietf.org/doc/html/rfc3339) for more information - -#### Configuration of a Relative Timespan - -```text -- - -``` - -example: - -```text -Mon-Fri 08:00-20:00 Asia/Tokyo # From Monday to Friday: from 08:00 to 20:00 -Sat-Sun 00:00-24:00 UTC # On The Weekend: the entire day -Mon-Fri 20:00-08:00 Australia/Sydney # From Monday to Friday: from Midnight to 08:00 and from 20:00 until end of day -Mon-Sun 00:00-00:00 America/New_York # The timespan never matches, this would not do anything -Mon-Tue 20:00-24:00 Africa/Johannesburg # On Monday and Tuesday: from 20:00 to midnight -Mon-Tue 20:00-00:00 Europe/Amsterdam # On Monday and Tuesday: from 20:00 to midnight -``` - -Valid Values: - -Weekdays: (case-insensitive) - -- Mon -- Tue -- Wed -- Thu -- Fri -- Sat -- Sun - -Timezones: - -- all from the [IANA Time Zone database](https://www.iana.org/time-zones) - -> [!Note] -> The IANA Time Zone database mainly supports regional/city timezones (example: `Europe/Berlin`, `America/Los_Angeles`) instead of abbreviations (example: `CEST`, `PST`, `PDT`). -> It supports some abbreviations like `CET`, `MET` and `PST8PDT` but these (not including `UTC`) shouldn't be used, and only exist for backwards compatibility. -> Time of day: 00:00 - 24:00 - -#### Multiple/Complex Timespans - -In some cases you need to define multiple Timespans. You can do this like this: - -``` -,, -``` - -OR with optional spaces: - -``` -, , -``` - -The timespans can be absolute, relative or mixed. - -Example: downscale over the weekend and at night: - -``` -Sat-Sun 00:00-24:00 Europe/Berlin, Mon-Fri 20:00-07:00 Europe/Berlin -``` - -### Duration - -A duration can be defined either by an integer representing seconds - -```text -"120" # 120 seconds (2 minutes) -"900" # 900 seconds (15 minutes) -``` - -Or by a duration string: - -```text -"1h30m" # 1 hour and 30 minutes -"1.5h" # 1 hour and 30 minutes -"2m" # 2 minutes -"10s" # 10 seconds -"300s" # 300 seconds -``` - -Other units: - -```text -"ns" # nanoseconds -"us"/"µs" # microseconds -"ms" # milliseconds -"s" # seconds -"m" # minutes -"h" # hours -``` - -See [Golangs official documentation](https://pkg.go.dev/time#ParseDuration) for more information - -## Concepts - -### Layers - -Layers are layers of values. If the highest Layer doesn't have a value, it falls through it and tries to get the value from the next lower layer. - -#### Layer Hierarchy - -1. [Workload Layer](#workload-layer) -2. [Namespace Layer](#namespace-layer) -3. [CLI Layer](#cli-layer) -4. [ENV Layer](#env-layer) - -#### Workload Layer - -Defined by the [annotations](#annotations) on the [workload](#scalable-resources) every scan. - -#### Namespace Layer - -Defined by the [annotations](#annotations) on the namespace every scan. - -#### CLI Layer - -Defined by the [command line arguments](#arguments) at startup. - -#### ENV Layer - -Defined by the [environemt variables](#environment-variables) at startup. - -#### Examples - -> [!Note] -> A process line with "(...)" is a compacted form, instead of showing the process on each layer - -```text ---- Layers -Workload: (no annotations) -Namespace: exclude=true -CLI: (defaults) -ENV: (no env vars) ---- Process: -Exclusion not specified on workload layer, going to next layer -Exclusion set to true on namespace layer, excluding workload ---- Result: -Workload is excluded, no changes will be made to it -``` - -```text ---- Layers -Workload: exclude=false -Namespace: exclude=true -CLI: downtime="Mon-Fri 08:00-16:00 Europe/Berlin" -ENV: (no env vars) ---- Process: -Exclusion set to false on workload layer, not excluding workload -No forced scaling found on any layer (...) -No scaling specified on Workload layer, going to next layer -No scaling specified on Namespace layer, going to next layer -Scaling "downtime" specified on CLI layer, scaling according to the downtime schedule on the cli layer ---- Result: -Workload will be scaled according to the downtime schedule on the cli layer -``` - -```text ---- Layers -Workload: uptime="Mon-Fri 08:00-16:00 Europe/Berlin" -Namespace: force-downtime=true -CLI: downtime="Mon-Fri 20:00-08:00 America/Los_Angeles" -ENV: (no env vars) ---- Process: -Exclusion not set on any layer (...) -Forced scaling found on namespace layer, forcing downscale (...) ---- Result: -Workload will be forced into a down-scaled state -``` - -```text ---- Layers -Workload: uptime="Mon-Fri 08:00-16:00 Europe/Berlin" -Namespace: force-downtime=true -CLI: downtime="Mon-Fri 20:00-08:00 America/Los_Angeles" -ENV: (no env vars) ---- Process: -Exclusion not set on any layer (...) -No forced scaling found on any layer (...) -Scaling "uptime" set on workload layer, scaling according to the uptime schedule on the cli layer ---- Result: -Workload will be scaled according to the uptime schedule on the cli layer -``` - -### Values - -- downscale-period: - - comma seperated list of [timespans](#timespans) - - within these periods the [workload](#scalable-resources) will be scaled down, outside of them the state will be ignored - - incompatible with [downtime](#downtime), [uptime](#uptime) -- downtime: - - comma seperated list of [timespans](#timespans) - - within these timespans the [workload](#scalable-resources) will be scaled down, outside of them it will be scaled up - - incompatible with [downscale-period](#downscale-period), [upscale-period](#upscale-period), [uptime](#uptime) -- upscale-period: - - comma seperated list of [timespans](#timespans) - - within these periods the [workload](#scalable-resources) will be scaled up, outside of them the state will be ignored - - incompatible with [downtime](#downtime), [uptime](#uptime) -- uptime: - - comma seperated list of [timespans](#timespans) - - within these timespans the [workload](#scalable-resources) will be scaled up, outside of them it will be scaled down - - incompatible with [downscale-period](#downscale-period), [upscale-period](#upscale-period), [downtime](#downtime) -- exclude: - - boolean - - when true, the [workload](#scalable-resources) will be excluded/ignored while scaling -- exclude-until: - - RFC3339 Timestamp - - the [workload](#scalable-resources) will be excluded until this time -- force-uptime: - - boolean - - if set to true the [workload](#scalable-resources) will be forced into an uptime state - - incompatible with [force-downtime](#force-downtime) -- force-downtime: - - boolean - - if set to true the [workload](#scalable-resources) will be forced into an downtime state - - incompatible with [force-uptime](#force-uptime) -- downscale-replicas: - - int - - the replicas that the [workload](#scalable-resources) should have while downscaled -- grace-period: - - [duration](#duration) - - the duration a [workload](#scalable-resources) has to exist until it is first scaled. Will use the [time annotation](#--time-annotation) instead of the creation time of the workload if the time annotation argument is set. - -See [the layers concept](#layers) for more details on which of the layers [values](#values) will be used - -## Migrating from py-kube-downscaler - -### Basic migration - -1. Remove the old kube-downscaler - -```bash -helm uninstall py-kube-downscaler -``` - -2. Make sure all programs/non-default use cases support the [breaking changes](#edge-cases) -3. Make sure all timestamps are [RFC 3339](#diff-uniform-timestamp) compatible -4. [Install the new downscaler](#installation) - -### Edge cases - -If you had an implementation that used some of the quirks of the py-kube-downscaler you might need to change them to work with the GoKubeDownscaler. - -Some cases where this might be needed include: - -- [Incompatibility instead of priority](#diff-incompatible) - - example: if you had a program that dynamically added an uptime annotation on a workload with a downtime annotation because you relied on the uptime annotation taking over -- [Layer system](#diff-layer-system) - - example: the behaviour of excluding a namespace resulting in all workloads in it being excluded is not quite the same, as the workload could overwrite this by setting exclude to false -- [A pod that upscales the whole cluster](https://github.com/caas-team/py-kube-downscaler/blob/main/README.md?plain=1#L90) - - this behaviour is no longer available -- [RFC3339 timestamp](#diff-uniform-timestamp) - - if you used the short form versions of the ISO 8601 timestamp (`2023-08-12`, `2023-233` or `2023-W34-1`) -- [Actual exclusion](#diff-actual-exclusion) - - example: if you had a program that dynamically excluded a namespace and need it to then go in an upscaled state - -### Differences to py-kube-downscaler - -Incompatibility instead of priority: - -- some values are now incompatible instead of using one over the other if both are set -- backwards compatible: shouldn't break anything in most cases - -Duration units: - -- instead of integers representing seconds you can also use [duration strings](#duration) -- backwards compatible: fully compatible, integer seconds are still supported - -Layer system: - -- makes it easier and more uniform to know what configuration is going to be used. All annotations can now also be easily applied to namespaces. See [the layers concept](#layers) for information on the new behaviour -- backwards compatible: shouldn't break anything in most cases - -[--explicit-include](#--explicit-include) cli argument: - -- a simple way to explicitly include single workloads. See [--explicit-include](#--explicit-include) for more details. -- backwards compatible: fully compatible, no prior behaviour was changed - -Comfort spaces: - -- allows for spaces in configuration to make the configuration more readable. (applies to: any comma seperated list, [absolute timespans](#configuration-of-an-absolute-timespan)) -- backwards compatible: fully compatible, you can still use the configuration without spaces - -Uniform timestamp: - -- all timestamps are [RFC3339 Timestamps](https://datatracker.ietf.org/doc/html/rfc3339) this is more optimized for golang, more consistent and also used by Kubernetes itself -- backwards compatible: mostly, unless you used a short form of ISO 8601 (`2023-08-12`, `2023-233` or `2023-W34-1`) it should be totally fine to not change anything - -Overlapping [relative timespans](#configuration-of-a-relative-timespan) into next day: - -- relative timespans can overlap into the "next" day (`Mon-Fri 20:00-06:00 UTC`). See [Relative Timespans](#configuration-of-a-relative-timespan) for information on how this behaves -- backwards compatible: fully compatible, this didn't change any existing functionallity - -Actual exclusion: - -- [excluding a workload](#exclude) won't force the workload to be upscaled, instead it will just ignore its state -- backwards compatible: should be fully compatible, unless your implementation relies on this - -IANA Timezones: - -- the downscaler uses the [IANA timezone database](https://www.iana.org/time-zones) -- backwards compatible: fully compatible, "Olson timezones" is just a lesser known synonym for the IANA time zone database - -Workload error events: - -- errors with the configuration on the [namespace](#namespace-layer) or [workload layer](#workload-layer) are shown as events on the workload -- backwards compatible: fully compatible, doesn't change any existing functionality - ---deployment-time-annotation -> [--time-annotation](#--time-annotation): - -- the `--deployment-time-annotation` cli argument was changed to `--time-annotation` -- backwards compatible: if you used this cli argument, you have to change it to `--time-annotation` - -### Missing Features - -Currently the GoKubeDownscaler is still a WIP. This means that there are still some features missing. You can find a list of the known-missing features [here](/../../labels/missing%20feature). If you think that any other features are missing or you have an idea for a new feature, feel free to open an [Issue](/../../issues/) - -## Troubleshooting - -See [troubleshooting](docs/troubleshooting.md) +Installation is done via the [Helm Chart](./deployments/chart/). +Information on how to install the Downscaler is on [our website](https://caas-team.github.io/GoKubeDownscaler/guides/getting-started/installation). ## Developing -Please read the [contribution manifest](./CONTRIBUTING.md) +This section covers the basics of developing on this repo, a more detailed guide can be found on [our website](https://caas-team.github.io/GoKubeDownscaler/guides/developing). + +Please read the [contribution manifest](./CONTRIBUTING.md). -### Cloning the Repository +### Cloning the repository ```bash git clone https://github.com/caas-team/GoKubeDownscaler.git @@ -569,3 +60,19 @@ The downscaler will use the current-context in the kubeconfig. ```bash go run -k=path/to/kubeconfig # ... additional configuration ``` + +### Testing the website + +#### installing dependencies + +```bash +npm install --prefix website +``` + +#### running it locally + +```bash +npm run --prefix website start +``` + +after that the website is available on `localhost:3000/GoKubeDownscaler` diff --git a/deployments/chart/README.md b/deployments/chart/README.md index 12c95c8..fa71867 100644 --- a/deployments/chart/README.md +++ b/deployments/chart/README.md @@ -53,26 +53,26 @@ Here is a brief overview of all the values contained in this chart: -| **Key** | **Description** | -| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| replicaCount | Adjusts the number of replicas that the go-kube-downscaler deployment will have. | -| image | Contains the repository URL and the image tag for the image you want to use. | -| arguments | Defines command line arguments for the container. | -| includedResources | Defines all the resources that the go-kube-downscaler is supposed to be able to handle. | -| fullnameOverride | Overrides the full names of the created Kubernetes resources with the provided name if set. | -| nameOverride | Overrides the chart name for the created Kubernetes resources. | -| constrainedDownscaler | Sets the go-kube-downscaler to a constrained state if true, meaning that it does not run clusterwide but restricted to a list of namespaces. These namespaces are listed in [constrainedNamespaces](#constrainedNamespaces). | -| constrainedNamespaces | A list of namespaces the go-kube-downscaler is going to operate on when constrained. | -| serviceAccount | Specifies whether a new ServiceAccount is supposed to be created and if not, what the name of the ServiceAccount to use is. | -| podSecurityContext | Defines the SecurityContext on pod level. (More info [here](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)) | -| securityContext | Defines the SecurityContext on container level. (More info [here](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)) | -| resources | Defines the CPU and memory limits and requests. | -| nodeSelector | Defines labels of nodes that you want the deployment to schedule them on. | -| tolerations | Adds tolerations to the pods of the deployment to be able to be scheduled on nodes with matching taints. (More info [here](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)) | -| affinity | Defines rules for node affinity and pod affinity/anti-affinity. (More info [here](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/)) | -| configMapName | The name of the configmap for the go-kube-downscaler. | -| excludedNamespaces | A list of namespaces that are supposed to be excluded from the downscaling process of the go-kube-downscaler. | -| extraConfig | Adds additional specified environment variables to the ConfigMap. | +| **Key** | **Description** | +| ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| replicaCount | Adjusts the number of replicas that the go-kube-downscaler deployment will have. | +| image | Contains the repository URL and the image tag for the image you want to use. | +| arguments | Defines command line arguments for the container. | +| includedResources | Defines all the resources that the go-kube-downscaler is supposed to be able to handle. | +| fullnameOverride | Overrides the full names of the created Kubernetes resources with the provided name if set. | +| nameOverride | Overrides the chart name for the created Kubernetes resources. | +| constrainedDownscaler | Sets the go-kube-downscaler to a constrained state if true, meaning that it does not run clusterwide but restricted to a list of namespaces. These namespaces are listed in [constrainedNamespaces](#constrainedNamespaces). | +| constrainedNamespaces | A list of namespaces the go-kube-downscaler is going to operate on when constrained. | +| serviceAccount | Specifies whether a new ServiceAccount is supposed to be created and if not, what the name of the ServiceAccount to use is. | +| podSecurityContext | Defines the SecurityContext on pod level. (More info [here](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)) | +| securityContext | Defines the SecurityContext on container level. (More info [here](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)) | +| resources | Defines the CPU and memory limits and requests. | +| nodeSelector | Defines labels of nodes that you want the deployment to schedule them on. | +| tolerations | Adds tolerations to the pods of the deployment to be able to be scheduled on nodes with matching taints. (More info [here](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)) | +| affinity | Defines rules for node affinity and pod affinity/anti-affinity. (More info [here](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/)) | +| configMapName | The name of the configmap for the go-kube-downscaler. | +| excludedNamespaces | A list of namespaces that are supposed to be excluded from the downscaling process of the go-kube-downscaler. | +| extraConfig | Adds additional specified environment variables to the ConfigMap. | The default values can be found [here](./values.yaml). diff --git a/internal/pkg/scalable/cronjobs.go b/internal/pkg/scalable/cronjobs.go index 165ef91..2369efa 100644 --- a/internal/pkg/scalable/cronjobs.go +++ b/internal/pkg/scalable/cronjobs.go @@ -21,7 +21,7 @@ func getCronJobs(namespace string, clientsets *Clientsets, ctx context.Context) return results, nil } -// cronJob is a wrapper for batch/v1.CronJob to implement the suspendScaledResource interface +// cronJob is a wrapper for cronjob.v1.batch to implement the suspendScaledResource interface type cronJob struct { *batch.CronJob } diff --git a/internal/pkg/scalable/daemonsets.go b/internal/pkg/scalable/daemonsets.go index dd27ac5..b772208 100644 --- a/internal/pkg/scalable/daemonsets.go +++ b/internal/pkg/scalable/daemonsets.go @@ -25,7 +25,7 @@ func getDaemonSets(namespace string, clientsets *Clientsets, ctx context.Context return results, nil } -// daemonSet is a wrapper for apps/v1.DeamonSet to implement the Workload interface +// daemonSet is a wrapper for deamonset.v1.apps to implement the Workload interface type daemonSet struct { *appsv1.DaemonSet } diff --git a/internal/pkg/scalable/deployments.go b/internal/pkg/scalable/deployments.go index c54a08e..657809c 100644 --- a/internal/pkg/scalable/deployments.go +++ b/internal/pkg/scalable/deployments.go @@ -21,7 +21,7 @@ func getDeployments(namespace string, clientsets *Clientsets, ctx context.Contex return results, nil } -// deployment is a wrapper for apps/v1.Deployment to implement the replicaScaledResource interface +// deployment is a wrapper for deployment.v1.apps to implement the replicaScaledResource interface type deployment struct { *appsv1.Deployment } diff --git a/internal/pkg/scalable/horizontalpodautoscalers.go b/internal/pkg/scalable/horizontalpodautoscalers.go index 4daffcd..fe0f6ee 100644 --- a/internal/pkg/scalable/horizontalpodautoscalers.go +++ b/internal/pkg/scalable/horizontalpodautoscalers.go @@ -24,7 +24,7 @@ func getHorizontalPodAutoscalers(namespace string, clientsets *Clientsets, ctx c return results, nil } -// horizontalPodAutoscaler is a wrapper for autoscaling/v2.HorizontalPodAutoscaler to implement the replicaScaledResource interface +// horizontalPodAutoscaler is a wrapper for horizontalpodautoscaler.v2.autoscaling to implement the replicaScaledResource interface type horizontalPodAutoscaler struct { *appsv1.HorizontalPodAutoscaler } diff --git a/internal/pkg/scalable/jobs.go b/internal/pkg/scalable/jobs.go index 83518e1..24de818 100644 --- a/internal/pkg/scalable/jobs.go +++ b/internal/pkg/scalable/jobs.go @@ -21,7 +21,7 @@ func getJobs(namespace string, clientsets *Clientsets, ctx context.Context) ([]W return results, nil } -// job is a wrapper for batch/v1.Job to implement the suspendScaledResource interface +// job is a wrapper for job.v1.batch to implement the suspendScaledResource interface type job struct { *batch.Job } diff --git a/internal/pkg/scalable/poddisruptionbudgets.go b/internal/pkg/scalable/poddisruptionbudgets.go index 93e3714..56dc90e 100644 --- a/internal/pkg/scalable/poddisruptionbudgets.go +++ b/internal/pkg/scalable/poddisruptionbudgets.go @@ -25,7 +25,7 @@ func getPodDisruptionBudgets(namespace string, clientsets *Clientsets, ctx conte return results, nil } -// podDisruptionBudget is a wrapper for policy/v1.PodDisruptionBudget to implement the Workload interface +// podDisruptionBudget is a wrapper for poddisruptionbudget.v1.policy to implement the Workload interface type podDisruptionBudget struct { *policy.PodDisruptionBudget } diff --git a/internal/pkg/scalable/rollouts.go b/internal/pkg/scalable/rollouts.go index f22ea2d..b59d0c1 100644 --- a/internal/pkg/scalable/rollouts.go +++ b/internal/pkg/scalable/rollouts.go @@ -21,7 +21,7 @@ func getRollouts(namespace string, clientsets *Clientsets, ctx context.Context) return results, nil } -// rollout is a wrapper for argoproj.io/v1alpha1.Rollout to implement the replicaScaledResource interface +// rollout is a wrapper for rollout.v1alpha1.argoproj.io to implement the replicaScaledResource interface type rollout struct { *argov1alpha1.Rollout } diff --git a/internal/pkg/scalable/scaledobjects.go b/internal/pkg/scalable/scaledobjects.go index ab1bcda..a15de6e 100644 --- a/internal/pkg/scalable/scaledobjects.go +++ b/internal/pkg/scalable/scaledobjects.go @@ -28,7 +28,7 @@ func getScaledObjects(namespace string, clientsets *Clientsets, ctx context.Cont return results, nil } -// scaledObject is a wrapper for keda.sh/v1alpha1.ScaledObject to implement the replicaScaledResource interface +// scaledObject is a wrapper for scaledobject.v1alpha1.keda.sh to implement the replicaScaledResource interface type scaledObject struct { *kedav1alpha1.ScaledObject } diff --git a/internal/pkg/scalable/stacks.go b/internal/pkg/scalable/stacks.go index b446a92..b9c79fa 100644 --- a/internal/pkg/scalable/stacks.go +++ b/internal/pkg/scalable/stacks.go @@ -21,7 +21,7 @@ func getStacks(namespace string, clientsets *Clientsets, ctx context.Context) ([ return results, nil } -// stack is a wrapper for zalando.org/v1.Stack to implement the replicaScaledResource interface +// stack is a wrapper for stack.v1.zalando.org to implement the replicaScaledResource interface type stack struct { *zalandov1.Stack } diff --git a/internal/pkg/scalable/statefulsets.go b/internal/pkg/scalable/statefulsets.go index ee84d91..de3e300 100644 --- a/internal/pkg/scalable/statefulsets.go +++ b/internal/pkg/scalable/statefulsets.go @@ -21,7 +21,7 @@ func getStatefulSets(namespace string, clientsets *Clientsets, ctx context.Conte return results, nil } -// statefulset is a wrapper for apps/v1.StatefulSet to implement the replicaScaledResource interface +// statefulset is a wrapper for statefulset.v1.apps to implement the replicaScaledResource interface type statefulSet struct { *appsv1.StatefulSet } diff --git a/internal/pkg/values/regexList.go b/internal/pkg/values/regexList.go index 7efbc9b..3961bc3 100644 --- a/internal/pkg/values/regexList.go +++ b/internal/pkg/values/regexList.go @@ -12,7 +12,7 @@ func (r *RegexList) Set(text string) error { entries := strings.Split(text, ",") for _, entry := range entries { entry = strings.TrimSpace(entry) - re, err := regexp.Compile(entry) + re, err := regexp.Compile(fmt.Sprintf("^%s$", entry)) if err != nil { return fmt.Errorf("failed to compile stringlist entry as a regex: %w", err) } diff --git a/website/content/_global_md_links.mdx b/website/content/_global_md_links.mdx new file mode 100644 index 0000000..5c959d3 --- /dev/null +++ b/website/content/_global_md_links.mdx @@ -0,0 +1,26 @@ +{/* Repo links */} +[contribution-manifest]: https://github.com/caas-team/GoKubeDownscaler/blob/main/CONTRIBUTING.md "Contribution Manifest" +[chart-yaml]: https://github.com/caas-team/GoKubeDownscaler/blob/main/deployments/chart/Chart.yaml "Chart.yaml" + +{/* Guides links */} +[guides-developing]: /GoKubeDownscaler/guides/developing "Developing Guide" +[guides-developing-website-update]: /GoKubeDownscaler/guides/developing/website#updating-dependencies "Updating Dependencies - Website Development Guide" + +{/* Documentation links */} +[docs-helm-permissions]: /GoKubeDownscaler/TODO "Helm Chart permission Documentation" +[docs-workflows]: /GoKubeDownscaler/docs/workflows "GitHub Workflow Documentation" + +{/* External links */} +[docusaurus]: https://docusaurus.io "Docusaurus" +[docusaurus-markdown-docs]: https://docusaurus.io/docs/markdown-features "Docusaurus Markdown Documentation" +[brew]: https://brew.sh "Brew" +[pre-commit]: https://pre-commit.com "Pre-Commit" +[pre-commit-install]: https://pre-commit.com/#install "Pre-Commit Installation" +[golangci-lint-install]: https://golangci-lint.run/welcome/install/#local-installation "GolangCi-Lint Installation" +[gofumpt-install]: https://github.com/mvdan/gofumpt "GoFumpt Installation" +[go-install]: https://go.dev/doc/install "Go Installation" +[git-install]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git "Git Installation" +[npm-install]: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm#using-a-node-installer-to-install-nodejs-and-npm "NPM Installation" +[svgo]: https://svgo.dev/ "SVGO" +[svgr]: https://react-svgr.com/ "SVGR" +[semver]: https://semver.org/ "Semantic Versioning" diff --git a/website/content/docs/0 - Workflows.mdx b/website/content/docs/0 - Workflows.mdx new file mode 100644 index 0000000..b376de0 --- /dev/null +++ b/website/content/docs/0 - Workflows.mdx @@ -0,0 +1,37 @@ +--- +title: Workflows +id: workflows +--- + +import { GithubLabel } from "/src/components/GithubLabel.tsx"; + +# Workflows + +This section covers documentation on all github workflows in the repository. + +All workflows are in `./.github/workflows`. + +## Auto Assign Author + +This workflow automatically assigns the author of the PR as the assignee unless the assignees were otherwise specified. + +File: `auto_assign_author.yaml` +Runs on: pull_request.opened, pull_request.reopened + +## Check for Release + +This workflow stops a pull request which when merged would result in a new release from being merged automatically. + +The workflow checks if the app version or Helm chart version in the Chart.yaml changed. +This would result in a new release if the pull request were to be merged. + +If merging the PR would result in a new release the label will be added to it. +Additionally a message warning about this and explaining the steps needed to merge will be sent in the pull request. + +The pull request can not be merged until the label gets added to the PR. +After that the label will get removed automatically and the PR can be merged. + +File: `check_for_release.yaml` +Runs on: pull_request.opened, pull_request.synchronize, pull_request.labeled, pull_request.unlabeled + +## Check Version diff --git a/website/content/docs/index.mdx b/website/content/docs/index.mdx deleted file mode 100644 index b3d30c9..0000000 --- a/website/content/docs/index.mdx +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Documentation ---- - -# Documentation diff --git a/website/content/guides/getting-started/0 - Installation.md b/website/content/guides/0 - getting-started/0 - Installation.mdx similarity index 100% rename from website/content/guides/getting-started/0 - Installation.md rename to website/content/guides/0 - getting-started/0 - Installation.mdx diff --git a/website/content/guides/getting-started/1 - Basic Night Time Saving.md b/website/content/guides/0 - getting-started/1 - Basic Night Time Saving.mdx similarity index 100% rename from website/content/guides/getting-started/1 - Basic Night Time Saving.md rename to website/content/guides/0 - getting-started/1 - Basic Night Time Saving.mdx diff --git a/website/content/guides/Getting Started.mdx b/website/content/guides/0 - getting-started/index.mdx similarity index 89% rename from website/content/guides/Getting Started.mdx rename to website/content/guides/0 - getting-started/index.mdx index d9b93a3..2f3bed6 100644 --- a/website/content/guides/Getting Started.mdx +++ b/website/content/guides/0 - getting-started/index.mdx @@ -7,7 +7,7 @@ import DocCardList from "@theme/DocCardList"; # Getting Started -# Basic configuration +# Basic Configuration These are some basic example configurations and usecases: diff --git a/website/content/guides/1 - developing/0 - Downscaler.mdx b/website/content/guides/1 - developing/0 - Downscaler.mdx new file mode 100644 index 0000000..8f2a8a2 --- /dev/null +++ b/website/content/guides/1 - developing/0 - Downscaler.mdx @@ -0,0 +1,106 @@ +--- +title: Downscaler +id: downscaler +--- + +# Downscaler + +This section covers how to start development on the downscaler. + +If you haven't already, read and follow the instructions for [setting up the repository locally][guides-developing]. + +The files for the downscaler can mainly be found in `./cmd/kubedownscaler` and `./internal`. + +## Installing Prerequisite + +Before you start modifying the downscaler you should install its prerequisites. + +### Installing Go + +Installing go is necessary to be able to run the downscaler locally. + +You can either use brew to install and update go: + +```bash +brew install go +``` + +To update go using brew: + +```bash +brew upgrade go +``` + +Or you can follow [these instructions][go-install] to install go another way. + +After that you can check if your installation was successful. + +```bash +go version +``` + +The output should be something like: + +```text +go version go1.23.2 linux/amd64 +``` + +### Installing Dependencies + +Once you have go installed you can start installing the Kubedownscalers dependencies. + +```bash +go mod download +``` + +## Running the Downscaler Locally + +To run the downscaler locally you need to specify a kubeconfig for it to use. +The downscaler will use the current-context selected in the kubeconfig. +The user of the selected context has to have the [permissions required to scale][docs-helm-permissions]. + +```bash +go run ./cmd/kubedownscaler -k path/to/kubeconfig +``` + +## Testing the Downscaler + +To test your code changes you should write or change existing tests to match your new functionality. + +You can run all tests like this: + +```bash +go test ./... +``` + +## Compiling/Building + +You normally don't need to build the binary or docker image locally +as workflows handle building those for releasing new versions. +This is only necessary for eg. testing the docker image. + +### Binary + +This is how you can build a binary of the kubedownscaler: + +```bash +CGO_ENABLED=0 go build -o bin/gokubedownscaler ./cmd/kubedownscaler +``` + +Disabling CGO isn't strictly required although it does sometimes lead to problems. + +### Docker Image + +Building the Docker image is just like building any other Docker image: + +```bash +docker build -t ghcr.io/caas-team/gokubedownscaler:someTag . +``` + +## Running the Docker Image Locally + +To run the Docker container locally you also need to specify a kubeconfig. + +```bash +docker run -v path/to/kubeconfig:/app/kubeconfig ghcr.io/caas-team/gokubedownscaler:latest -k=/app/kubeconfig +``` diff --git a/website/content/guides/1 - developing/1 - Website.mdx b/website/content/guides/1 - developing/1 - Website.mdx new file mode 100644 index 0000000..958dbd4 --- /dev/null +++ b/website/content/guides/1 - developing/1 - Website.mdx @@ -0,0 +1,161 @@ +--- +title: Website +id: website +--- + +# Website + +This section covers how to start developing on the website of the downscaler. + +If you haven't already, read and follow the instructions for [setting up the repository locally][guides-developing]. + +## Installing Prerequisite + +Before being able to develop on the website you need to install some prerequisites. + +### Installing Npm + +NPM is required to be able to install the required packages to start the website. + +You can either use brew to install npm: + +```bash +brew install node +``` + +Or you can install it [another way][npm-install]. + +To check if the installation was successful you can run: + +```bash +node -v +``` + +and + +```bash +npm -v +``` + +The output should be something like: + +```text +v22.6.0 +``` + +for node and + +```text +10.8.2 +``` + +for npm. + +### Installing Dependencies + +After npm is installed you can install the websites dependencies. + +```bash +npm install --prefix website +``` + +### Updating Dependencies + +After pulling new commits that changed `package.json` you should update your node packages. + +To update the dependencies you can use: + +```bash +npm update --prefix website +``` + +## Running the Website Locally + +Now that the prerequisites are installed you can start the website. + +```bash +npm run --prefix website start +``` + +## Starting Development + +The following section covers the basics of how to make changes to the website. +You can find more information on configuring this site in the [official docusaurus documentation][docusaurus]. + +All files for the website can be found in `./website`. + +### Adding/Changing Pages and Categories + +The website is built using [Docusaurus][docusaurus] which allows for documentation/guides pages to be markdown or mdx files. +The markdown files are located in `./website/content/guides` and `./website/content/docs`. + +#### Pages + +You can edit a page just by editing its mdx file. +You can find information on markdown and MDX syntax [on the docusaurus website][docusaurus-markdown-docs]. + +To add a new page you can just add a `.mdx` file into any of the existing folders. +Docusaurus will automatically build the changes and add the file as a entry into the sidebar. + +#### Categories + +You can add categories by adding folders in the `guides` or `docs` folders. +Categories don't have an index by default, so you will need to create one. +Category indexes are the //TODO + +#### Sidebar Structure and Order + +The structure of the guides and docs is basically the same as on the built website. +Folders are categories, mdx files are pages. +Category indexes are the index.mdx files in their respective categories' folders. + +ORder //TODO + +### Markdown Links + +//TODO + +### Best Practices + +//TODO + +avoid click here links + +avoid using inline-html in markdown (excluded Doccard) + +try to avoid too small headings h3 is good h4 is to be avoided and h5 and smaller should not be used + +Dont make too deep Categories. Try to stick to not putting Categories in Categories in Categories. (3 deep is too deep) + +Title case https://en.wikipedia.org/wiki/Capitalization#Title_case + +## Troubleshooting + +Sometimes the website looks broken/not how you expected, has errors or won't start/open. +In these cases you have probably tried loads of things to get it working again. +These are some of the most common fixes for such issues. + +### Clear Docusaurus Cache + +Docusaurus caches a most files and doesn't rebuild them until they themselves change (eg. rendered markdown files, [SVGO][svgo]/[SVGR][svgr] optimized SVGs, etc.). +This can lead to problems when there are custom external dependencies which don't trigger a rebuild. + +This command forces docusaurus to clear its cache and rebuild all files on the next start. + +```bash +npm run --prefix website docusaurus clear +``` + +### (Re-)Install Packages + +There are multiple reasons why reinstalling NPMs packages might fix some issues. +Some of the most common reasons could be: + +- corrupted modules +- outdated packages ([`npm update`][guides-developing-website-update] could also resolve this) +- ... + +```bash +rm -rf ./website/node_modules +npm install --prefix website +``` diff --git a/website/content/guides/1 - developing/2 - Helm Chart.mdx b/website/content/guides/1 - developing/2 - Helm Chart.mdx new file mode 100644 index 0000000..2ff927c --- /dev/null +++ b/website/content/guides/1 - developing/2 - Helm Chart.mdx @@ -0,0 +1,8 @@ +--- +title: Helm Chart +id: helm-chart +--- + +# Helm Chart + +This section covers how to start developing on the helm chart of the downscaler. diff --git a/website/content/guides/1 - developing/3 - Maintaining the Repository.mdx b/website/content/guides/1 - developing/3 - Maintaining the Repository.mdx new file mode 100644 index 0000000..e43462e --- /dev/null +++ b/website/content/guides/1 - developing/3 - Maintaining the Repository.mdx @@ -0,0 +1,31 @@ +--- +title: Maintaining the Repository +id: maintaining-the-repository +--- + +import { GithubLabel } from "/src/components/GithubLabel.tsx"; + +# Maintaining the Repository + +This section covers how to do some maintainer tasks on the repository. + +For documentation on the workflows see [this documentation page][docs-workflows]. + +## Releasing a New Version + +The process to releasing a new version is almost completely automated. +There are multiple workflows that handle the release process. +All you need to do is to bump the [semver][semver] of either +the Helm chart version(`.version`) or the app version(`.appVersion`) +within the [Chart.yaml][chart-yaml](`./deployments/chart/Chart.yaml`). +Once merged into main the [workflows][docs-workflows] will automatically start releasing the new version. + +:::info + +To merge a pull request which would result in a new version once merged into main +there is an additional approval step to stop you from accidentally merging it without realizing. + +To allow the pull request to make a new release after being merged you need to add the label to it. +This will retrigger a workflow run which then automatically removes the label and allows for the pull request to be merged. + +::: diff --git a/website/content/guides/1 - developing/index.mdx b/website/content/guides/1 - developing/index.mdx new file mode 100644 index 0000000..4a919b2 --- /dev/null +++ b/website/content/guides/1 - developing/index.mdx @@ -0,0 +1,99 @@ +--- +title: Developing +id: developing +--- + +import DocCardList from "@theme/DocCardList"; + +# Developing + +Guides on how to start developing on the GoKubeDownscaler. + +Before you contribute to the project we would advise you to read the [Contribution Manifest][contribution-manifest]. + +## Cloning the Repository + +To work on the downscaler effectively you should clone the repository on to your system. +You can find instruction on how to install git [on their website][git-install]. + +```bash +git clone https://github.com/caas-team/GoKubeDownscaler.git +cd GoKubeDownscaler +``` + +## Setting up Pre-Commit + +[Pre-Commit][pre-commit] is a framework for running checks before committing, +this ensures that formatting stays consistent, +stops you from committing to protected branches (locally) +and stops you from committing broken code or new functionality with out updating the tests. + +### Recommended Installation + +The recommended way to install pre-commit and the needed dependencies is via `brew`. +If you don't have brew installed on your system you can find how to install it by following the instructions on [their website][brew]. + +```bash +brew install pre-commit +``` + +The Pre-Commit checks for the Downscaler have some dependencies which need to be installed manually. + +```bash +brew install golangci-lint +brew install gofumpt +``` + +### Alternative Installation + +Alternatively you can install pre-commit and the dependencies manually. +Installation instructions for pre-commit can be found [on their website][pre-commit-install]. +Additionally you will need to install [golangci-lint][golangci-lint-install] +and [gofumpt][gofumpt-install] as dependencies for the pre-commit checks of the downscaler. + +### Enabling Pre-Commit + +Next we will have to enabling pre-commit for the repository. +Make sure you are in the GoKubeDownscaler git repository. + +```bash +pre-commit install +``` + +### Running Pre-Commit manually + +Sometimes it can be useful to run pre-commit without also committing +or just letting it run on all files instead of just the changed ones. + +This command lets you start a pre-commit run on all files manually: + +```bash +pre-commit run --all-files +``` + +#### Skipping Pre-Commit checks temporarily + +Pre-Commit normally shouldn't be ignored, but in some cases you might need to skip some or all pre-commit checks temporarily. +All checks will run in the pre-commit workflow once you push your changes and haven't resolved the issues. + +To disable one or multiple checks: + +```bash +SKIP=prevent-todo-comments,another-check-id-here pre-commit run --all-files +``` + +or + +```bash +SKIP=prevent-todo-comments,another-check-id-here git commit +``` + +If you need to disable all checks you can run this to skip all git hooks: + +```bash +git commit --no-verify +``` + +## Overview + + diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 8e6dae4..7a53367 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -6,7 +6,7 @@ import { svgoConfigPlugin } from "./plugins/svgo-config.cts"; const config: Config = { title: "GoKubeDownscaler", - tagline: "A vertical autoscaler for Kubernetes workloads", + tagline: "A horizontal autoscaler for Kubernetes workloads", favicon: "img/CaaS-Logo.svg", url: "https://caas-team.github.io", @@ -98,7 +98,7 @@ const config: Config = { }, { label: "Guides", - to: "/guides/getting-started", + to: "/guides", }, ], }, @@ -132,7 +132,24 @@ const config: Config = { darkTheme: prismThemes.dracula, }, } satisfies Preset.ThemeConfig, + headTags: [ + { + tagName: "link", + attributes: { + rel: "manifest", + href: "/GoKubeDownscaler/manifest.json", + }, + }, + ], plugins: [svgoConfigPlugin, tailwindPlugin], + markdown: { + preprocessor: ({ fileContent }) => { + // this injects the global md links into every md file + const fs = require("node:fs"); + const links = fs.readFileSync("./content/_global_md_links.mdx"); + return fileContent + "\n" + links; + }, + }, }; export default config; diff --git a/website/package-lock.json b/website/package-lock.json index 90b41df..2c8a957 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -30,34 +30,34 @@ } }, "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.6.tgz", + "integrity": "sha512-lkDoW4I7h2kKlIgf3pUt1LqvxyYKkVyiypoGLlUnhPSnCpmeOwudM6rNq6YYsCmdQtnDQoW5lUNNuj6ASg3qeg==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-plugin-algolia-insights": "1.17.6", + "@algolia/autocomplete-shared": "1.17.6" } }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.6.tgz", + "integrity": "sha512-17NnaacuFzSWVuZu4NKzVeaFIe9Abpw8w+/gjc7xhZFtqj+GadufzodIdchwiB2eM2cDdiR3icW7gbNTB3K2YA==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.6" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz", + "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.6" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -65,9 +65,9 @@ } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz", + "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==", "license": "MIT", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -98,6 +98,21 @@ "@algolia/cache-common": "4.24.0" } }, + "node_modules/@algolia/client-abtesting": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.13.0.tgz", + "integrity": "sha512-6CoQjlMi1pmQYMQO8tXfuGxSPf6iKX5FP9MuMe6IWmvC81wwTvOehnwchyBl2wuPVhcw2Ar53K53mQ60DAC64g==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/client-account": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", @@ -164,11 +179,25 @@ } }, "node_modules/@algolia/client-common": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.10.2.tgz", - "integrity": "sha512-eE4OaTlb5KZdCehWmDARq2KEmMF7DEeFLjKqFDcZNb56k1DMSsa9zCQRXZMovlf2AXLsx0A/1q+SGAEgzF7G3w==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.13.0.tgz", + "integrity": "sha512-2SP6bGGWOTN920MLZv8s7yIR3OqY03vEe4U+vb2MGdL8a/8EQznF3L/nTC/rGf/hvEfZlX2tGFxPJaF2waravg==", "license": "MIT", - "peer": true, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.13.0.tgz", + "integrity": "sha512-ldHTe+LVgC6L4Wr6doAQQ7Ku0jAdhaaPg1T+IHzmmiRZb2Uq5OsjW2yC65JifOmzPCiMkIZE2mGRpWgkn5ktlw==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, "engines": { "node": ">= 14.0.0" } @@ -194,17 +223,31 @@ "@algolia/transporter": "4.24.0" } }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.13.0.tgz", + "integrity": "sha512-pYo0jbLUtPDN1r341UHTaF2fgN5rbaZfDZqjPRKPM+FRlRmxFxqFQm1UUfpkSUWYGn7lECwDpbKYiKUf81MTwA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/client-search": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.10.2.tgz", - "integrity": "sha512-rGX8uil2uvPycFgtS9Fzwvh4tgKvfFWG5RIh3E77W42HrO66bykCf9jHqhIIlCxdDJih1PuUqBYZIkIAAoSkww==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.13.0.tgz", + "integrity": "sha512-s2ge3uZ6Zg2sPSFibqijgEYsuorxcc8KVHg3I95nOPHvFHdnBtSHymhZvq4sp/fu8ijt/Y8jLwkuqm5myn+2Sg==", "license": "MIT", - "peer": true, "dependencies": { - "@algolia/client-common": "5.10.2", - "@algolia/requester-browser-xhr": "5.10.2", - "@algolia/requester-fetch": "5.10.2", - "@algolia/requester-node-http": "5.10.2" + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" }, "engines": { "node": ">= 14.0.0" @@ -216,6 +259,21 @@ "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", "license": "MIT" }, + "node_modules/@algolia/ingestion": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.13.0.tgz", + "integrity": "sha512-fm5LEOe4FPDOc1D+M9stEs8hfcdmbdD+pt9og5shql6ueTZJANDbFoQhDOpiPJizR/ps1GwmjkWfUEywx3sV+Q==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/logger-common": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", @@ -231,6 +289,21 @@ "@algolia/logger-common": "4.24.0" } }, + "node_modules/@algolia/monitoring": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.13.0.tgz", + "integrity": "sha512-e8Hshlnm2G5fapyUgWTBwhJ22yXcnLtPC4LWZKx7KOvv35GcdoHtlUBX94I/sWCJLraUr65JvR8qOo3LXC43dg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/recommend": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", @@ -290,13 +363,12 @@ } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.10.2.tgz", - "integrity": "sha512-gzlfE/H05ggDiEWNi8WaDSRhpE5X8rD1JqYKPPeM31JRI3TutQIKAk3MSUsa1bHM/Di56r2Gm6L1g3ZlZv2ETA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.13.0.tgz", + "integrity": "sha512-NV6oSCt5lFuzfsVQoSBpewEWf/h4ySr7pv2bfwu9yF/jc/g39pig8+YpuqsxlRWBm/lTGVA2V0Ai9ySwrNumIA==", "license": "MIT", - "peer": true, "dependencies": { - "@algolia/client-common": "5.10.2" + "@algolia/client-common": "5.13.0" }, "engines": { "node": ">= 14.0.0" @@ -309,26 +381,24 @@ "license": "MIT" }, "node_modules/@algolia/requester-fetch": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.10.2.tgz", - "integrity": "sha512-Q27ciW9WRdq3pUITVlxpHIwe9QWOe+oPvgs8Z+gsv8vMkwXnLfANvSgeZCyQgx3SqzUPzhel0ozVq7Qoh8xIkg==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.13.0.tgz", + "integrity": "sha512-094bK4rumf+rXJazxv3mq6eKRM0ep5AxIo8T0YmOdldswQt79apeufFiPLN19nHEWH22xR2FelimD+T/wRSP+Q==", "license": "MIT", - "peer": true, "dependencies": { - "@algolia/client-common": "5.10.2" + "@algolia/client-common": "5.13.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.10.2.tgz", - "integrity": "sha512-WMUQ4iFhNnQXC4F1Yj51x8tgIvq5h8jtTLMBs7LbMiW6JhnLHfBVl7IVk6X1fZJO5YcvXW051HN8aFlfAb5QEw==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.13.0.tgz", + "integrity": "sha512-JY5xhEYMgki53Wm+A6R2jUpOUdD0zZnBq+PC5R1TGMNOYL1s6JjDrJeMsvaI2YWxYMUSoCnRoltN/yf9RI8n3A==", "license": "MIT", - "peer": true, "dependencies": { - "@algolia/client-common": "5.10.2" + "@algolia/client-common": "5.13.0" }, "engines": { "node": ">= 14.0.0" @@ -372,12 +442,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.9.tgz", - "integrity": "sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -385,30 +456,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.9.tgz", - "integrity": "sha512-yD+hEuJ/+wAJ4Ox2/rpNv5HIuPG82x3ZlQvYVn8iYCprdxzE7P1udpGF1jyjQVBU4dgznN+k2h103vxZ7NdPyw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.9.tgz", - "integrity": "sha512-WYvQviPw+Qyib0v92AwNIrdLISTp7RfDkM7bPqBvpbnhY4wq8HvHBZREVdYDXk98C8BkOIVnHAY3yvj7AVISxQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helpers": "^7.25.9", - "@babel/parser": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -433,12 +504,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.9.tgz", - "integrity": "sha512-omlUGkr5EaoIJrhLf9CJ0TvjBRpd9+AXRG//0GEQ9THSo8wPiTlbpy1/Ow8ZTrbXpjd9FHXfbFQx32I04ht0FA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "license": "MIT", "dependencies": { - "@babel/types": "^7.25.9", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -596,13 +668,12 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.9.tgz", - "integrity": "sha512-TvLZY/F3+GvdRYFZFyxMvnsKi+4oJdgZzU3BoGN9Uc2d9C6zfNwJcKKhjqLAhK8i46mv93jsO74fDh3ih6rpHA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-simple-access": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9", "@babel/traverse": "^7.25.9" }, @@ -736,111 +807,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.9.tgz", - "integrity": "sha512-oKWp3+usOJSzDZOucZUAMayhPz/xVjzymyDzUN8dk0Wd3RWMlGLXi07UCQ/CgQVb8LvXx3XBajJH4XGgkt7H7g==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "license": "MIT", "dependencies": { "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", - "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.9.tgz", - "integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.25.9" + "@babel/types": "^7.26.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -953,9 +938,9 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.9.tgz", - "integrity": "sha512-4GHX5uzr5QMOOuzV0an9MFju4hKlm0OyePl/lHhcsTVae5t/IKVHnb8W67Vr6FuLlk5lPqLB7n7O+K5R46emYg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -968,9 +953,9 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.9.tgz", - "integrity": "sha512-u3EN9ub8LyYvgTnrgp8gboElouayiwPdnM7x5tcnW3iSt09/lQYPwMNK40I9IUxo7QOZhAsPHCmmuO7EPdruqg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1124,9 +1109,9 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.9.tgz", - "integrity": "sha512-UIf+72C7YJ+PJ685/PpATbCz00XqiFEzHX5iysRwfvNT0Ko+FaXSvRgLytFSp8xUItrG9pFM/KoBBZDrY/cYyg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", @@ -1727,6 +1712,22 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", @@ -1930,12 +1931,12 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.9.tgz", - "integrity": "sha512-XqDEt+hfsQukahSX9JOBDHhpUHDhj2zGSxoqWQFCMajOSBnbhBdgON/bU/5PkBA1yX5tqW6tTzuIPVsZTQ7h5Q==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.9", + "@babel/compat-data": "^7.26.0", "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", @@ -1945,8 +1946,8 @@ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.25.9", - "@babel/plugin-syntax-import-attributes": "^7.25.9", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", "@babel/plugin-transform-async-generator-functions": "^7.25.9", @@ -1954,7 +1955,7 @@ "@babel/plugin-transform-block-scoped-functions": "^7.25.9", "@babel/plugin-transform-block-scoping": "^7.25.9", "@babel/plugin-transform-class-properties": "^7.25.9", - "@babel/plugin-transform-class-static-block": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", "@babel/plugin-transform-classes": "^7.25.9", "@babel/plugin-transform-computed-properties": "^7.25.9", "@babel/plugin-transform-destructuring": "^7.25.9", @@ -1987,6 +1988,7 @@ "@babel/plugin-transform-private-property-in-object": "^7.25.9", "@babel/plugin-transform-property-literals": "^7.25.9", "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", "@babel/plugin-transform-reserved-words": "^7.25.9", "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", @@ -2055,9 +2057,9 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.25.9.tgz", - "integrity": "sha512-XWxw1AcKk36kgxf4C//fl0ikjLeqGUWn062/Fd8GtpTfDJOX6Ud95FK+4JlDA36BX4bNGndXi3a6Vr4Jo5/61A==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", @@ -2074,9 +2076,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2086,9 +2088,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.9.tgz", - "integrity": "sha512-eHeq2HWhgn3aH6Gz4Dnajqp8U5DjBg3h933LlGJ52hAN6Kx34KAL7O3NzwTrldl9PrgKTyBcz0ScVIQ3A6e2fA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", "license": "MIT", "dependencies": { "core-js-pure": "^3.30.2", @@ -2131,9 +2133,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.9.tgz", - "integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -2163,21 +2165,21 @@ } }, "node_modules/@docsearch/css": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.2.tgz", - "integrity": "sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.7.0.tgz", + "integrity": "sha512-1OorbTwi1eeDmr0v5t+ckSRlt1zM5GHjm92iIl3kUu7im3GHuP+csf6E0WBg8pdXQczTWP9J9+o9n+Vg6DH5cQ==", "license": "MIT" }, "node_modules/@docsearch/react": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.2.tgz", - "integrity": "sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.7.0.tgz", + "integrity": "sha512-8e6tdDfkYoxafEEPuX5eE1h9cTkLvhe4KgoFkO5JCddXSQONnN1FHcDZRI4r8894eMpbYq6rdJF0dVYh8ikwNQ==", "license": "MIT", "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.6.2", - "algoliasearch": "^4.19.1" + "@algolia/autocomplete-core": "1.17.6", + "@algolia/autocomplete-preset-algolia": "1.17.6", + "@docsearch/css": "3.7.0", + "algoliasearch": "^5.12.0" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", @@ -2200,6 +2202,75 @@ } } }, + "node_modules/@docsearch/react/node_modules/@algolia/client-analytics": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.13.0.tgz", + "integrity": "sha512-pS3qyXiWTwKnrt/jE79fqkNqZp7kjsFNlJDcBGkSWid74DNc6DmArlkvPqyLxnoaYGjUGACT6g56n7E3mVV2TA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/client-personalization": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.13.0.tgz", + "integrity": "sha512-RnCfOSN4OUJDuMNHFca2M8lY64Tmw0kQOZikge4TknTqHmlbKJb8IbJE7Rol79Z80W2Y+B1ydcjV7DPje4GMRA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/recommend": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.13.0.tgz", + "integrity": "sha512-53/wW96oaj1FKMzGdFcZ/epygfTppLDUvgI1thLkd475EtVZCH3ZZVUNCEvf1AtnNyH1RnItkFzX8ayWCpx2PQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/algoliasearch": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.13.0.tgz", + "integrity": "sha512-04lyQX3Ev/oLYQx+aagamQDXvkUUfX1mwrLrus15+9fNaYj28GDxxEzbwaRfvmHFcZyoxvup7mMtDTTw8SrTEQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-abtesting": "5.13.0", + "@algolia/client-analytics": "5.13.0", + "@algolia/client-common": "5.13.0", + "@algolia/client-insights": "5.13.0", + "@algolia/client-personalization": "5.13.0", + "@algolia/client-query-suggestions": "5.13.0", + "@algolia/client-search": "5.13.0", + "@algolia/ingestion": "1.13.0", + "@algolia/monitoring": "1.13.0", + "@algolia/recommend": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@docusaurus/core": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", @@ -3496,6 +3567,26 @@ "@types/ms": "*" } }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -3524,9 +3615,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.0.tgz", - "integrity": "sha512-AbXMTZGt40T+KON9/Fdxx0B2WK5hsgxcfXJLr5bFpZ7b4JCex2WyQPTEKdXqfHiY5nKKBScZ7yCoO6Pvgxfvnw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz", + "integrity": "sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -3653,12 +3744,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.7.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.9.tgz", - "integrity": "sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.19.8" } }, "node_modules/@types/node-forge": { @@ -3689,9 +3780,9 @@ "license": "MIT" }, "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", "license": "MIT" }, "node_modules/@types/range-parser": { @@ -3803,9 +3894,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -3833,148 +3924,148 @@ "license": "ISC" }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -4024,10 +4115,19 @@ "node": ">= 0.6" } }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4036,15 +4136,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -4746,9 +4837,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001669", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", - "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", + "version": "1.0.30001679", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001679.tgz", + "integrity": "sha512-j2YqID/YwpLnKzCmBOS4tlZdWprXm3ZmQLBH9ZBXFOhoxLA46fwyBvx6toCBWBmnuwUY/qB3kEU6gFx8qgCroA==", "funding": [ { "type": "opencollective", @@ -5122,23 +5213,32 @@ } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "license": "MIT", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", + "negotiator": "~0.6.4", "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/compression/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5154,12 +5254,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5329,9 +5423,9 @@ } }, "node_modules/core-js": { - "version": "3.38.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz", - "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -5340,12 +5434,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.38.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", - "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", "license": "MIT", "dependencies": { - "browserslist": "^4.23.3" + "browserslist": "^4.24.2" }, "funding": { "type": "opencollective", @@ -5353,9 +5447,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.38.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz", - "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.39.0.tgz", + "integrity": "sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -5396,9 +5490,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -6134,9 +6228,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.45", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.45.tgz", - "integrity": "sha512-vOzZS6uZwhhbkZbcRyiy99Wg+pYFV5hk+5YaECvx0+Z31NR3Tt5zS6dze2OepT6PCTzVzT0dIJItti+uAW5zmw==", + "version": "1.5.55", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.55.tgz", + "integrity": "sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -6436,9 +6530,9 @@ } }, "node_modules/estree-util-value-to-estree": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", - "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.2.1.tgz", + "integrity": "sha512-Vt2UOjyPbNQQgT5eJh+K5aATti0OjCIAGc9SgMdOFYbohuifsWclR74l0iZTJwePMgWYdX1hlVS+dedH9XV8kw==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" @@ -8958,9 +9052,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -9277,9 +9371,9 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -9287,6 +9381,7 @@ "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" @@ -11223,9 +11318,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz", - "integrity": "sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -11338,9 +11433,9 @@ } }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -11761,9 +11856,9 @@ "license": "ISC" }, "node_modules/parse5": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz", - "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "license": "MIT", "dependencies": { "entities": "^4.5.0" @@ -13465,9 +13560,9 @@ "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.1.tgz", - "integrity": "sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", + "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.0.2" @@ -15165,9 +15260,9 @@ "license": "Apache-2.0" }, "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/type-fest": { @@ -15765,18 +15860,18 @@ } }, "node_modules/webpack": { - "version": "5.95.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", - "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", "license": "MIT", "dependencies": { - "@types/estree": "^1.0.5", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", diff --git a/website/plugins/tailwind-config.cts b/website/plugins/tailwind-config.cts index 9103606..ec1ead6 100644 --- a/website/plugins/tailwind-config.cts +++ b/website/plugins/tailwind-config.cts @@ -1,4 +1,9 @@ -export function tailwindPlugin(context, options) { +import { LoadContext, Plugin, PluginOptions } from "@docusaurus/types"; + +export function tailwindPlugin( + context: LoadContext, + options: PluginOptions +): Plugin { return { name: "tailwind-plugin", configurePostCss(postcssOptions) { diff --git a/website/sidebars.ts b/website/sidebars.ts index 26162ac..1cdf5b9 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -9,18 +9,8 @@ const sidebars: SidebarsConfig = { ], GuidesSidebar: [ { - type: "category", - label: "Getting Started", - link: { - type: "doc", - id: "guides/getting-started", - }, - items: [ - { - type: "autogenerated", - dirName: "guides/getting-started", - }, - ], + type: "autogenerated", + dirName: "guides", }, ], }; diff --git a/website/src/api/github.ts b/website/src/api/github.ts new file mode 100644 index 0000000..dfd74fe --- /dev/null +++ b/website/src/api/github.ts @@ -0,0 +1,32 @@ +import { adjustToLightHsl, hexToRGB, rgbToHSL } from "../util/color"; + +export const FetchGithubLabels = async ({ + org, + repo, +}: FetchGithubLabelArgs): Promise => { + try { + const response = await fetch( + `https://api.github.com/repos/${org}/${repo}/labels` + ); + if (!response.ok) { + throw new Error(`got unexpected status '${response.status}' from github`); + } + const data = (await response.json()) as GithubLabel[]; + return data.map((label) => { + const rgb = hexToRGB(label.color); + const hsl = rgbToHSL(rgb); + const lightHsl = adjustToLightHsl(hsl, rgb); + + return { + name: label.name, + description: label.description, + rgb: rgb, + hsl: hsl, + lightHsl: lightHsl, + url: `https://github.com/${org}/${repo}/labels/${label.name}`, + }; + }); + } catch (error) { + throw new Error(`Failed to fetch labels from github: ${error.message}`); + } +}; diff --git a/website/src/components/CaasAvatar.tsx b/website/src/components/CaasAvatar.tsx index f026ba2..3355bb5 100644 --- a/website/src/components/CaasAvatar.tsx +++ b/website/src/components/CaasAvatar.tsx @@ -8,11 +8,15 @@ export default function CaasAvatar(): JSX.Element { return (
- +
- +
{name}
{description} diff --git a/website/src/components/FirstDocRedirect.tsx b/website/src/components/FirstDocRedirect.tsx new file mode 100644 index 0000000..49613df --- /dev/null +++ b/website/src/components/FirstDocRedirect.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { Redirect } from "@docusaurus/router"; +import { + useActivePlugin, + useAllDocsData, +} from "@docusaurus/plugin-content-docs/client"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; + +interface RedirectToFirstDocProps { + sidebar: string; +} + +export const RedirectToFirstDoc: React.FC = ({ + sidebar, +}) => { + const activePlugin = useActivePlugin(); + const allDocsData = useAllDocsData(); + const { siteConfig } = useDocusaurusContext(); + + if (!activePlugin || !allDocsData) { + return null; // wait + } + + const pluginId = activePlugin.pluginId; + const version = allDocsData[pluginId]?.versions[0]; + + if (!version) { + console.error("No version data available"); + return ; + } + + const sidebarItem = version.sidebars[sidebar]; + + if (!sidebarItem) { + console.error(`Sidebar "${sidebar}" does not exist`); + return ; + } + + if (sidebarItem.link?.path) { + return ; + } + + console.error(`Sidebar "${sidebar}" does not contain a valid link`); + return ; +}; diff --git a/website/src/components/GithubLabel.tsx b/website/src/components/GithubLabel.tsx new file mode 100644 index 0000000..fb9f961 --- /dev/null +++ b/website/src/components/GithubLabel.tsx @@ -0,0 +1,34 @@ +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import React, { useEffect, useState } from "react"; +import { hexToRGB, rgbToHSL } from "../util/color"; +import { useGithub } from "./hook/githubHook"; + +export const GithubLabel: React.FC = ({ + label: labelName, +}) => { + const { labels } = useGithub(); + const [label, setLabel] = useState(undefined); + + useEffect(() => { + if (!labels) return; + setLabel(labels.find((l) => l.name === labelName)); + }, [labels]); + + return label ? ( + + {labelName} + + ) : ( + {labelName} + ); +}; diff --git a/website/src/components/Homepage/SupportedResources.tsx b/website/src/components/Homepage/SupportedResources.tsx index 5dafdca..4e43587 100644 --- a/website/src/components/Homepage/SupportedResources.tsx +++ b/website/src/components/Homepage/SupportedResources.tsx @@ -1,13 +1,5 @@ -import clsx from "clsx"; import Heading from "@theme/Heading"; -type SupportedResourceGroupProps = { - title: string; - Svg: React.ComponentType>; - href: string; - supportedResources: string[]; -}; - const SupportedResourceGroupList: SupportedResourceGroupProps[] = [ { title: "Prometheus", @@ -58,7 +50,7 @@ function SupportedResourceGroup({ return (
diff --git a/website/src/components/context/githubContext.tsx b/website/src/components/context/githubContext.tsx new file mode 100644 index 0000000..a4fdd7d --- /dev/null +++ b/website/src/components/context/githubContext.tsx @@ -0,0 +1,33 @@ +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import { FetchGithubLabels } from "@site/src/api/github"; +import React, { createContext, useEffect, useState } from "react"; + +export const GithubContext = createContext(undefined); + +export const GithubProvider: React.FC = ({ children }) => { + const {siteConfig: { organizationName, projectName }} = useDocusaurusContext(); // prettier-ignore + const [labelData, setLabelData] = useState(undefined); + + useEffect(() => { + // get static assets from github on build + const fetchLabels = async () => { + try { + const labels = await FetchGithubLabels({ + org: organizationName, + repo: projectName, + }); + setLabelData(labels); + } catch (error) { + console.error(`Failed to fetch labels: ${error.message}`); + } + }; + + fetchLabels(); + }, [organizationName, projectName]); + + return ( + + {children} + + ); +}; diff --git a/website/src/components/hook/githubHook.ts b/website/src/components/hook/githubHook.ts new file mode 100644 index 0000000..e822bad --- /dev/null +++ b/website/src/components/hook/githubHook.ts @@ -0,0 +1,10 @@ +import { useContext } from "react"; +import { GithubContext } from "../context/githubContext"; + +export const useGithub = () => { + const context = useContext(GithubContext); + if (context === undefined) { + throw new Error("useGithub must be used within a GithubProvider"); + } + return context; +}; diff --git a/website/src/pages/docs.mdx b/website/src/pages/docs.mdx new file mode 100644 index 0000000..a9972d6 --- /dev/null +++ b/website/src/pages/docs.mdx @@ -0,0 +1,5 @@ +{/* this doc acts as a redirect from /docs to the first actual doc in the sidebar */} + +import { RedirectToFirstDoc } from "/src/components/FirstDocRedirect.tsx"; + + diff --git a/website/src/pages/guides.mdx b/website/src/pages/guides.mdx new file mode 100644 index 0000000..89fdac3 --- /dev/null +++ b/website/src/pages/guides.mdx @@ -0,0 +1,5 @@ +{/* this doc acts as a redirect from /guides to the first actual doc in the sidebar */} + +import { RedirectToFirstDoc } from "/src/components/FirstDocRedirect.tsx"; + + diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 4a5233e..54562f2 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -15,7 +15,7 @@ function HomepageHeader() {

{siteConfig.tagline}

diff --git a/website/src/theme/Root.tsx b/website/src/theme/Root.tsx new file mode 100644 index 0000000..dde8f0e --- /dev/null +++ b/website/src/theme/Root.tsx @@ -0,0 +1,8 @@ +import React from "react"; +import { GithubProvider } from "../components/context/githubContext"; + +const Root: React.FC<{ children: React.ReactNode }> = ({ children }) => { + return {children}; +}; + +export default Root; diff --git a/website/src/types/api/github.ts b/website/src/types/api/github.ts new file mode 100644 index 0000000..5ddc9e9 --- /dev/null +++ b/website/src/types/api/github.ts @@ -0,0 +1,19 @@ +interface GithubLabel { + name: string; + description: string; + color: string; +} + +interface CachedGithubLabel { + name: string; + description: string; + rgb: RgbColor; + hsl: HslColor; + lightHsl: HslColor; + url: string; +} + +interface FetchGithubLabelArgs { + org: string; + repo: string; +} diff --git a/website/src/types/components/GithubLabel.d.ts b/website/src/types/components/GithubLabel.d.ts new file mode 100644 index 0000000..4039ffd --- /dev/null +++ b/website/src/types/components/GithubLabel.d.ts @@ -0,0 +1,3 @@ +interface GithubLabelProps { + label: string; +} diff --git a/website/src/types/components/HomepageFeatures.d.ts b/website/src/types/components/HomepageFeatures.d.ts new file mode 100644 index 0000000..0208e15 --- /dev/null +++ b/website/src/types/components/HomepageFeatures.d.ts @@ -0,0 +1,6 @@ +interface SupportedResourceGroupProps { + title: string; + Svg: React.ComponentType>; + href: string; + supportedResources: string[]; +} diff --git a/website/src/types/components/RedirectToFirstDoc.d.ts b/website/src/types/components/RedirectToFirstDoc.d.ts new file mode 100644 index 0000000..26e348f --- /dev/null +++ b/website/src/types/components/RedirectToFirstDoc.d.ts @@ -0,0 +1,3 @@ +interface RedirectToFirstDocProps { + sidebar: string; +} diff --git a/website/src/types/components/context.d.ts b/website/src/types/components/context.d.ts new file mode 100644 index 0000000..076e467 --- /dev/null +++ b/website/src/types/components/context.d.ts @@ -0,0 +1,8 @@ +interface IContextProps { + children: React.ReactNode; +} + +interface IGithubContext { + /** labels is a static list of available labels on the repository */ + labels: CachedGithubLabel[]; +} diff --git a/website/src/types/util/color.d.ts b/website/src/types/util/color.d.ts new file mode 100644 index 0000000..61a9060 --- /dev/null +++ b/website/src/types/util/color.d.ts @@ -0,0 +1,11 @@ +interface RgbColor { + r: number; + g: number; + b: number; +} + +interface HslColor { + h: number; + s: number; + l: number; +} diff --git a/website/src/util/color.ts b/website/src/util/color.ts new file mode 100644 index 0000000..c3473b0 --- /dev/null +++ b/website/src/util/color.ts @@ -0,0 +1,46 @@ +export function rgbToHSL(rgb: RgbColor): HslColor { + rgb = { r: rgb.r / 255, g: rgb.g / 255, b: rgb.b / 255 }; + + const max = Math.max(rgb.r, rgb.g, rgb.b); + const min = Math.min(rgb.r, rgb.g, rgb.b); + const l = (max + min) / 2; + + let s = 0; + if (max !== min) { + s = l > 0.5 ? (max - min) / (2 - max - min) : (max - min) / (max + min); + } + + let h = 0; + if (max === rgb.r) { + h = (rgb.g - rgb.b) / (max - min); + } else if (max === rgb.g) { + h = 2 + (rgb.b - rgb.r) / (max - min); + } else if (max === rgb.b) { + h = 4 + (rgb.r - rgb.g) / (max - min); + } + h = Math.round(h * 60); + + if (h < 0) h += 360; + + s = Math.round(s * 100); + const lightness = Math.round(l * 100); + + return { h, s, l: lightness }; +} + +export function hexToRGB(hex: string): RgbColor { + hex = hex.replace(/^#/, ""); + + const r = parseInt(hex.slice(0, 2), 16); + const g = parseInt(hex.slice(2, 4), 16); + const b = parseInt(hex.slice(4, 6), 16); + return { r, g, b }; +} + +export function adjustToLightHsl(hsl: HslColor, rgb: RgbColor): HslColor { + const lightnessThreshold = 60 / 100; + const percievedLightness = (rgb.r * 0.2126 + rgb.g * 0.7152 + rgb.b * 0.0722) / 255; // prettier-ignore + const lightnessSwitch = Math.max(0, Math.min((1/(lightnessThreshold - percievedLightness)), 1)); // prettier-ignore + const lightenBy = (lightnessThreshold - percievedLightness) * 100 * lightnessSwitch; // prettier-ignore + return { h: hsl.h, s: hsl.s, l: hsl.l + lightenBy }; +} diff --git a/website/static/manifest.json b/website/static/manifest.json new file mode 100644 index 0000000..5150e75 --- /dev/null +++ b/website/static/manifest.json @@ -0,0 +1,56 @@ +{ + "short_name": "GoKubeDownscaler", + "name": "GoKubeDownscaler", + "icons": [ + { + "src": "/GoKubeDownscaler/img/CaaS-Logo.svg", + "type": "image/svg+xml", + "sizes": "any" + } + ], + "id": "/GoKubeDownscaler", + "start_url": "/GoKubeDownscaler", + "background_color": "#FFFFFF", + "display": "standalone", + "scope": "/GoKubeDownscaler", + "theme_color": "#FFFFFF", + "shortcuts": [ + { + "name": "Documentation", + "short_name": "Documentation", + "description": "Documentation on the GoKubeDownscaler", + "url": "/GoKubeDownscaler/docs", + "icons": [ + { + "src": "/GoKubeDownscaler/img/CaaS-Logo.svg", + "sizes": "any" + } + ] + }, + { + "name": "Guides", + "short_name": "Guides", + "description": "Guides for the GoKubeDownscaler", + "url": "/GoKubeDownscaler/guides", + "icons": [ + { + "src": "/GoKubeDownscaler/img/CaaS-Logo.svg", + "sizes": "any" + } + ] + }, + { + "name": "About", + "short_name": "About", + "description": "Information about the GoKubeDownscaler", + "url": "/GoKubeDownscaler/about", + "icons": [ + { + "src": "/GoKubeDownscaler/img/CaaS-Logo.svg", + "sizes": "any" + } + ] + } + ], + "description": "A horizontal autoscaler for Kubernetes workloads" +}