From 7f14edd0395bbd439568e68a1a54ee2d9c57d700 Mon Sep 17 00:00:00 2001 From: yage Date: Fri, 10 May 2024 13:32:02 -0600 Subject: [PATCH] v5.0.0 ===================================================================== Excited to bring V5 to life. This includes some BREAKING CHANGES to several aspects of ZSH-type scwrypts. Please refer to the readme for upgrade details (specifically docs/upgrade/v4-to-v5.md) --- New Features ------------------------- - ZSH testing library with basic mock capabilities - new scwrypts environment file format includes metadata and more advanced features like optional parent env overrides, selection inheritence, and improved structurual flexibility - speedup cache for non-CI runs of ZSH-type scwrypts - ${scwryptsmodule} syntax now allows a consistent unique-naming scheme for functions in ZSH-type scwrypts while providing better insight into origin of API calls in other modules - reusable, case-statement-driven argument parsers in ZSH-type scwrypts --- Changes ------------------------------ - several utility function renames in ZSH-type scwrypts to improve consistency - documentation comments included in ZSH libraries - ZSH-type scwrypts now allow library modules to live alongside executables (zsh/lib still supported; autodetection determines default) --- Bug Fixes ---------------------------- - hardened environment checking for REQUIRED_ENV variables; this removes the ability to overwrite variables in local function contexts --- .circleci/config.yml | 53 +- .config/create-new-env | 89 + .config/env.yaml | 66 + README.md | 85 +- docs/humans.txt | 4 +- docs/upgrade/v3-to-v4.md | 18 +- docs/upgrade/v4-to-v5.md | 136 + plugins/ci/.config/env.yaml | 1 + plugins/ci/README.md | 11 +- plugins/ci/check-all-dependencies | 12 +- plugins/ci/ci.scwrypts.zsh | 6 +- .../{kubectl => kube}/.config/env.template | 0 .../.config/env.template.descriptions | 0 plugins/kube/.config/env.yaml | 5 + .../.config/static/redis.zsh | 0 plugins/{kubectl => kube}/README.md | 0 .../driver/kubectl.completion.zsh | 11 +- .../driver/kubectl.driver.zsh | 44 +- plugins/{kubectl => kube}/driver/meta.zsh | 86 +- plugins/{kubectl => kube}/get-context | 6 +- plugins/{kubectl => kube}/get-namespace | 6 +- plugins/kube/kube.scwrypts.zsh | 10 + plugins/kube/kubectl/cli.module.zsh | 18 + plugins/kube/kubectl/context.module.zsh | 56 + plugins/kube/kubectl/kubectl.module.zsh | 17 + plugins/kube/kubectl/namespace.module.zsh | 23 + plugins/kube/kubectl/service.module.zsh | 77 + plugins/kube/meta/get-static-redis-definition | 7 + .../lib => kube/redis}/redis.module.zsh | 37 +- plugins/{kubectl => kube}/serve | 14 +- plugins/{kubectl => kube}/set-context | 18 +- plugins/{kubectl => kube}/set-namespace | 18 +- plugins/kubectl/kubectl.scwrypts.zsh | 11 - plugins/kubectl/lib/kubectl.module.zsh | 158 - .../kubectl/meta/get-static-redis-definition | 7 - py/lib/scwrypts/env.py | 23 +- py/lib/scwrypts/http/discord/test_client.py | 6 +- py/lib/scwrypts/test/generate.py | 4 +- scwrypts | 401 +- scwrypts.plugin.zsh | 2 +- scwrypts.scwrypts.zsh | 182 +- zsh/README.md | 112 +- zsh/cloud/aws/aws.module.zsh | 13 + zsh/cloud/aws/aws.test.zsh | 28 + zsh/cloud/aws/cli.module.zsh | 36 + zsh/cloud/aws/cli.test.zsh | 65 + zsh/cloud/aws/ecr/ecr.module.zsh | 6 + zsh/cloud/aws/ecr/ecr.test.zsh | 16 + zsh/cloud/aws/ecr/login | 20 +- zsh/cloud/aws/ecr/login.module.zsh | 30 + zsh/cloud/aws/ecr/login.test.zsh | 47 + zsh/cloud/aws/efs/mount | 100 +- zsh/cloud/aws/efs/unmount | 51 +- zsh/cloud/aws/eks/cli.module.zsh | 86 + zsh/cloud/aws/eks/cli.test.zsh | 105 + zsh/cloud/aws/eks/cluster-login.module.zsh | 43 + zsh/cloud/aws/eks/cluster-login.test.zsh | 66 + zsh/cloud/aws/eks/eks.module.zsh | 10 + zsh/cloud/aws/eks/eks.test.zsh | 24 + zsh/cloud/aws/eks/login | 2 +- .../aws/eks/zshparse/cluster-name.module.zsh | 44 + .../aws/eks/zshparse/zshparse.module.zsh | 6 + zsh/cloud/aws/eksctl/cli.module.zsh | 40 + zsh/cloud/aws/eksctl/cli.test.zsh | 72 + zsh/cloud/aws/eksctl/eksctl.module.zsh | 10 + zsh/cloud/aws/eksctl/eksctl.test.zsh | 20 + .../iamserviceaccount/check-exists.module.zsh | 57 + .../iamserviceaccount/check-exists.test.zsh | 63 + .../iamserviceaccount/create.module.zsh | 93 + .../eksctl/iamserviceaccount/create.test.zsh | 150 + .../iamserviceaccount.module.zsh | 9 + .../iamserviceaccount.test.zsh | 20 + .../iamserviceaccount/zshparse.module.zsh | 35 + zsh/cloud/aws/rds/create-backup | 2 +- zsh/cloud/aws/rds/interactive-login | 2 +- zsh/cloud/aws/rds/load-backup | 2 +- .../aws => cloud/aws/rds}/rds.module.zsh | 52 +- zsh/cloud/aws/route53/backup | 33 +- zsh/cloud/aws/zshparse/overrides.module.zsh | 79 + zsh/cloud/aws/zshparse/zshparse.module.zsh | 6 + zsh/cloud/media-sync/pull | 7 - zsh/cloud/media-sync/push | 7 - zsh/config.global.zsh | 9 + zsh/config.user.zsh | Bin 0 -> 989 bytes zsh/config.zsh | 183 + zsh/db/postgres/interactive-pgcli | 2 +- zsh/db/postgres/pg_dump | 2 +- zsh/db/postgres/pg_restore | 2 +- .../db => db/postgres}/postgres.module.zsh | 60 +- zsh/db/postgres/run-sql | 28 +- zsh/docker/cleanup | 30 +- zsh/hello-world | 4 +- zsh/helm/get-template | 18 +- zsh/helm/get-template.module.zsh | 135 + zsh/helm/helm.module.zsh | 15 + zsh/helm/update-dependencies | 18 +- zsh/helm/update-dependencies.module.zsh | 31 + zsh/helm/validate.module.zsh | 119 + zsh/helm/zshparse.module.zsh | 54 + zsh/import.driver.zsh | 340 ++ zsh/lib/cloud/aws/cli.module.zsh | 23 - zsh/lib/cloud/aws/ecr.module.zsh | 27 - zsh/lib/cloud/aws/eks.module.zsh | 90 - zsh/lib/cloud/aws/eksctl.module.zsh | 116 - zsh/lib/cloud/media-sync.module.zsh | 69 - zsh/lib/config.user.zsh | Bin 502 -> 0 bytes zsh/lib/config.zsh | 95 - zsh/lib/helm/dependency.module.zsh | 42 - zsh/lib/helm/helm.module.zsh | 9 - zsh/lib/helm/template.module.zsh | 111 - zsh/lib/helm/validate.module.zsh | 95 - zsh/lib/import.driver.zsh | 156 - zsh/lib/media/youtube.module.zsh | 48 - zsh/lib/misc/k8s-helper.plugin.zsh | 26 - zsh/lib/misc/tally.module.zsh | 106 - zsh/lib/office/latex.module.zsh | 44 - zsh/lib/office/memo.module.zsh | 15 - zsh/lib/redis/redis.module.zsh | 43 - zsh/lib/scwrypts/environment-files.module.zsh | 126 - zsh/lib/scwrypts/meta.module.zsh | 23 - zsh/lib/scwrypts/run.module.zsh | 195 - zsh/lib/scwrypts/scwrypts.module.zsh | 15 - zsh/lib/scwrypts/virtualenv.module.zsh | 173 - zsh/lib/system/config/config.module.zsh | 18 - zsh/lib/system/config/default.conf.zsh | 19 - zsh/lib/system/desktop/notify.module.zsh | 16 - zsh/lib/system/packages/git.module.zsh | 78 - zsh/lib/system/vim/vim.module.zsh | 11 - zsh/lib/system/vim/vundle.module.zsh | 53 - zsh/lib/utils/colors.zsh | 44 - zsh/lib/utils/credits.zsh | 11 - zsh/lib/utils/dependencies.zsh | 52 - zsh/lib/utils/environment.zsh | 39 - zsh/lib/utils/io.fzf.zsh | 45 - zsh/lib/utils/io.print.zsh | 65 - zsh/lib/utils/io.usage.zsh | 65 - zsh/lib/utils/io.zsh | 249 - zsh/lib/utils/os.zsh | 12 - zsh/lib/utils/utils.module.zsh | 89 - zsh/media/youtube/README.md | 5 - zsh/media/youtube/download | 20 - zsh/media/youtube/get-audio-clip | 46 - zsh/misc/tally | 8 - zsh/notify/desktop.module.zsh | 15 + zsh/notify/notify.module.zsh | 37 + zsh/office/latex/build-pdf | 23 - zsh/office/latex/cleanup | 15 - zsh/office/latex/create-new | 59 - zsh/office/latex/get-pdf | 7 - zsh/office/latex/open-pdf | 10 - zsh/office/latex/templates/basic/template.tex | 37 - zsh/office/latex/templates/main.tex | 9 - zsh/office/latex/templates/math/code.sty | 11 - .../latex/templates/math/formatting.sty | 46 - zsh/office/latex/templates/math/imports.sty | 16 - zsh/office/latex/templates/math/shorthand.sty | 13 - zsh/office/latex/templates/math/template.tex | 12 - .../times-new-roman-12/custom-headers.sty | 7 - .../times-new-roman-12/formatting.sty | 31 - .../templates/times-new-roman-12/imports.sty | 11 - .../templates/times-new-roman-12/template.tex | 15 - zsh/office/memo/open | 23 - zsh/office/memo/remove | 25 - zsh/redis/cli.module.zsh | 51 + zsh/redis/curl | 52 +- zsh/redis/curl.module.zsh | 89 + zsh/redis/enabled.module.zsh | 9 + zsh/redis/redis.module.zsh | 15 + zsh/sanity-check | 59 +- zsh/scwrypts/README.md | 68 - zsh/scwrypts/cache-output.module.zsh | 143 + zsh/scwrypts/configure | 36 +- zsh/scwrypts/environment/common.module.zsh | 63 + zsh/scwrypts/environment/copy | 35 - zsh/scwrypts/environment/delete | 33 - zsh/scwrypts/environment/edit | 42 - .../environment/environment.module.zsh | 32 + .../get-envvar-lookup-map.module.zsh | 35 + .../environment/get-full-template.module.zsh | 48 + zsh/scwrypts/environment/getenv | 69 + zsh/scwrypts/environment/init.module.zsh | 142 + .../environment/select-env.module.zsh | 18 + zsh/scwrypts/environment/synchronize | 174 - zsh/scwrypts/environment/update | 150 + zsh/scwrypts/environment/update.module.zsh | 257 + zsh/scwrypts/environment/user.module.zsh | 276 + zsh/scwrypts/get-realpath.module.zsh | 17 + zsh/scwrypts/get-runstring.module.zsh | 145 + zsh/scwrypts/list-available.module.zsh | 57 + zsh/scwrypts/logs/clear | 31 +- zsh/scwrypts/logs/view | 15 +- zsh/scwrypts/meta.module.zsh | 15 + zsh/scwrypts/rebuild-cache | 89 + .../gitignore => scwrypts/select.module.zsh} | 0 .../template/module/.gitignore} | 0 zsh/scwrypts/template/module/.tex | 9 + zsh/scwrypts/template/module/create | 14 + .../template/module/create.module.zsh | 32 + zsh/scwrypts/template/module/template.zsh | 129 + zsh/scwrypts/template/module/use.module.zsh | 0 zsh/scwrypts/template/zshparse.module.zsh | 92 + zsh/scwrypts/virtualenv/common.module.zsh | 36 + zsh/scwrypts/virtualenv/delete.module.zsh | 49 + zsh/scwrypts/virtualenv/env/py.module.zsh | 87 + zsh/scwrypts/virtualenv/env/zx.module.zsh | 46 + zsh/scwrypts/virtualenv/refresh | 59 +- zsh/scwrypts/virtualenv/update-all | 31 +- zsh/scwrypts/virtualenv/update.module.zsh | 34 + zsh/scwrypts/virtualenv/virtualenv.module.zsh | 12 + zsh/scwrypts/virtualenv/zshparse.module.zsh | 24 + zsh/system/config/settings | 7 - zsh/system/config/symlinks | 41 - zsh/system/config/terminfo | 21 - zsh/system/config/update | 10 - .../git-package-installer/build.module.zsh | 69 + .../git-package-installer/clone.module.zsh | 31 + .../git-package-installer.module.zsh | 11 + zsh/system/git-package-installer/install | 27 + .../git-package-installer/pull.module.zsh | 33 + .../git-package-installer/zshparse.module.zsh | 81 + zsh/system/packages/build | 7 - zsh/system/packages/download | 7 - zsh/system/packages/install | 83 - zsh/system/packages/update | 7 - zsh/system/vim/vundle/edit-build-actions | 7 - zsh/system/vim/vundle/install | 13 - zsh/system/vim/vundle/rebuild | 7 - zsh/unittest/execute-test-file.module.zsh | 51 + zsh/unittest/mock/create.module.zsh | 196 + zsh/unittest/mock/env.module.zsh | 85 + zsh/unittest/mock/mock.module.zsh | 10 + zsh/unittest/operations.module.zsh | 38 + zsh/unittest/run | 68 + zsh/unittest/test/provides.module.zsh | 8 + zsh/unittest/test/test.module.zsh | 9 + zsh/unittest/unittest.module.zsh | 30 + zsh/{lib => }/utils/README.md | 10 +- zsh/utils/apps/70-wrapper.zsh | 1 + zsh/utils/apps/99-fzf.zsh | 43 + zsh/utils/apps/99-less.zsh | 1 + zsh/utils/apps/99-notify-send.zsh | 13 + zsh/utils/apps/99-yq.zsh | 8 + zsh/utils/dependencies.zsh | 78 + zsh/utils/environment.zsh | 250 + zsh/utils/io/00-colors.zsh | 58 + zsh/utils/io/10-print.zsh | 104 + zsh/utils/io/20-echo.zsh | 57 + zsh/utils/io/30-user.zsh | 114 + zsh/utils/io/99-capture.zsh | 11 + zsh/utils/io/99-flow-control.zsh | 38 + zsh/utils/io/99-usage.zsh | 102 + zsh/utils/os.zsh | 24 + zsh/utils/parse.args.zsh | 114 + zsh/utils/parse.autosetup.zsh | 94 + zsh/utils/parse.help.zsh | 150 + zsh/utils/parse.zsh | 137 + zsh/utils/utils.module.zsh | 94 + zx/lib/package.json | 27 +- zx/lib/pnpm-lock.yaml | 3698 +++++++----- zx/lib/src/index.ts | 6 +- .../get-scwrypts-lookup.ts} | 8 +- .../parse-cli-args.ts} | 2 +- .../scwrypts.ts} | 8 +- zx/lib/src/scwrypts/get-scwrypts-lookup.ts | 2 +- zx/lib/src/scwrypts/index.ts | 4 + zx/lib/src/scwrypts/scwrypts.ts | 2 +- .../src/scwrypts/type.scwrypts-log-level.ts | 7 + zx/lib/src/scwrypts/type.scwrypts-options.ts | 10 + zx/lib/src/scwrypts/types.ts | 16 - zx/lib/tsconfig.json | 2 +- zx/package-lock.json | 5345 +++-------------- 271 files changed, 11459 insertions(+), 10516 deletions(-) create mode 100755 .config/create-new-env create mode 100644 .config/env.yaml create mode 100644 docs/upgrade/v4-to-v5.md create mode 100644 plugins/ci/.config/env.yaml rename plugins/{kubectl => kube}/.config/env.template (100%) rename plugins/{kubectl => kube}/.config/env.template.descriptions (100%) create mode 100644 plugins/kube/.config/env.yaml rename plugins/{kubectl => kube}/.config/static/redis.zsh (100%) rename plugins/{kubectl => kube}/README.md (100%) rename plugins/{kubectl => kube}/driver/kubectl.completion.zsh (81%) rename plugins/{kubectl => kube}/driver/kubectl.driver.zsh (79%) rename plugins/{kubectl => kube}/driver/meta.zsh (54%) rename plugins/{kubectl => kube}/get-context (53%) rename plugins/{kubectl => kube}/get-namespace (53%) create mode 100644 plugins/kube/kube.scwrypts.zsh create mode 100644 plugins/kube/kubectl/cli.module.zsh create mode 100644 plugins/kube/kubectl/context.module.zsh create mode 100644 plugins/kube/kubectl/kubectl.module.zsh create mode 100644 plugins/kube/kubectl/namespace.module.zsh create mode 100644 plugins/kube/kubectl/service.module.zsh create mode 100755 plugins/kube/meta/get-static-redis-definition rename plugins/{kubectl/lib => kube/redis}/redis.module.zsh (69%) rename plugins/{kubectl => kube}/serve (77%) rename plugins/{kubectl => kube}/set-context (56%) rename plugins/{kubectl => kube}/set-namespace (52%) delete mode 100644 plugins/kubectl/kubectl.scwrypts.zsh delete mode 100644 plugins/kubectl/lib/kubectl.module.zsh delete mode 100755 plugins/kubectl/meta/get-static-redis-definition create mode 100644 zsh/cloud/aws/aws.module.zsh create mode 100644 zsh/cloud/aws/aws.test.zsh create mode 100644 zsh/cloud/aws/cli.module.zsh create mode 100644 zsh/cloud/aws/cli.test.zsh create mode 100644 zsh/cloud/aws/ecr/ecr.module.zsh create mode 100644 zsh/cloud/aws/ecr/ecr.test.zsh create mode 100644 zsh/cloud/aws/ecr/login.module.zsh create mode 100644 zsh/cloud/aws/ecr/login.test.zsh create mode 100644 zsh/cloud/aws/eks/cli.module.zsh create mode 100644 zsh/cloud/aws/eks/cli.test.zsh create mode 100644 zsh/cloud/aws/eks/cluster-login.module.zsh create mode 100644 zsh/cloud/aws/eks/cluster-login.test.zsh create mode 100644 zsh/cloud/aws/eks/eks.module.zsh create mode 100644 zsh/cloud/aws/eks/eks.test.zsh create mode 100644 zsh/cloud/aws/eks/zshparse/cluster-name.module.zsh create mode 100644 zsh/cloud/aws/eks/zshparse/zshparse.module.zsh create mode 100644 zsh/cloud/aws/eksctl/cli.module.zsh create mode 100644 zsh/cloud/aws/eksctl/cli.test.zsh create mode 100644 zsh/cloud/aws/eksctl/eksctl.module.zsh create mode 100644 zsh/cloud/aws/eksctl/eksctl.test.zsh create mode 100644 zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.module.zsh create mode 100644 zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.test.zsh create mode 100644 zsh/cloud/aws/eksctl/iamserviceaccount/create.module.zsh create mode 100644 zsh/cloud/aws/eksctl/iamserviceaccount/create.test.zsh create mode 100644 zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.module.zsh create mode 100644 zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.test.zsh create mode 100644 zsh/cloud/aws/eksctl/iamserviceaccount/zshparse.module.zsh rename zsh/{lib/cloud/aws => cloud/aws/rds}/rds.module.zsh (76%) create mode 100644 zsh/cloud/aws/zshparse/overrides.module.zsh create mode 100644 zsh/cloud/aws/zshparse/zshparse.module.zsh delete mode 100755 zsh/cloud/media-sync/pull delete mode 100755 zsh/cloud/media-sync/push create mode 100644 zsh/config.global.zsh create mode 100644 zsh/config.user.zsh create mode 100644 zsh/config.zsh rename zsh/{lib/db => db/postgres}/postgres.module.zsh (70%) create mode 100644 zsh/helm/get-template.module.zsh create mode 100644 zsh/helm/helm.module.zsh create mode 100644 zsh/helm/update-dependencies.module.zsh create mode 100644 zsh/helm/validate.module.zsh create mode 100644 zsh/helm/zshparse.module.zsh create mode 100644 zsh/import.driver.zsh delete mode 100644 zsh/lib/cloud/aws/cli.module.zsh delete mode 100644 zsh/lib/cloud/aws/ecr.module.zsh delete mode 100644 zsh/lib/cloud/aws/eks.module.zsh delete mode 100644 zsh/lib/cloud/aws/eksctl.module.zsh delete mode 100644 zsh/lib/cloud/media-sync.module.zsh delete mode 100644 zsh/lib/config.user.zsh delete mode 100644 zsh/lib/config.zsh delete mode 100644 zsh/lib/helm/dependency.module.zsh delete mode 100644 zsh/lib/helm/helm.module.zsh delete mode 100644 zsh/lib/helm/template.module.zsh delete mode 100644 zsh/lib/helm/validate.module.zsh delete mode 100644 zsh/lib/import.driver.zsh delete mode 100644 zsh/lib/media/youtube.module.zsh delete mode 100644 zsh/lib/misc/k8s-helper.plugin.zsh delete mode 100644 zsh/lib/misc/tally.module.zsh delete mode 100644 zsh/lib/office/latex.module.zsh delete mode 100644 zsh/lib/office/memo.module.zsh delete mode 100644 zsh/lib/redis/redis.module.zsh delete mode 100644 zsh/lib/scwrypts/environment-files.module.zsh delete mode 100644 zsh/lib/scwrypts/meta.module.zsh delete mode 100644 zsh/lib/scwrypts/run.module.zsh delete mode 100644 zsh/lib/scwrypts/scwrypts.module.zsh delete mode 100644 zsh/lib/scwrypts/virtualenv.module.zsh delete mode 100644 zsh/lib/system/config/config.module.zsh delete mode 100644 zsh/lib/system/config/default.conf.zsh delete mode 100644 zsh/lib/system/desktop/notify.module.zsh delete mode 100644 zsh/lib/system/packages/git.module.zsh delete mode 100644 zsh/lib/system/vim/vim.module.zsh delete mode 100644 zsh/lib/system/vim/vundle.module.zsh delete mode 100644 zsh/lib/utils/colors.zsh delete mode 100644 zsh/lib/utils/credits.zsh delete mode 100644 zsh/lib/utils/dependencies.zsh delete mode 100644 zsh/lib/utils/environment.zsh delete mode 100644 zsh/lib/utils/io.fzf.zsh delete mode 100644 zsh/lib/utils/io.print.zsh delete mode 100644 zsh/lib/utils/io.usage.zsh delete mode 100644 zsh/lib/utils/io.zsh delete mode 100644 zsh/lib/utils/os.zsh delete mode 100644 zsh/lib/utils/utils.module.zsh delete mode 100644 zsh/media/youtube/README.md delete mode 100755 zsh/media/youtube/download delete mode 100755 zsh/media/youtube/get-audio-clip delete mode 100755 zsh/misc/tally create mode 100644 zsh/notify/desktop.module.zsh create mode 100644 zsh/notify/notify.module.zsh delete mode 100755 zsh/office/latex/build-pdf delete mode 100755 zsh/office/latex/cleanup delete mode 100755 zsh/office/latex/create-new delete mode 100755 zsh/office/latex/get-pdf delete mode 100755 zsh/office/latex/open-pdf delete mode 100644 zsh/office/latex/templates/basic/template.tex delete mode 100644 zsh/office/latex/templates/main.tex delete mode 100644 zsh/office/latex/templates/math/code.sty delete mode 100644 zsh/office/latex/templates/math/formatting.sty delete mode 100644 zsh/office/latex/templates/math/imports.sty delete mode 100644 zsh/office/latex/templates/math/shorthand.sty delete mode 100644 zsh/office/latex/templates/math/template.tex delete mode 100644 zsh/office/latex/templates/times-new-roman-12/custom-headers.sty delete mode 100644 zsh/office/latex/templates/times-new-roman-12/formatting.sty delete mode 100644 zsh/office/latex/templates/times-new-roman-12/imports.sty delete mode 100644 zsh/office/latex/templates/times-new-roman-12/template.tex delete mode 100755 zsh/office/memo/open delete mode 100755 zsh/office/memo/remove create mode 100644 zsh/redis/cli.module.zsh create mode 100644 zsh/redis/curl.module.zsh create mode 100644 zsh/redis/enabled.module.zsh create mode 100644 zsh/redis/redis.module.zsh delete mode 100644 zsh/scwrypts/README.md create mode 100644 zsh/scwrypts/cache-output.module.zsh create mode 100644 zsh/scwrypts/environment/common.module.zsh delete mode 100755 zsh/scwrypts/environment/copy delete mode 100755 zsh/scwrypts/environment/delete delete mode 100755 zsh/scwrypts/environment/edit create mode 100644 zsh/scwrypts/environment/environment.module.zsh create mode 100644 zsh/scwrypts/environment/get-envvar-lookup-map.module.zsh create mode 100644 zsh/scwrypts/environment/get-full-template.module.zsh create mode 100755 zsh/scwrypts/environment/getenv create mode 100644 zsh/scwrypts/environment/init.module.zsh create mode 100644 zsh/scwrypts/environment/select-env.module.zsh delete mode 100755 zsh/scwrypts/environment/synchronize create mode 100755 zsh/scwrypts/environment/update create mode 100644 zsh/scwrypts/environment/update.module.zsh create mode 100644 zsh/scwrypts/environment/user.module.zsh create mode 100644 zsh/scwrypts/get-realpath.module.zsh create mode 100644 zsh/scwrypts/get-runstring.module.zsh create mode 100644 zsh/scwrypts/list-available.module.zsh create mode 100644 zsh/scwrypts/meta.module.zsh create mode 100755 zsh/scwrypts/rebuild-cache rename zsh/{office/latex/templates/math/gitignore => scwrypts/select.module.zsh} (100%) rename zsh/{office/latex/templates/gitignore => scwrypts/template/module/.gitignore} (100%) create mode 100644 zsh/scwrypts/template/module/.tex create mode 100755 zsh/scwrypts/template/module/create create mode 100644 zsh/scwrypts/template/module/create.module.zsh create mode 100644 zsh/scwrypts/template/module/template.zsh create mode 100644 zsh/scwrypts/template/module/use.module.zsh create mode 100644 zsh/scwrypts/template/zshparse.module.zsh create mode 100644 zsh/scwrypts/virtualenv/common.module.zsh create mode 100644 zsh/scwrypts/virtualenv/delete.module.zsh create mode 100644 zsh/scwrypts/virtualenv/env/py.module.zsh create mode 100644 zsh/scwrypts/virtualenv/env/zx.module.zsh create mode 100644 zsh/scwrypts/virtualenv/update.module.zsh create mode 100644 zsh/scwrypts/virtualenv/virtualenv.module.zsh create mode 100644 zsh/scwrypts/virtualenv/zshparse.module.zsh delete mode 100755 zsh/system/config/settings delete mode 100755 zsh/system/config/symlinks delete mode 100755 zsh/system/config/terminfo delete mode 100755 zsh/system/config/update create mode 100644 zsh/system/git-package-installer/build.module.zsh create mode 100644 zsh/system/git-package-installer/clone.module.zsh create mode 100644 zsh/system/git-package-installer/git-package-installer.module.zsh create mode 100755 zsh/system/git-package-installer/install create mode 100644 zsh/system/git-package-installer/pull.module.zsh create mode 100644 zsh/system/git-package-installer/zshparse.module.zsh delete mode 100755 zsh/system/packages/build delete mode 100755 zsh/system/packages/download delete mode 100755 zsh/system/packages/install delete mode 100755 zsh/system/packages/update delete mode 100755 zsh/system/vim/vundle/edit-build-actions delete mode 100755 zsh/system/vim/vundle/install delete mode 100755 zsh/system/vim/vundle/rebuild create mode 100644 zsh/unittest/execute-test-file.module.zsh create mode 100644 zsh/unittest/mock/create.module.zsh create mode 100644 zsh/unittest/mock/env.module.zsh create mode 100644 zsh/unittest/mock/mock.module.zsh create mode 100644 zsh/unittest/operations.module.zsh create mode 100755 zsh/unittest/run create mode 100644 zsh/unittest/test/provides.module.zsh create mode 100644 zsh/unittest/test/test.module.zsh create mode 100644 zsh/unittest/unittest.module.zsh rename zsh/{lib => }/utils/README.md (92%) create mode 100644 zsh/utils/apps/70-wrapper.zsh create mode 100644 zsh/utils/apps/99-fzf.zsh create mode 100644 zsh/utils/apps/99-less.zsh create mode 100644 zsh/utils/apps/99-notify-send.zsh create mode 100644 zsh/utils/apps/99-yq.zsh create mode 100644 zsh/utils/dependencies.zsh create mode 100644 zsh/utils/environment.zsh create mode 100644 zsh/utils/io/00-colors.zsh create mode 100644 zsh/utils/io/10-print.zsh create mode 100644 zsh/utils/io/20-echo.zsh create mode 100644 zsh/utils/io/30-user.zsh create mode 100644 zsh/utils/io/99-capture.zsh create mode 100644 zsh/utils/io/99-flow-control.zsh create mode 100644 zsh/utils/io/99-usage.zsh create mode 100644 zsh/utils/os.zsh create mode 100644 zsh/utils/parse.args.zsh create mode 100644 zsh/utils/parse.autosetup.zsh create mode 100644 zsh/utils/parse.help.zsh create mode 100644 zsh/utils/parse.zsh create mode 100644 zsh/utils/utils.module.zsh rename zx/lib/src/scwrypts/{get-scwrypts-lookup.test.ts => __tests__/get-scwrypts-lookup.ts} (90%) rename zx/lib/src/scwrypts/{parse-cli-args.test.ts => __tests__/parse-cli-args.ts} (93%) rename zx/lib/src/scwrypts/{scwrypts.test.ts => __tests__/scwrypts.ts} (94%) create mode 100644 zx/lib/src/scwrypts/index.ts create mode 100644 zx/lib/src/scwrypts/type.scwrypts-log-level.ts create mode 100644 zx/lib/src/scwrypts/type.scwrypts-options.ts delete mode 100644 zx/lib/src/scwrypts/types.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index 62e7115..475bfa1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,10 +22,14 @@ executors: - image: node:18 resource_class: medium + zsh: + docker: + - image: alpine:3 + resource_class: small commands: archlinux-run: - description: execute command steps in the archlinux container from the CI user + description: execute steps in the archlinux container as the CI user parameters: _name: type: string @@ -243,6 +247,47 @@ jobs: - run: pip install build && python -m build - run: pip install twine && twine upload dist/* + zsh-test: + executor: zsh + working_directory: ~/scwrypts + steps: + - checkout: + path: ~/scwrypts + - run: + name: install dependencies + command: | + : \ + && apk add \ + coreutils \ + findutils \ + fzf \ + perl \ + sed \ + gawk \ + git \ + jo \ + jq \ + util-linux \ + uuidgen \ + yq \ + zsh \ + ; + - run: + name: scwrypts zsh/unittest + command: | + ~/scwrypts/scwrypts run unittest \ + ; + - run: + name: scwrypts returns proper success codes + command: | + ~/scwrypts/scwrypts -n sanity check -- --exit-code 0 + [[ $? -eq 0 ]] || exit 1 + - run: + shell: /bin/sh + name: scwrypts returns proper error codes + command: | + ~/scwrypts/scwrypts -n sanity check -- --exit-code 101 + [[ $? -eq 101 ]] || exit 1 workflows: test: @@ -255,6 +300,7 @@ workflows: - python-test: *dev-filters - nodejs-test: *dev-filters + - zsh-test: *dev-filters publish: jobs: @@ -285,6 +331,7 @@ workflows: - aur-test - python-publish - nodejs-publish + - zsh-test - python-test: *only-publish-for-full-semver - python-publish: @@ -292,6 +339,7 @@ workflows: context: [pypi-yage] requires: - python-test + - zsh-test - nodejs-test: *only-publish-for-full-semver - nodejs-publish: @@ -299,3 +347,6 @@ workflows: context: [npm-wrynegade] requires: - nodejs-test + - zsh-test + + - zsh-test: *only-publish-for-full-semver diff --git a/.config/create-new-env b/.config/create-new-env new file mode 100755 index 0000000..f0b7bd7 --- /dev/null +++ b/.config/create-new-env @@ -0,0 +1,89 @@ +#!/bin/zsh +# +# a temporary template conversion utility for env.template (<=v4) +# to env.yaml (>=v5) +# +eval $(scwrypts --config) +use -c scwrypts/environment-files + +ENVIRONMENT_ROOT="$1" +[ "$ENVIRONMENT_ROOT" ] || ENVIRONMENT_ROOT="${0:a:h}" + +OLDENV="$ENVIRONMENT_ROOT/env.template" +NEWENV="$ENVIRONMENT_ROOT/env.yaml" +ENVMAP="$ENVIRONMENT_ROOT/.map.txt" + +GROUP="$2" +[ $GROUP ] || GROUP=scwrypts +GENERATE_TEMPLATE \ + | sed '1,4d; /^$/d' \ + | sed -z 's/# \([^\n]*\)\n\([^\n]*\)=/\2=\n\2=DESCRIPTION=\1/g' \ + | sed ' + s/^export // + /./i--- + s/\s\+$// + s/__/=/g + s/^\(AWS\|REDIS\)_/\1=/ + s/^\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]*\)=$/\L\1:\n \2:\n \3:\n \4:\n \5:/ + s/^\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]*\)=$/\L\1:\n \2:\n \3:\n \4:/ + s/^\([^=]*\)=\([^=]*\)=\([^=]*\)=$/\L\1:\n \2:\n \3:/ + s/^\([^=]*\)=\([^=]*\)=$/\L\1:\n \2:/ + s/^\([^=]*\)=$/\L\1:/ + s/^\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]\+\)$/\L\1:\n \2:\n \3:\n \4:\n \5: \E\6/ + s/^\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]\+\)$/\L\1:\n \2:\n \3:\n \4: \E\5/ + s/^\([^=]*\)=\([^=]*\)=\([^=]*\)=\([^=]\+\)$/\L\1:\n \2:\n \3: \E\4/ + s/^\([^=]*\)=\([^=]*\)=\([^=]\+\)$/\L\1:\n \2: \E\3/ + s/^\([^=]*\)=\([^=]\+\)$/\L\1: \E\2/ + s/: (\(.*\))/: [\1]/ + /^/,/:/{s/_/-/g} + ' \ + | sed ' + s/^ \(description:.*\)/ \1/ + s/description:/.DESCRIPTION:/ + ' \ + | sed -z 's/\n\(\s\+\).DESCRIPTION:\([^\n]\+\)/\n\1.DESCRIPTION: >-\n\1 \2/g' \ + | yq eval-all '. as $item ireduce ({}; . *+ $item)' \ + > "$NEWENV" \ + ; + +cat -- "$OLDENV" \ + | sed ' + s/#.*// + /^$/d + s/^export // + s/\s\+$// + s/^\([^=]*\)=.*/\1=\n\1/ + ' \ + | sed ' + /^/s/.*/\L&/ + /^/s/__/./g + /^/s/_/-/g + s/^/./ + s/\(aws\|redis\)-/\1./ + ' \ + | perl -pe 's/=\n/^/' \ + | column -ts '^' \ + > "$ENVMAP" \ + ; + +while read line +do + ENV_VAR=$(echo $line | awk '{print $1;}') + LOOKUP=$(echo $line | awk '{print $2;}') + + cp "$NEWENV" "$NEWENV.temp" + cat "$NEWENV.temp" \ + | yq ". | $LOOKUP.[\".ENVIRONMENT\"] = \"$ENV_VAR\"" \ + | yq 'sort_keys(...)' \ + > "$NEWENV" + ; +done < "$ENVMAP" + +rm -- "$NEWENV.temp" "$ENVMAP" &>/dev/null + +head -n1 -- "$NEWENV" | grep -q "^{}$" && { + echo '---' > "$NEWENV" +} + +cat -- "$NEWENV" | yq +SUCCESS "new environment saved to '$NEWENV'" diff --git a/.config/env.yaml b/.config/env.yaml new file mode 100644 index 0000000..c5dd908 --- /dev/null +++ b/.config/env.yaml @@ -0,0 +1,66 @@ +--- +aws: + .DESCRIPTION: >- + standard AWS environment variables used by awscli and other tools + account: + .ENVIRONMENT: AWS_ACCOUNT + efs: + local-mount-point: + .DESCRIPTION: >- + fully-qualified path to mount the EFS drive + .ENVIRONMENT: AWS__EFS__LOCAL_MOUNT_POINT + profile: + .ENVIRONMENT: AWS_PROFILE + region: + .ENVIRONMENT: AWS_REGION +directus: + .DESCRIPTION: >- + details for a directus instance + api-token: + .ENVIRONMENT: DIRECTUS__API_TOKEN + base-url: + .ENVIRONMENT: DIRECTUS__BASE_URL +discord: + .DESCRIPTION: >- + details for discord bot + bot-token: + .ENVIRONMENT: DISCORD__BOT_TOKEN + content-footer: + .ENVIRONMENT: DISCORD__CONTENT_FOOTER + content-header: + .ENVIRONMENT: DISCORD__CONTENT_HEADER + default-avatar-url: + .ENVIRONMENT: DISCORD__DEFAULT_AVATAR_URL + default-channel-id: + .ENVIRONMENT: DISCORD__DEFAULT_CHANNEL_ID + default-username: + .ENVIRONMENT: DISCORD__DEFAULT_USERNAME + default-webhook: + .ENVIRONMENT: DISCORD__DEFAULT_WEBHOOK +linear: + .DESCRIPTION: >- + linear.app project management configuration + api-token: + .ENVIRONMENT: LINEAR__API_TOKEN +redis: + .DESCRIPTION: >- + redis connection credentials + auth: + .ENVIRONMENT: REDIS_AUTH + host: + .ENVIRONMENT: REDIS_HOST + port: + .ENVIRONMENT: REDIS_PORT +twilio: + .DESCRIPTION: >- + twilio account / credentials + account-sid: + .ENVIRONMENT: TWILIO__ACCOUNT_SID + api-key: + .ENVIRONMENT: TWILIO__API_KEY + api-secret: + .ENVIRONMENT: TWILIO__API_SECRET + default-phone-from: + .ENVIRONMENT: TWILIO__DEFAULT_PHONE_FROM + default-phone-to: + .ENVIRONMENT: TWILIO__DEFAULT_PHONE_TO diff --git a/README.md b/README.md index 354ad14..13204c6 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,76 @@ -# *Scwrypts* (Wryn + Scripts) +# *Scwrypts* -Scwrypts is a friendly CLI / API for quickly running *sandboxed scripts* in the terminal. +Scwrypts is a CLI and API for safely running scripts in the terminal, CI, and other automated environments. -In modern developer / dev-ops workflows, scripts require a complex configurations. -Without a better solution, the developer is cursed to copy lines-upon-lines of variables into terminals, create random text artifacts, or maybe even commit secure credentials into source. -Scwrypts leverages ZSH to give hot-key access to run scripts in such environments. +Local runs provide a user-friendly approach to quickly execute CI workflows and automations in your terminal. +Each local run runs through an interactive, *sandboxed environment* so you never accidentally run dev credentials in production ever again! ## Major Version Upgrade Notice -Please refer to [Version 3 to Version 4 Upgrade Path](./docs/upgrade/v3-to-v4.md) when upgrading from scwrypts v3 to scwrypts v4! +Please refer to [Version 4 to Version 5 Upgrade Path](./docs/upgrade/v4-to-v5.md) when upgrading from scwrypts v4 to scwrypts v5! -## Dependencies -Due to the wide variety of resources used by scripting libraries, the user is expected to manually resolve dependencies. -Dependencies are lazy-loaded, and more information can be found by command error messages or in the appropriate README. +## Installation -Because Scwrypts relies on Scwrypts (see [Meta Scwrypts](./zsh/scwrypts)), `zsh` must be installed and [`junegunn/fzf`](https://github.com/junegunn/fzf) must be available on your PATH. +Quick installation is supported through both the [Arch User Repository](https://aur.archlinux.org/packages/scwrypts) and [Homebrew](https://github.com/wrynegade/homebrew-brew/tree/main/Formula) -## Usage -Install Scwrypts by cloning this repository and sourcing `scwrypts.plugin.zsh` in your `zshrc`. -You can now run Scwrypts using the ZLE hotkey bound to `SCWRYPTS_SHORTCUT` (default `CTRL + W`). +```bash +# AUR +yay -Syu scwrypts -```console -% cd -% echo "source $(pwd)/scwrypts.plugin.zsh >> $HOME/.zshrc" +# homebrew +brew install wrynegade/scwrypts ``` -Check out [Meta Scwrypts](./zsh/scwrypts) to quickly set up environments and adjust configuration. +### Manual Installation - -### No Install / API Usage -Alternatively, the `scwrypts` API can be used directly: +To install scwrypts manually, clone this repository (and take note of where it is installed) +Replacing the `/path/to/cloned-repo` appropriately, add the following line to your `~/.zshrc`: ```zsh -./scwrypts [--env environment-name] (...script-name-patterns...) [-- ...passthrough arguments... ] +source /path/to/cloned-repo/scwrypts.plugin.zsh ``` -Given one or more script patterns, Scwrypts will filter the commands by pattern conjunction. -If only one command is found which matches the pattern(s), it will immediately begin execution. -If multiple commands match, the user will be prompted to select from the filtered list. -Of course, if no commands match, Scwrypts will exit with an error. +The next time you start your terminal, you can now execute scwrypts by using the plugin shortcut(s) (by default `CTRL + SPACE`). +Plugin shortcuts are configurable in your scwrypts configuration file found in `~/.config/scwrypts/config.zsh`, and [here is the default config](./zsh/config.user.zsh). -Given no script patterns, Scwrypts becomes an interactive CLI, prompting the user to select a command. +If you want to use the `scwrypts` program directly, you can either invoke the executable `./scwrypts` or link it in your PATH for easy access. +For example, if you have `~/.local/bin` in your PATH, you might run: +```zsh +ln -s /path/to/cloned-repo/scwrypts "${HOME}/.local/bin/scwrypts" +``` -After determining which script to run, if no environment has been specified, Scwrypts prompts the user to choose one. +#### PATH Dependencies + +Scwrypts provides a framework for workflows which often depend on a variety of other tools. +Although the lazy-loaded dependency model allows hardening in CI and extendability, the user is expected to _resolve required PATH dependencies_. + +When running locally, this is typically as simple as "install the missing program," but this may require additional steps when working in automated environments. + +By default, the `ci` plugin is enabled which provides the `check all dependencies` scwrypt. +You can run this to output a comprehensive list of PATH dependencies across all scwrypts groups, but, at a bare minimum, you will need the following applications in your PATH: + +```bash +zsh + +grep # GNU +sed # GNU +sort # GNU + +fzf # https://github.com/junegunn/fzf (only required for interactive / local) +jo # https://github.com/jpmens/jo +jq # https://github.com/jqlang/jq +yq # https://github.com/mikefarah/yq +``` -### Using in CI/CD or Automated Workflows -Set environment variable `CI=true` (and use the no install method) to run in an automated pipeline. +## Usage in CI and Automated Environments + +Set environment variable `CI=true` to run scwrypts in an automated environment. There are a few notable changes to this runtime: -- **The Scwrypts sandbox environment will not load.** All variables will be read from context. +- **The Scwrypts sandbox environment will not load.** All variables will be read directly from the current context. - User yes/no prompts will **always be YES** - Other user input will default to an empty string -- Logs will not be captured -- Setting the environment variable `SCWRYPTS_GROUP_LOADER__[a-z_]\+` will source the file indicated in the variable (this allows custom groups without needing to modify the `config.zsh` directly) - - In GitHub actions, `*.scwrypts.zsh` groups are detected automatically from the `$GITHUB_WORKSPACE`; set `SCWRYPTS_GITHUB_NO_AUTOLOAD=true` to disable - +- Logs will not be captured in the user's local cache +- In GitHub actions, `*.scwrypts.zsh` groups are detected automatically from the `$GITHUB_WORKSPACE`; set `SCWRYPTS_GITHUB_NO_AUTOLOAD=true` to disable ## Contributing diff --git a/docs/humans.txt b/docs/humans.txt index 799046a..b826057 100644 --- a/docs/humans.txt +++ b/docs/humans.txt @@ -1,6 +1,6 @@ - ___________________________ + ___________________________ < ~thanks for your support~ > - --------------------------- + --------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ diff --git a/docs/upgrade/v3-to-v4.md b/docs/upgrade/v3-to-v4.md index 66d0af3..bfba8ac 100644 --- a/docs/upgrade/v3-to-v4.md +++ b/docs/upgrade/v3-to-v4.md @@ -57,7 +57,7 @@ Don't worry, it's easy. Take your original scwrypt, and slap the executable stuff into a function called `MAIN` (yes, it must be _exactly_, all-caps `MAIN`): ```diff -#!/bin/zsh +#!/usr/bin/env zsh ##################################################################### DEPENDENCIES+=(dep-function-a dep-function-b) REQUIRED_ENV+=() @@ -69,11 +69,11 @@ CHECK_ENVIRONMENT - echo "do some stuff here" - # ... etc ... -- SUCCESS "completed the stuff" +- echo.success "completed the stuff" + MAIN() { + echo "do some stuff here" + # ... etc ... -+ SUCCESS "completed the stuff ++ echo.success "completed the stuff + } ``` @@ -85,7 +85,7 @@ All I had to do in this case was delete the function invocation at the end: ```diff # ... top boilerplate ... MAIN() { - SUCCESS "look at me I'm so cool I already wrote this in a main function" + echo.success "look at me I'm so cool I already wrote this in a main function" } - - ##################################################################### @@ -115,20 +115,20 @@ Also you can ditch the `CHECK_ENVIRONMENT`. While it won't hurt, v4 already does this, so just get rid of it. Here's my recommended formatting: ```diff -#!/bin/zsh +#!/usr/bin/env zsh - ##################################################################### DEPENDENCIES+=(dep-function-a dep-function-b) - REQUIRED_ENV+=() use do/awesome/stuff --group my-custom-library -- +- - CHECK_ENVIRONMENT ##################################################################### MAIN() { echo "do some stuff here" # ... etc ... - SUCCESS "completed the stuff + echo.success "completed the stuff } ``` @@ -164,7 +164,7 @@ If you _have_ done it already, typically by writing a variable called "USAGE" in Returning to our original `MAIN()` example, I'll add some options parsing so we should now look something like this: ```sh -#!/bin/zsh +#!/usr/bin/env zsh DEPENDENCIES+=(dep-function-a dep-function-b) use do/awesome/stuff --group my-custom-library @@ -200,7 +200,7 @@ I want to call out a few specific ones: Just add another section to define these values before declaring `MAIN`: ```sh -#!/bin/zsh +#!/usr/bin/env zsh DEPENDENCIES+=(dep-function-a dep-function-b) use do/awesome/stuff --group my-custom-library diff --git a/docs/upgrade/v4-to-v5.md b/docs/upgrade/v4-to-v5.md new file mode 100644 index 0000000..728babf --- /dev/null +++ b/docs/upgrade/v4-to-v5.md @@ -0,0 +1,136 @@ +# Scwrypts Upgrade v4 to v5 Notes + +Although scwrypts v4 brings a number of new features, most functionality is backwards-compatible. + +## Lots of renames! + +Nearly every module received a rename. +This was a decision made to improve both style-consistency and import transparency, but has resulted in a substantial number of breaking changes to `zsh-type scwrypts modules`. + +### `zsh/utils` Functions + +The functions in the underlying library have all been renamed, but otherwise maintain the same functionality. +For a full reference, check out the [zsh/utils](../../zsh/utils/utils.module.zsh), but some critical renames are: +```bash +FZF >> utils.fzf +FZF_USER_INPUT >> utils.fzf.user-input +LESS >> utils.less +YQ >> utils.yq + +SUCCESS >> echo.success +ERROR >> echo.error +REMINDER >> echo.reminder +STATUS >> echo.status +WARNING >> echo.warning +DEBUG >> echo.debug +FAIL >> utils.fail +ABORT >> utils.abort + +CHECK_ERRORS >> utils.check-errors + +Yn >> utils.Yn +yN >> utils.yN + +EDIT >> utils.io.edit + +CHECK_ENVIRONMENT >> utils.check-environment +``` + +### `zsh/utils` Color Functions + +Rather than storing ANSI colors as a variable, colors are now stored as a function which prints the color code. +Doing this has proven more versatile than trying to extract the value of the variable in several contexts. +Rename looks like this for all named ANSI colors: + +```bash +$__GREEN >> utils.colors.green +$__BRIGHT_RED >> utils.colors.bright-red +``` + +The most common use case of colors is indirectly through the `echo.*` commands, so a new function now provides _the color used by the associated `echo.*` command_: + +```bash +# instead of +STATUS "Hello there, ${_BRIGHT_GREEN}bobby${_YELLOW}. How are you?" + +# use +echo.status "Hello there, $(utils.colors.bright-green)bobby$(echo.status.color). How are you? +``` + +### ZSH Scwrypts Module Naming + +**This is the biggest point of refactor.** + +You will notice that modules now declare their functions using a `${scwryptsmodule}` notation. +This notation provides a dot-notated name which is intended to provide a consistent, unique naming system in ZSH (remember, everything loaded into the same shell script must have a globally-unique name). +Consider the new naming method for the following: + +```bash +# v4: zsh/lib/helm/template.module.zsh + +HELM__TEMPLATE__GET() { + # ... +} + +# v5: zsh/helm/get-template.module.zsh +${scwryptsmodule}() { + # ... +} +``` + +Although the import syntax is generally the same, now we reference the full name of the module instead of the arbitrarily defined `HELM__TEMPLATE__GET`: + +``` +# in some other scwrypt +use helm/get-template + +helm.get-template --raw ./my-helm-chart +``` + +The name `${scwryptsmodule}` is depended on the scwrypts library path. +Since there is not an easy way to provide an exhaustive list, go through all the places where you `use` something from the scwrypts core library, and check to see where it is now. +One of the critical call-outs is the AWS CLI, which no longer follows the "just use ALL CAPS for function names," but instead is a proper module. + +Both of the following are valid ways to use the scwrypts-safe aws-cli (`AWS` in v4): + +```bash +# to import _only_ AWS cli +use cloud.aws.cli + +cloud.aws.cli sts get-caller-identity + +# importing the full AWS module also provides an alias +use cloud.aws + +cloud.aws sts get-caller-identity +``` + +### Great news! + +Great news! +We have finished with **all of the necessary steps** to migrate to v5! + +If you still have the energy, take some time to make these _recommended_ adjustments too. + + +### Use the new `${scwryptsmodule}` syntax + +The `${scwryptsmodule}` name is now automatically available in any module. +The one change from the `${scwryptsmodule}` in scwrypts core is that **your scwrypts group name is the first dot**. + +If I'm building the scwrypts group called `my-cool-stuff` and open the file `my-cool-stuff/zsh/module-a.module.zsh`, then `${scwryptsmodule}` will refer to `my-cool-stuff.module-a`. + +### Update your `*.scwrypts.zsh` declaration file + +In v4 and earlier, it was tricky to create your own scwrypts group, since you had to create a particular folder structure, and write a `group-name.scwrypts.zsh` file with some somewhat arbitrary requirements. +In v5, you can now make any folder a scwrypts group by simply _creating the `*.scwrypts.zsh` file_. + +```bash +# this will turn the current folder into the root of a scwrypts group called `my-cool-stuff` +touch 'my-cool-stuff.scwrypts.zsh' + ├── zsh + ├── zx + └── py +``` + +Advanced options for scwrypts are now [documented in the example](../../scwrypts.scwrypts.zsh), so please refer to it for any additional changes you may need for existing scwrypts modules. diff --git a/plugins/ci/.config/env.yaml b/plugins/ci/.config/env.yaml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/plugins/ci/.config/env.yaml @@ -0,0 +1 @@ +--- diff --git a/plugins/ci/README.md b/plugins/ci/README.md index 8a40381..f4efe5e 100644 --- a/plugins/ci/README.md +++ b/plugins/ci/README.md @@ -1,10 +1,3 @@ -# Kubernetes `kubectl` Helper Plugin +# CI Helper -Leverages a local `redis` application to quickly and easily set an alias `k` for `kubectl --context --namespace `. -Much like scwrypts environments, `k` aliases are *only* shared amongst session with the same `SCWRYPTS_ENV` to prevent accidental cross-contamination. - - -## Getting Started - -Enable the plugin in `~/.config/scwrypts/config.zsh` by adding `SCWRYPTS_PLUGIN_ENABLED__KUBECTL=1`. -Use `k` as your new `kubectl` and checkout `k --help` and `k meta --help`. +Disabled by default, this is used in CI contexts to try and identify missing requirements for the current workflow. diff --git a/plugins/ci/check-all-dependencies b/plugins/ci/check-all-dependencies index bc9d7c2..15e6eb1 100755 --- a/plugins/ci/check-all-dependencies +++ b/plugins/ci/check-all-dependencies @@ -1,7 +1,7 @@ -#!/bin/zsh +#!/usr/bin/env zsh ##################################################################### MAIN() { - cd "$SCWRYPTS_ROOT__scwrypts/" + cd "$(scwrypts.config.group scwrypts root)" DEPENDENCIES+=() for group in ${SCWRYPTS_GROUPS[@]} @@ -11,7 +11,7 @@ MAIN() { GROUP_HOME="$(eval 'echo $SCWRYPTS_ROOT__'$group)" [ $GROUP_HOME ] && [ -d "$GROUP_HOME" ] || continue - STATUS "checking dependencies for $group" + echo.status "checking dependencies for $group" DEPENDENCIES+=($( for file in $( { @@ -21,13 +21,13 @@ MAIN() { } | grep -v '\.md$' | grep -v 'check-all-dependencies$') do sed -z 's/.*DEPENDENCIES+=(\([^)]*\)).*/\1\n/; s/#.*\n//g; s/\s\+/\n/g' "$GROUP_HOME/$file" - done + done )) done DEPENDENCIES=(zsh $(echo $DEPENDENCIES | sed 's/ /\n/g' | sort -u | grep '^[-_a-zA-Z]\+$')) - STATUS "discovered dependencies: ($DEPENDENCIES)" + echo.status "discovered dependencies: ($DEPENDENCIES)" echo $DEPENDENCIES | sed 's/ /\n/g' - CHECK_ENVIRONMENT && SUCCESS "all dependencies satisfied" + utils.check-environment && echo.success "all dependencies satisfied" } diff --git a/plugins/ci/ci.scwrypts.zsh b/plugins/ci/ci.scwrypts.zsh index 7530945..1109657 100644 --- a/plugins/ci/ci.scwrypts.zsh +++ b/plugins/ci/ci.scwrypts.zsh @@ -1,5 +1 @@ -SCWRYPTS_GROUPS+=(ci) - -export SCWRYPTS_TYPE__ci=zsh -export SCWRYPTS_ROOT__ci="$SCWRYPTS_ROOT__scwrypts/plugins/ci" -export SCWRYPTS_COLOR__ci='\033[0m' +export ${scwryptsgroup}__type=zsh diff --git a/plugins/kubectl/.config/env.template b/plugins/kube/.config/env.template similarity index 100% rename from plugins/kubectl/.config/env.template rename to plugins/kube/.config/env.template diff --git a/plugins/kubectl/.config/env.template.descriptions b/plugins/kube/.config/env.template.descriptions similarity index 100% rename from plugins/kubectl/.config/env.template.descriptions rename to plugins/kube/.config/env.template.descriptions diff --git a/plugins/kube/.config/env.yaml b/plugins/kube/.config/env.yaml new file mode 100644 index 0000000..b2c2a88 --- /dev/null +++ b/plugins/kube/.config/env.yaml @@ -0,0 +1,5 @@ +--- +scwrypts-kubectl-redis: + .DESCRIPTION: >- + [currently only 'managed'] 'managed' or 'custom' redis configuration + .ENVIRONMENT: SCWRYPTS_KUBECTL_REDIS diff --git a/plugins/kubectl/.config/static/redis.zsh b/plugins/kube/.config/static/redis.zsh similarity index 100% rename from plugins/kubectl/.config/static/redis.zsh rename to plugins/kube/.config/static/redis.zsh diff --git a/plugins/kubectl/README.md b/plugins/kube/README.md similarity index 100% rename from plugins/kubectl/README.md rename to plugins/kube/README.md diff --git a/plugins/kubectl/driver/kubectl.completion.zsh b/plugins/kube/driver/kubectl.completion.zsh similarity index 81% rename from plugins/kubectl/driver/kubectl.completion.zsh rename to plugins/kube/driver/kubectl.completion.zsh index bb02f5f..251b3dc 100644 --- a/plugins/kubectl/driver/kubectl.completion.zsh +++ b/plugins/kube/driver/kubectl.completion.zsh @@ -6,10 +6,11 @@ for CLI in kubectl helm flux do eval "_${CLI[1]}() { local SUBSESSION=0 - echo \${words[2]} | grep -q '^[0-9]\\+$' && SUBSESSION=\${words[2]} + local SUBSESSION_OFFSET=2 + echo \${words[2]} | grep -q '^[0-9]\\+$' && SUBSESSION=\${words[2]} && SUBSESSION_OFFSET=3 local PASSTHROUGH_WORDS=($CLI) - [[ \$CURRENT -gt 2 ]] && echo \${words[2]} | grep -qv '^[0-9]\\+$' && { + [[ \$CURRENT -gt \${SUBSESSION_OFFSET} ]] && echo \${words[\${SUBSESSION_OFFSET}]} | grep -qv '^[0-9]\\+$' && { local KUBECONTEXT=\$(k \$SUBSESSION meta get context) local NAMESPACE=\$(k \$SUBSESSION meta get namespace) @@ -26,8 +27,8 @@ do for WORD in \${words[@]:1} do case \$WORD in - [0-9]* ) continue ;; - -- ) + ( [0-9]* ) continue ;; + ( -- ) echo \$words | grep -q 'exec' && ((DELIMIT_COUNT+=1)) [[ \$DELIMIT_COUNT -eq 0 ]] && ((DELIMIT_COUNT+=1)) && continue ;; @@ -37,7 +38,7 @@ do echo \"\$words\" | grep -q '\\s\\+$' && PASSTHROUGH_WORDS+=(' ') - words=\"\$PASSTHROUGH_WORDS\" + words=\"\${PASSTHROUGH_WORDS[@]}\" _$CLI } " diff --git a/plugins/kubectl/driver/kubectl.driver.zsh b/plugins/kube/driver/kubectl.driver.zsh similarity index 79% rename from plugins/kubectl/driver/kubectl.driver.zsh rename to plugins/kube/driver/kubectl.driver.zsh index 06118c2..892cab5 100644 --- a/plugins/kubectl/driver/kubectl.driver.zsh +++ b/plugins/kube/driver/kubectl.driver.zsh @@ -7,12 +7,12 @@ f() { _SCWRYPTS_KUBECTL_DRIVER flux $@; } _SCWRYPTS_KUBECTL_DRIVER() { [ ! $SCWRYPTS_ENV ] && { - ERROR "must set SCWRYPTS_ENV in order to use '$(echo $CLI | head -c1)'" + echo.error "must set SCWRYPTS_ENV in order to use '$(echo $CLI | head -c1)'" return 1 } - which REDIS >/dev/null 2>&1 \ - || eval "$(scwrypts -n --name meta/get-static-redis-definition --type zsh --group kubectl)" + which kube.redis >/dev/null 2>&1 \ + || eval "$(scwrypts -n --name meta/get-static-redis-definition --type zsh --group kube)" local CLI="$1"; shift 1 @@ -38,16 +38,16 @@ _SCWRYPTS_KUBECTL_DRIVER() { description: - " - local USAGE__usage=$(echo $CLI | head -c1) + local USAGE__usage=$(echo $CLI | head -c1) local USAGE__args="$( { - echo "\\033[0;32m[0-9]\\033[0m^if the first argument is a number 0-9, uses or creates a subsession (default 0)" + echo "$(utils.colors.print green '[0-9]')^if the first argument is a number 0-9, uses or creates a subsession (default 0)" echo " ^ " for C in ${CUSTOM_COMMANDS[@]} do - echo "\\033[0;32m$C\\033[0m^$(SCWRYPTS_KUBECTL_CUSTOM_COMMAND_DESCRIPTION__$C 2>/dev/null)" - done + echo "$(utils.colors.print green ${C})^$(SCWRYPTS_KUBECTL_CUSTOM_COMMAND_DESCRIPTION__$C 2>/dev/null)" + done } | column -ts '^' )" @@ -61,18 +61,18 @@ _SCWRYPTS_KUBECTL_DRIVER() { utility. These functions leverage redis and scwrypts environments to allow quick selection of contexts and namespaces usable across all active shell instances. - + The scwrypts group 'kubectl' has simple selection executables for kubecontext and namespace, but also provides the library to enable enriched, use-case-sensitive setup of kubernetes context. All actions are scoped to the current SCWRYPTS_ENV - currently : \\033[0;33m$SCWRYPTS_ENV\\033[0m - + currently : $(utils.colors.print yellow ${SCWRYPTS_ENV}) + " ########################################## - + local USER_ARGS=() local CUSTOM_COMMAND=0 @@ -134,9 +134,9 @@ _SCWRYPTS_KUBECTL_DRIVER() { while [[ $# -gt 0 ]]; do USER_ARGS+=($1); shift 1; done - CHECK_ERRORS --no-fail || return 1 + utils.check-errors || return 1 - [[ $HELP -eq 1 ]] && { USAGE; return 0; } + [[ $HELP -eq 1 ]] && { utils.io.usage; return 0; } ##################################################################### @@ -154,12 +154,12 @@ _SCWRYPTS_KUBECTL_DRIVER() { [ $CONTEXT ] && [[ $CLI =~ ^flux$ ]] && CLI_ARGS+=(--context $CONTEXT) [[ $STRICT -eq 1 ]] && { - [ $CONTEXT ] || ERROR "missing kubectl 'context'" - [ $NAMESPACE ] || ERROR "missing kubectl 'namespace'" + [ $CONTEXT ] || echo.error "missing kubectl 'context'" + [ $NAMESPACE ] || echo.error "missing kubectl 'namespace'" - CHECK_ERRORS --no-fail --no-usage || { - ERROR "with 'strict' settings enabled, context and namespace must be set!" - REMINDER " + utils.check-errors --no-fail --no-usage || { + echo.error "with 'strict' settings enabled, context and namespace must be set!" + echo.reminder " these values can be set directly with $(echo $CLI | head -c1) meta set (namespace|context) " @@ -170,16 +170,16 @@ _SCWRYPTS_KUBECTL_DRIVER() { [ $NAMESPACE ] && CLI_ARGS+=(--namespace $NAMESPACE) [[ $VERBOSE -eq 1 ]] && { - REMINDER " + echo.reminder " context '$CONTEXT' namespace '$NAMESPACE' environment '$SCWRYPTS_ENV' subsession '$SUBSESSION' " - STATUS "running $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}" + echo.status "running $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}" } || { [[ $(_SCWRYPTS_KUBECTL_SETTINGS get context) =~ ^show$ ]] && { - REMINDER "$SCWRYPTS_ENV.$SUBSESSION : $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}" + echo.reminder "$SCWRYPTS_ENV.$SUBSESSION : $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}" } } $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]} @@ -190,7 +190,7 @@ _SCWRYPTS_KUBECTL_DRIVER() { _SCWRYPTS_KUBECTL_SETTINGS() { # (get setting-name) or (set setting-name setting-value) - REDIS h$1 ${SCWRYPTS_ENV}:kubectl:settings ${@:2} | grep . + kube.redis h$1 ${SCWRYPTS_ENV}:kubectl:settings ${@:2} | grep . } ##################################################################### diff --git a/plugins/kubectl/driver/meta.zsh b/plugins/kube/driver/meta.zsh similarity index 54% rename from plugins/kubectl/driver/meta.zsh rename to plugins/kube/driver/meta.zsh index 9b0c021..7f7115d 100644 --- a/plugins/kubectl/driver/meta.zsh +++ b/plugins/kube/driver/meta.zsh @@ -23,16 +23,16 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__meta() { while [[ $# -gt 0 ]] do case $1 in - -h | --help ) HELP=1 ;; + ( -h | --help ) HELP=1 ;; - set ) + ( set ) USAGE__usage+=" set" USAGE__args="set (namespace|context)" USAGE__description="interactively set a namespace or context for '$SCWRYPTS_ENV'" case $2 in - namespace | context ) USER_ARGS+=($1 $2 $3); [ $3 ] && shift 1 ;; - -h | --help ) HELP=1 ;; - '' ) + ( namespace | context ) USER_ARGS+=($1 $2 $3); [ $3 ] && shift 1 ;; + ( -h | --help ) HELP=1 ;; + ( '' ) : \ && SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta set context \ && SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta set namespace \ @@ -40,40 +40,40 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__meta() { return $? ;; - * ) ERROR "cannot set '$2'" ;; + ( * ) echo.error "cannot set '$2'" ;; esac shift 1 ;; - get ) + ( get ) USAGE__usage+=" get" USAGE__args="get (namespace|context|all)" USAGE__description="output the current namespace or context for '$SCWRYPTS_ENV'" case $2 in - namespace | context | all ) USER_ARGS+=($1 $2) ;; + ( namespace | context | all ) USER_ARGS+=($1 $2) ;; - -h | --help ) HELP=1 ;; + ( -h | --help ) HELP=1 ;; - * ) ERROR "cannot get '$2'" ;; + ( * ) echo.error "cannot get '$2'" ;; esac shift 1 ;; - copy ) + ( copy ) USAGE__usage+=" copy" USAGE__args+="copy [0-9]" USAGE__description="copy current subsession ($SUBSESSION) to target subsession id" case $2 in - [0-9] ) USER_ARGS+=($1 $2) ;; - -h | --help ) HELP=1 ;; - * ) ERROR "target session must be a number [0-9]" ;; + ( [0-9] ) USER_ARGS+=($1 $2) ;; + ( -h | --help ) HELP=1 ;; + ( * ) echo.error "target session must be a number [0-9]" ;; esac shift 1 ;; - clear | show | hide | strict | loose ) USER_ARGS+=($1) ;; + ( clear | show | hide | strict | loose ) USER_ARGS+=($1) ;; - * ) ERROR "no meta command '$1'" + ( * ) echo.error "no meta command '$1'" esac shift 1 done @@ -81,10 +81,10 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__meta() { SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta() { case $1 in - get ) + ( get ) [[ $2 =~ ^all$ ]] && { - local CONTEXT=$(REDIS get --prefix current:context | grep . || echo "\\033[1;31mnone set\\033[0m") - local NAMESPACE=$(REDIS get --prefix current:namespace | grep . || echo "\\033[1;31mnone set\\033[0m") + local CONTEXT=$(kube.redis get --prefix current:context | grep . || utils.colors.print bright-red "none set") + local NAMESPACE=$(kube.redis get --prefix current:namespace | grep . || utils.colors.print bright-red "none set") echo " environment : $SCWRYPTS_ENV context : $CONTEXT @@ -92,51 +92,53 @@ SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta() { CLI settings command context : $(_SCWRYPTS_KUBECTL_SETTINGS get context) - strict mode : $([[ $STRICT -eq 1 ]] && echo "on" || echo "\\033[1;31moff\\033[0m") + strict mode : $([[ $STRICT -eq 1 ]] && utils.colors.print green on || utils.colors.print bright-red off) " | sed 's/^ \+//' >&2 return 0 } - REDIS get --prefix current:$2 + kube.redis get --prefix current:$2 ;; - set ) - scwrypts -n --name set-$2 --type zsh --group kubectl -- $3 --subsession $SUBSESSION >/dev/null \ - && SUCCESS "$2 set" - ;; - - copy ) + ( set ) : \ - && STATUS "copying $1 to $2" \ - && scwrypts -n --name set-context --type zsh --group kubectl -- --subsession $2 $(k meta get context | grep . || echo 'reset') \ - && scwrypts -n --name set-namespace --type zsh --group kubectl -- --subsession $2 $(k meta get namespace | grep . || echo 'reset') \ - && SUCCESS "subsession $1 copied to $2" \ + && scwrypts -n --name set-$2 --type zsh --group kube -- $3 --subsession $SUBSESSION >/dev/null \ + && k $SUBSESSION meta get $2 \ ; ;; - clear ) - scwrypts -n --name set-context --type zsh --group kubectl -- --subsession $SUBSESSION reset >/dev/null \ - && SUCCESS "subsession $SUBSESSION reset to default" + ( copy ) + : \ + && echo.status "copying $1 to $2" \ + && scwrypts -n --name set-context --type zsh --group kube -- --subsession $2 $(k $1 meta get context | grep . || echo 'reset') \ + && scwrypts -n --name set-namespace --type zsh --group kube -- --subsession $2 $(k $1 meta get namespace | grep . || echo 'reset') \ + && echo.success "subsession $1 copied to $2" \ + ; ;; - show ) + ( clear ) + scwrypts -n --name set-context --type zsh --group kube -- --subsession $SUBSESSION reset >/dev/null \ + && echo.success "subsession $SUBSESSION reset to default" + ;; + + ( show ) _SCWRYPTS_KUBECTL_SETTINGS set context show >/dev/null \ - && SUCCESS "now showing full command context" + && echo.success "now showing full command context" ;; - hide ) + ( hide ) _SCWRYPTS_KUBECTL_SETTINGS set context hide >/dev/null \ - && SUCCESS "now hiding command context" + && echo.success "now hiding command context" ;; - loose ) + ( loose ) _SCWRYPTS_KUBECTL_SETTINGS set strict 0 >/dev/null \ - && WARNING "now running in 'loose' mode" + && echo.warning "now running in 'loose' mode" ;; - strict ) + ( strict ) _SCWRYPTS_KUBECTL_SETTINGS set strict 1 >/dev/null \ - && SUCCESS "now running in 'strict' mode" + && echo.success "now running in 'strict' mode" ;; esac } diff --git a/plugins/kubectl/get-context b/plugins/kube/get-context similarity index 53% rename from plugins/kubectl/get-context rename to plugins/kube/get-context index d484c13..749b811 100755 --- a/plugins/kubectl/get-context +++ b/plugins/kube/get-context @@ -1,7 +1,7 @@ -#!/bin/zsh -use kubectl --group kubectl +#!/usr/bin/env zsh +use kubectl --group kube ##################################################################### MAIN() { - KUBECTL__GET_CONTEXT + kube.kubectl.context.get } diff --git a/plugins/kubectl/get-namespace b/plugins/kube/get-namespace similarity index 53% rename from plugins/kubectl/get-namespace rename to plugins/kube/get-namespace index 87293c0..206d536 100755 --- a/plugins/kubectl/get-namespace +++ b/plugins/kube/get-namespace @@ -1,7 +1,7 @@ -#!/bin/zsh -use kubectl --group kubectl +#!/usr/bin/env zsh +use kubectl --group kube ##################################################################### MAIN() { - KUBECTL__GET_NAMESPACE + kube.kubectl.namespace.get } diff --git a/plugins/kube/kube.scwrypts.zsh b/plugins/kube/kube.scwrypts.zsh new file mode 100644 index 0000000..e09e1c1 --- /dev/null +++ b/plugins/kube/kube.scwrypts.zsh @@ -0,0 +1,10 @@ +export ${scwryptsgroup}__type=zsh +export ${scwryptsgroup}__color=$(utils.colors.red) + +##################################################################### + +SCWRYPTS_STATIC_CONFIG__kubectl+=( + "${scwryptsgrouproot}/.config/static/redis.zsh" +) + +source "${scwryptsgrouproot}/driver/kubectl.driver.zsh" diff --git a/plugins/kube/kubectl/cli.module.zsh b/plugins/kube/kubectl/cli.module.zsh new file mode 100644 index 0000000..edf2a94 --- /dev/null +++ b/plugins/kube/kubectl/cli.module.zsh @@ -0,0 +1,18 @@ +##################################################################### + +DEPENDENCIES+=(kubectl) + +use redis --group kube + +##################################################################### + +kube.cli() { + local NAMESPACE="$(kube.redis get --prefix "current:namespace")" + local CONTEXT="$(kube.kubectl.context.get)" + + local ARGS=() + [ "${NAMESPACE}" ] && ARGS+=(--namespace "${NAMESPACE}") + [ "${CONTEXT}" ] && ARGS+=(--context "${CONTEXT}") + + kubectl ${ARGS[@]} $@ +} diff --git a/plugins/kube/kubectl/context.module.zsh b/plugins/kube/kubectl/context.module.zsh new file mode 100644 index 0000000..3de22c2 --- /dev/null +++ b/plugins/kube/kubectl/context.module.zsh @@ -0,0 +1,56 @@ +##################################################################### + +use --group kube kubectl/cli +use --group kube kubectl/namespace +use --group kube redis + +##################################################################### + +${scwryptsmodule}.get() { kube.redis get --prefix "current:context"; } + +${scwryptsmodule}.set() { + local CONTEXT=$1 + [ ! "${CONTEXT}" ] && return 1 + + [[ "${CONTEXT}" =~ reset ]] && { + : \ + && kube.redis del --prefix "current:context" \ + && kube.kubectl.namespace.set reset \ + ; + return $? + } + + : \ + && kube.redis set --prefix "current:context" "${CONTEXT}" \ + && kube.kubectl.namespace.set reset \ + ; +} + +${scwryptsmodule}.select() { + case "$(kube.kubectl.context.list | grep -v '^reset$' | wc -l)" in + ( 0 ) + echo.error "no contexts available" + return 1 + ;; + ( 1 ) + kube.kubectl.context.list | tail -n1 + ;; + ( * ) + kube.kubectl.context.list | utils.fzf 'select a context' + ;; + esac +} + +${scwryptsmodule}.list() { + echo reset + local ALL_CONTEXTS="$(kube.cli config get-contexts -o name | sort -u)" + + echo "${ALL_CONTEXTS}" | grep -v '^arn:aws:eks' + + [[ "${AWS_ACCOUNT}" ]] && { + echo "${ALL_CONTEXTS}" | grep "^arn:aws:eks:.*:${AWS_ACCOUNT}" + true + } || { + echo "${ALL_CONTEXTS}" | grep '^arn:aws:eks' + } +} diff --git a/plugins/kube/kubectl/kubectl.module.zsh b/plugins/kube/kubectl/kubectl.module.zsh new file mode 100644 index 0000000..13e9ba7 --- /dev/null +++ b/plugins/kube/kubectl/kubectl.module.zsh @@ -0,0 +1,17 @@ +# +# combines kubectl with redis to both facilitate use of kubectl +# between varying contexts/namespaces AND grant persistence between +# terminal sessions +# + +# redis wrapper for kubectl +use --group kube kubectl/cli + +# simplify commands for kubecontexts +use --group kube kubectl/context + +# simplify commands for namespaces +use --group kube kubectl/namespace + +# local redirect commands for remote kubernetes services +use --group kube kubectl/service diff --git a/plugins/kube/kubectl/namespace.module.zsh b/plugins/kube/kubectl/namespace.module.zsh new file mode 100644 index 0000000..e537e88 --- /dev/null +++ b/plugins/kube/kubectl/namespace.module.zsh @@ -0,0 +1,23 @@ +${scwryptsmodule}.get() { kube.redis get --prefix "current:namespace"; } + +${scwryptsmodule}.set() { + local NAMESPACE=$1 + [ ! "${NAMESPACE}" ] && return 1 + + [[ "${NAMESPACE}" =~ reset ]] && { + kube.redis del --prefix "current:namespace" + return $? + } + + kube.redis set --prefix "current:namespace" "${NAMESPACE}" +} + +${scwryptsmodule}.select() { + kube.kubectl.namespace.list | utils.fzf 'select a namespace' +} + +${scwryptsmodule}.list() { + echo reset + echo default + kube.cli get namespaces -o name | sed 's/^namespace\///' | sort | grep -v '^default$' +} diff --git a/plugins/kube/kubectl/service.module.zsh b/plugins/kube/kubectl/service.module.zsh new file mode 100644 index 0000000..e4a7e7a --- /dev/null +++ b/plugins/kube/kubectl/service.module.zsh @@ -0,0 +1,77 @@ +##################################################################### + +use --group kube kubectl/cli +use --group kube kubectl/context +use --group kube kubectl/namespace + +##################################################################### + +${scwryptsmodule}.serve() { + [ "${CONTEXT}" ] || local CONTEXT="$(kube.kubectl.context.get)" + [ "${CONTEXT}" ] || echo.error 'must configure a context in which to serve' + + [ "${NAMESPACE}" ] || local NAMESPACE="$(kube.kubectl.namespace.get)" + [ "${NAMESPACE}" ] || echo.error 'must configure a namespace in which to serve' + + utils.check-errors --no-usage || return 1 + + [ "${SERVICE}" ] && SERVICE="$(kube.kubectl.service.list | jq -c "select (.service == \"${SERVICE}\")" || echo ${SERVICE})" + [ "${SERVICE}" ] || local SERVICE="$(kube.kubectl.service.select)" + [ "${SERVICE}" ] || echo.error 'must provide or select a service' + + kube.kubectl.service.list | grep -q "^${SERVICE}$"\ + || echo.error "no service '${SERVICE}' in '${CONFIG}/${NAMESPACE}'" + + utils.check-errors --no-usage || return 1 + + ########################################## + + SERVICE_PASSWORD="$(kube.kubectl.service.get-password)" + kube.kubectl.service.parse + + echo.reminder "attempting to serve ${NAMESPACE}/${SERVICE_NAME}:${SERVICE_PORT}" + [ "${SERVICE_PASSWORD}" ] && echo.reminder "password : ${SERVICE_PASSWORD}" + + kube.cli port-forward "service/${SERVICE_NAME}" "${SERVICE_PORT}" +} + +##################################################################### + +${scwryptsmodule}.select() { + [ "${NAMESPACE}" ] || local NAMESPACE="$(kube.kubectl.namespace.get)" + [ "${NAMESPACE}" ] || return 1 + + local SERVICES="$(kube.kubectl.service.list)" + local SELECTED="$({ + echo "namespace service port" + echo ${SERVICES} \ + | jq -r '.service + " " + .port' \ + | sed "s/^/${NAMESPACE} /" \ + ; + } \ + | column -t \ + | utils.fzf 'select a service' --header-lines=1 \ + | awk '{print $2;}' \ + )" + + echo "${SERVICES}" | jq -c "select (.service == \"${SELECTED}\")" +} + +${scwryptsmodule}.list() { + kube.cli get service --no-headers\ + | awk '{print "{\"service\":\""$1"\",\"ip\":\""$3"\",\"port\":\""$5"\"}"}' \ + | jq -c 'select (.ip != "None")' \ + ; +} + +${scwryptsmodule}.get-password() { + [ "${PASSWORD_SECRET}" ] && [ "${PASSWORD_KEY}" ] || return 0 + + kube.cli get secret "${PASSWORD_SECRET}" -o jsonpath="{.data.${PASSWORD_KEY}}" \ + | base64 --decode +} + +${scwryptsmodule}.parse() { + SERVICE_NAME="$(echo "${SERVICE}" | jq -r .service)" + SERVICE_PORT="$(echo "${SERVICE}" | jq -r .port | sed 's|/.*$||')" +} diff --git a/plugins/kube/meta/get-static-redis-definition b/plugins/kube/meta/get-static-redis-definition new file mode 100755 index 0000000..9924293 --- /dev/null +++ b/plugins/kube/meta/get-static-redis-definition @@ -0,0 +1,7 @@ +#!/usr/bin/env zsh +use redis --group kube +##################################################################### + +MAIN() { + echo $(kube.redis --get-static-definition) +} diff --git a/plugins/kubectl/lib/redis.module.zsh b/plugins/kube/redis/redis.module.zsh similarity index 69% rename from plugins/kubectl/lib/redis.module.zsh rename to plugins/kube/redis/redis.module.zsh index cda2ae7..4d0c385 100644 --- a/plugins/kubectl/lib/redis.module.zsh +++ b/plugins/kube/redis/redis.module.zsh @@ -5,16 +5,13 @@ DEPENDENCIES+=( docker ) -# TODO; allow custom redis configuration -export SCWRYPTS_KUBECTL_REDIS=managed +REQUIRED_ENV+=() -REQUIRED_ENV+=( - SCWRYPTS_KUBECTL_REDIS -) +utils.environment.check SCWRYPTS_KUBECTL_REDIS --default managed ##################################################################### -REDIS() { +kube.redis() { [ ! $USAGE ] && local USAGE=" usage: [...options...] @@ -24,7 +21,7 @@ REDIS() { -p, --prefix apply dynamic prefix to the next command line argument --get-prefix output key prefix for current session+subsession - --get-static-definition output the static ZSH function definition for REDIS + --get-static-definition output the static ZSH function definition for kube.redis additional arguments and options are passed through to 'redis-cli' " @@ -38,15 +35,15 @@ REDIS() { while [[ $# -gt 0 ]] do - case $1 in - -p | --prefix ) USER_ARGS+=("${REDIS_PREFIX}${SCWRYPTS_ENV}:${SUBSESSION}:$2"); shift 1 ;; + case $1 in + ( -p | --prefix ) USER_ARGS+=("${REDIS_PREFIX}${SCWRYPTS_ENV}:${SUBSESSION}:$2"); shift 1 ;; - --subsession ) SUBSESSION=$2; shift 1 ;; + ( --subsession ) SUBSESSION=$2; shift 1 ;; - --get-prefix ) echo $REDIS_PREFIX; return 0 ;; - --get-static-definition ) ECHO_STATIC_DEFINITION=1 ;; + ( --get-prefix ) echo $REDIS_PREFIX; return 0 ;; + ( --get-static-definition ) ECHO_STATIC_DEFINITION=1 ;; - * ) USER_ARGS+=($1) ;; + ( * ) USER_ARGS+=($1) ;; esac shift 1 done @@ -62,14 +59,14 @@ REDIS() { REDIS_ARGS+=(--raw) [[ $ECHO_STATIC_DEFINITION -eq 1 ]] && { - echo "REDIS() {\ + echo "kube.redis() {\ local USER_ARGS=(); \ [ ! \$SUBSESSION ] && local SUBSESSION=0 ;\ while [[ \$# -gt 0 ]]; \ do \ case \$1 in - -p | --prefix ) USER_ARGS+=(\"${REDIS_PREFIX}\${SCWRYPTS_ENV}:\${SUBSESSION}:\$2\"); shift 1 ;; \ - * ) USER_ARGS+=(\$1) ;; \ + ( -p | --prefix ) USER_ARGS+=(\"${REDIS_PREFIX}\${SCWRYPTS_ENV}:\${SUBSESSION}:\$2\"); shift 1 ;; \ + ( * ) USER_ARGS+=(\$1) ;; \ esac; \ shift 1; \ done; \ @@ -81,9 +78,9 @@ REDIS() { redis-cli ${REDIS_ARGS[@]} ${USER_ARGS[@]} } -REDIS ping | grep -qi pong || { +kube.redis ping 2>/dev/null | grep -qi pong || { RPID=$(docker ps -a | grep scwrypts-kubectl-redis | awk '{print $1;}') - [ $RPID ] && STATUS 'refreshing redis instance' && docker rm -f $RPID + [ $RPID ] && echo.status 'refreshing redis instance' && docker rm -f $RPID unset RPID docker run \ @@ -92,6 +89,6 @@ REDIS ping | grep -qi pong || { --publish $SCWRYPTS_KUBECTL_REDIS_PORT__managed:6379 \ redis >/dev/null 2>&1 - STATUS 'awaiting redis connection' - until REDIS ping 2>/dev/null | grep -qi pong; do sleep 0.5; done + echo.status 'awaiting redis connection' + until kube.redis ping 2>/dev/null | grep -qi pong; do sleep 0.5; done } diff --git a/plugins/kubectl/serve b/plugins/kube/serve similarity index 77% rename from plugins/kubectl/serve rename to plugins/kube/serve index 1dadfcf..6725ffd 100755 --- a/plugins/kubectl/serve +++ b/plugins/kube/serve @@ -1,5 +1,5 @@ -#!/bin/zsh -use kubectl --group kubectl +#!/usr/bin/env zsh +use kubectl --group kube ##################################################################### MAIN() { @@ -12,7 +12,7 @@ MAIN() { options: --context override context --namespace override namespace - --subsession REDIS subsession (default 0) + --subsession kube.redis subsession (default 0) to show a required password on screen, use both: --password-secret Secret resource @@ -33,17 +33,17 @@ MAIN() { --password-secret ) PASSWORD_SECRET=$2; shift 1 ;; --password-key ) PASSWORD_KEY=$2; shift 1 ;; - -h | --help ) USAGE; return 0 ;; + -h | --help ) utils.io.usage; return 0 ;; * ) - [ $SERVICE ] && ERROR "unexpected argument '$2'" + [ $SERVICE ] && echo.error "unexpected argument '$2'" SERVICE=$1 ;; esac shift 1 done - CHECK_ERRORS + utils.check-errors --fail - KUBECTL__SERVE + kube.kubectl.serve } diff --git a/plugins/kubectl/set-context b/plugins/kube/set-context similarity index 56% rename from plugins/kubectl/set-context rename to plugins/kube/set-context index c68523d..7cbfdff 100755 --- a/plugins/kubectl/set-context +++ b/plugins/kube/set-context @@ -1,5 +1,5 @@ -#!/bin/zsh -use kubectl --group kubectl +#!/usr/bin/env zsh +use kubectl --group kube ##################################################################### MAIN() { @@ -10,7 +10,7 @@ MAIN() { context (optional) the full name of the kubeconfig context to set options: - --subsession REDIS subsession (default 0) + --subsession kube.redis subsession (default 0) -h, --help show this dialogue and exit " @@ -22,20 +22,18 @@ MAIN() { case $1 in --subsession ) SUBSESSION=$2; shift 1 ;; - -h | --help ) USAGE; return 0 ;; - * ) - [ $CONTEXT ] && ERROR "unexpected argument '$2'" + [ $CONTEXT ] && echo.error "unexpected argument '$2'" CONTEXT=$1 ;; esac shift 1 done - [ $CONTEXT ] || CONTEXT=$(KUBECTL__SELECT_CONTEXT) - [ $CONTEXT ] || ERROR 'must provide or select a valid kube context' + [ $CONTEXT ] || CONTEXT=$(kube.kubectl.context.select) + [ $CONTEXT ] || echo.error 'must provide or select a valid kube context' - CHECK_ERRORS + utils.check-errors --fail - KUBECTL__SET_CONTEXT $CONTEXT + kube.kubectl.context.set $CONTEXT } diff --git a/plugins/kubectl/set-namespace b/plugins/kube/set-namespace similarity index 52% rename from plugins/kubectl/set-namespace rename to plugins/kube/set-namespace index 470fb42..5afade4 100755 --- a/plugins/kubectl/set-namespace +++ b/plugins/kube/set-namespace @@ -1,5 +1,5 @@ -#!/bin/zsh -use kubectl --group kubectl +#!/usr/bin/env zsh +use kubectl --group kube ##################################################################### MAIN() { @@ -10,7 +10,7 @@ MAIN() { namespace (optional) the full name of the namespace context to set options: - --subsession REDIS subsession (default 0) + --subsession kube.redis subsession (default 0) -h, --help show this dialogue and exit " @@ -22,20 +22,20 @@ MAIN() { case $1 in --subsession ) SUBSESSION=$2; shift 1 ;; - -h | --help ) USAGE; return 0 ;; + -h | --help ) utils.io.usage; return 0 ;; * ) - [ $NAMESPACE ] && ERROR "unexpected argument '$2'" + [ $NAMESPACE ] && echo.error "unexpected argument '$2'" NAMESPACE=$1 ;; esac shift 1 done - [ $NAMESPACE ] || NAMESPACE=$(KUBECTL__SELECT_NAMESPACE) - [ $NAMESPACE ] || ERROR 'must provide or select a valid namespace' + [ $NAMESPACE ] || NAMESPACE=$(kube.kubectl.namespace.select) + [ $NAMESPACE ] || echo.error 'must provide or select a valid namespace' - CHECK_ERRORS + utils.check-errors --fail - KUBECTL__SET_NAMESPACE $NAMESPACE + kube.kubectl.namespace.set $NAMESPACE } diff --git a/plugins/kubectl/kubectl.scwrypts.zsh b/plugins/kubectl/kubectl.scwrypts.zsh deleted file mode 100644 index 4b28a00..0000000 --- a/plugins/kubectl/kubectl.scwrypts.zsh +++ /dev/null @@ -1,11 +0,0 @@ -SCWRYPTS_GROUPS+=(kubectl) - -export SCWRYPTS_TYPE__kubectl=zsh -export SCWRYPTS_ROOT__kubectl="$SCWRYPTS_ROOT__scwrypts/plugins/kubectl" -export SCWRYPTS_COLOR__kubectl='\033[0;31m' - -SCWRYPTS_STATIC_CONFIG__kubectl+=( - "$SCWRYPTS_ROOT__kubectl/.config/static/redis.zsh" -) - -source "$SCWRYPTS_ROOT__kubectl/driver/kubectl.driver.zsh" diff --git a/plugins/kubectl/lib/kubectl.module.zsh b/plugins/kubectl/lib/kubectl.module.zsh deleted file mode 100644 index b47d2ae..0000000 --- a/plugins/kubectl/lib/kubectl.module.zsh +++ /dev/null @@ -1,158 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - kubectl -) - -REQUIRED_ENV+=() - -use redis --group kubectl - -##################################################################### - -KUBECTL() { - local NAMESPACE=$(REDIS get --prefix "current:namespace") - local CONTEXT=$(KUBECTL__GET_CONTEXT) - - local KUBECTL_ARGS=() - [ $NAMESPACE ] && KUBECTL_ARGS+=(--namespace $NAMESPACE) - [ $CONTEXT ] && KUBECTL_ARGS+=(--context $CONTEXT) - - kubectl ${KUBECTL_ARGS[@]} $@ -} - -##################################################################### - -KUBECTL__GET_CONTEXT() { REDIS get --prefix "current:context"; } - -KUBECTL__SET_CONTEXT() { - local CONTEXT=$1 - [ ! $CONTEXT ] && return 1 - - [[ $CONTEXT =~ reset ]] && { - : \ - && REDIS del --prefix "current:context" \ - && KUBECTL__SET_NAMESPACE reset \ - ; - return $? - } - - : \ - && REDIS set --prefix "current:context" "$CONTEXT" \ - && KUBECTL__SET_NAMESPACE reset \ - ; -} - -KUBECTL__SELECT_CONTEXT() { - KUBECTL__LIST_CONTEXTS | FZF 'select a context' -} - -KUBECTL__LIST_CONTEXTS() { - echo reset - local ALL_CONTEXTS=$(KUBECTL config get-contexts -o name | sort) - - echo $ALL_CONTEXTS | grep -v '^arn:aws:eks' - - [[ $AWS_ACCOUNT ]] && { - echo $ALL_CONTEXTS | grep "^arn:aws:eks:.*:$AWS_ACCOUNT" - true - } || { - echo $ALL_CONTEXTS | grep '^arn:aws:eks' - } -} - -##################################################################### - -KUBECTL__GET_NAMESPACE() { REDIS get --prefix "current:namespace"; } - -KUBECTL__SET_NAMESPACE() { - local NAMESPACE=$1 - [ ! $NAMESPACE ] && return 1 - - [[ $NAMESPACE =~ reset ]] && { - REDIS del --prefix "current:namespace" - return $? - } - - REDIS set --prefix "current:namespace" "$NAMESPACE" -} - -KUBECTL__SELECT_NAMESPACE() { - KUBECTL__LIST_NAMESPACES | FZF 'select a namespace' -} - -KUBECTL__LIST_NAMESPACES() { - echo reset - echo default - KUBECTL get namespaces -o name | sed 's/^namespace\///' | sort -} - -##################################################################### - -KUBECTL__SERVE() { - [ $CONTEXT ] || local CONTEXT=$(KUBECTL__GET_CONTEXT) - [ $CONTEXT ] || ERROR 'must configure a context in which to serve' - - [ $NAMESPACE ] || local NAMESPACE=$(KUBECTL__GET_NAMESPACE) - [ $NAMESPACE ] || ERROR 'must configure a namespace in which to serve' - - CHECK_ERRORS --no-fail --no-usage || return 1 - - [ $SERVICE ] && SERVICE=$(KUBECTL__LIST_SERVICES | jq -c "select (.service == \"$SERVICE\")" || echo $SERVICE) - [ $SERVICE ] || local SERVICE=$(KUBECTL__SELECT_SERVICE) - [ $SERVICE ] || ERROR 'must provide or select a service' - - KUBECTL__LIST_SERVICES | grep -q "^$SERVICE$"\ - || ERROR "no service '$SERVICE' in '$CONFIG/$NAMESPACE'" - - CHECK_ERRORS --no-fail --no-usage || return 1 - - ########################################## - - SERVICE_PASSWORD="$(KUBECTL__GET_SERVICE_PASSWORD)" - KUBECTL__SERVICE_PARSE - - REMINDER "attempting to serve ${NAMESPACE}/${SERVICE_NAME}:${SERVICE_PORT}" - [ $SERVICE_PASSWORD ] && REMINDER "password : $SERVICE_PASSWORD" - - KUBECTL port-forward service/$SERVICE_NAME $SERVICE_PORT -} - -KUBECTL__SELECT_SERVICE() { - [ $NAMESPACE ] || local NAMESPACE=$(KUBECTL__GET_NAMESPACE) - [ $NAMESPACE ] || return 1 - - local SERVICES=$(KUBECTL__LIST_SERVICES) - local SELECTED=$({ - echo "namespace service port" - echo $SERVICES \ - | jq -r '.service + " " + .port' \ - | sed "s/^/$NAMESPACE /" \ - ; - } \ - | column -t \ - | FZF 'select a service' --header-lines=1 \ - | awk '{print $2;}' \ - ) - - echo $SERVICES | jq -c "select (.service == \"$SELECTED\")" -} - -KUBECTL__LIST_SERVICES() { - KUBECTL get service --no-headers\ - | awk '{print "{\"service\":\""$1"\",\"ip\":\""$3"\",\"port\":\""$5"\"}"}' \ - | jq -c 'select (.ip != "None")' \ - ; -} - -KUBECTL__GET_SERVICE_PASSWORD() { - [ $PASSWORD_SECRET ] && [ $PASSWORD_KEY ] || return 0 - - KUBECTL get secret $PASSWORD_SECRET -o jsonpath="{.data.$PASSWORD_KEY}" \ - | base64 --decode -} - -KUBECTL__SERVICE_PARSE() { - SERVICE_NAME=$(echo $SERVICE | jq -r .service) - SERVICE_PORT=$(echo $SERVICE | jq -r .port | sed 's|/.*$||') -} diff --git a/plugins/kubectl/meta/get-static-redis-definition b/plugins/kubectl/meta/get-static-redis-definition deleted file mode 100755 index 3df971b..0000000 --- a/plugins/kubectl/meta/get-static-redis-definition +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use redis --group kubectl -##################################################################### - -MAIN() { - echo $(REDIS --get-static-definition) -} diff --git a/py/lib/scwrypts/env.py b/py/lib/scwrypts/env.py index b4715ac..426bd3f 100644 --- a/py/lib/scwrypts/env.py +++ b/py/lib/scwrypts/env.py @@ -1,10 +1,27 @@ -from os import getenv as os_getenv +from json import loads + +from .scwrypts import scwrypts from .scwrypts.exceptions import MissingVariableError +ENV = {} -def getenv(name, required=True): - value = os_getenv(f'{name}__override', os_getenv(name)) +def getenv(name, required=True, default=None): + if ENV.get('configuration') is None or ENV.get('environment') is None: + full_environment = loads( + scwrypts( + name = 'scwrypts/environment/getenv', + group = 'scwrypts', + _type = 'zsh', + executable_args = '-n', + args = '--all', + ).stdout + ) + + ENV['configuration'] = full_environment['configuration'] + ENV['environment'] = full_environment['environment'] + + value = ENV.get('environment', {}).get(name, default) if required and not value: raise MissingVariableError(name) diff --git a/py/lib/scwrypts/http/discord/test_client.py b/py/lib/scwrypts/http/discord/test_client.py index f748f33..e9f64d1 100644 --- a/py/lib/scwrypts/http/discord/test_client.py +++ b/py/lib/scwrypts/http/discord/test_client.py @@ -5,7 +5,7 @@ from pytest import fixture from .client import request -def test_discord_request(sample, _response): +def test_discord_request(sample, _mock_getenv, _response): assert _response == sample.response def test_discord_request_client_setup(sample, mock_get_request_client, _mock_getenv, _response): @@ -41,7 +41,7 @@ def fixture_mock_get_request_client(sample): @fixture(name='_mock_getenv') def fixture_mock_getenv(sample): - with patch('scwrypts.http.discord.client.getenv',) as mock: + with patch('scwrypts.http.discord.client.getenv') as mock: mock.side_effect = lambda name, **kwargs: { 'DISCORD__BOT_TOKEN': sample.bot_token, }[name] @@ -49,6 +49,6 @@ def fixture_mock_getenv(sample): @fixture(name='_mock_getenv_optional') def fixture_mock_getenv_optional(): - with patch('scwrypts.http.discord.client.getenv',) as mock: + with patch('scwrypts.http.discord.client.getenv') as mock: mock.side_effect = lambda name, **kwargs: None yield mock diff --git a/py/lib/scwrypts/test/generate.py b/py/lib/scwrypts/test/generate.py index 5f6e5cb..0460e93 100644 --- a/py/lib/scwrypts/test/generate.py +++ b/py/lib/scwrypts/test/generate.py @@ -4,9 +4,11 @@ from json import dumps, loads from random import randint, uniform, choice from re import sub from string import printable -from typing import Hashable, Callable +from typing import Callable from uuid import uuid4 +from collections.abc import Hashable + from requests import Response, status_codes from yaml import safe_dump diff --git a/scwrypts b/scwrypts index 8840e3d..59215dd 100755 --- a/scwrypts +++ b/scwrypts @@ -1,12 +1,16 @@ -#!/bin/zsh +#!/usr/bin/env zsh export EXECUTION_DIR=$(pwd) export SCWRYPTS_RUNTIME_ID=$(uuidgen) -source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 +source "$(dirname -- $(readlink -f -- "$0"))/zsh/import.driver.zsh" || return 42 + +use scwrypts/environment +use scwrypts/list-available +use scwrypts/get-runstring + ##################################################################### () { - cd "$SCWRYPTS_ROOT__scwrypts" - GIT_SCWRYPTS() { git -C "$SCWRYPTS_ROOT__scwrypts" $@; } - + cd "$(scwrypts.config.group scwrypts root)" + GIT_SCWRYPTS() { git -C "$(scwrypts.config.group scwrypts root)" $@; } local ERRORS=0 local USAGE=' @@ -39,7 +43,7 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 --list-envs print out environment list and exit --list-groups print out configured scwrypts groups and exit --config "eval"-ed to enable config and "use" import in non-scwrypts environments - --root print out SCWRYPTS_ROOT__scwrypts and exit + --root print out scwrypts.config.group.scwrypts.root and exit --update update scwrypts library to latest version --version print out scwrypts version and exit @@ -55,76 +59,76 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 ### cli argument parsing and global configuration ################### ##################################################################### - local ENV_NAME="$SCWRYPTS_ENV" + local ENV_NAME="${SCWRYPTS_ENV}" local SEARCH_PATTERNS=() local VARSPLIT SEARCH_GROUP SEARCH_TYPE SEARCH_NAME - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=3 + [ ! ${SCWRYPTS_LOG_LEVEL} ] && local SCWRYPTS_LOG_LEVEL=3 local SHIFT_COUNT while [[ $# -gt 0 ]] do SHIFT_COUNT=1 case $1 in - -[a-z][a-z]* ) + ( -[a-z][a-z]* ) VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/') - set -- throw-away $(echo " $VARSPLIT ") ${@:2} + set -- throw-away $(echo " ${VARSPLIT} ") ${@:2} ;; ### alternate commands ################### - -h | --help ) - USAGE + ( -h | --help ) + utils.io.usage return 0 ;; - -l | --list ) - SCWRYPTS__GET_AVAILABLE_SCWRYPTS + ( -l | --list ) + scwrypts.list-available return 0 ;; - --list-envs ) - SCWRYPTS__GET_ENV_NAMES + ( --list-envs ) + scwrypts.environment.common.get-env-names return 0 ;; - --list-groups ) + ( --list-groups ) echo "${SCWRYPTS_GROUPS[@]}" | sed 's/\s\+/\n/g' | sort -u return 0 ;; - --version ) - case $SCWRYPTS_INSTALLATION_TYPE in - manual ) echo "scwrypts $(GIT_SCWRYPTS describe --tags) (via GIT)" ;; - * ) echo "scwrypts $(cat "$SCWRYPTS_ROOT__scwrypts/VERSION")" ;; + ( --version ) + case ${SCWRYPTS_INSTALLATION_TYPE} in + ( manual ) echo "scwrypts $(GIT_SCWRYPTS describe --tags) (via GIT)" ;; + ( * ) echo "scwrypts $(cat "$(scwrypts.config.group scwrypts root)/VERSION")" ;; esac return 0 ;; - --root ) - echo "$SCWRYPTS_ROOT__scwrypts" + ( --root ) + scwrypts.config.group scwrypts root return 0 ;; - --config ) - echo "source '$SCWRYPTS_ROOT__scwrypts/zsh/lib/import.driver.zsh'" - echo "CHECK_ENVIRONMENT --no-fail --no-usage" + ( --config ) + echo "source '$(scwrypts.config.group scwrypts root)/zsh/import.driver.zsh'" + echo "utils.check-environment --no-fail --no-usage" echo "unset __SCWRYPT" return 0 ;; - --update ) - case $SCWRYPTS_INSTALLATION_TYPE in + ( --update ) + case ${SCWRYPTS_INSTALLATION_TYPE} in aur ) - SCWRYPTS_LOG_LEVEL=3 REMINDER " + echo.reminder --force-print " This installation is built from the AUR. Update through 'makepkg' or use your preferred AUR package management tool (e.g. 'yay -Syu scwrypts') " ;; homebrew ) - SCWRYPTS_LOG_LEVEL=3 REMINDER "This installation is managed by homebrew. Update me with 'brew update'" + echo.reminder --force-print "This installation is managed by homebrew. Update me with 'brew update'" ;; manual ) @@ -135,22 +139,22 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 local DIFF_STATUS=$? - [[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && { - SUCCESS 'already up-to-date with origin/main' + [[ ${SYNC_STATUS} -eq 0 ]] && [[ ${DIFF_STATUS} -eq 0 ]] && { + echo.success 'already up-to-date with origin/main' } || { GIT_SCWRYPTS rebase --autostash origin/main \ - && SUCCESS 'up-to-date with origin/main' \ + && echo.success 'up-to-date with origin/main' \ && GIT_SCWRYPTS log -n1 \ || { GIT_SCWRYPTS rebase --abort - ERROR 'unable to update scwrypts; please try manual upgrade' - REMINDER "installation in '$SCWRYPTS_ROOT__scwrypts'" + echo.error 'unable to update scwrypts; please try manual upgrade' + echo.reminder "installation in '$(scwrypts.config.group scwrypts root)'" } } ;; * ) - SCWRYPTS_LOG_LEVEL=3 REMINDER " + echo.reminder --force-print " This is a managed installation of scwrypts. Please update through your system package manager. " @@ -161,228 +165,236 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 ### scwrypts filters ##################### - -m | --name ) + ( -m | --name ) ((SHIFT_COUNT+=1)) - [ $2 ] || { ERROR "missing value for argument $1"; break; } + [ $2 ] || { echo.error "missing value for argument $1"; break; } SEARCH_NAME=$2 ;; - -g | --group ) + ( -g | --group ) ((SHIFT_COUNT+=1)) - [ $2 ] || { ERROR "missing value for argument $1"; break; } + [ $2 ] || { echo.error "missing value for argument $1"; break; } SEARCH_GROUP=$2 GROUP=$2 ;; - -t | --type ) + ( -t | --type ) ((SHIFT_COUNT+=1)) - [ $2 ] || { ERROR "missing value for argument $1"; break; } + [ $2 ] || { echo.error "missing value for argument $1"; break; } SEARCH_TYPE=$2 TYPE=$2 ;; ### runtime settings ##################### - -y | --yes ) export __SCWRYPTS_YES=1 ;; + ( -y | --yes ) export __SCWRYPTS_YES=1 ;; - -n ) SCWRYPTS_LOG_LEVEL=0 ;; + ( -n ) SCWRYPTS_LOG_LEVEL=0 ;; - -v | --log-level ) + ( -v | --log-level ) ((SHIFT_COUNT+=1)) - [[ $2 =~ ^[0-4]$ ]] || ERROR "invalid setting for log-level '$2'" + [[ $2 =~ ^[0-4]$ ]] || echo.error "invalid setting for log-level '$2'" SCWRYPTS_LOG_LEVEL=$2 ;; - -o | --output ) + ( -o | --output ) ((SHIFT_COUNT+=1)) export SCWRYPTS_OUTPUT_FORMAT=$2 - case $SCWRYPTS_OUTPUT_FORMAT in - pretty | json ) ;; - * ) ERROR "unsupported format '$SCWRYPTS_OUTPUT_FORMAT'" ;; + case ${SCWRYPTS_OUTPUT_FORMAT} in + ( pretty | json ) ;; + * ) echo.error "unsupported format '${SCWRYPTS_OUTPUT_FORMAT}'" ;; esac ;; - -e | --env ) + ( -e | --env ) ((SHIFT_COUNT+=1)) - [ $2 ] || { ERROR "missing value for argument $1"; break; } + [ $2 ] || { echo.error "missing value for argument $1"; break; } - [ $ENV_NAME ] && DEBUG 'overwriting session environment' + [ ${ENV_NAME} ] && echo.debug 'overwriting session environment' ENV_NAME="$2" - STATUS "using CLI environment '$ENV_NAME'" + echo.status "using CLI environment '${ENV_NAME}'" ;; ########################################## - -- ) shift 1; break ;; # pass arguments after '--' to the scwrypt - --* ) ERROR "unrecognized argument '$1'" ;; - * ) SEARCH_PATTERNS+=($1) ;; + ( -- ) shift 1; break ;; # pass arguments after '--' to the scwrypt + ( --* ) echo.error "unrecognized argument '$1'" ;; + ( * ) SEARCH_PATTERNS+=($1) ;; esac - shift $SHIFT_COUNT + [[ ${SHIFT_COUNT} -le $# ]] \ + && shift ${SHIFT_COUNT} \ + || echo.error "missing argument for '$1'" \ + || shift $# \ + ; done - [ $SCWRYPTS_OUTPUT_FORMAT ] || export SCWRYPTS_OUTPUT_FORMAT=pretty + [ ${SCWRYPTS_OUTPUT_FORMAT} ] || export SCWRYPTS_OUTPUT_FORMAT=pretty - [ $SEARCH_NAME ] && { - [ $SEARCH_TYPE ] || ERROR '--name requires --type argument' - [ $SEARCH_GROUP ] || ERROR '--name requires --group argument' + [ ${SEARCH_NAME} ] && { + [ ${SEARCH_TYPE} ] || echo.error '--name requires --type argument' + [ ${SEARCH_GROUP} ] || echo.error '--name requires --group argument' } - CHECK_ERRORS + utils.check-errors --fail + ##################################################################### ### scwrypts selection / filtering ################################## ##################################################################### - local SCWRYPTS_AVAILABLE - SCWRYPTS_AVAILABLE=$(SCWRYPTS__GET_AVAILABLE_SCWRYPTS) + local SCWRYPTS_AVAILABLE=$(scwrypts.list-available) ########################################## - [ $SEARCH_NAME ] && SCWRYPTS_AVAILABLE=$({ - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | sed -e 's/\x1b\[[0-9;]*m//g' | grep "^$SEARCH_NAME *$SEARCH_TYPE *$SEARCH_GROUP\$" + [ ${SEARCH_NAME} ] && SCWRYPTS_AVAILABLE=$({ + echo ${SCWRYPTS_AVAILABLE} | head -n1 + echo ${SCWRYPTS_AVAILABLE} | utils.colors.remove | grep "^${SEARCH_NAME} *${SEARCH_TYPE} *${SEARCH_GROUP}\$" }) || { - [ $SEARCH_TYPE ] && { + [ ${SEARCH_TYPE} ] && { SCWRYPTS_AVAILABLE=$(\ { - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | grep ' [^/]*'$SEARCH_TYPE'[^/]* ' + echo ${SCWRYPTS_AVAILABLE} | head -n1 + echo ${SCWRYPTS_AVAILABLE} | grep ' [^/]*'${SEARCH_TYPE}'[^/]* ' } \ - | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ + | sed 's/ \+$/'$(utils.colors.reset)'/; s/ \+/^/g' \ | column -ts '^' ) } - [ $SEARCH_GROUP ] && { + [ ${SEARCH_GROUP} ] && { SCWRYPTS_AVAILABLE=$( { - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | grep "$SEARCH_GROUP"'[^/ ]*$' + echo ${SCWRYPTS_AVAILABLE} | head -n1 + echo ${SCWRYPTS_AVAILABLE} | grep "${SEARCH_GROUP}"'[^/ ]*$' } \ - | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ + | sed 's/ \+$/'$(utils.colors.reset)'/; s/ \+/^/g' \ | column -ts '^' ) } [[ ${#SEARCH_PATTERNS[@]} -gt 0 ]] && { - POTENTIAL_ERROR+="\n PATTERNS : $SEARCH_PATTERNS" + POTENTIAL_ERROR+="\n PATTERNS : ${SEARCH_PATTERNS}" local P for P in ${SEARCH_PATTERNS[@]} do SCWRYPTS_AVAILABLE=$( { - echo $SCWRYPTS_AVAILABLE | head -n1 - echo $SCWRYPTS_AVAILABLE | grep $P + echo ${SCWRYPTS_AVAILABLE} | head -n1 + echo ${SCWRYPTS_AVAILABLE} | grep ${P} } ) done } } - [[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -lt 2 ]] && { - FAIL 1 "$(echo " + [[ $(echo ${SCWRYPTS_AVAILABLE} | wc -l) -lt 2 ]] && { + utils.fail 1 "$(echo " no such scwrypt exists - NAME : '$SEARCH_NAME' - TYPE : '$SEARCH_TYPE' - GROUP : '$SEARCH_GROUP' - PATTERNS : '$SEARCH_PATTERNS' + NAME : '${SEARCH_NAME}' + TYPE : '${SEARCH_TYPE}' + GROUP : '${SEARCH_GROUP}' + PATTERNS : '${SEARCH_PATTERNS}' " | sed "1d; \$d; /''$/d")" } ########################################## - [[ $(echo $SCWRYPTS_AVAILABLE | wc -l) -eq 2 ]] \ - && SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | tail -n1) \ - || SCWRYPT_SELECTION=$(echo $SCWRYPTS_AVAILABLE | FZF "select a script to run" --header-lines 1) \ + [[ $(echo ${SCWRYPTS_AVAILABLE} | wc -l) -eq 2 ]] \ + && SCWRYPT_SELECTION=$(echo ${SCWRYPTS_AVAILABLE} | tail -n1) \ + || SCWRYPT_SELECTION=$(echo ${SCWRYPTS_AVAILABLE} | utils.fzf "select a script to run" --header-lines 1) \ ; - [ $SCWRYPT_SELECTION ] || exit 2 + [ ${SCWRYPT_SELECTION} ] || utils.abort ########################################## - local NAME TYPE GROUP - SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION + () { + set -- $(echo $@ | utils.colors.remove) + export SCWRYPT_NAME=$1 + export SCWRYPT_TYPE=$2 + export SCWRYPT_GROUP=$3 + } ${SCWRYPT_SELECTION} - export SCWRYPT_NAME=$NAME - export SCWRYPT_TYPE=$TYPE - export SCWRYPT_GROUP=$GROUP ##################################################################### ### environment variables and configuration validation ############## ##################################################################### local ENV_REQUIRED=true \ - && [ ! $CI ] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/environment ]] \ + && [ ! ${CI} ] \ + && [[ ! ${SCWRYPT_NAME} =~ scwrypts/logs ]] \ + && [[ ! ${SCWRYPT_NAME} =~ scwrypts/environment ]] \ || ENV_REQUIRED=false - local REQUIRED_ENVIRONMENT_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$SCWRYPT_GROUP) + local REQUIRED_ENVIRONMENT_REGEX="$(scwrypts.config.group ${SCWRYPT_GROUP} required_environment_regex)" - [ $ENV_NAME ] && [ $REQUIRED_ENVIRONMENT_REGEX ] && { - [[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \ - || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" + [ ${ENV_NAME} ] && [ ${REQUIRED_ENVIRONMENT_REGEX} ] && { + [[ ${ENV_NAME} =~ ${REQUIRED_ENVIRONMENT_REGEX} ]] \ + || utils.fail 5 "group '${SCWRYPT_GROUP}' requires current environment name to match '${REQUIRED_ENVIRONMENT_REGEX}' (currently ${ENV_NAME})" } - [[ $ENV_REQUIRED =~ true ]] && { - [ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV) - [ ! $ENV_NAME ] && ABORT + [[ ${ENV_REQUIRED} =~ true ]] && { + [ ! ${ENV_NAME} ] && { + scwrypts.environment.init \ + || echo.error "failed to initialize scwrypts environments (see above)" \ + || return 1 \ + ; - export ENV_NAME - export SCWRYPTS_ENV=$ENV_NAME + ENV_NAME=$(scwrypts.environment.select-env) + [ "${ENV_NAME}" ] || user.abort + } for GROUP in ${SCWRYPTS_GROUPS[@]} do - local REQUIRED_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$GROUP) - [ $REQUIRED_REGEX ] && { - [[ $ENV_NAME =~ $REQUIRED_REGEX ]] || continue + local REQUIRED_REGEX="$(scwrypts.config.group ${GROUP} required_environment_regex)" + [ ${REQUIRED_REGEX} ] && { + [[ ${ENV_NAME} =~ ${REQUIRED_REGEX} ]] || continue } - local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP") - source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'" - for f in $(eval 'echo $SCWRYPTS_STATIC_CONFIG__'$GROUP) + for f in $(find "$(scwrypts.config.group ${GROUP} root)/.config/static" -type f 2>/dev/null) do - source "$f" || FAIL 5 "invalid static config '$f'" + source "${f}" || utils.fail 5 "invalid static config '${f}'" done done } - [ $REQUIRED_ENVIRONMENT_REGEX ] && { - [[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \ - || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" + [ ${REQUIRED_ENVIRONMENT_REGEX} ] && { + [[ ${ENV_NAME} =~ ${REQUIRED_ENVIRONMENT_REGEX} ]] \ + || utils.fail 5 "group '${SCWRYPT_GROUP}' requires current environment name to match '${REQUIRED_ENVIRONMENT_REGEX}' (currently ${ENV_NAME})" } + export SCWRYPTS_ENV=${ENV_NAME} ########################################## - [ ! $SUBSCWRYPT ] && export SUBSCWRYPT=0 + [ ! ${SUBSCWRYPT} ] && export SUBSCWRYPT=0 - [[ $SCWRYPTS_INSTALLATION_TYPE =~ ^manual$ ]] && { - [[ $SUBSCWRYPT -eq 0 ]] && [[ $ENV_NAME =~ prod ]] && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] && { - STATUS "on '$ENV_NAME'; checking diff against origin/main" + [[ ${SCWRYPTS_INSTALLATION_TYPE} =~ ^manual$ ]] && { + [[ ${SUBSCWRYPT} -eq 0 ]] && [[ ${SCWRYPTS_ENV} =~ prod ]] && [[ ${SCWRYPTS_LOG_LEVEL} -gt 0 ]] && { + echo.status "on '${SCWRYPTS_ENV}'; checking diff against origin/main" local WARNING_MESSAGE - [ ! $WARNING_MESSAGE ] && { + [ ! ${WARNING_MESSAGE} ] && { GIT_SCWRYPTS fetch --quiet origin main \ || WARNING_MESSAGE='I am unable to verify your scwrypts version' } - [ ! $WARNING_MESSAGE ] && { + [ ! ${WARNING_MESSAGE} ] && { GIT_SCWRYPTS diff --exit-code origin/main -- . >/dev/null 2>&1 \ || WARNING_MESSAGE='your scwrypts is currently out-of-date' } - [ $WARNING_MESSAGE ] && { - [[ $SCWRYPTS_LOG_LEVEL -lt 3 ]] && { - REMINDER "you are running in ${__BRIGHT_RED}production${__BRIGHT_MAGENTA} and $WARNING_MESSAGE" + [ ${WARNING_MESSAGE} ] && { + [[ ${SCWRYPTS_LOG_LEVEL} -lt 3 ]] && { + echo.reminder "you are running in $(utils.colors.bright-red)production$(utils.colors.bright-magenta) and ${WARNING_MESSAGE}" } || { GIT_SCWRYPTS diff --exit-code origin/main -- . >&2 - WARNING "you are trying to run in ${__BRIGHT_RED}production${__YELLOW} but $WARNING_MESSAGE (relevant diffs and errors above)" + echo.warning "you are trying to run in $(utils.colors.bright-red)production$(echo.warning.color) but ${WARNING_MESSAGE} (relevant diffs and errors above)" yN 'continue?' || { - REMINDER "you can use 'scwrypts --update' to quickly update scwrypts to latest" - ABORT + echo.reminder "you can use 'scwrypts --update' to quickly update scwrypts to latest" + user.abort } } } @@ -391,92 +403,123 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 ########################################## - local RUN_STRING=$(SCWRYPTS__GET_RUNSTRING $SCWRYPT_NAME $SCWRYPT_TYPE $SCWRYPT_GROUP) - [ "$RUN_STRING" ] || return 42 + local RUN_STRING=$(scwrypts.get-runstring ${SCWRYPT_NAME} ${SCWRYPT_TYPE} ${SCWRYPT_GROUP}) + [ "${RUN_STRING}" ] || return 42 + ##################################################################### ### logging and pretty header/footer setup ########################## ##################################################################### + local RUN_MODE=normal + [[ ${SCWRYPT_NAME} =~ interactive ]] && RUN_MODE=interactive + local LOGFILE \ - && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] \ - && [[ $SUBSCWRYPT -eq 0 ]] \ - && [[ ! $SCWRYPT_NAME =~ scwrypts/logs ]] \ - && [[ ! $SCWRYPT_NAME =~ interactive ]] \ - && LOGFILE="$SCWRYPTS_LOG_PATH/$(echo $GROUP/$TYPE/$NAME | sed 's/^\.\///; s/\//\%/g').log" \ + && [[ ${RUN_MODE} =~ normal ]] \ + && [[ ${SCWRYPTS_LOG_LEVEL} -gt 0 ]] \ + && [[ ${SUBSCWRYPT} -eq 0 ]] \ + && [[ ! ${SCWRYPT_NAME} =~ scwrypts/logs ]] \ + && LOGFILE="${SCWRYPTS_LOG_PATH}/$(echo ${GROUP}/${TYPE}/${NAME} | sed 's/^\.\///; s/\//\%/g').log" \ || LOGFILE='/dev/null' \ ; - local RUN_MODE=normal - [[ $LOGFILE =~ ^/dev/null$ ]] && RUN_MODE=no-logfile - [[ $SCWRYPT_NAME =~ interactive ]] && RUN_MODE=interactive - local HEADER FOOTER - [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && { - case $SCWRYPTS_OUTPUT_FORMAT in - pretty ) + [[ ${SCWRYPTS_LOG_LEVEL} -ge 2 ]] && { + case ${SCWRYPTS_OUTPUT_FORMAT} in + ( raw ) + HEADER="--- start scwrypt ${SCWRYPT_GROUP}/${SCWRYPT_TYPE} ${SCWRYPT_NAME} in ${SCWRYPTS_ENV} ---" + FOOTER="--- end scwrypt ---" + ;; + ( pretty ) HEADER=$( echo " ===================================================================== - scwrypt : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME + scwrypt : ${SCWRYPT_GROUP} ${SCWRYPT_TYPE} ${SCWRYPT_NAME} run at : $(date) - config : $ENV_NAME - log level : $SCWRYPTS_LOG_LEVEL - \\033[1;33m--- SCWRYPT BEGIN ---------------------------------------------------\\033[0m + config : ${SCWRYPTS_ENV} + log level : ${SCWRYPTS_LOG_LEVEL} + $(utils.colors.print bright-yellow '--- SCWRYPT BEGIN ---------------------------------------------------') " | sed 's/^\s\+//; 1d' ) - FOOTER="\\033[1;33m--- SCWRYPT END ---------------------------------------------------\\033[0m" + FOOTER="$(utils.colors.print bright-yellow '--- SCWRYPT END ---------------------------------------------------')" ;; - json ) + ( json ) HEADER=$(echo '{}' | jq -c ". | .timestamp = \"$(date +%s)\" - | .runtime = \"$SCWRYPTS_RUNTIME_ID\" - | .scwrypt = \"start of $SCWRYPT_NAME $SCWRYPT_GROUP $SCWRYPT_TYPE\" - | .config = \"$ENV_NAME\" - | .logLevel = \"$SCWRYPTS_LOG_LEVEL\" - | .subscwrypt = $SUBSCWRYPT + | .runtime = \"${SCWRYPTS_RUNTIME_ID}\" + | .scwrypt = \"start of ${SCWRYPT_NAME} ${SCWRYPT_GROUP} ${SCWRYPT_TYPE}\" + | .config = \"${SCWRYPTS_ENV}\" + | .logLevel = \"${SCWRYPTS_LOG_LEVEL}\" + | .subscwrypt = ${SUBSCWRYPT} ") ;; esac } - [[ $SUBSCWRYPT -eq 0 ]] || { - case $SCWRYPTS_OUTPUT_FORMAT in - pretty ) - HEADER="\\033[0;33m--- ($SUBSCWRYPT) BEGIN $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" - FOOTER="\\033[0;33m--- ($SUBSCWRYPT) END $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" + [[ ${SUBSCWRYPT} -eq 0 ]] || { + case ${SCWRYPTS_OUTPUT_FORMAT} in + ( pretty ) + HEADER="$(utils.colors.print yellow "--- (${SUBSCWRYPT}) BEGIN ${SCWRYPT_GROUP} ${SCWRYPT_TYPE} ${SCWRYPT_NAME} ---")" + FOOTER="$(utils.colors.print yellow "--- (${SUBSCWRYPT}) END ${SCWRYPT_GROUP} ${SCWRYPT_TYPE} ${SCWRYPT_NAME} ---")" ;; esac } + ##################################################################### ### run the scwrypt ################################################# ##################################################################### set -o pipefail { - [ $HEADER ] && echo $HEADER - case $RUN_MODE in - normal ) - (eval "$RUN_STRING $(printf "%q " "$@")") - EXIT_CODE=$? - ;; - no-logfile ) - eval "$RUN_STRING $(printf "%q " "$@")" - EXIT_CODE=$? - ;; - interactive ) - eval "$RUN_STRING $(printf "%q " "$@")" /dev/tty 2>&1 - EXIT_CODE=$? - ;; - esac - [ $FOOTER ] && echo $FOOTER - [[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m' + [[ ${SCWRYPTS_LOG_LEVEL} -ge 2 ]] && __SCWRYPTS_PRINT_EXIT_CODE=true - [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && [ ! $SUBSCWRYPT ] \ - && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m" + [ ${HEADER} ] && echo ${HEADER} >&2 - return $EXIT_CODE - } | tee --append "$LOGFILE" + ( + case ${RUN_MODE} in + ( normal ) + eval "${RUN_STRING} $(printf "%q " "$@")" + ;; + ( interactive ) + eval "${RUN_STRING} $(printf "%q " "$@")" /dev/tty + ;; + esac + ) + + EXIT_CODE=$? + + [ ${FOOTER} ] && echo ${FOOTER} >&2 + + [[ ${__SCWRYPTS_PRINT_EXIT_CODE} =~ true ]] && { + EXIT_COLOR=$( [[ ${EXIT_CODE} -eq 0 ]] && utils.colors.bright-green || utils.colors.bright-red ) + case ${SCWRYPTS_OUTPUT_FORMAT} in + ( raw ) + echo "terminated with code ${EXIT_CODE}" >&2 + ;; + ( pretty ) + echo "terminated with ${EXIT_COLOR}code ${EXIT_CODE}$(utils.colors.reset)" >&2 + ;; + ( json ) + [[ ${EXIT_CODE} =~ 0 ]] \ + && echo.success --force-print "terminated with code ${EXIT_CODE}" \ + || echo.error --force-print "terminated with code ${EXID_CODE}" \ + ; + ;; + esac + } + + return ${EXIT_CODE} + } | tee --append "${LOGFILE}" } $@ + +EXIT_CODE=$? + +[ "${SCWRYPTS_TEMP_PATH}" ] && [ -d "${SCWRYPTS_TEMP_PATH}" ] \ + && { + rm -- $(find "${SCWRYPTS_TEMP_PATH}" -mindepth 1 -maxdepth 1 -type f) + rmdir "${SCWRYPTS_TEMP_PATH}" + } &>/dev/null + +return ${EXIT_CODE} diff --git a/scwrypts.plugin.zsh b/scwrypts.plugin.zsh index bb40a9d..25f8b37 100644 --- a/scwrypts.plugin.zsh +++ b/scwrypts.plugin.zsh @@ -204,7 +204,7 @@ command -v compdef &>/dev/null && { # stop providing suggestions if your pattern is sufficient [[ $(echo $_remaining_scwrypts | wc -l) -le 1 ]] && return 0 - local _remaining_patterns="$(echo "$_remaining_scwrypts" | sed 's/\s\+/\n/g; s|/|\n|g;' | sort -u)" + local _remaining_patterns="$(echo "$_remaining_scwrypts" | sed 's/\s\+/\n/g; s|/|\n|g; s/-/\n/g;' | sort -u)" for _pattern in ${_patterns[@]} do diff --git a/scwrypts.scwrypts.zsh b/scwrypts.scwrypts.zsh index ab52c17..0bcb5ef 100644 --- a/scwrypts.scwrypts.zsh +++ b/scwrypts.scwrypts.zsh @@ -1,11 +1,177 @@ -SCWRYPTS_GROUPS+=(scwrypts) +# +# configuration for a scwrypts "group" or "plugin" +# -export SCWRYPTS_ROOT__scwrypts="$SCWRYPTS_ROOT" -export SCWRYPTS_COLOR__scwrypts='\033[0;32m' -#export SCWRYPTS_TYPE__scwrypts= -#export SCWRYPTS_LIBRARY_ROOT__scwrypts= +# this file defines the configuration for the 'scwrypts' group which +# is required for proper operation, but otherwise loads exactly like +# any other group/plugin -export SCWRYPTS_VIRTUALENV_PATH__scwrypts="$SCWRYPTS_DATA_PATH/virtualenv" +# +# both ${scwryptsgroup} and ${scwryptsgrouproot} are set automatically +# +# ${scwryptsgroup} is determined by the filename 'NAME.scwrypts.zsh' +# +# NAME must be unique and match : ^[a-z][a-z0-9_]*[a-z0-9]$ +# - STARTS with a lower letter +# - ENDS with a lower letter or number +# - contains only lower-alphanumeric and underscores +# - is at least two characters long +# +# ${scwryptsgrouproot} is automatically set as the parent directory +# /path/to/group-source <-- this will be ${scwryptsgrouproot} +# ├── groupname.scwrypts.zsh +# └── your-scwrypts-source-here +# -export SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts=(3.12 3.11 3.10) -export SCWRYPTS_NODE_VERSION__scwrypts=18.0.0 +##################################################################### +### REQUIRED CONFIGURATION ########################################## +##################################################################### + +# Currently, no configuration is required; simply creating the +# groupname.scwrypts.zsh is sufficient to define a new group + + +##################################################################### +### OPTIONAL CONFIGURATION ########################################## +##################################################################### + +# ${scwryptsgroup}__option_key configuration values can be accessed anywhere in zsh scwrypts +# with $(scwrypts.config.group group-name option_key) + +readonly ${scwryptsgroup}__type= +# +# ${scwryptsgroup}__type (optional) (default = not set) +# +# used when only one scwrypt "type" (e.g. 'zsh' or 'py') is declared +# in the group +# +# WHEN THIS IS SET, scwrypts will lookup executables starting from the +# base directory (using type ${scwryptsgroup}__type): +# +# /path/to/group-source +# ├── groupname.scwrypts.zsh +# ├── valid-scwrypts-executable +# └── some-other +# ├── valid-scwrypts-executable +# └── etc +# +# when this is NOT set, scwrypts must be nested inside a directory +# which matches the type name +# +# /path/to/group-source +# ├── groupname.scwrypts.zsh +# │ +# ├── zsh +# │ ├── valid-scwrypts-executable +# │ └── some-other +# │ ├── valid-scwrypts-executable +# │ └── etc +# │ +# └── py +# ├── valid-scwrypts-executable.py +# └── some-other +# ├── valid-scwrypts-executable.py +# └── etc +# + + +readonly ${scwryptsgroup}__color=$(utils.colors.green) +# +# ${scwryptsgroup}__color (optional) (default = no color / regular text color) +# +# an ANSI color sequence which determines the color of scwrypts in +# interactive menus +# + + +readonly ${scwryptsgroup}__zshlibrary= +# +# ${scwryptsgroup}__zshlibrary (optional) (default = *see below*) +# +# allows arbitrary 'use module/name --group groupname' imports +# within zsh-type scwrypts +# +# usually this is set at or within ${scwryptsgrouproot} +# +# by default, this uses either: +# 1. ${scwryptsgrouproot}/zsh/lib (compatibility) +# 2. ${scwryptsgrouproot}/zsh (preferred) +# + + +readonly ${scwryptsgroup}__virtualenv_path="${SCWRYPTS_STATE_PATH}/virtualenv" +# +# ${scwryptsgroup}__virtualenv_path +# (optional) +# (default = ~/.local/state/scwrypts/virtualenv) +# +# defines the path in which virtual environments are stored for +# the group +# + + +readonly ${scwryptsgroup}__required_environment_regex= +# +# ${scwryptsgroup}__required_environment_regex (optional) (default = allow any) +# +# helps isolate environment by locking group execution to +# environment names which match the regex +# +# when not set, no environment name restrictions are enforced +# +# when set, interactive menus will be adjusted and non-interactive +# execution will fail if the name of the environment does not match +# + + +##################################################################### +### ADVANCED CONFIGURATION ########################################## +##################################################################### + +#${scwryptsgroup}.list-available() {} +# +# ${scwryptsgroup}.list-available() +# +# a function which outputs lines of "${SCWRYPT_TYPE}/${SCWRYPT_NAME}" +# to stdout +# +# by default, looks for executable files in ${scwryptsgrouproot} +# +# during execution of this function, the following variables are +# available: +# +# - $GROUP_ROOT : USE THIS instead of ${scwryptsgrouproot} +# - $GROUP_TYPE : USE THIS instead of ${scwryptsgroup}__type +# +# (see ./zsh/scwrypts/list-available.module.zsh for more details) +# + + +#${scwryptsgroup}.TYPE.get-runstring() {} +# +# a function which outputs what should be literally run when executing +# the indicated type; scwrypts already implements runstring generators +# for supported types (that's the main thing which makes them "supported") +# +# configuration variables are still automatically included as a +# prefix to the runstring +# +# (see ./zsh/scwrypts/get-runstring.module.zsh for more details) +# + + +##################################################################### +### HYPER-ADVANCED CONFIGURATION #################################### +##################################################################### + +# +# additional zsh can be defined or run arbitrarily; this is NOT recommended +# unless you understand the implications of the various places where +# this code is loaded +# +# if you want to know where to get started (it will take some learning!), +# review the execution process in: +# - ./scwrypts +# - ./zsh/scwrypts/get-runstring.module.zsh +# - ./zsh/scwrypts/environment/user.module.zsh +# diff --git a/zsh/README.md b/zsh/README.md index 7690c07..6375079 100644 --- a/zsh/README.md +++ b/zsh/README.md @@ -1,21 +1,113 @@ # ZSH Scwrypts [![Generic Badge](https://img.shields.io/badge/1password-op-informational.svg)](https://1password.com/downloads/command-line) [![Generic Badge](https://img.shields.io/badge/BurntSushi-rg-informational.svg)](https://github.com/BurntSushi/ripgrep) +[![Generic Badge](https://img.shields.io/badge/dbcli-pgcli-informational.svg)](https://github.com/dbcli/pgcli) [![Generic Badge](https://img.shields.io/badge/junegunn-fzf-informational.svg)](https://github.com/junegunn/fzf) [![Generic Badge](https://img.shields.io/badge/mikefarah-yq-informational.svg)](https://github.com/mikefarah/yq) [![Generic Badge](https://img.shields.io/badge/stedolan-jq-informational.svg)](https://github.com/stedolan/jq) -[![Generic Badge](https://img.shields.io/badge/dbcli-pgcli-informational.svg)](https://github.com/dbcli/pgcli)
-Since they emulate direct user interaction, shell scripts are often the straightforward choice for task automation. +Since they emulate direct user interaction, shell scripts are a (commonly dreaded) go-to for automation. -## Basic Utilities +Although the malleability of shell scripts can make integrations quickly, the ZSH-type scwrypt provides a structure to promote extendability and clean code while performing a lot of the heavy lifting to ensure consistent execution across different runtimes. -One of my biggest pet-peeves with scripting is when every line of a *(insert-language-here)* program is escaped to shell. -This kind of program, which doesn't use language features, should be a shell script. -While there are definitely unavoidable limitations to shell scripting, we can minimize a variety of problems with a modern shell and shared utilities library. +## The Basic Framework -Loaded by `common.zsh`, the [`utils/` library](./utils) provides: -- common function wrappers to unify flags and context -- lazy dependency and environment variable validation -- consistent (and pretty) user input / output +Take a look at the simplest ZSH-type scwrypt: [hello-world](./hello-world). +The bare minimum API for ZSH-type scwrypts is to: + +1. include the shebang `#!/usr/bin/env zsh` on the first line of the file +2. wrap your zsh in a function called `MAIN()` +3. make the file executable (e.g. `chmod +x hello-world`) + +Once this is complete, you are free to simply _write valid zsh_ then execute the scwrypt with `scwrypts hello world zsh`! + +## Basics+ + +While it would be perfectly fine to use the `echo` function in our scwrypt, you'll notice that the `hello-world` scwrypt instead uses `echo.success` which is _not_ valid ZSH by default. +This is a helper function provided by the scwrypts ZSH library, and it does a lot more work than you'd expect. + +Although this function defaults to print user messages in color, notice what happens when you run `scwrypts --output json hello world zsh`: + +```json +{"timestamp":1745674060,"runtime":"c62737da-481e-4013-a370-4dedc76bf4d2","scwrypt":"start of hello-world scwrypts zsh","logLevel":"3","subscwrypt":0} +{"timestamp":1745674060,"runtime":"c62737da-481e-4013-a370-4dedc76bf4d2","status":"SUCCESS","message":"\"Hello, World!\""} +{"timestamp":1745674060,"runtime":"c62737da-481e-4013-a370-4dedc76bf4d2","status":"SUCCESS","message":"\"terminated with code 0\""} +``` + +We get a LOT more information. + +It's 100% possible for you to include your own take on printing messages, but it is highly recommended to use the tools provided here. + +### What is loaded by default? + +By default, every ZSH-type scwrypt will load [the basic utilities suite](./utils), which is a little different from scwrypts ZSH modules, and a little bit complex. +Although it's totally worth a deep-dive, here are the fundamentals you should ALWAYS use: + +#### Printing User Messages or Logs + +Whenever you want to print a message to the user or logs, rather than using `echo`, use the following: + +| function name | minimum log level | description | +| --------------- | ----------------- | --------------------------------- | +| `echo.success` | 1 | indicate successful completion | +| `echo.error` | 1 | indicate an error has occurred | +| `echo.reminder` | 1 | an important, information message | +| `echo.status` | 2 | a regular, information message | +| `echo.warning` | 3 | a non-critical warning | +| `echo.debug` | 4 | a message for scwrypt developers | + + +Of the `echo` family, there are two unique functions: + +- `echo.error` will **increment the `ERRORS` variable** then return an error code of `$ERRORS` (this makes it easy to chain with command failure by using `||`) +- `echo.debug` will inject state information like the timestamp and current function stack + + +#### Yes / No Prompts + +The two helpers `utils.Yn` and `utils.yN` take a user-friendly yes/no question as an argument. + +- when the user responds "yes", the command returns 0 / success / `&&` +- when the user responds "no", the command returns 1 / error / `||` +- when the user responds with _nothing_ (e.g. just presses enter), the _default_ is used + +The two commands work identically; however, the capitalization denotes the default: +- `utils.Yn` = default "yes" +- `utils.yN` = default "no" + +#### Select from a List Prompt + +When you want the user to select an item from a list, scwrypts typically use `fzf`. +There are a LOT of options to `fzf`, so there are two provided helpers. + +The basic selector, `utils.fzf` (most of the time, you want to use this one) which outputs: +- _the selection_ if the user made a choice +- _nothing / empty string_ if the user cancelled or made an invalid choice + +The user-input selector, `utils.fzf.user-input` which outputs: +- _the selection_ if the user made a choice +- _the text typed by the user_ if the user typed something other than the listed choices +- _nothing / empty string_ if the user cancelled +- _a secondary `utils.fzf` prompt_ if the user's choice was ambiguous + +### Imports + +Don't use `source` in ZSH-type scwrypts (I mean, if you're pretty clever you can get it to work, but DON'T THOUGH). +Instead, use `use`! + +The `use` command, rather than specifying file directories, you reference the path to `*.module.zsh`. +This means you don't have to know the exact path to any given file. +For example, if I wanted to import the safety tool for `aws` CLI commands, I can do the following: + +```zsh +#!/usr/bin/env zsh + +use cloud/aws + +##################################################################### + +MAIN() { + cloud.aws sts get-caller-identity +} +``` diff --git a/zsh/cloud/aws/aws.module.zsh b/zsh/cloud/aws/aws.module.zsh new file mode 100644 index 0000000..9a4ea5a --- /dev/null +++ b/zsh/cloud/aws/aws.module.zsh @@ -0,0 +1,13 @@ +# +# provides utilities for interacting with Amazon Web Services (AWS) +# + +# context wrapper for AWS CLI v2 +use cloud/aws/cli +eval "${scwryptsmodule}() { ${scwryptsmodule}.cli \$@; }" + +# simplify context commands for kubectl on EKS +use cloud/aws/eks + +# context wrapper for eksctl +use cloud/aws/eksctl diff --git a/zsh/cloud/aws/aws.test.zsh b/zsh/cloud/aws/aws.test.zsh new file mode 100644 index 0000000..f011532 --- /dev/null +++ b/zsh/cloud/aws/aws.test.zsh @@ -0,0 +1,28 @@ +##################################################################### + +use unittest +testmodule=cloud.aws + +##################################################################### + +beforeall() { + use cloud/aws +} + +##################################################################### + +test.provides-aws-cli() { + unittest.test.provides ${testmodule}.cli +} + +test.provides-aws-cli-alias() { + unittest.test.provides ${testmodule} +} + +test.provides-eks() { + unittest.test.provides ${testmodule}.eks +} + +test.provides-eksctl() { + unittest.test.provides ${testmodule}.eksctl +} diff --git a/zsh/cloud/aws/cli.module.zsh b/zsh/cloud/aws/cli.module.zsh new file mode 100644 index 0000000..bde6ea4 --- /dev/null +++ b/zsh/cloud/aws/cli.module.zsh @@ -0,0 +1,36 @@ +##################################################################### + +DEPENDENCIES+=(aws) + +use cloud/aws/zshparse + +##################################################################### + +${scwryptsmodule}() { + local PARSERS=(cloud.aws.zshparse.overrides) + local ARGS=() + local DESCRIPTION=" + Safe context wrapper for aws cli commands; prevents accidental local environment + bleed-through, but otherwise works exactly like 'aws'. For help with awscli, try + 'AWS [command] help' (no -h or --help) + + This wrapper should be used in place of _all_ 'aws' usages within scwrypts. + " + + eval "$(utils.parse.autosetup)" + + ########################################## + + echo.debug "invoking '$(echo "$AWS_EVAL_PREFIX" | sed 's/AWS_\(ACCESS_KEY_ID\|SECRET_ACCESS_KEY\)=[^ ]\+ //g')aws ${AWS_CONTEXT_ARGS[@]} ${ARGS[@]}'" + eval "${AWS_EVAL_PREFIX}aws ${AWS_CONTEXT_ARGS[@]} ${ARGS[@]}" +} + +##################################################################### + +${scwryptsmodule}.parse() { + return 0 # uses default args parser +} + +${scwryptsmodule}.parse.usage() { + USAGE__args+='\$@ arguments forwarded to the AWS CLI' +} diff --git a/zsh/cloud/aws/cli.test.zsh b/zsh/cloud/aws/cli.test.zsh new file mode 100644 index 0000000..e3b5eb7 --- /dev/null +++ b/zsh/cloud/aws/cli.test.zsh @@ -0,0 +1,65 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.cli + +##################################################################### + +beforeall() { + use cloud/aws/cli +} + +beforeeach() { + unittest.mock aws + unittest.mock echo.debug + + _ARGS=($(uuidgen) $(uuidgen) $(uuidgen)) + + _AWS_REGION=$(uuidgen) + _AWS_PROFILE=$(uuidgen) + + unittest.mock.env AWS_ACCOUNT --value $(uuidgen) + unittest.mock.env AWS_PROFILE --value ${_AWS_PROFILE} + unittest.mock.env AWS_REGION --value ${_AWS_REGION} +} + +aftereach() { + unset _AWS_REGION + unset _AWS_PROFILE +} + +##################################################################### + +test.forwards-arguments() { + ${testmodule} ${_ARGS[@]} + + aws.assert.callstack \ + --output json \ + --region ${_AWS_REGION} \ + --profile ${_AWS_PROFILE} \ + ${_ARGS[@]} \ + ; +} + +test.overrides-region() { + local OVERRIDE_REGION=$(uuidgen) + + ${testmodule} --region ${OVERRIDE_REGION} ${_ARGS[@]} + + aws.assert.callstack \ + --output json \ + --region ${OVERRIDE_REGION} \ + --profile ${_AWS_PROFILE} \ + ${_ARGS[@]} \ + ; +} + +test.overrides-account() { + local OVERRIDE_ACCOUNT=$(uuidgen) + + ${testmodule} --account ${OVERRIDE_ACCOUNT} ${_ARGS[@]} + + echo.debug.assert.callstackincludes \ + AWS_ACCOUNT=${OVERRIDE_ACCOUNT} \ + ; +} diff --git a/zsh/cloud/aws/ecr/ecr.module.zsh b/zsh/cloud/aws/ecr/ecr.module.zsh new file mode 100644 index 0000000..eb866fc --- /dev/null +++ b/zsh/cloud/aws/ecr/ecr.module.zsh @@ -0,0 +1,6 @@ +# +# common operations for AWS Elastic Container Registry (ECR) +# + +# that obnoxious command which pushes the AWS temporary credentials to 'docker login' +use cloud/aws/ecr/login diff --git a/zsh/cloud/aws/ecr/ecr.test.zsh b/zsh/cloud/aws/ecr/ecr.test.zsh new file mode 100644 index 0000000..866a5ee --- /dev/null +++ b/zsh/cloud/aws/ecr/ecr.test.zsh @@ -0,0 +1,16 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.ecr + +##################################################################### + +beforeall() { + use cloud/aws/ecr +} + +##################################################################### + +test.provides-ecr-login() { + unittest.test.provides ${testmodule}.login +} diff --git a/zsh/cloud/aws/ecr/login b/zsh/cloud/aws/ecr/login index 415441b..87a7315 100755 --- a/zsh/cloud/aws/ecr/login +++ b/zsh/cloud/aws/ecr/login @@ -1,7 +1,17 @@ -#!/bin/zsh -use cloud/aws/ecr +#!/usr/bin/env zsh ##################################################################### -MAIN() { - ECR_LOGIN $@ -} +use cloud/aws/ecr/login +use cloud/aws/zshparse + +##################################################################### + +USAGE__description=' + interactively setup temporary credentials for ECR in the given region +' + +cloud.aws.zshparse.overrides.usage + +##################################################################### + +MAIN() { cloud.aws.ecr.login $@; } diff --git a/zsh/cloud/aws/ecr/login.module.zsh b/zsh/cloud/aws/ecr/login.module.zsh new file mode 100644 index 0000000..72bd224 --- /dev/null +++ b/zsh/cloud/aws/ecr/login.module.zsh @@ -0,0 +1,30 @@ +##################################################################### + +use cloud/aws/cli +use cloud/aws/zshparse + +DEPENDENCIES+=(docker) + +##################################################################### + +${scwryptsmodule}() { + local DESCRIPTION=" + Performs the appropriate 'docker login' command with temporary + credentials from AWS. + " + + local PARSERS=(cloud.aws.zshparse.overrides) + + eval "$(utils.parse.autosetup)" + + ########################################## + + ${AWS} ecr get-login-password \ + | docker login "${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com" \ + --username AWS \ + --password-stdin \ + &>/dev/null \ + && echo.success "authenticated docker for '${ACCOUNT}' in '${REGION}'" \ + || echo.error "unable to authenticate docker for '${ACCOUNT}' in '${REGION}'" \ + ; +} diff --git a/zsh/cloud/aws/ecr/login.test.zsh b/zsh/cloud/aws/ecr/login.test.zsh new file mode 100644 index 0000000..5d689a7 --- /dev/null +++ b/zsh/cloud/aws/ecr/login.test.zsh @@ -0,0 +1,47 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.ecr.login + +##################################################################### + +beforeall() { + use cloud/aws/ecr/login +} + +beforeeach() { + unittest.mock cloud.aws.cli + unittest.mock docker + + _AWS_ACCOUNT=$(uuidgen) + _AWS_PROFILE=$(uuidgen) + _AWS_REGION=$(uuidgen) + + unittest.mock.env AWS_ACCOUNT --value ${_AWS_ACCOUNT} + unittest.mock.env AWS_PROFILE --value ${_AWS_PROFILE} + unittest.mock.env AWS_REGION --value ${_AWS_REGION} + + _EXPECTED_AWS_ARGS=( + --account ${_AWS_ACCOUNT} + --region ${_AWS_REGION} + ) +} + +aftereach() { + unset \ + _AWS_ACCOUNT _AWS_PROFILE _AWS_REGION \ + _EXPECTED_AWS_ARGS \ + ; +} + +##################################################################### + +test.login-forwards-credentials-to-docker() { + ${testmodule} + + docker.assert.callstack \ + login "${_AWS_ACCOUNT}.dkr.ecr.${_AWS_REGION}.amazonaws.com" \ + --username AWS \ + --password-stdin \ + ; +} diff --git a/zsh/cloud/aws/efs/mount b/zsh/cloud/aws/efs/mount index 45dd844..0dc09d0 100755 --- a/zsh/cloud/aws/efs/mount +++ b/zsh/cloud/aws/efs/mount @@ -1,64 +1,82 @@ -#!/bin/zsh -DEPENDENCIES+=(jq) -REQUIRED_ENV+=(AWS__EFS__LOCAL_MOUNT_POINT) +#!/usr/bin/env zsh +##################################################################### use cloud/aws/cli +use cloud/aws/zshparse/overrides + +DEPENDENCIES+=(jq mount sort sudo) +REQUIRED_ENV+=(AWS__EFS__LOCAL_MOUNT_POINT) + +##################################################################### + +USAGE__description=' + interactively mount an AWS EFS volume to the local filesystem +' + ##################################################################### MAIN() { - GETSUDO || exit 1 - [ ! -d $AWS__EFS__LOCAL_MOUNT_POINT ] && { - sudo mkdir $AWS__EFS__LOCAL_MOUNT_POINT \ - && STATUS "created local mount point '$AWS__EFS__LOCAL_MOUNT_POINT'" - } + local PARSERS=(cloud.aws.zshparse.overrides) + eval "$(utils.parse.autosetup)" + utils.io.getsudo || return 1 + ########################################## + + { + mkdir -p -- "${AWS__EFS__LOCAL_MOUNT_POINT}" \ + || sudo mkdir -p -- "${AWS__EFS__LOCAL_MOUNT_POINT}" + } &>/dev/null + + [ -d "${AWS__EFS__LOCAL_MOUNT_POINT}" ] \ + || echo.error "unable to create local mount point '${AWS__EFS__LOCAL_MOUNT_POINT}'" \ + || return local FS_ID=$(\ - AWS efs describe-file-systems \ - | jq -r '.[] | .[] | .FileSystemId' \ - | FZF 'select a filesystem to mount' \ + $AWS efs describe-file-systems \ + | jq -r '.[] | .[] | .FileSystemId' \ + | utils.fzf 'select a filesystem to mount' \ ) - [ ! $FS_ID ] && ABORT + [ ! ${FS_ID} ] && utils.abort - local MOUNT_POINT="$AWS__EFS__LOCAL_MOUNT_POINT/$FS_ID" - [ -d "$MOUNT_POINT" ] && sudo rmdir "$MOUNT_POINT" >/dev/null 2>&1 - [ -d "$MOUNT_POINT" ] && { - STATUS "$FS_ID is already mounted" - exit 0 + local MOUNT_POINT="${AWS__EFS__LOCAL_MOUNT_POINT}/${FS_ID}" + [ -d "${MOUNT_POINT}" ] && sudo rmdir "${MOUNT_POINT}" &>/dev/null + [ -d "${MOUNT_POINT}" ] && { + echo.status "${FS_ID} is already mounted" + return 0 } - local MOUNT_TARGETS=$(AWS efs describe-mount-targets --file-system-id $FS_ID) + local MOUNT_TARGETS=$($AWS efs describe-mount-targets --file-system-id ${FS_ID}) local ZONE=$(\ - echo $MOUNT_TARGETS \ - | jq -r '.[] | .[] | .AvailabilityZoneName' \ - | sort -u | FZF 'select availability zone'\ + echo ${MOUNT_TARGETS} \ + | jq -r '.[] | .[] | .AvailabilityZoneName' \ + | sort -u | utils.fzf 'select availability zone'\ ) - [ ! $ZONE ] && ABORT + [ ! "${ZONE}" ] && utils.abort local MOUNT_IP=$(\ - echo $MOUNT_TARGETS \ - | jq -r ".[] | .[] | select (.AvailabilityZoneName == \"$ZONE\") | .IpAddress" \ - | head -n1 \ + echo ${MOUNT_TARGETS} \ + | jq -r ".[] | .[] | select (.AvailabilityZoneName == \"${ZONE}\") | .IpAddress" \ + | head -n1 \ ) - SUCCESS 'ready to mount!' - REMINDER 'for private file-systems, you must be connected to the appropriate VPN' + echo.success 'ready to mount!' + echo.status " + file system id : ${FS_ID} + availability zone : ${ZONE} + file system ip : ${MOUNT_IP} + local mount point : ${MOUNT_POINT} + " + echo.reminder 'for private file-systems, you must be connected to the appropriate VPN' + Yn 'proceed?' || utils.abort - STATUS "file system id : $FS_ID" - STATUS "availability zone : $ZONE" - STATUS "file system ip : $MOUNT_IP" - STATUS "local mount point : $MOUNT_POINT" - - Yn 'proceed?' || ABORT - - sudo mkdir $MOUNT_POINT \ + sudo mkdir -- "${MOUNT_POINT}" \ && sudo mount \ -t nfs4 \ -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport \ - $MOUNT_IP:/ \ - "$MOUNT_POINT" \ - && SUCCESS "mounted at '$MOUNT_POINT'" \ + "${MOUNT_IP}:/" \ + "${MOUNT_POINT}" \ + && echo.success "mounted at '${MOUNT_POINT}'" \ || { - sudo rmdir $MOUNT_POINT >/dev/null 2>&1 - FAIL 2 "unable to mount '$FS_ID'" - } + sudo rmdir -- "${MOUNT_POINT}" &>/dev/null + echo.error "unable to mount '${FS_ID}'" + } } diff --git a/zsh/cloud/aws/efs/unmount b/zsh/cloud/aws/efs/unmount index 62beca9..c84f6bd 100755 --- a/zsh/cloud/aws/efs/unmount +++ b/zsh/cloud/aws/efs/unmount @@ -1,32 +1,39 @@ -#!/bin/zsh -DEPENDENCIES+=(jq) -REQUIRED_ENV+=(AWS__EFS__LOCAL_MOUNT_POINT) - -use cloud/aws/cli +#!/usr/bin/env zsh ##################################################################### +DEPENDENCIES+=(jq umount sudo) +REQUIRED_ENV+=(AWS__EFS__LOCAL_MOUNT_POINT) + +##################################################################### + +USAGE__description=' + interactively unmount an AWS EFS volume to the local filesystem +' + MAIN() { - [ ! -d "$AWS__EFS__LOCAL_MOUNT_POINT" ] && { - STATUS 'no efs currently mounted' - exit 0 + eval "$(utils.parse.autosetup)" + ########################################## + + [ ! -d "${AWS__EFS__LOCAL_MOUNT_POINT}" ] && { + echo.status 'no efs currently mounted' + return 0 } - local MOUNTED=$(ls "$AWS__EFS__LOCAL_MOUNT_POINT") - [ ! $MOUNTED ] && { - STATUS 'no efs currently mounted' - exit 0 + local MOUNTED=$(cd -- "${AWS__EFS__LOCAL_MOUNT_POINT}" | find . -type -f | sed 's|^\./.||') + [ "${MOUNTED}" ] && { + echo.status 'no efs currently mounted' + return 0 } - GETSUDO || exit 1 + utils.io.getsudo || return 1 + local SELECTED=$(echo ${MOUNTED} | utils.fzf 'select a file system to unmount') + [ "${SELECTED}" ] || user.abort - local SELECTED=$(echo $MOUNTED | FZF 'select a file system to unmount') - [ ! $SELECTED ] && ABORT - - local EFS="$AWS__EFS__LOCAL_MOUNT_POINT/$SELECTED" - STATUS "unmounting '$SELECTED'" - sudo umount $EFS >/dev/null 2>&1 - sudo rmdir $EFS \ - && SUCCESS "done" \ - || FAIL 2 "failed to unmount '$EFS'" + local EFS="${AWS__EFS__LOCAL_MOUNT_POINT}/${SELECTED}" + echo.status "unmounting '${SELECTED}'" + sudo umount "${EFS}" >/dev/null 2>&1 + sudo rmdir -- "${EFS}" \ + && echo.success "done" \ + || utils.fail 2 "failed to unmount '${EFS}'" } diff --git a/zsh/cloud/aws/eks/cli.module.zsh b/zsh/cloud/aws/eks/cli.module.zsh new file mode 100644 index 0000000..c53eb46 --- /dev/null +++ b/zsh/cloud/aws/eks/cli.module.zsh @@ -0,0 +1,86 @@ +##################################################################### + +use cloud/aws/eks/cluster-login + +use cloud/aws/zshparse +use cloud/aws/eks/zshparse + +##################################################################### + +${scwryptsmodule}() { + local DESCRIPTION=" + Context wrapper for kubernetes CLI commands on AWS EKS. This + will automatically attempt login for first-time connections, + and ensures the correct kubecontext is used for the expected + command. + + EKS --cluster-name my-cluster kubectl get pods + EKS --cluster-name my-cluster helm history my-deployment + ... etc ... + " + local ARGS=() PARSERS=( + cloud.aws.zshparse.overrides + cloud.aws.eks.zshparse.cluster-name + ) + + eval "$(utils.parse.autosetup)" + + ########################################## + + local CONTEXT="arn:aws:eks:${REGION}:${ACCOUNT}:cluster/${CLUSTER_NAME}" + + local ALREADY_LOGGED_IN + kubectl config get-contexts --output=name | grep -q "^${CONTEXT}$" \ + && ALREADY_LOGGED_IN=true \ + || ALREADY_LOGGED_IN=false \ + ; + + case ${ALREADY_LOGGED_IN} in + ( true ) ;; + ( false ) + cloud.aws.eks.cluster-login \ + ${AWS_PASSTHROUGH[@]} \ + --cluster-name ${CLUSTER_NAME} \ + >/dev/null \ + || echo.error "unable to login to cluster '${CLUSTER_NAME}'" \ + || return 1 + ;; + esac + + local CONTEXT_ARGS=() + case ${KUBECLI} in + ( helm ) + CONTEXT_ARGS+=(--kube-context ${CONTEXT}) # *rolls eyes* THANKS, helm + ;; + ( * ) + CONTEXT_ARGS+=(--context ${CONTEXT}) + ;; + esac + + ${KUBECLI} ${CONTEXT_ARGS[@]} ${ARGS[@]} +} + +##################################################################### + +${scwryptsmodule}.parse() { return 0; } + +${scwryptsmodule}.parse.locals() { + local KUBECLI # extracted from default ARGS parser +} + +${scwryptsmodule}.parse.usage() { + USAGE__usage+=' kubecli [...kubecli-args...]' + + USAGE__args+=' + kubecli cli which uses kubernetes context arguments (e.g. kubectl, helm, flux) + kubecli-args arguments forwarded to the kubectl-style CLI + ' +} + +${scwryptsmodule}.parse.validate() { + KUBECLI="${ARGS[1]}" + ARGS=(${ARGS[@]:1}) + + [ ${KUBECLI} ] \ + || echo.error "missing argument for 'kubecli'" +} diff --git a/zsh/cloud/aws/eks/cli.test.zsh b/zsh/cloud/aws/eks/cli.test.zsh new file mode 100644 index 0000000..c7d11e1 --- /dev/null +++ b/zsh/cloud/aws/eks/cli.test.zsh @@ -0,0 +1,105 @@ +##################################################################### + +use unittest + +testmodule=cloud.aws.eks.cli + +##################################################################### + +beforeall() { + use cloud/aws/eks/cli + use cloud/aws/eks/cluster-login +} + +beforeeach() { + unittest.mock cloud.aws.eks.cluster-login + + _CLUSTER_NAME=$(uuidgen) + + _AWS_ACCOUNT=$(uuidgen) + _AWS_PROFILE=$(uuidgen) + _AWS_REGION=$(uuidgen) + + _KUBECLI=$(uuidgen) + _KUBECLI_ARGS=($(uuidgen) $(uuidgen) $(uuidgen)) + + unittest.mock.env AWS_ACCOUNT --value ${_AWS_ACCOUNT} + unittest.mock.env AWS_PROFILE --value ${_AWS_PROFILE} + unittest.mock.env AWS_REGION --value ${_AWS_REGION} + + _EXPECTED_KUBECONTEXT="arn:aws:eks:${_AWS_REGION}:${_AWS_ACCOUNT}:cluster/${_CLUSTER_NAME}" + _KUBECTL_KUBECONTEXTS="$(uuidgen)\n${_EXPECTED_KUBECONTEXT}\n$(uuidgen)" + + _EXPECTED_AWS_ARGS=( + --account ${_AWS_ACCOUNT} + --region ${_AWS_REGION} + ) +} + +aftereach() { + unset \ + _CLUSTER_NAME \ + _AWS_ACCOUNT _AWS_PROFILE _AWS_REGION \ + _EXPECTED_AWS_ARGS \ + ; +} + +mock.kubectl() { + unittest.mock kubectl --stdout "${_KUBECTL_KUBECONTEXTS}" +} + +mock.kubecli() { + command -v ${_KUBECLI} &>/dev/null || ${_KUBECLI}() { true; } + unittest.mock ${_KUBECLI} +} + +##################################################################### + +test.uses-correct-kubecli-args() { + mock.kubectl + mock.kubecli + + ${testmodule} --cluster-name ${_CLUSTER_NAME} ${_KUBECLI} ${_KUBECLI_ARGS[@]} + + ${_KUBECLI}.assert.callstack \ + --context ${_EXPECTED_KUBECONTEXT} \ + ${_KUBECLI_ARGS[@]} + ; +} + +test.uses-correct-helm-args() { + _KUBECLI=helm + + mock.kubectl + mock.kubecli + + ${testmodule} --cluster-name ${_CLUSTER_NAME} ${_KUBECLI} ${_KUBECLI_ARGS[@]} + + ${_KUBECLI}.assert.callstack \ + --kube-context ${_EXPECTED_KUBECONTEXT} \ + ${_KUBECLI_ARGS[@]} + ; +} + +test.performs-login() { + _KUBECTL_KUBECONTEXTS="$(uuidgen)\n$(uuidgen)" + + mock.kubectl + mock.kubecli + + ${testmodule} --cluster-name ${_CLUSTER_NAME} ${_KUBECLI} ${_KUBECLI_ARGS[@]} + + cloud.aws.eks.cluster-login.assert.callstack \ + ${_EXPECTED_AWS_ARGS[@]} \ + --cluster-name ${_CLUSTER_NAME} \ + ; +} + +test.does-not-perform-login-if-already-logged-in() { + mock.kubectl + mock.kubecli + + ${testmodule} --cluster-name ${_CLUSTER_NAME} ${_KUBECLI} ${_KUBECLI_ARGS[@]} + + cloud.aws.eks.cluster-login.assert.not.called +} diff --git a/zsh/cloud/aws/eks/cluster-login.module.zsh b/zsh/cloud/aws/eks/cluster-login.module.zsh new file mode 100644 index 0000000..013fafa --- /dev/null +++ b/zsh/cloud/aws/eks/cluster-login.module.zsh @@ -0,0 +1,43 @@ +##################################################################### + +use cloud/aws/cli + +use cloud/aws/zshparse +use cloud/aws/eks/zshparse + +##################################################################### + +${scwryptsmodule}() { + local DESCRIPTION=' + Interactively sets the default kubeconfig to match the selected + cluster in EKS. Also creates the kubeconfig entry if it does not + already exist. + ' + local PARSERS=( + cloud.aws.zshparse.overrides + cloud.aws.eks.zshparse.cluster-name + ) + + local EKS_CLUSTER_NAME_INTERACTIVE=allowed + + eval "$(utils.parse.autosetup)" + + ##################################################################### + + [ ${CLUSTER_NAME} ] || CLUSTER_NAME=$(\ + ${AWS} eks list-clusters \ + | jq -r '.[] | .[]' \ + | utils.fzf "select an eks cluster (${ACCOUNT}/${REGION})" + ) + + [ ${CLUSTER_NAME} ] || echo.error 'must select a valid cluster or use --cluster-name' + + utils.check-errors || return $? + + ########################################## + + echo.status 'updating kubeconfig for EKS cluster '${CLUSTER_NAME}'' + ${AWS} eks update-kubeconfig --name ${CLUSTER_NAME} \ + && echo.success "kubeconfig updated with '${CLUSTER_NAME}'" \ + || echo.error "failed to update kubeconfig; do you have permission to access '${CLUSTER_NAME}'?" +} diff --git a/zsh/cloud/aws/eks/cluster-login.test.zsh b/zsh/cloud/aws/eks/cluster-login.test.zsh new file mode 100644 index 0000000..bf6b612 --- /dev/null +++ b/zsh/cloud/aws/eks/cluster-login.test.zsh @@ -0,0 +1,66 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.eks.cluster-login + +##################################################################### + +beforeall() { + use cloud/aws/eks/cluster-login +} + +beforeeach() { + unittest.mock cloud.aws.cli + + _CLUSTER_NAME=$(uuidgen) + + _AWS_ACCOUNT=$(uuidgen) + _AWS_PROFILE=$(uuidgen) + _AWS_REGION=$(uuidgen) + + unittest.mock.env AWS_ACCOUNT --value ${_AWS_ACCOUNT} + unittest.mock.env AWS_PROFILE --value ${_AWS_PROFILE} + unittest.mock.env AWS_REGION --value ${_AWS_REGION} + + _EXPECTED_AWS_ARGS=( + --account ${_AWS_ACCOUNT} + --region ${_AWS_REGION} + ) +} + +aftereach() { + unset \ + _CLUSTER_NAME \ + _AWS_ACCOUNT _AWS_PROFILE _AWS_REGION \ + _EXPECTED_AWS_ARGS \ + ; +} + +##################################################################### + +test.login-to-correct-cluster() { + ${testmodule} --cluster-name ${_CLUSTER_NAME} + + cloud.aws.cli.assert.callstack \ + ${_EXPECTED_AWS_ARGS[@]} \ + eks update-kubeconfig \ + --name ${_CLUSTER_NAME} \ + ; +} + +test.interactive-login-ignored-on-ci() { + ${testmodule} + cloud.aws.cli.assert.not.called +} + +test.interactive-login-to-correct-cluster() { + unittest.mock utils.fzf --stdout ${_CLUSTER_NAME} + + ${testmodule} + + cloud.aws.cli.assert.callstack \ + ${_EXPECTED_AWS_ARGS[@]} \ + eks update-kubeconfig \ + --name ${_CLUSTER_NAME} \ + ; +} diff --git a/zsh/cloud/aws/eks/eks.module.zsh b/zsh/cloud/aws/eks/eks.module.zsh new file mode 100644 index 0000000..93c44b9 --- /dev/null +++ b/zsh/cloud/aws/eks/eks.module.zsh @@ -0,0 +1,10 @@ +# +# run kubectl/helm/etc commands on AWS Elastic Kubernetes Service (EKS) +# + +# provides an EKS connection wrapper for any kubectl-like cli +use cloud/aws/eks/cli +eval "${scwryptsmodule}() { ${scwryptsmodule}.cli $@; }" + +# sets up kubeconfig to connect to EKS +use cloud/aws/eks/cluster-login diff --git a/zsh/cloud/aws/eks/eks.test.zsh b/zsh/cloud/aws/eks/eks.test.zsh new file mode 100644 index 0000000..52fa4fc --- /dev/null +++ b/zsh/cloud/aws/eks/eks.test.zsh @@ -0,0 +1,24 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.eks + +##################################################################### + +beforeall() { + use cloud/aws +} + +##################################################################### + +test.provides-eks-cli() { + unittest.test.provides ${testmodule}.cli +} + +test.provides-eks-cli-alias() { + unittest.test.provides ${testmodule} +} + +test.provides-cluster-login() { + unittest.test.provides ${testmodule}.cluster-login +} diff --git a/zsh/cloud/aws/eks/login b/zsh/cloud/aws/eks/login index 76b0fe7..d29b9f0 100755 --- a/zsh/cloud/aws/eks/login +++ b/zsh/cloud/aws/eks/login @@ -1,4 +1,4 @@ -#!/bin/zsh +#!/usr/bin/env zsh use cloud/aws/eks ##################################################################### diff --git a/zsh/cloud/aws/eks/zshparse/cluster-name.module.zsh b/zsh/cloud/aws/eks/zshparse/cluster-name.module.zsh new file mode 100644 index 0000000..899c4e9 --- /dev/null +++ b/zsh/cloud/aws/eks/zshparse/cluster-name.module.zsh @@ -0,0 +1,44 @@ +${scwryptsmodule}.locals() { + local CLUSTER_NAME + + # set to 'allowed' to enable interactive cluster select + # by default, the '--cluster-name' flag is required + local EKS_CLUSTER_NAME_INTERACTIVE +} + +${scwryptsmodule}() { + local PARSED=0 + + case $1 in + ( -c | --cluster-name ) + CLUSTER_NAME="$2" + ((PARSED+=2)) + ;; + esac + + return $PARSED +} + +${scwryptsmodule}.usage() { + [[ "$USAGE__usage" =~ '\[...options...\]' ]] || USAGE__usage+=' [...options...]' + + USAGE__options+="\n + -c, --cluster-name EKS cluster name identifier string + " +} + +${scwryptsmodule}.validate() { + [ $CLUSTER_NAME ] && return 0 + + [[ $EKS_CLUSTER_NAME_INTERACTIVE =~ allowed ]] \ + || echo.error 'missing cluster name' \ + || return + + CLUSTER_NAME=$(\ + $AWS eks list-clusters \ + | jq -r '.[] | .[]' \ + | utils.fzf "select an eks cluster ($ACCOUNT/$REGION)" \ + ) + + [ $CLUSTER_NAME ] || echo.error 'must select a valid cluster or use --cluster-name' +} diff --git a/zsh/cloud/aws/eks/zshparse/zshparse.module.zsh b/zsh/cloud/aws/eks/zshparse/zshparse.module.zsh new file mode 100644 index 0000000..e29aac5 --- /dev/null +++ b/zsh/cloud/aws/eks/zshparse/zshparse.module.zsh @@ -0,0 +1,6 @@ +# +# argument parsers for common EKS arguments +# + +# get the EKS "ClusterName" identifier +use cloud/aws/eks/zshparse/cluster-name diff --git a/zsh/cloud/aws/eksctl/cli.module.zsh b/zsh/cloud/aws/eksctl/cli.module.zsh new file mode 100644 index 0000000..ad4dc66 --- /dev/null +++ b/zsh/cloud/aws/eksctl/cli.module.zsh @@ -0,0 +1,40 @@ +##################################################################### + +use cloud/aws/zshparse/overrides + +DEPENDENCIES+=(eksctl) + +##################################################################### + +${scwryptsmodule}() { + local PARSERS=(cloud.aws.zshparse.overrides) + local DESCRIPTION=" + Context wrapper for eksctl commands; prevents accidental local environment + bleed-through, but otherwise works exactly like 'eksctl'. + + This wrapper should be used in place of _all_ 'eksctl' usages within scwrypts. + " + + eval "$(utils.parse.autosetup)" + + ########################################## + + echo.debug "invoking '$(echo "$AWS_EVAL_PREFIX" | sed 's/AWS_\(ACCESS_KEY_ID\|SECRET_ACCESS_KEY\)=[^ ]\+ //g')eksctl ${ARGS[@]}'" + eval "${AWS_EVAL_PREFIX}eksctl ${ARGS[@]}" +} + +##################################################################### + +${scwryptsmodule}.parse() { + return 0 +} + +${scwryptsmodule}.parse.locals() { + local ARGS=() +} + +${scwryptsmodule}.parse.usage() { + USAGE__args+=' + args all remaining arguments are forwarded to eksctl + ' +} diff --git a/zsh/cloud/aws/eksctl/cli.test.zsh b/zsh/cloud/aws/eksctl/cli.test.zsh new file mode 100644 index 0000000..00887c9 --- /dev/null +++ b/zsh/cloud/aws/eksctl/cli.test.zsh @@ -0,0 +1,72 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.eksctl.cli + +##################################################################### + +beforeall() { + use cloud/aws/eksctl/cli +} + +beforeeach() { + unittest.mock eksctl + unittest.mock echo.debug + + _ARGS=($(uuidgen) $(uuidgen) $(uuidgen)) + + _AWS_REGION=$(uuidgen) + _AWS_PROFILE=$(uuidgen) + + unittest.mock.env AWS_ACCOUNT --value $(uuidgen) + unittest.mock.env AWS_PROFILE --value ${_AWS_PROFILE} + unittest.mock.env AWS_REGION --value ${_AWS_REGION} +} + +aftereach() { + unset _AWS_REGION + unset _AWS_PROFILE +} + +##################################################################### + +test.forwards-arguments() { + ${testmodule} ${_ARGS[@]} + + eksctl.assert.callstack \ + ${_ARGS[@]} \ + ; +} + +test.forwards-profile() { + # + # --profile is an invalid argument for eksctl, so it + # MUST be forwarded as AWS_PROFILE to prevent environment + # bleeding + # + ${testmodule} ${_ARGS[@]} + + echo.debug.assert.callstackincludes \ + AWS_PROFILE=${OVERRIDE_REGION} \ + ; +} + +test.overrides-region() { + local OVERRIDE_REGION=$(uuidgen) + + ${testmodule} --region ${OVERRIDE_REGION} ${_ARGS[@]} + + echo.debug.assert.callstackincludes \ + AWS_REGION=${OVERRIDE_REGION} \ + ; +} + +test.overrides-account() { + local OVERRIDE_ACCOUNT=$(uuidgen) + + ${testmodule} --account ${OVERRIDE_ACCOUNT} ${_ARGS[@]} + + echo.debug.assert.callstackincludes \ + AWS_ACCOUNT=${OVERRIDE_ACCOUNT} \ + ; +} diff --git a/zsh/cloud/aws/eksctl/eksctl.module.zsh b/zsh/cloud/aws/eksctl/eksctl.module.zsh new file mode 100644 index 0000000..cde3cc6 --- /dev/null +++ b/zsh/cloud/aws/eksctl/eksctl.module.zsh @@ -0,0 +1,10 @@ +# +# module for eksctl actions +# + +# context wrapper for direct use of eksctl +use cloud/aws/eksctl/cli +eval "${scwryptsmodule}() { ${scwryptsmodule}.cli \$@; }" + +# argument helper for creating a standard iamserviceaccount +use cloud/aws/eksctl/iamserviceaccount diff --git a/zsh/cloud/aws/eksctl/eksctl.test.zsh b/zsh/cloud/aws/eksctl/eksctl.test.zsh new file mode 100644 index 0000000..9191b25 --- /dev/null +++ b/zsh/cloud/aws/eksctl/eksctl.test.zsh @@ -0,0 +1,20 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.eksctl + +##################################################################### + +beforeall() { + use cloud/aws/eksctl +} + +##################################################################### + +test.provides-eksctl-cli() { + unittest.test.provides ${testmodule}.cli +} + +test.provides-eksctl-alias() { + unittest.test.provides ${testmodule} +} diff --git a/zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.module.zsh b/zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.module.zsh new file mode 100644 index 0000000..e8705e1 --- /dev/null +++ b/zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.module.zsh @@ -0,0 +1,57 @@ +##################################################################### + +use cloud/aws/eks/cli + +use cloud/aws/eksctl/iamserviceaccount/zshparse +use cloud/aws/zshparse/overrides + +DEPENDENCIES+=(kubectl yq) + +##################################################################### + +${scwryptsmodule}() { + local DESCRIPTION=" + determine whether the target iamserviceaccount already + exists on Kubernetes + + OK: + exit code 0 : the serviceaccount exists on kubernetes + exit code 100 : the serviceaccount does not exist on kubernetes + + ERROR: + exit code 200 : the serviceaccount exists on kubernetes, but does not match the target role + " + + local PARSERS=( + cloud.aws.eksctl.iamserviceaccount.zshparse + cloud.aws.zshparse.overrides + ) + + eval "$(utils.parse.autosetup)" + + ########################################## + + echo.status "checking for existing role-arn" + local CURRENT_ROLE_ARN=$( + cloud.aws.eks.cli kubectl ${AWS_PASSTHROUGH_ARGS[@]} --namespace "${NAMESPACE}" get serviceaccount "${SERVICEACCOUNT}" -o yaml \ + | utils.yq -r '.metadata.annotations["eks.amazonaws.com/role-arn"]' \ + | grep -v '^null$' \ + ) + + [ "${CURRENT_ROLE_ARN}" ] || { + echo.status "serviceaccount does not exist or has no configured role" + return 100 + } + + [[ ${CURRENT_ROLE_ARN} =~ "${ROLE_NAME}$" ]] || { + echo.status "\ + serviceaccount current role does not match desired role: + CURRENT : ${CURRENT_ROLE_ARN} + DESIRED : arn:aws:iam::${AWS_ACCOUNT}:role/${ROLE_NAME} + " + return 200 + } + + echo.status "serviceaccount current role matches desired role" + return 0 +} diff --git a/zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.test.zsh b/zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.test.zsh new file mode 100644 index 0000000..85935e9 --- /dev/null +++ b/zsh/cloud/aws/eksctl/iamserviceaccount/check-exists.test.zsh @@ -0,0 +1,63 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.eksctl.iamserviceaccount.check-exists + +##################################################################### + +beforeall() { + use cloud/aws/eksctl/iamserviceaccount/check-exists + use cloud/aws/eks/cli +} + +beforeeach() { + _SERVICEACCOUNT=$(uuidgen) + _NAMEPACE=$(uuidgen) + _ROLE_NAME=$(uuidgen) + _ROLE_ARN="$(uuidgen)/${_ROLE_NAME}" + + unittest.mock.env AWS_ACCOUNT --value $(uuidgen) + unittest.mock.env AWS_PROFILE --value $(uuidgen) + unittest.mock.env AWS_REGION --value $(uuidgen) + + _ARGS=( + --serviceaccount ${_SERVICEACCOUNT} + --namespace ${_NAMEPACE} + --role-name ${_ROLE_NAME} + ) +} + +aftereach() { + unset _SERVICEACCOUNT _NAMESPACE _ROLE_NAME _ARGS +} + +##################################################################### + +test.detects-exists() { + unittest.mock cloud.aws.eks.cli \ + --stdout '{"metadata":{"annotations":{"eks.amazonaws.com/role-arn":"'$_ROLE_ARN'"}}}' \ + ; + + ${testmodule} ${_ARGS[@]} + + [[ $? -eq 0 ]] +} + +test.detects-not-exists() { + unittest.mock cloud.aws.eks.cli \ + --stdout '{}' + + ${testmodule} ${_ARGS[@]} + + [[ $? -eq 100 ]] +} + +test.detects-exists-but-does-not-match() { + unittest.mock cloud.aws.eks.cli \ + --stdout '{"metadata":{"annotations":{"eks.amazonaws.com/role-arn":"'$(uuidgen)'"}}}' \ + ; + + ${testmodule} ${_ARGS[@]} + + [[ $? -eq 200 ]] +} diff --git a/zsh/cloud/aws/eksctl/iamserviceaccount/create.module.zsh b/zsh/cloud/aws/eksctl/iamserviceaccount/create.module.zsh new file mode 100644 index 0000000..0130100 --- /dev/null +++ b/zsh/cloud/aws/eksctl/iamserviceaccount/create.module.zsh @@ -0,0 +1,93 @@ +##################################################################### + +use cloud/aws/eksctl/cli +use cloud/aws/eksctl/iamserviceaccount/check-exists + +use cloud/aws/eksctl/iamserviceaccount/zshparse +use cloud/aws/zshparse/overrides +use cloud/aws/eks/zshparse/cluster-name + +##################################################################### + +${scwryptsmodule}() { + local DESCRIPTION=" + creates an 'iamserviceaccount' which provides a Kubernetes + serviceaccount with AWS role identity and access control + " + + local PARSERS=( + cloud.aws.eksctl.iamserviceaccount.zshparse + cloud.aws.zshparse.overrides + cloud.aws.eks.zshparse.cluster-name + ) + + eval "$(utils.parse.autosetup)" + + ########################################## + + case ${FORCE} in + ( true ) ;; + ( false ) + cloud.aws.eksctl.iamserviceaccount.check-exists \ + --serviceaccount "${SERVICEACCOUNT}" \ + --namespace "${NAMESPACE}" \ + --role-name "${ROLE_NAME}" \ + ${AWS_PASSTHROUGH[@]} \ + ; + case $? in + ( 0 ) echo.success "'${NAMESPACE}/${SERVICEACCOUNT}' already configured with '${ROLE_NAME}'" + return 0 + ;; + ( 100 ) # role does not exist yet; continue with rollout + ;; + ( 200 ) echo.error "'${NAMESPACE}/${SERVICEACCOUNT}' has been configured with a different role than '${ROLE_NAME}'" + echo.reminder "must use --force flag to overwrite" + return 2 + ;; + esac + ;; + esac + + echo.status "creating iamserviceaccount" \ + && cloud.aws.eksctl.cli ${AWS_PASSTHROUGH_ARGS[@]} create iamserviceaccount \ + --cluster "${CLUSTER_NAME}" \ + --namespace "${NAMESPACE}" \ + --name "${SERVICEACCOUNT}" \ + --role-name "${ROLE_NAME}" \ + --override-existing-serviceaccounts \ + --approve \ + ${ARGS[@]} \ + && echo.success "successfully configured '${NAMESPACE}/${SERVICEACCOUNT}' with IAM role '${ROLE_NAME}'" \ + || echo.error "unable to configure '${NAMESPACE}/${SERVICEACCOUNT}' with IAM role '${ROLE_NAME}'\n(check cloudformation dashboard for details)" \ + ; +} + +##################################################################### + +${scwryptsmodule}.parse.locals() { + local FORCE=false # whether or not to force a new eksctl deployment + local ARGS=() +} + +${scwryptsmodule}.parse() { + local PARSED=0 + + case $1 in + --force ) PARSED=1; FORCE=true ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.parse.usage() { + USAGE__options+=" + --force don't check for existing serviceaccount and override any existing configuration + " + + USAGE__args+=" + args all remaining arguments are forwarded to 'eksctl create iamserviceaccount' + + eksctl create iamserviceaccount args: + $(eksctl create iamserviceaccount --help 2>&1 | grep -v -- '--name' | grep -v -- '--namespace' | grep -v -- '--role-name' | sed 's/^/ /') + " +} diff --git a/zsh/cloud/aws/eksctl/iamserviceaccount/create.test.zsh b/zsh/cloud/aws/eksctl/iamserviceaccount/create.test.zsh new file mode 100644 index 0000000..c37acd4 --- /dev/null +++ b/zsh/cloud/aws/eksctl/iamserviceaccount/create.test.zsh @@ -0,0 +1,150 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.eksctl.iamserviceaccount.create + +##################################################################### + +beforeall() { + use cloud/aws/eksctl/iamserviceaccount/create +} + +beforeeach() { + unittest.mock cloud.aws.eksctl.cli + + _SERVICEACCOUNT=$(uuidgen) + _NAMESPACE=$(uuidgen) + _ROLE_NAME=$(uuidgen) + _ROLE_ARN="$(uuidgen)/${_ROLE_NAME}" + + _CLUSTER_NAME=$(uuidgen) + + _AWS_ACCOUNT=$(uuidgen) + _AWS_REGION=$(uuidgen) + + unittest.mock.env AWS_ACCOUNT --value ${_AWS_ACCOUNT} + unittest.mock.env AWS_PROFILE --value $(uuidgen) + unittest.mock.env AWS_REGION --value ${_AWS_REGION} + + _IAMSERVICEACCOUNT_ARGS=( + --serviceaccount ${_SERVICEACCOUNT} + --namespace ${_NAMESPACE} + --role-name ${_ROLE_NAME} + ) + + _EXTRA_ARGS=($(uuidgen) $(uuidgen) $(uuidgen)) + + _ARGS=( + --cluster-name ${_CLUSTER_NAME} + ${_IAMSERVICEACCOUNT_ARGS[@]} + -- + ${_EXTRA_ARGS[@]} + ) + + _EXPECTED_AWS_PASSTHROUGH=( + --account ${_AWS_ACCOUNT} + --region ${_AWS_REGION} + ) +} + +aftereach() { + unset \ + _SERVICEACCOUNT _NAMESPACE _ROLE_NAME \ + _CLUSTER_NAME \ + _AWS_ACCOUNT _AWS_REGION \ + _ARGS _EXPECTED_AWS_PASSTHROUGH_ARGS \ + ; +} + +##################################################################### + +test.performs-check-exists() { + unittest.mock cloud.aws.eksctl.iamserviceaccount.check-exists \ + --exit-code 0 \ + ; + + ${testmodule} ${_ARGS[@]} + + cloud.aws.eksctl.iamserviceaccount.check-exists.assert.callstack \ + ${_IAMSERVICEACCOUNT_ARGS[@]} \ + ${_EXPECTED_AWS_PASSTHROUGH[@]} \ + ; +} + +test.ignores-check-exist-on-force() { + unittest.mock cloud.aws.eksctl.iamserviceaccount.check-exists \ + --exit-code 0 \ + ; + + ${testmodule} ${_ARGS[@]} --force + + cloud.aws.eksctl.iamserviceaccount.check-exists.assert.not.called +} + +test.does-not-create-if-exists() { + unittest.mock cloud.aws.eksctl.iamserviceaccount.check-exists \ + --exit-code 0 \ + ; + + ${testmodule} ${_ARGS[@]} + + cloud.aws.eksctl.cli.assert.not.called +} + +test.creates-role() { + unittest.mock cloud.aws.eksctl.iamserviceaccount.check-exists \ + --exit-code 100 \ + ; + + ${testmodule} ${_ARGS[@]} + + cloud.aws.eksctl.cli.assert.callstack \ + create iamserviceaccount \ + --cluster ${_CLUSTER_NAME} \ + --namespace ${_NAMESPACE} \ + --name ${_SERVICEACCOUNT} \ + --role-name ${_ROLE_NAME} \ + --override-existing-serviceaccounts \ + --approve \ + ${_EXTRA_ARGS[@]} \ + ; +} + +test.creates-role-on-force() { + unittest.mock cloud.aws.eksctl.iamserviceaccount.check-exists \ + --exit-code 0 \ + ; + + ${testmodule} ${_ARGS[@]} --force + + cloud.aws.eksctl.cli.assert.callstack \ + create iamserviceaccount \ + --cluster ${_CLUSTER_NAME} \ + --namespace ${_NAMESPACE} \ + --name ${_SERVICEACCOUNT} \ + --role-name ${_ROLE_NAME} \ + --override-existing-serviceaccounts \ + --approve \ + ${_EXTRA_ARGS[@]} \ + ; +} + +test.does-not-create-if-mismatched-role() { + unittest.mock cloud.aws.eksctl.iamserviceaccount.check-exists \ + --exit-code 200 \ + ; + + ${testmodule} ${_ARGS[@]} + + cloud.aws.eksctl.cli.assert.not.called +} + +test.returns-correct-error-if-mismatched-role() { + unittest.mock cloud.aws.eksctl.iamserviceaccount.check-exists \ + --exit-code 200 \ + ; + + ${testmodule} ${_ARGS[@]} + + [[ $? -eq 2 ]] +} diff --git a/zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.module.zsh b/zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.module.zsh new file mode 100644 index 0000000..0aca283 --- /dev/null +++ b/zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.module.zsh @@ -0,0 +1,9 @@ +# +# build 'iamserviceaccount' to enable IAM identity / access control +# + +# create the iamserviceaccount +use cloud/aws/eksctl/iamserviceaccount/create + +# check whether the iamserviceaccount exists in kubernetes +use cloud/aws/eksctl/iamserviceaccount/check-exists diff --git a/zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.test.zsh b/zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.test.zsh new file mode 100644 index 0000000..29b6fbd --- /dev/null +++ b/zsh/cloud/aws/eksctl/iamserviceaccount/iamserviceaccount.test.zsh @@ -0,0 +1,20 @@ +##################################################################### + +use unittest +testmodule=cloud.aws.eksctl.iamserviceaccount + +##################################################################### + +beforeall() { + use cloud/aws/eksctl/iamserviceaccount +} + +##################################################################### + +test.provides-create() { + unittest.test.provides ${testmodule}.create +} + +test.provides-check-exists() { + unittest.test.provides ${testmodule}.check-exists +} diff --git a/zsh/cloud/aws/eksctl/iamserviceaccount/zshparse.module.zsh b/zsh/cloud/aws/eksctl/iamserviceaccount/zshparse.module.zsh new file mode 100644 index 0000000..8442af9 --- /dev/null +++ b/zsh/cloud/aws/eksctl/iamserviceaccount/zshparse.module.zsh @@ -0,0 +1,35 @@ +##################################################################### + +${scwryptsmodule}.locals() { + local SERVICEACCOUNT + local NAMESPACE + local ROLE_NAME +} + +${scwryptsmodule}() { + local PARSED=0 + + case $1 in + ( --serviceaccount ) PARSED=2; SERVICEACCOUNT=$2 ;; + ( --namespace ) PARSED=2; NAMESPACE=$2 ;; + ( --role-name ) PARSED=2; ROLE_NAME=$2 ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.usage() { + USAGE__options+=" + --serviceaccount (required) target k8s:ServiceAccount + --namespace (required) target k8s:Namespace + --role-name (required) name of the IAM role to assign + " +} + +${scwryptsmodule}.validate() { + [ "${SERVICEACCOUNT}" ] || echo.error "--serviceaccount is required" + [ "${NAMESPACE}" ] || echo.error "--namespace is required" + [ "${ROLE_NAME}" ] || echo.error "--role-name is required" +} + +##################################################################### diff --git a/zsh/cloud/aws/rds/create-backup b/zsh/cloud/aws/rds/create-backup index c6fc357..2df21d5 100755 --- a/zsh/cloud/aws/rds/create-backup +++ b/zsh/cloud/aws/rds/create-backup @@ -1,4 +1,4 @@ -#!/bin/zsh +#!/usr/bin/env zsh use cloud/aws/rds use db/postgres ##################################################################### diff --git a/zsh/cloud/aws/rds/interactive-login b/zsh/cloud/aws/rds/interactive-login index 5e57e9f..61ea4ab 100755 --- a/zsh/cloud/aws/rds/interactive-login +++ b/zsh/cloud/aws/rds/interactive-login @@ -1,4 +1,4 @@ -#!/bin/zsh +#!/usr/bin/env zsh use cloud/aws/rds use db/postgres ##################################################################### diff --git a/zsh/cloud/aws/rds/load-backup b/zsh/cloud/aws/rds/load-backup index c8ac1cc..65e0bc2 100755 --- a/zsh/cloud/aws/rds/load-backup +++ b/zsh/cloud/aws/rds/load-backup @@ -1,4 +1,4 @@ -#!/bin/zsh +#!/usr/bin/env zsh use cloud/aws/rds use db/postgres ##################################################################### diff --git a/zsh/lib/cloud/aws/rds.module.zsh b/zsh/cloud/aws/rds/rds.module.zsh similarity index 76% rename from zsh/lib/cloud/aws/rds.module.zsh rename to zsh/cloud/aws/rds/rds.module.zsh index 4285f85..4ae1803 100644 --- a/zsh/lib/cloud/aws/rds.module.zsh +++ b/zsh/cloud/aws/rds/rds.module.zsh @@ -1,13 +1,7 @@ ##################################################################### -DEPENDENCIES+=( - docker -) - -REQUIRED_ENV+=( - AWS_ACCOUNT - AWS_REGION -) +DEPENDENCIES+=(docker) +REQUIRED_ENV+=(AWS_ACCOUNT AWS_REGION) use cloud/aws/cli @@ -15,13 +9,13 @@ use cloud/aws/cli RDS__SELECT_DATABASE() { local DATABASES=$(_RDS__GET_AVAILABLE_DATABASES) - [ ! $DATABASES ] && FAIL 1 'no databases available' + [ ! $DATABASES ] && utils.fail 1 'no databases available' local ID=$(\ echo $DATABASES | jq -r '.instance + " @ " + .cluster' \ - | FZF 'select a database (instance@cluster)' \ + | utils.fzf 'select a database (instance@cluster)' \ ) - [ ! $ID ] && ABORT + [ ! $ID ] && user.abort local INSTANCE=$(echo $ID | sed 's/ @ .*$//') local CLUSTER=$(echo $ID | sed 's/^.* @ //') @@ -49,24 +43,24 @@ RDS__GET_DATABASE_CREDENTIALS() { while [[ $# -gt 0 ]] do case $1 in - --print-password ) PRINT_PASSWORD=1 ;; - * ) - WARNING "unrecognized argument $1" + ( --print-password ) PRINT_PASSWORD=1 ;; + ( * ) + echo.warning "unrecognized argument $1" ERRORS+=1 ;; esac shift 1 done - CHECK_ERRORS + utils.check-errors --fail ########################################## local DATABASE=$(RDS__SELECT_DATABASE) - [ ! $DATABASE ] && ABORT + [ ! $DATABASE ] && user.abort DB_HOST="$(echo $DATABASE | jq -r '.host')" - [ ! $DB_HOST ] && { ERROR 'unable to find host'; return 2; } + [ ! $DB_HOST ] && { echo.error 'unable to find host'; return 2; } DB_PORT="$(echo $DATABASE | jq -r '.port')" [ ! $DB_PORT ] && DB_PORT=5432 @@ -76,17 +70,17 @@ RDS__GET_DATABASE_CREDENTIALS() { local AUTH_METHOD=$(\ echo "iam\nsecretsmanager\nuser-input" \ - | FZF 'select an authentication method' \ + | utils.fzf 'select an authentication method' \ ) - [ ! $AUTH_METHOD ] && ABORT + [ ! $AUTH_METHOD ] && user.abort case $AUTH_METHOD in - iam ) _RDS_AUTH__iam ;; - secretsmanager ) _RDS_AUTH__secretsmanager ;; - user-input ) _RDS_AUTH__userinput ;; + ( iam ) _RDS_AUTH__iam ;; + ( secretsmanager ) _RDS_AUTH__secretsmanager ;; + ( user-input ) _RDS_AUTH__userinput ;; esac - [[ $PRINT_PASSWORD -eq 1 ]] && DEBUG "password : $DB_PASS" + [[ $PRINT_PASSWORD -eq 1 ]] && echo.debug "password : $DB_PASS" return 0 } @@ -104,19 +98,19 @@ _RDS_AUTH__secretsmanager() { local CREDENTIALS=$(_RDS__GET_SECRETSMANAGER_CREDENTIALS) echo $CREDENTIALS | jq -e '.pass' >/dev/null 2>&1 \ && DB_PASS="$(echo $CREDENTIALS | jq -r '.pass')" - + echo $CREDENTIALS | jq -e '.password' >/dev/null 2>&1 \ && DB_PASS="$(echo $CREDENTIALS | jq -r '.password')" - + echo $CREDENTIALS | jq -e '.user' >/dev/null 2>&1 \ && DB_USER=$(echo $CREDENTIALS | jq -r '.user') - + echo $CREDENTIALS | jq -e '.username' >/dev/null 2>&1 \ && DB_USER=$(echo $CREDENTIALS | jq -r '.username') - + echo $CREDENTIALS | jq -e '.name' >/dev/null 2>&1 \ && DB_NAME=$(echo $CREDENTIALS | jq -r '.name') - + echo $CREDENTIALS | jq -e '.dbname' >/dev/null 2>&1 \ && DB_NAME=$(echo $CREDENTIALS | jq -r '.dbname') } @@ -125,7 +119,7 @@ _RDS__GET_SECRETSMANAGER_CREDENTIALS() { local ID=$(\ AWS secretsmanager list-secrets \ | jq -r '.[] | .[] | .Name' \ - | FZF 'select a secret' \ + | utils.fzf 'select a secret' \ ) [ ! $ID ] && return 1 diff --git a/zsh/cloud/aws/route53/backup b/zsh/cloud/aws/route53/backup index 43e1a40..d22ceda 100755 --- a/zsh/cloud/aws/route53/backup +++ b/zsh/cloud/aws/route53/backup @@ -1,33 +1,30 @@ -#!/bin/zsh +#!/usr/bin/env zsh DEPENDENCIES+=(cli53) -REQUIRED_ENV+=(AWS_PROFILE) +REQUIRED_ENV+=(AWS_PROFILE AWS_ACCOUNT) ##################################################################### +utils.cli53() { + AWS_ACCOUNT=${AWS_ACCOUNT} \ + cli53 --profile ${AWS_PROFILE} $@; +} + MAIN() { - local BACKUP_PATH="$SCWRYPTS_OUTPUT_PATH/$ENV_NAME/aws-dns-backup/$(date '+%Y-%m-%d')" - mkdir -p $BACKUP_PATH >/dev/null 2>&1 + local BACKUP_BASE_PATH="${SCWRYPTS_DATA_PATH}/route53-backup/${SCWRYPTS_ENV}" local DOMAIN local JOBS=() - for DOMAIN in $(ROUTE53_GET_DOMAINS) + for DOMAIN in $(utils.cli53 list | awk '{print $2;}' | sed '1d; s/\.$//') do - ( STATUS "creating '$BACKUP_PATH/$DOMAIN.txt'" \ - && cli53 export --profile $AWS_PROFILE $DOMAIN > "$BACKUP_PATH/$DOMAIN.txt" \ - && SUCCESS "backed up '$DOMAIN'" \ - || ERROR "failed to back up '$DOMAIN'" \ + ( + utils.cli53 export ${DOMAIN} > "${BACKUP_BASE_PATH}/${DOMAIN}/$(date '+%Y-%m-%d_%H%M').cli53.txt" \ + && echo.success "backed up '${DOMAIN}'" \ + || echo.error "failed to back up '${DOMAIN}'" \ ) & JOBS+=$! done local P - for P in ${JOBS[@]}; do wait $P >/dev/null 2>&1; done -} + for P in ${JOBS[@]}; do wait ${P} &>/dev/null; done -##################################################################### - -ROUTE53_GET_DOMAINS() { - cli53 list --profile $AWS_PROFILE \ - | awk '{print $2;}' \ - | sed '1d; s/\.$//'\ - ; + echo.reminder "successful backups can be found in '${BACKUP_BASE_PATH}'" } diff --git a/zsh/cloud/aws/zshparse/overrides.module.zsh b/zsh/cloud/aws/zshparse/overrides.module.zsh new file mode 100644 index 0000000..16b4f48 --- /dev/null +++ b/zsh/cloud/aws/zshparse/overrides.module.zsh @@ -0,0 +1,79 @@ +${scwryptsmodule}.locals() { + local ACCOUNT # parsed/configured AWS_ACCOUNT (use this instead of the env var!) + local REGION # parsed/configured AWS_REGION (use this instead of the env var!) + + local AWS_PASSTHROUGH=() # used to forward parsed overrides to cloud.aws.cli calls (e.g. 'cloud.aws.cli ${AWS_PASSTHROUGH[@]} your command') + local AWS=() # used to forward parsed overrides to cloud.aws.cli calls (e.g. '$AWS your command') + + # should only be used by cloud/aws/cli + local AWS_EVAL_PREFIX + local AWS_CONTEXT_ARGS=() +} + +${scwryptsmodule}() { + local PARSED=0 + + case $1 in + ( --account ) PARSED+=2; ACCOUNT=$2 ;; + ( --region ) PARSED+=2; REGION=$2 ;; + esac + + return $PARSED +} + +${scwryptsmodule}.usage() { + [[ "$USAGE__usage" =~ ' \[...options...\]' ]] || USAGE__usage+=' [...options...]' + + USAGE__options+="\n + --account overrides required AWS_ACCOUNT scwrypts env value + --region overrides required AWS_REGION scwrypts env value + " +} + + +${scwryptsmodule}.validate() { + AWS_CONTEXT_ARGS=(--output json) + + [ $ACCOUNT ] || { utils.environment.check AWS_ACCOUNT &>/dev/null && ACCOUNT=$AWS_ACCOUNT; } + [ $ACCOUNT ] \ + && AWS_EVAL_PREFIX+="AWS_ACCOUNT=$ACCOUNT " \ + && AWS_PASSTHROUGH+=(--account $ACCOUNT) \ + || echo.error "missing either --account or AWS_ACCOUNT" \ + ; + + [ $REGION ] || { utils.environment.check AWS_REGION &>/dev/null && REGION=$AWS_REGION; } + [ $REGION ] \ + && AWS_EVAL_PREFIX+="AWS_REGION=$REGION AWS_DEFAULT_REGION=$REGION " \ + && AWS_CONTEXT_ARGS+=(--region $REGION) \ + && AWS_PASSTHROUGH+=(--region $REGION) \ + || echo.error "missing either --region or AWS_REGION" \ + ; + + utils.environment.check AWS_PROFILE &>/dev/null + [ $AWS_PROFILE ] \ + && AWS_EVAL_PREFIX+="AWS_PROFILE=$AWS_PROFILE " \ + && AWS_CONTEXT_ARGS+=(--profile $AWS_PROFILE) \ + ; + + AWS=(cloud.aws.cli ${AWS_PASSTHROUGH[@]}) + + [ ! $CI ] && { + # non-CI must use PROFILE authentication + [ $AWS_PROFILE ] || echo.error "missing either --profile or AWS_PROFILE"; + + [[ $AWS_PROFILE =~ ^default$ ]] \ + && echo.warning "it is HIGHLY recommended to NOT use the 'default' profile for aws operations\nconsider using '$USER.$SCWRYPTS_ENV' instead" + } + + [ $CI ] && { + # CI can use 'profile' or envvar 'access key' authentication + [ $AWS_PROFILE ] && return 0 # 'profile' preferred + + [ $AWS_ACCESS_KEY_ID ] && [ $AWS_SECRET_ACCESS_KEY ] \ + && AWS_EVAL_PREFIX+="AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID " \ + && AWS_EVAL_PREFIX+="AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY " \ + && return 0 + + echo.error "running in CI, but missing both profile and access-key configuration\n(one AWS authentication method *must* be used)" + } +} diff --git a/zsh/cloud/aws/zshparse/zshparse.module.zsh b/zsh/cloud/aws/zshparse/zshparse.module.zsh new file mode 100644 index 0000000..8a63543 --- /dev/null +++ b/zsh/cloud/aws/zshparse/zshparse.module.zsh @@ -0,0 +1,6 @@ +# +# argument parsers for common AWS-CLI arguments +# + +# load/override AWS_* variables +use cloud/aws/zshparse/overrides diff --git a/zsh/cloud/media-sync/pull b/zsh/cloud/media-sync/pull deleted file mode 100755 index 1903cc7..0000000 --- a/zsh/cloud/media-sync/pull +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use cloud/media-sync -##################################################################### - -MAIN() { - MEDIA_SYNC__PULL $@ -} diff --git a/zsh/cloud/media-sync/push b/zsh/cloud/media-sync/push deleted file mode 100755 index 000d132..0000000 --- a/zsh/cloud/media-sync/push +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use cloud/media-sync -##################################################################### - -MAIN() { - MEDIA_SYNC__PUSH $@ -} diff --git a/zsh/config.global.zsh b/zsh/config.global.zsh new file mode 100644 index 0000000..645a50b --- /dev/null +++ b/zsh/config.global.zsh @@ -0,0 +1,9 @@ +scwrypts.config() { + [ $1 ] || return 1 + + case $1 in + ( python.versions ) echo "3.13\n3.12\n3.11\n3.10" ;; + ( nodejs.version ) echo "22.0.0" ;; + ( * ) return 1 ;; + esac +} diff --git a/zsh/config.user.zsh b/zsh/config.user.zsh new file mode 100644 index 0000000000000000000000000000000000000000..04ee339851d06b51fba3f12e04388356f5a6a928 GIT binary patch literal 989 zcmb_bOK;mS4BoZ=2Rn^u3V7X+_`V{CEY_L;NgT*dyPgcyregt$4bYPg#34DiiJ{XciGMU{R6@1wi?31HI;?Ko+5)*oq{5gbu;$0AQJ|bKjFv=oC zP%)wL3V2fpTO!mbT6b}(S6d%St9Y{nY#zCi%?cX>SaNe4mc&K}(dEu}gEJt$%dd*r5rbZ~SVph10e|2}BuVjfQK<1SEB9xLiC-FGTr%6ou zuMojWUD`qELUA|LM|6{3c_A9sH8x35(mF#UXoX#Jx3l55-j06nS=ZqaUz#lD z`6L;*9ZUOPFTG)>`j=c`;pB4kM)9HsT}vxUxJS^)R8c!J{(JlnE*^WV;OzY3<#&9Y z$AfH;kCG|*(Y<)_=O*e2Suhdlnkn2wJMP^#J?Ft$WVPBp|MMEXHg^8+J|<0)Y!mHk GFM~fRNhFp4 literal 0 HcmV?d00001 diff --git a/zsh/config.zsh b/zsh/config.zsh new file mode 100644 index 0000000..d82534c --- /dev/null +++ b/zsh/config.zsh @@ -0,0 +1,183 @@ +##################################################################### +### preflight config validation ##################################### +##################################################################### + +[[ ${__SCWRYPT} -eq 1 ]] && return 0 # avoid config reload if already active + +# Apparently MacOS puts ALL of the homebrew stuff inside of a top level git repository +# with bizarre git ignores; so: +# - USE the git root if it's a manual install... +# - UNLESS that git root is just the $(brew --prefix) +__SCWRYPTS_ROOT="$(cd -- "${0:a:h}"; git rev-parse --show-toplevel 2>/dev/null | grep -v "^$(brew --prefix 2>/dev/null)$")" + +[ ${__SCWRYPTS_ROOT} ] && [ -d "${__SCWRYPTS_ROOT}" ] \ + || __SCWRYPTS_ROOT="$(echo "${0:a:h}" | sed -n 's|\(share/scwrypts\).*$|\1|p')" + +[ ${__SCWRYPTS_ROOT} ] && [ -d "${__SCWRYPTS_ROOT}" ] || { + echo "cannot determine scwrypts root path for current installation; aborting" + exit 1 +} + +[ -f "${__SCWRYPTS_ROOT}/MANAGED_BY" ] \ + && readonly SCWRYPTS_INSTALLATION_TYPE=$(cat "${__SCWRYPTS_ROOT}/MANAGED_BY") \ + || readonly SCWRYPTS_INSTALLATION_TYPE=manual \ + ; + +##################################################################### + +# +# this is like a manual "use" invocation, but the import driver relies +# on this file, so here we go ahead and do it by hand once +# +# equivalent to "use utils" +# (which is unnecessary since utils are ALWAYS loaded with import.driver.zsh) +# +# normally more logic is necessary for "use", but utils.module.zsh is a +# special module which supports direct-sourcing from any zsh environment +# +source "${__SCWRYPTS_ROOT}/zsh/utils/utils.module.zsh" +SCWRYPTS_LIBRARY_LOADED__scwrypts__utils=true + +##################################################################### +### scwrypts global configuration ################################### +##################################################################### + +readonly SCWRYPTS_CONFIG_PATH="${XDG_CONFIG_HOME:-${HOME}/.config}/scwrypts" +readonly SCWRYPTS_ENV_PATH="${SCWRYPTS_CONFIG_PATH}/environments" + +readonly SCWRYPTS_DATA_PATH="${XDG_DATA_HOME:-${HOME}/.local/share}/scwrypts" + +readonly SCWRYPTS_STATE_PATH="${XDG_STATE_HOME:-${HOME}/.local/state}/scwrypts" +readonly SCWRYPTS_LOG_PATH="${SCWRYPTS_STATE_PATH}/logs" + +[ -d /tmp ] \ + && readonly SCWRYPTS_TEMP_PATH="/tmp/scwrypts/${SCWRYPTS_RUNTIME_ID}" \ + || readonly SCWRYPTS_TEMP_PATH="${XDG_RUNTIME_DIR:-/run/user/${UID}}/scwrypts/${SCWRYPTS_RUNTIME_ID}" \ + ; + +mkdir -p \ + "${SCWRYPTS_ENV_PATH}" \ + "${SCWRYPTS_LOG_PATH}" \ + "${SCWRYPTS_TEMP_PATH}" \ + ; + +DEFAULT_CONFIG="${__SCWRYPTS_ROOT}/zsh/config.user.zsh" +source "${DEFAULT_CONFIG}" + +USER_CONFIG_OVERRIDES="${SCWRYPTS_CONFIG_PATH}/config.zsh" + +[ ! -f "${USER_CONFIG_OVERRIDES}" ] && { + mkdir -p $(dirname "${USER_CONFIG_OVERRIDES}") + cp "${DEFAULT_CONFIG}" "${USER_CONFIG_OVERRIDES}" +} + +source "${USER_CONFIG_OVERRIDES}" +source "${__SCWRYPTS_ROOT}/zsh/config.global.zsh" + +##################################################################### +### load groups and plugins ######################################### +##################################################################### + +SCWRYPTS_GROUPS=() + +command -v echo.warning &>/dev/null || WARNING() { echo "echo.warning : $@" >&2; } +command -v echo.error &>/dev/null || ERROR() { echo "echo.error : $@" >&2; return 1; } +command -v utils.fail &>/dev/null || FAIL() { echo.error "${@:2}"; exit $1; } + +__SCWRYPTS_GROUP_LOADERS=( + "${__SCWRYPTS_ROOT}/scwrypts.scwrypts.zsh" +) + +[ "${GITHUB_WORKSPACE}" ] && [ ! "${SCWRYPTS_GITHUB_NO_AUTOLOAD}" ] && { + SCWRYPTS_GROUP_DIRS+=("${GITHUB_WORKSPACE}") +} + +for __SCWRYPTS_GROUP_DIR in ${SCWRYPTS_GROUP_DIRS[@]} +do + [ -d "${__SCWRYPTS_GROUP_DIR}" ] || continue + for __SCWRYPTS_GROUP_LOADER in $(find "${__SCWRYPTS_GROUP_DIR}" -type f -name \*scwrypts.zsh) + do + __SCWRYPTS_GROUP_LOADERS+=("${__SCWRYPTS_GROUP_LOADER}") + done +done + +scwrypts.config.group() { + local GROUP_NAME="$1" + local CONFIG_KEY="$2" + + [ "$GROUP_NAME" ] && [ "$CONFIG_KEY" ] \ + || return 1 + + echo ${(P)$(echo SCWRYPTS_GROUP_CONFIGURATION__${GROUP_NAME}__${CONFIG_KEY})} +} + +for __SCWRYPTS_GROUP_LOADER in ${__SCWRYPTS_GROUP_LOADERS} +do + __SCWRYPTS_GROUP_LOADER_REALPATH="$(readlink -f -- "${__SCWRYPTS_GROUP_LOADER}")" + + [ -f "${__SCWRYPTS_GROUP_LOADER_REALPATH}" ] || { + echo.warning "error loading group '${__SCWRYPTS_GROUP_LOADER}': cannot read file" + continue + } + + __SCWRYPTS_GROUP_NAME="$(\ + basename -- "${__SCWRYPTS_GROUP_LOADER_REALPATH}" \ + | sed -n 's/^\([a-z][a-z0-9_]*[a-z0-9]\).scwrypts.zsh$/\1/p' \ + )" + + [ "$__SCWRYPTS_GROUP_NAME" ] || { + echo.warning "unable to load group '${__SCWRYPTS_GROUP_LOADER_REALPATH}': invalid group name" >&2 + continue + } + + [[ $(scwrypts.config.group "$__SCWRYPTS_GROUP_NAME" loaded) =~ true ]] && { + echo.warning "unable to load group '${__SCWRYPTS_GROUP_NAME}': duplicate name" + continue + } + + scwryptsgroup="SCWRYPTS_GROUP_CONFIGURATION__${__SCWRYPTS_GROUP_NAME}" + scwryptsgrouproot="$(dirname -- "${__SCWRYPTS_GROUP_LOADER_REALPATH}")" + + : \ + && readonly ${scwryptsgroup}__root="${scwryptsgrouproot}" \ + && source "${__SCWRYPTS_GROUP_LOADER_REALPATH}" \ + && SCWRYPTS_GROUPS+=(${__SCWRYPTS_GROUP_NAME}) \ + && readonly ${scwryptsgroup}__loaded=true \ + || echo.warning "error encountered when loading group '${__SCWRYPTS_GROUP_NAME}'" \ + ; + + [[ ! ${__SCWRYPTS_GROUP_NAME} =~ ^scwrypts$ ]] && [ ! "$(scwrypts.config.group ${__SCWRYPTS_GROUP_NAME} zshlibrary)" ] && { + case $(scwrypts.config.group ${__SCWRYPTS_GROUP_NAME} type) in + ( zsh ) + [ -d "${scwryptsgrouproot}/lib" ] \ + && readonly ${scwryptsgroup}__zshlibrary="${scwryptsgrouproot}/lib" \ + || readonly ${scwryptsgroup}__zshlibrary="${scwryptsgrouproot}" \ + ; + ;; + ( '' ) + [ -d "${scwryptsgrouproot}/zsh/lib" ] \ + && readonly ${scwryptsgroup}__zshlibrary="${scwryptsgrouproot}/zsh/lib" \ + || readonly ${scwryptsgroup}__zshlibrary="${scwryptsgrouproot}/zsh" \ + ; + ;; + esac + } +done + +[[ ${SCWRYPTS_GROUPS[1]} =~ ^scwrypts$ ]] \ + || utils.fail 69 "encountered error when loading essential group 'scwrypts'; aborting" + +##################################################################### +### cleanup ######################################################### +##################################################################### + +unset __SCWRYPTS_ROOT # you should now use '$(scwrypts.config.group scwrypts root)' + +unset \ + __SCWRYPTS_GROUP_LOADER __SCWRYPTS_GROUP_LOADERS __SCWRYPTS_GROUP_LOADER_REALPATH \ + __SCWRYPTS_GROUP_DIR SCWRYPTS_GROUP_DIRS \ + __SCWRYPTS_GROUP_NAME \ + scwryptsgroup scwryptsgrouproot \ + ; + +__SCWRYPT=1 # arbitrary; indicates currently inside a scwrypt diff --git a/zsh/db/postgres/interactive-pgcli b/zsh/db/postgres/interactive-pgcli index d323312..2673912 100755 --- a/zsh/db/postgres/interactive-pgcli +++ b/zsh/db/postgres/interactive-pgcli @@ -1,4 +1,4 @@ -#!/bin/zsh +#!/usr/bin/env zsh use db/postgres ##################################################################### diff --git a/zsh/db/postgres/pg_dump b/zsh/db/postgres/pg_dump index e47cd60..8ea6304 100755 --- a/zsh/db/postgres/pg_dump +++ b/zsh/db/postgres/pg_dump @@ -1,4 +1,4 @@ -#!/bin/zsh +#!/usr/bin/env zsh use db/postgres ##################################################################### diff --git a/zsh/db/postgres/pg_restore b/zsh/db/postgres/pg_restore index a5808d3..718fd06 100755 --- a/zsh/db/postgres/pg_restore +++ b/zsh/db/postgres/pg_restore @@ -1,4 +1,4 @@ -#!/bin/zsh +#!/usr/bin/env zsh use db/postgres ##################################################################### diff --git a/zsh/lib/db/postgres.module.zsh b/zsh/db/postgres/postgres.module.zsh similarity index 70% rename from zsh/lib/db/postgres.module.zsh rename to zsh/db/postgres/postgres.module.zsh index dcc55e8..8d908b4 100644 --- a/zsh/lib/db/postgres.module.zsh +++ b/zsh/db/postgres/postgres.module.zsh @@ -25,7 +25,7 @@ PG_DUMP() { - STATUS " + echo.status " making backup of : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME (compressed) : '$OUTPUT_FILE.dump' @@ -34,21 +34,21 @@ PG_DUMP() { " : \ - && STATUS "creating compressed backup..." \ + && echo.status "creating compressed backup..." \ && eval PGPASSWORD=$(printf '%q ' "$DB_PASS") psql ${PSQL_ARGS[@]} \ --format custom \ --file "$OUTPUT_FILE.dump" \ --verbose \ - && SUCCESS "completed compressed backup" \ - && STATUS "creating raw backup..." \ + && echo.success "completed compressed backup" \ + && echo.status "creating raw backup..." \ && pg_restore -f "$OUTPUT_FILE.raw.sql" "$OUTPUT_FILE.dump" \ - && SUCCESS "completed raw backup" \ - && STATUS "creating single-transaction raw backup..." \ + && echo.success "completed raw backup" \ + && echo.status "creating single-transaction raw backup..." \ && { echo "BEGIN;\n"; cat "$OUTPUT_FILE.raw.sql"; echo "\nEND;" } > "$OUTPUT_FILE.sql" \ - && SUCCESS "completed single-transaction raw backup" \ - || { ERROR "error creating backup for '$DB_HOST/$DB_NAME' (see above)"; return 1; } + && echo.success "completed single-transaction raw backup" \ + || { echo.error "error creating backup for '$DB_HOST/$DB_NAME' (see above)"; return 1; } - SUCCESS " + echo.success " completed backup : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME (compressed) : '$OUTPUT_FILE.dump' @@ -64,11 +64,11 @@ PG_RESTORE() { local FILE POSTGRES__SET_LOGIN_ARGS $@ - local INPUT_FILE=$(find "$DATA_DIR"/backup.* -type f | FZF 'select database file to restore') + local INPUT_FILE=$(find "$DATA_DIR"/backup.* -type f | utils.fzf 'select database file to restore') [ $INPUT_FILE ] && [ -f "$INPUT_FILE" ] || { - ERROR 'no file selected or missing backup file; aborting' - REMINDER " + echo.error 'no file selected or missing backup file; aborting' + echo.reminder " backups must be *.sql or *.dump files starting with the prefix 'backup.' in the following directory: @@ -80,7 +80,7 @@ PG_RESTORE() { local RAW=1 [[ $INPUT_FILE =~ \\.dump$ ]] && RAW=0 - STATUS " + echo.status " loading backup for : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME file : '$INPUT_FILE' @@ -88,13 +88,13 @@ PG_RESTORE() { local EXIT_CODE [[ $RAW -eq 1 ]] && { - REMINDER " + echo.reminder " loading a backup from a raw sql dump may result in data loss make sure your database is ready to accept the database file! " - yN 'continue?' || ABORT + yN 'continue?' || user.abort PSQL < "$INPUT_FILE" EXIT_CODE=$? @@ -110,8 +110,8 @@ PG_RESTORE() { } [[ $EXIT_CODE -eq 0 ]] \ - && SUCCESS "finished restoring backup for '$DB_HOST/$DB_NAME'" \ - || ERROR "error restoring backup for '$DB_HOST/$DB_NAME' (see above)" \ + && echo.success "finished restoring backup for '$DB_HOST/$DB_NAME'" \ + || echo.error "error restoring backup for '$DB_HOST/$DB_NAME' (see above)" \ ; return $EXIT_CODE @@ -120,14 +120,14 @@ PG_RESTORE() { ##################################################################### POSTGRES__LOGIN_INTERACTIVE() { - DEPENDENCIES=(pgcli) CHECK_ENVIRONMENT --optional \ + utils.dependencies.check pgcli --optional \ && COMMAND=pgcli || COMMAND=psql - [[ $COMMAND =~ psql ]] && WARNING "using 'psql' instead" + [[ $COMMAND =~ psql ]] && echo.warning "using 'psql' instead" POSTGRES__SET_LOGIN_ARGS $@ - STATUS " + echo.status " performing login : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME working directory : $DATA_DIR " @@ -146,25 +146,25 @@ POSTGRES__SET_LOGIN_ARGS() { while [[ $# -gt 0 ]] do case $1 in - -h | --host ) DB_HOST="$2"; shift 1 ;; - -p | --port ) DB_PORT="$2"; shift 1 ;; - -d | --name ) DB_NAME="$2"; shift 1 ;; - -U | --user ) DB_USER="$2"; shift 1 ;; - -P | --pass ) DB_PASS="$2"; shift 1 ;; + ( -h | --host ) DB_HOST="$2"; shift 1 ;; + ( -p | --port ) DB_PORT="$2"; shift 1 ;; + ( -d | --name ) DB_NAME="$2"; shift 1 ;; + ( -U | --user ) DB_USER="$2"; shift 1 ;; + ( -P | --pass ) DB_PASS="$2"; shift 1 ;; - --file ) PSQL_FILE="$2"; shift 1 ;; + ( --file ) PSQL_FILE="$2"; shift 1 ;; - --data-dir-prefix ) DATA_DIR_PREFIX="$2"; shift 1 ;; + ( --data-dir-prefix ) DATA_DIR_PREFIX="$2"; shift 1 ;; - * ) PSQL_ARGS+=($1) ;; + ( * ) PSQL_ARGS+=($1) ;; esac shift 1 done [ $PSQL_FILE ] && [ ! -f "$PSQL_FILE" ] \ - && ERROR "no such file available:\n'$PSQL_FILE'" + && echo.error "no such file available:\n'$PSQL_FILE'" - CHECK_ERRORS + utils.check-errors --fail ########################################## diff --git a/zsh/db/postgres/run-sql b/zsh/db/postgres/run-sql index f4f7017..ea30185 100755 --- a/zsh/db/postgres/run-sql +++ b/zsh/db/postgres/run-sql @@ -1,9 +1,9 @@ -#!/bin/zsh +#!/usr/bin/env zsh use db/postgres ##################################################################### MAIN() { - WARNING " \nthis function is in a beta state\n " + echo.warning " \nthis function is in a beta state\n " local _PASS _ARGS=() POSTGRES__SET_LOGIN_ARGS $@ @@ -15,27 +15,27 @@ MAIN() { cd $SQL_DIR [[ $(ls "*.sql" 2>&1 | wc -l) -eq 0 ]] && { - ERROR "you haven't made any SQL commands yet" - REMINDER "add '.sql' files here: '$SQL_DIR/'" + echo.error "you haven't made any SQL commands yet" + echo.reminder "add '.sql' files here: '$SQL_DIR/'" return 1 } - [ ! $INPUT_FILE ] && INPUT_FILE=$(FZF 'select a sql file to run') - [ ! $INPUT_FILE ] && ABORT + [ ! $INPUT_FILE ] && INPUT_FILE=$(utils.fzf 'select a sql file to run') + [ ! $INPUT_FILE ] && user.abort - [ ! -f "$INPUT_FILE" ] && FAIL 2 "no such sql file '$SQL_DIR/$INPUT_FILE'" + [ ! -f "$INPUT_FILE" ] && utils.fail 2 "no such sql file '$SQL_DIR/$INPUT_FILE'" - STATUS "loading '$INPUT_FILE' preview..." + echo.status "loading '$INPUT_FILE' preview..." LESS "$INPUT_FILE" - STATUS "login : $_USER@$_HOST:$_PORT/$_NAME" - STATUS "command : '$INPUT_FILE'" + echo.status "login : $_USER@$_HOST:$_PORT/$_NAME" + echo.status "command : '$INPUT_FILE'" - yN 'run this command?' || ABORT + yN 'run this command?' || user.abort - STATUS "running '$INPUT_FILE'" + echo.status "running '$INPUT_FILE'" PSQL < $INPUT_FILE \ - && SUCCESS "finished running '$INPUT_FILE'" \ - || FAIL 3 "something went wrong running '$INPUT_FILE' (see above)" + && echo.success "finished running '$INPUT_FILE'" \ + || utils.fail 3 "something went wrong running '$INPUT_FILE' (see above)" } diff --git a/zsh/docker/cleanup b/zsh/docker/cleanup index dec86b9..2241427 100755 --- a/zsh/docker/cleanup +++ b/zsh/docker/cleanup @@ -1,13 +1,29 @@ -#!/bin/zsh +#!/usr/bin/env zsh DEPENDENCIES+=(docker) ##################################################################### MAIN() { - WARNING 'this will prune all docker resources from the current machine' - WARNING 'pruned resources are PERMANENTLY DELETED' - yN 'continue?' || return 1 + local RESOURCES=( + container + image + volume + system + ) - SUCCESS "CONTAINER : $(docker container prune -f 2>/dev/null | tail -n 1)" - SUCCESS "IMAGE : $(docker image prune -f 2>/dev/null | tail -n 1)" - SUCCESS "VOLUME : $(docker volume prune -f 2>/dev/null | tail -n 1)" + echo.warning " + this will prune the following docker resources from the + current machine: + (${RESOURCES[@]}) + + pruned resources are PERMANENTLY DELETED + " + + utils.yN 'continue?' || utils.abort + + echo.success "$( + for RESOURCE in ${RESOURCES[@]} + do + echo "${RESOURCE}^:^$(docker ${RESOURCE} prune -f 2>/dev/null | tail -n 1)" + done | column -ts '^' + )" } diff --git a/zsh/hello-world b/zsh/hello-world index 5352069..5b57e0c 100755 --- a/zsh/hello-world +++ b/zsh/hello-world @@ -1,6 +1,6 @@ -#!/bin/zsh +#!/usr/bin/env zsh ##################################################################### MAIN() { - SUCCESS 'Hello, World!' + echo.success 'Hello, World!' } diff --git a/zsh/helm/get-template b/zsh/helm/get-template index 195b49e..f019b5b 100755 --- a/zsh/helm/get-template +++ b/zsh/helm/get-template @@ -1,9 +1,13 @@ -#!/bin/zsh -use helm -use scwrypts +#!/usr/bin/env zsh ##################################################################### -MAIN() { - unset USAGE - HELM__TEMPLATE__GET $@ -} +use helm + +##################################################################### + +helm.zshparse.usage +helm.get-template.parse.usage + +##################################################################### + +MAIN() { helm.get-template $@; } diff --git a/zsh/helm/get-template.module.zsh b/zsh/helm/get-template.module.zsh new file mode 100644 index 0000000..d0e7eb8 --- /dev/null +++ b/zsh/helm/get-template.module.zsh @@ -0,0 +1,135 @@ +##################################################################### + +use scwrypts/get-realpath + +use helm/zshparse + +DEPENDENCIES+=(helm) + +##################################################################### + +${scwryptsmodule}() { + local PARSERS=(helm.zshparse) + eval "$(utils.parse.autosetup)" + + ########################################## + + local HELM_LINT_ARGS=(${HELM_ARGS[@]}) + + [[ ${USE_CHART_ROOT} =~ false ]] \ + && HELM_ARGS+=(--show-only "$(echo "${TEMPLATE_FILENAME}" | sed "s|^${CHART_ROOT}/||")") + + local TEMPLATE_OUTPUT DEBUG_OUTPUT + utils.io.capture TEMPLATE_OUTPUT DEBUG_OUTPUT \ + helm template "${CHART_ROOT}" ${HELM_ARGS[@]} --debug \ + ; + + local EXIT_CODE + [ "${TEMPLATE_OUTPUT}" ] && EXIT_CODE=0 || EXIT_CODE=1 + + case ${OUTPUT_MODE} in + ( raw ) + [[ ${EXIT_CODE} -eq 0 ]] \ + && echo "${TEMPLATE_OUTPUT}" | grep -v '^# Source:.*$' \ + || echo "${DEBUG_OUTPUT}" >&2 \ + ; + ;; + + ( color ) + [[ ${EXIT_CODE} -eq 0 ]] \ + && echo "${TEMPLATE_OUTPUT}" | bat --language yaml --color always \ + || echo "${DEBUG_OUTPUT}" >&2 \ + ; + ;; + + ( debug ) + [[ ${EXIT_CODE} -eq 0 ]] \ + && KUBEVAL_RAW=$( + echo "${TEMPLATE_OUTPUT}" \ + | kubeval --schema-location https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master \ + ) \ + || KUBEVAL_RAW='no template output; kubeval skipped' + + echo " + ${TEMPLATE_OUTPUT} + --- + debug: |\n$(echo ${DEBUG_OUTPUT} | sed 's/^/ /g') + + kubeval: |\n$(echo ${KUBEVAL_RAW} | sed 's/^/ /g') + + lint: |\n$(helm lint "${CHART_ROOT}" ${HELM_LINT_ARGS[@]} 2>&1 | sed 's/^/ /g') + " | sed 's/^ \+//; 1d; $d' + ;; + esac + + return ${EXIT_CODE} +} + +##################################################################### + +${scwryptsmodule}.parse() { + local PARSED=0 + + case $1 in + ( --colorize ) PARSED=1; OUTPUT_MODE=color ;; + ( --raw ) PARSED=1; OUTPUT_MODE=raw ;; + ( --debug ) PARSED=1; OUTPUT_MODE=debug ;; + + ( --update ) PARSED=1; UPDATE_DEPENDENCIES=true ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.parse.locals() { + local OUTPUT_MODE=default + local UPDATE_DEPENDENCIES=false +} + +${scwryptsmodule}.parse.usage() { + USAGE__description=" + Smart helm-template generator which auto-detects the chart + and sample values for testing and developing helm charts. + " + + local DEFAULT + utils.dependencies.check bat &>/dev/null \ + && DEFAULT=color || DEFAULT=raw + + USAGE__options+=" + --colorize $([[ ${DEFAULT} =~ color ]] && printf '(default) ')use 'bat' to colorize output + --raw $([[ ${DEFAULT} =~ raw ]] && printf '(default) ')remove scwrypts-added fluff and only output helm template details + --debug debug template with kubeval and helm-lint + + --update update dependencies before generating template output + " +} + +${scwryptsmodule}.parse.validate() { + case ${OUTPUT_MODE} in + ( default ) + utils.dependencies.check bat &>/dev/null \ + && OUTPUT_MODE=color \ + || OUTPUT_MODE=raw \ + ; + ;; + + ( color ) + utils.dependencies.check bat || ((ERRORS+=1)) + ;; + + ( debug ) + utils.dependencies.check kubeval \ + || echo.error 'kubeval is required for --debug' + ;; + esac + + case ${UPDATE_DEPENDENCIES} in + ( false ) ;; + ( true ) + use helm/update-dependencies + helm.update-dependencies --template-filename "${TEMPLATE_FILENAME}" &>/dev/null \ + || echo.error 'failed to update dependencies' + ;; + esac +} diff --git a/zsh/helm/helm.module.zsh b/zsh/helm/helm.module.zsh new file mode 100644 index 0000000..9df49c6 --- /dev/null +++ b/zsh/helm/helm.module.zsh @@ -0,0 +1,15 @@ +# +# helm template testing and generation helpers +# + + +# ensures default values are injected from local Chart dependencies +use helm/update-dependencies + + +# template generation +use helm/get-template + + +# shared argument parser +use helm/zshparse diff --git a/zsh/helm/update-dependencies b/zsh/helm/update-dependencies index 14779a0..1b0b65e 100755 --- a/zsh/helm/update-dependencies +++ b/zsh/helm/update-dependencies @@ -1,9 +1,13 @@ -#!/bin/zsh -use helm -use scwrypts +#!/usr/bin/env zsh ##################################################################### -MAIN() { - unset USAGE - HELM__DEPENDENCY__UPDATE $@ -} +use helm + +##################################################################### + +helm.zshparse.usage +helm.update-dependencies.parse.usage + +##################################################################### + +MAIN() { helm.update-dependencies $@; } diff --git a/zsh/helm/update-dependencies.module.zsh b/zsh/helm/update-dependencies.module.zsh new file mode 100644 index 0000000..3b463b2 --- /dev/null +++ b/zsh/helm/update-dependencies.module.zsh @@ -0,0 +1,31 @@ +##################################################################### + +use helm/zshparse + +DEPENDENCIES+=(helm) + +##################################################################### + +${scwryptsmodule}() { + local PARSERS=(helm.zshparse) + + eval "$(utils.parse.autosetup)" + + ########################################## + + echo.status "updating helm dependencies for '${CHART_ROOT}'" \ + + helm dependency update "${CHART_ROOT}" \ + && echo.success "helm chart dependencies updated" \ + || echo.error "unable to update helm chart dependencies (see above)" \ + || return 1 +} + +##################################################################### + +${scwryptsmodule}.parse() { return 0; } +${scwryptsmodule}.parse.usage() { + USAGE__description=' + Auto-detect chart and build dependencies for any file within a helm chart. + ' +} diff --git a/zsh/helm/validate.module.zsh b/zsh/helm/validate.module.zsh new file mode 100644 index 0000000..ad17dfc --- /dev/null +++ b/zsh/helm/validate.module.zsh @@ -0,0 +1,119 @@ +##################################################################### + +DEPENDENCIES+=(yq) +REQUIRED_ENV+=() + +##################################################################### + +${scwryptsmodule}() { + local USAGE=" + Smart helm-detection / validator which determines the helm + chart root and other details given a particular filename. + + You must set TEMPLATE_FILENAME, and this function will verify + the template is part of a helm chart and set up the following + variables: + + - CHART_ROOT : the fully qualified path to the directory + containing Chart.yaml + + - CHART_NAME : Chart.yaml > .name + + - USE_CHART_ROOT (true/false) + true : operations should use/output the entire chart + false : operations should use/output a single template + + - HELM_ARGS : an array of arguments which apply to any 'helm' + command + " + + [ "${TEMPLATE_FILENAME}" ] && [ -f "${TEMPLATE_FILENAME}" ] \ + || echo.error 'must provide a template filename' \ + || return 1 + + ########################################## + + CHART_ROOT="$(helm.validate.get-chart-root)" + [ ${CHART_ROOT} ] && [ -d "${CHART_ROOT}" ] \ + || echo.error 'unable to determine helm root; is this a helm template file?' \ + || return 1 + + ########################################## + + CHART_NAME=$(utils.yq -r .name "${CHART_ROOT}/Chart.yaml") + + ########################################## + + USE_CHART_ROOT=false + + case "${TEMPLATE_FILENAME}" in + ( *values.*.yaml | *tests/*.yaml ) + HELM_ARGS+=(--values ${TEMPLATE_FILENAME}) + USE_CHART_ROOT=true + ;; + + ( *.tpl ) + USE_CHART_ROOT=true + ;; + esac + + [[ $(dirname -- "${TEMPLATE_FILENAME}") =~ ^${CHART_ROOT}$ ]] \ + && USE_CHART_ROOT=true + + ########################################## + + HELM_ARGS=($(helm.validate.get-default-values-args) ${HELM_ARGS[@]}) + + ########################################## + + return 0 +} + +${scwryptsmodule}.get-chart-root() { + local SEARCH_DIR=$(dirname -- "${TEMPLATE_FILENAME}") + while [[ ! ${SEARCH_DIR} =~ ^/$ ]] + do + [ -f "${SEARCH_DIR}/Chart.yaml" ] \ + && echo "${SEARCH_DIR}" \ + && return 0 \ + ; + + SEARCH_DIR="$(dirname -- "${SEARCH_DIR}")" + done + return 1 +} + +${scwryptsmodule}.get-default-values-args() { + local F + local VALUES_FILES_ORDER=( + values.yaml # the default values of the chart + tests/default.yaml # a template test which provides any required values not included in the default values + ) + + local LOCAL_DEPENDENCY_CHART LOCAL_CHART_ROOT + for LOCAL_DEPENDENCY_CHART in $(\ + cat "${CHART_ROOT}/Chart.yaml" \ + | utils.yq -r '.dependencies[] | .repository' \ + | grep '^file://' \ + | sed 's|file://||' \ + ) + do + [[ "${LOCAL_DEPENDENCY_CHART}" =~ ^[/~] ]] \ + && LOCAL_CHART_ROOT="${LOCAL_DEPENDENCY_CHART}" \ + || LOCAL_CHART_ROOT=$(readlink -f -- "${CHART_ROOT}/${LOCAL_DEPENDENCY_CHART}") \ + ; + + for F in ${VALUES_FILES_ORDER[@]} + do + [ -f "${LOCAL_CHART_ROOT}/${F}" ] \ + && echo --values "${LOCAL_CHART_ROOT}/${F}" + done + done + + local HELM_VALUES_ARGS=() + for F in ${VALUES_FILES_ORDER[@]} + do + [ -f "${CHART_ROOT}/${F}" ] \ + && echo --values "${CHART_ROOT}/${F}" + done +} diff --git a/zsh/helm/zshparse.module.zsh b/zsh/helm/zshparse.module.zsh new file mode 100644 index 0000000..8c3b2f7 --- /dev/null +++ b/zsh/helm/zshparse.module.zsh @@ -0,0 +1,54 @@ +##################################################################### + +use helm/validate +use scwrypts/get-realpath + +##################################################################### + +${scwryptsmodule}() { + local PARSED=0 + + case $1 in + ( -t | --template-filename ) + PARSED=2 + TEMPLATE_FILENAME="$(scwrypts.get-realpath "$2")" + ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.locals() { + local TEMPLATE_FILENAME + local ARGS=() + + # configured by helm.validate + local CHART_NAME + local CHART_ROOT + local HELM_ARGS=() +} + +${scwryptsmodule}.usage() { + USAGE__options+=' + -t, --template-filename path to a template/*.yaml file of a helm chart + ' + + USAGE__args+=' + \$@ additional args are forwarded to helm + ' +} + +${scwryptsmodule}.validate() { + helm.validate || return 1 + + HELM_ARGS+=(${ARGS[@]}) + + echo.debug " + template filename : ${TEMPLATE_FILENAME} + chart name : ${CHART_NAME} + chart root : ${CHART_ROOT} + helm args : ${HELM_ARGS[@]} + " +} + +##################################################################### diff --git a/zsh/import.driver.zsh b/zsh/import.driver.zsh new file mode 100644 index 0000000..3060ed3 --- /dev/null +++ b/zsh/import.driver.zsh @@ -0,0 +1,340 @@ +command -v use use.is-loaded use.get-library-root &>/dev/null && return 0 + + ################################################################### +# # +# usage: use [OPTIONS ...] zsh/module/path # +# # + ################################################################### +# # +# OPTIONS: # +# # +# -g, --group lookup library root from friendly group # +# name (requires configuration) # +# (default: scwrypts) # +# # +# -r, --library-root fully qualified path to a library root # +# # +# --check-environment check environment immediately rather than # +# wait for downstream call to # +# utils.check-environment # +# # +# # +# ZSHIMPORT_USE_CACHE (true|false; default: true) # +# setting this to false will always require direct, source files # +# # +# Allows for import-style library loading in zsh. No matter what # +# scwrypt is run, this function (and required helpers) are *also* # +# loaded, ensuring that 'use' is always available in scwrypts # +# context. # +# # +# # +# Friendly group-names can be configured by setting the variable # +# 'SCWRYPTS_GROUP_CONFIGRUATION____root' to the fully # +# qualified path to the root directory of the modules library. # +# # +# # + ################################################################### + + +# I have no idea why, but CircleCI obliterates this env var in particular +# every time. Just going to force it like this for now +[ $CIRCLECI ] && export ZSHIMPORT_USE_CACHE=false + +[ ${ZSHIMPORT_USE_CACHE} ] || export ZSHIMPORT_USE_CACHE=true + +[[ ${ZSHIMPORT_USE_CACHE} =~ true ]] && { + command -v jo jq sha1sum &>/dev/null || { + echo.warning "missing utilities prevents import cache" + export ZSHIMPORT_USE_CACHE=false + } +} + +[ ${ZSHIMPORT_CACHE_DIR} ] || export ZSHIMPORT_CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/zshimport" + +source "${0:a:h}/config.zsh" + +use() { + local SCWRYPTS_LIBRARY SCWRYPTS_LIBRARY_ROOT SCWRYPTS_LIBRARY_GROUP + local DEFER_ENVIRONMENT_CHECK=true + + local ONLY_OUTPUT_METADATA=false + local ONLY_GENERATE_CACHE=false + + while [[ $# -gt 0 ]] + do + case $1 in + ( -g | --group ) + [ "${SCWRYPTS_LIBRARY_ROOT}" ] && echo.error 'specify only one of {(-g), (-r)}' + SCWRYPTS_LIBRARY_GROUP=$2 + shift 1 + ;; + + ( -r | --library-root ) + [ "${SCWRYPTS_LIBRARY_GROUP}" ] && echo.error 'specify only one of {(-g), (-r)}' + SCWRYPTS_LIBRARY_ROOT=$2 + shift 1 + ;; + + ( -c | --check-environment ) + DEFER_ENVIRONMENT_CHECK=false + ;; + + ( --meta ) + ONLY_OUTPUT_METADATA=true + ;; + + ( --generate-cache ) + ONLY_GENERATE_CACHE=true + ;; + + ( * ) + [ ! "${SCWRYPTS_LIBRARY}" ] \ + && SCWRYPTS_LIBRARY=$1 \ + || echo.error 'too many arguments; expected exactly 1 argument' \ + + ;; + esac + shift 1 + done + + [ ! "${SCWRYPTS_LIBRARY}" ] && echo.error 'no library specified for import' + + : \ + && [ ! "${SCWRYPTS_LIBRARY_GROUP}" ] \ + && [ ! "${SCWRYPTS_LIBRARY_ROOT}" ] \ + && SCWRYPTS_LIBRARY_GROUP=scwrypts + + # bail ASAP, check errors later + use.is-loaded && [[ ${ONLY_OUTPUT_METADATA} =~ false ]] && [[ ${ONLY_GENERATE_CACHE} =~ false ]] && return 0 + + [ ! "${SCWRYPTS_LIBRARY_ROOT}" ] && SCWRYPTS_LIBRARY_ROOT="$(use.get-scwrypts-library-root)" + [ ! "${SCWRYPTS_LIBRARY_ROOT}" ] && echo.error "unable to determine library root from group name '${SCWRYPTS_LIBRARY_GROUP}'" + + ##################################################################### + + local LIBRARY_FILE LIBRARY_FILE_TEMP CACHE_FILE + + [ ! "${LIBRARY_FILE}" ] && { + LIBRARY_FILE_TEMP="${SCWRYPTS_LIBRARY_ROOT}/${SCWRYPTS_LIBRARY}.module.zsh" + [ -f "${LIBRARY_FILE_TEMP}" ] && { + LIBRARY_FILE="${LIBRARY_FILE_TEMP}" + CACHE_FILE="${SCWRYPTS_LIBRARY}.module.zsh" + } + } + + [ ! "${LIBRARY_FILE}" ] && { # "group" library reference + LIBRARY_FILE_TEMP="${SCWRYPTS_LIBRARY_ROOT}/${SCWRYPTS_LIBRARY}/$(basename -- "${SCWRYPTS_LIBRARY}").module.zsh" + [ -f "${LIBRARY_FILE_TEMP}" ] && { + LIBRARY_FILE="${LIBRARY_FILE_TEMP}" + CACHE_FILE="${SCWRYPTS_LIBRARY}/$(basename -- "${SCWRYPTS_LIBRARY}").module.zsh" + } + } + + [ "${LIBRARY_FILE}" ] \ + || echo.error "no such library '${SCWRYPTS_LIBRARY_GROUP}/${SCWRYPTS_LIBRARY}'" + + ##################################################################### + + local LIBRARY_HASH LIBRARY_CACHE_DIR LIBRARY_CACHE_FILE + + ##################################################################### + + utils.check-errors || { + ((IMPORT_ERRORS+=1)) + return 1 + } + + ##################################################################### + + local SCWRYPTS_MODULE_BEFORE=${scwryptsmodule} + [[ ${SCWRYPTS_LIBRARY_GROUP} =~ ^scwrypts$ ]] \ + && export scwryptsmodule="$(echo "${SCWRYPTS_LIBRARY}" | sed 's|/|.|g')" \ + || export scwryptsmodule="${SCWRYPTS_LIBRARY_GROUP}.$(echo "${SCWRYPTS_LIBRARY}" | sed 's|/|.|g')" \ + ; + + [[ ${ONLY_OUTPUT_METADATA} =~ true ]] && { + use.get-metadata + return 0 + } + + case "${ZSHIMPORT_USE_CACHE}" in + ( false ) ;; + ( true ) + LIBRARY_HASH="$(use.compute-scwrypts-library-hash)" + LIBRARY_CACHE_DIR="${ZSHIMPORT_CACHE_DIR}/${SCWRYPTS_LIBRARY_GROUP}-${LIBRARY_HASH}" + LIBRARY_CACHE_FILE="${LIBRARY_CACHE_DIR}/${CACHE_FILE}" + + [ "${LIBRARY_HASH}" ] && [ "${LIBRARY_CACHE_DIR}" ] && [ "${LIBRARY_CACHE_FILE}" ] \ + || echo.error "error when computing library hash for ${SCWRYPTS_LIBRARY_GROUP}/${SCWRYPTS_LIBRARY}" + + use.generate-cache \ + || echo.error "error generating cache for ${SCWRYPTS_LIBRARY_GROUP}/${SCWRYPTS_LIBRARY}" \ + || return 1 + ;; + esac + + [[ ${ONLY_GENERATE_CACHE} =~ true ]] && { + cat "${LIBRARY_CACHE_FILE}" | grep . + return $? + } + + case ${ZSHIMPORT_USE_CACHE} in + ( true ) + source "${LIBRARY_CACHE_FILE}" || { + ((IMPORT_ERRORS+=1)) + echo.error "import error for '${SCWRYPTS_LIBRARY_GROUP}/${SCWRYPTS_LIBRARY}'" + echo.debug "cache : '${LIBRARY_CACHE_FILE}'" + return 1 + } + ;; + + ( false ) + + source "${LIBRARY_FILE}" || { + ((IMPORT_ERRORS+=1)) + echo.error "import error for '${SCWRYPTS_LIBRARY_GROUP}/${SCWRYPTS_LIBRARY}'" + export scwryptsmodule=${SCWRYPTS_MODULE_BEFORE} + return 1 + } + + [[ ${DEFER_ENVIRONMENT_CHECK} =~ false ]] && { + utils.check-environment || { + ((IMPORT_ERRORS+=1)) + echo.error "import error for '${SCWRYPTS_LIBRARY_GROUP}/${SCWRYPTS_LIBRARY}'" + return 1 + } + } + + use.is-loaded --set + [[ ${SCWRYPTS_MODULE_BEFORE} ]] \ + && export scwryptsmodule=${SCWRYPTS_MODULE_BEFORE} \ + || unset scwryptsmodule \ + ; + ;; + esac + + return 0 +} + +use.get-scwrypts-library-root() { + local VARIABLE_NAME="SCWRYPTS_LIBRARY_ROOT__${SCWRYPTS_LIBRARY_GROUP}" + echo "${(P)VARIABLE_NAME}" | grep . && return 0 + + ########################################## + + local ROOT + + ROOT="$(scwrypts.config.group "${SCWRYPTS_LIBRARY_GROUP}" zshlibrary)" + [ "${ROOT}" ] && eval ${VARIABLE_NAME}="${ROOT}" && echo "${ROOT}" && return 0 + + ########################################## + + local GROUP_ROOT="$(scwrypts.config.group "${SCWRYPTS_LIBRARY_GROUP}" root)" + local GROUP_TYPE="$(scwrypts.config.group "${SCWRYPTS_LIBRARY_GROUP}" type)" + + [[ ${GROUP_TYPE} =~ zsh ]] \ + && ROOT="${GROUP_ROOT}/lib" \ + || ROOT="${GROUP_ROOT}/zsh/lib" \ + ; + + [ -d "${ROOT}" ] || ROOT="$(dirname -- "${ROOT}")" + + [ "${ROOT}" ] && [ -d "${ROOT}" ] \ + || echo.error "unable to determine library root" \ + || return 1 + + eval ${VARIABLE_NAME}="${ROOT}" + echo "${ROOT}" +} + +use.compute-scwrypts-library-hash() { + LC_ALL=POSIX find "${SCWRYPTS_LIBRARY_ROOT}" -type f -name \*.module.zsh -print0 \ + | sort -z \ + | xargs -0 sha1sum \ + | sha1sum \ + | awk '{print $1;}' \ + ; +} + +use.is-loaded() { + local VARIABLE_NAME="SCWRYPTS_LIBRARY_LOADED__${SCWRYPTS_LIBRARY_GROUP}__$(echo ${SCWRYPTS_LIBRARY} | sed 's|[/-]|_|g')" + + [[ $1 =~ ^--set$ ]] && eval ${VARIABLE_NAME}=true + + [[ ${(P)VARIABLE_NAME} =~ true ]] +} + +use.get-metadata() { + jo \ + LIBRARY_FILE="${LIBRARY_FILE}" \ + SCWRYPTS_LIBRARY_GROUP="${SCWRYPTS_LIBRARY_GROUP}" \ + SCWRYPTS_LIBRARY="${SCWRYPTS_LIBRARY}" \ + scwryptsmodule="${scwryptsmodule}" \ + ; +} + +##################################################################### + +use.generate-cache() { + [ "${LIBRARY_CACHE_FILE}" ] || return 1 + + [ -f "${LIBRARY_CACHE_FILE}" ] && return 0 + + ########################################## + + mkdir -p -- "$(dirname -- "${LIBRARY_CACHE_FILE}")" + + local IMPORTS=":${LIBRARY_FILE}:" + + use.generate-cache.create-import $(use.get-metadata) > "${LIBRARY_CACHE_FILE}" + + local METADATA SUBFILE SUBMODULE + while $(grep -q '^use\s' "${LIBRARY_CACHE_FILE}") + do + NEXT_IMPORT=$(grep '^use\s' ${LIBRARY_CACHE_FILE} | head -n1) + METADATA="$(eval "${NEXT_IMPORT} --meta")" + + [ "${METADATA}" ] \ + || echo.error "error getting metadata for '${NEXT_IMPORT}'" \ + || return 1 + + SUBFILE="$(echo "${METADATA}" | jq -r .LIBRARY_FILE)" + [[ "${IMPORTS}" =~ ":${SUBFILE}:" ]] && { + grep -v "^${NEXT_IMPORT}$" "${LIBRARY_CACHE_FILE}" > "${LIBRARY_CACHE_FILE}.tmp" + mv "${LIBRARY_CACHE_FILE}.tmp" "${LIBRARY_CACHE_FILE}" + continue + } + + IMPORTS+="${SUBFILE}:" + + SUBMODULE="$(echo "${METADATA}" | jq -r .scwryptsmodule)" + use.generate-cache.create-import "${METADATA}" > "${LIBRARY_CACHE_FILE}.subfile" + + { + sed -n '0,/^use\s/p' ${LIBRARY_CACHE_FILE} | sed '$d' + echo '() {' + cat "${LIBRARY_CACHE_FILE}.subfile" + echo '}' + sed -n '/^use\s/,$p' ${LIBRARY_CACHE_FILE} | sed '1d' + } > "${LIBRARY_CACHE_FILE}.tmp" + mv "${LIBRARY_CACHE_FILE}.tmp" "${LIBRARY_CACHE_FILE}" + rm "${LIBRARY_CACHE_FILE}.subfile" + done +} + +use.generate-cache.create-import() { + local METADATA="$1" + + local FILENAME="$(echo "${METADATA}" | jq -r .LIBRARY_FILE)" + local SCWRYPTSMODULE="$(echo "${METADATA}" | jq -r .scwryptsmodule)" + local GROUP="$(echo "${METADATA}" | jq -r .SCWRYPTS_LIBRARY_GROUP)" + local LIBRARY="$(echo "${METADATA}" | jq -r .SCWRYPTS_LIBRARY | sed 's|[/-]|_|g')" + + local IS_LOADED_VARIABLE="SCWRYPTS_LIBRARY_LOADED__${GROUP}__${LIBRARY}" + + echo "[[ \$${IS_LOADED_VARIABLE} =~ true ]] && return 0" + echo "export scwryptsmodule=${SCWRYPTSMODULE}" + sed "/^use\\s/aexport scwryptsmodule=${SCWRYPTSMODULE}" "${FILENAME}" + echo "${IS_LOADED_VARIABLE}=true" + echo "unset scwryptsmodule" +} diff --git a/zsh/lib/cloud/aws/cli.module.zsh b/zsh/lib/cloud/aws/cli.module.zsh deleted file mode 100644 index a84cb9b..0000000 --- a/zsh/lib/cloud/aws/cli.module.zsh +++ /dev/null @@ -1,23 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - aws -) - -REQUIRED_ENV+=() - -##################################################################### - -AWS() { - local ARGS=() - - ARGS+=(--output json) - - [ ! $CI ] && { - REQUIRED_ENV=(AWS_REGION AWS_ACCOUNT AWS_PROFILE) CHECK_ENVIRONMENT || return 1 - ARGS+=(--profile $AWS_PROFILE) - ARGS+=(--region $AWS_REGION) - } - - aws ${ARGS[@]} $@ -} diff --git a/zsh/lib/cloud/aws/ecr.module.zsh b/zsh/lib/cloud/aws/ecr.module.zsh deleted file mode 100644 index 6cb4f40..0000000 --- a/zsh/lib/cloud/aws/ecr.module.zsh +++ /dev/null @@ -1,27 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - docker -) - -REQUIRED_ENV+=() - -use cloud/aws/cli - -##################################################################### - -ECR_LOGIN() { - REQUIRED_ENV=(AWS_REGION AWS_ACCOUNT) CHECK_ENVIRONMENT || return 1 - - STATUS "performing AWS ECR docker login" - AWS ecr get-login-password \ - | docker login \ - --username AWS \ - --password-stdin \ - "$AWS_ACCOUNT.dkr.ecr.$AWS_REGION.amazonaws.com" \ - && SUCCESS "authenticated docker for '$AWS_ACCOUNT' in '$AWS_REGION'" \ - || { - ERROR "unable to authenticate docker for '$AWS_ACCOUNT' in '$AWS_REGION'" - return 1 - } -} diff --git a/zsh/lib/cloud/aws/eks.module.zsh b/zsh/lib/cloud/aws/eks.module.zsh deleted file mode 100644 index efc059e..0000000 --- a/zsh/lib/cloud/aws/eks.module.zsh +++ /dev/null @@ -1,90 +0,0 @@ -##################################################################### - -DEPENDENCIES+=(kubectl yq) -REQUIRED_ENV+=() - -use cloud/aws/cli - -##################################################################### - -EKS__KUBECTL() { EKS kubectl $@; } -EKS__FLUX() { EKS flux $@; } - -##################################################################### - -EKS() { - local USAGE=" - usage: cli [...kubectl args...] - - args: - cli a kubectl-style CLI (e.g. kubectl, helm, flux, etc) - - Allows access to kubernetes CLI commands by configuring environment - to point to a specific cluster. - " - - REQUIRED_ENV=(AWS_REGION AWS_ACCOUNT CLUSTER_NAME) DEPENDENCIES=(kubectl $1) CHECK_ENVIRONMENT || return 1 - - local CONTEXT="arn:aws:eks:${AWS_REGION}:${AWS_ACCOUNT}:cluster/${CLUSTER_NAME}" - - kubectl config get-contexts | grep -q $CONTEXT \ - || EKS__CLUSTER_LOGIN -c $CLUSTER_NAME >/dev/null - - local CONTEXT_ARGS=() - case $1 in - helm ) CONTEXT_ARGS+=(--kube-context $CONTEXT) ;; - * ) CONTEXT_ARGS+=(--context $CONTEXT) ;; - esac - - $1 ${CONTEXT_ARGS[@]} ${@:2} -} - -##################################################################### - -EKS__CLUSTER_LOGIN() { - local USAGE=" - usage: [...options...] - - options - -c, --cluster-name (optional) login a specific cluster - - - Interactively sets the default kubeconfig to match the selected - cluster in EKS. Also creates the kubeconfig entry if it does not - already exist. - " - REQUIRED_ENV=(AWS_ACCOUNT AWS_REGION) CHECK_ENVIRONMENT || return 1 - - - local CLUSTER_NAME - - while [[ $# -gt 0 ]] - do - case $1 in - -c | --cluster-name ) CLUSTER_NAME="$2"; shift 1 ;; - - * ) [ ! $APPLICATION ] && APPLICATION="$1" \ - || ERROR "extra positional argument '$1'" - ;; - esac - shift 1 - done - - [ ! $CLUSTER_NAME ] && CLUSTER_NAME=$(\ - AWS eks list-clusters \ - | jq -r '.[] | .[]' \ - | FZF 'select a cluster' - ) - - [ ! $CLUSTER_NAME ] && ERROR 'must select a valid cluster or use -c flag' - - CHECK_ERRORS - - ########################################## - - STATUS 'creating / updating kubeconfig for EKS cluster' - STATUS "updating kubeconfig for '$CLUSTER_NAME'" - AWS eks update-kubeconfig --name $CLUSTER_NAME \ - && SUCCESS "kubeconfig updated with '$CLUSTER_NAME'" \ - || ERROR "failed to update kubeconfig; do you have permissions to access '$CLUSTER_NAME'?" -} diff --git a/zsh/lib/cloud/aws/eksctl.module.zsh b/zsh/lib/cloud/aws/eksctl.module.zsh deleted file mode 100644 index 5598f0e..0000000 --- a/zsh/lib/cloud/aws/eksctl.module.zsh +++ /dev/null @@ -1,116 +0,0 @@ -##################################################################### - -DEPENDENCIES+=(eksctl) -REQUIRED_ENV+=() - -use cloud/aws/eks - -##################################################################### - -EKSCTL() { - REQUIRED_ENV=(AWS_PROFILE AWS_REGION) CHECK_ENVIRONMENT || return 1 - - AWS_PROFILE=$AWS_PROFILE AWS_REGION=$AWS_REGION \ - eksctl $@ -} - -EKSCTL__CREATE_IAMSERVICEACCOUNT() { - local USAGE=" - usage: serviceaccount-name namespace [...options...] -- [...'eksctl create iamserviceaccount' args...] - - options: - --serviceaccount (required) target k8s:ServiceAccount - --namespace (required) target k8s:Namespace - --role-name (required) name of the IAM role to assign - - --force don't check for existing serviceaccount and override any existing configuration - - eksctl create iamserviceaccount args: - $(eksctl create iamserviceaccount --help 2>&1 | grep -v -- '--name' | grep -v -- '--namespace' | grep -v -- '--role-name' | sed 's/^/ /') - " - REQUIRED_ENV=(AWS_REGION AWS_ACCOUNT CLUSTER_NAME) CHECK_ENVIRONMENT || return 1 - - local SERVICEACCOUNT NAMESPACE ROLE_NAME - local FORCE=0 - local EKSCTL_ARGS=() - - while [[ $# -gt 0 ]] - do - case $1 in - --serviceaccount ) SERVICEACCOUNT=$2; shift 1 ;; - --namespace ) NAMESPACE=$2; shift 1 ;; - --role-name ) ROLE_NAME=$2; shift 1 ;; - - --force ) FORCE=1 ;; - - -- ) shift 1; break ;; - - * ) ERROR "unknown argument '$1'" ;; - esac - shift 1 - done - - while [[ $# -gt 0 ]]; do EKSCTL_ARGS+=($1); shift 1; done - - [ $SERVICEACCOUNT ] || ERROR "--serviceaccount is required" - [ $NAMESPACE ] || ERROR "--namespace is required" - [ $ROLE_NAME ] || ERROR "--role-name is required" - - CHECK_ERRORS --no-fail || return 1 - - ########################################## - - [[ $FORCE -eq 0 ]] && { - _EKS__CHECK_IAMSERVICEACCOUNT_EXISTS - local EXISTS_STATUS=$? - case $EXISTS_STATUS in - 0 ) - SUCCESS "'$NAMESPACE/$SERVICEACCOUNT' already configured with '$ROLE_NAME'" - return 0 - ;; - 1 ) ;; # role does not exist yet; continue with rollout - 2 ) - ERROR "'$NAMESPACE/$SERVICEACCOUNT' has been configured with a different role than '$ROLE_NAME'" - REMINDER "must use --force flag to overwrite" - return 2 - ;; - esac - } - - STATUS "creating iamserviceaccount" \ - && EKSCTL create iamserviceaccount \ - --cluster $CLUSTER_NAME \ - --namespace $NAMESPACE \ - --name $SERVICEACCOUNT \ - --role-name $ROLE_NAME \ - --override-existing-serviceaccounts \ - --approve \ - ${EKSCTL_ARGS[@]} \ - && SUCCESS "successfully configured '$NAMESPACE/$SERVICEACCOUNT' with IAM role '$ROLE_NAME'" \ - || { ERROR "unable to configure '$NAMESPACE/$SERVICEACCOUNT' with IAM role '$ROLE_NAME' (check cloudformation dashboard for details)"; return 3; } -} - -_EKS__CHECK_IAMSERVICEACCOUNT_EXISTS() { - STATUS "checking for existing role-arn" - local CURRENT_ROLE_ARN=$( - EKS__KUBECTL --namespace $NAMESPACE get serviceaccount $SERVICEACCOUNT -o yaml \ - | YQ -r '.metadata.annotations["eks.amazonaws.com/role-arn"]' \ - | grep -v '^null$' \ - ) - - [ $CURRENT_ROLE_ARN ] || { - STATUS "serviceaccount does not exist or has no configured role" - return 1 - } - - [[ $CURRENT_ROLE_ARN =~ "$ROLE_NAME$" ]] || { - STATUS "serviceaccount current role does not match desired role: - CURRENT : $CURRENT_ROLE_ARN - DESIRED : arn:aws:iam::${AWS_ACCOUNT}:role/$ROLE_NAME - " - return 2 - } - - STATUS "serviceaccount current role matches desired role" - return 0 -} diff --git a/zsh/lib/cloud/media-sync.module.zsh b/zsh/lib/cloud/media-sync.module.zsh deleted file mode 100644 index 438fe2e..0000000 --- a/zsh/lib/cloud/media-sync.module.zsh +++ /dev/null @@ -1,69 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() - -REQUIRED_ENV+=( - MEDIA_SYNC__TARGETS - MEDIA_SYNC__S3_BUCKET -) - -use cloud/aws/cli - -##################################################################### - -MEDIA_SYNC__PUSH() { - local FLAGS=($@) - local FAILED_COUNT=0 - - STATUS 'starting media upload to s3' - - local TARGET - for TARGET in ${MEDIA_SYNC__TARGETS[@]} - do - _MEDIA_SYNC push $TARGET $FLAGS || ((FAILED_COUNT+=1)) - done - - [[ $FAILED_COUNT -eq 0 ]] \ - && SUCCESS 's3 media files now up-to-date' \ - || FAIL $FAILED_COUNT 'unable to upload one or more targets' \ - ; -} - -MEDIA_SYNC__PULL() { - local FLAGS=($@) - local FAILED_COUNT=0 - - STATUS 'starting media download from s3' - - local TARGET - for TARGET in ${MEDIA_SYNC__TARGETS[@]} - do - _MEDIA_SYNC pull $TARGET $FLAGS || ((FAILED_COUNT+=1)) - done - - [[ $FAILED_COUNT -eq 0 ]] \ - && SUCCESS 'local media files now up-to-date' \ - || FAIL $FAILED_COUNT 'unable to download one or more targets' \ - ; -} - -_MEDIA_SYNC() { - local ACTION="$1" - local REMOTE_TARGET="s3://$MEDIA_SYNC__S3_BUCKET/$2" - local LOCAL_TARGET="$HOME/$2" - - local A B - case $ACTION in - push ) A="$LOCAL_TARGET"; B="$REMOTE_TARGET" ;; - pull ) A="$REMOTE_TARGET"; B="$LOCAL_TARGET" ;; - - * ) ERROR "unknown action '$1'"; return 1 ;; - esac - - local FLAGS=(${@:3}) - - STATUS "${ACTION}ing $2" - AWS s3 sync $A $B $FLAGS \ - && SUCCESS "$2 up-to-date" \ - || { ERROR "unable to sync $2 (see above)"; return 1; } -} diff --git a/zsh/lib/config.user.zsh b/zsh/lib/config.user.zsh deleted file mode 100644 index 7610d9e92417df510fd4fc38036348571e5d2077..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 502 zcmZXRK~ID*5QRPWA9!*CCTL8=JsS=zAdnz!plJ3)Shl+okrG-o{(E<`($?6^q|Nu< z^v&4FhL#We?l4b{?DznDJQV?ZK7nYzrteV-WFu4tuf>MYvW^Q}ky(`|Di5UW|C=*=JprW30;lOfi2xyVP9hAfm zA`M6RORWW0XMuuU4X&#+3!}n-FC9?e#>jWF{0*n(U}SdL@Yzj#_+Wz+M$inanJAeG z@Amv)!nmTOqW{`xp3icerG?OOXS+@`+n(*fgNH|8!*W>}pC(xqr+FRa{yK}ox_+Ox Jtd+gDLO(anld=E+ diff --git a/zsh/lib/config.zsh b/zsh/lib/config.zsh deleted file mode 100644 index f9b9fa3..0000000 --- a/zsh/lib/config.zsh +++ /dev/null @@ -1,95 +0,0 @@ -[[ $__SCWRYPT -eq 1 ]] && return 0 -##################################################################### - -# Apparently MacOS puts ALL of the homebrew stuff inside of a top level git repository -# with bizarre git ignores; so: -# - USE the git root if it's a manual install... -# - UNLESS that git root is just the $(brew --prefix) -SCWRYPTS_ROOT="$(cd -- ${0:a:h}; git rev-parse --show-toplevel 2>/dev/null | grep -v "^$(brew --prefix 2>/dev/null)$")" - -[ $SCWRYPTS_ROOT ] && [ -d "$SCWRYPTS_ROOT" ] \ - || SCWRYPTS_ROOT="$(echo "${0:a:h}" | sed -n 's|\(share/scwrypts\).*$|\1|p')" - -[ $SCWRYPTS_ROOT ] && [ -d "$SCWRYPTS_ROOT" ] || { - echo "cannot determine scwrypts root path for current installation; aborting" - exit 1 -} - -export SCWRYPTS_ROOT__scwrypts="$SCWRYPTS_ROOT" - -[ -f "$SCWRYPTS_ROOT__scwrypts/MANAGED_BY" ] \ - && export SCWRYPTS_INSTALLATION_TYPE=$(cat "$SCWRYPTS_ROOT__scwrypts/MANAGED_BY") \ - || export SCWRYPTS_INSTALLATION_TYPE=manual \ - ; - - -##################################################################### - -DEFAULT_CONFIG="$SCWRYPTS_ROOT__scwrypts/zsh/lib/config.user.zsh" -source "$DEFAULT_CONFIG" - -USER_CONFIG_OVERRIDES="$SCWRYPTS_CONFIG_PATH/config.zsh" -[ ! -f "$USER_CONFIG_OVERRIDES" ] && { - mkdir -p $(dirname "$USER_CONFIG_OVERRIDES") - cp "$DEFAULT_CONFIG" "$USER_CONFIG_OVERRIDES" -} -source "$USER_CONFIG_OVERRIDES" - -mkdir -p \ - "$SCWRYPTS_CONFIG_PATH" \ - "$SCWRYPTS_DATA_PATH" \ - "$SCWRYPTS_ENV_PATH" \ - "$SCWRYPTS_LOG_PATH" \ - "$SCWRYPTS_OUTPUT_PATH" \ - ; - -export \ - SCWRYPTS_GROUPS \ - SCWRYPTS_CONFIG_PATH \ - SCWRYPTS_DATA_PATH \ - SCWRYPTS_SHORTCUT \ - SCWRYPTS_ENV_SHORTCUT \ - SCWRYPTS_LOG_PATH \ - SCWRYPTS_OUTPUT_PATH \ - ; - -source "$SCWRYPTS_ROOT/scwrypts.scwrypts.zsh" \ - || FAIL 69 'failed to set up scwrypts group; aborting' - - -##################################################################### - -for plugin in $(ls $SCWRYPTS_ROOT__scwrypts/plugins) -do - [[ $(eval 'echo $SCWRYPTS_PLUGIN_ENABLED__'$plugin) -eq 1 ]] && { - source "$SCWRYPTS_ROOT/plugins/$plugin/$plugin.scwrypts.zsh" - } -done - -##################################################################### - -for GROUP_LOADER in $(env | sed -n 's/^SCWRYPTS_GROUP_LOADER__[a-z_]\+=//p') -do - [ -f "$GROUP_LOADER" ] && source "$GROUP_LOADER" -done - -: \ - && [ ! "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] \ - && [ $GITHUB_WORKSPACE ] \ - && [ ! $SCWRYPTS_GITHUB_NO_AUTOLOAD ] \ - && SCWRYPTS_AUTODETECT_GROUP_BASEDIR="$GITHUB_WORKSPACE" \ - ; - -[ "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] && [ -d "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] && { - for GROUP_LOADER in $(find "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" -type f -name \*scwrypts.zsh) - do - [ -f "$GROUP_LOADER" ] && source "$GROUP_LOADER" - done -} - -##################################################################### - -SCWRYPTS_GROUPS=(scwrypts $(echo $SCWRYPTS_GROUPS | sed 's/\s\+/\n/g' | sort -u | grep -v '^scwrypts$')) - -##################################################################### -__SCWRYPT=1 # arbitrary; indicates currently inside a scwrypt diff --git a/zsh/lib/helm/dependency.module.zsh b/zsh/lib/helm/dependency.module.zsh deleted file mode 100644 index 8ed11a0..0000000 --- a/zsh/lib/helm/dependency.module.zsh +++ /dev/null @@ -1,42 +0,0 @@ -##################################################################### - -DEPENDENCIES+=(helm kubeval) -REQUIRED_ENV+=() - -use helm/validate - -##################################################################### - -HELM__DEPENDENCY__UPDATE() { - [ ! $USAGE ] && local USAGE=" - usage: [...options...] - - options - -t, --template-filename path to a template/*.yaml file of a helm chart - - Auto-detect chart and build dependencies for any file within a helm chart. - " - local TEMPLATE_FILENAME CHART_ROOT VALUES_FILES=() - local COLORIZE=0 RAW=0 DEBUG=0 - - while [[ $# -gt 0 ]] - do - case $1 in - -t | --template-filename ) TEMPLATE_FILENAME="$(SCWRYPTS__GET_REALPATH "$2")"; shift 1 ;; - - * ) ERROR "unexpected argument '$1'" ;; - esac - shift 1 - done - - HELM__VALIDATE - CHECK_ERRORS || return 1 - - ########################################## - - STATUS "updating helm dependencies for '$CHART_ROOT'" \ - && cd $CHART_ROOT \ - && helm dependency update \ - && SUCCESS "helm chart dependencies updated" \ - || { ERROR "unable to update helm chart dependencies (see above)"; return 1; } -} diff --git a/zsh/lib/helm/helm.module.zsh b/zsh/lib/helm/helm.module.zsh deleted file mode 100644 index 1be8095..0000000 --- a/zsh/lib/helm/helm.module.zsh +++ /dev/null @@ -1,9 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -use helm/dependency -use helm/template - -##################################################################### diff --git a/zsh/lib/helm/template.module.zsh b/zsh/lib/helm/template.module.zsh deleted file mode 100644 index df4f23b..0000000 --- a/zsh/lib/helm/template.module.zsh +++ /dev/null @@ -1,111 +0,0 @@ -##################################################################### - -DEPENDENCIES+=(helm kubeval) -REQUIRED_ENV+=() - -use helm/validate -use scwrypts - -##################################################################### - -HELM__TEMPLATE__GET() { - [ ! $USAGE ] && local USAGE=" - usage: [...options...] (--) [...helm args...] - - options - -t, --template-filename path to a template/*.yaml file of a helm chart - - --colorize use 'bat' to colorize output - --raw remove scwrypts-added fluff and only output helm template details - - -h, --help show this help dialogue - - Smart helm-template generator which auto-detects the chart - and sample values for testing and developing helm charts. - " - local HELM_ARGS=() - local TEMPLATE_FILENAME TEMPLATE_NAME CHART_ROOT CHART_NAME VALUES_FILES=() - local COLORIZE=0 RAW=0 DEBUG=0 - - while [[ $# -gt 0 ]] - do - case $1 in - -t | --template-filename ) TEMPLATE_FILENAME="$(SCWRYPTS__GET_REALPATH "$2")"; shift 1 ;; - - --colorize ) - DEPENDENCIES=(bat) CHECK_ENVIRONMENT || return 1 - COLORIZE=1 - ;; - - --raw ) RAW=1 ;; - - -h | --help ) USAGE; return 0 ;; - -- ) shift 1; break ;; - - - * ) HELM_ARGS+=($1) ;; - esac - shift 1 - done - - while [[ $# -gt 0 ]]; do HELM_ARGS+=($1); shift 1; done - - HELM__VALIDATE - CHECK_ERRORS || return 1 - - ########################################## - - local EXIT_CODE=0 - local TEMPLATE_OUTPUT DEBUG_OUTPUT - [ $USE_CHART_ROOT ] && [[ $USE_CHART_ROOT -eq 1 ]] && { - CAPTURE TEMPLATE_OUTPUT DEBUG_OUTPUT helm template "$CHART_ROOT" ${HELM_ARGS[@]} --debug - true - } || { - CAPTURE TEMPLATE_OUTPUT DEBUG_OUTPUT helm template "$CHART_ROOT" ${HELM_ARGS[@]} --debug --show-only "$(echo $TEMPLATE_FILENAME | sed "s|^$CHART_ROOT/||")" - } - - [ ! $TEMPLATE_OUTPUT ] && EXIT_CODE=1 - - - [[ $RAW -eq 1 ]] && { - [ $USE_CHART_ROOT ] && [[ $USE_CHART_ROOT -eq 1 ]] || HELM_ARGS+=(--show-only $(echo $TEMPLATE_FILENAME | sed "s|^$CHART_ROOT/||")) - [[ $COLORIZE -eq 1 ]] \ - && helm template "$CHART_ROOT" ${HELM_ARGS[@]} 2>&1 | bat --language yaml --color always \ - || helm template "$CHART_ROOT" ${HELM_ARGS[@]} | grep -v '^# Source:.*$' \ - ; - - return $EXIT_CODE - } - - [ $TEMPLATE_OUTPUT ] && { - KUBEVAL_RAW=$(echo $TEMPLATE_OUTPUT | kubeval --schema-location https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master) - true - } || { - TEMPLATE_OUTPUT="---\nerror: chart or '$(basename $(dirname $TEMPLATE_FILENAME))/$(basename $TEMPLATE_FILENAME)' invalid" - KUBEVAL_RAW="no template output; kubeval skipped" - - [ $USE_CHART_ROOT ] && [[ $USE_CHART_ROOT -eq 1 ]] || { - DEBUG_OUTPUT="$(helm template "$CHART_ROOT" ${HELM_ARGS[@]} --debug 2>&1 >/dev/null)" - } - } - - TEMPLATE_OUTPUT="$TEMPLATE_OUTPUT ---- -debug: | -$(echo $DEBUG_OUTPUT | sed 's/^/ /g') - -kubeval: | -$(echo $KUBEVAL_RAW | sed 's/^/ /g') - -lint: | -$(helm lint $CHART_ROOT ${HELM_ARGS[@]} 2>&1 | sed 's/^/ /g') -" - - [[ $COLORIZE -eq 1 ]] && { - echo $TEMPLATE_OUTPUT | bat --language yaml --color always - } || { - echo $TEMPLATE_OUTPUT - } - - return $EXIT_CODE -} diff --git a/zsh/lib/helm/validate.module.zsh b/zsh/lib/helm/validate.module.zsh deleted file mode 100644 index f68ac50..0000000 --- a/zsh/lib/helm/validate.module.zsh +++ /dev/null @@ -1,95 +0,0 @@ -##################################################################### - -DEPENDENCIES+=(yq) -REQUIRED_ENV+=() - -##################################################################### - -HELM__VALIDATE() { - [ ! $USAGE ] && USAGE=" - usage: - - environment - TEMPLATE_FILENAME target template filename - - Smart helm-detection / validator which determines the helm - chart root and other details given a particular filename. - " - - [ $TEMPLATE_FILENAME ] && [ -f "$TEMPLATE_FILENAME" ] || { - ERROR 'must provide a template filename' - return 1 - } - - _HELM__GET_CHART_ROOT - [ $CHART_ROOT ] && [ -d "$CHART_ROOT" ] || { - ERROR 'unable to determine helm root; is this a helm template file?' - return 1 - } - - CHART_NAME=$(YQ -r .name "$CHART_ROOT/Chart.yaml") - - [[ $TEMPLATE_FILENAME =~ values.*.yaml$ ]] && { - HELM_ARGS+=(--values $TEMPLATE_FILENAME) - USE_CHART_ROOT=1 - } - - [[ $TEMPLATE_FILENAME =~ tests/.*.yaml$ ]] && { - HELM_ARGS+=(--values $TEMPLATE_FILENAME) - USE_CHART_ROOT=1 - } - [[ $TEMPLATE_FILENAME =~ .tpl$ ]] \ - && USE_CHART_ROOT=1 - - [[ $(dirname $TEMPLATE_FILENAME) =~ ^$CHART_ROOT$ ]] \ - && USE_CHART_ROOT=1 - - _HELM__GET_DEFAULT_VALUES_ARGS - - return 0 -} - -_HELM__GET_CHART_ROOT() { - local SEARCH_DIR=$(dirname "$TEMPLATE_FILENAME") - while [ ! $CHART_ROOT ] && [[ ! $SEARCH_DIR =~ ^/$ ]] - do - [ -f "$SEARCH_DIR/Chart.yaml" ] && CHART_ROOT="$SEARCH_DIR" && return 0 - SEARCH_DIR="$(dirname "$SEARCH_DIR")" - done - - return 1 -} - -_HELM__GET_DEFAULT_VALUES_ARGS() { - for F in \ - "$CHART_ROOT/tests/default.yaml" \ - "$CHART_ROOT/values.test.yaml" \ - "$CHART_ROOT/values.yaml" \ - ; - do - [ -f "$F" ] && HELM_ARGS=(--values "$F" $HELM_ARGS) - done - - for LOCAL_REPOSITORY in $(\ - cat "$CHART_ROOT/Chart.yaml" \ - | YQ -r '.dependencies[] | .repository' \ - | grep '^file://' \ - | sed 's|file://||' \ - ) - do - [[ $LOCAL_REPOSITORY =~ ^[/~] ]] \ - && LOCAL_REPOSITORY_ROOT="$LOCAL_REPOSITORY" \ - || LOCAL_REPOSITORY_ROOT="$CHART_ROOT/$LOCAL_REPOSITORY" \ - ; - - for F in \ - "$LOCAL_REPOSITORY_ROOT/tests/default.yaml" \ - "$LOCAL_REPOSITORY_ROOT/values.test.yaml" \ - "$LOCAL_REPOSITORY_ROOT/values.yaml" \ - ; - do - [ -f "$F" ] && HELM_ARGS=(--values "$F" $HELM_ARGS) - done - done -} - diff --git a/zsh/lib/import.driver.zsh b/zsh/lib/import.driver.zsh deleted file mode 100644 index 8eff2c7..0000000 --- a/zsh/lib/import.driver.zsh +++ /dev/null @@ -1,156 +0,0 @@ -[[ $SCWRYPTS_IMPORT_DRIVER_READY -eq 1 ]] && return 0 - ################################################################### -# # -# usage: use [OPTIONS ...] zsh/module/path # -# # - ################################################################### -# # -# OPTIONS: # -# # -# -g, --group lookup library root from friendly group # -# name (requires configuration) # -# (default: scwrypts) # -# # -# -r, --library-root fully qualified path to a library root # -# # -# --check-environment check environment immediately rather than # -# wait for downstream CHECK_ENVIRONMENT call # -# # -# # -# Allows for import-style library loading in zsh. No matter what # -# scwrypt is run, this function (and required helpers) are *also* # -# loaded, ensuring that 'use' is always available in scwrypts # -# context. # -# # -# # -# Friendly group-names can be configured by setting the variable # -# 'SCWRYPTS_LIBRARY_ROOT__' to the fully qualified path # -# to the root directory of the modules library. # -# # -# # - ################################################################### - -source "${0:a:h}/config.zsh" - -use() { - local SCWRYPTS_LIBRARY SCWRYPTS_LIBRARY_ROOT SCWRYPTS_LIBRARY_GROUP - local DEFER_ENVIRONMENT_CHECK=true - - while [[ $# -gt 0 ]] - do - case $1 in - -g | --group ) - [ $SCWRYPTS_LIBRARY_ROOT ] && ERROR 'specify only one of {(-g), (-r)}' - SCWRYPTS_LIBRARY_GROUP=$2 - shift 1 - ;; - -r | --library-root ) - [ $SCWRYPTS_LIBRARY_GROUP ] && ERROR 'specify only one of {(-g), (-r)}' - SCWRYPTS_LIBRARY_ROOT=$2 - shift 1 - ;; - -c | --check-environment ) - DEFER_ENVIRONMENT_CHECK=false - ;; - * ) - [ ! $SCWRYPTS_LIBRARY ] \ - && SCWRYPTS_LIBRARY=$1 \ - || ERROR 'too many arguments; expected exactly 1 argument' \ - - ;; - esac - shift 1 - done - - [ ! $SCWRYPTS_LIBRARY ] && ERROR 'no library specified for import' - - : \ - && [ ! $SCWRYPTS_LIBRARY_GROUP ] \ - && [ ! $SCWRYPTS_LIBRARY_ROOT ] \ - && SCWRYPTS_LIBRARY_GROUP=scwrypts - - [ ! $SCWRYPTS_LIBRARY_ROOT ] && SCWRYPTS_LIBRARY_ROOT=$(GET_SCWRYPTS_LIBRARY_ROOT) - [ ! $SCWRYPTS_LIBRARY_ROOT ] && ERROR "unable to determine library root from group name '$SCWRYPTS_LIBRARY_GROUP'" - - ##################################################################### - - local LIBRARY_FILE LIBRARY_FILE_TEMP - - [ ! $LIBRARY_FILE ] \ - && LIBRARY_FILE_TEMP="$SCWRYPTS_LIBRARY_ROOT/$SCWRYPTS_LIBRARY.module.zsh" \ - && [ -f "$LIBRARY_FILE_TEMP" ] \ - && LIBRARY_FILE="$LIBRARY_FILE_TEMP" - - [ ! $LIBRARY_FILE ] \ - && LIBRARY_FILE_TEMP="$SCWRYPTS_LIBRARY_ROOT/$SCWRYPTS_LIBRARY/$(echo $SCWRYPTS_LIBRARY | sed 's/.*\///').module.zsh" \ - && [ -f "$LIBRARY_FILE_TEMP" ] \ - && LIBRARY_FILE="$LIBRARY_FILE_TEMP" \ - - [ ! $LIBRARY_FILE ] \ - && ERROR "no such library '$SCWRYPTS_LIBRARY_GROUP/$SCWRYPTS_LIBRARY'" - - ##################################################################### - - CHECK_ERRORS --no-fail || { - ((IMPORT_ERRORS+=1)) - return 1 - } - - ##################################################################### - - IS_LOADED && return 0 - - source "$LIBRARY_FILE" || { - ((IMPORT_ERRORS+=1)) - ERROR "import error for '$SCWRYPTS_LIBRARY_GROUP/$SCWRYPTS_LIBRARY'" - return 1 - } - - [[ $DEFER_ENVIRONMENT_CHECK =~ false ]] && { - CHECK_ENVIRONMENT || { - ((IMPORT_ERRORS+=1)) - ERROR "import error for '$SCWRYPTS_LIBRARY_GROUP/$SCWRYPTS_LIBRARY'" - return 1 - } - } - - IS_LOADED --set -} - -GET_SCWRYPTS_LIBRARY_ROOT() { - local ROOT - - ROOT=$(eval echo '$SCWRYPTS_LIBRARY_ROOT__'$SCWRYPTS_LIBRARY_GROUP) - [ $ROOT ] && echo $ROOT && return 0 - - [[ $(eval echo '$SCWRYPTS_TYPE__'$SCWRYPTS_LIBRARY_GROUP) =~ zsh ]] \ - && ROOT=$(eval echo '$SCWRYPTS_ROOT__'$SCWRYPTS_LIBRARY_GROUP/lib) \ - || ROOT=$(eval echo '$SCWRYPTS_ROOT__'$SCWRYPTS_LIBRARY_GROUP/zsh/lib) \ - ; - [ $ROOT ] && echo $ROOT && return 0 -} - -IS_LOADED() { - local VARIABLE_NAME="SCWRYPTS_LIBRARY_LOADED__${SCWRYPTS_LIBRARY_GROUP}__$(echo $SCWRYPTS_LIBRARY | sed 's|[/-]|_|g')" - - [[ $1 =~ ^--set$ ]] \ - && eval $VARIABLE_NAME=1 \ - - [[ $(eval echo '$'$VARIABLE_NAME || echo 0) -eq 1 ]] -} - - -# temporary definitions for first load -CHECK_ERRORS() { return 0; unset -f CHECK_ERRORS; } -CHECK_ENVIRONMENT() { return 0; unset -f CHECK_ENVIRONMENT; } -ERROR() { echo $@ >&2; exit 1; } - -##################################################################### - -# ensures that zsh/utils and zsh/scwrypts/meta are always present! - -use utils -use scwrypts/meta - -##################################################################### -SCWRYPTS_IMPORT_DRIVER_READY=1 diff --git a/zsh/lib/media/youtube.module.zsh b/zsh/lib/media/youtube.module.zsh deleted file mode 100644 index 528429d..0000000 --- a/zsh/lib/media/youtube.module.zsh +++ /dev/null @@ -1,48 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - ffmpeg - youtube-dl -) - -REQUIRED_ENV+=() - -##################################################################### - -YT__GLOBAL_ARGS=( - --no-call-home - --restrict-filenames - ) - -YT__OUTPUT_DIR="$SCWRYPTS_DATA_PATH/youtube" - -YT__GET_INFO() { - youtube-dl --dump-json ${YT__GLOBAL_ARGS[@]} $@ -} - -YT__GET_FILENAME() { - YT__GET_INFO $@ \ - | jq -r '._filename' \ - | sed 's/\.[^.]*$/\.mp4/' \ - ; -} - -YT__DOWNLOAD() { - local OUTPUT_DIR="$SCWRYPTS_DATA_PATH/youtube" - [ ! -d $YT__OUTPUT_DIR ] && mkdir -p $YT__OUTPUT_DIR - cd "$YT__OUTPUT_DIR" - youtube-dl ${YT__GLOBAL_ARGS[@]} $@ \ - --format 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4' \ - ; -} - -GET_VIDEO_LENGTH() { - local FILENAME="$1" - - ffprobe \ - -v quiet \ - -show_entries format=duration \ - -of default=noprint_wrappers=1:nokey=1 \ - -i $FILENAME \ - ; -} diff --git a/zsh/lib/misc/k8s-helper.plugin.zsh b/zsh/lib/misc/k8s-helper.plugin.zsh deleted file mode 100644 index 38e9125..0000000 --- a/zsh/lib/misc/k8s-helper.plugin.zsh +++ /dev/null @@ -1,26 +0,0 @@ -K8s_HELPER__NAMESPACE_KEY='k8s-helper' -K8s_HELPER__REDIS_HOST=127.0.0.1 -K8s_HELPER__REDIS_PORT=6379 -K8s_HELPER__REDIS_AUTH= - -REDIS_CLI() { - local ARGS=() - [ $K8s_HELPER__REDIS_HOST ] && ARGS+=(-h $K8s_HELPER__REDIS_HOST) - [ $K8s_HELPER__REDIS_PORT ] && ARGS+=(-p $K8s_HELPER__REDIS_PORT) - [ $K8s_HELPER__REDIS_AUTH ] && ARGS+=(-a $K8s_HELPER__REDIS_AUTH --no-auth-warning) - redis-cli ${ARGS[@|} $@ -} - -K8s_HELPER__SET_NAMESPACE() { - REDIS_CLI hset $K8s_HELPER__NAMESPACE_KEY namespace $@ -} - -K8s_HELPER__GET_NAMESPACE() { - REDIS_CLI hget $K8s_HELPER__NAMESPACE_KEY namespace -} - -K8s_HELPER__KUBECTL() { - kubectl -n $(K8s_HELPER__GET_NAMESPACE) $@ -} - -alias k='K8s_HELPER__PREFIX ' diff --git a/zsh/lib/misc/tally.module.zsh b/zsh/lib/misc/tally.module.zsh deleted file mode 100644 index eb94bef..0000000 --- a/zsh/lib/misc/tally.module.zsh +++ /dev/null @@ -1,106 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -##################################################################### - -TALLY_USE_REDIS=false # maybe someday -TALLY_PATH="$SCWRYPTS_DATA_PATH/tally" - -##################################################################### - -TALLY() { - local USAGE=" - usage: [...options...] - - options: - -c, --increment-count increment the tally by this much (default 1) - -n, --tally-name name of tally system (default 'default') - - -g, --get only output the current value - -s, --set set the tally to a specific value - -r, --reset set the tally back to zero - - --raw only output the tally value - - -h, --help print this dialogue and exit - - Simple tally mark system; keep track of a count. - " - - local INCREMENT_COUNT=1 - local TALLY_NAME=default - local RAW=false - - local SET_VALUE= - - while [[ $# -gt 0 ]] - do - case $1 in - -c | --increment-count ) INCREMENT_COUNT=$2; shift 1 ;; - -n | --tally-name ) TALLY_NAME=$2; shift 1 ;; - - -g | --get ) INCREMENT_COUNT=0 ;; - - -s | --set ) SET_VALUE=$2; shift 1 ;; - -r | --reset ) SET_VALUE=0 ;; - - --raw ) RAW=true ;; - - -h | --help ) USAGE; return 0 ;; - - * ) ERROR "unknown argument '$1'" ;; - esac - shift 1 - done - - [ $TALLY_NAME ] && echo "$TALLY_NAME" | grep -qv '/' \ - || ERROR "invalid tally name '$TALLY_NAME'" - - local TALLY_FILENAME="$TALLY_PATH/$TALLY_NAME.txt" - - CHECK_ERRORS --no-fail || return 1 - - ########################################## - - local NEW_VALUE CURRENT_VALUE=0 - [ $SET_VALUE ] && NEW_VALUE=$SET_VALUE || { - [ -f "$TALLY_FILENAME" ] && { - CURRENT_VALUE=$(cat "$TALLY_FILENAME" | tail -n1 | grep '^[0-9]\+') - } - - [ $CURRENT_VALUE ] || { - ERROR "malformed tally file '$TALLY_FILENAME'; aborting" - return 1 - } - - NEW_VALUE=$(($CURRENT_VALUE + $INCREMENT_COUNT)) - } - - ########################################## - - local TALLY_DIR="$(dirname "$TALLY_FILENAME")" - - [ -d "$TALLY_DIR" ] || mkdir -p "$TALLY_DIR" - [ -d "$TALLY_DIR" ] || { - ERROR "unable to write to '$TALLY_DIR'; aborting" - return 1 - } - - echo "# autogenerated tally file; avoid direct modification\n$NEW_VALUE" > "$TALLY_FILENAME" || { - ERROR "failed to write to '$TALLY_FILENAME': aborting" - return 1 - } - - ########################################## - - case $RAW in - true ) printf "$NEW_VALUE" ;; - false ) - case $TALLY_NAME in - default ) SUCCESS "current tally : $NEW_VALUE" ;; - * ) SUCCESS "$TALLY_NAME : $NEW_VALUE" ;; - esac - esac -} diff --git a/zsh/lib/office/latex.module.zsh b/zsh/lib/office/latex.module.zsh deleted file mode 100644 index a13e4d1..0000000 --- a/zsh/lib/office/latex.module.zsh +++ /dev/null @@ -1,44 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - rg - pdflatex -) - -REQUIRED_ENV+=() - -##################################################################### - -LATEX__GET_MAIN_FILENAME() { - local FILENAME=$(SCWRYPTS__GET_REALPATH "$1") - local DIRNAME="$FILENAME" - - for _ in {1..3} - do - CHECK_IS_MAIN_LATEX_FILE && return 0 - DIRNAME="$(dirname "$FILENAME")" - STATUS "checking '$DIRNAME'" - [[ $DIRNAME =~ ^$HOME$ ]] && break - FILENAME=$( - rg -l --max-depth 1 'documentclass' "$DIRNAME/" \ - | grep '\.tex$' \ - | head -n1 \ - ) - STATUS "here is '$FILENAME'" - done - - WARNING 'unable to find documentclass; pdflatex will probably fail' - echo "$1" -} - -LATEX__CHECK_IS_MAIN_FILE() { - [ ! $FILENAME ] && return 1 - grep -q 'documentclass' $FILENAME 2>/dev/null && echo $FILENAME || return 3 -} - -LATEX__GET_PDF() { - local FILENAME=$(LATEX__GET_MAIN_FILENAME "$1" | sed 's/\.[^.]*$/.pdf/') - [ $FILENAME ] && [ -f $FILENAME ] || FAIL 1 "no compiled pdf found for '$1'; have you run 'build-pdf'?" - SUCCESS 'found main pdf' - echo $FILENAME -} diff --git a/zsh/lib/office/memo.module.zsh b/zsh/lib/office/memo.module.zsh deleted file mode 100644 index df7a381..0000000 --- a/zsh/lib/office/memo.module.zsh +++ /dev/null @@ -1,15 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -##################################################################### - -set +o noglob - -MEMO__FILETYPE=md -MEMO__DIR="$SCWRYPTS_DATA_PATH/memo" - -[ ! -d $MEMO__DIR ] && mkdir -p $MEMO__DIR - -MEMO__LIST_ALL() { ls $MEMO__DIR | sed "s/\.$MEMO__FILETYPE$//" | sort; } diff --git a/zsh/lib/redis/redis.module.zsh b/zsh/lib/redis/redis.module.zsh deleted file mode 100644 index fa4d8a7..0000000 --- a/zsh/lib/redis/redis.module.zsh +++ /dev/null @@ -1,43 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - redis-cli -) - -REQUIRED_ENV+=() - -##################################################################### - -REDIS() { - [[ ${#ARGS[@]} -eq 0 ]] && REDIS__SET_LOGIN_ARGS $@ - - redis-cli ${#ARGS[@]} -} - - -REDIS__SET_LOGIN_ARGS() { - while [[ $# -gt 0 ]] - do - case $1 in - --host ) _ARGS+=(-h $2); _HOST="$2"; shift 1 ;; - --port ) _ARGS+=(-p $2); _PORT="$2"; shift 1 ;; - --pass ) _ARGS+=(-a $2); _PASS="$2"; shift 1 ;; - - --file ) _FILE="$2"; shift 1 ;; - - * ) _ARGS+=($1) ;; - esac - shift 1 - done - - [ $_FILE ] && [ ! -f "$_FILE" ] && { - ERROR "no such file '$_FILE'" - exit 1 - } - - return 0 -} - -REDIS__ENABLED() { - REDIS ping 2>&1 | grep -qi pong -} diff --git a/zsh/lib/scwrypts/environment-files.module.zsh b/zsh/lib/scwrypts/environment-files.module.zsh deleted file mode 100644 index eda68d5..0000000 --- a/zsh/lib/scwrypts/environment-files.module.zsh +++ /dev/null @@ -1,126 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -use utils - -##################################################################### - -SCWRYPTS__SELECT_ENV() { - SCWRYPTS__GET_ENV_NAMES | FZF 'select an environment' -} - -SCWRYPTS__SELECT_OR_CREATE_ENV() { - SCWRYPTS__GET_ENV_NAMES | FZF_USER_INPUT 'select / create an environment' -} - -SCWRYPTS__GET_ENV_FILES() { - local NAME="$1" - - local FILENAMES=$( - for GROUP in ${SCWRYPTS_GROUPS[@]} - do - echo "$SCWRYPTS_ENV_PATH/$GROUP/$NAME" - done - ) - - echo $FILENAMES | grep 'environments/scwrypts/' - echo $FILENAMES | grep -v 'environments/scwrypts/' | sort - - SCWRYPTS__GET_ENV_NAMES | grep -q $NAME \ - || { ERROR "no environment '$NAME' exists"; return 1; } -} - -SCWRYPTS__GET_ENV_FILE() { - local NAME="$1" - local GROUP="$2" - - [ ! $GROUP ] && { ERROR 'must provide group'; return 1; } - - echo "$SCWRYPTS_ENV_PATH/$GROUP/$NAME" - - SCWRYPTS__GET_ENV_NAMES | grep -q $NAME \ - || { ERROR "no environment '$NAME' exists"; return 1; } - - [ -f "$SCWRYPTS_ENV_PATH/$GROUP/$NAME" ] || { - mkdir -p "$SCWRYPTS_ENV_PATH/$GROUP" - touch "$SCWRYPTS_ENV_PATH/$GROUP/$NAME" - } - [ -f "$SCWRYPTS_ENV_PATH/$GROUP/$NAME" ] \ - || { ERROR "missing environment file for '$GROUP/$NAME'"; return 2; } -} - -SCWRYPTS__GET_ENV_TEMPLATE_FILES() { - local GROUP - for GROUP in ${SCWRYPTS_GROUPS[@]} - do - eval echo '$SCWRYPTS_ROOT__'$GROUP/.config/env.template - done -} - -SCWRYPTS__GET_ENV_NAMES() { - SCWRYPTS__INIT_ENVIRONMENTS || { - ERROR 'environment initialization error' - return 1 - } - [ $REQUIRED_ENVIRONMENT_REGEX ] && { - ls "$SCWRYPTS_ENV_PATH/scwrypts" | grep "$REQUIRED_ENVIRONMENT_REGEX" | sort -r - } || { - ls "$SCWRYPTS_ENV_PATH/scwrypts" | sort -r - } -} - -SCWRYPTS__INIT_ENVIRONMENTS() { - [ ! -d "$SCWRYPTS_ENV_PATH" ] && mkdir -p "$SCWRYPTS_ENV_PATH" - [[ $(ls "$SCWRYPTS_ENV_PATH" | wc -l) -gt 0 ]] && return 0 - - STATUS "initializing environments for scwrypts" - - local BASIC_ENV - for BASIC_ENV in local dev prod - do - for GROUP in ${SCWRYPTS_GROUPS[@]} - do - mkdir -p "$SCWRYPTS_ENV_PATH/$GROUP" - GENERATE_TEMPLATE > "$SCWRYPTS_ENV_PATH/$GROUP/$BASIC_ENV" - done - done -} - -##################################################################### - -_SED() { sed --follow-symlinks $@; } - -GENERATE_TEMPLATE() { - [ ! $GROUP ] && { ERROR 'must provide GROUP'; return 1; } - DIVIDER='#####################################################################' - HEADER='### scwrypts runtime configuration ' - [[ GROUP =~ ^scwrypts$ ]] || HEADER="${HEADER}(group '$GROUP') " - printf "#!/bin/zsh\n$DIVIDER\n$HEADER%s\n$DIVIDER\n" "${DIVIDER:${#$(echo "$HEADER")}}" - - local FILE CONTENT - local VARIABLE DESCRIPTION - FILE=$(eval echo '$SCWRYPTS_ROOT__'$GROUP/.config/env.template) - - CONTENT=$(GET_VARIABLE_NAMES "$FILE" | sed 's/^/export /; s/$/=/') - - while read DESCRIPTION_LINE - do - VARIABLE=$(echo $DESCRIPTION_LINE | sed 's/ \+| .*$//') - DESCRIPTION=$(echo $DESCRIPTION_LINE | sed 's/^.* | //') - [ ! $DESCRIPTION ] && continue - - CONTENT=$(echo "$CONTENT" | sed "/^export $VARIABLE=/i #" | sed "/^export $VARIABLE=/i # $DESCRIPTION") - done < <(_SED -n '/^[^ ]\+ \+| /p' "$FILE.descriptions") - - echo "$CONTENT" | sed 's/^#$//' -} - -GET_VARIABLE_NAMES() { - local FILE="$1" - grep '^export' "$FILE" \ - | sed 's/^export //; s/=.*//' \ - | grep -v '__[a-z]\+$' \ - ; -} diff --git a/zsh/lib/scwrypts/meta.module.zsh b/zsh/lib/scwrypts/meta.module.zsh deleted file mode 100644 index 1d45c4b..0000000 --- a/zsh/lib/scwrypts/meta.module.zsh +++ /dev/null @@ -1,23 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -use scwrypts/environment-files -use scwrypts/run - -##################################################################### - -SCWRYPTS__RUN() { # context wrapper to run scwrypts within scwrypts - local EXIT_CODE=0 - ((SUBSCWRYPT+=1)) - - SCWRYPTS_LOG_LEVEL=$SCWRYPTS_LOG_LEVEL \ - SUBSCWRYPT=$SUBSCWRYPT \ - $SCWRYPTS_ROOT__scwrypts/scwrypts $@ - - EXIT_CODE=$? - - ((SUBSCWRYPT-=1)) - return $EXIT_CODE -} diff --git a/zsh/lib/scwrypts/run.module.zsh b/zsh/lib/scwrypts/run.module.zsh deleted file mode 100644 index b01cd97..0000000 --- a/zsh/lib/scwrypts/run.module.zsh +++ /dev/null @@ -1,195 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -use scwrypts/environment-files - -##################################################################### - -SCWRYPTS__GET_AVAILABLE_SCWRYPTS() { - local TYPE_COLOR='\033[0;37m' - local GROUP GROUP_PATH GROUP_COLOR LOOKUP_PIDS=() - { - echo 'NAME^TYPE^GROUP' - for GROUP in ${SCWRYPTS_GROUPS[@]} - do - GROUP_PATH=$(eval echo '$SCWRYPTS_ROOT__'$GROUP) - GROUP_COLOR=$(eval echo '$SCWRYPTS_COLOR__'$GROUP) - - GROUP_TYPE=$(eval echo '$SCWRYPTS_TYPE__'$GROUP) - [ $GROUP_TYPE ] && MINDEPTH=1 && GROUP_TYPE="$GROUP_TYPE\\/" || MINDEPTH=2 - - command -v SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__$GROUP >/dev/null 2>&1 \ - && LOOKUP=SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__$GROUP \ - || LOOKUP=SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__scwrypts \ - ; - - { - $LOOKUP \ - | sed "s|\\([^/]*\\)/\(.*\)$|$(printf $__COLOR_RESET)\\2^$(printf $TYPE_COLOR)\\1^$(printf $GROUP_COLOR)$GROUP$(printf $__COLOR_RESET)|" \ - } & - LOOKUP_PIDS+=($!) - done - for p in ${LOOKUP_PIDS[@]}; do wait $p; done - } | column -t -s '^' -} - -SCWRYPTS__SEPARATE_SCWRYPT_SELECTION() { - set -- $(echo $@ | sed -e 's/\x1b\[[0-9;]*m//g') - while [[ $# -gt 0 ]] - do - [ ! $NAME ] && NAME=$1 && shift 1 && continue - [ ! $TYPE ] && TYPE=$1 && shift 1 && continue - [ ! $GROUP ] && GROUP=$1 && shift 1 && continue - shift 1 - done -} - -SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__scwrypts() { - # implementation should output lines of the following format: - # "${SCWRYPT_TYPE}/${SCWRYPT_NAME}" - cd "$GROUP_PATH" - find . -mindepth $MINDEPTH -type f -executable \ - | grep -v '\.git' \ - | grep -v 'node_modules' \ - | sed "s/^\\.\\///; s/\\.[^.]*$//; s/^/$GROUP_TYPE/" \ - | grep -v '^plugins/' \ - ; -} - -SCWRYPTS__GET_RUNSTRING() { - local GROUP_PATH=$(eval echo '$SCWRYPTS_ROOT__'$SCWRYPT_GROUP) - local RUNSTRING - - [ $SCWRYPT_NAME ] && [ $SCWRYPT_TYPE ] && [ $SCWRYPT_GROUP ] || { - ERROR 'missing required information to get runstring' - return 1 - } - - [ $ENV_REQUIRED ] && [[ $ENV_REQUIRED -eq 1 ]] && [ ! $ENV_NAME ] && { - ERROR 'missing required information to get runstring' - return 1 - } - - [ ! $RUNSTRING ] && typeset -f SCWRYPTS__GET_RUNSTRING__${SCWRYPT_GROUP}__${SCWRYPT_TYPE} >/dev/null 2>&1 && { - RUNSTRING=$(SCWRYPTS__GET_RUNSTRING__${SCWRYPT_GROUP}__${SCWRYPT_TYPE}) - [ ! $RUNSTRING ] && { - ERROR "SCWRYPTS__GET_RUNSTRING__${SCWRYPT_GROUP}__${SCWRYPT_TYPE} error" - return 2 - } - } - - [ ! $RUNSTRING ] && typeset -f SCWRYPTS__GET_RUNSTRING__${SCWRYPT_TYPE} >/dev/null 2>&1 && { - RUNSTRING=$(SCWRYPTS__GET_RUNSTRING__${SCWRYPT_TYPE}) - [ ! $RUNSTRING ] && { - ERROR "SCWRYPTS__GET_RUNSTRING__${SCWRYPT_TYPE} error" - return 3 - } - } - - [ ! $RUNSTRING ] && { - ERROR "type ${SCWRYPT_TYPE} (group ${SCWRYPT_GROUP}) has no supported runstring generator" - return 4 - } - - RUNSTRING="SCWRYPTS_ENV=$ENV_NAME; $RUNSTRING" - RUNSTRING="source $SCWRYPTS_ROOT__scwrypts/zsh/lib/import.driver.zsh; $RUNSTRING" - - local _VIRTUALENV=$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$SCWRYPT_GROUP'/$SCWRYPT_TYPE/bin/activate') - [ -f $_VIRTUALENV ] && RUNSTRING="source $_VIRTUALENV; $RUNSTRING" - - local G SCWRYPTSENV - for G in ${SCWRYPTS__GROUPS[@]} - do - SCWRYPTSENV="$SCWRYPTS_ENV_PATH/$G/$ENV_NAME" - [ -f $SCWRYPTSENV ] && RUNSTRING="source $SCWRYPTSENV; $RUNSTRING" - done - - echo "$RUNSTRING" -} - -SCWRYPTS__GET_RUNSTRING__zsh() { - __CHECK_DEPENDENCY zsh || return 1 - - local SCWRYPT_FILENAME - - [ $(eval echo '$SCWRYPTS_TYPE__'$SCWRYPT_GROUP) ] \ - && SCWRYPT_FILENAME="$GROUP_PATH/$SCWRYPT_NAME" \ - || SCWRYPT_FILENAME="$GROUP_PATH/$SCWRYPT_TYPE/$SCWRYPT_NAME" \ - ; - - SCWRYPTS__GET_RUNSTRING__zsh__generic "$SCWRYPT_FILENAME" - return 0 -} - -SCWRYPTS__GET_RUNSTRING__zsh__generic() { - # boilerplate to allow - # - multiflag splitting (e.g. -abc = -a -b -c) - # - help flag injection (e.g. -h | --help) - # - default USAGE definition (allows USAGE__options style usage definition) - # - required MAIN() function wrapping - # - # this is available automatically in SCWRYPTS_GROUP declaration contexts - # (e.g. my-group.scwrypts.zsh) - local ZSH_FILENAME="$1" - [ $ZSH_FILENAME ] || { - ERROR ' - to use SCWRYPTS__GET_RUNSTRING__zsh__generic, you must provide a - ZSH_FILENAME (arg $1) where the MAIN function is defined - ' - return 1 - } - printf " - source '$SCWRYPT_FILENAME' - CHECK_ENVIRONMENT - ERRORS=0 - - export USAGE=\" - usage: - - - args: - - - options: - - -h, --help display this message and exit - - description: - - \" - - [ ! \$USAGE__usage ] && export USAGE__usage='[...options...]' - - () { - local MAIN_ARGS=() - local VARSPLIT - while [[ \$# -gt 0 ]] - do - case \$1 in - -[a-z][a-z]* ) - VARSPLIT=\$(echo \"\$1 \" | sed 's/^\\\\(-.\\\\)\\\\(.*\\\\) /\\\\1 -\\\\2/') - set -- throw-away \$(echo \" \$VARSPLIT \") \${@:2} - ;; - -h | --help ) USAGE; exit 0 ;; - * ) MAIN_ARGS+=(\$1) ;; - esac - shift 1 - done - MAIN \${MAIN_ARGS[@]} - } " -} - -SCWRYPTS__GET_RUNSTRING__py() { - __CHECK_DEPENDENCY python || return 1 - CURRENT_PYTHON_VERSION=$(python --version | sed 's/^[^0-9]*\(3\.[^.]*\).*$/\1/') - echo $SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts | grep -q $CURRENT_PYTHON_VERSION || { - WARNING "only tested on the following python versions: $(printf ', %s.x' ${SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts[@]} | sed 's/^, //')" - WARNING 'compatibility may vary' - } - - echo "cd $GROUP_PATH; python -m $(echo $SCWRYPT_TYPE/$SCWRYPT_NAME | sed 's/\//./g; s/\.py$//; s/\.\.//')" -} - -SCWRYPTS__GET_RUNSTRING__zx() { - __CHECK_DEPENDENCY zx || return 1 - - echo "export FORCE_COLOR=3; cd $GROUP_PATH; ./$SCWRYPT_TYPE/$SCWRYPT_NAME.js" -} diff --git a/zsh/lib/scwrypts/scwrypts.module.zsh b/zsh/lib/scwrypts/scwrypts.module.zsh deleted file mode 100644 index 2c407f9..0000000 --- a/zsh/lib/scwrypts/scwrypts.module.zsh +++ /dev/null @@ -1,15 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -##################################################################### - -SCWRYPTS__GET_REALPATH() { - [[ ! $1 =~ ^[/~] ]] \ - && echo $(readlink -f "$EXECUTION_DIR/$1") \ - || echo "$1" \ - ; - - return 0 -} diff --git a/zsh/lib/scwrypts/virtualenv.module.zsh b/zsh/lib/scwrypts/virtualenv.module.zsh deleted file mode 100644 index 4e7275e..0000000 --- a/zsh/lib/scwrypts/virtualenv.module.zsh +++ /dev/null @@ -1,173 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -use utils - -##################################################################### - -AVAILABLE_VIRTUALENVS=(py zx) - -REFRESH_VIRTUALENV() { - local GROUP="$1" - local TYPE="$2" - local VIRTUALENV_PATH="$(_VIRTUALENV__GET_PATH)" - - [ ! $TYPE ] && { ERROR 'no virtualenv type specified'; return 1; } - - STATUS "refreshing $GROUP/$TYPE virtualenv" - DELETE_VIRTUALENV $GROUP $TYPE \ - && UPDATE_VIRTUALENV $GROUP $TYPE \ - && SUCCESS 'successfully refreshed virtualenv' \ - || { ERROR 'something went wrong during refresh (see above)'; return 1; } \ - ; -} - -UPDATE_VIRTUALENV() { - local GROUP="$1" - local TYPE="$2" - local VIRTUALENV_PATH="$(_VIRTUALENV__GET_PATH)" - - [ ! $TYPE ] && { ERROR 'no virtualenv type specified'; return 1; } - - : \ - && which CREATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \ - && which ACTIVATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \ - && which UPDATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \ - && which DEACTIVATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \ - || { STATUS "no virtualenv available for $GROUP/$TYPE; skipping"; return 0; } - - STATUS "updating $GROUP/$TYPE virtualenv" \ - && CREATE_VIRTUALENV__${GROUP}__${TYPE} \ - && ACTIVATE_VIRTUALENV__${GROUP}__${TYPE} \ - && UPDATE_VIRTUALENV__${GROUP}__${TYPE} \ - && DEACTIVATE_VIRTUALENV__${GROUP}__${TYPE} \ - && SUCCESS "$GROUP/$TYPE virtualenv up-to-date" \ - || { ERROR "failed to update $GROUP/$TYPE virtualenv (see errors above)"; return 2; } -} - -DELETE_VIRTUALENV() { - [ $CI ] && return 0 - - local GROUP="$1" - local TYPE="$2" - local VIRTUALENV_PATH="$(_VIRTUALENV__GET_PATH)" - - [ ! $TYPE ] && { ERROR 'no virtualenv type specified'; return 1; } - - STATUS "dropping $GROUP/$TYPE virtualenv artifacts" - - [ ! -d $VIRTUALENV_PATH ] && { - SUCCESS "no $GROUP/$TYPE environment detected" - return 0 - } - - rm -rf $VIRTUALENV_PATH \ - && SUCCESS "succesfully cleaned up $GROUP/$TYPE virtualenv" \ - || { ERROR "unabled to remove '$VIRTUALENV_PATH'"; return 1; } -} - -##################################################################### - -_VIRTUALENV__GET_PATH() { - local ENV_PATH="$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$GROUP 2>/dev/null)" - [ ! $ENV_PATH ] && ENV_PATH="$SCWRYPTS_VIRTUALENV_PATH__scwrypts" - - mkdir -p "$ENV_PATH/$TYPE" &>/dev/null - - echo $ENV_PATH/$TYPE -} - -##################################################################### - -CREATE_VIRTUALENV__scwrypts__py() { - [ $CI ] && return 0 - [ -d $VIRTUALENV_PATH ] && return 0 - - DEPENDENCIES=(virtualenv) CHECK_ENVIRONMENT || return 1 - - STATUS 'creating python virtualenv' - local PY PYTHON - for PY in $(echo $SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts) - do - which python$PY >/dev/null 2>&1 && { - PYTHON=$(which python$PY) - break - } - done - [ ! $PYTHON ] && { - ERROR 'python>=3.10 not available; skipping python env' - return 1 - } - - STATUS 'setting up virtualenv' - virtualenv $VIRTUALENV_PATH --python="$PYTHON" \ - && SUCCESS 'python virtualenv created' \ - || { - ERROR "unable to create '$VIRTUALENV_PATH' with '$PYTHON'" - return 2 - } -} - -ACTIVATE_VIRTUALENV__scwrypts__py() { - [ $CI ] && return 0 - source $VIRTUALENV_PATH/bin/activate || { - ERROR "failed to activate virtualenv $GROUP/$TYPE; did create fail?" - return 1 - } -} - -UPDATE_VIRTUALENV__scwrypts__py() { - local PIP_INSTALL_ARGS=() - - PIP_INSTALL_ARGS+=(--no-cache-dir) - PIP_INSTALL_ARGS+=(-r requirements.txt) - - cd "$SCWRYPTS_ROOT__scwrypts/py" - pip install ${PIP_INSTALL_ARGS[@]} -} - -DEACTIVATE_VIRTUALENV__scwrypts__py() { - deactivate >/dev/null 2>&1 - return 0 -} - -########################################## - -CREATE_VIRTUALENV__scwrypts__zx() { - [ $CI ] && return 0 - [ -d $VIRTUALENV_PATH ] && return 0 - - DEPENDENCIES=(nodeenv) CHECK_ENVIRONMENT || return 1 - - STATUS 'setting up nodeenv' - nodeenv $VIRTUALENV_PATH --node=$SCWRYPTS_NODE_VERSION__scwrypts \ - && SUCCESS 'node virtualenv created' \ - || { - ERROR "unable to create '$VIRTUALENV_PATH' with '$SCWRYPTS_NODE_VERSION__scwrypts'" - return 2 - } -} - -ACTIVATE_VIRTUALENV__scwrypts__zx() { - [ $CI ] && return 0 - source $VIRTUALENV_PATH/bin/activate || { - ERROR "failed to activate virtualenv $GROUP/$TYPE; did create fail?" - return 1 - } -} - -UPDATE_VIRTUALENV__scwrypts__zx() { - local NPM_INSTALL_ARGS=() - - [ $CI ] && NPM_INSTALL_ARGS+=(--ignore-scripts) - - cd "$SCWRYPTS_ROOT__scwrypts/zx" - npm install ${NPM_INSTALL_ARGS[@]} -} - -DEACTIVATE_VIRTUALENV__scwrypts__zx() { - deactivate_node >/dev/null 2>&1 - return 0 -} diff --git a/zsh/lib/system/config/config.module.zsh b/zsh/lib/system/config/config.module.zsh deleted file mode 100644 index cf1f723..0000000 --- a/zsh/lib/system/config/config.module.zsh +++ /dev/null @@ -1,18 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -##################################################################### - -DEFAULT_CONFIG="${0:a:h}/default.conf.zsh" - -SAFE_SYMLINKS=1 - -# in case dotfiles.zsh is sourced; allows users to provide initial config -[ ! $CONFIG__USER_SETTINGS ] \ - && CONFIG__USER_SETTINGS="$SCWRYPTS_CONFIG_PATH/dotfiles.zsh" - -[ ! -f "$CONFIG__USER_SETTINGS" ] && cp "$DEFAULT_CONFIG" "$CONFIG__USER_SETTINGS" - -source "$CONFIG__USER_SETTINGS" diff --git a/zsh/lib/system/config/default.conf.zsh b/zsh/lib/system/config/default.conf.zsh deleted file mode 100644 index 1e29f1c..0000000 --- a/zsh/lib/system/config/default.conf.zsh +++ /dev/null @@ -1,19 +0,0 @@ -# -# scwrypts dot-files config -# - -#TERMINFO_PATH=/path/to/sourced/terminfo/files - -# -# SAFE_SYMLINKS=1, makes a backup of config files that already exist -# SAFE_SYMLINKS=0, deletes existing config file -# -#SAFE_SYMLINKS=1 - - -# lines which begin with '#' are ignored -SYMLINKS=" -# fully qualified path ~/.config/THE-REST -# --------------------------------------------- -# /path/to/your/kitty.conf kitty/kitty.conf -" diff --git a/zsh/lib/system/desktop/notify.module.zsh b/zsh/lib/system/desktop/notify.module.zsh deleted file mode 100644 index ae0f62f..0000000 --- a/zsh/lib/system/desktop/notify.module.zsh +++ /dev/null @@ -1,16 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - notify-send -) - -REQUIRED_ENV+=() - -##################################################################### - -NOTIFY() { - local D=$DISPLAY - [ ! $D ] && D=:0 - - DISPLAY=$D notify-send "SCWRYPTS $SCWRYPT_NAME" $@ -} diff --git a/zsh/lib/system/packages/git.module.zsh b/zsh/lib/system/packages/git.module.zsh deleted file mode 100644 index 08a6638..0000000 --- a/zsh/lib/system/packages/git.module.zsh +++ /dev/null @@ -1,78 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - git - make -) - -REQUIRED_ENV+=() - -##################################################################### - -PACKAGE_INSTALL_DIR="$HOME/.local/share/source-packages" -[ ! -d "$PACKAGE_INSTALL_DIR" ] && mkdir -p "$PACKAGE_INSTALL_DIR" - -##################################################################### - -CLONE() { - cd "$PACKAGE_INSTALL_DIR" - STATUS "downloading $NAME" - git clone "$TARGET" "$NAME" \ - && SUCCESS "successfully downloaded '$NAME'" \ - || FAIL 1 "failed to download '$NAME'" \ - ; -} - -PULL() { - STATUS "updating '$NAME'" - cd "$PACKAGE_INSTALL_DIR/$NAME" - git pull origin $(git rev-parse --abbrev-ref HEAD) \ - && SUCCESS "successfully updated '$NAME'" \ - || FAIL 1 "failed to update '$NAME'" \ - ; -} - -##################################################################### - -BUILD() { - cd "$PACKAGE_INSTALL_DIR/$NAME" - - CHECK_MAKE && { MAKE && return 0 || return 1; } - CHECK_MAKEPKG && { MAKEPKG && return 0 || return 2; } - - WARNING 'could not detect supported installation method' - - REMINDER 'complete manual installation in the directory below:' - REMINDER "$PACKAGE_INSTALL_DIR/$NAME" -} - -CHECK_MAKE() { [ -f ./Makefile ]; } -CHECK_MAKEPKG() { [ -f ./PKGBUILD ]; } - -MAKE() { - [[ $CLEAN -eq 1 ]] && { - STATUS "cleaning '$NAME'" - make clean - } - - STATUS "building '$NAME'" - make \ - && SUCCESS "finished building '$NAME'" \ - || FAIL 1 "build failed for '$NAME' (see above)"\ - ; - - STATUS "installing '$NAME'" - GETSUDO - sudo make install \ - && SUCCESS "succesfully installed '$NAME'" \ - || FAIL 2 "failed to install '$NAME' (see above)"\ - ; -} - -MAKEPKG() { - STATUS "installing '$NAME'" - yes | makepkg -si \ - && SUCCESS "succesfully installed '$NAME'" \ - || FAIL 1 "failed to install '$NAME' (see above)"\ - ; -} diff --git a/zsh/lib/system/vim/vim.module.zsh b/zsh/lib/system/vim/vim.module.zsh deleted file mode 100644 index b1b593c..0000000 --- a/zsh/lib/system/vim/vim.module.zsh +++ /dev/null @@ -1,11 +0,0 @@ -##################################################################### - -DEPENDENCIES+=( - vim -) - -REQUIRED_ENV+=() - -##################################################################### - -VIM() { vim $@ /dev/tty; } diff --git a/zsh/lib/system/vim/vundle.module.zsh b/zsh/lib/system/vim/vundle.module.zsh deleted file mode 100644 index 7f3ba51..0000000 --- a/zsh/lib/system/vim/vundle.module.zsh +++ /dev/null @@ -1,53 +0,0 @@ -##################################################################### - -DEPENDENCIES+=() -REQUIRED_ENV+=() - -use system/vim - -##################################################################### - -VUNDLE__PLUGIN_DIR="$HOME/.vim/bundle" -VUNDLE__BUILD_DEFINITIONS="$SCWRYPTS_CONFIG_PATH/vundle.zsh" - -[ ! -f $VUNDLE__BUILD_DEFINITIONS ] && { - { - echo -e "#\n# Scwrypts Build Definitions\n#\n" - } > $VUNDLE__BUILD_DEFINITIONS -} - -VUNDLE__PLUGIN_LIST=$(ls $VUNDLE__PLUGIN_DIR | grep -v 'Vundle.vim' | grep -v 'build.zsh') -source $VUNDLE__BUILD_DEFINITIONS -for PLUGIN in $(echo $VUNDLE__PLUGIN_LIST) -do - which VUNDLE__BUILD__$PLUGIN >/dev/null 2>/dev/null || { - echo -e "\nVUNDLE__BUILD__$PLUGIN() {\n # ... build steps from $HOME/.vim/$PLUGIN \n}" \ - >> $VUNDLE__BUILD_DEFINITIONS - VUNDLE__BUILD__$PLUGIN() {} - } -done - -##################################################################### - -VUNDLE__PLUGIN_INSTALL() { - VIM +PluginInstall +qall \ - && SUCCESS 'successfully installed Vundle.vim plugins' \ - || FAIL 1 'failed to install Vundle.vim plugins' -} - -VUNDLE__REBUILD_PLUGINS() { - local ERRORS=0 - - local PLUGIN - for PLUGIN in $(echo $VUNDLE__PLUGIN_LIST) - do - cd "$VUNDLE__PLUGIN_DIR/$PLUGIN" - STATUS "building '$PLUGIN'" - VUNDLE__BUILD__$PLUGIN \ - && SUCCESS "finished building '$PLUGIN'" \ - || ERROR "failed to build '$PLUGIN' (see above)" \ - ; - done - - return $ERRORS -} diff --git a/zsh/lib/utils/colors.zsh b/zsh/lib/utils/colors.zsh deleted file mode 100644 index adc2565..0000000 --- a/zsh/lib/utils/colors.zsh +++ /dev/null @@ -1,44 +0,0 @@ -__BLACK='\033[0;30m' -__DARK_GRAY='\033[1;30m' - -__RED='\033[0;31m' -__BRIGHT_RED='\033[1;31m' - -__GREEN='\033[0;32m' -__BRIGHT_GREEN='\033[1;32m' - -__YELLOW='\033[0;33m' -__BRIGHT_YELLOW='\033[1;33m' - -__BLUE='\033[0;34m' -__BRIGHT_BLUE='\033[1;34m' - -__MAGENTA='\033[0;35m' -__BRIGHT_MAGENTA='\033[1;35m' - -__CYAN='\033[0;36m' -__BRIGHT_CYAN='\033[1;36m' - -__WHITE='\033[1;37m' -__LIGHT_GRAY='\033[0;37m' - -__COLOR_RESET='\033[0m' - -__GET_RANDOM_COLOR() { - local COLORS=( - $__RED - $__BRIGHT_RED - $__GREEN - $__BRIGHT_GREEN - $__YELLOW - $__BRIGHT_YELLOW - $__BLUE - $__BRIGHT_BLUE - $__MAGENTA - $__BRIGHT_MAGENTA - $__CYAN - $__BRIGHT_CYAN - $__WHITE - ) - print "$__COLOR_RESET${COLORS[$(shuf -i 1-${#COLORS[@]} -n 1)]}" -} diff --git a/zsh/lib/utils/credits.zsh b/zsh/lib/utils/credits.zsh deleted file mode 100644 index e55170d..0000000 --- a/zsh/lib/utils/credits.zsh +++ /dev/null @@ -1,11 +0,0 @@ -__CREDITS() { - # scwrypts exclusive ("credits" pulled from README files) - [ ! $SCWRYPTS_ROOT ] && return 0 - - local COMMAND="$1" - [[ $COMMAND =~ - ]] && COMMAND=$(echo $COMMAND | sed 's/-/--/g') - cd $SCWRYPTS_ROOT - cat ./**/README.md \ - | grep 'Generic Badge' \ - | sed -n "s/.*Generic Badge.*-$COMMAND-.*(/(/p" -} diff --git a/zsh/lib/utils/dependencies.zsh b/zsh/lib/utils/dependencies.zsh deleted file mode 100644 index 3888763..0000000 --- a/zsh/lib/utils/dependencies.zsh +++ /dev/null @@ -1,52 +0,0 @@ -__CHECK_DEPENDENCIES() { - local DEP ERRORS=0 - local SCWRYPTS_LOG_LEVEL=1 - [ ! $E ] && E=ERROR - - DEPENDENCIES=($(echo $DEPENDENCIES | sed 's/ \+/\n/g' | sort -u)) - - for DEP in ${DEPENDENCIES[@]}; do __CHECK_DEPENDENCY $DEP || ((ERRORS+=1)); done - __CHECK_COREUTILS || ((ERRORS+=$?)) - - return $ERRORS -} - -__CHECK_DEPENDENCY() { - local DEPENDENCY="$1" - [ ! $DEPENDENCY ] && return 1 - command -v $DEPENDENCY >/dev/null 2>&1 || { - $E "application '$1' "$([[ $OPTIONAL -eq 1 ]] && echo preferred || echo required)" but not available on PATH $(__CREDITS $1)" - return 1 - } - - [[ $DEPENDENCY =~ ^yq$ ]] && { - yq --version | grep -q mikefarah \ - || WARNING 'detected kislyuk/yq but mikefarah/yq is preferred (compatibility may vary)' - } - - return 0 -} - -__CHECK_COREUTILS() { - local COREUTILS=(awk find grep sed readlink) - local MISSING_DEPENDENCY_COUNT=0 - local NON_GNU_DEPENDENCY_COUNT=0 - - local UTIL - for UTIL in $(echo $COREUTILS) - do - __CHECK_DEPENDENCY $UTIL || { ((MISSING_DEPENDENCY_COUNT+=1)); continue; } - - $UTIL --version 2>&1 | grep 'GNU' | grep -qv 'BSD' || { - WARNING "non-GNU version of $UTIL detected" - ((NON_GNU_DEPENDENCY_COUNT+=1)) - } - done - - [[ $NON_GNU_DEPENDENCY_COUNT -gt 0 ]] && { - WARNING 'scripts rely on GNU coreutils; compatibility may vary' - IS_MACOS && REMINDER 'GNU coreutils can be installed and linked through Homebrew' - } - - return $MISSING_DEPENDENCY_COUNT -} diff --git a/zsh/lib/utils/environment.zsh b/zsh/lib/utils/environment.zsh deleted file mode 100644 index bd7a85a..0000000 --- a/zsh/lib/utils/environment.zsh +++ /dev/null @@ -1,39 +0,0 @@ -__CHECK_REQUIRED_ENV() { - local SCWRYPTS_LOG_LEVEL=1 - local VAR ERROR=0 - REQUIRED_ENV=($(echo $REQUIRED_ENV | sed 's/\s\+/\n/g' | sort -u)) - for VAR in ${REQUIRED_ENV[@]}; do __CHECK_ENV_VAR $VAR || ((ERROR+=1)); done - return $ERROR -} - -__CHECK_ENV_VAR() { - local NAME="$1" - [ ! $NAME ] && return 1 - - local OVERRIDE_VALUE=$(eval echo '$'$NAME'__override') - [ $OVERRIDE_VALUE ] && export $NAME=$OVERRIDE_VALUE && return 0 - - local OPTIONAL="$2" - local DEFAULT_VALUE="$3" - - local VALUE=$(eval echo '$'$NAME) - [ $VALUE ] && return 0 - - local SELECTION_VALUES=$(eval echo '$'$NAME'__select' | sed 's/,/\n/g; s/ /\n/g') - [[ $ERROR -eq 0 ]] && [[ ${#SELECTION_VALUES[@]} -gt 0 ]] && { - local SELECTION=$(echo $SELECTION_VALUES | FZF "select a value for '$NAME'") - [ $SELECTION ] && { - export $NAME=$SELECTION - return 0 - } - } - [ $VALUE ] && return 0 - - [ $OPTIONAL ] && { - [ $DEFAULT_VALUE ] && $NAME="$DEFAULT_VALUE" - return 0 - } || { - ERROR "variable '$NAME' required" - return 1 - } -} diff --git a/zsh/lib/utils/io.fzf.zsh b/zsh/lib/utils/io.fzf.zsh deleted file mode 100644 index 89713e4..0000000 --- a/zsh/lib/utils/io.fzf.zsh +++ /dev/null @@ -1,45 +0,0 @@ -FZF() { - [ $CI ] && { - DEBUG "invoked FZF with $@" - FAIL 1 'currently in CI, but FZF requires user input' - } - - local FZF_ARGS=() - - FZF_ARGS+=(-i) - FZF_ARGS+=(--ansi) - FZF_ARGS+=(--bind=ctrl-c:cancel) - FZF_ARGS+=(--height=50%) - FZF_ARGS+=(--layout=reverse) - - local SELECTION=$(fzf ${FZF_ARGS[@]} --prompt "$1 : " ${@:2} 2>/dev/tty) - PROMPT "$1" - - [ $BE_QUIET ] || { - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $SELECTION >&2 - } - echo $SELECTION - [ $SELECTION ] -} - -FZF_USER_INPUT() { # allow user to type custom answers; reconfirm if ambiguous with select - local FZF_OUTPUT=$(BE_QUIET=1 FZF $@ --print-query | sed '/^$/d' | sort -u) - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $FZF_OUTPUT | head -n1 >&2 - [ ! $FZF_OUTPUT ] && return 1 - - [[ $(echo "$FZF_OUTPUT" | wc -l) -eq 1 ]] \ - && { echo "$FZF_OUTPUT"; return 0; } - - local FZF_OUTPUT=$( - echo "$FZF_OUTPUT" \ - | sed "1s/\$/^$(printf "$__LIGHT_GRAY\\033[3m")<- what you typed$(printf $__COLOR_RESET)/" \ - | sed "2s/\$/^$(printf "$__LIGHT_GRAY\\033[3m")<- what you selected$(printf $__COLOR_RESET)/" \ - | column -ts '^' \ - | BE_QUIET=1 FZF "$@ (clarify)" \ - ) - - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $FZF_OUTPUT >&2 - FZF_OUTPUT=$(echo $FZF_OUTPUT | sed 's/\s\+<- what you .*$//') - echo $FZF_OUTPUT - [ $FZF_OUTPUT ] -} diff --git a/zsh/lib/utils/io.print.zsh b/zsh/lib/utils/io.print.zsh deleted file mode 100644 index 7c948a6..0000000 --- a/zsh/lib/utils/io.print.zsh +++ /dev/null @@ -1,65 +0,0 @@ -PRINT() { - local MESSAGE - local LAST_LINE_END='\n' - local STDERR=1 - local STDOUT=0 - - local LTRIM=1 - local FORMAT=$SCWRYPTS_OUTPUT_FORMAT - local _S - while [[ $# -gt 0 ]] - do - _S=1 - case $1 in - -n | --no-trim-tabs ) LTRIM=0 ;; - -x | --no-line-end ) LAST_LINE_END='' ;; - -o | --use-stdout ) STDOUT=1; STDERR=0 ;; - - -f | --format ) ((_S+=1)); FORMAT=$2 ;; - - * ) MESSAGE+="$(echo $1) " ;; - esac - shift $_S - done - - [ $FORMAT ] || FORMAT=pretty - local STYLED_MESSAGE - case $FORMAT in - pretty ) - STYLED_MESSAGE="$(echo "$MESSAGE" | sed 's/%/%%/g')" - STYLED_MESSAGE="$({ - printf "${COLOR}" - while IFS='' read line - do - [[ $PREFIX =~ ^[[:space:]]\+$ ]] && printf '\n' - - printf "${PREFIX} : $(echo "$line" | sed 's/^ \+//; s/ \+$//')" - - PREFIX=$(echo $PREFIX | sed 's/./ /g') - done <<< $MESSAGE - })" - STYLED_MESSAGE="${COLOR}$(echo "$STYLED_MESSAGE" | sed 's/%/%%/g')${__COLOR_RESET}${LAST_LINE_END}" - ;; - json ) - STYLED_MESSAGE="$( - echo '{}' | jq -c ". - | .timestamp = \"$(date +%s)\" - | .runtime = \"$SCWRYPTS_RUNTIME_ID\" - | .status = \"$(echo "$PREFIX" | sed 's/ .*//')\" - | .message = $(echo $MESSAGE | sed 's/^\t\+//' | jq -Rs) - " | sed 's/\\/\\\\/g' - )\n" - ;; - * ) - echo "ERROR : unsupported format '$FORMAT'" >&2 - return 1 - ;; - esac - - - - [[ $STDERR -eq 1 ]] && printf -- "$STYLED_MESSAGE" >&2 - [[ $STDOUT -eq 1 ]] && printf -- "$STYLED_MESSAGE" - - return 0 -} diff --git a/zsh/lib/utils/io.usage.zsh b/zsh/lib/utils/io.usage.zsh deleted file mode 100644 index 789c337..0000000 --- a/zsh/lib/utils/io.usage.zsh +++ /dev/null @@ -1,65 +0,0 @@ -USAGE() { # formatter for USAGE variable - [ ! $USAGE ] && return 0 - local USAGE_LINE=$(echo $USAGE | grep -i '^[ ]*usage *:' | sed 's/^[ ]*//') - - [ $USAGE__usage ] && echo $USAGE_LINE | grep -q 'usage: -' \ - && USAGE_LINE=$(echo $USAGE_LINE | sed "s/usage: -/usage: $USAGE__usage/") - - [ $__SCWRYPT ] \ - && USAGE_LINE=$( - echo $USAGE_LINE \ - | sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \ - | sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \ - ) - - local THE_REST=$(echo $USAGE | grep -vi '^[ ]*usage *:' ) - - local DYNAMIC_USAGE_ELEMENT - # - # create dynamic usage elements (like 'args') by defining USAGE__ - # then using the syntax ": -" in your USAGE variable - # - # e.g. - # - # USAGE__args=" - # subcommand arg 1 arg 1 description - # subcommand arg 2 some other description - # " - # - # USAGE=" - # usage: some-command [...args...] - # - # args: - - # -h, --help some arguments are applicable everywhere - # " - # - for DYNAMIC_USAGE_ELEMENT in $(echo $THE_REST | sed -n 's/^\([^:]*\): -$/\1/p') - do - DYNAMIC_USAGE_ELEMENT_TEXT=$(eval echo '$USAGE__'$DYNAMIC_USAGE_ELEMENT) - #[ $DYNAMIC_USAGE_ELEMENT_TEXT ] || continue - - - case $DYNAMIC_USAGE_ELEMENT in - description ) - DYNAMIC_USAGE_ELEMENT_TEXT=$(echo "$DYNAMIC_USAGE_ELEMENT_TEXT" | perl -p0e 's/^[\n\s]+//') - DYNAMIC_USAGE_ELEMENT_TEXT="$__YELLOW\\033[03m$DYNAMIC_USAGE_ELEMENT_TEXT\\033[0m" - ;; - * ) - DYNAMIC_USAGE_ELEMENT_TEXT=$(echo $DYNAMIC_USAGE_ELEMENT_TEXT | sed 's/[^ ]/ &/') - ;; - esac - - THE_REST=$(echo $THE_REST | perl -pe "s$DYNAMIC_USAGE_ELEMENT: -$DYNAMIC_USAGE_ELEMENT:\n$DYNAMIC_USAGE_ELEMENT_TEXT\n\n") - done - - # allow for dynamic 'description: -' but delete the 'description:' header line - THE_REST=$(echo $THE_REST | sed '/^[ ]*description:$/d') - - echo "$__BLUE$USAGE_LINE$__COLOR_RESET\n\n$THE_REST" \ - | sed "s/^\t\+//; s/\s\+$//; s/^\\s*$//;" \ - | sed '/./,$!d; :a; /^\n*$/{$d;N;ba;};' \ - | perl -p0e 's/\n{2,}/\n\n/g' \ - | perl -p0e 's/:\n{2,}/:\n/g' \ - | perl -p0e 's/([a-z]+:)\n([a-z]+:)/\2/g' \ - >&2 -} diff --git a/zsh/lib/utils/io.zsh b/zsh/lib/utils/io.zsh deleted file mode 100644 index 508d9ac..0000000 --- a/zsh/lib/utils/io.zsh +++ /dev/null @@ -1,249 +0,0 @@ -##################################################################### -### basic colorized print messages ################################## -##################################################################### - -source "${0:a:h}/io.print.zsh" -[ ! $ERRORS ] && ERRORS=0 - -ERROR() { # command encountered an error - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ - && PREFIX="ERROR ✖" COLOR=$__RED PRINT "$@" - ((ERRORS+=1)) - return $ERRORS -} - -SUCCESS() { # command completed successfully - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ - && PREFIX="SUCCESS ✔" COLOR=$__GREEN PRINT "$@" - return 0 -} - -REMINDER() { # include sysadmin reminder or other important notice to users - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ - && PREFIX="REMINDER " COLOR=$__BRIGHT_MAGENTA PRINT "$@" - return 0 -} - -STATUS() { # general status updates (prefer this to generic 'echo') - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 - [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] \ - && PREFIX="STATUS " COLOR=$__BLUE PRINT "$@" - return 0 -} - -WARNING() { # warning-level messages; not errors - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 - [[ $SCWRYPTS_LOG_LEVEL -ge 3 ]] \ - && PREFIX="WARNING " COLOR=$__YELLOW PRINT "$@" - return 0 -} - -DEBUG() { # helpful during development or (sparingly) to help others' development - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 - [[ $SCWRYPTS_LOG_LEVEL -ge 4 ]] \ - && PREFIX="DEBUG ℹ" COLOR=$__WHITE PRINT "$@" - return 0 -} - -PROMPT() { # you probably want to use yN or INPUT from below - [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=4 - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] \ - && PREFIX="PROMPT " COLOR=$__CYAN PRINT "$@" \ - && PREFIX="USER ⌨" COLOR=$__BRIGHT_CYAN PRINT '' --no-line-end \ - ; - return 0 -} - -FAIL() { SCWRYPTS_LOG_LEVEL=1 ERROR "${@:2}"; exit $1; } -ABORT() { FAIL 69 'user abort'; } - -##################################################################### -### check for reported errors and format USAGE contents ############# -##################################################################### - -CHECK_ERRORS() { - local FAIL_OUT=true - local DISPLAY_USAGE=true - - [ ! $ERRORS ] && ERRORS=0 - - while [[ $# -gt 0 ]] - do - case $1 in - --fail ) FAIL_OUT=true ;; - --no-fail ) FAIL_OUT=false ;; - - --usage ) DISPLAY_USAGE=true ;; - --no-usage ) DISPLAY_USAGE=false ;; - esac - shift 1 - done - - [[ $ERRORS -eq 0 ]] && return 0 - - [[ $DISPLAY_USAGE =~ true ]] && USAGE - - [[ $FAIL_OUT =~ true ]] && exit $ERRORS || return $ERRORS -} - -source "${0:a:h}/io.usage.zsh" - -##################################################################### -### facilitate user prompt and input ################################ -##################################################################### - -# yes/no prompts && = yes (exit code 0) -# || = no (exit code 1) -Yn() { [[ ! $(READ_YN $@ '[Yn]') =~ [nN] ]]; } # default 'yes' -yN() { [[ $(READ_YN $@ '[yN]') =~ [yY] ]]; } # default 'no' - -INPUT() { # read a single line of user input - PROMPT "${@:2}" - READ $1 - local VALUE=$(eval echo '$'$1) - [ $VALUE ] -} - -source "${0:a:h}/io.fzf.zsh" # allow user to select from a list of inputs - -EDIT() { # edit a file in user's preferred editor - [ $CI ] && { - WARNING 'currently in CI, skipping EDIT' - return 0 - } - - STATUS "opening '$1' for editing" - $EDITOR $@ /dev/tty - SUCCESS "finished editing '$1'!" -} - -##################################################################### -### basic commands with tricky states or default requirements ####### -##################################################################### - -LESS() { less -R $@ /dev/tty; } - -YQ() { - yq --version | grep -q mikefarah || { - yq $@ - return $? - } - - yq eval '... comments=""' | yq $@ -} - -##################################################################### -### other i/o utilities ############################################# -##################################################################### - -CAPTURE() { - [ ! $USAGE ] && USAGE=" - usage: stdout-varname stderr-varname [...cmd and args...] - - captures stdout and stderr on separate variables for a command - " - { - IFS=$'\n' read -r -d '' $2; - IFS=$'\n' read -r -d '' $1; - } < <((printf '\0%s\0' "$(${@:3})" 1>&2) 2>&1) -} - - -GETSUDO() { - echo "\\033[1;36mPROMPT  : checking sudo password...\\033[0m" >&2 - sudo echo hi >/dev/null 2>&1 &2 - - READ ${READ_ARGS[@]} -s -k yn - - [[ $PERFORM_FAKE_PROMPT =~ true ]] \ - && echo $yn >&2 - ;; - esac - - [[ $SCWRYPTS_LOG_LEVEL -ge 1 ]] && echo $yn >&2 - - echo $yn -} diff --git a/zsh/lib/utils/os.zsh b/zsh/lib/utils/os.zsh deleted file mode 100644 index c5276d0..0000000 --- a/zsh/lib/utils/os.zsh +++ /dev/null @@ -1,12 +0,0 @@ -IS_MACOS() { uname -s | grep -q 'Darwin'; } - -OPEN() { - local OPEN='' - { - command -v xdg-open && OPEN=xdg-open - command -v open && OPEN=open - } >/dev/null 2>&1 - - [ ! $OPEN ] && { ERROR 'unable to detect default open command (e.g. xdg-open)'; return 1 } - $OPEN $@ -} diff --git a/zsh/lib/utils/utils.module.zsh b/zsh/lib/utils/utils.module.zsh deleted file mode 100644 index a9ba63c..0000000 --- a/zsh/lib/utils/utils.module.zsh +++ /dev/null @@ -1,89 +0,0 @@ -##################################################################### - -DEPENDENCIES+=(fzf) # (extensible) list of PATH dependencies -REQUIRED_ENV+=() # (extensible) list of required environment variables - -##################################################################### - -source ${0:a:h}/colors.zsh -source ${0:a:h}/io.zsh -source ${0:a:h}/os.zsh -source ${0:a:h}/credits.zsh - -##################################################################### - -source ${0:a:h}/dependencies.zsh -source ${0:a:h}/environment.zsh - -##################################################################### - -CHECK_ENVIRONMENT() { - local OPTIONAL=0 - - while [[ $# -gt 0 ]] - do - case $1 in - --optional ) OPTIONAL=1 ;; - esac - shift 1 - done - - [[ $OPTIONAL -eq 1 ]] && E=WARNING || E=ERROR - - local ENVIRONMENT_STATUS=0 - - __CHECK_DEPENDENCIES $DEPENDENCIES - local MISSING_DEPENDENCIES=$? - - __CHECK_REQUIRED_ENV $REQUIRED_ENV - local MISSING_ENVIRONMENT_VARIABLES=$? - - ########################################## - - local ERROR_MESSAGE="" - [[ $MISSING_DEPENDENCIES -ne 0 ]] && { - ((ENVIRONMENT_STATUS+=1)) - ERROR_MESSAGE+="\n$MISSING_DEPENDENCIES missing " - - [[ $MISSING_DEPENDENCIES -eq 1 ]] \ - && ERROR_MESSAGE+='dependency' \ - || ERROR_MESSAGE+='dependencies' \ - ; - } - - [[ $MISSING_ENVIRONMENT_VARIABLES -ne 0 ]] && { - ((ENVIRONMENT_STATUS+=2)) - ERROR_MESSAGE+="\n$MISSING_ENVIRONMENT_VARIABLES missing environment variable" - - [[ $MISSING_ENVIRONMENT_VARIABLES -gt 1 ]] && ERROR_MESSAGE+=s - } - - [ $IMPORT_ERRORS ] && [[ $IMPORT_ERRORS -ne 0 ]] && { - ((ENVIRONMENT_STATUS+=4)) - ERROR_MESSAGE+="\n$IMPORT_ERRORS import error" - - [[ $IMPORT_ERRORS -gt 1 ]] && ERROR_MESSAGE+=s - } - - ########################################## - - [[ ENVIRONMENT_STATUS -ne 0 ]] && [[ $OPTIONAL -eq 0 ]] && { - ERROR_MESSAGE=$(echo $ERROR_MESSAGE | sed '1d; s/^/ /') - $E "environment errors found (see above)\n$ERROR_MESSAGE" - } - - [[ $MISSING_ENVIRONMENT_VARIABLES -ne 0 ]] && [[ $__SCWRYPT ]] && { - REMINDER " - to quickly update missing environment variables, run: - 'scwrypts zsh/scwrypts/environment/edit' - " - } - - [[ $ENVIRONMENT_STATUS -ne 0 ]] && [[ $NO_EXIT -ne 1 ]] && [[ $OPTIONAL -eq 0 ]] && { - exit $ENVIRONMENT_STATUS - } - - return $ENVIRONMENT_STATUS -} - -CHECK_ENVIRONMENT diff --git a/zsh/media/youtube/README.md b/zsh/media/youtube/README.md deleted file mode 100644 index 1bf7b5d..0000000 --- a/zsh/media/youtube/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# ZSH Scwrypts -[![Generic Badge](https://img.shields.io/badge/ytdl--org-youtube--dl-informational.svg)](https://github.com/ytdl-org/youtube-dl) -
- -Quick wrappers for downloading and trimming YouTube videos. diff --git a/zsh/media/youtube/download b/zsh/media/youtube/download deleted file mode 100755 index eaeac2f..0000000 --- a/zsh/media/youtube/download +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/zsh -use media/youtube -##################################################################### - -MAIN() { - local URLS=($@) - - [[ ${#URLS[@]} -eq 0 ]] && URLS=($(echo '' | FZF_USER_INPUT 'enter URL')) - [[ ${#URLS[@]} -eq 0 ]] && ABORT - - local FILENAME=$(YT__GET_FILENAME $URLS) - [ ! $FILENAME ] && ERROR "unable to download '$URLS'" - - SUCCESS "Found '$FILENAME'" - Yn "Proceed with download?" || return 1 - - YT__DOWNLOAD $URLS \ - && SUCCESS "downloaded to '$YT__OUTPUT_DIR/$FILENAME'" \ - || { ERROR "failed to download '$FILENAME'"; return 2; } -} diff --git a/zsh/media/youtube/get-audio-clip b/zsh/media/youtube/get-audio-clip deleted file mode 100755 index 3294303..0000000 --- a/zsh/media/youtube/get-audio-clip +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/zsh -use media/youtube -##################################################################### - -MAIN() { - local URLS=($@) - - [[ ${#URLS[@]} -eq 0 ]] && URLS=($(echo '' | FZF_USER_INPUT 'enter URL')) - [[ ${#URLS[@]} -eq 0 ]] && ABORT - - local FILENAME=$(YT__GET_FILENAME $URLS) - [ ! $FILENAME ] && ERROR "unable to download '$URLS'" - - INPUT_FILE="$YT__OUTPUT_DIR/$FILENAME" - - [ ! -f "$INPUT_FILE" ] && { - SCWRYPTS__RUN youtube/download -- $URLS || return 1 - } - - SUCCESS "video download '$FILENAME' detected!" - - LENGTH=$(GET_VIDEO_LENGTH "$INPUT_FILE") - [ ! $LENGTH ] && { ERROR "unable to determine video length for '$INPUT_FILE'"; return 2; } - START_TIME=$(echo 0 | FZF_USER_INPUT "enter start time (0 ≤ t < $LENGTH)") - [ ! $START_TIME ] && ABORT - END_TIME=$(echo $LENGTH | FZF_USER_INPUT "enter end time ($START_TIME > t ≥ $LENGTH)") - [ ! $END_TIME ] && ABORT - - STATUS - STATUS "video : $FILENAME" - STATUS "start time : $START_TIME" - STATUS "end time : $END_TIME" - STATUS - OUTPUT_FILE=$(echo '' \ - | FZF_USER_INPUT 'what should I call this clip? (.mp3)' \ - | sed 's/\.mp3$//' \ - ) - [ ! $OUTPUT_FILE ] && ABORT - OUTPUT_FILE="$YT__OUTPUT_DIR/$OUTPUT_FILE.mp3" - - ffmpeg -i "$INPUT_FILE" -q:a 0 -map a \ - -ss $START_TIME -t $(($END_TIME - $START_TIME))\ - "$OUTPUT_FILE" \ - && SUCCESS "created clip '$OUTPUT_FILE'" \ - || { ERROR "error creating clip '$(basename $OUTPUT_FILE)' (see above)"; return 3; } -} diff --git a/zsh/misc/tally b/zsh/misc/tally deleted file mode 100755 index 1ac0e72..0000000 --- a/zsh/misc/tally +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/zsh -use misc/tally -##################################################################### - -MAIN() { - unset USAGE - TALLY $@ -} diff --git a/zsh/notify/desktop.module.zsh b/zsh/notify/desktop.module.zsh new file mode 100644 index 0000000..fd365e3 --- /dev/null +++ b/zsh/notify/desktop.module.zsh @@ -0,0 +1,15 @@ +##################################################################### + +SCWRYPTS_NOTIFICATION_ENGINES+=(${scwryptsmodule}) + +${scwryptsmodule}.success() { notify.desktop echo.success $@; } +${scwryptsmodule}.error() { notify.desktop echo.error $@; } +${scwryptsmodule}.reminder() { notify.desktop echo.reminder $@; } +${scwryptsmodule}.status() { notify.desktop echo.status $@; } +${scwryptsmodule}.warning() { notify.desktop echo.warning $@; } +${scwryptsmodule}.debug() { notify.desktop echo.debug $@; } + +${scwryptsmodule}() { + local MESSAGE="$($1 --stdout ${@:2} | utils.colors.remove)" + [ "${MESSAGE}" ] && utils.notify-send "${MESSAGE}" +} diff --git a/zsh/notify/notify.module.zsh b/zsh/notify/notify.module.zsh new file mode 100644 index 0000000..6d2108b --- /dev/null +++ b/zsh/notify/notify.module.zsh @@ -0,0 +1,37 @@ +# +# send notifications from the command line +# + +SCWRYPTS_NOTIFICATION_ENGINES=(echo) +# +# a "notification engine" implements all the .methods in the first block +# of ../utils/io/20-echo.zsh (e.g. "echo.success") +# +# using 'echo' as a notification engine will print the message to the +# console as well +# +# overwrite this variable if you only want to notify a subset of engines +# e.g. : +# local SCWRYPTS_NOTIFICATION_ENGINES=(echo desktop) +# + +# notify-send integration +use notify/desktop + +##################################################################### + +${scwryptsmodule}() { # notify all available methods + local ENGINE + for ENGINE in ${SCWRYPTS_NOTIFICATION_ENGINES[@]} + do + ${ENGINE}.${1} ${@:2} + done + return 0 +} + +${scwryptsmodule}.success() { notify success $@; } +${scwryptsmodule}.error() { notify error $@; return 1; } +${scwryptsmodule}.reminder() { notify reminder $@; } +${scwryptsmodule}.status() { notify status $@; } +${scwryptsmodule}.warning() { notify warning $@; } +${scwryptsmodule}.debug() { notify debug $@; } diff --git a/zsh/office/latex/build-pdf b/zsh/office/latex/build-pdf deleted file mode 100755 index 39ef9cd..0000000 --- a/zsh/office/latex/build-pdf +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/zsh -use office/latex -##################################################################### - -MAIN() { - [ ! $1 ] && FAIL 1 'must provide filename' - local FILENAME=$(LATEX__GET_MAIN_FILENAME "$1") - - local ARGS=(-interaction=nonstopmode) - ARGS+=("$FILENAME") - - cd "$(dirname $FILENAME)" - - STATUS 'running compile (1/2)' - pdflatex ${ARGS[@]} \ - || FAIL 2 'first compile failed (see above)' - - STATUS 'running compile (2/2)' - pdflatex ${ARGS[@]} >/dev/null 2>&1 \ - || FAIL 3 'second compile failed :c' - - SUCCESS "created '$(echo $FILENAME | sed 's/\.[^.]*$/.pdf/')'" -} diff --git a/zsh/office/latex/cleanup b/zsh/office/latex/cleanup deleted file mode 100755 index efd699b..0000000 --- a/zsh/office/latex/cleanup +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/zsh -use office/latex -##################################################################### - -MAIN() { - local DIRECTORY=$(SCWRYPTS__GET_REALPATH ".") - [ $1 ] && DIRECTORY="$(dirname "$(LATEX__GET_MAIN_FILENAME "$1")")" - [ $DIRECTORY ] && [ -d $DIRECTORY ] \ - || FAIL 1 'unable to parse valid directory' - - cd $DIRECTORY - rm $(ls | grep '\.\(aux\)\|\(log\)\|\(pdf\)\|\(out\)\|\(dvi\)$') - - SUCCESS "cleaned up latex artifacts in '$DIRECTORY'" -} diff --git a/zsh/office/latex/create-new b/zsh/office/latex/create-new deleted file mode 100755 index 2a8d394..0000000 --- a/zsh/office/latex/create-new +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/zsh -use office/latex -##################################################################### - -TEMPLATE_DIR="${0:a:h}/templates" - -MAIN() { - local DOCUMENT_DIR="$EXECUTION_DIR" - local TEMPLATE=$(GET_TEMPLATES | FZF 'select a template') - [ ! $TEMPLATE ] && ABORT - SUCCESS "selected template '$TEMPLATE'" - - INPUT DOC_TITLE 'document title' || ABORT - - local DOCUMENT_FILE="$DOCUMENT_DIR/$(SLUGIFY_TITLE).tex" - [ -f "$DOCUMENT_FILE" ] && FAIL 1 "'$(basename $DOCUMENT_FILE)' already exists" - - INPUT DOC_ID 'document id/subtitle' - INPUT AUTHOR 'author name' - INPUT AUTHOR_ID 'author id/title' - - { - PRINT_TITLE_INFO - cat "$TEMPLATE_DIR/$TEMPLATE/template.tex" - } > "$DOCUMENT_FILE" - cp "$TEMPLATE_DIR/gitignore" "$DOCUMENT_DIR/.gitignore" - for FILE in $(find "$TEMPLATE_DIR/$TEMPLATE" -type f | grep -v '/template.tex$') - do - cp "$FILE" "$DOCUMENT_DIR/" || return 2 - done - [[ ! $TEMPLATE =~ ^basic$ ]] \ - && mkdir "$DOCUMENT_DIR/sections" "$DOCUMENT_DIR/graphics" - - SUCCESS "finished generating '$(basename $DOCUMENT_FILE)' from '$TEMPLATE'" -} - -##################################################################### - -GET_TEMPLATES() { - find "$TEMPLATE_DIR" -type d | sed "s^$TEMPLATE_DIR/*^^; /^$/d" -} - -PRINT_TITLE_INFO() { - local DATESTRING=$(date '+%B %_d, %Y' | sed 's/ \{1,\}/ /g') - sed " - s^LATEX-DOC-TITLE^$DOC_TITLE^ - s^LATEX-DOC-DATE^$DATESTRING^ - s^LATEX-DOC-ID^$DOC_ID^ - s^LATEX-AUTHOR-NAME^$AUTHOR^ - s^LATEX-AUTHOR-ID^$AUTHOR_ID^ - " "$TEMPLATE_DIR/main.tex" -} - -SLUGIFY_TITLE() { - echo $DOC_TITLE | sed "s^['\"\\/,\!@#\$%^&*()]*^^g; s^\s\+^-^g;" -} - -##################################################################### -MAIN $@ diff --git a/zsh/office/latex/get-pdf b/zsh/office/latex/get-pdf deleted file mode 100755 index a25f5a5..0000000 --- a/zsh/office/latex/get-pdf +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use office/latex -##################################################################### - -MAIN() { - LATEX__GET_PDF $@ -} diff --git a/zsh/office/latex/open-pdf b/zsh/office/latex/open-pdf deleted file mode 100755 index 6b5765d..0000000 --- a/zsh/office/latex/open-pdf +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/zsh -use office/latex -##################################################################### - -MAIN() { - local PDF=$(LATEX__GET_PDF $@) - [ ! $PDF ] && return 1 - - OPEN "$PDF" -} diff --git a/zsh/office/latex/templates/basic/template.tex b/zsh/office/latex/templates/basic/template.tex deleted file mode 100644 index 2b79211..0000000 --- a/zsh/office/latex/templates/basic/template.tex +++ /dev/null @@ -1,37 +0,0 @@ -\usepackage[margin=.75in,bottom=0.5in,top=1.0in]{geometry} - -\usepackage{enumitem} -\usepackage{fancyhdr} -\usepackage{hyperref} -\usepackage{lastpage} - -\newcommand{\headerL} {\documentTitle: \documentDate} -\newcommand{\headerC} {\documentId} -\newcommand{\headerR} {\authorName\ (\authorId)} -\newcommand{\pageOfTotal} {\thepage\ of~\pageref{LastPage}} - -\pagestyle{fancy} -\fancypagestyle{plain}{% - \fancyhf{} - \fancyhead[L]{\headerL}\fancyhead[R]{\headerR}\fancyhead[C]{\headerC} - \fancyfoot[C]{\pageOfTotal} -} - -\renewcommand{\baselinestretch}{1} -\setlength{\parskip}{0em} -\hyphenpenalty=5000% - -\fancyhf{} -\fancyhead[L]{\headerL}\fancyhead[R]{\headerR}\fancyhead[C]{\headerC} -\fancyfoot[C]{\pageOfTotal} - -\title{\documentTitle} -\author{\authorName\ \\ \authorId} -\date{\documentDate} - -\begin{document} -\maketitle% -% --------------------------------------------------------------------- - -% --------------------------------------------------------------------- -\end{document} diff --git a/zsh/office/latex/templates/main.tex b/zsh/office/latex/templates/main.tex deleted file mode 100644 index 16ba717..0000000 --- a/zsh/office/latex/templates/main.tex +++ /dev/null @@ -1,9 +0,0 @@ -\documentclass[letterpaper]{article} - -\newcommand{\documentTitle} {LATEX-DOC-TITLE} -\newcommand{\documentDate} {LATEX-DOC-DATE} -\newcommand{\documentId} {LATEX-DOC-ID} - -\newcommand{\authorName} {LATEX-AUTHOR-NAME} -\newcommand{\authorId} {LATEX-AUTHOR-ID} - diff --git a/zsh/office/latex/templates/math/code.sty b/zsh/office/latex/templates/math/code.sty deleted file mode 100644 index 9cc6e16..0000000 --- a/zsh/office/latex/templates/math/code.sty +++ /dev/null @@ -1,11 +0,0 @@ -\ProvidesPackage{code} -% --------------------------------------------------------------------- - -\newcommand{\clispsnippet}[2]{% - \lstinputlisting[% - caption=#1, - language=Lisp, - showstringspaces=false, - numbers=left, - ]{#2} -} diff --git a/zsh/office/latex/templates/math/formatting.sty b/zsh/office/latex/templates/math/formatting.sty deleted file mode 100644 index 8781a68..0000000 --- a/zsh/office/latex/templates/math/formatting.sty +++ /dev/null @@ -1,46 +0,0 @@ -\ProvidesPackage{formatting} -% --------------------------------------------------------------------- - -\newcommand{\headerLeft} {\documentTitle: \documentDate} -\newcommand{\headerCenter} {\documentId} -\newcommand{\headerRight} {\authorName\ (\authorId)} -\newcommand{\pageOfTotal} {\thepage\ of~\pageref{LastPage}} - -\newtheorem{theorem}{Theorem}[section] -\newtheorem{lemma}[theorem]{Lemma} -\newtheorem{corollary}{Corollary}[theorem] - -\RequirePackage[margin=1in,bottom=.5in,includefoot]{geometry} -\RequirePackage{lastpage} -\RequirePackage{fancyhdr} - -% --------------------------------------------------------------------- -% Page 1 - -\pagestyle{fancy} -\fancypagestyle{plain}{% - \fancyhf{} - \fancyhead[L]{\headerLeft} - \fancyhead[R]{\headerRight} - \fancyhead[C]{\headerCenter} - \fancyfoot[C]{\pageOfTotal} -} - -\renewcommand{\baselinestretch}{1} -\setlength{\parskip}{0em} -\setlength{\parindent}{0em} - -% --------------------------------------------------------------------- -% Pages 2+ - -\fancyhf{} -\fancyhead[L]{\headerLeft} -\fancyhead[R]{\headerRight} -\fancyhead[C]{\headerCenter} -\fancyfoot[C]{\pageOfTotal} - -% --------------------------------------------------------------------- - -\title{\documentTitle} -\author{\authorName\ \\ \authorId} -\date{\documentDate} diff --git a/zsh/office/latex/templates/math/imports.sty b/zsh/office/latex/templates/math/imports.sty deleted file mode 100644 index 8027bc9..0000000 --- a/zsh/office/latex/templates/math/imports.sty +++ /dev/null @@ -1,16 +0,0 @@ -\ProvidesPackage{imports} -% --------------------------------------------------------------------- - -\RequirePackage{amssymb} % "bold" math letters (e.g. set of integers ℤ) -\RequirePackage{amsmath} % advanced math symbols - -\RequirePackage{listings} % code snippet styling block - -\RequirePackage{tikz} % graphic drawing / generation -\usetikzlibrary{arrows,automata} -\usetikzlibrary{trees} - -\RequirePackage{graphicx} % include images -\graphicspath{{./graphics/}} - -\RequirePackage[english]{babel} % -- English compilation rules diff --git a/zsh/office/latex/templates/math/shorthand.sty b/zsh/office/latex/templates/math/shorthand.sty deleted file mode 100644 index 103aefc..0000000 --- a/zsh/office/latex/templates/math/shorthand.sty +++ /dev/null @@ -1,13 +0,0 @@ -\ProvidesPackage{shorthand} -% --------------------------------------------------------------------- - -\newcommand{\egfcoefficient}{\ensuremath{\left[\frac{x^n}{n!}\right]}} -\newcommand{\ogfcoefficient}{\ensuremath{\left[x^n\right]}} -\newcommand{\falling}[1]{^{\underline{#1}}} -\newcommand{\divides}{\ensuremath{\;\backslash\;}} - -\newcommand{\sumgz}{\ensuremath{\sum_{n\geq 0}}} -\newcommand{\sumdiv}{\ensuremath{\sum_{d\divides n}}} - -\newcommand{\union}{\ensuremath{\cup}} -\newcommand{\intersect}{\ensuremath{\cap}} diff --git a/zsh/office/latex/templates/math/template.tex b/zsh/office/latex/templates/math/template.tex deleted file mode 100644 index afae7d1..0000000 --- a/zsh/office/latex/templates/math/template.tex +++ /dev/null @@ -1,12 +0,0 @@ -\usepackage{imports} -\usepackage{formatting} -\usepackage{shorthand} -\usepackage{code} - -\begin{document} -\maketitle -% --------------------------------------------------------------------- -% \input{sections/01.introduction.tex} -% \includegraphic{graphics/diagram-a.png} -% --------------------------------------------------------------------- -\end{document} diff --git a/zsh/office/latex/templates/times-new-roman-12/custom-headers.sty b/zsh/office/latex/templates/times-new-roman-12/custom-headers.sty deleted file mode 100644 index 9dd0034..0000000 --- a/zsh/office/latex/templates/times-new-roman-12/custom-headers.sty +++ /dev/null @@ -1,7 +0,0 @@ -\ProvidesPackage{custom-headers} -% --------------------------------------------------------------------- - -\newcommand{\firstH}[1] {\begin{large}\textbf{#1}\end{large}\par} -\newcommand{\secondH}[1] {\textbf{#1}\par} -\newcommand{\thirdH}[1] {\textbf{#1}. } -\newcommand{\fourthH}[1] {\textbf{\textit{#1}}. } diff --git a/zsh/office/latex/templates/times-new-roman-12/formatting.sty b/zsh/office/latex/templates/times-new-roman-12/formatting.sty deleted file mode 100644 index 2f3b2a1..0000000 --- a/zsh/office/latex/templates/times-new-roman-12/formatting.sty +++ /dev/null @@ -1,31 +0,0 @@ -\ProvidesPackage{formatting} -% --------------------------------------------------------------------- - -\newcommand{\horizontalHeader} {% - \authorName\hfill - \authorId\hfill - \documentId\hfill - \documentDate% -} - -\RequirePackage[margin=1in]{geometry} -\RequirePackage{fancyhdr} - -% --------------------------------------------------------------------- - -\pagestyle{fancy} -\renewcommand{\headrulewidth}{0pt} -\fancyhead[C]{\horizontalHeader} -\fancyfoot[C]{\thepage} - -\renewcommand{\baselinestretch}{1} -\setlength{\parskip}{1em} -\setlength{\parindent}{0em} -\raggedright% - -% --------------------------------------------------------------------- - -\newcommand{\insertTitle} {% - \centerline{\begin{large}\textbf{\documentTitle}\end{large}} -} - diff --git a/zsh/office/latex/templates/times-new-roman-12/imports.sty b/zsh/office/latex/templates/times-new-roman-12/imports.sty deleted file mode 100644 index e166963..0000000 --- a/zsh/office/latex/templates/times-new-roman-12/imports.sty +++ /dev/null @@ -1,11 +0,0 @@ -\ProvidesPackage{imports} -% --------------------------------------------------------------------- - -\RequirePackage{times} % "Times New Roman" font - -\RequirePackage{kantlipsum} % generate Kantian lorem ipsum - -\RequirePackage{graphicx} % include images -\graphicspath{{./graphics/}} - -\RequirePackage[english]{babel} % -- English compilation rules diff --git a/zsh/office/latex/templates/times-new-roman-12/template.tex b/zsh/office/latex/templates/times-new-roman-12/template.tex deleted file mode 100644 index 1654e12..0000000 --- a/zsh/office/latex/templates/times-new-roman-12/template.tex +++ /dev/null @@ -1,15 +0,0 @@ -\usepackage{imports} -\usepackage{formatting} -\usepackage{custom-headers} - -\begin{document} -\insertTitle% -% --------------------------------------------------------------------- - -% \input{sections/abstract.tex} -% \includgraphics{graphics/table-a.png} -\firstH{First-level Header} -\kant% - -% --------------------------------------------------------------------- -\end{document} diff --git a/zsh/office/memo/open b/zsh/office/memo/open deleted file mode 100755 index 83aaf89..0000000 --- a/zsh/office/memo/open +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/zsh -use office/memo -##################################################################### - -MAIN() { - local MEMO_NAME=$(MEMO__LIST_ALL | FZF_USER_INPUT 'select/create a memo') - [ ! "$MEMO_NAME" ] && ABORT - - MEMO_FILE="$MEMO__DIR/$MEMO_NAME.$MEMO__FILETYPE" - - [ ! -f $MEMO_FILE ] && { - STATUS "creating memo '$MEMO_NAME'" - echo "# $MEMO_NAME" > "$MEMO_FILE" \ - && SUCCESS "created memo '$MEMO_NAME'" \ - || FAIL 1 "failed to create '$MEMO_FILE'" \ - ; - } - - DATESTRING="## $(date '+%A, %B %-d, %Y')" - grep -q "$DATESTRING" "$MEMO_FILE" || echo "$DATESTRING" >> "$MEMO_FILE" - - EDIT "$MEMO_FILE" -} diff --git a/zsh/office/memo/remove b/zsh/office/memo/remove deleted file mode 100755 index 59341fb..0000000 --- a/zsh/office/memo/remove +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/zsh -use office/memo -##################################################################### - -MAIN() { - local MEMO_NAME=$(MEMO__LIST_ALL | FZF 'select a memo to delete') - local MEMO_FILE="$MEMO__DIR/$MEMO_NAME.$MEMO__FILETYPE" - [ "$MEMO_NAME" ] && [ -f "$MEMO_FILE" ] || ABORT - - STATUS "--- START OF MEMO ---------------------------------------------------" - cat "$MEMO_FILE" - STATUS "--- END OF MEMO -----------------------------------------------------" - - WARNING ' - memos are not backed up by default; deletion is permanent! - ' - - yN 'are you sure you want to delete this memo?' || ABORT - - STATUS "deleting memo '$MEMO_FILE'" - rm "$MEMO_FILE" \ - && SUCCESS "removed memo '$MEMO_NAME'" \ - || FAIL 1 "failed to remove memo '$MEMO_NAME'" \ - ; -} diff --git a/zsh/redis/cli.module.zsh b/zsh/redis/cli.module.zsh new file mode 100644 index 0000000..d75e7c9 --- /dev/null +++ b/zsh/redis/cli.module.zsh @@ -0,0 +1,51 @@ +##################################################################### + +${scwryptsmodule}() { + utils.dependencies.check redis-cli || return 1 + + local USE_DEFAULT_CREDENTIALS=true ARGS PARSERS=() + + eval "$ZSHPARSEARGS" + + redis-cli ${#ARGS[@]} +} + +##################################################################### + +${scwryptsmodule}.parse() { + # local USE_DEFAULT_CREDENTIALS=true ARGS=() + local PARSED=0 + + case $1 in + ( --host ) PARSED=2; USE_DEFAULT_CREDENTIALS=false; ARGS+=(-h $2) ;; + ( --port ) PARSED=2; USE_DEFAULT_CREDENTIALS=false; ARGS+=(-p $2) ;; + ( --auth ) PARSED=2; USE_DEFAULT_CREDENTIALS=false; ARGS+=(-a $2) ;; + ( * ) PARSED=1; ARGS+=($1) ;; + esac + + return $PARSED +} + +${scwryptsmodule}.parse.usage() { + USAGE__options=" + --host address of redis host + --port (default = 6379) access port for redis service + --auth (optional) connection password + + (additional arguments and options are forwarded to redis-cli) + " +} + +${scwryptsmodule}.parse.validate() { + [[ ${USE_DEFAULT_CREDENTIALS} =~ true ]] && { + utils.environment.check REDIS_HOST &>/dev/null \ + || echo.error "must set REDIS_HOST" \ + ; + + utils.environment.check REDIS_PORT --default 6379 &>/dev/null + utils.environment.check REDIS_AUTH --optional &>/dev/null + + ARGS+=(-h "${REDIS_HOST}" -p "${REDIS_PORT}") + [ "${REDIS_AUTH}" ] && ARGS+=(-a "${REDIS_AUTH}") + } +} diff --git a/zsh/redis/curl b/zsh/redis/curl index c5cdd40..64d7f78 100755 --- a/zsh/redis/curl +++ b/zsh/redis/curl @@ -1,46 +1,14 @@ -#!/bin/zsh -use redis +#!/usr/bin/env zsh +##################################################################### + +use redis/curl + +##################################################################### + +redis.curl.parse.usage + ##################################################################### MAIN() { - [ ! $TTL ] && TTL=10 - - [[ $(REDIS__ENABLED) -eq 0 ]] && { - curl $@ - return $? - } - - local ARGS=() - local URL - - while [[ $# -gt 0 ]] - do - case $1 in - -- ) shift 1 ;; - --*= ) ARGS+=($1); shift 1 ;; - --* ) ARGS+=($1 $2); shift 2 ;; - -* ) ARGS+=($1); shift 1 ;; - * ) URL=$1; break ;; - esac - done - - local KEY=$(GET_URL_KEY $URL) - local OUTPUT=$(REDIS get $KEY 2>&1) - [ $OUTPUT ] && { - [[ ${#ARGS[@]} -gt 0 ]] && __WARN "cache hit found; ignoring arguments ($ARGS)" - echo $OUTPUT - return - } - - local OUTPUT=$(curl -s $@) - [ ! $OUTPUT ] && return 1 - - REDIS set $KEY "$OUTPUT" >/dev/null - REDIS expire $KEY $TTL >/dev/null - - echo $OUTPUT + redis.curl $@ } - -##################################################################### - -GET_URL_KEY() { echo "scwrypts:curl:$1" | sed 's/\s\+/+/g'; } diff --git a/zsh/redis/curl.module.zsh b/zsh/redis/curl.module.zsh new file mode 100644 index 0000000..eacd5a5 --- /dev/null +++ b/zsh/redis/curl.module.zsh @@ -0,0 +1,89 @@ +##################################################################### + +use redis/cli +use redis/enabled + +##################################################################### + +${scwryptsmodule}() { + eval "$(usage.reset)" + local \ + URL TTL KEY CURL_ARGS=() \ + PARSERS=() + + eval "$ZSHPARSEARGS" + + ########################################## + + redis.enabled || { + echo.debug "redis not available; performing curl without cache\ncurl -s ${CURL_ARGS[@]} '${URL}'" + curl -s ${CURL_ARGS[@]} "${URL}" + return $? + } + + local OUTPUT=$(REDIS get "${KEY}" 2>&1) + + [ "${OUTPUT}" ] && { + echo ${OUTPUT} + return 0 + } + + local OUTPUT=$(curl -s ${CURL_ARGS[@]} "${URL}") + [ "${OUTPUT}" ] || return 1 + + { + redis.cli set "${KEY}" "${OUTPUT}" + redis.cli expire "${KEY}" "${TTL}" + } &>/dev/null + + echo ${OUTPUT} +} + +##################################################################### + +${scwryptsmodule}.parse() { + # local URL TTL KEY CURL_ARGS=() + local PARSED=0 + + case $1 in + ( --ttl ) TTL=$2 ;; + + ( -- ) PARSED=1 ;; + ( --*= ) PARSED=1 ; CURL_ARGS+=($1) ;; + ( --* ) PARSED=2 ; CURL_ARGS+=($1 $2) ;; + ( -* ) PARSED=1 ; CURL_ARGS+=($1) ;; + + ( * ) + PARSED=$# + URL=$1 + CURL_ARGS+=(${@:2}) + ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.parse.usage() { + USAGE__options+=" + --ttl indicated number of seconds before the request should expire + + all additional arguments are passed on to curl + $(utils.colors.print light-gray "$(curl --help)") + " + + [ "${USAGE__description}" ] || USAGE__description=" + cache curl requests with the indicated ttl + + each request is cached by scwrypts env (currently ${SCWRYPTS_ENV}) + " +} + +${scwryptsmodule}.parse.validate() { + [ "${URL}" ] \ + || echo.error "no url provided" + + [ "${TTL}" ] \ + || TTL=10 + + KEY="scwrypts:${SCWRYPTS_ENV}:curl:$(echo "${URL}" | sed 's/\s\+/+/g')" +} diff --git a/zsh/redis/enabled.module.zsh b/zsh/redis/enabled.module.zsh new file mode 100644 index 0000000..6cead39 --- /dev/null +++ b/zsh/redis/enabled.module.zsh @@ -0,0 +1,9 @@ +##################################################################### + +use redis/cli + +##################################################################### + +${scwryptsmodule}() { # silent; returns true if connection succeeds + SUPPRESS_USAGE_OUTPUT=true redis.cli $@ ping 2>&1 | grep -qi pong +} diff --git a/zsh/redis/redis.module.zsh b/zsh/redis/redis.module.zsh new file mode 100644 index 0000000..5ba8308 --- /dev/null +++ b/zsh/redis/redis.module.zsh @@ -0,0 +1,15 @@ +# +# basic redis interface +# + + +# direct interface to redis-cli with long-flags for authentication arguments +use redis/cli + + +# silently checks whether redis is configured and connection is valid +use redis/enabled + + +# works just like curl, but caches if redis is available +use redis/curl diff --git a/zsh/sanity-check b/zsh/sanity-check index cab5791..113d851 100755 --- a/zsh/sanity-check +++ b/zsh/sanity-check @@ -1,9 +1,9 @@ -#!/bin/zsh +#!/usr/bin/env zsh ##################################################################### USAGE__options=' -e, --exit-code desired exit code of the function (default "0") - -f, --output-function one of the zsh/utils output functions (default "SUCCESS") + -f, --output-function one of the zsh/utils output functions (default "success") -m, --message a message to display (default "Hello, World!") ' @@ -15,38 +15,39 @@ USAGE__description=' ##################################################################### MAIN() { - local OUTPUT_FUNCTION=SUCCESS + local OUTPUT_FUNCTION=success local EXIT_CODE=0 local MESSAGE='Hello, world!' - ARGUMENT_REQUIRED() { ERROR "'$1' requires an argument"; } - - while [[ $# -gt 0 ]] - do - case $1 in - -e | --exit-code ) - EXIT_CODE="$2" - [ $2 ] && shift 1 || ARGUMENT_REQUIRED - ;; - -f | --output-function ) - OUTPUT_FUNCTION="$2" - [ $2 ] && shift 1 || ARGUMENT_REQUIRED - ;; - -m | --message ) - MESSAGE="$2" - [ $2 ] && shift 1 || ARGUMENT_REQUIRED - ;; - * ) ERROR "unknown argument '$1'" ;; - esac - shift 1 - done - - CHECK_ERRORS + eval "${ZSHPARSEARGS}" ########################################## - [[ $OUTPUT_FUNCTION =~ ^FAIL$ ]] && FAIL $EXIT_CODE "$MESSAGE" + [[ ${OUTPUT_FUNCTION} =~ ^fail$ ]] && utils.fail ${EXIT_CODE} "${MESSAGE}" - $OUTPUT_FUNCTION "$MESSAGE" - return $EXIT_CODE + echo.${OUTPUT_FUNCTION} "${MESSAGE}" + return ${EXIT_CODE} +} + +##################################################################### + +MAIN.parse() { + local PARSED=0 + + case $1 in + ( -e | --exit-code ) + PARSED=2 + EXIT_CODE="$2" + ;; + ( -f | --output-function ) + PARSED=2 + OUTPUT_FUNCTION="$2" + ;; + ( -m | --message ) + PARSED=2 + MESSAGE="$2" + ;; + esac + + return ${PARSED} } diff --git a/zsh/scwrypts/README.md b/zsh/scwrypts/README.md deleted file mode 100644 index 7041c74..0000000 --- a/zsh/scwrypts/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# Meta Scwrypts - -The fastest way to configure scwrypts is through scwrypts! -The ZSH scripts in this library are used to manage Scwrypts artifacts. - - -## Configure -**Great for first-time setup!** - -It is simple to edit the local dot-config and restart your terminal. -It is much faster to hit `CTRL+W` and select `config/edit` through a fuzzy search. -This will immediately open your custom configuration file and reload any necessary resources on save. - -## Environment -If you use Scwrypts, **you should use these commands all the time**. -This is your gateway to managing scwrypts sandboxed environments. - -Command | Description ------------------ | --------------------------------------------------------------------------------------- -`edit` | edit an existing environment -`copy` | create and edit a new environment from an existing one -`delete` | permanently delete an environment by name -`stage-variables` | stage missing variables; [helpful for non-ZSH scwrypts](../../py/scwrypts/getenv.py) -`synchronize` | uses [template](../../.env.template) to add missing and remove extemporaneous variables - -### Environment Inheritance -You can make a child environment by naming an environment `.`. -Children inherit all parent-set values, and **parent-set values overwrite child-set values**. -Remember that synchronize runs *every time you edit an environment*, so changes propagate to children immediately. -Inherited values are denoted by `# from ` in the environment file. - -Nested children will inherit values from all parents. - -### Special Environment Variable Syntax - -All environment variables which end in `__[a-z_]+` are ignored by the template file. -These environment variables *will propagate to children*, but will not be removed nor staged into the `.env.template`. - -#### `__select` Environment Variables -Omit any variable, but provide a comma-separated list with the `__select` suffix, and the user will be prompted to select a value from the provided options. - -In the following configuration, the user will be prompted to select an `AWS_REGION` once at the beginning of scwrypt execution: - -```zsh -export AWS_REGION= -export AWS_REGION__select=us-east-1,us-east-2,us-west-1,us-west-2 -``` - -Setting the `AWS_REGION` variable will cause scwrypts to ignore the `__select` syntax. - -CI will fail on select, because CI fails on any FZF prompt. - -#### `__override` Environment Variables -Override any variable with the indicated value. -This will take precedence over existing values *and* any other special environment variable types. - -Examples of use: -- temporarily changing a single value in your current session (e.g. `export VARIABLE__override=value`) -- overriding a variable for a one-time command (e.g. `VARIABLE__override=value scwrypts ...`) - - -## Logs -Quickly view or clear Scwrypts logs. - -## Virtualenv -In addition to the custom environment sandbox, scwrypts will load the appropriate virtual environment for the current script. -Update / create the environment with `update-all`. -Drop and recreate the environment with `refresh`. diff --git a/zsh/scwrypts/cache-output.module.zsh b/zsh/scwrypts/cache-output.module.zsh new file mode 100644 index 0000000..197a49b --- /dev/null +++ b/zsh/scwrypts/cache-output.module.zsh @@ -0,0 +1,143 @@ +##################################################################### + +${scwryptsmodule}() { + eval "$(usage.reset)" + local USAGE__description=" + Caches any successful shell operation for the current scwrypts runtime; + useful for operations which require heavy processing, but frequent access. + + Keep in mind the following: + - Operations are hashed exclusively by the --cache-file argument; use of the + same cache file for multiple different commands will result in erratic behavior, + so make sure the filename is unique across the full scwrypts runtime + + - Operations which have a failed shell exit code are not cached; operations + MUST succeed the first time in order to be cached + + - The full stdout of the operation is cached to RAM + " + + local \ + USE_CACHE=true CACHE_ARGS_COUNT=0 CACHE_FILE \ + ARGS=() ARGS_FORCE=allowed \ + ; + + eval "$ZSHPARSEARGS" + + local CACHE_FILE_FULLPATH="$SCWRYPTS_TEMP_PATH/$CACHE_FILE" + + case $USE_CACHE in + ( bypass ) ${ARGS[@]} ;; + ( true | reset ) + local EXIT_CODE=0 + + [[ $USE_CACHE =~ reset ]] && rm -- "$CACHE_FILE_FULLPATH" &>/dev/null + + [ -f "$CACHE_FILE_FULLPATH" ] || { + ${ARGS[@]} > "$CACHE_FILE_FULLPATH" + EXIT_CODE=$? + } + + case $EXIT_CODE in + ( 0 ) cat "$CACHE_FILE_FULLPATH" + ;; + ( * ) cat "$CACHE_FILE_FULLPATH" 2>/dev/null + echo.error "error running '${ARGS[@]}'" + rm -- "$CACHE_FILE_FULLPATH" &>/dev/null + ;; + esac + + return $EXIT_CODE + ;; + esac +} + +##################################################################### + +${scwryptsmodule}.parse() { + # local USE_CACHE CACHE_ARGS_COUNT=0 CACHE_FILE + local PARSED=0 + case $1 in + ( --use-cache ) + PARSED=2 + case $2 in + ( true | reset | bypass ) + ((CACHE_ARGS_COUNT+=1)) + USE_CACHE=$2 + ;; + ( * ) echo.error "cannot set USE_CACHE to '$2'" ;; + esac + ;; + + ( --cache-file ) + PARSED=2 + CACHE_FILE=$2 + ;; + esac + return $PARSED +} + +${scwryptsmodule}.parse.usage() { + USAGE__options+="\n + --cache-file (required) runtime-unique filename for cached data + for cache to be automatically cleared, make sure this is a simple filename (no directories) + + --reset-cache clear the cache before performing the operation + --bypass-cache skip the cache for a clean operation, but don't clear existing or set new cache data + " + + USAGE__args+="\n + remaining arguments are executed as a shell command + " +} + +${scwryptsmodule}.parse.validate() { + case $USE_CACHE in + ( true | reset | bypass ) ;; + ( * ) echo.error "invalid value '$USE_CACHE' for USE_CACHE (are you missing 'local USE_CACHE=true'?)" ;; + esac + + [[ "$CACHE_FILE" ]] && { + mkdir -p -- "$SCWRYPTS_TEMP_PATH/$(dirname -- "$CACHE_FILE")" \ + || echo.error "unable to create base directory '$SCWRYPTS_TEMP_PATH/$(dirname -- "$CACHE_FILE")'" + + true + } || echo.error "missing cache file" + + [[ ${#ARGS[@]} -gt 0 ]] \ + || echo.error "no command provided" + + [[ $CACHE_ARGS_COUNT -le 1 ]] \ + || echo.error "too many '--use-cache' flags used" +} + +##################################################################### + +${scwryptsmodule}.zshparse.args() { + # local CACHE_ARGS=() + local PARSED=0 + case $1 in + ( --use-cache ) + PARSED=2 + case $2 in + ( true | reset | bypass ) + CACHE_ARGS+=(--use-cache $2) + ;; + + ( * ) echo.error "invalid --use-cache value '$2'" ;; + esac + esac + return $PARSED +} + +${scwryptsmodule}.zshparse.args.usage() { + USAGE__options+="\n + --use-cache (default true) one of {'true', 'reset', 'bypass'} + " + + USAGE__description+="\n + (this function uses functions cached per scwrypts runtime) + " +} + +##################################################################### diff --git a/zsh/scwrypts/configure b/zsh/scwrypts/configure index 7d5f907..2581986 100755 --- a/zsh/scwrypts/configure +++ b/zsh/scwrypts/configure @@ -1,33 +1,33 @@ -#!/bin/zsh +#!/usr/bin/env zsh use scwrypts/meta ##################################################################### MAIN() { local USER_CONFIG_OVERRIDES="$SCWRYPTS_CONFIG_PATH/config.zsh" - + [ ! -f "$USER_CONFIG_OVERRIDES" ] && { - STATUS 'first-time setup detected; creating local configuration override...' + echo.status 'first-time setup detected; creating local configuration override...' cp "$DEFAULT_CONFIG" "$USER_CONFIG_OVERRIDES" - - EDIT $USER_CONFIG_OVERRIDES - - STATUS 'attempting first-time build for virtual environments' - SCWRYPTS__RUN --name scwrypts/virtualenv/update-all --group scwrypts --type zsh \ - && SUCCESS 'finished updating virtualenvs' \ - || WARNING 'unable to create one or more virtualenv (see above)' \ + + utils.io.edit $USER_CONFIG_OVERRIDES + + echo.status 'attempting first-time build for virtual environments' + scwrypts.meta.run --name scwrypts/virtualenv/update-all --group scwrypts --type zsh \ + && echo.success 'finished updating virtualenvs' \ + || echo.warning 'unable to create one or more virtualenv (see above)' \ ; - - REMINDER ' + + echo.reminder ' in the future, you can use the following scwrypt to update required virtual environments (equivalent to "npm install" or "pip install -r requirements"): - + scwrypts --name scwrypts/virtualenv/update-all --group scwrypts --type zsh ' } || { - EDIT "$USER_CONFIG_OVERRIDES" + utils.io.edit "$USER_CONFIG_OVERRIDES" } - - - SUCCESS 'saved new configuration' - REMINDER 'changes which affect the hot-key plugin will require a ZSHRC reload' + + + echo.success 'saved new configuration' + echo.reminder 'changes which affect the hot-key plugin will require a ZSHRC reload' } diff --git a/zsh/scwrypts/environment/common.module.zsh b/zsh/scwrypts/environment/common.module.zsh new file mode 100644 index 0000000..541e35c --- /dev/null +++ b/zsh/scwrypts/environment/common.module.zsh @@ -0,0 +1,63 @@ +##################################################################### + +DEPENDENCIES+=(grep jq sed sort yq) + +##################################################################### + +${scwryptsmodule}.get-env-names() { + [ $REQUIRED_ENVIRONMENT_REGEX ] && { + scwrypts.environment.common.find-env-names \ + | grep "$REQUIRED_ENVIRONMENT_REGEX" + return $? + } + + scwrypts.environment.common.find-env-names +} + +${scwryptsmodule}.get-env-filename() { # provides the fully qualified path to the group config file + local NAME="$1" + local GROUP="$2" + [ $NAME ] && [ $GROUP ] \ + || echo.error 'cannot determine environment filename without name ($1) and group ($2)' \ + || return 1 + + echo "$SCWRYPTS_ENV_PATH/$NAME.$GROUP.env.yaml" +} + +${scwryptsmodule}.get-parent-env-names() { # deepest parent first; e.g. for 'a.b.c.d', returns (a a.b a.b.c) + local NAME="$1" + [[ $NAME =~ . ]] || return 0 + + local PARENT_ENV_NAMES=() + while [ $NAME ] + do + NAME="$(echo $NAME | sed -n 's/\.[^.]\+$//p')" + [ $NAME ] && PARENT_ENV_NAMES+=($NAME) + done + + echo ${PARENT_ENV_NAMES[@]} | sed 's/\s\+/\n/g' | sort +} + +${scwryptsmodule}.find-env-files() { + find "$SCWRYPTS_ENV_PATH/" -mindepth 1 -maxdepth 1 -type f -name \*.env.yaml 2>/dev/null +} + +${scwryptsmodule}.find-env-names() { + scwrypts.environment.common.find-env-files \ + | sed "s|^$SCWRYPTS_ENV_PATH/||; s|\\.[^.]\\+\\.env\\.yaml$||" \ + | sort --reverse --unique \ + ; +} + +${scwryptsmodule}.find-env-files-by-name() { + local NAME="$1" + [ $NAME ] || return 1 + + find "$SCWRYPTS_ENV_PATH/" -mindepth 1 -maxdepth 1 -type f -name $NAME.\*.env.yaml 2>/dev/null +} + +${scwryptsmodule}.combine-template-files() { + utils.yq eval-all '. as $item ireduce ({}; . * $item)' \ + | sed 's/: {}$/:/' \ + | utils.yq 'sort_keys(...)' \ +} diff --git a/zsh/scwrypts/environment/copy b/zsh/scwrypts/environment/copy deleted file mode 100755 index 1d13045..0000000 --- a/zsh/scwrypts/environment/copy +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/zsh -use scwrypts/environment-files -##################################################################### - -MAIN() { - PROMPT 'choose an environment to copy' - TEMPLATE_ENV_NAME=$(SCWRYPTS__SELECT_ENV) - [ ! $TEMPLATE_ENV_NAME ] && ABORT - - STATUS "selected '$TEMPLATE_ENV_NAME'" - - PROMPT 'enter new environment name' - ENV_NAME=$(echo '' | FZF_USER_INPUT 'new environment') - [ ! $ENV_NAME ] && ABORT - SCWRYPTS__GET_ENV_NAMES | grep -q $ENV_NAME && FAIL 1 "'$ENV_NAME' already exists" - - for GROUP in ${SCWRYPTS_GROUPS[@]} - do - TEMPLATE_ENV_FILE=$(SCWRYPTS__GET_ENV_FILE $TEMPLATE_ENV_NAME $GROUP 2>/dev/null) - ENV_FILE=$(SCWRYPTS__GET_ENV_FILE $ENV_NAME $GROUP 2>/dev/null) - - STATUS "creating environment '$ENV_NAME'" - cat "$TEMPLATE_ENV_FILE" \ - | sed 's/ # from.*//' \ - > "$ENV_FILE" \ - && SUCCESS "created '$ENV_FILE'" \ - || FAIL 2 "something went wrong creating '$ENV_FILE'" - done - - STATUS "synchronizing environments" - SCWRYPTS__RUN --name scwrypts/environment/synchronize --group scwrypts --type zsh -- --no-prompt \ - && SUCCESS "finished copy environment '$TEMPLATE_ENV_NAME > $ENV_NAME'" \ - || FAIL 3 'error during synchronization of new environment (see above)' \ - ; -} diff --git a/zsh/scwrypts/environment/delete b/zsh/scwrypts/environment/delete deleted file mode 100755 index 36c0620..0000000 --- a/zsh/scwrypts/environment/delete +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/zsh -use scwrypts/environment-files -##################################################################### - -MAIN() { - PROMPT 'choose an environment to delete' - ENV_NAME=$(SCWRYPTS__SELECT_ENV) - [ ! $ENV_NAME ] && ABORT - - ENV_FILES=($(SCWRYPTS__GET_ENV_FILES $ENV_NAME)) - - STATUS "preparing to remove '$ENV_NAME'" - - WARNING " - the '$ENV_NAME' environment will be removed configured options - and stored credentials will be lost forever: - - $(echo $ENV_FILES | sed 's| /|\n - /|g; s/^/ - /') - " - - yN 'continue?' || ABORT - - STATUS "removing environment" - for ENV_FILE in ${ENV_FILES[@]} - do - rm "$ENV_FILE" \ - && SUCCESS "removed '$ENV_FILE'" \ - || ERROR "unable to remove '$ENV_FILE'; is it protected?" \ - ; - done - - CHECK_ERRORS -n || FAIL 2 "some errors ocurred when cleaning up $ENV_NAME" -} diff --git a/zsh/scwrypts/environment/edit b/zsh/scwrypts/environment/edit deleted file mode 100755 index d8e7e66..0000000 --- a/zsh/scwrypts/environment/edit +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/zsh -use scwrypts/environment-files -##################################################################### - -MAIN() { - [ $1 ] && ENV_NAME="$1" - - [ ! $1 ] && { - [ $SCWRYPTS_ENV ] \ - && ENV_NAME=$SCWRYPTS_ENV \ - || ENV_NAME=$(SCWRYPTS__SELECT_OR_CREATE_ENV) - } - [ ! $ENV_NAME ] && ABORT - - ENV_FILES=($(SCWRYPTS__GET_ENV_FILES $ENV_NAME 2>/dev/null)) - for ENV_FILE in ${ENV_FILES[@]} - do - [ ! -f "$ENV_FILE" ] && { - STATUS "Creating '$ENV_FILE'..." \ - && mkdir -p "$(dirname "$ENV_FILE")" \ - && touch "$ENV_FILE" \ - && ((CREATED+=1)) \ - && SUCCESS "created '$ENV_NAME'" \ - || { ERROR "failed to create '$ENV_FILE'"; exit 1; } - } - - [ $CREATED ] && [[ $CREATED -gt 0 ]] && { - STATUS "detected new environment files; performing sync" \ - && SCWRYPTS__RUN --name scwrypts/environment/synchronize --group scwrypts --type zsh -- --no-prompt \ - || FAIL 1 "failure during sync for '$ENV_NAME'" \ - } - ; - done - - EDIT $ENV_FILES - - SCWRYPTS__RUN --name scwrypts/environment/synchronize --group scwrypts --type zsh -- --no-prompt \ - || FAIL 4 'failed to run environment sync' \ - ; - - SUCCESS "environment '$ENV_NAME' successfully modified" -} diff --git a/zsh/scwrypts/environment/environment.module.zsh b/zsh/scwrypts/environment/environment.module.zsh new file mode 100644 index 0000000..3a55374 --- /dev/null +++ b/zsh/scwrypts/environment/environment.module.zsh @@ -0,0 +1,32 @@ +# +# library to facilitate loading scwrypts runtime variables from +# user-friendly YAML files or environment variables +# + + +# common lookups used by all environment logic +use scwrypts/environment/common + + +# allows utils.fzf selection of environments +use scwrypts/environment/select-env + + +# initialize environments, or skip if already initialized +use scwrypts/environment/init + + +# injects metadata and unifies environment template +use scwrypts/environment/get-full-template + + +# lookup environment variables by config path +use scwrypts/environment/get-envvar-lookup-map + + +# generates local/non-CI configuration +use scwrypts/environment/user + + +# create/edit/delete operations on local configurations +use scwrypts/environment/update diff --git a/zsh/scwrypts/environment/get-envvar-lookup-map.module.zsh b/zsh/scwrypts/environment/get-envvar-lookup-map.module.zsh new file mode 100644 index 0000000..7530f74 --- /dev/null +++ b/zsh/scwrypts/environment/get-envvar-lookup-map.module.zsh @@ -0,0 +1,35 @@ +##################################################################### + +use scwrypts/cache-output +use scwrypts/environment/get-full-template + +##################################################################### + +${scwryptsmodule}() { + eval "$(usage.reset)" + local USAGE__description=" + outputs a JSON map which can be used to lookup config-file query + paths from environment variable names; GET_FULL_TEMPLATE flags OK + + key : environment variable name + value : jq-style query path + " + + local \ + PARSERS=( + scwrypts.cache-output.zshparse.args # passthrough + ) + + eval "$ZSHPARSEARGS" + + ########################################## + + scwrypts.environment.get-full-template $@ \ + | utils.yq -P ' + .. + | select(. == "*") + | {(.): "." + (path | join(".") + ".value")} + '\ + | sed -n 's/\.\.ENVIRONMENT//p' \ + ; +} diff --git a/zsh/scwrypts/environment/get-full-template.module.zsh b/zsh/scwrypts/environment/get-full-template.module.zsh new file mode 100644 index 0000000..199ac79 --- /dev/null +++ b/zsh/scwrypts/environment/get-full-template.module.zsh @@ -0,0 +1,48 @@ +##################################################################### + +use scwrypts/cache-output +use scwrypts/environment/common + +##################################################################### + +${scwryptsmodule}() { + eval "$(usage.reset)" + local USAGE__description=" + Provies the combined YAML of all available scwrypts group 'template.yaml' files. + + Template is cached after first generation in a given scwrypts runtime. + " + + local \ + CACHE_ARGS=() \ + PARSERS=( + scwrypts.cache-output.zshparse.args + ) + + eval "$ZSHPARSEARGS" + ########################################## + + scwrypts.cache-output ${CACHE_ARGS[@]} \ + --cache-file environment.template.yaml \ + -- \ + scwrypts.environment.get-full-template.helper \ + ; +} + +${scwryptsmodule}.helper() { + local GROUP GROUP_ROOT GROUP_TEMPLATE_FILENAME + { + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + GROUP_ROOT="$(scwrypts.config.group ${GROUP} root)" + + GROUP_TEMPLATE_FILENAME="${GROUP_ROOT}/.config/env.yaml" + + [ -f "${GROUP_TEMPLATE_FILENAME}" ] && { + [[ $(head -n1 "${GROUP_TEMPLATE_FILENAME}") =~ ^---$ ]] || echo --- + cat "${GROUP_TEMPLATE_FILENAME}" \ + | utils.yq "(.. | select(has(\".ENVIRONMENT\"))) += {\".GROUP\":\"${GROUP}\"}" + } + done + } | scwrypts.environment.common.combine-template-files +} diff --git a/zsh/scwrypts/environment/getenv b/zsh/scwrypts/environment/getenv new file mode 100755 index 0000000..6919898 --- /dev/null +++ b/zsh/scwrypts/environment/getenv @@ -0,0 +1,69 @@ +#!/usr/bin/env zsh + +use scwrypts/environment + +##################################################################### + +USAGE__options=" + --all print the whole environment instead of individual environment variables +" + +USAGE__args=" + \$1 must be the name of the environment variable + \$2... any additional arguments to forward to utils.environment.check +" + +USAGE__description=" + Wrapper API for utils.environment.check to get environment variable values + from non-zsh scwrypts environments. Value of the variable is written + to stdout, and returns an error status if the variable is required + and missing. + + ------ utils.environment.check help ------ + + $(utils.environment.check --help 2>&1 | sed 's/^/ > /g' | grep -v 'usage') + + ------ utils.environment.check help ------ +" + +##################################################################### + +MAIN() { + local MODE=single-variable + local ARGS=() ARGS_FORCE=true + + eval "${ZSHPARSEARGS}" + + case $MODE in + ( single-variable ) + utils.environment.check --print-value ${ARGS[@]} + ;; + ( all ) + scwrypts.environment.user.get-json + ;; + esac +} + +MAIN.parse() { + local PARSED=0 + + case $1 in + ( --all ) PARSED=1; MODE=all ;; + esac + + return $PARSED +} + + +MAIN.parse.validate() { + case $MODE in + ( single-variable ) + [[ "${#ARGS[@]}" -eq 0 ]] \ + && echo.error "missing variable / lookup path to check" + ;; + ( all ) + [[ "${#ARGS[@]}" -gt 0 ]] \ + && echo.error "unexpected variable name with '--all' flag" + ;; + esac +} diff --git a/zsh/scwrypts/environment/init.module.zsh b/zsh/scwrypts/environment/init.module.zsh new file mode 100644 index 0000000..53e8a45 --- /dev/null +++ b/zsh/scwrypts/environment/init.module.zsh @@ -0,0 +1,142 @@ +##################################################################### + +use scwrypts/environment/common + +##################################################################### + +${scwryptsmodule}() { + [ ${CI} ] && return 0 + + mkdir -p "${SCWRYPTS_ENV_PATH}" + [[ $(scwrypts.environment.common.find-env-files | wc -l) -gt 0 ]] && return 0 + + [[ $(scwrypts.environment.common.find-legacy-env-files | wc -l) -gt 0 ]] && { + scwrypts.environment.legacy.convert + return $? + } + + # + # usually we don't want to do this, but waiting to load these is critical + # to scwrypts runtime performance! + # + use scwrypts/environment/update + + echo.status "initializing environments for scwrypts" + + local BASIC_ENV + for BASIC_ENV in local dev prod + do + scwrypts.environment.update --environment-name "${BASIC_ENV}" + done +} + +##################################################################### + +scwrypts.environment.legacy.find-env-files() { + find "${SCWRYPTS_ENV_PATH}/" -mindepth 2 -maxdepth 2 -type f 2>/dev/null +} + +scwrypts.environment.legacy.find-env-names() { + scwrypts.environment.legacy.find-env-files \ + | sed 's|.*/||' \ + | sort --unique \ + ; +} + +##################################################################### + +scwrypts.environment.legacy.convert() { + local GROUP GROUP_ROOT + local GROUP_TEMPLATE_FILENAME LEGACY_TEMPLATE_FILENAME + + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + GROUP_ROOT="$(scwrypts.config.group ${GROUP} root)" + GROUP_TEMPLATE_FILENAME="${GROUP_ROOT}/.config/env.yaml" + LEGACY_TEMPLATE_FILENAME="${GROUP_ROOT}/.config/env.template" + + [ ! -f "${GROUP_TEMPLATE_FILENAME}" ] && [ -f "${LEGACY_TEMPLATE_FILENAME}" ] && { + scwrypts.environment.legacy.convert.v4-to-v5.template-file + } + + [ -f "$GROUP_TEMPLATE_FILENAME" ] && echo.success "environment template '$GROUP' OK" + done + + local ENVIRONMENT_NAME + local GROUP_CONFIG_FILENAME LEGACY_CONFIG_FILENAME + for ENVIRONMENT_NAME in $(scwrypts.environment.legacy.find-env-names) + do + local MIGRATE_GROUP=false + echo.status "checking '${ENVIRONMENT_NAME}' configuration files" + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + GROUP_CONFIG_FILENAME="$(scwrypts.environment.common.get-env-filename "${ENVIRONMENT_NAME}" "${GROUP}")" + LEGACY_CONFIG_FILENAME="${SCWRYPTS_ENV_PATH}/${GROUP}/${ENVIRONMENT_NAME}" + + [ ! -f "${GROUP_CONFIG_FILENAME}" ] && [ -f "${LEGACY_CONFIG_FILENAME}" ] && { + MIGRATE_GROUP=true + } + done + + [[ ${MIGRATE_GROUP} =~ true ]] && { + scwrypts.environment.legacy.convert.v4-to-v5.config-file \ + && echo.success "successfully migrated '${ENVIRONMENT_NAME}'" + } + done +} + +scwrypts.environment.legacy.convert.v4-to-v5.template-file() { + scwrypts.environment.legacy.convert.v4-to-v5.deprecation-warning + + echo.status "detected legacy template for '${GROUP}'; attempting v5 conversion" + + "$(scwrypts.config.group scwrypts root)/.config/create-new-env" "${GROUP_ROOT}/.config" "${GROUP}" &>/dev/null + + utils.io.edit "${GROUP_TEMPLATE_FILENAME}" + + echo.reminder "the file '${GROUP_TEMPLATE_FILENAME}' should be committed to the appropriate repository" +} + +scwrypts.environment.legacy.convert.v4-to-v5.config-file() { + scwrypts.environment.legacy.convert.v4-to-v5.deprecation-warning + + SCWRYPTS_LOG_LEVEL=4 echo.status "detected legacy environment configuration file for '${ENVIRONMENT_NAME}'; attempting v5 conversion" + + local LEGACY_CONFIG_FILE + local LEGACY_CONFIG_VALUES="$( + cat "${SCWRYPTS_ENV_PATH}/"*"/${ENVIRONMENT_NAME}" \ + | sed '/^#/d; /^$/d; /=$/d; /# from/d' \ + | sed -z 's/\n\s\+/ /g' \ + | sed -z 's/\n)/)/g' \ + | sed 's/( /\n(/' \ + | sed '/^(/{s/ /,/g}; s/^(\(.*\))$/[\1]/' \ + | sed '/^\[/{s|\([^][,]\+\)|"\1"|g}' \ + | sed "s/^\\[.*\\]$/'&'/" \ + | sed -z "s/\\n'\[/'[/g" \ + | sed 's/^export \([^=]\+\)=/\1: /' \ + | utils.yq --unwrapScalar=false '..style="double"' \ + )" + + local ENV_VAR NEW_TEMPLATE_KEY NEW_TEMPLATE="$(scwrypts.environment.get-full-template --reset-cache)" + for ENV_VAR in $(echo "${LEGACY_CONFIG_VALUES}" | utils.yq -r 'keys | .[]') + do + NEW_TEMPLATE_KEY=$(scwrypts.environment.template.get-envvar-lookup-map | utils.yq -r ".${ENV_VAR}") + NEW_TEMPLATE_VALUE="$(echo "${LEGACY_CONFIG_VALUES}" | utils.yq -r ".${ENV_VAR}")" + echo "${NEW_TEMPLATE_VALUE}" | grep -q '^[[].*[]]$' \ + || NEW_TEMPLATE_VALUE="\"${NEW_TEMPLATE_VALUE}\"" + + NEW_TEMPLATE="$( + echo "${NEW_TEMPLATE}" | utils.yq "${NEW_TEMPLATE_KEY} = ${NEW_TEMPLATE_VALUE}" + )" + done + + scwrypts.environment.update.update-user-configs "${NEW_TEMPLATE}" "${ENVIRONMENT_NAME}" +} + +export __SCWRYPTS_ENVIRONMENT__DEPRECATION_WARNING=false +scwrypts.environment.legacy.convert.v4-to-v5.deprecation-warning() { + [[ ${__SCWRYPTS_ENVIRONMENT__DEPRECATION_echo}.warning =~ true ]] && return 0 + + echo.warning "DEPRECATED : the v4 to v5 environment migration is temporary and will be removed in 5.2" + export __SCWRYPTS_ENVIRONMENT__DEPRECATION_WARNING=true +} diff --git a/zsh/scwrypts/environment/select-env.module.zsh b/zsh/scwrypts/environment/select-env.module.zsh new file mode 100644 index 0000000..ae6d9d6 --- /dev/null +++ b/zsh/scwrypts/environment/select-env.module.zsh @@ -0,0 +1,18 @@ +########################################################### + +use scwrypts/environment/common + +########################################################### + +${scwryptsmodule}() { + local SELECTOR=utils.fzf + local MESSAGE='select an environment' + + [[ "$1" =~ --allow-create ]] && { + SELECTOR=utils.fzf.user-input + MESSAGE='select / create an environment' + } + + scwrypts.environment.common.get-env-names \ + | ${SELECTOR} "${MESSAGE}" +} diff --git a/zsh/scwrypts/environment/synchronize b/zsh/scwrypts/environment/synchronize deleted file mode 100755 index baeab1a..0000000 --- a/zsh/scwrypts/environment/synchronize +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/zsh -use scwrypts/environment-files -##################################################################### - -MAIN() { - while [[ $# -gt 0 ]] - do - case $1 in - --no-prompt ) SLIENT=1; shift 1 ;; - - * ) WARNING "argument '$1' not recognized" - shift 1 ;; - esac - done - - local TEMPLATE_FILE - [ ! $SLIENT ] && { - yN 'change the template(s) before sync?' && { - EDIT $( - for TEMPLATE_FILE in $(SCWRYPTS__GET_ENV_TEMPLATE_FILES) - do - [ -f "$TEMPLATE_FILE" ] && echo "$TEMPLATE_FILE" - [ -f "$TEMPLATE_FILE.descriptions" ] && echo "$TEMPLATE_FILE.descriptions" - done - ) - } - - for TEMPLATE_FILE in $(SCWRYPTS__GET_ENV_TEMPLATE_FILES) - do - { - echo '#!/bin/zsh' - cat "$TEMPLATE_FILE" \ - | sed ' - /__[a-z_]\+=$/d; - /^#/d; /^$/d; - s/^[A-Z]/export &/; s/^[^#=]\\+$/&=/; - ' \ - | LC_COLLATE=C sort -u - } > "$TEMPLATE_FILE.temp" - mv "$TEMPLATE_FILE.temp" "$TEMPLATE_FILE" - done - } - - local ENVIRONMENTS ENVIRONMENT_FILES - local FILE NAME ENVIRONMENT_FILE - - GROUP_PIDS=() - for GROUP in ${SCWRYPTS_GROUPS} - do - { - ENVIRONMENTS=($(SCWRYPTS__GET_ENV_NAMES | sort -r)) - ENVIRONMENT_FILES=($( - for NAME in ${ENVIRONMENTS[@]} - do - SCWRYPTS__GET_ENV_FILE $NAME $GROUP - done - )) - - STATUS 'generating working environment files...' - for FILE in ${ENVIRONMENT_FILES[@]} - do - GENERATE_TEMP_ENVIRONMENT_FILE "$FILE" - done - - STATUS 'cascading environment values to children...' - for NAME in ${ENVIRONMENTS[@]} - do - CASCADE_ENVIRONMENT $NAME - done - - STATUS 'cleaning up working space...' - for FILE in ${ENVIRONMENT_FILES[@]} - do - CLEANUP_ENVIRONMENT_FILE "$FILE" - done - SUCCESS 'finished sync!' - } & - GROUP_PIDS+=$! - done - for P in ${GROUP_PIDS[@]}; do wait $P; done -} - -##################################################################### - -CASCADE_ENVIRONMENT() { - local PARENT_NAME="$1" - local PARENT_FILE="$(SCWRYPTS__GET_ENV_FILE $PARENT_NAME $GROUP).temp" - - local CHILD_NAMES=($(echo $ENVIRONMENTS | sed 's/ \+/\n/g' |grep "^$PARENT_NAME\\.")) - [[ ${#CHILD_NAMES[@]} -eq 0 ]] && return 0 - - local PARENT_VARIABLES="$(READ_PARENT_VARIABLES "$PARENT_NAME" "$PARENT_FILE")" - [ ! $PARENT_VARIABLES ] && return 0 - - local CHILD_NAME CHILD_FILE CONTENT - for CHILD_NAME in ${CHILD_NAMES[@]} - do - STATUS "propagating environment '$PARENT_NAME' to child '$CHILD_NAME'" - CHILD_FILE="$(SCWRYPTS__GET_ENV_FILE $CHILD_NAME $GROUP).temp" - CONTENT=$(cat "$CHILD_FILE") - echo "$PARENT_VARIABLES" | ADD_LINES - echo "$CONTENT" > "$CHILD_FILE" - done - - SUCCESS "finished '$PARENT_NAME' propagation" -} - -##################################################################### - -GENERATE_TEMP_ENVIRONMENT_FILE() { - local FILE="$1" - local CONTENT=$(GENERATE_TEMPLATE) - - READ_POPULATED_VARIABLES "$FILE" | ADD_LINES - - echo "$CONTENT" > "$FILE.temp" -} - -ADD_LINES() { - local LINE VARIABLE SHORT VALUE - while read LINE - do - VARIABLE=$(echo $LINE | sed 's/=.*$//') - echo $CONTENT | grep -qi "^$VARIABLE" || { - echo $LINE | grep -q '__[a-z_]\+=' || { - WARNING "skipping variable $(echo $LINE | sed 's/^export //; s/=.*//') - (must be included in a template before it can be added)" - continue - } - SHORT=$(echo "$VARIABLE" | sed 's/__[a-z].*//') - CONTENT=$(echo "$CONTENT" | sed "/^$SHORT/a $LINE") - } - - CONTENT=$(echo "$CONTENT" | sed "s%^$VARIABLE.*$%$LINE%") - done -} - -READ_POPULATED_VARIABLES() { - local FILE="$1" - cat "$FILE" \ - | grep -v '^#' \ - | grep -v '=$' \ - | grep -v '^$' \ - | grep -v ' # from ' \ - | awk '/^[^=]+$/{printf "%s_____",$0;next}7' \ - | sed 's/\(_____\)\(export\)/\1\n\2/; s/\(_____\)$/\1\n/' \ - | sed 's/^.*_____.*$/_____&/' \ - | sed 's/^_____export/export/' \ - | sed -z 's/[\n ] *_____/_____/g' \ - | grep -v '^$' \ - ; -} - -READ_PARENT_VARIABLES() { - local PARENT_NAME="$1" - local PARENT_FILE="$2" - READ_POPULATED_VARIABLES "$PARENT_FILE" \ - | sed 's/_____/ /g; s/\s\+/ /g' \ - | sed 's/( /(/; s/ )/)/' \ - | sed "s/$/ # from $PARENT_NAME/" \ - | grep -v '__[a-z_]\+=' \ - ; -} - -CLEANUP_ENVIRONMENT_FILE() { - cat "$1.temp" \ - | sed 's/_____$//g; s/_____/\n/g' \ - > "$1" - - rm "$1.temp" -} - -##################################################################### -MAIN $@ diff --git a/zsh/scwrypts/environment/update b/zsh/scwrypts/environment/update new file mode 100755 index 0000000..1b40089 --- /dev/null +++ b/zsh/scwrypts/environment/update @@ -0,0 +1,150 @@ +#!/usr/bin/env zsh + +use scwrypts/environment + +##################################################################### + +USAGE__options+=" + -m, --mode set the execution mode for update + edit (default) edit the current environment + copy copy one environment to another + delete permanently delete an existing environment + recursive (somewhat advanced) from deepest parent to target environment, edit all related environments in order + advanced (dangerous) API mode; requires a '--' and additional arguments + + -n, --name name of the environment to update (default is current '$SCWRYPTS_ENV')\n$(scwrypts.environment.common.get-env-names | sed 's/^/ /') + + --advanced-help help doc for advanced mode +" + +USAGE__description=' + interactive utility for scwrypts environment managment +' + +# program exists immediately after running, so environment changes +# cannot cause errors if this script is run on it's own +[[ $SUBSCWRYPT -eq 0 ]] \ + && export __SCWRYPTS_ENVIRONMENT__WORKFLOW_IS_CHANGE_SAFE=true + +##################################################################### + +MAIN() { + local MODE=edit + local ENVIRONMENT_NAME + + local ARGS=() + + local _S ERRORS=0 + while [[ $# -gt 0 ]] + do + _S=1 + case $1 in + ( --advanced-help ) + scwrypts.environment.update --help + return 0 + ;; + + ( -m | --mode ) + [ $2 ] && ((_S+=1)) || echo.error "missing mode name" || break + case $2 in + edit | copy | delete | recursive | advanced ) + MODE="$2" + ;; + * ) echo.error "invalid mode '$MODE'" ;; + esac + ;; + + ( -n | --name ) + [ $2 ] && ((_S+=1)) || echo.error "missing environment name" || break + ENVIRONMENT_NAME="$2" + ;; + + ( -- ) shift 1; ADVANCED_ARGS=($@); break ;; + ( * ) echo.error "unknown argument '$1'" ;; + esac + shift $_S + done + + utils.check-errors --fail + + case $MODE in + ( edit ) + [ "$ENVIRONMENT_NAME" ] || ENVIRONMENT_NAME="$SCWRYPTS_ENV" + ;; + ( copy ) + local SOURCE_ENVIRONMENT="$(scwrypts.environment.common.get-env-names | utils.fzf 'select an environment to copy')" + [ "$SOURCE_ENVIRONMENT" ] || user.abort + + [ "$ENVIRONMENT_NAME" ] || ENVIRONMENT_NAME=$(echo | utils.fzf.user-input 'new environment name') + [ "$ENVIRONMENT_NAME" ] || user.abort + ;; + ( delete ) + [ "$ENVIRONMENT_NAME" ] || ENVIRONMENT_NAME="$(scwrypts.environment.common.get-env-names | utils.fzf 'select an environment to delete')" + [ "$ENVIRONMENT_NAME" ] || user.abort + ;; + ( advanced ) + [ "$ENVIRONMENT_NAME" ] || ENVIRONMENT_NAME="$SCWRYPTS_ENV" + esac + + [ -f "$(scwrypts.environment.common.get-env-filename "$ENVIRONMENT_NAME" scwrypts)" ] \ + && local ENVIRONMENT_EXISTS=true \ + || local ENVIRONMENT_EXISTS=false \ + ; + + case $MODE in + ( edit ) + case $ENVIRONMENT_EXISTS in + ( true ) ;; + ( false ) + echo.warning "environment $ENVIRONMENT_NAME does not exist" + Yn "create new environment '$ENVIRONMENT_NAME'?" || user.abort + ;; + esac + ;; + + ( copy ) + ARGS+=(--create-from-existing "$SOURCE_ENVIRONMENT") + case $ENVIRONMENT_EXISTS in + ( true ) + echo.error "target environment '$ENVIRONMENT_NAME' already exists; refusing to copy" + ;; + ( false ) ;; + esac + ;; + + ( delete ) + ARGS+=(--mode delete) + case $ENVIRONMENT_EXISTS in + ( true ) + echo.reminder 'deleting an environment is PERMANENT\nmake sure your credentials are backed up!' + yN "are you sure you want to delete '$ENVIRONMENT_NAME'?" || user.abort + ;; + ( false ) + echo.error "environment '$ENVIRONMENT_NAME' does not exist (can't delete it if it's not there)" + ;; + esac + ;; + + ( recursive ) + ARGS+=(--mode recursive) + case $ENVIRONMENT_EXISTS in + ( true ) ;; + ( false ) + echo.error "environment '$ENVIRONMENT_NAME' does not exist; please create it before attempting recursive edit" + ;; + esac + ;; + + ( advanced ) + echo.warning "operating in advanced mode; I hope you know what you are doing!" + ;; + esac + + utils.check-errors --no-usage + + ########################################## + + ARGS+=(--environment-name $ENVIRONMENT_NAME) + + scwrypts.environment.update ${ARGS[@]} +} diff --git a/zsh/scwrypts/environment/update.module.zsh b/zsh/scwrypts/environment/update.module.zsh new file mode 100644 index 0000000..82d8b23 --- /dev/null +++ b/zsh/scwrypts/environment/update.module.zsh @@ -0,0 +1,257 @@ +##################################################################### + +use scwrypts/environment/common + +use scwrypts/environment/user +use scwrypts/environment/get-full-template +use scwrypts/environment/select-env + +##################################################################### + +[ $SCWRYPTS_ENVIRONMENT__PREFERRED_EDIT_MODE ] \ + || export SCWRYPTS_ENVIRONMENT__PREFERRED_EDIT_MODE=basic + +scwrypts.environment.update() { + local EDIT_MODE=$SCWRYPTS_ENVIRONMENT__PREFERRED_EDIT_MODE + local ENVIRONMENT_NAME="$SCWRYPTS_ENV" + local FROM_EXISTING + + local USAGE=" + usage: scwrypts.environment.update [...options...] + + options: + --mode update execution mode (default: $SCWRYPTS_ENVIRONMENT__PREFERRED_EDIT_MODE) + modes: + basic : create or edit environment with all tooltips and metadata + quiet : create or edit a compact environment with minimal metadata + init : create a new environment with no edit prompt + delete : delete target environment + recursive : (advanced) edit all inherited environments, starting from deepest parent + copy : (see --create-from-existing; most likely you don't need to set this flag) + + --environment-name name of the target environment (default is current: $SCWRYPTS_ENV) + --create-from-existing name of the environment to copy + + -h, --help print this dialogue and exit + " + + local _S ERRORS=0 + while [[ $# -gt 0 ]] + do + _S=1 + case $1 in + ( -h | --help ) utils.io.usage; return 0 ;; + + ( --environment-name ) + [ $2 ] && ((_S+=1)) || echo.error "missing environment name" || break + ENVIRONMENT_NAME="$2" + ;; + + ( --create-from-existing ) + [ $2 ] && ((_S+=1)) || echo.error "must provide environment name to copy" || break + EDIT_MODE=copy + FROM_EXISTING="$2" + ;; + + ( --mode ) + [ $2 ] && ((_S+=1)) || echo.error "missing mode" || break + EDIT_MODE="$2" + command -v scwrypts.environment.update.edit.$EDIT_MODE &>/dev/null \ + || echo.error "invalid mode '$EDIT_MODE'" + + ;; + + * ) echo.error "unknown argument '$1'" ;; + esac + shift $_S + done + + case $EDIT_MODE in + ( copy ) + [ $FROM_EXISTING ] || FROM_EXISTING=$(scwrypts.environment.select-env) + [ $FROM_EXISTING ] || echo.error "cannot work in '$EDIT_MODE' without existing target" + + [[ $(scwrypts.environment.common.find-env-files-by-name "$FROM_EXISTING" | wc -l) -gt 0 ]] \ + || echo.error "no such environment '$FROM_EXISTING' exists" + ;; + + ( * ) + [ ! $FROM_EXISTING ] || echo.error "cannot work in '$EDIT_MODE' with --create-from-existing" + ;; + esac + + utils.check-errors || return $? + + local TEMP_CONFIG_FILE="$SCWRYPTS_TEMP_PATH/environment.temp.yaml" + + [ -f "$TEMP_CONFIG_FILE" ] && { + echo.error "temp config file already exists at '$TEMP_CONFIG_FILE'\nis another environment update in-progress?" + echo.reminder "if you are certain no other environment update is in progress, you can resolve with\n rm -- '$TEMP_CONFIG_FILE'" + return 1 + } + + scwrypts.environment.update.edit.${EDIT_MODE} + local EXIT_CODE=$? + + rm "$TEMP_CONFIG_FILE" 2>/dev/null + + return $EXIT_CODE +} + +##################################################################### + +${scwryptsmodule}.edit.basic() { + scwrypts.environment.user.get \ + --environment-name $ENVIRONMENT_NAME \ + > "$TEMP_CONFIG_FILE" + + utils.io.edit "$TEMP_CONFIG_FILE" + + scwrypts.environment.update.update-user-configs "$(cat "$TEMP_CONFIG_FILE")" "$ENVIRONMENT_NAME" +} + +${scwryptsmodule}.edit.quiet() { + echo "--- # $ENVIRONMENT_NAME" > "$TEMP_CONFIG_FILE" + scwrypts.environment.user.get \ + --environment-name $ENVIRONMENT_NAME \ + | utils.yq '. + | del(.. | select(has(".ENVIRONMENT")).".ENVIRONMENT") + | del(.. | select(has(".GROUP")).".GROUP") + | del(.. | select(has(".DESCRIPTION")).".DESCRIPTION") + | del(.. | select(has("selection") and (.selection == null or (.selection | length) == 0)).selection) + | del(.. | select(has("selection") and has("value") and .value == null).value) + | del(.. | select(has(".PARENTVALUE") and has("value") and .value == null).value) + ' \ + >> "$TEMP_CONFIG_FILE" + + utils.io.edit "$TEMP_CONFIG_FILE" + + scwrypts.environment.update.update-user-configs "$(cat "$TEMP_CONFIG_FILE")" "$ENVIRONMENT_NAME" +} + +${scwryptsmodule}.edit.recursive() { + local RECURSIVE_EDIT_MODE="$SCWRYPTS_ENVIRONMENT__PREFERRED_EDIT_MODE" + [[ $RECURSIVE_EDIT_MODE =~ ^recursive$ ]] \ + && RECURSIVE_EDIT_MODE=quiet + + local PARENT_ENVIRONMENT_NAME + for PARENT_ENVIRONMENT_NAME in \ + $(scwrypts.environment.common.get-parent-env-names "$ENVIRONMENT_NAME") \ + $ENVIRONMENT_NAME + ; + do + echo.status "editing environment '$PARENT_ENVIRONMENT_NAME'" + scwrypts.environment.update \ + --environment-name $PARENT_ENVIRONMENT_NAME \ + --mode $RECURSIVE_EDIT_MODE \ + ; + done +} + +${scwryptsmodule}.edit.init() { + [ -f "$(scwrypts.environment.common.get-env-filename)" ] + + scwrypts.environment.user.get \ + --environment-name $ENVIRONMENT_NAME \ + > "$TEMP_CONFIG_FILE" + + scwrypts.environment.update.update-user-configs "$(cat "$TEMP_CONFIG_FILE")" +} + +${scwryptsmodule}.edit.copy() { + local GROUP_CONFIG_FILENAME SOURCE_CONFIG_FILENAME + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + cp \ + "$(scwrypts.environment.common.get-env-filename "$FROM_EXISTING" "$GROUP")" \ + "$(scwrypts.environment.common.get-env-filename "$ENVIRONMENT_NAME" "$GROUP")" \ + 2>/dev/null \ + ; + done + + scwrypts.environment.user.get \ + --environment-name $ENVIRONMENT_NAME \ + > "$TEMP_CONFIG_FILE" + + scwrypts.environment.update.update-user-configs "$(cat "$TEMP_CONFIG_FILE")" +} + +${scwryptsmodule}.edit.delete() { + touch "$TEMP_CONFIG_FILE" + + local ERRORS=0 GROUP GROUP_CONFIG_FILENAME + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + local GROUP_CONFIG_FILENAME="$(scwrypts.environment.common.get-env-filename "$ENVIRONMENT_NAME" "$GROUP")" + [ -f "$GROUP_CONFIG_FILENAME" ] || { + echo.status "nothing to cleanup for $ENVIRONMENT_NAME/$GROUP" + continue + } + + rm -- "$GROUP_CONFIG_FILENAME" \ + && echo.success "deleted '$GROUP_CONFIG_FILENAME'" \ + || echo.error "unable to delete '$GROUP_CONFIG_FILENAME'" \ + ; + done + + return $ERRORS +} + +##################################################################### +##################################################################### +##################################################################### + +export __SCWRYPTS_ENVIRONMENT__WORKFLOW_IS_CHANGE_SAFE=false +${scwryptsmodule}.update-user-configs() { + local NEW_CONFIGURATION="$1" + [ $NEW_CONFIGURATION ] || return 1 + + local ENVIRONMENT_NAME="$2" + [ $ENVIRONMENT_NAME ] || return 2 + + # reinject all metadata, since the update function is allowed to strip it + NEW_CONFIGURATION="$( + { + scwrypts.environment.user.get-full-template-with-value-keys --environment "$ENVIRONMENT_NAME" + echo --- + echo "$NEW_CONFIGURATION" + } | scwrypts.environment.common.combine-template-files + )" + + local METADATA_DELETE_QUERY="$( + echo "$NEW_CONFIGURATION" \ + | sed -n 's/^\s\+\(\.[-A-Za-z_:]\+\):.*$/ | del(.. | select(has("\1"))."\1")/p' \ + | sort --unique \ + )" + + local GROUP GROUP_CONFIG_FILENAME GROUP_CONFIG + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + local GROUP_CONFIG="$(echo "$NEW_CONFIGURATION" \ + | utils.yq ". + | del(.. | select(has(\".PARENTVALUE\") and has(\"value\") and .\".PARENTVALUE\" == .value)) + | del(.. | select(has(\".PARENTSELECTION\") and has(\"selection\") and .\".PARENTSELECTION\" == .selection)) + | del(.. | select(has(\".GROUP\") and .\".GROUP\" != \"$GROUP\")) + | del(.. | select(has(\"selection\") and (.selection == null or (.selection | length) == 0)).selection) + | del(.. | select(has(\"value\") and .value == null).value) + $METADATA_DELETE_QUERY + " \ + )" + + while echo "$GROUP_CONFIG" | grep -q '{}' + do + GROUP_CONFIG="$(echo "$GROUP_CONFIG" | utils.yq 'del(.. | select(tag == "!!map" and length == 0))')" + done + + [ "$GROUP_CONFIG" ] || GROUP_CONFIG='# no configuration set' + + echo "--- # $ENVIRONMENT_NAME > $GROUP\n$GROUP_CONFIG" > "$(scwrypts.environment.common.get-env-filename "$ENVIRONMENT_NAME" "$GROUP")" + done + + [[ $ENVIRONMENT_NAME =~ ^$SCWRYPTS_ENV$ ]] && [[ $__SCWRYPTS_ENVIRONMENT__WORKFLOW_IS_CHANGE_SAFE =~ false ]] && { + echo.warning "current scwrypts environment has changed" + export __SCWRYPTS_ENVIRONMENT__USER_ENVIRONMENT= + } + + return 0 +} diff --git a/zsh/scwrypts/environment/user.module.zsh b/zsh/scwrypts/environment/user.module.zsh new file mode 100644 index 0000000..15693d8 --- /dev/null +++ b/zsh/scwrypts/environment/user.module.zsh @@ -0,0 +1,276 @@ +##################################################################### + +use scwrypts/environment/common + +use scwrypts/environment/get-full-template +use scwrypts/environment/get-envvar-lookup-map + +use scwrypts/cache-output + +##################################################################### + +${scwryptsmodule}.get() { + eval "$(usage.reset)" + local USAGE__description=" + Generates a metadata-enriched environment YAML for the target environment. + " \ + CACHE_ARGS=() \ + ENVIRONMENT_NAME \ + PARSERS=( + scwrypts.cache-output.zshparse.args + scwrypts.environment.user.zshparse.env-name + ) + + eval "$ZSHPARSEARGS" + + ########################################## + + scwrypts.cache-output ${CACHE_ARGS[@]} \ + --cache-file environment.user.yaml \ + -- \ + scwrypts.environment.user.get.helper "$ENVIRONMENT_NAME" \ + ; +} + + +${scwryptsmodule}.get-shell-values() { + eval "$(usage.reset)" + local USAGE__description=" + used primarily by utils.environment.check in scwrypts environments + + returns yaml which contains shell-compatible lookup values + - moving inherited .PARENTVALUE to value (if value is empty) + - moving inherited .PARENTSELECTION to selection (if selection is empty) + - converting list 'values' to shell-arrays + " \ + CACHE_ARGS=() \ + ENVIRONMENT_NAME \ + PARSERS=( + scwrypts.cache-output.zshparse.args + scwrypts.environment.user.zshparse.env-name + ) + + eval "$ZSHPARSEARGS" + + ########################################## + + scwrypts.cache-output ${CACHE_ARGS[@]} \ + --cache-file environment.shell.yaml \ + -- \ + _SCWRYPTS_ENVIRONMENT__CONVERT_SHELL_VALUES \ + --environment-name "$ENVIRONMENT_NAME" \ + ; +} + +${scwryptsmodule}.get-json() { + eval "$(usage.reset)" + local USAGE__description=" + returns a JSON object containing live environment configurations + for the target environment + + contains both .path.style.lookup path and ENVIRONMENT_VARIABLE lookup keys + " \ + CACHE_ARGS=() \ + ENVIRONMENT_NAME \ + PARSERS=( + scwrypts.cache-output.zshparse.args + scwrypts.environment.user.zshparse.env-name + ) + + eval "$ZSHPARSEARGS" + + ########################################## + + scwrypts.cache-output ${CACHE_ARGS[@]} \ + --cache-file environment.user.json \ + -- \ + scwrypts.environment.user.get-json.helper \ + --environment-name "$ENVIRONMENT_NAME" \ + ; +} + +##################################################################### + +${scwryptsmodule}.zshparse.env-name() { + # local ENVIRONMENT_NAME + local PARSED=0 + case $1 in + ( --environment-name ) + PARSED=2 + ENVIRONMENT_NAME=$2 + + # bypass cache when specifying explicit environment name + [[ ${(t)CACHE_ARGS} =~ array ]] && CACHE_ARGS+=(--use-cache bypass) + ;; + esac + return $PARSED +} + +${scwryptsmodule}.zshparse.env-name.usage() { + USAGE__options+="\n + --environment-name name of a scwrypts environment (default: $SCWRYPTS_ENV) + using this flag will bypass cache + " +} + +${scwryptsmodule}.zshparse.env-name.validate() { + [ "$ENVIRONMENT_NAME" ] || ENVIRONMENT_NAME="$SCWRYPTS_ENV" +} + +##################################################################### + +${scwryptsmodule}.get.helper() { + local ENVIRONMENT_NAME LOADING_ORIGINAL_ENV=true + local _S ERRORS=0 + while [[ $# -gt 0 ]] + do + _S=1 + case $1 in + ( --parent ) LOADING_ORIGINAL_ENV=false + ;; + ( * ) + : \ + && [ ! $ENVIRONMENT_NAME ] \ + || echo.error "unknown argument '$1'" \ + || break + + [ $ENVIRONMENT_NAME ] || { ENVIRONMENT_NAME="$1"; break; } + esac + shift $_S + done + + utils.check-errors || return $? + + local ENVIRONMENT_NAME="$1" + [ $ENVIRONMENT_NAME ] || ENVIRONMENT_NAME=$SCWRYPTS_ENV + + [[ $LOADING_ORIGINAL_ENV =~ true ]] && { + case $SCWRYPTS_ENVIRONMENT__SHOW_ENV_HELP in + ( true ) + echo " + # + # current scwrypts environment = $ENVIRONMENT_NAME + # + # - metadata tags are READONLY; changes to any key which starts with a + # '.' followed by all-caps (e.g. '.DESCRIPTION') will be ignored on + # save + # + # - value precedence is as follows (lower number is higher priority): + # 0. runtime environment variable '__override' value + # 1. the value from the 'value' key + # 2. the value from the '.PARENTVALUE' (if 'value' key is null) + # 3. a user-selected value from the 'selection' list + # 4. a user-selected value from the '.PARENTSELECTION' list + # + # - values are used like environment variables, although most scalar + # values are permitted, they are converted to strings or string arrays + # before use; string 'null' is OK, but null-type means not configured + # + # - for 'value' null-type / empty = not configured + # - for 'selection' null-type / empty / empty-list = not configured + # + --- + " + ;; + ( false ) + echo "--- # current scwrypts environment = $ENVIRONMENT_NAME" + ;; + esac | sed 's/\(^\s\+\|\s\+$\)//g; /^$/d' + } + + local GROUP GROUP_CONFIG_FILENAME + { + scwrypts.environment.user.get-full-template-with-value-keys + [[ $LOADING_ORIGINAL_ENV =~ true ]] && { + for PARENT in $(scwrypts.environment.common.get-parent-env-names "$ENVIRONMENT_NAME") + do + echo --- + scwrypts.environment.user.get.helper --parent "$PARENT" \ + | sed ' + s/^\(\s\+\)\(value\|selection\):/\1.PARENT\U\2:/ + ' \ + | utils.yq '. + | del(.. | select(has(".PARENTVALUE") and .".PARENTVALUE" == null).".PARENTVALUE") + | del(.. | select(has(".PARENTSELECTION") and (.".PARENTSELECTION" | length) == 0).".PARENTSELECTION") + | del(.. | select(has(".PARENTSELECTION") and has(".PARENTVALUE")).".PARENTSELECTION") + ' \ + ; + done + } + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + GROUP_CONFIG_FILENAME="$(scwrypts.environment.common.get-env-filename "$ENVIRONMENT_NAME" "$GROUP")" + + [ -f "${GROUP_CONFIG_FILENAME}" ] || touch "${GROUP_CONFIG_FILENAME}" + + [[ $(head -n1 "$GROUP_CONFIG_FILENAME") =~ ^---$ ]] || echo --- + cat "$GROUP_CONFIG_FILENAME" + done + } \ + | scwrypts.environment.common.combine-template-files \ + | utils.yq -P \ + | sed -z 's/\n[a-z]/\n&/g' \ + | sed 's/value: null$/value:/; /\svalue:/G' \ + ; +} + +${scwryptsmodule}.get-full-template-with-value-keys() { + scwrypts.environment.get-full-template \ + | utils.yq '(.. | select(has(".ENVIRONMENT"))) += { + "selection": [], + "value": null + } + ' \ + | sed 's/ ""$//' +} + +##################################################################### + +_SCWRYPTS_ENVIRONMENT__CONVERT_SHELL_VALUES() { + scwrypts.environment.user.get $@ \ + | utils.yq '.. + |= select( + ((has ("value") | not) or .value == null) and has (".PARENTVALUE") + ).value = .".PARENTVALUE" + ' \ + | utils.yq '.. + |= select( + ((has ("selection") | not) or .selection == null or .selection | length == 0) and has (".PARENTVALUE") + ).value = .".PARENTVALUE" + ' \ + | utils.yq '.. + |= select( + has("value") and .value | type == "!!seq" and .value | length != 0 + ).value = "(" + (.value | join " ") + ")" + ' \ + | utils.yq '. + | del(.. | select(has(".PARENTVALUE")).".PARENTVALUE") + | del(.. | select(has(".ENVIRONMENT")).".ENVIRONMENT") + | del(.. | select(has(".GROUP")).".GROUP") + | del(.. | select(has(".DESCRIPTION")).".DESCRIPTION") + | del(.. | select(has("value") and .value == null).value) + | del(.. | select(has("selection") and (.selection == null or .selection | length == 0)).selection) + | del(.. | select(has("value") and has("selection")).selection) + ' \ + ; +} + +##################################################################### + +${scwryptsmodule}.get-json.helper() { + local SHELL_VALUES="$(_SCWRYPTS_ENVIRONMENT__CONVERT_SHELL_VALUES $@)" + local LOOKUP_MAP="$(scwrypts.environment.get-envvar-lookup-map)" + { + echo "configuration:" + echo "${SHELL_VALUES}" | sed 's/^/ /' + local ENVIRONMENT_VARIABLE + echo "environment:" + for ENVIRONMENT_VARIABLE in $(\ + scwrypts.environment.get-full-template \ + | utils.yq '.. | select(has(".ENVIRONMENT")) | .".ENVIRONMENT"' \ + ) + do + echo " ${ENVIRONMENT_VARIABLE}: $(echo "${SHELL_VALUES}" | utils.yq -r "$(echo "${LOOKUP_MAP}" | utils.yq -r ".${ENVIRONMENT_VARIABLE}")")" + done + } | utils.yq -oj +} diff --git a/zsh/scwrypts/get-realpath.module.zsh b/zsh/scwrypts/get-realpath.module.zsh new file mode 100644 index 0000000..64ebe34 --- /dev/null +++ b/zsh/scwrypts/get-realpath.module.zsh @@ -0,0 +1,17 @@ +${scwryptsmodule}() { + # + # returns the fully-qualified path from a user-specified, relative reference + # (allows for '--input-file ./my-file' on the command-line) + # + # also uses 'readlink --canonicalize' to read through symlinks to the realpath + # + + [ "$1" ] || return 1 + + [[ ! $1 =~ ^[/~] ]] \ + && echo $(readlink --canonicalize -- "${EXECUTION_DIR}/$1") \ + || echo "$1" \ + ; + + return 0 +} diff --git a/zsh/scwrypts/get-runstring.module.zsh b/zsh/scwrypts/get-runstring.module.zsh new file mode 100644 index 0000000..88424fb --- /dev/null +++ b/zsh/scwrypts/get-runstring.module.zsh @@ -0,0 +1,145 @@ +${scwryptsmodule}() { + local GROUP_ROOT=$(scwrypts.config.group ${SCWRYPT_GROUP} root) + local RUNSTRING + + [ ${SCWRYPT_NAME} ] && [ ${SCWRYPT_TYPE} ] && [ ${SCWRYPT_GROUP} ] || { + echo.error 'missing required information to get runstring' + return 1 + } + + [ ${ENV_REQUIRED} ] && [[ ${ENV_REQUIRED} -eq 1 ]] && [ ! ${SCWRYPTS_ENV} ] && { + echo.error 'missing required information to get runstring' + return 1 + } + + local GET_RUNSTRING + for GET_RUNSTRING in \ + SCWRYPTS_GROUP_CONFIGURATION__${SCWRYPT_GROUP}.${SCWRYPT_TYPE}.get-runstring \ + scwrypts.get-runstring.${SCWRYPT_TYPE} \ + 'no valid runstring generator' \ + ; + do + command -v ${GET_RUNSTRING} &>/dev/null && { + RUNSTRING="$(${GET_RUNSTRING})" + break + } + done + + [ ${RUNSTRING} ] \ + || echo.error "get-runstring error (${GET_RUNSTRING})" \ + || return 2 \ + ; + + echo "$(scwrypts.runstring.get-prefix) ${RUNSTRING}" +} + +scwrypts.runstring.get-prefix() { + local VIRTUALENV="${GROUP_ROOT}/${SCWRYPT_TYPE}/bin/activate" + [ -f "${VIRTUALENV}" ] && printf "source \"${VIRTUALENV}\"; " + + printf "source \"$(scwrypts.config.group scwrypts root)/zsh/import.driver.zsh\"; " + printf "SCWRYPTS_ENV=${SCWRYPTS_ENV}; " +} + +##################################################################### + +${scwryptsmodule}.zsh() { + utils.dependencies.check zsh || return 1 + + local SCWRYPT_FILENAME + + [ $(scwrypts.config.group ${SCWRYPT_GROUP} type) ] \ + && SCWRYPT_FILENAME="${GROUP_ROOT}/${SCWRYPT_NAME}" \ + || SCWRYPT_FILENAME="${GROUP_ROOT}/${SCWRYPT_TYPE}/${SCWRYPT_NAME}" \ + ; + + scwrypts.get-runstring.zsh.generic +} + +${scwryptsmodule}.zsh.generic() { + # + # boilerplate to allow + # - multiflag splitting (e.g. -abc = -a -b -c) + # - help flag injection (e.g. -h | --help) + # - default USAGE definition (allows USAGE__options style usage definition) + # - required MAIN() function wrapping + # + # this is available automatically in SCWRYPT_GROUP declaration contexts + # (e.g. my-group.scwrypts.zsh) + # + [ "${SCWRYPT_FILENAME}" ] || { + echo.error "must define a SCWRYPT_FILENAME" + return 1 + } + printf " + source '${SCWRYPT_FILENAME}' + utils.check-environment + ERRORS=0 + + export USAGE=\" + usage: - + + args: - + + options: - + -h, --help display this message and exit + + description: - + \" + + [ ! \$USAGE__usage ] && export USAGE__usage='[...options...]' + + () { + local MAIN_ARGS=() + local VARSPLIT + while [[ \$# -gt 0 ]] + do + case \$1 in + ( -[a-z][a-z]* ) + VARSPLIT=\$(echo \"\$1 \" | sed 's/^\\\\(-.\\\\)\\\\(.*\\\\) /\\\\1 -\\\\2/') + set -- throw-away \$(echo \" \$VARSPLIT \") \${@:2} + ;; + ( -h | --help ) utils.io.usage; exit 0 ;; + ( * ) MAIN_ARGS+=(\$1) ;; + esac + shift 1 + done + MAIN \${MAIN_ARGS[@]} + } " +} + +##################################################################### + +${scwryptsmodule}.py() { + utils.dependencies.check python || return 1 + use scwrypts/virtualenv + + local VIRTUALENV_PATH="$(scwrypts.virtualenv.common.get-path py)" + [ -f "${VIRTUALENV_PATH}/bin/activate" ] \ + || scwrypts.virtualenv.update py &>/dev/null + + printf " + source \"${VIRTUALENV_PATH}/bin/activate\" + cd -- \"${GROUP_ROOT}\" + python -m $(echo ${SCWRYPT_TYPE}/${SCWRYPT_NAME} | sed 's/\//./g; s/\.py$//; s/\.\.//') " +} + +##################################################################### + +${scwryptsmodule}.zx() { + utils.dependencies.check zx || return 1 + use scwrypts/virtualenv/update + + local ZX_ROOT + [[ "$(eval echo "\$SCWRYPTS_GROUP_CONFIGURATION__${GROUP}__type")" =~ zx ]] \ + && ZX_ROOT="${GROUP_ROOT}" \ + || ZX_ROOT="${GROUP_ROOT}/zx" \ + ; + + [ -d "${ZX_ROOT}/node_modules" ] \ + || scwrypts.virtualenv.update zx >&2 + + printf " + export FORCE_COLOR=3 + ${ZX_ROOT}/${SCWRYPT_NAME}.js " +} diff --git a/zsh/scwrypts/list-available.module.zsh b/zsh/scwrypts/list-available.module.zsh new file mode 100644 index 0000000..1e97483 --- /dev/null +++ b/zsh/scwrypts/list-available.module.zsh @@ -0,0 +1,57 @@ +${scwryptsmodule}() { + local TYPE_COLOR=$(utils.colors.light-gray) + local GROUP GROUP_ROOT GROUP_COLOR LOOKUP_PIDS=() + { + echo 'NAME^TYPE^GROUP' + for GROUP in ${SCWRYPTS_GROUPS} + do + GROUP_ROOT="$(scwrypts.config.group ${GROUP} root)" + GROUP_COLOR="$(scwrypts.config.group ${GROUP} color)" + [ "${GROUP_COLOR}" ] || GROUP_COLOR=$(utils.colors.reset) + + GROUP_TYPE=$(scwrypts.config.group ${GROUP} type) + [ ${GROUP_TYPE} ] && MINDEPTH=1 && GROUP_TYPE="${GROUP_TYPE}\\/" || MINDEPTH=2 + + command -v SCWRYPTS_GROUP_CONFIGURATION__${GROUP}.list-available >/dev/null 2>&1 \ + && LOOKUP=SCWRYPTS_GROUP_CONFIGURATION__${GROUP}.list-available \ + || LOOKUP=scwrypts.list-available.default \ + ; + + { + ${LOOKUP} \ + | sed "s|\\([^/]*\\)/\(.*\)$|$(utils.colors.reset)\\2^$(printf ${TYPE_COLOR})\\1^$(printf ${GROUP_COLOR})${GROUP}$(utils.colors.reset)|" \ + } & + LOOKUP_PIDS+=($!) + done + for p in ${LOOKUP_PIDS[@]}; do wait $p; done + } | column -t -s '^' +} + +##################################################################### + +${scwryptsmodule}.default() { + cd ${GROUP_ROOT} + find . -mindepth ${MINDEPTH} \ + \( \ + -type d -name .git \ + -o -type d -name node_modules \ + -o -type d -name __pycache__ \ + -o -type d -path ./.config \ + -o -type d -path ./.github \ + -o -type d -path ./docs \ + \) -prune \ + -o -type f -executable \ + -print \ + | sed "s/^\\.\\///; s/\\.[^.]*$//; s/^/${GROUP_TYPE}/" \ + ; +} + +##################################################################### + +SCWRYPTS_GROUP_CONFIGURATION__scwrypts.list-available() { + # removing a couple of things which need to be ignored in the + # scwrypts group, but don't necessarily need to be omitted by + # the default list-available :) + scwrypts.list-available.default \ + | grep -v '^\(plugins\|rs\)' +} diff --git a/zsh/scwrypts/logs/clear b/zsh/scwrypts/logs/clear index 7de4f3c..a717379 100755 --- a/zsh/scwrypts/logs/clear +++ b/zsh/scwrypts/logs/clear @@ -1,20 +1,21 @@ -#!/bin/zsh +#!/usr/bin/env zsh ##################################################################### MAIN() { - cd $SCWRYPTS_ROOT - - STATUS "Found $(ls $SCWRYPTS_LOG_PATH | wc -l) log files" - WARNING " - this will permanently clear all local cloud script logs found in - '$SCWRYPTS_LOG_PATH' - " - - yN 'continue?' || ABORT - - STATUS 'removing logfiles' - rm -rf $SCWRYPTS_LOG_PATH/* \ - && SUCCESS 'done' \ - || { ERROR 'failed :c'; exit 2; }\ + local LOGFILE_COUNT="$(find "${SCWRYPTS_LOG_PATH}" -type f 2>/dev/null | wc -l)" + + [ "${SCWRYPTS_LOG_PATH}" ] && [ -d "${SCWRYPTS_LOG_PATH}" ] && [[ ${LOGFILE_COUNT} -gt 0 ]] || { + echo.success "no local logs found; nothing to do!" + return 0 + } + + echo.status "found ${LOGFILE_COUNT} log files" + echo.warning "this will permanently delete everything in\n${SCWRYPTS_LOG_PATH}" + + utils.yN 'continue?' || utils.abort + + rm -rf "${SCWRYPTS_LOG_PATH}" \ + && echo.success 'all logfiles removed' \ + || echo.error 'something went wrong (see above)' \ ; } diff --git a/zsh/scwrypts/logs/view b/zsh/scwrypts/logs/view index f4a03a9..95440ed 100755 --- a/zsh/scwrypts/logs/view +++ b/zsh/scwrypts/logs/view @@ -1,13 +1,12 @@ -#!/bin/zsh +#!/usr/bin/env zsh ##################################################################### MAIN() { - cd $SCWRYPTS_ROOT PROMPT 'select a script log' - LOG_FILE=$(ls -t $SCWRYPTS_LOG_PATH | FZF 'logfile') - [ ! $LOG_FILE ] && { ERROR 'user abort'; exit 1; } - - STATUS 'opening logfile' - LESS "$SCWRYPTS_LOG_PATH/$LOG_FILE" - SUCCESS 'done' + LOG_FILE=$(cd "${SCWRYPTS_LOG_PATH}"; ls -t | utils.fzf 'logfile') + [ "${LOG_FILE}" ] || utils.abort + + echo.status 'opening logfile' + LESS "${SCWRYPTS_LOG_PATH}/${LOG_FILE}" + echo.success 'done' } diff --git a/zsh/scwrypts/meta.module.zsh b/zsh/scwrypts/meta.module.zsh new file mode 100644 index 0000000..4b50070 --- /dev/null +++ b/zsh/scwrypts/meta.module.zsh @@ -0,0 +1,15 @@ +##################################################################### + +${scwryptsmodule}.run() { # context wrapper to run scwrypts within scwrypts + local EXIT_CODE=0 + ((SUBSCWRYPT+=1)) + + SCWRYPTS_LOG_LEVEL=$SCWRYPTS_LOG_LEVEL \ + SUBSCWRYPT=$SUBSCWRYPT \ + $(scwrypts.config.group scwrypts root)/scwrypts $@ + + EXIT_CODE=$? + + ((SUBSCWRYPT-=1)) + return $EXIT_CODE +} diff --git a/zsh/scwrypts/rebuild-cache b/zsh/scwrypts/rebuild-cache new file mode 100755 index 0000000..901b5d9 --- /dev/null +++ b/zsh/scwrypts/rebuild-cache @@ -0,0 +1,89 @@ +#!/usr/bin/env zsh +##################################################################### + +USAGE__args=" + \$@ a list of groups; one of (${SCWRYPTS_GROUPS[@]}) +" + +USAGE__description=" + clear and rebuild the zsh library cache for one or all + groups + + by default, clears the entire cache and rebuilds for all + groups; specifying any number of groups as args will only + build the listed groups + + at any time the entire cache can be cleared by manually + deleting the cache directory + - by default it is : ~/.cache/zshimport + - you have configured : ${ZSHIMPORT_CACHE_DIR} +" + +##################################################################### + +MAIN() { + local ARGS=() + + eval "${ZSHPARSEARGS}" + + case ${#ARGS[@]} in + ( 0 ) ARGS=(${SCWRYPTS_GROUPS[@]}) ;; + esac + + local GROUP GROUP_ROOT GROUP_TYPE GROUP_MODULES GROUP_MODULE CACHE_DIR + for GROUP in ${ARGS[@]} + do + GROUP_ROOT="$(scwrypts.config.group ${GROUP} zshlibrary)" + [ "${GROUP_ROOT}" ] && [ -d "${GROUP_ROOT}" ] || { + GROUP_ROOT="$(scwrypts.config.group ${GROUP} root)" + case "$(scwrypts.config.group ${GROUP} type)" in + ( '' ) + GROUP_ROOT="${GROUP_ROOT}/zsh" + ;; + esac + } + [ "${GROUP_ROOT}" ] && [ -d "${GROUP_ROOT}" ] || { + echo.warning "cannot identify group root for '${GROUP}'; skipping" + continue + } + + GROUP_MODULES=($( + find "${GROUP_ROOT}" -type f -name \*.module.zsh \ + | sed "s|^${GROUP_ROOT}/||" \ + | sed 's/\.module.zsh//' \ + )) + + [[ ${#GROUP_MODULES[@]} -eq 0 ]] && { + echo.warning "no modules found for group '${GROUP}'; skipping" + continue + } + + echo.status "cleaning up old cache(s) for ${GROUP}" + for CACHE_DIR in $(find "${ZSHIMPORT_CACHE_DIR}" -mindepth 1 -maxdepth 1 -name ${GROUP}\*) + do + [ "${CACHE_DIR}" ] \ + && rm -rf -- "${CACHE_DIR}" \ + && echo.status " $(utils.colors.yellow)x $(basename -- ${CACHE_DIR})" \ + || echo.status " $(utils.colors.red)x $(basename -- ${CACHE_DIR}) (failed to delete)" \ + ; + done + + echo.status "rebuilding cache for ${GROUP}" + for GROUP_MODULE in ${GROUP_MODULES[@]} + do + use --group ${GROUP} ${GROUP_MODULE} --generate-cache &>/dev/null \ + && echo.status " $(utils.colors.green)-> ${GROUP_MODULE}" \ + || echo.status " $(utils.colors.red)-> ${GROUP_MODULE} (failed to build)" \ + ; + done + done +} + +MAIN.parse() {} +MAIN.parse.validate() { + [[ ${ZSHIMPORT_USE_CACHE} =~ true ]] \ + || echo.error "ZSHIMPORT_USE_CACHE is set to 'false' so I cannot rebuild the cache" + + [ "${ZSHIMPORT_CACHE_DIR}" ] && [ -d "${ZSHIMPORT_CACHE_DIR}" ] \ + || echo.error "I cannot find the ZSHIMPORT_CACHE_DIR '${ZSHIMPORT_CACHE_DIR}'" +} diff --git a/zsh/office/latex/templates/math/gitignore b/zsh/scwrypts/select.module.zsh similarity index 100% rename from zsh/office/latex/templates/math/gitignore rename to zsh/scwrypts/select.module.zsh diff --git a/zsh/office/latex/templates/gitignore b/zsh/scwrypts/template/module/.gitignore similarity index 100% rename from zsh/office/latex/templates/gitignore rename to zsh/scwrypts/template/module/.gitignore diff --git a/zsh/scwrypts/template/module/.tex b/zsh/scwrypts/template/module/.tex new file mode 100644 index 0000000..9eee8cd --- /dev/null +++ b/zsh/scwrypts/template/module/.tex @@ -0,0 +1,9 @@ +\documentclass[letterpaper]{article} + +\newcommand{\documentTitle} {} +\newcommand{\documentDate} {August 28, 2024} +\newcommand{\documentId} {} + +\newcommand{\authorName} {} +\newcommand{\authorId} {} + diff --git a/zsh/scwrypts/template/module/create b/zsh/scwrypts/template/module/create new file mode 100755 index 0000000..d10be6d --- /dev/null +++ b/zsh/scwrypts/template/module/create @@ -0,0 +1,14 @@ +#!/usr/bin/env zsh +##################################################################### + +use scwrypts/template/module/create +use scwrypts/template/zshparse + +##################################################################### + +scwrypts.template.module.create.parse.usage +scwrypts.template.zshparse.include-help.usage + +##################################################################### + +MAIN() { scwrypts.template.module.create $@; } diff --git a/zsh/scwrypts/template/module/create.module.zsh b/zsh/scwrypts/template/module/create.module.zsh new file mode 100644 index 0000000..5d14523 --- /dev/null +++ b/zsh/scwrypts/template/module/create.module.zsh @@ -0,0 +1,32 @@ +##################################################################### + +use scwrypts/template/zshparse + +##################################################################### + +${scwryptsmodule}() { + local TEMPLATE_FILE="$(scwrypts.config.group scwrypts root)/zsh/scwrypts/template/module/template.zsh" + local PARSERS=( + scwrypts.template.zshparse.include-help + scwrypts.template.zshparse.mode-select + ) + + eval "$(utils.parse.autosetup)" + ########################################## + + case ${TEMPLATE_GENERATION_MODE} in + ( stdout ) + echo "${TEMPLATE}" + ;; + esac +} + +##################################################################### + +${scwryptsmodule}.parse() { return 0; } + +${scwryptsmodule}.parse.usage() { + USAGE__description=' + sets up recommended boilerplate for a new scwrypts module + ' +} diff --git a/zsh/scwrypts/template/module/template.zsh b/zsh/scwrypts/template/module/template.zsh new file mode 100644 index 0000000..4fe7613 --- /dev/null +++ b/zsh/scwrypts/template/module/template.zsh @@ -0,0 +1,129 @@ +##################################################################### + +# +# include 'use' imports here +# use your/zsh/module --group your-group (would include your-group.your.zsh.module) +# +#use + +# +# DEPENDENCIES are commands which must be executable +# (either on \$PATH or fully-qualified executable) +# +# REQUIRED_ENV are environment variables which must be present +# (loaded from \$SCWRYPTS_ENV) +# +#DEPENDENCIES+=() +#REQUIRED_ENV+=() + +##################################################################### + +# +# ${scwryptsmodule} helps you create a globally-unique name for this function +# +# suppose we import this library with: +# use submodule-a/submodule-b/this-library --group my-group +# +# ${scwryptsmodule} will expand to 'my-group.submodule-a.submodule-b.this-library' +# (the full name MUST be used anywhere this function is referenced!) +# +# although using ${scwryptsmodule} is not required, remember that your function +# name MUST be globally unique or it will overwrite / be overwritten by other modules +# +${scwryptsmodule}() { + # this is the description that will appear when you pass this command -h or --help + local DESCRIPTION=' + command description here + ' + # include non-default parsers here (e.g. you 'use some/zshparse/library' above); + # the ${scwryptsmodule}.parse below is ALREADY included automatically + #local PARSERS=() + + # autosetup handles ALL parsing logic below; ${scwryptsmodule}() will + # return with an error code if ANY argument validation errors occur + # + # some defaults are included (like -h | --help which prints usage and exits) + eval "$(utils.parse.autosetup)" + ########################################## + + # your function body goes HERE +} + +##################################################################### + +# +# all ${scwryptsmodule}.parse* functions are OPTIONAL (but recommended) +# +${scwryptsmodule}.parse() { + # represents the total number of arguments successfully parsed by this parser + local PARSED=0 + + # parse arguments one at a time in a case statement + case $1 in + # + # ( -s | --setting-a ) PARSED=1; MY_SETTING_A=true ;; + # + # you have access to the entire list of remaining UNPARSED variables + # ( --setting-b ) PARSED=2; MY_SETTING_B="$2" ;; + # + # + # unless you have a specific reason to, DO NOT PARSE A DEFAULT CASE '( * )' + # let the zshparser handle: + # - unknown / fallthrough arguments + # - missing arguments "$2" (you can ASSUME it is there) + # + # + # if you want to capture "all remaining arguments" define ARGS as described + # in ${scwryptsmodule}.parse.locals() below + # + esac + + # return the TOTAL NUMBER OF ARGUMENTS PARSED + return ${PARSED} +} + +${scwryptsmodule}.parse.locals() { + # + # local variables here are declared as "local" in ${scwryptsmodule}() above + # be certain to: + # - define each variable ON A SEPARATE LINE "local MY_VARIABLE" + # - declare ALL variables used in ${scwryptsmodule}.parse + # - declare ALL variables used in ${scwryptsmodule}.parse.validate + # + # local MY_SETTING_A + # local MY_SETTING_B=default-value + # + # declaring "local ARGS=()" will accept ALL unrecognized arguments into the + # ARGS array + # + # local ARGS=() +} + +${scwryptsmodule}.parse.usage() { + # add to the existing USAGE__* variables to improve the --help message + # (e.g. USAGE__options, USAGE__args, USAGE__description) + USAGE__options+=' + ' + # rather than defining 'local DESCRIPTION' above, you can opt to definie + # the USAGE__description here which is helpful when providing an executable + # wrapper for this module + # + #USAGE__description='' + # +} + +${scwryptsmodule}.parse.validate() { + # + # after all arguments have been parsed, this validation is run + # + # although the exit code of this function IS IGNORED, you can indicate + # validation errors by calling: + # echo.error 'error message' + # + # you can also 'return' early if you need, but 'return 1' is not considered + # an error status (you MUST declare errors with echo.error) + # + # any data manipulation will be available in ${scwryptsmodule}() SO LONG AS + # your variables are declared in ${scwryptsmodule}.parse.locals() (above) + # +} diff --git a/zsh/scwrypts/template/module/use.module.zsh b/zsh/scwrypts/template/module/use.module.zsh new file mode 100644 index 0000000..e69de29 diff --git a/zsh/scwrypts/template/zshparse.module.zsh b/zsh/scwrypts/template/zshparse.module.zsh new file mode 100644 index 0000000..8536bef --- /dev/null +++ b/zsh/scwrypts/template/zshparse.module.zsh @@ -0,0 +1,92 @@ +##################################################################### + +${scwryptsmodule}.include-help() { + local PARSED=0 + + case $1 in + ( --include-help ) + PARSED=2 + case $2 in + ( true | false ) INCLUDE_HELP=$2 ;; + ( * ) echo.error "invalid value for --include-help '$2'" ;; + esac + ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.include-help.locals() { + local INCLUDE_HELP=${SCWRYPTS_GENERATOR__SHOW_HELP} # default is configurable + + local TEMPLATE_FILE # by providing the TEMPLATE_FILE, the TEMPLATE literal text is automatically generated + local TEMPLATE +} + +${scwryptsmodule}.include-help.usage() { + USAGE__options+=" + --include-help whether to include help comments in the description + (default : ${SCWRYPTS_GENERATOR__SHOW_HELP}) + " +} + +${scwryptsmodule}.include-help.validate() { + [ "${TEMPLATE_FILE}" ] && { + [ -f "${TEMPLATE_FILE}" ] \ + || echo.error "no template at '${TEMPLATE_FILE}'" \ + || return + + case ${INCLUDE_HELP} in + ( true ) + TEMPLATE="$(cat -- "${TEMPLATE_FILE}")" + ;; + ( false ) + TEMPLATE="$(sed -- '/# /d; /^\s*#$/d' "${TEMPLATE_FILE}")" + ;; + esac + + [ "${TEMPLATE}" ] \ + || echo.error "failed to generate template '${TEMPLATE_FILE}'" + } +} + +##################################################################### + +${scwryptsmodule}.mode-select() { + local PARSED=0 + + case $1 in + #( -g | --group ) PARSED=2; MODULE_GROUP="$2" ;; + #( -n | --name ) PARSED=2; MODULE_NAME="$2" ;; + + ( --mode ) + PARSED=2 + TEMPLATE_GENERATION_MODE=$2 + ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.mode-select.locals() { + local TEMPLATE_GENERATION_MODE=stdout + + #local MODULE_GROUP + #local MODULE_NAME +} + +${scwryptsmodule}.mode-select.usage() { + USAGE__options+=' + --mode one of the supported template generation modes + supported : (stdout) + ' +} + +${scwryptsmodule}.mode-select.validate() { + case ${TEMPLATE_GENERATION_MODE} in + ( stdout ) ;; + ( * ) + echo.error "invalid template output mode '${TEMPLATE_GENERATION_MODE}'" + ;; + esac +} diff --git a/zsh/scwrypts/virtualenv/common.module.zsh b/zsh/scwrypts/virtualenv/common.module.zsh new file mode 100644 index 0000000..6d2a589 --- /dev/null +++ b/zsh/scwrypts/virtualenv/common.module.zsh @@ -0,0 +1,36 @@ +##################################################################### + +SCWRYPTS_VIRTUALENV__AVAILABLE_VIRTUALENVS=() + +use scwrypts/virtualenv/env/py +use scwrypts/virtualenv/env/zx + +use scwrypts/virtualenv/zshparse + +##################################################################### + +${scwryptsmodule}.get-path() { + local TYPE ARGS=() PARSERS=( + scwrypts.virtualenv.zshparse.type-arg + ) + + eval "$ZSHPARSEARGS" + + ########################################## + + local ENV_PATH="${SCWRYPTS_STATE_PATH}/virtualenv/${SCWRYPTS_ENV}/${TYPE}" + + mkdir -p -- "${ENV_PATH}" &>/dev/null + + echo "${ENV_PATH}" +} + +${scwryptsmodule}.validate-controller() { + local TYPE="$1" + command -v \ + virtualenv.${TYPE}.create \ + virtualenv.${TYPE}.activate \ + virtualenv.${TYPE}.deactivate \ + virtualenv.${TYPE}.update \ + &>/dev/null +} diff --git a/zsh/scwrypts/virtualenv/delete.module.zsh b/zsh/scwrypts/virtualenv/delete.module.zsh new file mode 100644 index 0000000..0c74b04 --- /dev/null +++ b/zsh/scwrypts/virtualenv/delete.module.zsh @@ -0,0 +1,49 @@ +##################################################################### + +use scwrypts/virtualenv/common + +##################################################################### + +${scwryptsmodule}() { + local TYPE + + local _S ERRORS=0 POSITIONAL_ARGS=0 + while [[ $# -gt 0 ]] + do + _S=1 + case $1 in + ( * ) + ((POSITIONAL_ARGS+=1)) + case ${POSITIONAL_ARGS} in + ( 1 ) TYPE="$1" ;; + ( * ) echo.error "unknown argument '$1'" ;; + esac + esac + shift ${_S} + done + + [ "${GROUP}" ] || echo.error 'missing group argument' + [ "${TYPE}" ] || echo.error 'missing type argument' + + utils.check-errors || return $? + + ########################################## + + scwrypts.virtualenv.common.validate-controller "${TYPE}" || { + echo.status "no environment controller exists for ${TYPE}" + return 0 + } + + local VIRTUALENV_PATH="$(scwrypts.virtualenv.common.get-path "${TYPE}")" + [ -d "${VIRTUALENV_PATH}" ] || { + echo.success "no ${TYPE} environment detected" + return 0 + } + + ########################################## + + rm -rf -- "${VIRTUALENV_PATH}" \ + && echo.success "succesfully cleaned up ${TYPE} virtualenv" \ + || echo.error "unabled to remove '${VIRTUALENV_PATH}'" \ + ; +} diff --git a/zsh/scwrypts/virtualenv/env/py.module.zsh b/zsh/scwrypts/virtualenv/env/py.module.zsh new file mode 100644 index 0000000..5f327cf --- /dev/null +++ b/zsh/scwrypts/virtualenv/env/py.module.zsh @@ -0,0 +1,87 @@ +##################################################################### +SCWRYPTS_VIRTUALENV__AVAILABLE_VIRTUALENVS+=(py) +##################################################################### + +virtualenv.py.create() { + utils.dependencies.check virtualenv || return 1 + + ########################################## + + local VIRTUALENV_PATH="$(scwrypts.virtualenv.common.get-path py)" + local PYTHON="$(virtualenv.py.get-base-executable)" + + [ -f "${VIRTUALENV_PATH}/bin/activate" ] && return 0 + + echo.status 'creating python virtualenv' + + [ "${PYTHON}" ] \ + || echo.error 'python>=3.10 not available; skipping python env' \ + || return 1 + + echo.status 'setting up virtualenv' + virtualenv "${VIRTUALENV_PATH}" --python="${PYTHON}" \ + && echo.success 'python virtualenv created' \ + || echo.error "unable to create '${VIRTUALENV_PATH}' with '${PYTHON}'" \ + ; +} + +virtualenv.py.activate() { + source "$(scwrypts.virtualenv.common.get-path py)/bin/activate" +} + +virtualenv.py.deactivate() { + deactivate &>/dev/null + return 0 +} + +virtualenv.py.update() { + local ERRORS=0 + local GROUP REQUIREMENTS_FILENAME + + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + case "$(eval echo "\$SCWRYPTS_GROUP_CONFIGURATION__${GROUP}__type")" in + ( '' ) + REQUIREMENTS_FILENAME="$(scwrypts.config.group ${GROUP} root)/py/requirements.txt" + ;; + ( py ) + REQUIREMENTS_FILENAME="$(scwrypts.config.group ${GROUP} root)/requirements.txt" + ;; + ( * ) + continue + ;; + esac + + [ "${REQUIREMENTS_FILENAME}" ] && [ -f "${REQUIREMENTS_FILENAME}" ] \ + || echo.error "group ${GROUP} appears to be misconfigured" \ + || continue + + ( cd "$(dirname -- "${REQUIREMENTS_FILENAME}")" \ + && pip install \ + --no-cache-dir \ + --requirement "${REQUIREMENTS_FILENAME}" \ + ) \ + || echo.error "something went wrong during pip install for ${GROUP}" \ + || continue + done + + return ${ERRORS} +} + +##################################################################### + +virtualenv.py.get-base-executable() { + local PY PYTHON + for PY in $(scwrypts.config python.versions) + do + python --version | grep -qi " ${PY}" \ + && which python \ + && break \ + ; + + which python${PY} &>/dev/null \ + && which python${PY} \ + && break \ + ; + done +} diff --git a/zsh/scwrypts/virtualenv/env/zx.module.zsh b/zsh/scwrypts/virtualenv/env/zx.module.zsh new file mode 100644 index 0000000..2e7847e --- /dev/null +++ b/zsh/scwrypts/virtualenv/env/zx.module.zsh @@ -0,0 +1,46 @@ +##################################################################### +SCWRYPTS_VIRTUALENV__AVAILABLE_VIRTUALENVS+=(zx) +##################################################################### + + +virtualenv.zx.create() { + utils.dependencies.check npm || return 1 +} + +virtualenv.zx.activate() { + return 0 # npm setup is managed by package.json +} + +virtualenv.zx.deactivate() { + return 0 # npm setup is managed by package.json +} + +virtualenv.zx.update() { + local ERRORS=0 + local GROUP NPM_ROOT + + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + case "$(eval echo "\$SCWRYPTS_GROUP_CONFIGURATION__${GROUP}__type")" in + ( '' ) + NPM_ROOT="$(scwrypts.config.group ${GROUP} root)/zx" + ;; + ( zx ) + NPM_ROOT="$(scwrypts.config.group ${GROUP} root)" + ;; + ( * ) + continue + ;; + esac + + [ "${NPM_ROOT}" ] && [ -d "${NPM_ROOT}" ] \ + || echo.error "group ${GROUP} appears to be misconfigured" \ + || continue + + ( cd "${NPM_ROOT}" && npm install; ) \ + || echo.error "something went wrong during npm install for ${GROUP}" \ + || continue + done + + return ${ERRORS} +} diff --git a/zsh/scwrypts/virtualenv/refresh b/zsh/scwrypts/virtualenv/refresh index 6a94698..730d4a4 100755 --- a/zsh/scwrypts/virtualenv/refresh +++ b/zsh/scwrypts/virtualenv/refresh @@ -1,27 +1,50 @@ -#!/bin/zsh -use scwrypts/virtualenv +#!/usr/bin/env zsh +use scwrypts/virtualenv/update +use scwrypts/virtualenv/delete +##################################################################### + +USAGE__options=' + -t, --type type of virtual environment to refresh + ' + +USAGE__description=' + drops, recreates, and updates the virtual environment used + by scwrypts in the appropriate group + ' + ##################################################################### MAIN() { + local ENV_GROUP ENV_TYPE + + local ERRORS=0 _S while [[ $# -gt 0 ]] do + _S=1 case $1 in - -g | --group ) ENV_GROUP="$2"; shift 1 ;; + ( -t | --type ) + [ $2 ] && ((_S+=1)) \ + || echo.error "missing env type" \ + || break + + ENV_TYPE="$2" + ;; esac - shift 1 + shift $_S done - - [ ! $ENV_GROUP ] && ENV_GROUP=scwrypts - - ENV_TYPE=$(echo $AVAILABLE_VIRTUALENVS | sed 's/ \+/\n/' | FZF 'select an environment to refresh') - [ ! $ENV_TYPE ] && ABORT - - REMINDER " - this will permanently remove all artifacts for the scwrypts $ENV_TYPE environment - (safe unless you have put something important in $(_VIRTUALENV__GET_PATH $ENV_GROUP $ENV_TYPE)) - " - - Yn "drop and recreate $ENV_TYPE virtual environment?" || ABORT - - REFRESH_VIRTUALENV $ENV_GROUP $ENV_TYPE + + [ $ENV_TYPE ] || ENV_TYPE=$(\ + echo ${SCWRYPTS_VIRTUALENV__AVAILABLE_VIRTUALENVS[@]} \ + | sed 's/ \+/\n/' \ + | utils.fzf 'select an environment to refresh' \ + ) + [ $ENV_TYPE ] || echo.error "no environment type selected" + + utils.check-errors --fail + + ########################################## + : \ + && scwrypts.virtualenv.delete "$ENV_TYPE" \ + && scwrypts.virtualenv.update "$ENV_TYPE" \ + ; } diff --git a/zsh/scwrypts/virtualenv/update-all b/zsh/scwrypts/virtualenv/update-all index af58960..8566e67 100755 --- a/zsh/scwrypts/virtualenv/update-all +++ b/zsh/scwrypts/virtualenv/update-all @@ -1,21 +1,22 @@ -#!/bin/zsh -use scwrypts/virtualenv +#!/usr/bin/env zsh +use scwrypts/virtualenv/update ##################################################################### MAIN() { - STATUS 'beginning update for all environments' - - FAILED_COUNT=0 - - for ENV_GROUP in ${SCWRYPTS_GROUPS[@]} + local ERRORS=0 + local ENV_TYPE ENV_TYPE_COUNT=${#SCWRYPTS_VIRTUALENV__AVAILABLE_VIRTUALENVS[@]} + + echo.status 'beginning update for all environments' + for ENV_TYPE in ${SCWRYPTS_VIRTUALENV__AVAILABLE_VIRTUALENVS[@]} do - for ENV_TYPE in ${AVAILABLE_VIRTUALENVS[@]} - do - UPDATE_VIRTUALENV $ENV_GROUP $ENV_TYPE || ((FAILED_COUNT+=1)) - done + scwrypts.virtualenv.update $ENV_TYPE \ + && echo.success "successfully updated '${ENV_TYPE}'" \ + || echo.error "error updating '${ENV_TYPE}'" \ + ; done - - [[ $FAILED_COUNT -eq 0 ]] \ - && SUCCESS 'all environments up-to-date' \ - || FAIL $FAILED_COUNT "failed to update $FAILED_COUNT more environment(s)" + + [[ ${ERRORS} -eq 0 ]] \ + && echo.success "successfully updated ${ENV_TYPE_COUNT} / ${ENV_TYPE_COUNT} environment(s)" \ + || echo.error "failed to update ${FAILED_COUNT} / ${ENV_TYPE_COUNT} environment(s)" \ + ; } diff --git a/zsh/scwrypts/virtualenv/update.module.zsh b/zsh/scwrypts/virtualenv/update.module.zsh new file mode 100644 index 0000000..9150589 --- /dev/null +++ b/zsh/scwrypts/virtualenv/update.module.zsh @@ -0,0 +1,34 @@ +##################################################################### + +use scwrypts/virtualenv/common +use scwrypts/virtualenv/zshparse + +##################################################################### + +${scwryptsmodule}() { + eval "$(usage.reset)" + local USAGE__description=' + update virtualenv dependencies + ' + local TYPE ARGS=() PARSERS=( + scwrypts.virtualenv.zshparse.type-arg + ) + eval "$ZSHPARSEARGS" + + ########################################## + + scwrypts.virtualenv.common.validate-controller "${TYPE}" \ + || echo.error "no environment controller exists for ${TYPE}" \ + || return 1 + + : \ + && virtualenv.${TYPE}.create \ + && virtualenv.${TYPE}.activate \ + && virtualenv.${TYPE}.update \ + && virtualenv.${TYPE}.deactivate \ + && echo.success "virtualenv '${TYPE}' up-to-date" \ + || echo.error "failed to update '${TYPE}' virtualenv (see errors above)" \ + ; +} + +##################################################################### diff --git a/zsh/scwrypts/virtualenv/virtualenv.module.zsh b/zsh/scwrypts/virtualenv/virtualenv.module.zsh new file mode 100644 index 0000000..8a3618a --- /dev/null +++ b/zsh/scwrypts/virtualenv/virtualenv.module.zsh @@ -0,0 +1,12 @@ +# +# library to manage virtual environments for various scwrypts +# runtime types +# + + +# create / update virtual environments +use scwrypts/virtualenv/update + + +# delete virtual environments +use scwrypts/virtualenv/delete diff --git a/zsh/scwrypts/virtualenv/zshparse.module.zsh b/zsh/scwrypts/virtualenv/zshparse.module.zsh new file mode 100644 index 0000000..01b12ff --- /dev/null +++ b/zsh/scwrypts/virtualenv/zshparse.module.zsh @@ -0,0 +1,24 @@ +##################################################################### + +${scwryptsmodule}.type-arg() { + # local TYPE ARGS=() # relies on default "args" parser + return 0 +} + +${scwryptsmodule}.type-arg.usage() { + USAGE__args=" + \$1 virtual environment type (one of ${SCWRYPTS_VIRTUALENV__AVAILABLE_VIRTUALENVS[@]}) + " +} + +${scwryptsmodule}.type-arg.validate() { + TYPE="${ARGS[1]}" + + [[ ${#ARGS} -gt 1 ]] \ + && echo.error "too many arguments" + + [ "${TYPE}" ] \ + || echo.error "must specify virtualenv type" +} + +##################################################################### diff --git a/zsh/system/config/settings b/zsh/system/config/settings deleted file mode 100755 index 9eebcbf..0000000 --- a/zsh/system/config/settings +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use system/config -##################################################################### - -MAIN() { - EDIT "$CONFIG__USER_SETTINGS" -} diff --git a/zsh/system/config/symlinks b/zsh/system/config/symlinks deleted file mode 100755 index a158447..0000000 --- a/zsh/system/config/symlinks +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/zsh -use system/config -##################################################################### - -MAIN() { - while read SYMLINK - do - SETUP_SYMLINK $(echo $SYMLINK | awk '{print $1;}') $(echo $SYMLINK | awk '{print $2}') - done < <(echo $SYMLINKS | sed -n '/^[^#]/p') -} - -##################################################################### - -SETUP_SYMLINK() { - [ ! $2 ] && FAIL 1 'must provide SOURCE_CONFIG and TARGET_CONFIG' - - local SOURCE_CONFIG="$1" - local TARGET_CONFIG="$HOME/.config/$2" - - [ ! -f "$SOURCE_CONFIG" ] && [ ! -d "$SOURCE_CONFIG" ] && [ -f "$TARGET_CONFIG" ] && { - DEBUG 'SOURCE_CONFIG is not tracked; copying from TARGET_CONFIG' - mkdir -p "$(dirname "$SOURCE_CONFIG")" - cp "$TARGET_CONFIG" "$SOURCE_CONFIG" - } - [ ! -f "$SOURCE_CONFIG" ] && [ ! -d "$SOURCE_CONFIG" ] && { - WARNING "no such file or directory '$SOURCE_CONFIG'" - return 0 - } - - [ ! -d $(dirname "$TARGET_CONFIG") ] && mkdir -p $(dirname "$TARGET_CONFIG") - - [[ $SAFE_SYMLINKS -eq 1 ]] \ - && mv "$TARGET_CONFIG" "$TARGET_CONFIG.bak" >/dev/null 2>&1 - - rm "$TARGET_CONFIG" >/dev/null 2>&1 - - ln -s "$SOURCE_CONFIG" "$TARGET_CONFIG" \ - && SUCCESS "successfully linked '$(basename $(dirname $TARGET_CONFIG))/$(basename $TARGET_CONFIG)'" \ - || FAIL 3 "failed to create link '$TARGET_CONFIG'" \ - ; -} diff --git a/zsh/system/config/terminfo b/zsh/system/config/terminfo deleted file mode 100755 index 119c871..0000000 --- a/zsh/system/config/terminfo +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/zsh -DEPENDENCIES+=(tic) - -use system/config -##################################################################### - -MAIN() { - [ ! $TERMINFO_PATH ] && return 0 - [ ! -d $TERMINFO_PATH ] && FAIL 1 "TERMINFO_PATH='$TERMINFO_PATH' does not exist" - - local ERRORS=0 - for TERMINFO in $(find $TERMINFO_PATH -type f) - do - tic -x $TERMINFO >/dev/null 2>&1 \ - && SUCCESS "added '$(basename $TERMINFO)'" \ - || ERROR "failed to add '$(basename $TERMINFO)'" \ - ; - done - - CHECK_ERRORS -} diff --git a/zsh/system/config/update b/zsh/system/config/update deleted file mode 100755 index 5976380..0000000 --- a/zsh/system/config/update +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/zsh -use scwrypts/meta -##################################################################### - -MAIN() { - STATUS 'updating all config files and links' - SCWRYPTS__RUN --name system/config/symlinks --group scwrypts --type zsh || exit 1 - SCWRYPTS__RUN --name system/config/terminfo --group scwrypts --type zsh || exit 2 - SUCCESS 'finished updating config files and links' -} diff --git a/zsh/system/git-package-installer/build.module.zsh b/zsh/system/git-package-installer/build.module.zsh new file mode 100644 index 0000000..3fd0ad9 --- /dev/null +++ b/zsh/system/git-package-installer/build.module.zsh @@ -0,0 +1,69 @@ +##################################################################### + +use system/git-package-installer/zshparse + +##################################################################### + +${scwryptsmodule}() { + local \ + GIT_REPOSITORY_URL LOCAL_NAME INSTALLATION_BASE_PATH \ + UPDATE=false MAKE_CLEAN=false \ + PASSTHROUGH_ARGS=() \ + PARSERS=( + system.git-package-installer.zshparse + ) + + eval "$ZSHPARSEARGS" + + ########################################## + + [ -d "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" ] || { + system.git-package-installer.clone ${PASSTHROUGH_ARGS[@]} \ + || return 1 + } + + local INSTALLER + [ -f "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}/Makefile" ] && INSTALLER=make + [ -f "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}/PKGBUILD" ] && INSTALLER=makepkg + + case ${INSTALLER} in + ( make | makepkg ) + echo.status "installing '${LOCAL_NAME}'" + system.git-package-installer.build.${INSTALLER} + ;; + ( * ) + echo.warning 'could not detect supported installation method' + echo.reminder "complete manual installation here:\n${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" + ;; + esac +} + +##################################################################### + +${scwryptsmodule}.make() { + utils.dependencies.check make || return 1 + ( + cd "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" + [[ ${MAKE_CLEAN} =~ true ]] && make clean + + : \ + && make \ + && utils.io.getsudo \ + && sudo make install \ + && echo.success "succesfully installed '${LOCAL_NAME}'" \ + || echo.error "failed to install '${LOCAL_NAME}' (see above)" \ + ; + ) +} + +${scwryptsmodule}.makepkg() { + utils.dependencies.check makepkg || return 1 + ( + cd "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" + + yes | makepkg -si \ + && echo.success "succesfully installed '${LOCAL_NAME}'" \ + || echo.error "failed to install '${LOCAL_NAME}' (see above)" \ + ; + ) +} diff --git a/zsh/system/git-package-installer/clone.module.zsh b/zsh/system/git-package-installer/clone.module.zsh new file mode 100644 index 0000000..c03d141 --- /dev/null +++ b/zsh/system/git-package-installer/clone.module.zsh @@ -0,0 +1,31 @@ +##################################################################### + +use system/git-package-installer/zshparse + +DEPENDENCIES+=(git) + +##################################################################### + +${scwryptsmodule}() { + local \ + GIT_REPOSITORY_URL LOCAL_NAME INSTALLATION_BASE_PATH \ + UPDATE=false MAKE_CLEAN=false \ + PASSTHROUGH_ARGS=() \ + PARSERS=( + system.git-package-installer.zshparse + ) + + eval "$ZSHPARSEARGS" + + [ -d "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}/.git" ] \ + && echo.success "already cloned '${LOCAL_NAME}'" \ + && return 0 \ + ; + + ########################################## + + git clone "${GIT_REPOSITORY_URL}" "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" \ + && echo.success "successfully cloned '${LOCAL_NAME}'\ninstall dir : ${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" \ + || echo.error "failed to clone '${LOCAL_NAME}'" \ + ; +} diff --git a/zsh/system/git-package-installer/git-package-installer.module.zsh b/zsh/system/git-package-installer/git-package-installer.module.zsh new file mode 100644 index 0000000..d08e63b --- /dev/null +++ b/zsh/system/git-package-installer/git-package-installer.module.zsh @@ -0,0 +1,11 @@ +# +# install packages from source +# + +# basic installation steps +use system/git-package-installer/clone +use system/git-package-installer/pull +use system/git-package-installer/build + +# common argument parser +use system/git-package-installer/zshparse diff --git a/zsh/system/git-package-installer/install b/zsh/system/git-package-installer/install new file mode 100755 index 0000000..80e73ce --- /dev/null +++ b/zsh/system/git-package-installer/install @@ -0,0 +1,27 @@ +#!/usr/bin/env zsh +use system/git-package-installer +##################################################################### + +system.git-package-installer.zshparse.usage + +##################################################################### + +MAIN() { + local \ + GIT_REPOSITORY_URL LOCAL_NAME INSTALLATION_BASE_PATH \ + UPDATE=false SKIP_BUILD=false SKIP_PULL=false MAKE_CLEAN=false \ + PASSTHROUGH_ARGS=() \ + PARSERS=( + system.git-package-installer.zshparse + ) + + eval "$ZSHPARSEARGS" + + ########################################## + + : \ + && system.git-package-installer.clone ${PASSTHROUGH_ARGS[@]} \ + && system.git-package-installer.pull ${PASSTHROUGH_ARGS[@]} \ + && system.git-package-installer.build ${PASSTHROUGH_ARGS[@]} \ + ; +} diff --git a/zsh/system/git-package-installer/pull.module.zsh b/zsh/system/git-package-installer/pull.module.zsh new file mode 100644 index 0000000..2d9a9e3 --- /dev/null +++ b/zsh/system/git-package-installer/pull.module.zsh @@ -0,0 +1,33 @@ +##################################################################### + +use system/git-package-installer/zshparse + +DEPENDENCIES+=(git) + +##################################################################### + +${scwryptsmodule}() { + local \ + GIT_REPOSITORY_URL LOCAL_NAME INSTALLATION_BASE_PATH \ + UPDATE=false MAKE_CLEAN=false \ + PASSTHROUGH_ARGS=() \ + PARSERS=( + system.git-package-installer.zshparse + ) + + eval "$ZSHPARSEARGS" + + [[ $UPDATE =~ false ]] \ + && echo.success "no update requested" \ + && return 0 \ + ; + + ########################################## + + local TARGET_BRANCH=$(git -C "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" rev-parse --abbrev-ref HEAD) + + git -C "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" pull origin ${TARGET_BRANCH} \ + && echo.success "successfully updated '${LOCAL_NAME}'" \ + || echo.error "failed to update '${LOCAL_NAME}'" \ + ; +} diff --git a/zsh/system/git-package-installer/zshparse.module.zsh b/zsh/system/git-package-installer/zshparse.module.zsh new file mode 100644 index 0000000..0f6b756 --- /dev/null +++ b/zsh/system/git-package-installer/zshparse.module.zsh @@ -0,0 +1,81 @@ +##################################################################### + +DEPENDENCIES+=(git) + +##################################################################### + +${scwryptsmodule}() { + # local GIT_REPOSITORY_URL LOCAL_NAME INSTALLATION_BASE_PATH + # local UPDATE=false MAKE_CLEAN=false + # local PASSTHROUGH_ARGS=() + local PARSED=0 + + case $1 in + ( -t | --target-url ) + PARSED=2 + GIT_REPOSITORY_URL="$2" + # PASSTHROUGH_ARGS+=() included in .validate() + ;; + + ( -n | --local-name ) + PARSED=2 + LOCAL_NAME="$2" + # PASSTHROUGH_ARGS+=() included in .validate() + ;; + + ( -u | --update ) PARSED=1; PASSTHROUGH_ARGS+=(-u); UPDATE=true ;; + ( -c | --make-clean ) PARSED=1; PASSTHROUGH_ARGS+=(-c); MAKE_CLEAN=true ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.usage() { + USAGE__options+=' + -t, --target-url target git repository address for build source + -n, --local-name (optional) override the default git-clone name for local directory + + -u, --update if package exists, update using current branch + -c, --make-clean when using a "make" target, invoke "make clean" before (re)build/install + ' +} + +${scwryptsmodule}.validate() { + INSTALLATION_BASE_PATH="${XDG_DATA_HOME:-${HOME}/.local/share}/git-packages-source" + mkdir -p -- "${INSTALLATION_BASE_PATH}" + + [ ! ${GIT_REPOSITORY_URL} ] && [ ! ${LOCAL_NAME} ] && { + UPDATE=true + LOCAL_NAME=$(\ + cd "${INSTALLATION_BASE_PATH}"; \ + find . -mindepth 1 -maxdepth 1 -type d \ + | sed 's|^\./||' \ + | utils.fzf 'select a package to update' \ + ) + + [ ${LOCAL_NAME} ] \ + || echo.error '--target-url or --local-name required' \ + || return \ + ; + } + + [ ! "${GIT_REPOSITORY_URL}" ] && [ "${LOCAL_NAME}" ] && [ -d "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}/.git" ] && { + GIT_REPOSITORY_URL="$(\ + git -C "${INSTALLATION_BASE_PATH}/${LOCAL_NAME}" remote -v \ + | grep ^origin.*(fetch)$ \ + | awk '{print $2;}' \ + | head -n 1 \ + )" + } + + [ "${GIT_REPOSITORY_URL}" ] && [ ! "${LOCAL_NAME}" ] && { + LOCAL_NAME="$(basename -- "${GIT_REPOSITORY_URL}" | sed 's/\.git$//')" + } + + [ "${GIT_REPOSITORY_URL}" ] && [ "${LOCAL_NAME}" ] \ + || echo.error "couldn't determine URL automatically\n('${LOCAL_NAME}' must be installed at '${INSTALLATION_BASE_PATH}/${LOCAL_NAME}')" + + PASSTHROUGH_ARGS+=(-t "${GIT_REPOSITORY_URL}" -n "${LOCAL_NAME}") +} + +##################################################################### diff --git a/zsh/system/packages/build b/zsh/system/packages/build deleted file mode 100755 index 470ae87..0000000 --- a/zsh/system/packages/build +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use scwrypts/meta -##################################################################### - -MAIN() { - SCWRYPTS__RUN --name system/packages/install --group scwrypts --type zsh -- --only-build $@ -} diff --git a/zsh/system/packages/download b/zsh/system/packages/download deleted file mode 100755 index 87bb3f9..0000000 --- a/zsh/system/packages/download +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use scwrypts/meta -##################################################################### - -MAIN() { - SCWRYPTS__RUN --name system/packages/install --group scwrypts --type zsh -- --only-pull $@ -} diff --git a/zsh/system/packages/install b/zsh/system/packages/install deleted file mode 100755 index 7427745..0000000 --- a/zsh/system/packages/install +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/zsh -use system/packages/git -##################################################################### - -MAIN() { - local USAGE=" - usage: [...options...] - - options - -t, --target-url target URL; required for first-time download - -n, --local-name local name for package (optional) - - -u, --update if package exists, update without prompt - -b, --only-build if package exists, skip update step and only build - -p, --only-pull skip the automated build step - -c, --clean for make, run make clean before build - - -h, --help print this message and exit - " - local NAME - local TARGET - - local SKIP_BUILD=0 - local SKIP_PULL=0 - local UPDATE=0 - local CLEAN=0 - - while [[ $# -gt 0 ]] - do - case $1 in - -t | --target-url ) TARGET="$2"; shift 1 ;; - -n | --local-name ) NAME="$2"; shift 1 ;; - - -u | --update ) UPDATE=1 ;; - -b | --only-build ) SKIP_PULL=1 ;; - -p | --only-pull ) SKIP_BUILD=1 ;; - -c | --clean ) CLEAN=1 ;; - - -h | --help ) USAGE; exit 0 ;; - - -* ) ERROR "unknown argument '$1'" ;; - - * ) [ ! $TARGET ] && TARGET="$1" \ - || ERROR "extra positional argument '$1'" \ - ; - ;; - esac - shift 1 - done - - [[ $SKIP_PULL -eq 1 ]] && [[ $SKIP_BUILD -eq 1 ]] && ERROR 'only one of [-b | -p] can be specified' - - [ ! $TARGET ] && [ ! $NAME ] && { - [[ $SKIP_BUILD -eq 1 ]] && { - ERROR 'cannot skip build without specifying package local-name' - } || { - UPDATE=1 - NAME=$(ls "$PACKAGE_INSTALL_DIR" | FZF 'select a package to update') - [ ! $NAME ] && ERROR 'target-url required' - } - } - - CHECK_ERRORS - - #################################################### - - [ ! $NAME ] && { - NAME=$(echo $TARGET | sed 's/.*\///; s/\.git$//') - DEBUG "using default name '$NAME'" - } - - [ -d "$PACKAGE_INSTALL_DIR/$NAME" ] && [[ $SKIP_PULL -eq 0 ]] && { - [[ $UPDATE -eq 0 ]] && Yn "package '$NAME' already exists; update now?" && UPDATE=1 - [[ $UPDATE -eq 1 ]] && PULL || return 1 - } - - [ ! -d "$PACKAGE_INSTALL_DIR/$NAME" ] && { - CLONE || return 2 - } - - [[ $SKIP_BUILD -eq 1 ]] && return 0 - BUILD -} diff --git a/zsh/system/packages/update b/zsh/system/packages/update deleted file mode 100755 index c5c7a1f..0000000 --- a/zsh/system/packages/update +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use scwrypts/meta -##################################################################### - -MAIN() { - SCWRYPTS__RUN --name system/packages/install --group scwrypts --type zsh -- --update $@ -} diff --git a/zsh/system/vim/vundle/edit-build-actions b/zsh/system/vim/vundle/edit-build-actions deleted file mode 100755 index d76c3f4..0000000 --- a/zsh/system/vim/vundle/edit-build-actions +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use system/vim/vundle -##################################################################### - -MAIN() { - EDIT "$VUNDLE__BUILD_DEFINITIONS" -} diff --git a/zsh/system/vim/vundle/install b/zsh/system/vim/vundle/install deleted file mode 100755 index f382baa..0000000 --- a/zsh/system/vim/vundle/install +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/zsh -use system/vim/vundle -##################################################################### - -MAIN() { - [ -d "$HOME/.vim/bundle/Vundle.vim" ] || { - mkdir -p "$HOME/.vim/bundle/" - git clone https://github.com/VundleVim/Vundle.vim.git "$HOME/.vim/bundle/Vundle.vim" - } - - VUNDLE__PLUGIN_INSTALL || return 1 - VUNDLE__REBUILD_PLUGINS || return 2 -} diff --git a/zsh/system/vim/vundle/rebuild b/zsh/system/vim/vundle/rebuild deleted file mode 100755 index a8689bb..0000000 --- a/zsh/system/vim/vundle/rebuild +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/zsh -use system/vim/vundle -##################################################################### - -MAIN() { - VUNDLE__REBUILD_PLUGINS $@ -} diff --git a/zsh/unittest/execute-test-file.module.zsh b/zsh/unittest/execute-test-file.module.zsh new file mode 100644 index 0000000..df7c22d --- /dev/null +++ b/zsh/unittest/execute-test-file.module.zsh @@ -0,0 +1,51 @@ +##################################################################### + +use unittest/operations + +##################################################################### + +${scwryptsmodule}() { + local ERRORS=0 TEST_ERRORS=0 + [ "$SCWRYPTS_LOG_LEVEL" ] || SCWRYPTS_LOG_LEVEL=4 + + local UNITTESTS=($(echo "${(k)functions}" | sed 's/ /\n/g' | grep '^test\.' | sort)) + [[ ${#UNITTESTS[@]} -gt 0 ]] \ + || echo.error "must define at least one unittest" \ + || return 1 + + echo.status "${SCWRYPTS_TEST_MODULE_STRING}starting test suite" + + local UNITTEST_RESULTS_DIR="${SCWRYPTS_TEMP_PATH}/test" + mkdir -p "${UNITTEST_RESULTS_DIR}" + + local TEST_COUNT=0 + + command -v beforeall &>/dev/null && beforeall + + local UNITTEST + for UNITTEST in ${UNITTESTS[@]} + do + ((TEST_COUNT+=1)) + ERRORS=0 + command -v beforeeach &>/dev/null && beforeeach + + ${UNITTEST} &> "${UNITTEST_RESULTS_DIR}/${UNITTEST}.txt" \ + && echo.success "${SCWRYPTS_TEST_MODULE_STRING}${UNITTEST}" \ + || { echo.error "${SCWRYPTS_TEST_MODULE_STRING}${UNITTEST}"; ((TEST_ERRORS+=1)); echo "--- begin test output ---">&2; cat "${UNITTEST_RESULTS_DIR}/${UNITTEST}.txt"; echo "--- end test output ---\n">&2; } + + command -v aftereach &>/dev/null && aftereach + + unittest.operations restore + unittest.mock.env.restore + done + + command -v afterall &>/dev/null && afterall + + local EXIT_CODE=$TEST_ERRORS + [[ $TEST_ERRORS -eq 0 ]] \ + && echo.success "${SCWRYPTS_TEST_MODULE_STRING}passed ${TEST_COUNT} / ${TEST_COUNT} test(s)" \ + || echo.error "${SCWRYPTS_TEST_MODULE_STRING}failed ${EXIT_CODE} / ${TEST_COUNT} test(s)" \ + ; + + return $EXIT_CODE +} diff --git a/zsh/unittest/mock/create.module.zsh b/zsh/unittest/mock/create.module.zsh new file mode 100644 index 0000000..4761a9e --- /dev/null +++ b/zsh/unittest/mock/create.module.zsh @@ -0,0 +1,196 @@ +##################################################################### + +DEPENDENCIES+=(sed) + +##################################################################### + +# +# "mocking" is critical to unittesting workflows, and although this +# provides a preliminary implementation idea for "mocking" in ZSH, +# this is very new and subject to change +# +# for critical workflows, though, some limited tests are way better +# than no tests at all! +# +# known issues: +# - callstack assertions are never set when the function call is +# a non-terminal member of a pipestream; for example: +# +# unittest.mock func-a --stdout asdf +# +# func-a | grep -q "asdf" +# ^ grep will succeed, indicating the mock worked +# +# func-a.assert.called +# ^ will fail; I guess pipe streams are executed in a subshell +# where export doesn't work as expected? +# + +MOCKS=() +${scwryptsmodule}() { + local DESCRIPTION=" + (beta) generates a function mock for basic ZSH unit testing + " + eval "$(utils.parse.autosetup)" + + ########################################## + + export MOCK__ORIGINAL_IMPLEMENTATION__${FUNCTION_VARIABLE}="$(which ${FUNCTION})" + + [ "${STDOUT}" ] && export MOCK__STDOUT__${FUNCTION_VARIABLE}="${STDOUT}" + [ "${STDERR}" ] && export MOCK__STDERR__${FUNCTION_VARIABLE}="${STDERR}" + + [ ${EXIT_CODE} ] || EXIT_CODE=0 + export MOCK__EXIT_CODE__${FUNCTION_VARIABLE}=${EXIT_CODE} + + ########################################## + + # tricky! in order to set the ${FUNCTION} as literal within zsh functions, we need + # to run all the test definitions as an eval line :S + + eval " + + export MOCK__CALLSTACK__${FUNCTION_VARIABLE}=() + export MOCK__CALLCOUNT__${FUNCTION_VARIABLE}=0 + + ${FUNCTION}() { + MOCK__CALLSTACK__${FUNCTION_VARIABLE}+=(\"\$@\") + ((MOCK__CALLCOUNT__${FUNCTION_VARIABLE}+=1)) + + printf \"\$MOCK__STDOUT__${FUNCTION_VARIABLE}\" + printf \"\$MOCK__STDERR__${FUNCTION_VARIABLE}\" >&2 + + return \$(eval echo '\$MOCK__EXIT_CODE__'${FUNCTION_VARIABLE}) + } + + ${FUNCTION}.assert.called() { + local ERRORS=0 + [[ MOCK__CALLCOUNT__${FUNCTION_VARIABLE} -gt 0 ]] \ + || echo.error \"${FUNCTION} was not called\" + } + + ${FUNCTION}.assert.not.called() { + local ERRORS=0 + ${FUNCTION}.assert.called &>/dev/null + [[ \$? -ne 0 ]] \ + || echo.error \"${FUNCTION} was called\" + } + + ${FUNCTION}.assert.callstack() { + local ERRORS=0 + [[ \"\$@\" =~ ^\${MOCK__CALLSTACK__${FUNCTION_VARIABLE}}$ ]] \ + || echo.error \"${FUNCTION} callstack does not match\nexpected : \$@\nreceived : \${MOCK__CALLSTACK__${FUNCTION_VARIABLE}}\" + } + + ${FUNCTION}.assert.callstackincludes() { + local ERRORS=0 + [[ \${MOCK__CALLSTACK__${FUNCTION_VARIABLE}} =~ \$@ ]] \ + || echo.error \"${FUNCTION} callstack does not include\nexpected : \$@\ncallstack : \${MOCK__CALLSTACK__${FUNCTION_VARIABLE}}\" + } + + ${FUNCTION}.reset() { + unset \ + MOCK__CALLSTACK__${FUNCTION_VARIABLE} \ + MOCK__CALLCOUNT__${FUNCTION_VARIABLE} \ + ; + } + + ${FUNCTION}.restore() { + MOCKS=(\$(echo \"\$MOCKS\" | sed 's/\s\+/\n/g' | grep -v \"^${FUNCTION}$\")) + + unset \ + MOCK__CALLSTACK__${FUNCTION_VARIABLE} \ + MOCK__CALLCOUNT__${FUNCTION_VARIABLE} \ + ; + + unset -f \ + ${FUNCTION} \ + ${FUNCTION}.assert.called \ + ${FUNCTION}.assert.not.called \ + ${FUNCTION}.assert.callstack \ + ${FUNCTION}.assert.callstackincludes \ + ${FUNCTION}.reset \ + ${FUNCTION}.restore \ + ; + + local ORIGINAL_IMPLEMENTATION=\"\$(eval echo '\$MOCK__ORIGINAL_IMPLEMENTATION__'${FUNCTION_VARIABLE})\" + [[ \$(echo \"\$ORIGINAL_IMPLEMENTATION\" | wc -l) -gt 1 ]] \ + && eval \"\$ORIGINAL_IMPLEMENTATION\" + + unset ORIGINAL__IMPLEMENTATION__${FUNCTION_VARIABLE} + } + " + + MOCKS+=(${FUNCTION}) +} + +##################################################################### + +${scwryptsmodule}.parse.locals() { + local FUNCTION + local FUNCTION_VARIABLE + local STDOUT + local STDERR + local EXIT_CODE +} + +${scwryptsmodule}.parse() { + # local FUNCTION STDOUT STDERR EXIT_CODE + local PARSED=0 + + case $1 in + ( --stdout ) + PARSED=2 + STDOUT="$2" + ;; + + ( --stderr ) + PARSED=2 + STDERR="$2" + ;; + + ( --exit-code ) + PARSED=2 + EXIT_CODE="$2" + ;; + + ( * ) [[ ${POSITIONAL_ARGS} -gt 0 ]] && return 0 + ((POSITIONAL_ARGS+=1)) + PARSED=1 + case ${POSITIONAL_ARGS} in + ( 1 ) FUNCTION="$1" ;; + esac + ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.parse.usage() { + USAGE__usage+=' function [...options...]' + + USAGE__args+=' + function the function to be mocked + ' + + USAGE__options+=' + --stdout mock the stdout output for the call + --stderr mock the stdout output for the call + --exit-code mock the exit code for the call + ' +} + +${scwryptsmodule}.parse.validate() { + FUNCTION_VARIABLE="$(echo "${FUNCTION}" | sed 's/\./___/g; s/-/_____/g')" + [ "${FUNCTION_VARIABLE}" ] || echo.error "failed to determine safe variable name for '${FUNCTION}'" + + [ ${FUNCTION} ] && command -v ${FUNCTION} &>/dev/null || { + [[ $(eval echo "\$MOCK_UNCALLABLE_WARNING_ISSUED__${FUNCTION_VARIABLE}") =~ true ]] || { + echo.warning "mocking uncallable '${FUNCTION}'" + export MOCK_UNCALLABLE_WARNING_ISSUED__${FUNCTION_VARIABLE}=true + } + } + + echo "${MOCKS}" | sed 's/\s\+/\n/g' | grep -q "^${FUNCTION}$" \ + && echo.error "cannot mock '${FUNCTION}' (it is already mocked)" +} diff --git a/zsh/unittest/mock/env.module.zsh b/zsh/unittest/mock/env.module.zsh new file mode 100644 index 0000000..9e69c29 --- /dev/null +++ b/zsh/unittest/mock/env.module.zsh @@ -0,0 +1,85 @@ +##################################################################### + +DEPENDENCIES+=(sed) + +##################################################################### + +MOCKED_ENV=() +${scwryptsmodule}() { + local DESCRIPTION=" + (beta) mocks an environment variable for testing + " + eval "$(utils.parse.autosetup)" + + ########################################## + + MOCKED_ENV+=(${ENVIRONMENT_VARIABLE_NAME}) + + export ${ENVIRONMENT_VARIABLE_NAME}__original_value="${(P)ENVIRONMENT_VARIABLE_NAME}" + export ${ENVIRONMENT_VARIABLE_NAME}=${ENVIRONMENT_VARIABLE_VALUE} +} + +${scwryptsmodule}.restore() { + local ENVIRONMENT_VARIABLE_NAME ORIGINAL_VALUE + for ENVIRONMENT_VARIABLE_NAME in ${MOCKED_ENV[@]} + do + ORIGINAL_VALUE="$(eval echo '$'$ENVIRONMENT_VARIABLE_NAME'__original_value')" + [ "$ORIGINAL_VALUE" ] \ + && export ${ENVIRONMENT_VARIABLE_NAME}="$ORIGINAL_VALUE" \ + || unset ${ENVIRONMENT_VARIABLE_NAME} \ + ; + + unset ${ENVIRONMENT_VARIABLE_NAME}__checked 2>/dev/null + done + MOCKED_ENV=() +} + +##################################################################### + +${scwryptsmodule}.parse.locals() { + local ENVIRONMENT_VARIABLE_NAME + local ENVIRONMENT_VARIABLE_VALUE +} + +${scwryptsmodule}.parse() { + local PARSED=0 + + case $1 in + ( --value ) + PARSED=2 + ENVIRONMENT_VARIABLE_VALUE="$2" + ;; + + ( * ) + [[ $POSITIONAL_ARGS -gt 0 ]] && return 0 + ((POSITIONAL_ARGS+=1)) + PARSED=1 + case $POSITIONAL_ARGS in + ( 1 ) ENVIRONMENT_VARIABLE_NAME="$1" + ;; + esac + ;; + esac + + return $PARSED +} + +${scwryptsmodule}.parse.usage() { + USAGE__usage+=' function [...options...]' + + USAGE__args+=' + name the name of the environment variable + ' + + USAGE__options+=' + --value the value of the environment variable + ' +} + +${scwryptsmodule}.parse.validate() { + [ "$ENVIRONMENT_VARIABLE_NAME" ] \ + || echo.error "no environment variable specified" + + echo "$MOCKED_ENV" | sed 's/\s\+/\n/g' | grep -q "^$ENVIRONMENT_VARIABLE_NAME$" \ + && echo.error "environment variable '$ENVIRONMENT_VARIABLE_NAME' has already been mocked" +} diff --git a/zsh/unittest/mock/mock.module.zsh b/zsh/unittest/mock/mock.module.zsh new file mode 100644 index 0000000..965f8e3 --- /dev/null +++ b/zsh/unittest/mock/mock.module.zsh @@ -0,0 +1,10 @@ +# +# function mocking utilities for ZSH unit testing +# + +# primary mock generator +use unittest/mock/create +eval "${scwryptsmodule}() { ${scwryptsmodule}.create \$@; }" + +# mock environment variables +use unittest/mock/env diff --git a/zsh/unittest/operations.module.zsh b/zsh/unittest/operations.module.zsh new file mode 100644 index 0000000..0dd8e16 --- /dev/null +++ b/zsh/unittest/operations.module.zsh @@ -0,0 +1,38 @@ +##################################################################### + +${scwryptsmodule}() { + local DESCRIPTION=" + allows batch operations against existing mocks for lib/test/unittest + " + eval "$(utils.parse.autosetup)" + + ########################################## + + local MOCK + for MOCK in ${MOCKS[@]} + do + ${MOCK}.${OPERATION} + done +} + +##################################################################### + +${scwryptsmodule}.locals() { + local OPERATION +} + +${scwryptsmodule}.parse() { + local PARSED=0 + + case $1 in + ( restore | reset ) PARSED=1; OPERATION="$1" ;; + esac + + return ${PARSED} +} + +${scwryptsmodule}.parse.usage() { + USAGE__args+=' + $1 one of (restore reset) to perform on all active mocks + ' +} diff --git a/zsh/unittest/run b/zsh/unittest/run new file mode 100755 index 0000000..e5ffbc3 --- /dev/null +++ b/zsh/unittest/run @@ -0,0 +1,68 @@ +#!/usr/bin/env zsh +##################################################################### + +use scwrypts/meta + +##################################################################### + +USAGE__description=" + runs tests across scwrypts zsh modules (beta) +" + +USAGE__args=' + $@ paths or lookup patterns to test +' + +##################################################################### + +MAIN() { + local \ + ARGS=() \ + PARSERS=() + + eval "$ZSHPARSEARGS" + + ########################################## + + local MODE + [[ ${#ARGS[@]} -eq 0 ]] \ + && MODE=all \ + || MODE=filter \ + ; + + local TEST_FILES="" GROUP + for GROUP in ${SCWRYPTS_GROUPS[@]} + do + TEST_FILES+="$(find "$(scwrypts.config.group ${GROUP} root)" -type f -name \*.test.zsh)" + done + + for FILTER in ${ARGS[@]} + do + TEST_FILES="$(echo "${TEST_FILES}" | grep "${FILTER}")" + done + + local SCWRYPTS_CONFIG="$(scwrypts.meta.run --config)" + local TEST_FILE + local TEST_SUITE_COUNT=0 TEST_SUITE_FAILED_COUNT=0 + for TEST_FILE in $(echo "${TEST_FILES}") + do + ((TEST_SUITE_COUNT+=1)) + local TEST_SUITE_NAME="$(basename -- "$(dirname -- ${TEST_FILE})")/$(basename -- "${TEST_FILE}")" + zsh <<< " + () { + local ERRORS=0 + local CI=true + $SCWRYPTS_CONFIG + source '$TEST_FILE' + use unittest/execute-test-file + utils.check-environment + SUPPRESS_USAGE_OUTPUT=true SCWRYPTS_TEST_MODULE_STRING=\"${TEST_SUITE_NAME} : \" unittest.execute-test-file + } + " || ((TEST_SUITE_FAILED_COUNT+=1)) + done + + [[ ${TEST_SUITE_FAILED_COUNT} -eq 0 ]] \ + && echo.success "\nsuccessfully passed ${TEST_SUITE_COUNT} / ${TEST_SUITE_COUNT} test suite(s)\n " \ + || echo.error "\nfailed ${TEST_SUITE_FAILED_COUNT} / ${TEST_SUITE_COUNT} test suite(s)\n " \ + ; +} diff --git a/zsh/unittest/test/provides.module.zsh b/zsh/unittest/test/provides.module.zsh new file mode 100644 index 0000000..bd51579 --- /dev/null +++ b/zsh/unittest/test/provides.module.zsh @@ -0,0 +1,8 @@ +${scwryptsmodule}() { + local ERRORS=0 + [ $1 ] \ + || echo.error "must specify a function name to provide" \ + || return 2 + + command -v $1 || echo.error "missing '$1'" +} diff --git a/zsh/unittest/test/test.module.zsh b/zsh/unittest/test/test.module.zsh new file mode 100644 index 0000000..a87910b --- /dev/null +++ b/zsh/unittest/test/test.module.zsh @@ -0,0 +1,9 @@ +# +# common logic used in testing +# + +# use uuidgen for random string generation +DEPENDENCIES+=(uuidgen) + +# ensure a module provides a function by name +use unittest/test/provides diff --git a/zsh/unittest/unittest.module.zsh b/zsh/unittest/unittest.module.zsh new file mode 100644 index 0000000..3397ce6 --- /dev/null +++ b/zsh/unittest/unittest.module.zsh @@ -0,0 +1,30 @@ +# +# (beta) module for performing unit tests on scwrypts zsh modules +# + +# provides function and environment variable mocking (+ some assertions) +use unittest/mock + +# provides common logic used in testing +use unittest/test + +# +# create a test file to match your module name +# ├── my-thing.module.zsh +# └── my-thing.test.zsh +# +# add the import line 'use unittest' +# +# define tests by creating functions called 'test.your-test-name()' +# - the test "passes" on successful return code (e.g. 'return 0') +# - the test "fails" on any other return code +# +# some other testing features implemented: +# - defining 'beforeall()' < executed before the test suite runs +# - defining 'beforeeach()' < executed before each test function +# - defining 'aftereach()' < executed after each test function +# - defining 'afterall()' < executed after the test suite completes +# +# using 'scwrypts unittest run' will run each test suite in an isolated +# subshell, so configurations are not persisted between test files +# diff --git a/zsh/lib/utils/README.md b/zsh/utils/README.md similarity index 92% rename from zsh/lib/utils/README.md rename to zsh/utils/README.md index 9927c65..b87c08e 100644 --- a/zsh/lib/utils/README.md +++ b/zsh/utils/README.md @@ -9,9 +9,9 @@ Doing so will *also* check for path dependencies and required environment variab ```shell -#!/bin/zsh +#!/usr/bin/env zsh source ./path/to/utils.plugin.zsh -SUCCESS 'ZSH utilities online!' +echo.success 'ZSH utilities online!' ``` Checkout [io](./io.zsh) and [os](./os.zsh) for available simple functions. @@ -26,14 +26,14 @@ Include a dependency by adding to the `DEPENDENCIES` array. If any dependencies are missing, `source utils.module.zsh` will return an error code and count the number of missing dependencies in the variable `DEP_ERROR_COUNT`. ```shell -#!/bin/zsh +#!/usr/bin/env zsh DEPENDENCIES+=( path-executable-1 path-executable-2 /path/to/arbitrary/program ) source ./path/to/utils.plugin.zsh -echo "missing $DEP_ERROR required dependencies" +echo "missing $DEP_echo.error required dependencies" ``` ### Environment @@ -47,7 +47,7 @@ If any environment variables are missing, `source utils.module.zsh` will return Missing environment variables will be added to the environment template (*exclusive to Scwrypts*). ```shell -#!/bin/zsh +#!/usr/bin/env zsh REQUIRED_ENV+=( AWS_PROFILE AWS_REGION diff --git a/zsh/utils/apps/70-wrapper.zsh b/zsh/utils/apps/70-wrapper.zsh new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/zsh/utils/apps/70-wrapper.zsh @@ -0,0 +1 @@ + diff --git a/zsh/utils/apps/99-fzf.zsh b/zsh/utils/apps/99-fzf.zsh new file mode 100644 index 0000000..b558281 --- /dev/null +++ b/zsh/utils/apps/99-fzf.zsh @@ -0,0 +1,43 @@ +utils.fzf() { + [ ${CI} ] && utils.fail 1 'currently in CI, but utils.fzf requires user input' + + local FZF_ARGS=( + -i + --ansi + --bind=ctrl-c:cancel + --height=50% + --layout=reverse + ) + + + local SELECTION=$(fzf ${FZF_ARGS[@]} --prompt "$1 : " ${@:2} 2>/dev/tty) + echo.prompt "$1" + + [ ${BE_QUIET} ] || { + [[ ${SCWRYPTS_LOG_LEVEL} -ge 1 ]] && echo ${SELECTION} >&2 + } + echo ${SELECTION} + [ ${SELECTION} ] +} + +utils.fzf.user-input() { # allow user to type custom answers; reconfirm if ambiguous with select + local FZF_OUTPUT=$(BE_QUIET=1 utils.fzf $@ --print-query | sed '/^$/d' | sort -u) + [[ ${SCWRYPTS_LOG_LEVEL} -ge 1 ]] && echo ${FZF_OUTPUT} | head -n1 >&2 + [ ! ${FZF_OUTPUT} ] && return 1 + + [[ $(echo "${FZF_OUTPUT}" | wc -l) -eq 1 ]] \ + && { echo "${FZF_OUTPUT}"; return 0; } + + local FZF_OUTPUT=$( + echo "${FZF_OUTPUT}" \ + | sed "1s/\$/^$(utils.colors.print light-gray '<- what you typed')/" \ + | sed "2s/\$/^$(utils.colors.print light-gray '<- what you selected')/" \ + | column -ts '^' \ + | BE_QUIET=1 utils.fzf "$@ (clarify)" \ + ) + + [[ ${SCWRYPTS_LOG_LEVEL} -ge 1 ]] && echo ${FZF_OUTPUT} >&2 + FZF_OUTPUT=$(echo ${FZF_OUTPUT} | sed 's/\s\+<- what you .*$//') + echo ${FZF_OUTPUT} + [ ${FZF_OUTPUT} ] +} diff --git a/zsh/utils/apps/99-less.zsh b/zsh/utils/apps/99-less.zsh new file mode 100644 index 0000000..390b37b --- /dev/null +++ b/zsh/utils/apps/99-less.zsh @@ -0,0 +1 @@ +utils.less() { less -R $@ /dev/tty; } diff --git a/zsh/utils/apps/99-notify-send.zsh b/zsh/utils/apps/99-notify-send.zsh new file mode 100644 index 0000000..1ea9693 --- /dev/null +++ b/zsh/utils/apps/99-notify-send.zsh @@ -0,0 +1,13 @@ +utils.notify-send() { + utils.dependencies.check notify-send &>/dev/null || { + echo.warning "missing 'notify-send'; cannot send desktop notifications" + utils.notify-send() { true; } + return 0 + } + + [ "${SCWRYPT_GROUP}" ] && [ "${SCWRYPT_NAME}" ] \ + && local TITLE="scwrypts/${SCWRYPT_GROUP} ${SCWRYPT_NAME}" \ + || local TITLE="zsh" + + notify-send "${TITLE}" $@ +} diff --git a/zsh/utils/apps/99-yq.zsh b/zsh/utils/apps/99-yq.zsh new file mode 100644 index 0000000..cbb4d99 --- /dev/null +++ b/zsh/utils/apps/99-yq.zsh @@ -0,0 +1,8 @@ +utils.yq() { + yq --version | grep -q mikefarah || { + yq $@ # this is a different version from the preferred but throwing this in for compatibility + return $? + } + + yq eval '... comments=""' | yq $@ +} diff --git a/zsh/utils/dependencies.zsh b/zsh/utils/dependencies.zsh new file mode 100644 index 0000000..e8fa0db --- /dev/null +++ b/zsh/utils/dependencies.zsh @@ -0,0 +1,78 @@ +utils.dependencies.check-all() { + local DEP ERRORS=0 + local SCWRYPTS_LOG_LEVEL=1 + [ ! ${E} ] && E=echo.error + + DEPENDENCIES=($(echo ${DEPENDENCIES} | sed 's/ \+/\n/g' | sort -u)) + + for DEP in ${DEPENDENCIES[@]}; do utils.dependencies.check ${DEP} || ((ERRORS+=1)); done + utils.dependencies.check-coreutils || ((ERRORS+=$?)) + + return ${ERRORS} +} + +utils.dependencies.check() { + local DEPENDENCY="$1" + [ ! ${DEPENDENCY} ] && return 1 + command -v ${DEPENDENCY} >/dev/null 2>&1 || { + [[ ${OPTIONAL} -eq 1 ]] \ + && echo.warning "application '$1' preferred but not available on PATH $(utils.dependencies.credits $1)" \ + || echo.error "application '$1' required but not available on PATH $(utils.dependencies.credits $1)" \ + ; + return 1 + } + + command -v utils.wrapper.${DEPENDENCY} &>/dev/null && { + utils.wrapper.${DEPENDENCY} \ + || echo.error "failed to define required context wrapper for '$1'" \ + || return 1 \ + ; + } + + [[ ${DEPENDENCY} =~ ^yq$ ]] && { + yq --version | grep -q mikefarah \ + || echo.warning 'detected kislyuk/yq but mikefarah/yq is preferred (compatibility may vary)' + } + + return 0 +} + +utils.dependencies.check-coreutils() { + local COREUTILS=(awk find grep sed readlink) + local MISSING_DEPENDENCY_COUNT=0 + local NON_GNU_DEPENDENCY_COUNT=0 + + local UTIL + for UTIL in $(echo ${COREUTILS}) + do + utils.dependencies.check ${UTIL} || { ((MISSING_DEPENDENCY_COUNT+=1)); continue; } + + ${UTIL} --version 2>&1 | grep 'GNU' | grep -qv 'BSD' || { + echo.warning "non-GNU version of ${UTIL} detected" + ((NON_GNU_DEPENDENCY_COUNT+=1)) + } + done + + [[ ${NON_GNU_DEPENDENCY_COUNT} -gt 0 ]] && { + echo.warning 'scripts rely on GNU coreutils; compatibility may vary' + utils.os.is-macos && echo.reminder 'GNU coreutils can be installed and linked through Homebrew' + } + + return ${MISSING_DEPENDENCY_COUNT} +} + +utils.dependencies.credits() { + return 0 + # scwrypts exclusive ("credits" pulled from README files) + [ ! ${__SCWRYPT} ] && return 0 + + local COMMAND="$1" + [[ $COMMAND =~ - ]] && COMMAND=$(echo $COMMAND | sed 's/-/--/g') + ( + cd "$(scwrypts.config.group scwrypts root)" + cat ./**/README.md \ + | grep 'Generic Badge' \ + | sed -n "s/.*Generic Badge.*-$COMMAND-.*(/(/p" \ + ; + ) +} diff --git a/zsh/utils/environment.zsh b/zsh/utils/environment.zsh new file mode 100644 index 0000000..696d3af --- /dev/null +++ b/zsh/utils/environment.zsh @@ -0,0 +1,250 @@ +utils.environment.check-all() { + # checks all environment variables in REQUIRED_ENV=() + local SCWRYPTS_LOG_LEVEL=4 + local VAR ERRORS=0 + + REQUIRED_ENV=($(echo ${REQUIRED_ENV} | sed 's/\s\+/\n/g' | sort --unique)) + + for VAR in ${REQUIRED_ENV[@]}; do utils.environment.check ${VAR} || ((ERRORS+=1)); done + + return ${ERRORS} +} + +utils.environment.check() { + local NAME OPTIONAL DEFAULT_VALUE LOOKUP_PATH + local NAME_IS=environment-variable + local PRINT_VALUE=false + + local USAGE=" + usage: utils.environment.check [...options...] + + options: + --optional marks the variable as optional + --default marks the variable as optional and provides a default value + --print-value print the value to stdout + + Verifies the existence of an environment variable in the current + runtime. When running in scwrypts, allows lookup of environment variable + values by either environment variable name or config lookup path: + + utils.environment.check AWS_ACCOUNT + utils.environment.check .aws.account + + When in CI, environment _values_ must always come from the corresponding + configuration env var (even when lookup is a config lookup path) + " + + local _S ERRORS=0 POSITIONAL_ARGS=0 + while [[ $# -gt 0 ]] + do + _S=1 + case $1 in + ( -h | --help ) + utils.io.usage + return 0 + ;; + + ( --optional ) + OPTIONAL=true + ;; + + ( --print-value ) + PRINT_VALUE=true + ;; + + ( --default ) + [ $2 ] && ((_S+=1)) \ + || echo.error "missing env var default value" \ + || break + + [ ! "${DEFAULT_VALUE}" ] \ + || echo.error "only one default value is supported" \ + || break + + [[ ${OPTIONAL} =~ true ]] \ + && echo.warning "--optional and --default flags are redundant; remove '--optional' flag" + + DEFAULT_VALUE="$2" + OPTIONAL=true + ;; + + ( * ) + ((POSITIONAL_ARGS+=1)) + case ${POSITIONAL_ARGS} in + ( 1 ) NAME="$1" + ;; + + ( 2 ) DEFAULT_VALUE="$1" + echo.warning "use of positional argument for default value is DEPRECATED\nplease use --default flag" + ;; + + ( * ) echo.error "unknown argument '$1'" + ;; + esac + ;; + esac + shift ${_S} + done + + [ "${NAME}" ] \ + || echo.error "must provide environment variable name" + + [ "${OPTIONAL}" ] || OPTIONAL=false + + echo "${NAME}" | grep -q '^\.' \ + && NAME_IS=lookup-path + + case ${NAME_IS} in + ( lookup-path ) + [ ${__SCWRYPT} ] || echo.error "lookup paths cannot be used outside of scwrypts (${NAME})" + [ ${__SCWRYPT} ] && { + use scwrypts/environment \ + || echo.error "unable to load lookup path" + + LOOKUP_PATH="${NAME}" + NAME=$(\ + scwrypts.environment.get-full-template \ + | utils.yq -r "${LOOKUP_PATH}.\".ENVIRONMENT\"" \ + | grep -v ^null$\ + ) + + [ ${NAME} ] || echo.error "no .ENVIRONMENT key is configured for '${LOOKUP_PATH}'" + } + ;; + ( environment-variable ) + ;; + esac + + utils.check-errors --no-usage || return $? + + ########################################## + + # only check env vars once + local ALREADY_CHECKED="$(eval echo '$'${NAME}'__checked')" + [ "${ALREADY_CHECKED}" ] && return ${ALREADY_CHECKED} + + [ ${__SCWRYPT} ] || local CI=true # outside of scwrypts, environment must load like CI runtime + [ ${CI} ] && { + local VALUE="$(eval echo '$'${NAME})" + [ "${VALUE}" ] && { + export ${NAME}__checked=0 + [[ ${PRINT_VALUE} =~ true ]] && echo "${VALUE}" + return 0 + } + + case ${OPTIONAL} in + ( true ) + [ "${DEFAULT_VALUE}" ] \ + && export ${NAME}=${DEFAULT_VALUE} \ + || echo.warning "environment variable '${NAME}' is not set" \ + ; + + export ${NAME}__checked=0 + return 0 + ;; + ( false ) + local ERROR_MESSAGE="missing required environment variable '${NAME}'" + [ "${LOOKUP_PATH}" ] && ERROR_MESSAGE+=" (config path '${LOOKUP_PATH}')" + + echo.error "${ERROR_MESSAGE}" + export ${NAME}__checked=1 + return 1 + ;; + esac + } + + [ ! ${LOOKUP_PATH} ] && { + LOOKUP_PATH="$(scwrypts.environment.get-envvar-lookup-map | utils.yq -r ".${NAME}" | sed 's/\.value$//')" + } + + # ensure environment safety; prevent bleed in from user's runtime + unset ${NAME} + local VALUE + for GET_VALUE_METHOD in \ + runtimeoverride \ + value \ + selection \ + select \ + ; + do + VALUE=$(utils.environment.check.${GET_VALUE_METHOD} "${NAME}" "${LOOKUP_PATH}" 2>/dev/null) + [ "${VALUE}" ] && eval "export ${NAME}=${VALUE}" && break + done + + [ "${VALUE}" ] && { + export ${NAME}__checked=0 + [[ ${PRINT_VALUE} =~ true ]] && echo "${VALUE}" + return 0 + } + + case ${OPTIONAL} in + ( true ) + [ "${DEFAULT_VALUE}" ] \ + && export ${NAME}=${DEFAULT_VALUE} \ + || echo.warning "environment variable '${NAME}' is not set" \ + ; + + export ${NAME}__checked=0 + [[ ${PRINT_VALUE} =~ true ]] && echo "${DEFAULT_VALUE}" + return 0 + ;; + ( false ) + local ERROR_MESSAGE="missing required environment variable '${NAME}'" + [ "${LOOKUP_PATH}" ] && ERROR_MESSAGE+=" (config path '${LOOKUP_PATH}')" + + echo.error "${ERROR_MESSAGE}" + export ${NAME}__checked=1 + return 1 + ;; + esac +} + +utils.environment.check.runtimeoverride() { + local NAME="$1" + local LOOKUP_PATH="$2" + eval echo '$'${NAME}'__override' +} + +utils.environment.check.value() { + local NAME="$1" + local LOOKUP_PATH="$2" + + scwrypts.environment.user.get-shell-values \ + | utils.yq -r "${LOOKUP_PATH}.value" \ + | grep -v '^null$' \ + ; +} + +utils.environment.check.selection() { + local NAME="$1" + local LOOKUP_PATH="$2" + + local SELECTION_VALUES=($( + scwrypts.environment.user.get-shell-values \ + | utils.yq -r "${LOOKUP_PATH}.selection[]" \ + | grep -v '^null$' \ + )) + + [[ ${#SELECTION_VALUES[@]} -gt 0 ]] || return + + echo "${SELECTION_VALUES}" \ + | sed 's/\s\+/\n/g' \ + | utils.fzf "select a value for '${NAME}'" \ + ; +} + +utils.environment.check.select() { # support for ENV_VAR__select=() + local NAME="$1" + local LOOKUP_PATH="$2" + + local SELECTION_VALUES=($(eval echo '$'${NAME}'__select')) + + [[ ${#SELECTION_VALUES[@]} -gt 0 ]] || return + + echo.warning "support for ENV_VAR__select syntax is deprecated;\nplease use the .selection[] array in the yaml configuration for user-selectable options" + + echo "${SELECTION_VALUES}" \ + | sed 's/\s\+/\n/g' \ + | utils.fzf "select a value for '${NAME}'" \ + ; +} diff --git a/zsh/utils/io/00-colors.zsh b/zsh/utils/io/00-colors.zsh new file mode 100644 index 0000000..8e7071c --- /dev/null +++ b/zsh/utils/io/00-colors.zsh @@ -0,0 +1,58 @@ +utils.colors.black() { printf '\033[0;30m'; } +utils.colors.dark-gray() { printf '\033[1;30m'; } +utils.colors.red() { printf '\033[0;31m'; } +utils.colors.bright-red() { printf '\033[1;31m'; } +utils.colors.green() { printf '\033[0;32m'; } +utils.colors.bright-green() { printf '\033[1;32m'; } +utils.colors.yellow() { printf '\033[0;33m'; } +utils.colors.bright-yellow() { printf '\033[1;33m'; } +utils.colors.blue() { printf '\033[0;34m'; } +utils.colors.bright-blue() { printf '\033[1;34m'; } +utils.colors.magenta() { printf '\033[0;35m'; } +utils.colors.bright-magenta() { printf '\033[1;35m'; } +utils.colors.cyan() { printf '\033[0;36m'; } +utils.colors.bright-cyan() { printf '\033[1;36m'; } +utils.colors.light-gray() { printf '\033[0;37m'; } +utils.colors.white() { printf '\033[1;37m'; } + +utils.colors.reset() { printf '\033[0m'; } + +utils.colors.remove() { sed 's/\x1b\[[0-9;]*m//g'; } + +##################################################################### + +utils.colors.print() { # print color + message + color-reset sequence + local COLOR="$1" + local MESSAGE="${@:2}" + + command -v utils.colors.${COLOR} &>/dev/null || { + printf "${MESSAGE}" + return + } + + printf "$(utils.colors.${COLOR})${MESSAGE}$(utils.colors.reset)" +} + +##################################################################### + +export __SCWRYPTS_UTILS_COLORS=( + $(utils.colors.red) + $(utils.colors.bright-red) + $(utils.colors.green) + $(utils.colors.bright-green) + $(utils.colors.yellow) + $(utils.colors.bright-yellow) + $(utils.colors.blue) + $(utils.colors.bright-blue) + $(utils.colors.magenta) + $(utils.colors.bright-magenta) + $(utils.colors.cyan) + $(utils.colors.bright-cyan) + $(utils.colors.white) + ) + +utils.colors.random() { + printf "$(utils.colors.reset)${__SCWRYPTS_UTILS_COLORS[$(shuf -i 1-${#__SCWRYPTS_UTILS_COLORS[@]} -n 1)]}" +} + +##################################################################### diff --git a/zsh/utils/io/10-print.zsh b/zsh/utils/io/10-print.zsh new file mode 100644 index 0000000..da4dca3 --- /dev/null +++ b/zsh/utils/io/10-print.zsh @@ -0,0 +1,104 @@ +DEPENDENCIES+=(jo jq printf) + +utils.io.print() { + local \ + MESSAGE \ + PREFIX COLOR \ + MINIMUM_LOG_LEVEL IGNORE_MINIMUM_LOG_LEVEL=false \ + PRINT_TO_STDERR=true \ + PRINT_TO_STDOUT=false \ + LAST_LINE_END='\n' \ + ; + + [ ${SCWRYPTS_LOG_LEVEL} ] || local SCWRYPTS_LOG_LEVEL=4 + [ ${SCWRYPTS_OUTPUT_FORMAT} ] || local SCWRYPTS_OUTPUT_FORMAT=pretty + + local _S + while [[ $# -gt 0 ]] + do + _S=1 + case $1 in + ( --prefix ) + _S=2 + PREFIX="$2" + ;; + + ( --color ) + _S=2 + COLOR="$2" + ;; + + ( --minimum-log-level ) + _S=2 + MINIMUM_LOG_LEVEL=$2 + ;; + + ( --force-print ) + IGNORE_MINIMUM_LOG_LEVEL=true + ;; + + ( --stdout ) + PRINT_TO_STDOUT=true + PRINT_TO_STDERR=false + ;; + + ( --no-line-end ) + LAST_LINE_END='' + ;; + + ( --format ) + _S=2 + local SCWRYPTS_OUTPUT_FORMAT=$2 + ;; + + ( * ) + [ "${MESSAGE}" ] && MESSAGE+=" $1" || MESSAGE="$1" + ;; + esac + + [[ ${_S} -le $# ]] && shift ${_S} || { echo "echo.error : missing argument for '$1'" >&2; return 1; } + done + + : \ + && [ "${MINIMUM_LOG_LEVEL}" ] \ + && [[ "${IGNORE_MINIMUM_LOG_LEVEL}" =~ false ]] \ + && [[ "${SCWRYPTS_LOG_LEVEL}" -lt "${MINIMUM_LOG_LEVEL}" ]] \ + && return 0 + + + MESSAGE="$(echo "${MESSAGE}" | sed 's/^ \+//; s/%/%%/g')" + case ${SCWRYPTS_OUTPUT_FORMAT} in + ( raw ) MESSAGE+="${LAST_LINE_END}" ;; + ( pretty ) + MESSAGE="${COLOR}$({ + while IFS='' read line + do + [[ ${PREFIX} =~ ^[[:space:]]\+$ ]] && printf '\n' + + printf "${PREFIX} : $(echo "${line}" | sed 's/^ \+//; s/ \+$//')" + + PREFIX=' ' + done <<< $(echo "${MESSAGE}" | sed 's/%/%%/g') + })${LAST_LINE_END}$(utils.colors.reset)" + ;; + ( json ) + MESSAGE="$(jo \ + timestamp=$(date +%s) \ + runtime=${SCWRYPTS_RUNTIME_ID} \ + status="$(echo "${PREFIX}" | sed 's/ .*//')" \ + message="$(echo -n "${MESSAGE}" | sed 's/^\t\+//' | jq -Rs)" \ + 2>/dev/null || echo "{\"error\":\"your message was too long so I encoded it manually\",\"messageB64\":\"$(echo "${MESSAGE}" | base64 | tr -d '\n')\"}" + )\n" + ;; + ( * ) + echo "echo.error : unsupported format '${SCWRYPTS_OUTPUT_FORMAT}'" >&2 + return 1 + ;; + esac + + + [[ ${PRINT_TO_STDERR} =~ true ]] && printf -- "${MESSAGE}" >&2 + [[ ${PRINT_TO_STDOUT} =~ true ]] && printf -- "${MESSAGE}" + + return 0 +} diff --git a/zsh/utils/io/20-echo.zsh b/zsh/utils/io/20-echo.zsh new file mode 100644 index 0000000..7717227 --- /dev/null +++ b/zsh/utils/io/20-echo.zsh @@ -0,0 +1,57 @@ +echo.success.color() { utils.colors.green; } +echo.success() { # command completed successfully + utils.io.print $@ --minimum-log-level 1 --prefix "SUCCESS ✔" --color $(echo.success.color) + return 0 +} + +echo.error.color() { utils.colors.red; } +echo.error() { # command encountered an error + utils.io.print $@ --minimum-log-level 1 --prefix "ERROR ✖" --color $(echo.error.color) + ((ERRORS+=1)) + return ${ERRORS} +} + +echo.reminder.color() { utils.colors.bright-magenta; } +echo.reminder() { # sysadmin reminder or important notice to users + utils.io.print $@ --minimum-log-level 1 --prefix "REMINDER " --color $(echo.reminder.color) + return 0 +} + +echo.status.color() { utils.colors.blue; } +echo.status() { # general status updates (prefer this to generic 'echo') + utils.io.print $@ --minimum-log-level 2 --prefix "STATUS " --color $(echo.status.color) + return 0 +} + +echo.warning.color() { utils.colors.yellow; } +echo.warning() { # warning-level messages; not errors + utils.io.print $@ --minimum-log-level 3 --prefix "WARNING " --color $(echo.warning.color) + return 0 +} + +echo.debug.color() { utils.colors.white; } +echo.debug() { # helpful during development or (sparingly) to help others' development + # early exit since debug injects state information + [ ${SCWRYPTS_LOG_LEVEL} ] && [[ ${SCWRYPTS_LOG_LEVEL} -lt 4 ]] && [[ ! $@ =~ --force-print ]] && return 0 + + utils.io.print $@ --minimum-log-level 4 --prefix "DEBUG ℹ" --color $(echo.debug.color) \ + "\n> DEBUG::funcstack : $(echo "${funcstack[@]:1}" | sed 's/ (anon) (eval) (anon)$/ scwrypts/')" \ + "\n> DEBUG::timestamp : $(date +%s)" \ + ; + return 0 +} + +##################################################################### + +echo.prompt() { + [ ! "${SCWRYPTS_LOG_LEVEL}" ] && local SCWRYPTS_LOG_LEVEL=4 + + [[ "${SCWRYPTS_LOG_LEVEL}" -eq 0 ]] && { + utils.io.print --format raw $@ ": " --no-line-end + return 0 + } + + utils.io.print $@ --prefix "PROMPT " --color $(utils.colors.cyan) + utils.io.print '' --prefix "USER ⌨" --color $(utils.colors.bright-cyan) --no-line-end + return 0 +} diff --git a/zsh/utils/io/30-user.zsh b/zsh/utils/io/30-user.zsh new file mode 100644 index 0000000..cd8875b --- /dev/null +++ b/zsh/utils/io/30-user.zsh @@ -0,0 +1,114 @@ +##################################################################### + +utils.io.input() { # read a single line of user input + echo.prompt "${@:2}" + utils.io.read $1 + local VALUE=$(eval echo '$'$1) + [ ${VALUE} ] +} + +# yes/no prompts && = yes (exit code 0) +# || = no (exit code 1) +utils.Yn() { [[ ! $(utils.io.read-yn $@ '[Yn]') =~ [nN] ]]; } # default 'yes' +utils.yN() { [[ $(utils.io.read-yn $@ '[yN]') =~ [yY] ]]; } # default 'no' + +utils.io.edit() { # edit a file in user's preferred editor + [ ${CI} ] && { + echo.warning 'currently in CI, skipping EDIT' + return 0 + } + + echo.status "opening '$1' for editing" + ${EDITOR} $@ /dev/tty + echo.success "finished editing '$1'!" +} + +utils.io.getsudo() { # ensure a user has sudo permissions + echo.prompt 'checking sudo password' --stdout | head -n1 >&2 + sudo echo hi >/dev/null 2>&1 &2 + + echo ${yn} +} diff --git a/zsh/utils/io/99-capture.zsh b/zsh/utils/io/99-capture.zsh new file mode 100644 index 0000000..5cbb7ef --- /dev/null +++ b/zsh/utils/io/99-capture.zsh @@ -0,0 +1,11 @@ +utils.io.capture() { + local USAGE=" + usage: stdout-varname stderr-varname [...cmd and args...] + + captures stdout and stderr on separate variables for a command + " + { + IFS=$'\n' read -r -d '' $2; + IFS=$'\n' read -r -d '' $1; + } < <((printf '\0%s\0' "$(${@:3})" 1>&2) 2>&1) +} diff --git a/zsh/utils/io/99-flow-control.zsh b/zsh/utils/io/99-flow-control.zsh new file mode 100644 index 0000000..fd8ca47 --- /dev/null +++ b/zsh/utils/io/99-flow-control.zsh @@ -0,0 +1,38 @@ +##################################################################### + +utils.fail() { # displays a crash error and exit + echo.error --force-print ${@:2} + exit $1 +} + +utils.abort() { # for consistency; use after user aborts REQUIRED input + utils.fail 69 'user abort' +} + +##################################################################### + +utils.check-errors() { # returns an error and reports usage if 'echo.error' was ever called + [ ${ERRORS} ] && [[ ${ERRORS} -ne 0 ]] || return 0 + + local DISPLAY_USAGE=true + local FAIL_OUT=false + + while [[ $# -gt 0 ]] + do + case $1 in + ( --no-usage ) DISPLAY_USAGE=false ;; + ( --fail ) FAIL_OUT=true ;; + + ( --no-fail ) + echo.warning "utils.check-errors : '--no-fail' is now the default behavior" + ;; + esac + shift 1 + done + + [[ ${DISPLAY_USAGE} =~ true ]] && utils.io.usage + + [[ ${FAIL_OUT} =~ true ]] && exit ${ERRORS} || return ${ERRORS} +} + +##################################################################### diff --git a/zsh/utils/io/99-usage.zsh b/zsh/utils/io/99-usage.zsh new file mode 100644 index 0000000..1adfd76 --- /dev/null +++ b/zsh/utils/io/99-usage.zsh @@ -0,0 +1,102 @@ +utils.io.usage() { # formatter for USAGE variable + [ ! ${USAGE} ] && return 0 + [[ ${SUPPRESS_USAGE_OUTPUT} =~ true ]] && return 0 + local USAGE_LINE=$(echo ${USAGE} | grep -i '^[ ]*usage *:' | sed 's/^[ ]*//') + + [ "${USAGE__options}" ] && [ "${USAGE__usage}" ] && { + [[ ${USAGE__usage} =~ options ]] || USAGE__usage+=' [...options...]' + } + + [ ${USAGE__usage} ] && echo ${USAGE_LINE} | grep -q 'usage: -' \ + && USAGE_LINE=$(echo ${USAGE_LINE} | sed "s/usage: -/usage: ${USAGE__usage}/") + + + [ ${__SCWRYPT} ] && [[ ! ${USAGE_LINE} =~ 'usage: [A-Z]' ]] && { + [[ ${#funcstack[@]} -eq 4 ]] && { + # when in a scwrypt at funcstack length 4, you are viewing the top-level + # help document of a MAIN function + USAGE_LINE=$(echo ${USAGE_LINE} | sed "s;^[^:]*:;& scwrypts ${SCWRYPT_NAME} --;") + } + } + + local THE_REST=$(echo ${USAGE} | grep -vi '^[ ]*usage *:' ) + + local DYNAMIC_USAGE_ELEMENT + # + # create dynamic usage elements (like 'args') by defining USAGE__ + # then using the syntax ": -" in your USAGE variable + # + # e.g. + # + # USAGE__args=" + # subcommand arg 1 arg 1 description + # subcommand arg 2 some other description + # " + # + # USAGE=" + # usage: some-command [...args...] + # + # args: - + # -h, --help some arguments are applicable everywhere + # " + # + for DYNAMIC_USAGE_ELEMENT in $(echo ${THE_REST} | sed -n 's/^\([^:]*\): -$/\1/p') + do + DYNAMIC_USAGE_ELEMENT_TEXT=$(eval echo '$USAGE__'${DYNAMIC_USAGE_ELEMENT}) + [ ${DYNAMIC_USAGE_ELEMENT_TEXT} ] || { + case ${DYNAMIC_USAGE_ELEMENT} in + ( options ) + # there's _always_ at least one of these + THE_REST=$(echo ${THE_REST} | sed "s/${DYNAMIC_USAGE_ELEMENT}: -/${DYNAMIC_USAGE_ELEMENT}:/") + ;; + ( * ) + THE_REST=$(echo ${THE_REST} | sed "/^[ ]*${DYNAMIC_USAGE_ELEMENT}: -/d") + ;; + esac + continue + } + + case ${DYNAMIC_USAGE_ELEMENT} in + description ) + DYNAMIC_USAGE_ELEMENT_TEXT=$(echo "${DYNAMIC_USAGE_ELEMENT_TEXT}" | perl -p0e 's/^[\n\s]+//') + DYNAMIC_USAGE_ELEMENT_TEXT="$(utils.colors.print yellow "${DYNAMIC_USAGE_ELEMENT_TEXT}")" + ;; + * ) + DYNAMIC_USAGE_ELEMENT_TEXT=$(echo ${DYNAMIC_USAGE_ELEMENT_TEXT} | sed 's/[^ ]/ &/') + ;; + esac + + THE_REST=$(echo ${THE_REST} | perl -pe "s${DYNAMIC_USAGE_ELEMENT}: -${DYNAMIC_USAGE_ELEMENT}:\n${DYNAMIC_USAGE_ELEMENT_TEXT}\n\n") + done + + # allow for dynamic 'description: -' but delete the 'description:' header line + THE_REST=$(echo ${THE_REST} | sed '/^[ ]*description:$/d') + + echo "$(utils.colors.blue)${USAGE_LINE}$(utils.colors.reset)\n\n${THE_REST}" \ + | sed "s/^\t\+//; s/\s\+$//; s/^\\s*$//;" \ + | sed '/./,$!d; :a; /^\n*$/{$d;N;ba;};' \ + | perl -p0e 's/\n{2,}/\n\n/g' \ + | perl -p0e 's/:\n{2,}/:\n/g' \ + | perl -p0e 's/([a-z]+:)\n([a-z]+:)/\2/g' \ + | sed -z 's/\s\n\+$//' \ + >&2 +} + +usage.reset() { + # eval "$(usage.reset)" to setup local usage defaults + echo " + local USAGE__usage=${funcstack[2]} + local USAGE__options + local USAGE__args + local USAGE__description + local USAGE=' + usage: - + + options: - + + args: - + + description: - + ' + " +} diff --git a/zsh/utils/os.zsh b/zsh/utils/os.zsh new file mode 100644 index 0000000..578ffc6 --- /dev/null +++ b/zsh/utils/os.zsh @@ -0,0 +1,24 @@ +##################################################################### + +utils.os.is-macos() { uname -s | grep -q 'Darwin'; } + +##################################################################### + +utils.open() { + local OPEN + for OPEN in \ + xdg-open \ + open \ + ; + do + command -v ${OPEN} &>/dev/null && break + OPEN= + done + + [ ${OPEN} ] \ + || echo.error 'unable to detect default open command (e.g. xdg-open)' \ + || return 1 \ + ; + + $OPEN $@ +} diff --git a/zsh/utils/parse.args.zsh b/zsh/utils/parse.args.zsh new file mode 100644 index 0000000..8464074 --- /dev/null +++ b/zsh/utils/parse.args.zsh @@ -0,0 +1,114 @@ +# +# parses unmatched args into the 'local ARGS=()' array; as seen below, +# this will only parse unmatched args if the +# parses '-h' or '--help', prints usage, and returns early +# + +# when parsers set values to variables, mention them in a comment on the +# first line of the function, so it is clear what variables must be set +# in the parent function + +utils.parse.args.locals() { + #local ARGS=() + # + # to enable this parser, you must include 'local ARGS=()' yourself + # + # if you are in a nested context where ARGS=() may exist from a parent, + # you can _disable_ this parser by declaring "local ARGS=none" + # + # this can be done either in a .locals() function or simply in the body + # of your function before utils.parse is called + # + + local ARGS_FORCE=allowed # typically you want this to be 'allowed', but see below for details +} + +utils.parse.args() { + local PARSED=0 + [ $ARGS_FORCE ] || local ARGS_FORCE=false + + case $ARGS_FORCE in + # + # ARGS_FORCE=true means no arguments will be filtered before going + # into the ARGS array; typically this is set _after_ hitting the '--' + # argument (done automatically below) + # + ( true ) + ((POSITIONAL_ARGS+=1)) + PARSED=1 + ARGS+=($1) + ;; + + # + # ARGS_FORCE=allowed will filter out flag/option arguments (e.g '-h' or '--help'), + # but after a '--' is parsed, ARGS_FORCE is set to 'true'. For example: + # + # MY_FUNCTION arg1 arg2 --help + # would set ARGS=(arg1 arg2) and ignore the '--help' + # + # MY_FUNCTION -- arg1 arg2 --help + # would set ARGS=(arg1 arg2 --help); consuming the '--help' + # + ( allowed ) + case $1 in + ( -[a-zA-Z0-9]* | --[a-zA-Z[0-9]* ) + ;; + + ( -- ) PARSED=1; ARGS_FORCE=true ;; + + ( * ) + ((POSITIONAL_ARGS+=1)) + PARSED=1 + ARGS+=($1) + ;; + esac + ;; + + # + # ARGS_FORCE=false will _always_ filter out flag/option arguments; although you + # typically want ARGS_FORCE=allowed, this is the 'default' option when ARGS_FORCE + # is not specified (required to allow safe fallthrough when no args should be parsed) + # + ( false ) + case $1 in + ( -[a-zA-Z0-9]* | --[a-zA-Z[0-9]* ) + ;; + + ( * ) + ((POSITIONAL_ARGS+=1)) + PARSED=1 + ARGS+=($1) + ;; + esac + ;; + esac + + return $PARSED +} + +utils.parse.args.usage() { + # don't auto-add "args" to the usage string if it's already there + [[ $USAGE__usage =~ args ]] && return 0 + + case $ARGS_FORCE in + ( allowed ) + USAGE__usage+=' -- [...args...]' + ;; + ( * ) + USAGE__usage+=' [...args...]' + ;; + esac + + # USAGE__args should be updated by the parent function +} + +utils.parse.args.safety() { + # skip this parser with NO_DEFAULT_PARSEARGS=true + [[ $NO_DEFAULT_PARSEARGS =~ true ]] && return 1 + + # skip this parser if 'local ARGS=()' is not declared + [[ ${(t)ARGS} =~ array ]] || return 1 + + # skip this parser if 'ARGS' is not empty + [[ ${#ARGS[@]} -eq 0 ]] || return 1 +} diff --git a/zsh/utils/parse.autosetup.zsh b/zsh/utils/parse.autosetup.zsh new file mode 100644 index 0000000..c662fee --- /dev/null +++ b/zsh/utils/parse.autosetup.zsh @@ -0,0 +1,94 @@ + +# +# relies on '.locals()' parser functions to: +# 1. auto-define all local variables +# 2. reset local usage and set initial description +# 3. set other standard local variables +# 4. perform ZSHPARSEARGS (see ./parse.zsh) +# +# usage: +# +# local DESCRIPTION= # put your '--help' description here +# local PARSERS=() # add all non-default parsers here +# eval "$(utils.autosetup)" +# +# you can use the '--debug' flag to see what's actually being +# set up here: +# +# eval "$(utils.autosetup --debug)" +# + +utils.parse.autosetup() { + local USE_DEFAULT_PARSERS=true + local DEBUG=false + + [[ ${(t)PARSERS} =~ array ]] || local PARSERS=() + + local _S ERRORS=0 + while [[ $# -gt 0 ]] + do + _S=1 + + case $1 in + ( --no-default-parsers ) + USE_DEFAULT_PARSERS=false + ;; + ( --debug ) + # this can be tricky debugging, but these messages are not always helpful + # to see when SCWRYPTS_LOG_LEVEL is high + DEBUG=true + ;; + ( * ) + echo.error "utils.autosetup error; unknown argument $1" + ;; + esac + + [[ ${_S} -le $# ]] \ + && shift ${_S} \ + || shift $# \ + ; + done + + utils.check-errors --no-usage || { + echo "echo.error 'utils.autosetup error'; return 127;" + return 127 + } + + case ${USE_DEFAULT_PARSERS} in + ( false ) ;; + ( true ) + PARSERS=(${funcstack[2]}.parse ${PARSERS[@]} utils.parse.args utils.parse.help) + ;; + esac + + [[ ${DEBUG} =~ true ]] \ + && echo.debug --force-print "utils.autosetup : parsers : ${PARSERS[@]}" + + for P in ${PARSERS[@]} + do + command -v ${P}.locals &>/dev/null || continue + which ${P}.locals | sed '1d; $d;' + + [[ ${DEBUG} =~ true ]] \ + && echo.debug --force-print "utils.autosetup : parser ${P} locals\n$(which ${P}.locals | sed 's/^/ /; 1d; $d;')" + done | sed 's^\s*local \([A-Z0-9a-z_]*\)\(=\(.*\)\)*$[ "$\1" ] || local \1=\3' + + usage.reset + + echo "local USAGE__description=$(printf "%q " "${DESCRIPTION}")" + echo "local USAGE__usage=${funcstack[2]}" + echo "local ERRORS=0" + echo "local POSITIONAL_ARGS=0" + + echo ' + utils.parse $@ || { + local ERROR_CODE=$? + unset PARSERS + case $ERROR_CODE in + -1 ) return 0 ;; # -h | --help + * ) return $ERROR_CODE ;; + esac + } + unset PARSERS + ' +} diff --git a/zsh/utils/parse.help.zsh b/zsh/utils/parse.help.zsh new file mode 100644 index 0000000..89a1f33 --- /dev/null +++ b/zsh/utils/parse.help.zsh @@ -0,0 +1,150 @@ +# +# parse the -h|--help argument, then requests that the parent function exit early +# by emitting EARLY_ESCAPE_CODE=-1 +# + +utils.parse.help() { + local PARSED=0 + + case $1 in + ( -h | --help ) + PARSED=1 + utils.io.usage + EARLY_ESCAPE_CODE=-1 + + # setting 'EARLY_ESCAPE_CODE=' will stop ALL argument parsing, forcing + # ZSHPARSEARGS to immediately return the value ${EARLY_ESCAPE_CODE} + # + # negative EARLY_ESCAPE_CODE values are _not_ processed automatically; + # however, this special case, 'EARLY_ESCAPE_CODE=-1' is handled in the + # 'eval "$ZSHPARSEARGS"' method of using ZSHPARSEARGS() + ;; + + esac + + # return value breaks the conventional "0" = success and "non-0" = failure + # in "parser" functions, the return value must declare _how many arguments were + # parsed_ rather than success/failure status + return ${PARSED} +} + + +# +# for a parser named 'MY_PARSER()', the optional 'MY_PARSER.safety()' function +# will check and see _IF_ the parser should be used. All safety functions are run +# at the very beginning of ZSHPARSEARGS. +# +# when the '.safety()' function succeeds, the parser is used +# when the '.safety()' function fails, the parser is SKIPPED +# +# when the '.safety()' function does not exist, the parser is used +# +utils.parse.help.safety() { + # skip this parser with NO_DEFAULT_HELP=true + [[ ${NO_DEFAULT_HELP} =~ true ]] && return 1 + + # skip this parser if no usage value + function are defined + [ "${USAGE}" ] && command -v utils.io.usage &>/dev/null || return 1 +} + + +# +# for a parser named 'MY_PARSER()', the optional 'MY_PARSER.usage()' function +# updates 'USAGE__*' values. Usage functions are run _after_ safety functions, +# and are ignored if the safety function causes the parser to be skipped. +# +utils.parse.help.usage() { + # + # PARSER.usage functions can be declared to automatically inject the + # proper usage values when the parser is used. + # + # Include an extra "newline" character at the beginning to separate + # the help text by a line + # + USAGE__options+="\n + -h, --help print this message and exit + " +} + + +# +# for a parser named 'MY_PARSER()', the optional 'MY_PARSER.locals()' function +# defines variables which will be local-scoped to the function which is USING +# the parser +# +# this is primarily meant for use in reusable parsers to avoid boilerplate of +# local variable definition in all use cases +# +# out of convenience, any local-scoped variables will also be available +# throughout all MY_PARSER.*() functions +# +# The utils.parse.help parser does not require any local variables, so consider +# the following example: +# +# ------------------------------------------ +# +# my-function() { +# local PARSERS=(MY_PARSER) +# +# eval "${ZSHPARSEARGS}" +# +# echo "my value is ${LOCAL_VARIABLE}" +# } +# # outside of my-function(), the LOCAL_VARIABLE is no longer local-scoped +# # (zsh local-scope "rules" still apply) +# +# MY_PARSER.locals() { +# local LOCAL_VARIABLE +# } +# +# MY_PARSER() { +# local PARSED=0 +# +# case $1 in +# ( --value ) +# PARSED=2 +# LOCAL_VARIABLE=$2 +# ;; +# esac +# +# return ${PARSED} +# } +# +# +# ------------------------------------------ + + +# +# for a parser named 'MY_PARSER()', the optional 'MY_PARSER.validate()' function +# validates parsing errors. Since validate functions are run at the very end of +# ZSHPARSEARGS (after all argument parsing is complete), this is your last chance +# to parsing errors +# +# Note that the return value of this function _is ignored_. You must use the 'ERROR()' +# function to emit errors up to ZSHPARSEARGS +# +# The utils.parse.help parser does not require any validate function, so consider +# the following example: +# +# ------------------------------------------ +# +# MY_PARSER() { +# # local REQUIRED_OPTION +# local PARSED=0 +# +# case $1 in +# ( --my-required-option ) +# PARSED=2 +# REQUIRED_OPTION=$2 +# ;; +# esac +# +# return ${PARSED} +# } +# +# MY_PARSER.validate() { +# [ "${REQUIRED_OPTION}" ] \ +# || echo.error "missing required option '--my-required-option'" +# } +# +# ------------------------------------------ diff --git a/zsh/utils/parse.zsh b/zsh/utils/parse.zsh new file mode 100644 index 0000000..7bd9791 --- /dev/null +++ b/zsh/utils/parse.zsh @@ -0,0 +1,137 @@ +# +# when you don't need to check any special negative cases, +# you can simply set up your PARSERS=() array and other local +# variable declarations, then run the following line: +# +# eval "$ZSHPARSEARGS" +# +# This will populate variables, run all validators, and handle +# the special '--help' case, forcing an early 'return 0' after +# parsing the args. +# +ZSHPARSEARGS=' +utils.parse $@ || { + local ERROR_CODE=$? + case $ERROR_CODE in + ( -1 ) return 0 ;; # -h | --help + ( * ) return $ERROR_CODE ;; + esac +} +' + +utils.parse() { + # + # Parses all arguments using PARSERS array; return value breaks the typical + # success/failure code paradigm: + # + # returns 0 if all arguments were parsed successfully (success) + # returns >0 a count of every argument which failed to parse successfully (failure) + # + # returns -1 if parent program should "return 0" immediately (success, but signal program end; e.g. --help should print usage and return 0) + # + # other _negative return codes_ can be processed in any custom way + # + # + # Makes argument parsing reusable in zsh. Best-practice argument + # parsing involves looping across the $@ args, processing and 'shift'-ing + # arguments until there are none left, but this can lead to a lot + # of boilerplate. While there _are_ utilities to try and simplify this, + # I've found their API to be quite complex and inconsistent across + # different environments. + # + # By including "parser" functions in the 'PARSERS=()' array, you can + # perform parsing logic (first element is highest priority, last element is + # lowest priority). A sample parser function is defined below. + # + # If variable values are set in the caller function, proper usage requires + # declaration of "local VARIABLE_NAME" in that parent caller _before_ + # invoking 'utils.zshparseargs $@' + # + local PARSER VALID_PARSERS=() + local DEFAULT_PARSERS=() + + [[ ${DEFAULT_PARSERS[@]-1} =~ ^utils.parse.help$ ]] \ + && local NO_DEFAULT_PARSERS=true # autosetup preloads default parsers + + [ ${NO_DEFAULT_PARSERS} ] || { + # automatically includes 'MY_FUNCTION.parse()' as 1st parser when parsing for 'MY_FUNCTION()' + [[ ${funcstack[2]} =~ ^[(]eval[)]$ ]] \ + && PARSERS=(${funcstack[3]}.parse ${PARSERS}) \ + || PARSERS=(${funcstack[2]}.parse ${PARSERS}) \ + ; + + PARSERS+=(utils.parse.args utils.parse.help) + } + + for PARSER in ${PARSERS[@]} + do + command -v ${PARSER} &>/dev/null || continue + command -v ${PARSER}.safety &>/dev/null || { + VALID_PARSERS+=(${PARSER}) + continue + } + + ${PARSER}.safety && VALID_PARSERS+=(${PARSER}) + done + + for PARSER in ${VALID_PARSERS[@]} + do + command -v ${PARSER}.usage &>/dev/null && ${PARSER}.usage + done + + local EARLY_ESCAPE_CODE _S ERRORS=0 POSITIONAL_ARGS=0 + while [[ $# -gt 0 ]] + do + _S=0 + for PARSER in ${VALID_PARSERS[@]} + do + ${PARSER} $@ + ((_S+=$?)) + + [ ${EARLY_ESCAPE_CODE} ] && return ${EARLY_ESCAPE_CODE} + + [[ ${_S} -gt 0 ]] && break + done + + [[ ${_S} -gt 0 ]] \ + || echo.error "unknown argument '$1'" \ + || ((_S+=1)) + + + [[ ${_S} -le $# ]] \ + || echo.error "invalid value(s) for '$1'" \ + || _S=$# + + shift ${_S} + done + + for PARSER in ${VALID_PARSERS[@]} + do + command -v ${PARSER}.validate &>/dev/null || continue + + ${PARSER}.validate + done + + utils.check-errors +} + +##################################################################### +### default parsers ################################################# +##################################################################### + +# while it is not recommended to leave so many comments on YOUR parser +# functions, these defaults provide verbose comments to provide you +# how-to-write-parser-functions reference +# +# refer to them in-order if you are trying to write a parser for the +# first time + +source "${0:a:h}/parse.help.zsh" +source "${0:a:h}/parse.args.zsh" + + +##################################################################### +### the easy-but-removed way to go ################################## +##################################################################### + +source "${0:a:h}/parse.autosetup.zsh" diff --git a/zsh/utils/utils.module.zsh b/zsh/utils/utils.module.zsh new file mode 100644 index 0000000..b4a63cf --- /dev/null +++ b/zsh/utils/utils.module.zsh @@ -0,0 +1,94 @@ +##################################################################### + +DEPENDENCIES+=(fzf) # (extensible) list of PATH dependencies +REQUIRED_ENV+=() # (extensible) list of required environment variables + +##################################################################### + +source ${0:a:h}/os.zsh +source ${0:a:h}/parse.zsh + +for __UTILS_FILE in \ + $(find "${0:a:h}/io" -type f | sort) \ + $(find "${0:a:h}/apps" -type f | sort) \ + ; +do + source "${__UTILS_FILE}" +done +unset __UTILS_FILE + +##################################################################### + +source ${0:a:h}/dependencies.zsh +source ${0:a:h}/environment.zsh + +##################################################################### + +utils.check-environment() { + local OPTIONAL=0 + + while [[ $# -gt 0 ]] + do + case $1 in + ( --optional ) OPTIONAL=1 ;; + esac + shift 1 + done + + local ENVIRONMENT_STATUS=0 + + utils.dependencies.check-all + local MISSING_DEPENDENCIES=$? + + utils.environment.check-all + local MISSING_ENVIRONMENT_VARIABLES=$? + + ########################################## + + local ERROR_MESSAGE="" + [[ ${MISSING_DEPENDENCIES} -ne 0 ]] && { + ((ENVIRONMENT_STATUS+=1)) + ERROR_MESSAGE+="\n${MISSING_DEPENDENCIES} missing " + + [[ ${MISSING_DEPENDENCIES} -eq 1 ]] \ + && ERROR_MESSAGE+='dependency' \ + || ERROR_MESSAGE+='dependencies' \ + ; + } + + [[ ${MISSING_ENVIRONMENT_VARIABLES} -ne 0 ]] && { + ((ENVIRONMENT_STATUS+=2)) + ERROR_MESSAGE+="\n${MISSING_ENVIRONMENT_VARIABLES} missing environment variable" + + [[ ${MISSING_ENVIRONMENT_VARIABLES} -gt 1 ]] && ERROR_MESSAGE+=s + } + + [ ${IMPORT_ERRORS} ] && [[ ${IMPORT_ERRORS} -ne 0 ]] && { + ((ENVIRONMENT_STATUS+=4)) + ERROR_MESSAGE+="\n${IMPORT_ERRORS} import error" + + [[ ${IMPORT_ERRORS} -gt 1 ]] && ERROR_MESSAGE+=s + } + + ########################################## + + [[ ENVIRONMENT_STATUS -ne 0 ]] && [[ ${OPTIONAL} -eq 0 ]] && { + ERROR_MESSAGE=$(echo ${ERROR_MESSAGE} | sed '1d; s/^/ /') + ${E} "environment errors found (see above)\n${ERROR_MESSAGE}" + } + + [[ ${MISSING_ENVIRONMENT_VARIABLES} -ne 0 ]] && [[ ${__SCWRYPT} ]] && { + echo.reminder " + to quickly update missing environment variables, run: + 'scwrypts zsh/scwrypts/environment/edit' + " + } + + [[ ${ENVIRONMENT_STATUS} -ne 0 ]] && [[ ${NO_EXIT} -ne 1 ]] && [[ ${OPTIONAL} -eq 0 ]] && { + exit ${ENVIRONMENT_STATUS} + } + + return ${ENVIRONMENT_STATUS} +} + +utils.check-environment diff --git a/zx/lib/package.json b/zx/lib/package.json index 28c43c0..93f8fc9 100644 --- a/zx/lib/package.json +++ b/zx/lib/package.json @@ -1,19 +1,26 @@ { "name": "scwrypts", - "main": "dist/index.js", - "type": "module", - "files": [ - "dist" - ], + "author": "Wryn (yage) Wagner", "description": "scwrypts integration for typescript", + "license": "GPL-3.0", + "type": "module", + "packageManager": "pnpm@9.4.0", "scripts": { "build": "rm -rf ./dist && tsc", "test": "jest", "lint": "eslint . && prettier --check src/", "format": "prettier --write src/" }, - "author": "Wryn (yage) Wagner", - "license": "GPL-3.0", + "main": "dist/index.js", + "files": [ + "dist" + ], + "exports": { + ".": { + "types": "./dist/index.d.js", + "import": "./dist/index.d.js" + } + }, "devDependencies": { "@jest/globals": "^29.7.0", "@types/jest": "^29.5.12", @@ -29,6 +36,9 @@ "typescript": "^5.3.3", "uuid": "^9.0.1" }, + "dependencies": { + "execa": "^8.0.1" + }, "eslintConfig": { "ignorePatterns": [ "dist", @@ -93,8 +103,5 @@ "moduleNameMapper": { "^(\\.{1,2}/.*)\\.js$": "$1" } - }, - "dependencies": { - "execa": "^8.0.1" } } diff --git a/zx/lib/pnpm-lock.yaml b/zx/lib/pnpm-lock.yaml index 2ef3260..f77066f 100644 --- a/zx/lib/pnpm-lock.yaml +++ b/zx/lib/pnpm-lock.yaml @@ -1,86 +1,1688 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - execa: - specifier: ^8.0.1 - version: 8.0.1 +importers: -devDependencies: - '@jest/globals': - specifier: ^29.7.0 - version: 29.7.0 - '@types/jest': - specifier: ^29.5.12 - version: 29.5.12 - '@types/node': - specifier: ^20.11.19 - version: 20.11.19 - '@types/uuid': - specifier: ^9.0.8 - version: 9.0.8 - '@typescript-eslint/eslint-plugin': - specifier: ^7.0.2 - version: 7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.3.3) - '@typescript-eslint/parser': - specifier: ^7.0.2 - version: 7.0.2(eslint@8.56.0)(typescript@5.3.3) - eslint: - specifier: ^8.56.0 - version: 8.56.0 - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) - prettier: - specifier: ^3.2.5 - version: 3.2.5 - ts-jest: - specifier: ^29.1.2 - version: 29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.3.3) - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@20.11.19)(typescript@5.3.3) - typescript: - specifier: ^5.3.3 - version: 5.3.3 - uuid: - specifier: ^9.0.1 - version: 9.0.1 + .: + dependencies: + execa: + specifier: ^8.0.1 + version: 8.0.1 + devDependencies: + '@jest/globals': + specifier: ^29.7.0 + version: 29.7.0 + '@types/jest': + specifier: ^29.5.12 + version: 29.5.12 + '@types/node': + specifier: ^20.11.19 + version: 20.11.19 + '@types/uuid': + specifier: ^9.0.8 + version: 9.0.8 + '@typescript-eslint/eslint-plugin': + specifier: ^7.0.2 + version: 7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.3.3) + '@typescript-eslint/parser': + specifier: ^7.0.2 + version: 7.0.2(eslint@8.56.0)(typescript@5.3.3) + eslint: + specifier: ^8.56.0 + version: 8.56.0 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.11.19)(ts-node@10.9.2) + prettier: + specifier: ^3.2.5 + version: 3.2.5 + ts-jest: + specifier: ^29.1.2 + version: 29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.3.3) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.11.19)(typescript@5.3.3) + typescript: + specifier: ^5.3.3 + version: 5.3.3 + uuid: + specifier: ^9.0.1 + version: 9.0.1 packages: - /@aashutoshrathi/word-wrap@1.2.6: + '@aashutoshrathi/word-wrap@1.2.6': resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} - dev: true - /@ampproject/remapping@2.2.1: + '@ampproject/remapping@2.2.1': resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.23.5': + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.23.5': + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.23.9': + resolution: {integrity: sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.23.6': + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.23.6': + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-environment-visitor@7.22.20': + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.23.0': + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.22.5': + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.22.15': + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.23.3': + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.22.5': + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.22.5': + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.22.6': + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.23.4': + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.22.20': + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.23.5': + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.23.9': + resolution: {integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.23.4': + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.23.9': + resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.23.3': + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.23.3': + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.23.9': + resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.23.9': + resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.23.9': + resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.10.0': + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.56.0': + resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.2': + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.3': + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.1.2': + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.22': + resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@tsconfig/node10@1.0.9': + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.5': + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.12': + resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@20.11.19': + resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==} + + '@types/semver@7.5.7': + resolution: {integrity: sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/uuid@9.0.8': + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.32': + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + + '@typescript-eslint/eslint-plugin@7.0.2': + resolution: {integrity: sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.0.2': + resolution: {integrity: sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.0.2': + resolution: {integrity: sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/type-utils@7.0.2': + resolution: {integrity: sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.0.2': + resolution: {integrity: sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/typescript-estree@7.0.2': + resolution: {integrity: sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.0.2': + resolution: {integrity: sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.0.2': + resolution: {integrity: sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.0.1: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001588: + resolution: {integrity: sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + electron-to-chromium@1.4.675: + resolution: {integrity: sha512-+1u3F/XPNIdUwv8i1lDxHAxCvNNU0QIqgb1Ycn+Jnng8ITzWSvUqixRSM7NOazJuwhf65IV17f/VbKj8DmL26A==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.56.0: + resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} + engines: {node: '>= 0.4'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.2: + resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.2.0: + resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.0.4: + resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@1.2.1: + resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-jest@29.1.2: + resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==} + engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + update-browserslist-db@1.0.13: + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@aashutoshrathi/word-wrap@1.2.6': {} + + '@ampproject/remapping@2.2.1': dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.22 - dev: true - /@babel/code-frame@7.23.5: - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} - engines: {node: '>=6.9.0'} + '@babel/code-frame@7.23.5': dependencies: '@babel/highlight': 7.23.4 chalk: 2.4.2 - dev: true - /@babel/compat-data@7.23.5: - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/compat-data@7.23.5': {} - /@babel/core@7.23.9: - resolution: {integrity: sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==} - engines: {node: '>=6.9.0'} + '@babel/core@7.23.9': dependencies: '@ampproject/remapping': 2.2.1 '@babel/code-frame': 7.23.5 @@ -99,61 +1701,38 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true - /@babel/generator@7.23.6: - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} - engines: {node: '>=6.9.0'} + '@babel/generator@7.23.6': dependencies: '@babel/types': 7.23.9 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.22 jsesc: 2.5.2 - dev: true - /@babel/helper-compilation-targets@7.23.6: - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} - engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.23.6': dependencies: '@babel/compat-data': 7.23.5 '@babel/helper-validator-option': 7.23.5 browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 - dev: true - /@babel/helper-environment-visitor@7.22.20: - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-environment-visitor@7.22.20': {} - /@babel/helper-function-name@7.23.0: - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} + '@babel/helper-function-name@7.23.0': dependencies: '@babel/template': 7.23.9 '@babel/types': 7.23.9 - dev: true - /@babel/helper-hoist-variables@7.22.5: - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} + '@babel/helper-hoist-variables@7.22.5': dependencies: '@babel/types': 7.23.9 - dev: true - /@babel/helper-module-imports@7.22.15: - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} - engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.22.15': dependencies: '@babel/types': 7.23.9 - dev: true - /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.23.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-environment-visitor': 7.22.20 @@ -161,211 +1740,118 @@ packages: '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - dev: true - /@babel/helper-plugin-utils@7.22.5: - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-plugin-utils@7.22.5': {} - /@babel/helper-simple-access@7.22.5: - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} + '@babel/helper-simple-access@7.22.5': dependencies: '@babel/types': 7.23.9 - dev: true - /@babel/helper-split-export-declaration@7.22.6: - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} + '@babel/helper-split-export-declaration@7.22.6': dependencies: '@babel/types': 7.23.9 - dev: true - /@babel/helper-string-parser@7.23.4: - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-string-parser@7.23.4': {} - /@babel/helper-validator-identifier@7.22.20: - resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-validator-identifier@7.22.20': {} - /@babel/helper-validator-option@7.23.5: - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-validator-option@7.23.5': {} - /@babel/helpers@7.23.9: - resolution: {integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==} - engines: {node: '>=6.9.0'} + '@babel/helpers@7.23.9': dependencies: '@babel/template': 7.23.9 '@babel/traverse': 7.23.9 '@babel/types': 7.23.9 transitivePeerDependencies: - supports-color - dev: true - /@babel/highlight@7.23.4: - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} - engines: {node: '>=6.9.0'} + '@babel/highlight@7.23.4': dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true - /@babel/parser@7.23.9: - resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} - engines: {node: '>=6.0.0'} - hasBin: true + '@babel/parser@7.23.9': dependencies: '@babel/types': 7.23.9 - dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.9): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.9): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.9): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.9): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.9): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.9): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.9): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.9): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.9): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.9): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.9): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.9): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.9): - resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.9)': dependencies: '@babel/core': 7.23.9 '@babel/helper-plugin-utils': 7.22.5 - dev: true - /@babel/template@7.23.9: - resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} - engines: {node: '>=6.9.0'} + '@babel/template@7.23.9': dependencies: '@babel/code-frame': 7.23.5 '@babel/parser': 7.23.9 '@babel/types': 7.23.9 - dev: true - /@babel/traverse@7.23.9: - resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==} - engines: {node: '>=6.9.0'} + '@babel/traverse@7.23.9': dependencies: '@babel/code-frame': 7.23.5 '@babel/generator': 7.23.6 @@ -379,46 +1865,27 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true - /@babel/types@7.23.9: - resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} - engines: {node: '>=6.9.0'} + '@babel/types@7.23.9': dependencies: '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - dev: true - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true + '@bcoe/v8-coverage@0.2.3': {} - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 - dev: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.4.0(eslint@8.56.0)': dependencies: eslint: 8.56.0 eslint-visitor-keys: 3.4.3 - dev: true - /@eslint-community/regexpp@4.10.0: - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true + '@eslint-community/regexpp@4.10.0': {} - /@eslint/eslintrc@2.1.4: - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 debug: 4.3.4 @@ -431,52 +1898,32 @@ packages: strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - dev: true - /@eslint/js@8.56.0: - resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + '@eslint/js@8.56.0': {} - /@humanwhocodes/config-array@0.11.14: - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.2 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - dev: true - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true + '@humanwhocodes/module-importer@1.0.1': {} - /@humanwhocodes/object-schema@2.0.2: - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} - dev: true + '@humanwhocodes/object-schema@2.0.2': {} - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} + '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 find-up: 4.1.0 get-package-type: 0.1.0 js-yaml: 3.14.1 resolve-from: 5.0.0 - dev: true - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true + '@istanbuljs/schema@0.1.3': {} - /@jest/console@29.7.0: - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 '@types/node': 20.11.19 @@ -484,16 +1931,8 @@ packages: jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - dev: true - /@jest/core@29.7.0(ts-node@10.9.2): - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + '@jest/core@29.7.0(ts-node@10.9.2)': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -527,38 +1966,26 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /@jest/environment@29.7.0: - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/node': 20.11.19 jest-mock: 29.7.0 - dev: true - /@jest/expect-utils@29.7.0: - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 - dev: true - /@jest/expect@29.7.0: - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect@29.7.0': dependencies: expect: 29.7.0 jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - dev: true - /@jest/fake-timers@29.7.0: - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@29.7.0': dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 @@ -566,11 +1993,8 @@ packages: jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 - dev: true - /@jest/globals@29.7.0: - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/globals@29.7.0': dependencies: '@jest/environment': 29.7.0 '@jest/expect': 29.7.0 @@ -578,16 +2002,8 @@ packages: jest-mock: 29.7.0 transitivePeerDependencies: - supports-color - dev: true - /@jest/reporters@29.7.0: - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + '@jest/reporters@29.7.0': dependencies: '@bcoe/v8-coverage': 0.2.3 '@jest/console': 29.7.0 @@ -615,47 +2031,32 @@ packages: v8-to-istanbul: 9.2.0 transitivePeerDependencies: - supports-color - dev: true - /@jest/schemas@29.6.3: - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 - dev: true - /@jest/source-map@29.6.3: - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/source-map@29.6.3': dependencies: '@jridgewell/trace-mapping': 0.3.22 callsites: 3.1.0 graceful-fs: 4.2.11 - dev: true - /@jest/test-result@29.7.0: - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-result@29.7.0': dependencies: '@jest/console': 29.7.0 '@jest/types': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.2 - dev: true - /@jest/test-sequencer@29.7.0: - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-sequencer@29.7.0': dependencies: '@jest/test-result': 29.7.0 graceful-fs: 4.2.11 jest-haste-map: 29.7.0 slash: 3.0.0 - dev: true - /@jest/transform@29.7.0: - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/transform@29.7.0': dependencies: '@babel/core': 7.23.9 '@jest/types': 29.6.3 @@ -674,11 +2075,8 @@ packages: write-file-atomic: 4.0.2 transitivePeerDependencies: - supports-color - dev: true - /@jest/types@29.6.3: - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 @@ -686,198 +2084,118 @@ packages: '@types/node': 20.11.19 '@types/yargs': 17.0.32 chalk: 4.1.2 - dev: true - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.3': dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.22 - dev: true - /@jridgewell/resolve-uri@3.1.2: - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - dev: true + '@jridgewell/resolve-uri@3.1.2': {} - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - dev: true + '@jridgewell/set-array@1.1.2': {} - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true + '@jridgewell/sourcemap-codec@1.4.15': {} - /@jridgewell/trace-mapping@0.3.22: - resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + '@jridgewell/trace-mapping@0.3.22': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true + '@nodelib/fs.stat@2.0.5': {} - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - dev: true - /@sinclair/typebox@0.27.8: - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - dev: true + '@sinclair/typebox@0.27.8': {} - /@sinonjs/commons@3.0.1: - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 - dev: true - /@sinonjs/fake-timers@10.3.0: - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sinonjs/fake-timers@10.3.0': dependencies: '@sinonjs/commons': 3.0.1 - dev: true - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true + '@tsconfig/node10@1.0.9': {} - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true + '@tsconfig/node12@1.0.11': {} - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true + '@tsconfig/node14@1.0.3': {} - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true + '@tsconfig/node16@1.0.4': {} - /@types/babel__core@7.20.5: - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.23.9 '@babel/types': 7.23.9 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.5 - dev: true - /@types/babel__generator@7.6.8: - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + '@types/babel__generator@7.6.8': dependencies: '@babel/types': 7.23.9 - dev: true - /@types/babel__template@7.4.4: - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + '@types/babel__template@7.4.4': dependencies: '@babel/parser': 7.23.9 '@babel/types': 7.23.9 - dev: true - /@types/babel__traverse@7.20.5: - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + '@types/babel__traverse@7.20.5': dependencies: '@babel/types': 7.23.9 - dev: true - /@types/graceful-fs@4.1.9: - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/graceful-fs@4.1.9': dependencies: '@types/node': 20.11.19 - dev: true - /@types/istanbul-lib-coverage@2.0.6: - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - dev: true + '@types/istanbul-lib-coverage@2.0.6': {} - /@types/istanbul-lib-report@3.0.3: - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + '@types/istanbul-lib-report@3.0.3': dependencies: '@types/istanbul-lib-coverage': 2.0.6 - dev: true - /@types/istanbul-reports@3.0.4: - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/istanbul-reports@3.0.4': dependencies: '@types/istanbul-lib-report': 3.0.3 - dev: true - /@types/jest@29.5.12: - resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} + '@types/jest@29.5.12': dependencies: expect: 29.7.0 pretty-format: 29.7.0 - dev: true - /@types/json-schema@7.0.15: - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - dev: true + '@types/json-schema@7.0.15': {} - /@types/node@20.11.19: - resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==} + '@types/node@20.11.19': dependencies: undici-types: 5.26.5 - dev: true - /@types/semver@7.5.7: - resolution: {integrity: sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==} - dev: true + '@types/semver@7.5.7': {} - /@types/stack-utils@2.0.3: - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - dev: true + '@types/stack-utils@2.0.3': {} - /@types/uuid@9.0.8: - resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - dev: true + '@types/uuid@9.0.8': {} - /@types/yargs-parser@21.0.3: - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - dev: true + '@types/yargs-parser@21.0.3': {} - /@types/yargs@17.0.32: - resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + '@types/yargs@17.0.32': dependencies: '@types/yargs-parser': 21.0.3 - dev: true - /@typescript-eslint/eslint-plugin@7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/eslint-plugin@7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.0.2(eslint@8.56.0)(typescript@5.3.3) @@ -895,17 +2213,8 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/parser@7.0.2(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/parser@7.0.2(eslint@8.56.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/scope-manager': 7.0.2 '@typescript-eslint/types': 7.0.2 @@ -916,25 +2225,13 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/scope-manager@7.0.2: - resolution: {integrity: sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/scope-manager@7.0.2': dependencies: '@typescript-eslint/types': 7.0.2 '@typescript-eslint/visitor-keys': 7.0.2 - dev: true - /@typescript-eslint/type-utils@7.0.2(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/type-utils@7.0.2(eslint@8.56.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/typescript-estree': 7.0.2(typescript@5.3.3) '@typescript-eslint/utils': 7.0.2(eslint@8.56.0)(typescript@5.3.3) @@ -944,21 +2241,10 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/types@7.0.2: - resolution: {integrity: sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==} - engines: {node: ^16.0.0 || >=18.0.0} - dev: true + '@typescript-eslint/types@7.0.2': {} - /@typescript-eslint/typescript-estree@7.0.2(typescript@5.3.3): - resolution: {integrity: sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/typescript-estree@7.0.2(typescript@5.3.3)': dependencies: '@typescript-eslint/types': 7.0.2 '@typescript-eslint/visitor-keys': 7.0.2 @@ -971,13 +2257,8 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/utils@7.0.2(eslint@8.56.0)(typescript@5.3.3): - resolution: {integrity: sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^8.56.0 + '@typescript-eslint/utils@7.0.2(eslint@8.56.0)(typescript@5.3.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@types/json-schema': 7.0.15 @@ -990,111 +2271,61 @@ packages: transitivePeerDependencies: - supports-color - typescript - dev: true - /@typescript-eslint/visitor-keys@7.0.2: - resolution: {integrity: sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==} - engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/visitor-keys@7.0.2': dependencies: '@typescript-eslint/types': 7.0.2 eslint-visitor-keys: 3.4.3 - dev: true - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: true + '@ungap/structured-clone@1.2.0': {} - /acorn-jsx@5.3.2(acorn@8.11.3): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-jsx@5.3.2(acorn@8.11.3): dependencies: acorn: 8.11.3 - dev: true - /acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - dev: true + acorn-walk@8.3.2: {} - /acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true + acorn@8.11.3: {} - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - dev: true - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 - dev: true - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true + ansi-regex@5.0.1: {} - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 - dev: true - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - dev: true - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true + ansi-styles@5.2.0: {} - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true + arg@4.1.3: {} - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 - dev: true - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true + argparse@2.0.1: {} - /array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true + array-union@2.1.0: {} - /babel-jest@29.7.0(@babel/core@7.23.9): - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 + babel-jest@29.7.0(@babel/core@7.23.9): dependencies: '@babel/core': 7.23.9 '@jest/transform': 29.7.0 @@ -1106,11 +2337,8 @@ packages: slash: 3.0.0 transitivePeerDependencies: - supports-color - dev: true - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} + babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.22.5 '@istanbuljs/load-nyc-config': 1.1.0 @@ -1119,22 +2347,15 @@ packages: test-exclude: 6.0.0 transitivePeerDependencies: - supports-color - dev: true - /babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.23.9 '@babel/types': 7.23.9 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.5 - dev: true - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.9): - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 + babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.9): dependencies: '@babel/core': 7.23.9 '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.9) @@ -1149,172 +2370,97 @@ packages: '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.9) '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.9) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.9) - dev: true - /babel-preset-jest@29.6.3(@babel/core@7.23.9): - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 + babel-preset-jest@29.6.3(@babel/core@7.23.9): dependencies: '@babel/core': 7.23.9 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.9) - dev: true - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true + balanced-match@1.0.2: {} - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 - dev: true - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} + braces@3.0.2: dependencies: fill-range: 7.0.1 - dev: true - /browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + browserslist@4.23.0: dependencies: caniuse-lite: 1.0.30001588 electron-to-chromium: 1.4.675 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.23.0) - dev: true - /bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} + bs-logger@0.2.6: dependencies: fast-json-stable-stringify: 2.1.0 - dev: true - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + bser@2.1.1: dependencies: node-int64: 0.4.0 - dev: true - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true + buffer-from@1.1.2: {} - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true + callsites@3.1.0: {} - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true + camelcase@5.3.1: {} - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - dev: true + camelcase@6.3.0: {} - /caniuse-lite@1.0.30001588: - resolution: {integrity: sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==} - dev: true + caniuse-lite@1.0.30001588: {} - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - dev: true - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true + char-regex@1.0.2: {} - /ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - dev: true + ci-info@3.9.0: {} - /cjs-module-lexer@1.2.3: - resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} - dev: true + cjs-module-lexer@1.2.3: {} - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: true - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true + co@4.6.0: {} - /collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - dev: true + collect-v8-coverage@1.0.2: {} - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + color-convert@1.9.3: dependencies: color-name: 1.1.3 - dev: true - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + color-convert@2.0.1: dependencies: color-name: 1.1.4 - dev: true - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true + color-name@1.1.3: {} - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true + color-name@1.1.4: {} - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true + concat-map@0.0.1: {} - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true + convert-source-map@2.0.0: {} - /create-jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true + create-jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 @@ -1328,135 +2474,65 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true + create-require@1.1.1: {} - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@4.3.4: dependencies: ms: 2.1.2 - dev: true - /dedent@1.5.1: - resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - dev: true + dedent@1.5.1: {} - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true + deep-is@0.1.4: {} - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - dev: true + deepmerge@4.3.1: {} - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true + detect-newline@3.1.0: {} - /diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + diff-sequences@29.6.3: {} - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true + diff@4.0.2: {} - /dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 - dev: true - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} + doctrine@3.0.0: dependencies: esutils: 2.0.3 - dev: true - /electron-to-chromium@1.4.675: - resolution: {integrity: sha512-+1u3F/XPNIdUwv8i1lDxHAxCvNNU0QIqgb1Ycn+Jnng8ITzWSvUqixRSM7NOazJuwhf65IV17f/VbKj8DmL26A==} - dev: true + electron-to-chromium@1.4.675: {} - /emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - dev: true + emittery@0.13.1: {} - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true + emoji-regex@8.0.0: {} - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 - dev: true - /escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - dev: true + escalade@3.1.2: {} - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true + escape-string-regexp@1.0.5: {} - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true + escape-string-regexp@2.0.0: {} - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true + escape-string-regexp@4.0.0: {} - /eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@7.2.2: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 - dev: true - /eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + eslint-visitor-keys@3.4.3: {} - /eslint@8.56.0: - resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true + eslint@8.56.0: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) '@eslint-community/regexpp': 4.10.0 @@ -1498,50 +2574,28 @@ packages: text-table: 0.2.0 transitivePeerDependencies: - supports-color - dev: true - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + espree@9.6.1: dependencies: acorn: 8.11.3 acorn-jsx: 5.3.2(acorn@8.11.3) eslint-visitor-keys: 3.4.3 - dev: true - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true + esprima@4.0.1: {} - /esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} + esquery@1.5.0: dependencies: estraverse: 5.3.0 - dev: true - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 - dev: true - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true + estraverse@5.3.0: {} - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true + esutils@2.0.3: {} - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + execa@5.1.1: dependencies: cross-spawn: 7.0.3 get-stream: 6.0.1 @@ -1552,11 +2606,8 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 strip-final-newline: 2.0.0 - dev: true - /execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} + execa@8.0.1: dependencies: cross-spawn: 7.0.3 get-stream: 8.0.1 @@ -1567,159 +2618,91 @@ packages: onetime: 6.0.0 signal-exit: 4.1.0 strip-final-newline: 3.0.0 - dev: false - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true + exit@0.1.2: {} - /expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 jest-get-type: 29.6.3 jest-matcher-utils: 29.7.0 jest-message-util: 29.7.0 jest-util: 29.7.0 - dev: true - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true + fast-deep-equal@3.1.3: {} - /fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true + fast-json-stable-stringify@2.1.0: {} - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true + fast-levenshtein@2.0.6: {} - /fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fastq@1.17.1: dependencies: reusify: 1.0.4 - dev: true - /fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fb-watchman@2.0.2: dependencies: bser: 2.1.1 - dev: true - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 - dev: true - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} + fill-range@7.0.1: dependencies: to-regex-range: 5.0.1 - dev: true - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + find-up@4.1.0: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - dev: true - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true - /flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@3.2.0: dependencies: flatted: 3.2.9 keyv: 4.5.4 rimraf: 3.0.2 - dev: true - /flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} - dev: true + flatted@3.2.9: {} - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true + fs.realpath@1.0.0: {} - /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true + fsevents@2.3.3: optional: true - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true + function-bind@1.1.2: {} - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true + gensync@1.0.0-beta.2: {} - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true + get-caller-file@2.0.5: {} - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true + get-package-type@0.1.0: {} - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true + get-stream@6.0.1: {} - /get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - dev: false + get-stream@8.0.1: {} - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - dev: true - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 - dev: true - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + glob@7.2.3: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -1727,23 +2710,14 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true + globals@11.12.0: {} - /globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} + globals@13.24.0: dependencies: type-fest: 0.20.2 - dev: true - /globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 @@ -1751,148 +2725,75 @@ packages: ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 - dev: true - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true + graceful-fs@4.2.11: {} - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true + graphemer@1.4.0: {} - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true + has-flag@3.0.0: {} - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true + has-flag@4.0.0: {} - /hasown@2.0.1: - resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} - engines: {node: '>= 0.4'} + hasown@2.0.1: dependencies: function-bind: 1.1.2 - dev: true - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true + html-escaper@2.0.2: {} - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true + human-signals@2.1.0: {} - /human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - dev: false + human-signals@5.0.0: {} - /ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - dev: true + ignore@5.3.1: {} - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true - /import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true + import-local@3.1.0: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - dev: true - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true + imurmurhash@0.1.4: {} - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + inflight@1.0.6: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: true - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true + inherits@2.0.4: {} - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true + is-arrayish@0.2.1: {} - /is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.13.1: dependencies: hasown: 2.0.1 - dev: true - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true + is-extglob@2.1.1: {} - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true + is-fullwidth-code-point@3.0.0: {} - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true + is-generator-fn@2.1.0: {} - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - dev: true - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true + is-number@7.0.0: {} - /is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true + is-path-inside@3.0.3: {} - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true + is-stream@2.0.1: {} - /is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: false + is-stream@3.0.0: {} - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@2.0.0: {} - /istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - dev: true + istanbul-lib-coverage@3.2.2: {} - /istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} + istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.23.9 '@babel/parser': 7.23.9 @@ -1901,11 +2802,8 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true - /istanbul-lib-instrument@6.0.2: - resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} - engines: {node: '>=10'} + istanbul-lib-instrument@6.0.2: dependencies: '@babel/core': 7.23.9 '@babel/parser': 7.23.9 @@ -1914,48 +2812,33 @@ packages: semver: 7.6.0 transitivePeerDependencies: - supports-color - dev: true - /istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} + istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 - dev: true - /istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} + istanbul-lib-source-maps@4.0.1: dependencies: debug: 4.3.4 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color - dev: true - /istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - dev: true - /jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 jest-util: 29.7.0 p-limit: 3.1.0 - dev: true - /jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-circus@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/expect': 29.7.0 @@ -1980,17 +2863,8 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: true - /jest-cli@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest-cli@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/test-result': 29.7.0 @@ -2008,19 +2882,8 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /jest-config@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true + jest-config@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): dependencies: '@babel/core': 7.23.9 '@jest/test-sequencer': 29.7.0 @@ -2049,39 +2912,27 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: true - /jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-diff@29.7.0: dependencies: chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.7.0 - dev: true - /jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 - dev: true - /jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-each@29.7.0: dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 jest-get-type: 29.6.3 jest-util: 29.7.0 pretty-format: 29.7.0 - dev: true - /jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-node@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 @@ -2089,16 +2940,10 @@ packages: '@types/node': 20.11.19 jest-mock: 29.7.0 jest-util: 29.7.0 - dev: true - /jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + jest-get-type@29.6.3: {} - /jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 @@ -2113,29 +2958,20 @@ packages: walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 - dev: true - /jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-leak-detector@29.7.0: dependencies: jest-get-type: 29.6.3 pretty-format: 29.7.0 - dev: true - /jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 jest-diff: 29.7.0 jest-get-type: 29.6.3 pretty-format: 29.7.0 - dev: true - /jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.23.5 '@jest/types': 29.6.3 @@ -2146,47 +2982,27 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 - dev: true - /jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 20.11.19 jest-util: 29.7.0 - dev: true - /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): dependencies: jest-resolve: 29.7.0 - dev: true - /jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + jest-regex-util@29.6.3: {} - /jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve-dependencies@29.7.0: dependencies: jest-regex-util: 29.6.3 jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - dev: true - /jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve@29.7.0: dependencies: chalk: 4.1.2 graceful-fs: 4.2.11 @@ -2197,11 +3013,8 @@ packages: resolve: 1.22.8 resolve.exports: 2.0.2 slash: 3.0.0 - dev: true - /jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runner@29.7.0: dependencies: '@jest/console': 29.7.0 '@jest/environment': 29.7.0 @@ -2226,11 +3039,8 @@ packages: source-map-support: 0.5.13 transitivePeerDependencies: - supports-color - dev: true - /jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runtime@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 @@ -2256,11 +3066,8 @@ packages: strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - dev: true - /jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-snapshot@29.7.0: dependencies: '@babel/core': 7.23.9 '@babel/generator': 7.23.6 @@ -2284,11 +3091,8 @@ packages: semver: 7.6.0 transitivePeerDependencies: - supports-color - dev: true - /jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 20.11.19 @@ -2296,11 +3100,8 @@ packages: ci-info: 3.9.0 graceful-fs: 4.2.11 picomatch: 2.3.1 - dev: true - /jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-validate@29.7.0: dependencies: '@jest/types': 29.6.3 camelcase: 6.3.0 @@ -2308,11 +3109,8 @@ packages: jest-get-type: 29.6.3 leven: 3.1.0 pretty-format: 29.7.0 - dev: true - /jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-watcher@29.7.0: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 @@ -2322,27 +3120,15 @@ packages: emittery: 0.13.1 jest-util: 29.7.0 string-length: 4.0.2 - dev: true - /jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@29.7.0: dependencies: '@types/node': 20.11.19 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - dev: true - /jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest@29.7.0(@types/node@20.11.19)(ts-node@10.9.2): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 @@ -2353,232 +3139,127 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true + js-tokens@4.0.0: {} - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true + js-yaml@3.14.1: dependencies: argparse: 1.0.10 esprima: 4.0.1 - dev: true - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + js-yaml@4.1.0: dependencies: argparse: 2.0.1 - dev: true - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true + jsesc@2.5.2: {} - /json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: true + json-buffer@3.0.1: {} - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true + json-parse-even-better-errors@2.3.1: {} - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true + json-schema-traverse@0.4.1: {} - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true + json-stable-stringify-without-jsonify@1.0.1: {} - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true + json5@2.2.3: {} - /keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 - dev: true - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true + kleur@3.0.3: {} - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true + leven@3.1.0: {} - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true + lines-and-columns@1.2.4: {} - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 - dev: true - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 - dev: true - /lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - dev: true + lodash.memoize@4.1.2: {} - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true + lodash.merge@4.6.2: {} - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 - dev: true - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + lru-cache@6.0.0: dependencies: yallist: 4.0.0 - dev: true - /make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + make-dir@4.0.0: dependencies: semver: 7.6.0 - dev: true - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true + make-error@1.3.6: {} - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + makeerror@1.0.12: dependencies: tmpl: 1.0.5 - dev: true - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge-stream@2.0.0: {} - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true + merge2@1.4.1: {} - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} + micromatch@4.0.5: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true + mimic-fn@2.1.0: {} - /mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - dev: false + mimic-fn@4.0.0: {} - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - dev: true - /minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.3: dependencies: brace-expansion: 2.0.1 - dev: true - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true + ms@2.1.2: {} - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true + natural-compare@1.4.0: {} - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true + node-int64@0.4.0: {} - /node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - dev: true + node-releases@2.0.14: {} - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true + normalize-path@3.0.0: {} - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 - dev: true - /npm-run-path@5.2.0: - resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + npm-run-path@5.2.0: dependencies: path-key: 4.0.0 - dev: false - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + once@1.4.0: dependencies: wrappy: 1.0.2 - dev: true - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + onetime@5.1.2: dependencies: mimic-fn: 2.1.0 - dev: true - /onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 - dev: false - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} + optionator@0.9.3: dependencies: '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 @@ -2586,398 +3267,200 @@ packages: levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + p-limit@2.3.0: dependencies: p-try: 2.2.0 - dev: true - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - dev: true - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + p-locate@4.1.0: dependencies: p-limit: 2.3.0 - dev: true - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - dev: true - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true + p-try@2.2.0: {} - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + parent-module@1.0.1: dependencies: callsites: 3.1.0 - dev: true - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.23.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: true - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true + path-exists@4.0.0: {} - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true + path-is-absolute@1.0.1: {} - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + path-key@3.1.1: {} - /path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - dev: false + path-key@4.0.0: {} - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true + path-parse@1.0.7: {} - /path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true + path-type@4.0.0: {} - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true + picocolors@1.0.0: {} - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true + picomatch@2.3.1: {} - /pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - dev: true + pirates@4.0.6: {} - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 - dev: true - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true + prelude-ls@1.2.1: {} - /prettier@3.2.5: - resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} - engines: {node: '>=14'} - hasBin: true - dev: true + prettier@3.2.5: {} - /pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.2.0 - dev: true - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + prompts@2.4.2: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 - dev: true - /punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - dev: true + punycode@2.3.1: {} - /pure-rand@6.0.4: - resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==} - dev: true + pure-rand@6.0.4: {} - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true + queue-microtask@1.2.3: {} - /react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true + react-is@18.2.0: {} - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true + require-directory@2.1.1: {} - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 - dev: true - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true + resolve-from@4.0.0: {} - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true + resolve-from@5.0.0: {} - /resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - dev: true + resolve.exports@2.0.2: {} - /resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true + resolve@1.22.8: dependencies: is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true + reusify@1.0.4: {} - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true + rimraf@3.0.2: dependencies: glob: 7.2.3 - dev: true - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - dev: true - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - dev: true + semver@6.3.1: {} - /semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} - hasBin: true + semver@7.6.0: dependencies: lru-cache: 6.0.0 - dev: true - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + shebang-regex@3.0.0: {} - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true + signal-exit@3.0.7: {} - /signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - dev: false + signal-exit@4.1.0: {} - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true + sisteransi@1.0.5: {} - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true + slash@3.0.0: {} - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true + source-map@0.6.1: {} - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true + sprintf-js@1.0.3: {} - /stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 - dev: true - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} + string-length@4.0.2: dependencies: char-regex: 1.0.2 strip-ansi: 6.0.1 - dev: true - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: true - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - dev: true - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true + strip-bom@4.0.0: {} - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true + strip-final-newline@2.0.0: {} - /strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - dev: false + strip-final-newline@3.0.0: {} - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true + strip-json-comments@3.1.1: {} - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 - dev: true - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: true - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + supports-color@8.1.1: dependencies: has-flag: 4.0.0 - dev: true - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true + supports-preserve-symlinks-flag@1.0.0: {} - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 - dev: true - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true + text-table@0.2.0: {} - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true + tmpl@1.0.5: {} - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true + to-fast-properties@2.0.0: {} - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - dev: true - /ts-api-utils@1.2.1(typescript@5.3.3): - resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' + ts-api-utils@1.2.1(typescript@5.3.3): dependencies: typescript: 5.3.3 - dev: true - /ts-jest@29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.3.3): - resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==} - engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true + ts-jest@29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.3.3): dependencies: '@babel/core': 7.23.9 bs-logger: 0.2.6 @@ -2990,21 +3473,8 @@ packages: semver: 7.6.0 typescript: 5.3.3 yargs-parser: 21.1.1 - dev: true - /ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3): - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true + ts-node@10.9.2(@types/node@20.11.19)(typescript@5.3.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.9 @@ -3021,130 +3491,71 @@ packages: typescript: 5.3.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - dev: true - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - dev: true - /type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true + type-detect@4.0.8: {} - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true + type-fest@0.20.2: {} - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true + type-fest@0.21.3: {} - /typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} - hasBin: true - dev: true + typescript@5.3.3: {} - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true + undici-types@5.26.5: {} - /update-browserslist-db@1.0.13(browserslist@4.23.0): - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + update-browserslist-db@1.0.13(browserslist@4.23.0): dependencies: browserslist: 4.23.0 escalade: 3.1.2 picocolors: 1.0.0 - dev: true - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + uri-js@4.4.1: dependencies: punycode: 2.3.1 - dev: true - /uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - dev: true + uuid@9.0.1: {} - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true + v8-compile-cache-lib@3.0.1: {} - /v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} - engines: {node: '>=10.12.0'} + v8-to-istanbul@9.2.0: dependencies: '@jridgewell/trace-mapping': 0.3.22 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - dev: true - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + walker@1.0.8: dependencies: makeerror: 1.0.12 - dev: true - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + which@2.0.2: dependencies: isexe: 2.0.0 - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true + wrappy@1.0.2: {} - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@4.0.2: dependencies: imurmurhash: 0.1.4 signal-exit: 3.0.7 - dev: true - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true + y18n@5.0.8: {} - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true + yallist@3.1.1: {} - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true + yallist@4.0.0: {} - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true + yargs-parser@21.1.1: {} - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + yargs@17.7.2: dependencies: cliui: 8.0.1 escalade: 3.1.2 @@ -3153,14 +3564,7 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: true - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true + yn@3.1.1: {} - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + yocto-queue@0.1.0: {} diff --git a/zx/lib/src/index.ts b/zx/lib/src/index.ts index 910f0c9..1a3f799 100644 --- a/zx/lib/src/index.ts +++ b/zx/lib/src/index.ts @@ -1,5 +1 @@ -export * from './scwrypts/scwrypts.js'; - -export { ScwryptsLogLevel } from './scwrypts/types.js'; - -export type { ScwryptsOptions } from './scwrypts/types.js'; +export * from './scwrypts/index.js'; diff --git a/zx/lib/src/scwrypts/get-scwrypts-lookup.test.ts b/zx/lib/src/scwrypts/__tests__/get-scwrypts-lookup.ts similarity index 90% rename from zx/lib/src/scwrypts/get-scwrypts-lookup.test.ts rename to zx/lib/src/scwrypts/__tests__/get-scwrypts-lookup.ts index 56fcbc2..9b92026 100644 --- a/zx/lib/src/scwrypts/get-scwrypts-lookup.test.ts +++ b/zx/lib/src/scwrypts/__tests__/get-scwrypts-lookup.ts @@ -2,11 +2,11 @@ import { describe, expect, test, beforeEach, jest } from '@jest/globals'; import { v4 as uuid } from 'uuid'; -import * as parseCLIArgs from './parse-cli-args.js'; +import * as Module_parseCLIArgs from '../parse-cli-args.js'; -import { getScwryptsLookup, Errors } from './get-scwrypts-lookup.js'; +import { getScwryptsLookup, Errors } from '../get-scwrypts-lookup.js'; -import type { ScwryptsOptions } from './types.js'; +import type { ScwryptsOptions } from '../type.scwrypts-options.js'; let sample: any; beforeEach(() => { @@ -15,7 +15,7 @@ beforeEach(() => { spy: {}, }; - sample.spy.parseCLIArgs = jest.spyOn(parseCLIArgs, 'parseCLIArgs'); + sample.spy.parseCLIArgs = jest.spyOn(Module_parseCLIArgs, 'parseCLIArgs'); sample.spy.parseCLIArgs.mockReturnValue(sample.parsedCLIArgs); }); diff --git a/zx/lib/src/scwrypts/parse-cli-args.test.ts b/zx/lib/src/scwrypts/__tests__/parse-cli-args.ts similarity index 93% rename from zx/lib/src/scwrypts/parse-cli-args.test.ts rename to zx/lib/src/scwrypts/__tests__/parse-cli-args.ts index f97c926..8755eef 100644 --- a/zx/lib/src/scwrypts/parse-cli-args.test.ts +++ b/zx/lib/src/scwrypts/__tests__/parse-cli-args.ts @@ -2,7 +2,7 @@ import { describe, expect, test, beforeEach } from '@jest/globals'; import { v4 as uuid } from 'uuid'; -import { parseCLIArgs } from './parse-cli-args.js'; +import { parseCLIArgs } from '../parse-cli-args.js'; let sample: any; beforeEach(() => { diff --git a/zx/lib/src/scwrypts/scwrypts.test.ts b/zx/lib/src/scwrypts/__tests__/scwrypts.ts similarity index 94% rename from zx/lib/src/scwrypts/scwrypts.test.ts rename to zx/lib/src/scwrypts/__tests__/scwrypts.ts index ee529b8..467e77b 100644 --- a/zx/lib/src/scwrypts/scwrypts.test.ts +++ b/zx/lib/src/scwrypts/__tests__/scwrypts.ts @@ -3,11 +3,11 @@ import { describe, expect, test, beforeEach, jest } from '@jest/globals'; import { v4 as uuid } from 'uuid'; import { execa } from 'execa'; -import * as Module_getScwryptsLookup from './get-scwrypts-lookup.js'; -import * as Module_parseCLIArgs from './parse-cli-args.js'; -import { ScwryptsLogLevel } from './types.js'; +import * as Module_getScwryptsLookup from '../get-scwrypts-lookup.js'; +import * as Module_parseCLIArgs from '../parse-cli-args.js'; +import { ScwryptsLogLevel } from '../type.scwrypts-log-level.js'; -import { scwrypts } from './scwrypts.js'; +import { scwrypts } from '../scwrypts.js'; jest.mock('execa', () => ({ execa: jest.fn(() => Promise.resolve()), diff --git a/zx/lib/src/scwrypts/get-scwrypts-lookup.ts b/zx/lib/src/scwrypts/get-scwrypts-lookup.ts index 067bbe8..78d3d92 100644 --- a/zx/lib/src/scwrypts/get-scwrypts-lookup.ts +++ b/zx/lib/src/scwrypts/get-scwrypts-lookup.ts @@ -1,6 +1,6 @@ import { parseCLIArgs } from './parse-cli-args.js'; -import type { ScwryptsOptions } from './types.js'; +import type { ScwryptsOptions } from './type.scwrypts-options.js'; export type ScwryptsLookupOptions = | { diff --git a/zx/lib/src/scwrypts/index.ts b/zx/lib/src/scwrypts/index.ts new file mode 100644 index 0000000..c203fca --- /dev/null +++ b/zx/lib/src/scwrypts/index.ts @@ -0,0 +1,4 @@ +export * from './scwrypts.js'; + +export * from './type.scwrypts-log-level.js'; +export * from './type.scwrypts-options.js'; diff --git a/zx/lib/src/scwrypts/scwrypts.ts b/zx/lib/src/scwrypts/scwrypts.ts index 3b9dd8e..24fb2ea 100644 --- a/zx/lib/src/scwrypts/scwrypts.ts +++ b/zx/lib/src/scwrypts/scwrypts.ts @@ -3,7 +3,7 @@ import { execa } from 'execa'; import { getScwryptsLookup } from './get-scwrypts-lookup.js'; import { parseCLIArgs } from './parse-cli-args.js'; -import type { ScwryptsOptions } from './types.js'; +import type { ScwryptsOptions } from './type.scwrypts-options.js'; export const scwrypts = async (options: ScwryptsOptions) => { const lookup = getScwryptsLookup(options); diff --git a/zx/lib/src/scwrypts/type.scwrypts-log-level.ts b/zx/lib/src/scwrypts/type.scwrypts-log-level.ts new file mode 100644 index 0000000..6c41248 --- /dev/null +++ b/zx/lib/src/scwrypts/type.scwrypts-log-level.ts @@ -0,0 +1,7 @@ +export enum ScwryptsLogLevel { + SILENT = 0, + QUIET = 1, + NORMAL = 2, + WARNING = 3, + DEBUG = 4, +} diff --git a/zx/lib/src/scwrypts/type.scwrypts-options.ts b/zx/lib/src/scwrypts/type.scwrypts-options.ts new file mode 100644 index 0000000..2b46295 --- /dev/null +++ b/zx/lib/src/scwrypts/type.scwrypts-options.ts @@ -0,0 +1,10 @@ +import type { ScwryptsLogLevel } from './type.scwrypts-log-level.js'; + +export type ScwryptsOptions = { + name?: string | undefined; + group?: string | undefined; + type?: string | undefined; + patterns?: string[] | undefined; + log_level?: ScwryptsLogLevel | undefined; + args?: string | string[] | undefined; +}; diff --git a/zx/lib/src/scwrypts/types.ts b/zx/lib/src/scwrypts/types.ts deleted file mode 100644 index 8870614..0000000 --- a/zx/lib/src/scwrypts/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -export type ScwryptsOptions = { - name: string | undefined; - group: string | undefined; - type: string | undefined; - patterns: string[] | undefined; - log_level: ScwryptsLogLevel | undefined; - args: string | string[] | undefined; -}; - -export enum ScwryptsLogLevel { - SILENT = 0, - QUIET = 1, - NORMAL = 2, - WARNING = 3, - DEBUG = 4, -} diff --git a/zx/lib/tsconfig.json b/zx/lib/tsconfig.json index 54f5a6e..83f67cd 100644 --- a/zx/lib/tsconfig.json +++ b/zx/lib/tsconfig.json @@ -14,5 +14,5 @@ "strict": true }, "include": ["src"], - "exclude": ["node_modules", "dist", "extensions", "**/*.test.ts"] + "exclude": ["node_modules", "dist", "**/__tests__/*"] } diff --git a/zx/package-lock.json b/zx/package-lock.json index 3dcd4da..08c1fc5 100644 --- a/zx/package-lock.json +++ b/zx/package-lock.json @@ -1,7 +1,7 @@ { "name": "scwrypts", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -35,137 +35,61 @@ "uuid": "^9.0.1" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/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==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/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==", - "dev": true - }, - "node_modules/@babel/code-frame/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==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/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==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", + "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -185,19 +109,21 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -205,14 +131,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -225,67 +152,36 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -295,88 +191,84 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", + "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -387,6 +279,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -399,6 +292,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -413,6 +307,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -421,13 +316,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "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==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -437,6 +334,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -446,6 +344,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -454,10 +353,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", + "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.2" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -470,6 +373,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -482,6 +386,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -494,6 +399,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -501,11 +407,44 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -518,6 +457,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -526,12 +466,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -545,6 +486,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -557,6 +499,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -569,6 +512,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -581,6 +525,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -593,6 +538,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -605,6 +551,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -612,11 +559,28 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -628,12 +592,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -643,33 +608,32 @@ } }, "node_modules/@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", + "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.2", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -682,18 +646,20 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", + "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -704,13 +670,15 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -723,6 +691,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -733,6 +702,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -744,10 +714,11 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -757,6 +728,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -780,6 +752,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -790,6 +763,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -798,10 +772,11 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -810,7 +785,9 @@ "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -825,6 +802,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -835,6 +813,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -847,6 +826,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -856,16 +836,19 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -882,6 +865,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -891,6 +875,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -904,6 +889,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -917,6 +903,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -929,6 +916,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -944,6 +932,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -956,6 +945,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -965,6 +955,7 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -974,6 +965,7 @@ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -991,6 +983,7 @@ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/reporters": "^29.7.0", @@ -1038,6 +1031,7 @@ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", @@ -1053,6 +1047,7 @@ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.7.0", "jest-snapshot": "^29.7.0" @@ -1066,6 +1061,7 @@ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" }, @@ -1078,6 +1074,7 @@ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", @@ -1095,6 +1092,7 @@ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -1110,6 +1108,7 @@ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^29.7.0", @@ -1153,6 +1152,7 @@ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -1165,6 +1165,7 @@ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", @@ -1179,6 +1180,7 @@ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/types": "^29.6.3", @@ -1194,6 +1196,7 @@ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", @@ -1209,6 +1212,7 @@ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", @@ -1235,6 +1239,7 @@ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -1248,14 +1253,15 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -1266,30 +1272,34 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1300,6 +1310,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1313,6 +1324,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -1322,6 +1334,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1334,13 +1347,15 @@ "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } @@ -1350,39 +1365,45 @@ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -1396,6 +1417,7 @@ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } @@ -1405,16 +1427,18 @@ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" } @@ -1424,6 +1448,7 @@ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1432,13 +1457,15 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -1448,6 +1475,7 @@ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -1457,49 +1485,42 @@ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, "node_modules/@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.16.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz", + "integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, - "node_modules/@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", - "dev": true - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/uuid": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -1508,28 +1529,28 @@ "version": "21.0.3", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz", - "integrity": "sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/type-utils": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1546,19 +1567,20 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.2.tgz", - "integrity": "sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1574,16 +1596,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", - "integrity": "sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1591,18 +1614,19 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz", - "integrity": "sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/utils": "7.0.2", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1618,12 +1642,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", - "integrity": "sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1631,22 +1656,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz", - "integrity": "sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1659,21 +1685,19 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.2.tgz", - "integrity": "sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1684,16 +1708,17 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz", - "integrity": "sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.0.2", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1704,13 +1729,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1723,15 +1750,20 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -1741,6 +1773,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1757,6 +1790,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1772,6 +1806,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -1784,6 +1819,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1793,6 +1829,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1808,6 +1845,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1820,28 +1858,39 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -1863,6 +1912,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -1879,6 +1929,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -1895,6 +1946,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1904,6 +1956,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -1915,23 +1968,27 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -1942,6 +1999,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" @@ -1957,33 +2015,36 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -1999,11 +2060,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2017,6 +2079,7 @@ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -2029,6 +2092,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -2037,13 +2101,15 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2053,14 +2119,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001588", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", - "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", "dev": true, "funding": [ { @@ -2075,13 +2142,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2098,6 +2167,7 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -2113,21 +2183,24 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true, + "license": "MIT" }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2142,6 +2215,7 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -2151,13 +2225,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2169,25 +2245,29 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -2208,12 +2288,14 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "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==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2224,10 +2306,11 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -2241,10 +2324,11 @@ } }, "node_modules/dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "dev": true, + "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -2258,13 +2342,15 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2274,6 +2360,7 @@ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2283,6 +2370,7 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -2292,6 +2380,7 @@ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -2301,6 +2390,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2313,6 +2403,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -2320,17 +2411,35 @@ "node": ">=6.0.0" } }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron-to-chromium": { - "version": "1.4.677", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.677.tgz", - "integrity": "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==", - "dev": true + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.12.tgz", + "integrity": "sha512-tIhPkdlEoCL1Y+PToq3zRNehUaKp3wBX/sr7aclAWdIWjvqAe/Im/H0SiCM4c1Q8BLPHCdoJTol+ZblflydehA==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2342,13 +2451,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -2358,6 +2469,7 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2367,6 +2479,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2375,16 +2488,17 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -2434,6 +2548,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2450,6 +2565,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2462,6 +2578,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2472,6 +2589,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2484,6 +2602,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -2501,6 +2620,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2510,10 +2630,11 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2526,6 +2647,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2538,6 +2660,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2547,6 +2670,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2555,6 +2679,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -2587,6 +2712,7 @@ "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", @@ -2602,13 +2728,15 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2625,6 +2753,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2636,19 +2765,22 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -2658,6 +2790,7 @@ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } @@ -2667,6 +2800,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -2674,11 +2808,35 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2691,6 +2849,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2707,6 +2866,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -2717,16 +2877,18 @@ } }, "node_modules/flatted": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.0.tgz", - "integrity": "sha512-noqGuLw158+DuD9UPRKHpJ2hGxpFyDlYYrfM0mWt4XhT4n0lwzTLh70Tkdyy4kyTmyTT9Bv7bWAJqw7cgkEXDg==", - "dev": true + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -2734,6 +2896,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2747,6 +2910,7 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2756,6 +2920,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -2765,6 +2930,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -2774,6 +2940,7 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -2782,6 +2949,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "license": "MIT", "engines": { "node": ">=16" }, @@ -2793,7 +2961,9 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2814,6 +2984,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -2826,6 +2997,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2836,6 +3008,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2848,6 +3021,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -2863,6 +3037,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -2882,28 +3057,32 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -2915,21 +3094,24 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/human-signals": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -2939,6 +3121,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2951,10 +3134,11 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -2974,6 +3158,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -2982,7 +3167,9 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -2992,21 +3179,27 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3017,6 +3210,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3026,6 +3220,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3035,6 +3230,7 @@ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3044,6 +3240,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -3056,6 +3253,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -3065,6 +3263,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3073,6 +3272,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -3083,22 +3283,25 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", - "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -3115,6 +3318,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -3129,6 +3333,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -3143,6 +3348,7 @@ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -3151,11 +3357,55 @@ "node": ">=8" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -3182,6 +3432,7 @@ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", "jest-util": "^29.7.0", @@ -3196,6 +3447,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -3219,6 +3471,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3231,6 +3484,7 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } @@ -3240,6 +3494,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3252,6 +3507,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3261,6 +3517,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -3273,6 +3530,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -3287,13 +3545,15 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/jest-changed-files/node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3303,6 +3563,7 @@ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -3334,6 +3595,7 @@ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.7.0", "@jest/test-result": "^29.7.0", @@ -3367,6 +3629,7 @@ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^29.7.0", @@ -3412,6 +3675,7 @@ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", @@ -3427,6 +3691,7 @@ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -3439,6 +3704,7 @@ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -3455,6 +3721,7 @@ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -3472,6 +3739,7 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -3481,6 +3749,7 @@ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", @@ -3506,6 +3775,7 @@ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, + "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" @@ -3519,6 +3789,7 @@ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", @@ -3534,6 +3805,7 @@ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -3554,6 +3826,7 @@ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -3568,6 +3841,7 @@ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -3585,6 +3859,7 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -3594,6 +3869,7 @@ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", @@ -3614,6 +3890,7 @@ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, + "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", "jest-snapshot": "^29.7.0" @@ -3627,6 +3904,7 @@ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", "@jest/environment": "^29.7.0", @@ -3659,6 +3937,7 @@ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -3692,6 +3971,7 @@ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", @@ -3723,6 +4003,7 @@ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -3740,6 +4021,7 @@ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", @@ -3757,6 +4039,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3769,6 +4052,7 @@ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, + "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", @@ -3788,6 +4072,7 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -3803,6 +4088,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3817,13 +4103,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -3836,6 +4124,7 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -3847,31 +4136,36 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -3884,6 +4178,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -3893,6 +4188,7 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3902,6 +4198,7 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3911,6 +4208,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3923,13 +4221,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -3944,19 +4244,22 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -3966,6 +4269,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -3980,13 +4284,15 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -3994,24 +4300,27 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -4022,6 +4331,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -4030,10 +4340,11 @@ } }, "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4048,39 +4359,45 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -4095,6 +4412,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -4107,6 +4425,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -4115,6 +4434,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -4126,17 +4446,18 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -4147,6 +4468,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4162,6 +4484,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -4177,6 +4500,7 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4186,6 +4510,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -4198,6 +4523,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -4216,6 +4542,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4225,6 +4552,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4233,6 +4561,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -4241,28 +4570,32 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -4275,6 +4608,7 @@ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -4284,6 +4618,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -4296,6 +4631,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -4309,6 +4645,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -4321,6 +4658,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -4336,6 +4674,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -4348,15 +4687,17 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -4372,6 +4713,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -4386,6 +4728,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4398,6 +4741,7 @@ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -4411,14 +4755,15 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ { @@ -4429,7 +4774,8 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -4449,19 +4795,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4471,6 +4820,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -4488,6 +4838,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -4500,6 +4851,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4509,6 +4861,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4518,6 +4871,7 @@ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -4527,6 +4881,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -4536,7 +4891,9 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -4566,6 +4923,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -4575,13 +4933,11 @@ "link": true }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4589,28 +4945,11 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -4622,6 +4961,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", "engines": { "node": ">=8" } @@ -4630,6 +4970,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", "engines": { "node": ">=14" }, @@ -4641,13 +4982,15 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4657,6 +5000,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -4666,6 +5010,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -4675,13 +5020,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -4694,6 +5041,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4703,6 +5051,7 @@ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -4716,6 +5065,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4730,6 +5080,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4742,6 +5093,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4750,6 +5102,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -4762,6 +5115,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4774,6 +5128,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4786,6 +5141,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4798,6 +5154,7 @@ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -4812,6 +5169,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4822,6 +5180,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4833,19 +5192,22 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4855,6 +5217,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4863,10 +5226,11 @@ } }, "node_modules/ts-api-utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", - "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -4875,12 +5239,14 @@ } }, "node_modules/ts-jest": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", - "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", + "version": "29.2.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.4.tgz", + "integrity": "sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==", "dev": true, + "license": "MIT", "dependencies": { "bs-logger": "0.x", + "ejs": "^3.1.10", "fast-json-stable-stringify": "2.x", "jest-util": "^29.0.0", "json5": "^2.2.3", @@ -4893,10 +5259,11 @@ "ts-jest": "cli.js" }, "engines": { - "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", @@ -4906,6 +5273,9 @@ "@babel/core": { "optional": true }, + "@jest/transform": { + "optional": true + }, "@jest/types": { "optional": true }, @@ -4922,6 +5292,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -4965,6 +5336,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -4977,6 +5349,7 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4986,6 +5359,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -4994,10 +5368,11 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5007,15 +5382,16 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -5031,9 +5407,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -5047,6 +5424,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -5060,6 +5438,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -5068,13 +5447,15 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -5089,6 +5470,7 @@ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } @@ -5097,6 +5479,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5107,11 +5490,22 @@ "node": ">= 8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5128,13 +5522,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -5147,13 +5543,15 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -5162,13 +5560,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -5187,6 +5587,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -5196,6 +5597,7 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5205,6 +5607,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5212,3825 +5615,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "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==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "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==", - "dev": true - }, - "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==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "dev": true - }, - "@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "requires": { - "@babel/types": "^7.22.15" - } - }, - "@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", - "dev": true, - "requires": { - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9" - } - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "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==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "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==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "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==", - "dev": true - }, - "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==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/template": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9" - } - }, - "@babel/traverse": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.9", - "@babel/types": "^7.23.9", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - } - }, - "@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "requires": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - } - }, - "@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "requires": { - "jest-get-type": "^29.6.3" - } - }, - "@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - } - }, - "@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - } - }, - "@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - } - }, - "@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.27.8" - } - }, - "@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "requires": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - } - }, - "@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", - "dev": true, - "requires": { - "@babel/types": "^7.20.7" - } - }, - "@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", - "dev": true, - "requires": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", - "dev": true, - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/semver": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", - "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true - }, - "@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "dev": true - }, - "@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz", - "integrity": "sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/type-utils": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/parser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.2.tgz", - "integrity": "sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", - "integrity": "sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2" - } - }, - "@typescript-eslint/type-utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz", - "integrity": "sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/types": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", - "integrity": "sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz", - "integrity": "sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - } - }, - "@typescript-eslint/utils": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.2.tgz", - "integrity": "sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "semver": "^7.5.4" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz", - "integrity": "sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.0.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "requires": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001588", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", - "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", - "dev": true, - "requires": {} - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "electron-to-chromium": { - "version": "1.4.677", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.677.tgz", - "integrity": "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==", - "dev": true - }, - "emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.0.tgz", - "integrity": "sha512-noqGuLw158+DuD9UPRKHpJ2hGxpFyDlYYrfM0mWt4XhT4n0lwzTLh70Tkdyy4kyTmyTT9Bv7bWAJqw7cgkEXDg==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==" - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==" - }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", - "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", - "dev": true, - "requires": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - } - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "requires": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - } - }, - "jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "dependencies": { - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - } - } - }, - "jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "requires": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - } - }, - "jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - } - }, - "jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true - }, - "jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "requires": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - } - }, - "jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true - }, - "jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "requires": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - } - }, - "jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "requires": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - } - }, - "jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - } - }, - "jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "requires": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "requires": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==" - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", - "requires": { - "path-key": "^4.0.0" - }, - "dependencies": { - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==" - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", - "dev": true - }, - "pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "requires": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "scwrypts": { - "version": "file:lib", - "requires": { - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.12", - "@types/node": "^20.11.19", - "@types/uuid": "^9.0.8", - "@typescript-eslint/eslint-plugin": "^7.0.2", - "@typescript-eslint/parser": "^7.0.2", - "eslint": "^8.56.0", - "execa": "^8.0.1", - "jest": "^29.7.0", - "prettier": "^3.2.5", - "ts-jest": "^29.1.2", - "ts-node": "^10.9.2", - "typescript": "^5.3.3", - "uuid": "^9.0.1" - } - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==" - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-api-utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", - "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", - "dev": true, - "requires": {} - }, - "ts-jest": { - "version": "29.1.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", - "integrity": "sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" - } - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "dependencies": { - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - } - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } }