From e4725c23eb17d5d5a2752d4ded69ba13cc55a02f Mon Sep 17 00:00:00 2001
From: William Will <10997562+willwill96@users.noreply.github.com>
Date: Thu, 30 Mar 2023 02:45:43 -0600
Subject: [PATCH 1/6] feat: add vitest testing
---
package.json | 7 +-
vitest.config.ts | 11 +
yarn.lock | 548 ++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 560 insertions(+), 6 deletions(-)
create mode 100644 vitest.config.ts
diff --git a/package.json b/package.json
index a53c49ca..8f38ac39 100644
--- a/package.json
+++ b/package.json
@@ -12,10 +12,10 @@
"prepare": "yarn generate-i18n-messages",
"build": "rimraf dist/ && tsc -p src/bin && tsc -p src/tsconfig.json && tsc-alias -p src/tsconfig.json && yarn grant-exec-perms && yarn copy-files dist/",
"build:watch": "tsc -p src/tsconfig.json && (concurrently \"tsc -p src/tsconfig.json -w\" \"tsc-alias -p src/tsconfig.json\")",
- "build:test": "rimraf dist_test/ && tsc -p test/tsconfig.json && tsc-alias -p test/tsconfig.json && yarn copy-files dist_test/src",
+ "test:types": "tsc -p test/tsconfig.json --noEmit",
"grant-exec-perms": "node dist/bin/tools/grant-exec-perms.js",
"copy-files": "copyfiles -u 1 src/**/*.ftl",
- "test": "yarn build:test && node dist_test/test/bin && node dist_test/test/lib",
+ "test": "yarn test:types && vitest run",
"test:sample-app": "yarn build:test && node dist_test/test/bin/main.js",
"_format": "prettier '**/*.{ts,tsx,json,md}'",
"format": "yarn _format --write",
@@ -80,7 +80,8 @@
"scripting-tools": "^0.19.13",
"ts-node": "^10.9.1",
"tsc-alias": "^1.8.3",
- "typescript": "^5.0.1-rc"
+ "typescript": "^5.0.1-rc",
+ "vitest": "^0.29.8"
},
"dependencies": {
"@octokit/rest": "^18.12.0",
diff --git a/vitest.config.ts b/vitest.config.ts
new file mode 100644
index 00000000..f372a9c9
--- /dev/null
+++ b/vitest.config.ts
@@ -0,0 +1,11 @@
+///
+import { defineConfig } from "vite";
+import path from "path";
+
+export default defineConfig({
+ test: {
+ alias: {
+ "keycloakify": path.resolve(__dirname, "./src")
+ }
+ }
+});
diff --git a/yarn.lock b/yarn.lock
index 1aa0dc72..c1518ac1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -198,6 +198,116 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
+"@esbuild/android-arm64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.14.tgz#4624cea3c8941c91f9e9c1228f550d23f1cef037"
+ integrity sha512-eLOpPO1RvtsP71afiFTvS7tVFShJBCT0txiv/xjFBo5a7R7Gjw7X0IgIaFoLKhqXYAXhahoXm7qAmRXhY4guJg==
+
+"@esbuild/android-arm@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.14.tgz#74fae60fcab34c3f0e15cb56473a6091ba2b53a6"
+ integrity sha512-0CnlwnjDU8cks0yJLXfkaU/uoLyRf9VZJs4p1PskBr2AlAHeEsFEwJEo0of/Z3g+ilw5mpyDwThlxzNEIxOE4g==
+
+"@esbuild/android-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.14.tgz#f002fbc08d5e939d8314bd23bcfb1e95d029491f"
+ integrity sha512-nrfQYWBfLGfSGLvRVlt6xi63B5IbfHm3tZCdu/82zuFPQ7zez4XjmRtF/wIRYbJQ/DsZrxJdEvYFE67avYXyng==
+
+"@esbuild/darwin-arm64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.14.tgz#b8dcd79a1dd19564950b4ca51d62999011e2e168"
+ integrity sha512-eoSjEuDsU1ROwgBH/c+fZzuSyJUVXQTOIN9xuLs9dE/9HbV/A5IqdXHU1p2OfIMwBwOYJ9SFVGGldxeRCUJFyw==
+
+"@esbuild/darwin-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.14.tgz#4b49f195d9473625efc3c773fc757018f2c0d979"
+ integrity sha512-zN0U8RWfrDttdFNkHqFYZtOH8hdi22z0pFm0aIJPsNC4QQZv7je8DWCX5iA4Zx6tRhS0CCc0XC2m7wKsbWEo5g==
+
+"@esbuild/freebsd-arm64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.14.tgz#480923fd38f644c6342c55e916cc7c231a85eeb7"
+ integrity sha512-z0VcD4ibeZWVQCW1O7szaLxGsx54gcCnajEJMdYoYjLiq4g1jrP2lMq6pk71dbS5+7op/L2Aod+erw+EUr28/A==
+
+"@esbuild/freebsd-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.14.tgz#a6b6b01954ad8562461cb8a5e40e8a860af69cbe"
+ integrity sha512-hd9mPcxfTgJlolrPlcXkQk9BMwNBvNBsVaUe5eNUqXut6weDQH8whcNaKNF2RO8NbpT6GY8rHOK2A9y++s+ehw==
+
+"@esbuild/linux-arm64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.14.tgz#1fe2f39f78183b59f75a4ad9c48d079916d92418"
+ integrity sha512-FhAMNYOq3Iblcj9i+K0l1Fp/MHt+zBeRu/Qkf0LtrcFu3T45jcwB6A1iMsemQ42vR3GBhjNZJZTaCe3VFPbn9g==
+
+"@esbuild/linux-arm@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.14.tgz#18d594a49b64e4a3a05022c005cb384a58056a2a"
+ integrity sha512-BNTl+wSJ1omsH8s3TkQmIIIQHwvwJrU9u1ggb9XU2KTVM4TmthRIVyxSp2qxROJHhZuW/r8fht46/QE8hU8Qvg==
+
+"@esbuild/linux-ia32@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.14.tgz#f7f0182a9cfc0159e0922ed66c805c9c6ef1b654"
+ integrity sha512-91OK/lQ5y2v7AsmnFT+0EyxdPTNhov3y2CWMdizyMfxSxRqHazXdzgBKtlmkU2KYIc+9ZK3Vwp2KyXogEATYxQ==
+
+"@esbuild/linux-loong64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.14.tgz#5f5305fdffe2d71dd9a97aa77d0c99c99409066f"
+ integrity sha512-vp15H+5NR6hubNgMluqqKza85HcGJgq7t6rMH7O3Y6ApiOWPkvW2AJfNojUQimfTp6OUrACUXfR4hmpcENXoMQ==
+
+"@esbuild/linux-mips64el@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.14.tgz#a602e85c51b2f71d2aedfe7f4143b2f92f97f3f5"
+ integrity sha512-90TOdFV7N+fgi6c2+GO9ochEkmm9kBAKnuD5e08GQMgMINOdOFHuYLPQ91RYVrnWwQ5683sJKuLi9l4SsbJ7Hg==
+
+"@esbuild/linux-ppc64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.14.tgz#32d918d782105cbd9345dbfba14ee018b9c7afdf"
+ integrity sha512-NnBGeoqKkTugpBOBZZoktQQ1Yqb7aHKmHxsw43NddPB2YWLAlpb7THZIzsRsTr0Xw3nqiPxbA1H31ZMOG+VVPQ==
+
+"@esbuild/linux-riscv64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.14.tgz#38612e7b6c037dff7022c33f49ca17f85c5dec58"
+ integrity sha512-0qdlKScLXA8MGVy21JUKvMzCYWovctuP8KKqhtE5A6IVPq4onxXhSuhwDd2g5sRCzNDlDjitc5sX31BzDoL5Fw==
+
+"@esbuild/linux-s390x@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.14.tgz#4397dff354f899e72fd035d72af59a700c465ccb"
+ integrity sha512-Hdm2Jo1yaaOro4v3+6/zJk6ygCqIZuSDJHdHaf8nVH/tfOuoEX5Riv03Ka15LmQBYJObUTNS1UdyoMk0WUn9Ww==
+
+"@esbuild/linux-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.14.tgz#6c5cb99891b6c3e0c08369da3ef465e8038ad9c2"
+ integrity sha512-8KHF17OstlK4DuzeF/KmSgzrTWQrkWj5boluiiq7kvJCiQVzUrmSkaBvcLB2UgHpKENO2i6BthPkmUhNDaJsVw==
+
+"@esbuild/netbsd-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.14.tgz#5fa5255a64e9bf3947c1b3bef5e458b50b211994"
+ integrity sha512-nVwpqvb3yyXztxIT2+VsxJhB5GCgzPdk1n0HHSnchRAcxqKO6ghXwHhJnr0j/B+5FSyEqSxF4q03rbA2fKXtUQ==
+
+"@esbuild/openbsd-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.14.tgz#74d14c79dcb6faf446878cc64284aa4e02f5ca6f"
+ integrity sha512-1RZ7uQQ9zcy/GSAJL1xPdN7NDdOOtNEGiJalg/MOzeakZeTrgH/DoCkbq7TaPDiPhWqnDF+4bnydxRqQD7il6g==
+
+"@esbuild/sunos-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.14.tgz#5c7d1c7203781d86c2a9b2ff77bd2f8036d24cfa"
+ integrity sha512-nqMjDsFwv7vp7msrwWRysnM38Sd44PKmW8EzV01YzDBTcTWUpczQg6mGao9VLicXSgW/iookNK6AxeogNVNDZA==
+
+"@esbuild/win32-arm64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.14.tgz#dc36ed84f1390e73b6019ccf0566c80045e5ca3d"
+ integrity sha512-xrD0mccTKRBBIotrITV7WVQAwNJ5+1va6L0H9zN92v2yEdjfAN7864cUaZwJS7JPEs53bDTzKFbfqVlG2HhyKQ==
+
+"@esbuild/win32-ia32@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.14.tgz#0802a107afa9193c13e35de15a94fe347c588767"
+ integrity sha512-nXpkz9bbJrLLyUTYtRotSS3t5b+FOuljg8LgLdINWFs3FfqZMtbnBCZFUmBzQPyxqU87F8Av+3Nco/M3hEcu1w==
+
+"@esbuild/win32-x64@0.17.14":
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.14.tgz#e81fb49de05fed91bf74251c9ca0343f4fc77d31"
+ integrity sha512-gPQmsi2DKTaEgG14hc3CHXHp62k8g6qr0Pas+I4lUxRMugGSATh/Bi8Dgusoz9IQ0IfdrvLpco6kujEIBoaogA==
+
"@jridgewell/gen-mapping@^0.1.0":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
@@ -400,6 +510,18 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
+"@types/chai-subset@^1.3.3":
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.3.tgz#97893814e92abd2c534de422cb377e0e0bdaac94"
+ integrity sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==
+ dependencies:
+ "@types/chai" "*"
+
+"@types/chai@*", "@types/chai@^4.3.4":
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4"
+ integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==
+
"@types/make-fetch-happen@^10.0.1":
version "10.0.1"
resolved "https://registry.yarnpkg.com/@types/make-fetch-happen/-/make-fetch-happen-10.0.1.tgz#9e718d8f5f6ed388e2020bb9b4fbd2dc23009b38"
@@ -480,12 +602,47 @@
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
-acorn-walk@^8.1.1:
+"@vitest/expect@0.29.8":
+ version "0.29.8"
+ resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.29.8.tgz#6ecdd031b4ea8414717d10b65ccd800908384612"
+ integrity sha512-xlcVXn5I5oTq6NiZSY3ykyWixBxr5mG8HYtjvpgg6KaqHm0mvhX18xuwl5YGxIRNt/A5jidd7CWcNHrSvgaQqQ==
+ dependencies:
+ "@vitest/spy" "0.29.8"
+ "@vitest/utils" "0.29.8"
+ chai "^4.3.7"
+
+"@vitest/runner@0.29.8":
+ version "0.29.8"
+ resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.29.8.tgz#ede8a7be8a074ea1180bc1d1595bd879ed15971c"
+ integrity sha512-FzdhnRDwEr/A3Oo1jtIk/B952BBvP32n1ObMEb23oEJNO+qO5cBet6M2XWIDQmA7BDKGKvmhUf2naXyp/2JEwQ==
+ dependencies:
+ "@vitest/utils" "0.29.8"
+ p-limit "^4.0.0"
+ pathe "^1.1.0"
+
+"@vitest/spy@0.29.8":
+ version "0.29.8"
+ resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.29.8.tgz#2e0c3b30e04d317b2197e3356234448aa432e131"
+ integrity sha512-VdjBe9w34vOMl5I5mYEzNX8inTxrZ+tYUVk9jxaZJmHFwmDFC/GV3KBFTA/JKswr3XHvZL+FE/yq5EVhb6pSAw==
+ dependencies:
+ tinyspy "^1.0.2"
+
+"@vitest/utils@0.29.8":
+ version "0.29.8"
+ resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.29.8.tgz#423da85fd0c6633f3ab496cf7d2fc0119b850df8"
+ integrity sha512-qGzuf3vrTbnoY+RjjVVIBYfuWMjn3UMUqyQtdGNZ6ZIIyte7B37exj6LaVkrZiUTvzSadVvO/tJm8AEgbGCBPg==
+ dependencies:
+ cli-truncate "^3.1.0"
+ diff "^5.1.0"
+ loupe "^2.3.6"
+ pretty-format "^27.5.1"
+
+acorn-walk@^8.1.1, acorn-walk@^8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
-acorn@^8.4.1:
+acorn@^8.4.1, acorn@^8.8.1, acorn@^8.8.2:
version "8.8.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
@@ -536,6 +693,11 @@ ansi-regex@^5.0.1:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+ansi-regex@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
+ integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
+
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -550,6 +712,16 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
+ansi-styles@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
+ integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
+
+ansi-styles@^6.0.0:
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
+ integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
+
anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
@@ -568,6 +740,11 @@ array-union@^2.1.0:
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+assertion-error@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
+ integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
+
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
@@ -635,6 +812,11 @@ browserslist@^4.21.3:
node-releases "^2.0.8"
update-browserslist-db "^1.0.10"
+cac@^6.7.14:
+ version "6.7.14"
+ resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959"
+ integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==
+
cacache@^17.0.0:
version "17.0.4"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.0.4.tgz#5023ed892ba8843e3b7361c26d0ada37e146290c"
@@ -664,6 +846,19 @@ caniuse-lite@^1.0.30001449:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301"
integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==
+chai@^4.3.7:
+ version "4.3.7"
+ resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51"
+ integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==
+ dependencies:
+ assertion-error "^1.1.0"
+ check-error "^1.0.2"
+ deep-eql "^4.1.2"
+ get-func-name "^2.0.0"
+ loupe "^2.3.1"
+ pathval "^1.1.1"
+ type-detect "^4.0.5"
+
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -696,6 +891,11 @@ character-reference-invalid@^1.0.0:
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
+check-error@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
+ integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
+
cheerio-select@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4"
@@ -773,6 +973,14 @@ cli-truncate@2.1.0, cli-truncate@^2.1.0:
slice-ansi "^3.0.0"
string-width "^4.2.0"
+cli-truncate@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389"
+ integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==
+ dependencies:
+ slice-ansi "^5.0.0"
+ string-width "^5.0.0"
+
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
@@ -941,13 +1149,20 @@ date-fns@^2.29.1:
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8"
integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==
-debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.2, debug@^4.3.3:
+debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
+deep-eql@^4.1.2:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d"
+ integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==
+ dependencies:
+ type-detect "^4.0.0"
+
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@@ -968,6 +1183,11 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+diff@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
+ integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==
+
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@@ -1005,6 +1225,11 @@ domutils@^3.0.1:
domelementtype "^2.3.0"
domhandler "^5.0.1"
+eastasianwidth@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
+ integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
+
electron-to-chromium@^1.4.284:
version "1.4.311"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.311.tgz#953bc9a4767f5ce8ec125f9a1ad8e00e8f67e479"
@@ -1015,6 +1240,11 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+emoji-regex@^9.2.2:
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
+ integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+
encoding@^0.1.13:
version "0.1.13"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
@@ -1046,6 +1276,34 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
+esbuild@^0.17.5:
+ version "0.17.14"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.14.tgz#d61a22de751a3133f3c6c7f9c1c3e231e91a3245"
+ integrity sha512-vOO5XhmVj/1XQR9NQ1UPq6qvMYL7QFJU57J5fKBKBKxp17uDt5PgxFDb4A2nEiXhr1qQs4x0F5+66hVVw4ruNw==
+ optionalDependencies:
+ "@esbuild/android-arm" "0.17.14"
+ "@esbuild/android-arm64" "0.17.14"
+ "@esbuild/android-x64" "0.17.14"
+ "@esbuild/darwin-arm64" "0.17.14"
+ "@esbuild/darwin-x64" "0.17.14"
+ "@esbuild/freebsd-arm64" "0.17.14"
+ "@esbuild/freebsd-x64" "0.17.14"
+ "@esbuild/linux-arm" "0.17.14"
+ "@esbuild/linux-arm64" "0.17.14"
+ "@esbuild/linux-ia32" "0.17.14"
+ "@esbuild/linux-loong64" "0.17.14"
+ "@esbuild/linux-mips64el" "0.17.14"
+ "@esbuild/linux-ppc64" "0.17.14"
+ "@esbuild/linux-riscv64" "0.17.14"
+ "@esbuild/linux-s390x" "0.17.14"
+ "@esbuild/linux-x64" "0.17.14"
+ "@esbuild/netbsd-x64" "0.17.14"
+ "@esbuild/openbsd-x64" "0.17.14"
+ "@esbuild/sunos-x64" "0.17.14"
+ "@esbuild/win32-arm64" "0.17.14"
+ "@esbuild/win32-ia32" "0.17.14"
+ "@esbuild/win32-x64" "0.17.14"
+
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -1158,6 +1416,11 @@ fsevents@~2.3.2:
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+function-bind@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+ integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@@ -1168,6 +1431,11 @@ get-caller-file@^2.0.5:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+get-func-name@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
+ integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
+
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -1235,6 +1503,13 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+has@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
+ integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+ dependencies:
+ function-bind "^1.1.1"
+
html-to-react@^1.3.4:
version "1.5.0"
resolved "https://registry.yarnpkg.com/html-to-react/-/html-to-react-1.5.0.tgz#6e0cf47ae1b091ba2f28a3832389fbce4d199ccc"
@@ -1382,6 +1657,13 @@ is-buffer@^2.0.0:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
+is-core-module@^2.9.0:
+ version "2.11.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
+ integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
+ dependencies:
+ has "^1.0.3"
+
is-decimal@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5"
@@ -1397,6 +1679,11 @@ is-fullwidth-code-point@^3.0.0:
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+is-fullwidth-code-point@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88"
+ integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==
+
is-glob@^4.0.1, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
@@ -1479,6 +1766,11 @@ json5@^2.2.2:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+jsonc-parser@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
+ integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
+
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@@ -1518,6 +1810,11 @@ listr2@^3.12.2:
through "^2.3.8"
wrap-ansi "^7.0.0"
+local-pkg@^0.4.2:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963"
+ integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==
+
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
@@ -1552,6 +1849,13 @@ loose-envify@^1.1.0, loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
+loupe@^2.3.1, loupe@^2.3.6:
+ version "2.3.6"
+ resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53"
+ integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==
+ dependencies:
+ get-func-name "^2.0.0"
+
lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
@@ -1751,6 +2055,16 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+mlly@^1.1.0, mlly@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.2.0.tgz#f0f6c2fc8d2d12ea6907cd869066689b5031b613"
+ integrity sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==
+ dependencies:
+ acorn "^8.8.2"
+ pathe "^1.1.0"
+ pkg-types "^1.0.2"
+ ufo "^1.1.1"
+
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
@@ -1766,6 +2080,11 @@ mylas@^2.1.9:
resolved "https://registry.yarnpkg.com/mylas/-/mylas-2.1.13.tgz#1e23b37d58fdcc76e15d8a5ed23f9ae9fc0cbdf4"
integrity sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==
+nanoid@^3.3.4:
+ version "3.3.6"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
+ integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
+
negotiator@^0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
@@ -1841,6 +2160,13 @@ p-limit@^3.0.2:
dependencies:
yocto-queue "^0.1.0"
+p-limit@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644"
+ integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==
+ dependencies:
+ yocto-queue "^1.0.0"
+
p-locate@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
@@ -1919,11 +2245,26 @@ path-key@^3.0.0, path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+path-parse@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
+ integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+pathe@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.0.tgz#e2e13f6c62b31a3289af4ba19886c230f295ec03"
+ integrity sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==
+
+pathval@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
+ integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
+
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
@@ -1941,6 +2282,15 @@ pkg-dir@^5.0.0:
dependencies:
find-up "^5.0.0"
+pkg-types@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.2.tgz#c233efc5210a781e160e0cafd60c0d0510a4b12e"
+ integrity sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==
+ dependencies:
+ jsonc-parser "^3.2.0"
+ mlly "^1.1.1"
+ pathe "^1.1.0"
+
please-upgrade-node@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
@@ -1955,11 +2305,29 @@ plimit-lit@^1.2.6:
dependencies:
queue-lit "^1.5.0"
+postcss@^8.4.21:
+ version "8.4.21"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4"
+ integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==
+ dependencies:
+ nanoid "^3.3.4"
+ picocolors "^1.0.0"
+ source-map-js "^1.0.2"
+
prettier@^2.3.0:
version "2.8.4"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3"
integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==
+pretty-format@^27.5.1:
+ version "27.5.1"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
+ integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==
+ dependencies:
+ ansi-regex "^5.0.1"
+ ansi-styles "^5.0.0"
+ react-is "^17.0.1"
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -2009,6 +2377,11 @@ react-is@^16.13.1, react-is@^16.8.6:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+react-is@^17.0.1:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
+ integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+
react-markdown@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-5.0.3.tgz#41040ea7a9324b564b328fb81dd6c04f2a5373ac"
@@ -2079,6 +2452,15 @@ resolve-from@^4.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
+resolve@^1.22.1:
+ version "1.22.1"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
+ integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
+ dependencies:
+ is-core-module "^2.9.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
restore-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
@@ -2114,6 +2496,13 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
+rollup@^3.18.0:
+ version "3.20.2"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.20.2.tgz#f798c600317f216de2e4ad9f4d9ab30a89b690ff"
+ integrity sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==
+ optionalDependencies:
+ fsevents "~2.3.2"
+
run-exclusive@^2.2.18:
version "2.2.18"
resolved "https://registry.yarnpkg.com/run-exclusive/-/run-exclusive-2.2.18.tgz#ec930edc3a7044750dc827df9372bde8f610f586"
@@ -2189,6 +2578,11 @@ shell-quote@^1.7.3:
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba"
integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==
+siginfo@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30"
+ integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==
+
signal-exit@^3.0.2, signal-exit@^3.0.3:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
@@ -2217,6 +2611,14 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"
+slice-ansi@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a"
+ integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==
+ dependencies:
+ ansi-styles "^6.0.0"
+ is-fullwidth-code-point "^4.0.0"
+
smart-buffer@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
@@ -2239,6 +2641,16 @@ socks@^2.6.2:
ip "^2.0.0"
smart-buffer "^4.2.0"
+source-map-js@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
+ integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+
+source-map@^0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
@@ -2251,6 +2663,16 @@ ssri@^10.0.0:
dependencies:
minipass "^4.0.0"
+stackback@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b"
+ integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==
+
+std-env@^3.3.1:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.3.2.tgz#af27343b001616015534292178327b202b9ee955"
+ integrity sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==
+
string-argv@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
@@ -2265,6 +2687,15 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
+string-width@^5.0.0:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
+ integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
+ dependencies:
+ eastasianwidth "^0.2.0"
+ emoji-regex "^9.2.2"
+ strip-ansi "^7.0.1"
+
string.prototype.codepointat@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz#004ad44c8afc727527b108cd462b4d971cd469bc"
@@ -2298,11 +2729,25 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
dependencies:
ansi-regex "^5.0.1"
+strip-ansi@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
+ integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==
+ dependencies:
+ ansi-regex "^6.0.1"
+
strip-final-newline@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+strip-literal@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-1.0.1.tgz#0115a332710c849b4e46497891fb8d585e404bd2"
+ integrity sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==
+ dependencies:
+ acorn "^8.8.2"
+
supports-color@8.1.1, supports-color@^8.1.0:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
@@ -2324,6 +2769,11 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
+supports-preserve-symlinks-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+
tar@^6.1.11:
version "6.1.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b"
@@ -2349,6 +2799,21 @@ through@^2.3.8:
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
+tinybench@^2.3.1:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.4.0.tgz#83f60d9e5545353610fe7993bd783120bc20c7a7"
+ integrity sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==
+
+tinypool@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.4.0.tgz#3cf3ebd066717f9f837e8d7d31af3c127fdb5446"
+ integrity sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==
+
+tinyspy@^1.0.2:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-1.1.1.tgz#0cb91d5157892af38cb2d217f5c7e8507a5bf092"
+ integrity sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==
+
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -2417,6 +2882,11 @@ tslib@^2.1.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
+type-detect@^4.0.0, type-detect@^4.0.5:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
+ integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
+
type-fest@^0.21.3:
version "0.21.3"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
@@ -2427,6 +2897,11 @@ typescript@^5.0.1-rc:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.2.tgz#891e1a90c5189d8506af64b9ef929fca99ba1ee5"
integrity sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==
+ufo@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.1.1.tgz#e70265e7152f3aba425bd013d150b2cdf4056d7c"
+ integrity sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==
+
unified@^9.0.0:
version "9.2.2"
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975"
@@ -2533,6 +3008,60 @@ vfile@^4.0.0:
unist-util-stringify-position "^2.0.0"
vfile-message "^2.0.0"
+vite-node@0.29.8:
+ version "0.29.8"
+ resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.29.8.tgz#6a1c9d4fb31e7b4e0f825d3a37abe3404e52bd8e"
+ integrity sha512-b6OtCXfk65L6SElVM20q5G546yu10/kNrhg08afEoWlFRJXFq9/6glsvSVY+aI6YeC1tu2TtAqI2jHEQmOmsFw==
+ dependencies:
+ cac "^6.7.14"
+ debug "^4.3.4"
+ mlly "^1.1.0"
+ pathe "^1.1.0"
+ picocolors "^1.0.0"
+ vite "^3.0.0 || ^4.0.0"
+
+"vite@^3.0.0 || ^4.0.0":
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-4.2.1.tgz#6c2eb337b0dfd80a9ded5922163b94949d7fc254"
+ integrity sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==
+ dependencies:
+ esbuild "^0.17.5"
+ postcss "^8.4.21"
+ resolve "^1.22.1"
+ rollup "^3.18.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+vitest@^0.29.8:
+ version "0.29.8"
+ resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.29.8.tgz#9c13cfa007c3511e86c26e1fe9a686bb4dbaec80"
+ integrity sha512-JIAVi2GK5cvA6awGpH0HvH/gEG9PZ0a/WoxdiV3PmqK+3CjQMf8c+J/Vhv4mdZ2nRyXFw66sAg6qz7VNkaHfDQ==
+ dependencies:
+ "@types/chai" "^4.3.4"
+ "@types/chai-subset" "^1.3.3"
+ "@types/node" "*"
+ "@vitest/expect" "0.29.8"
+ "@vitest/runner" "0.29.8"
+ "@vitest/spy" "0.29.8"
+ "@vitest/utils" "0.29.8"
+ acorn "^8.8.1"
+ acorn-walk "^8.2.0"
+ cac "^6.7.14"
+ chai "^4.3.7"
+ debug "^4.3.4"
+ local-pkg "^0.4.2"
+ pathe "^1.1.0"
+ picocolors "^1.0.0"
+ source-map "^0.6.1"
+ std-env "^3.3.1"
+ strip-literal "^1.0.0"
+ tinybench "^2.3.1"
+ tinypool "^0.4.0"
+ tinyspy "^1.0.2"
+ vite "^3.0.0 || ^4.0.0"
+ vite-node "0.29.8"
+ why-is-node-running "^2.2.2"
+
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
@@ -2558,6 +3087,14 @@ which@^2.0.1:
dependencies:
isexe "^2.0.0"
+why-is-node-running@^2.2.2:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.2.2.tgz#4185b2b4699117819e7154594271e7e344c9973e"
+ integrity sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==
+ dependencies:
+ siginfo "^2.0.0"
+ stackback "0.0.2"
+
wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
@@ -2652,6 +3189,11 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+yocto-queue@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
+ integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==
+
zod@^3.17.10:
version "3.20.6"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.20.6.tgz#2f2f08ff81291d47d99e86140fedb4e0db08361a"
From 58bb4037870ac3e5f778cd4c268d8380d2b4c14c Mon Sep 17 00:00:00 2001
From: William Will <10997562+willwill96@users.noreply.github.com>
Date: Thu, 30 Mar 2023 02:46:25 -0600
Subject: [PATCH 2/6] test: refactor existing tests to vitest
---
test/bin/index.ts | 1 -
test/bin/main.ts | 1 -
...tic.ts => replaceImportFromStatic.spec.ts} | 460 +++++++++---------
.../{getKcContext.ts => getKcContext.spec.ts} | 99 ++--
test/lib/index.ts | 1 -
.../tools/AndByDiscriminatingKey.type.spec.ts | 94 ++++
test/lib/tools/AndByDiscriminatingKey.type.ts | 91 ----
test/tools/assertIsSameCode.ts | 7 -
test/tools/isSameCode.ts | 5 +
9 files changed, 367 insertions(+), 392 deletions(-)
delete mode 100644 test/bin/index.ts
rename test/bin/{replaceImportFromStatic.ts => replaceImportFromStatic.spec.ts} (55%)
rename test/lib/{getKcContext.ts => getKcContext.spec.ts} (77%)
delete mode 100644 test/lib/index.ts
create mode 100644 test/lib/tools/AndByDiscriminatingKey.type.spec.ts
delete mode 100644 test/lib/tools/AndByDiscriminatingKey.type.ts
delete mode 100644 test/tools/assertIsSameCode.ts
create mode 100644 test/tools/isSameCode.ts
diff --git a/test/bin/index.ts b/test/bin/index.ts
deleted file mode 100644
index 6cbf91c6..00000000
--- a/test/bin/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-import "./replaceImportFromStatic";
diff --git a/test/bin/main.ts b/test/bin/main.ts
index 08be679b..531d4b3d 100644
--- a/test/bin/main.ts
+++ b/test/bin/main.ts
@@ -1,4 +1,3 @@
-import "./replaceImportFromStatic";
import { setupSampleReactProject, sampleReactProjectDirPath } from "./setupSampleReactProject";
import * as st from "scripting-tools";
import * as fs from "fs";
diff --git a/test/bin/replaceImportFromStatic.ts b/test/bin/replaceImportFromStatic.spec.ts
similarity index 55%
rename from test/bin/replaceImportFromStatic.ts
rename to test/bin/replaceImportFromStatic.spec.ts
index e66d97a3..c7894aca 100644
--- a/test/bin/replaceImportFromStatic.ts
+++ b/test/bin/replaceImportFromStatic.spec.ts
@@ -1,11 +1,12 @@
import { replaceImportsFromStaticInJsCode } from "keycloakify/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode";
import { generateCssCodeToDefineGlobals, replaceImportsInCssCode } from "keycloakify/bin/keycloakify/replacers/replaceImportsInCssCode";
import { replaceImportsInInlineCssCode } from "keycloakify/bin/keycloakify/replacers/replaceImportsInInlineCssCode";
-import { assert } from "tsafe/assert";
import { same } from "evt/tools/inDepth/same";
-import { assetIsSameCode } from "../tools/assertIsSameCode";
+import { expect, it, describe } from "vitest";
-{
+import { isSameCode } from "../tools/isSameCode";
+
+describe("bin/js-transforms", () => {
const jsCodeUntransformed = `
function f() {
return a.p+"static/js/" + ({}[e] || e) + "." + {
@@ -32,8 +33,7 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
}[e]+".chunk.css"
}
`;
-
- {
+ it("transforms standalone code properly", () => {
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
"jsCode": jsCodeUntransformed,
"buildOptions": {
@@ -89,10 +89,9 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
`;
- assetIsSameCode(fixedJsCode, fixedJsCodeExpected);
- }
-
- {
+ expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true);
+ });
+ it("transforms external app code properly", () => {
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
"jsCode": jsCodeUntransformed,
"buildOptions": {
@@ -150,126 +149,128 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
}
`;
- assetIsSameCode(fixedJsCode, fixedJsCodeExpected);
- }
-}
+ expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true);
+ });
+});
-{
- const { fixedCssCode, cssGlobalsToDefine } = replaceImportsInCssCode({
- "cssCode": `
+describe("bin/css-transforms", () => {
+ it("transforms absolute urls to css globals properly with no urlPathname", () => {
+ const { fixedCssCode, cssGlobalsToDefine } = replaceImportsInCssCode({
+ "cssCode": `
+ .my-div {
+ background: url(/logo192.png) no-repeat center center;
+ }
+
+ .my-div2 {
+ background: url(/logo192.png) no-repeat center center;
+ }
+
+ .my-div {
+ background-image: url(/static/media/something.svg);
+ }
+ `
+ });
+
+ const fixedCssCodeExpected = `
.my-div {
- background: url(/logo192.png) no-repeat center center;
+ background: var(--url1f9ef5a892c104c);
}
-
+
.my-div2 {
- background: url(/logo192.png) no-repeat center center;
+ background: var(--url1f9ef5a892c104c);
}
-
+
.my-div {
- background-image: url(/static/media/something.svg);
+ background-image: var(--urldd75cab58377c19);
}
- `
+ `;
+
+ expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true);
+
+ const cssGlobalsToDefineExpected = {
+ "url1f9ef5a892c104c": "url(/logo192.png) no-repeat center center",
+ "urldd75cab58377c19": "url(/static/media/something.svg)"
+ };
+
+ expect(same(cssGlobalsToDefine, cssGlobalsToDefineExpected)).toBe(true);
+
+ const { cssCodeToPrependInHead } = generateCssCodeToDefineGlobals({
+ cssGlobalsToDefine,
+ "buildOptions": {
+ "urlPathname": undefined
+ }
+ });
+
+ const cssCodeToPrependInHeadExpected = `
+ :root {
+ --url1f9ef5a892c104c: url(\${url.resourcesPath}/build/logo192.png) no-repeat center center;
+ --urldd75cab58377c19: url(\${url.resourcesPath}/build/static/media/something.svg);
+ }
+ `;
+
+ expect(isSameCode(cssCodeToPrependInHead, cssCodeToPrependInHeadExpected)).toBe(true);
});
+ it("transforms absolute urls to css globals properly with custom urlPathname", () => {
+ const { fixedCssCode, cssGlobalsToDefine } = replaceImportsInCssCode({
+ "cssCode": `
+ .my-div {
+ background: url(/x/y/z/logo192.png) no-repeat center center;
+ }
+
+ .my-div2 {
+ background: url(/x/y/z/logo192.png) no-repeat center center;
+ }
+
+ .my-div {
+ background-image: url(/x/y/z/static/media/something.svg);
+ }
+ `
+ });
- const fixedCssCodeExpected = `
- .my-div {
- background: var(--url1f9ef5a892c104c);
- }
-
- .my-div2 {
- background: var(--url1f9ef5a892c104c);
- }
-
- .my-div {
- background-image: var(--urldd75cab58377c19);
- }
- `;
-
- assetIsSameCode(fixedCssCode, fixedCssCodeExpected);
-
- const cssGlobalsToDefineExpected = {
- "url1f9ef5a892c104c": "url(/logo192.png) no-repeat center center",
- "urldd75cab58377c19": "url(/static/media/something.svg)"
- };
-
- assert(same(cssGlobalsToDefine, cssGlobalsToDefineExpected));
-
- const { cssCodeToPrependInHead } = generateCssCodeToDefineGlobals({
- cssGlobalsToDefine,
- "buildOptions": {
- "urlPathname": undefined
- }
- });
-
- const cssCodeToPrependInHeadExpected = `
- :root {
- --url1f9ef5a892c104c: url(\${url.resourcesPath}/build/logo192.png) no-repeat center center;
- --urldd75cab58377c19: url(\${url.resourcesPath}/build/static/media/something.svg);
- }
- `;
-
- assetIsSameCode(cssCodeToPrependInHead, cssCodeToPrependInHeadExpected);
-}
-
-{
- const { fixedCssCode, cssGlobalsToDefine } = replaceImportsInCssCode({
- "cssCode": `
+ const fixedCssCodeExpected = `
.my-div {
- background: url(/x/y/z/logo192.png) no-repeat center center;
+ background: var(--urlf8277cddaa2be78);
}
-
+
.my-div2 {
- background: url(/x/y/z/logo192.png) no-repeat center center;
+ background: var(--urlf8277cddaa2be78);
}
-
+
.my-div {
- background-image: url(/x/y/z/static/media/something.svg);
+ background-image: var(--url8bdc0887b97ac9a);
}
- `
+ `;
+
+ expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true);
+
+ const cssGlobalsToDefineExpected = {
+ "urlf8277cddaa2be78": "url(/x/y/z/logo192.png) no-repeat center center",
+ "url8bdc0887b97ac9a": "url(/x/y/z/static/media/something.svg)"
+ };
+
+ expect(same(cssGlobalsToDefine, cssGlobalsToDefineExpected)).toBe(true);
+
+ const { cssCodeToPrependInHead } = generateCssCodeToDefineGlobals({
+ cssGlobalsToDefine,
+ "buildOptions": {
+ "urlPathname": "/x/y/z/"
+ }
+ });
+
+ const cssCodeToPrependInHeadExpected = `
+ :root {
+ --urlf8277cddaa2be78: url(\${url.resourcesPath}/build/logo192.png) no-repeat center center;
+ --url8bdc0887b97ac9a: url(\${url.resourcesPath}/build/static/media/something.svg);
+ }
+ `;
+
+ expect(isSameCode(cssCodeToPrependInHead, cssCodeToPrependInHeadExpected)).toBe(true);
});
+});
- const fixedCssCodeExpected = `
- .my-div {
- background: var(--urlf8277cddaa2be78);
- }
-
- .my-div2 {
- background: var(--urlf8277cddaa2be78);
- }
-
- .my-div {
- background-image: var(--url8bdc0887b97ac9a);
- }
- `;
-
- assetIsSameCode(fixedCssCode, fixedCssCodeExpected);
-
- const cssGlobalsToDefineExpected = {
- "urlf8277cddaa2be78": "url(/x/y/z/logo192.png) no-repeat center center",
- "url8bdc0887b97ac9a": "url(/x/y/z/static/media/something.svg)"
- };
-
- assert(same(cssGlobalsToDefine, cssGlobalsToDefineExpected));
-
- const { cssCodeToPrependInHead } = generateCssCodeToDefineGlobals({
- cssGlobalsToDefine,
- "buildOptions": {
- "urlPathname": "/x/y/z/"
- }
- });
-
- const cssCodeToPrependInHeadExpected = `
- :root {
- --urlf8277cddaa2be78: url(\${url.resourcesPath}/build/logo192.png) no-repeat center center;
- --url8bdc0887b97ac9a: url(\${url.resourcesPath}/build/static/media/something.svg);
- }
- `;
-
- assetIsSameCode(cssCodeToPrependInHead, cssCodeToPrependInHeadExpected);
-}
-
-{
- const cssCode = `
+describe("bin/css-inline-transforms", () => {
+ describe("no url pathName", () => {
+ const cssCode = `
@font-face {
font-family: "Work Sans";
font-style: normal;
@@ -299,17 +300,16 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
src: url("/fonts/WorkSans/worksans-bold-webfont.woff2") format("woff2");
}
`;
+ it("transforms css for standalone app properly", () => {
+ const { fixedCssCode } = replaceImportsInInlineCssCode({
+ cssCode,
+ "buildOptions": {
+ "isStandalone": true,
+ "urlPathname": undefined
+ }
+ });
- {
- const { fixedCssCode } = replaceImportsInInlineCssCode({
- cssCode,
- "buildOptions": {
- "isStandalone": true,
- "urlPathname": undefined
- }
- });
-
- const fixedCssCodeExpected = `
+ const fixedCssCodeExpected = `
@font-face {
font-family: "Work Sans";
font-style: normal;
@@ -344,20 +344,19 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
}
`;
- assetIsSameCode(fixedCssCode, fixedCssCodeExpected);
- }
-
- {
- const { fixedCssCode } = replaceImportsInInlineCssCode({
- cssCode,
- "buildOptions": {
- "isStandalone": false,
- "urlOrigin": "https://demo-app.keycloakify.dev",
- "urlPathname": undefined
- }
+ expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true);
});
+ it("transforms css for external app properly", () => {
+ const { fixedCssCode } = replaceImportsInInlineCssCode({
+ cssCode,
+ "buildOptions": {
+ "isStandalone": false,
+ "urlOrigin": "https://demo-app.keycloakify.dev",
+ "urlPathname": undefined
+ }
+ });
- const fixedCssCodeExpected = `
+ const fixedCssCodeExpected = `
@font-face {
font-family: "Work Sans";
font-style: normal;
@@ -392,12 +391,12 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
}
`;
- assetIsSameCode(fixedCssCode, fixedCssCodeExpected);
- }
-}
+ expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true);
+ });
+ });
-{
- const cssCode = `
+ describe("with url pathName", () => {
+ const cssCode = `
@font-face {
font-family: "Work Sans";
font-style: normal;
@@ -427,101 +426,98 @@ import { assetIsSameCode } from "../tools/assertIsSameCode";
src: url("/x/y/z/fonts/WorkSans/worksans-bold-webfont.woff2") format("woff2");
}
`;
+ it("transforms css for standalone app properly", () => {
+ const { fixedCssCode } = replaceImportsInInlineCssCode({
+ cssCode,
+ "buildOptions": {
+ "isStandalone": true,
+ "urlPathname": "/x/y/z/"
+ }
+ });
- {
- const { fixedCssCode } = replaceImportsInInlineCssCode({
- cssCode,
- "buildOptions": {
- "isStandalone": true,
- "urlPathname": "/x/y/z/"
- }
+ const fixedCssCodeExpected = `
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-regular-webfont.woff2)
+ format("woff2");
+ }
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-medium-webfont.woff2)
+ format("woff2");
+ }
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-semibold-webfont.woff2)
+ format("woff2");
+ }
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-bold-webfont.woff2)
+ format("woff2");
+ }
+ `;
+
+ expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true);
});
+ it("transforms css for external app properly", () => {
+ const { fixedCssCode } = replaceImportsInInlineCssCode({
+ cssCode,
+ "buildOptions": {
+ "isStandalone": false,
+ "urlOrigin": "https://demo-app.keycloakify.dev",
+ "urlPathname": "/x/y/z/"
+ }
+ });
- const fixedCssCodeExpected = `
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 400;
- font-display: swap;
- src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-regular-webfont.woff2)
- format("woff2");
- }
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 500;
- font-display: swap;
- src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-medium-webfont.woff2)
- format("woff2");
- }
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 600;
- font-display: swap;
- src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-semibold-webfont.woff2)
- format("woff2");
- }
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 700;
- font-display: swap;
- src: url(\${url.resourcesPath}/build/fonts/WorkSans/worksans-bold-webfont.woff2)
- format("woff2");
- }
- `;
+ const fixedCssCodeExpected = `
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+ src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-regular-webfont.woff2)
+ format("woff2");
+ }
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 500;
+ font-display: swap;
+ src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-medium-webfont.woff2)
+ format("woff2");
+ }
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 600;
+ font-display: swap;
+ src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-semibold-webfont.woff2)
+ format("woff2");
+ }
+ @font-face {
+ font-family: "Work Sans";
+ font-style: normal;
+ font-weight: 700;
+ font-display: swap;
+ src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-bold-webfont.woff2)
+ format("woff2");
+ }
+ `;
- assetIsSameCode(fixedCssCode, fixedCssCodeExpected);
- }
-
- {
- const { fixedCssCode } = replaceImportsInInlineCssCode({
- cssCode,
- "buildOptions": {
- "isStandalone": false,
- "urlOrigin": "https://demo-app.keycloakify.dev",
- "urlPathname": "/x/y/z/"
- }
+ expect(isSameCode(fixedCssCode, fixedCssCodeExpected)).toBe(true);
});
-
- const fixedCssCodeExpected = `
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 400;
- font-display: swap;
- src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-regular-webfont.woff2)
- format("woff2");
- }
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 500;
- font-display: swap;
- src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-medium-webfont.woff2)
- format("woff2");
- }
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 600;
- font-display: swap;
- src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-semibold-webfont.woff2)
- format("woff2");
- }
- @font-face {
- font-family: "Work Sans";
- font-style: normal;
- font-weight: 700;
- font-display: swap;
- src: url(https://demo-app.keycloakify.dev/x/y/z/fonts/WorkSans/worksans-bold-webfont.woff2)
- format("woff2");
- }
- `;
-
- assetIsSameCode(fixedCssCode, fixedCssCodeExpected);
- }
-}
-
-console.log("PASS replace import from static");
+ });
+});
diff --git a/test/lib/getKcContext.ts b/test/lib/getKcContext.spec.ts
similarity index 77%
rename from test/lib/getKcContext.ts
rename to test/lib/getKcContext.spec.ts
index f52364aa..20023fff 100644
--- a/test/lib/getKcContext.ts
+++ b/test/lib/getKcContext.spec.ts
@@ -1,13 +1,14 @@
-import { getKcContext } from "../../src/login/kcContext/getKcContext";
-import type { ExtendKcContext } from "../../src/login/kcContext/getKcContextFromWindow";
-import type { KcContext } from "../../src/login/kcContext";
+import { getKcContext } from "keycloakify/login/kcContext/getKcContext";
+import type { ExtendKcContext } from "keycloakify/login/kcContext/getKcContextFromWindow";
+import type { KcContext } from "keycloakify/login/kcContext";
import { same } from "evt/tools/inDepth";
import { assert } from "tsafe/assert";
import type { Equals } from "tsafe";
-import { kcContextMocks, kcContextCommonMock } from "../../src/login/kcContext/kcContextMocks";
-import { deepClone } from "../../src/tools/deepClone";
+import { kcContextMocks, kcContextCommonMock } from "keycloakify/login/kcContext/kcContextMocks";
+import { deepClone } from "keycloakify/tools/deepClone";
+import { expect, it, describe } from "vitest";
-{
+describe("getKcContext", () => {
const authorizedMailDomains = ["example.com", "another-example.com", "*.yet-another-example.com", "*.example.com", "hello-world.com"];
const displayName = "this is an overwritten common value";
@@ -59,8 +60,7 @@ import { deepClone } from "../../src/tools/deepClone";
return { kcContext };
};
-
- {
+ it("has proper API for login.ftl", () => {
const pageId = "login.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
@@ -69,7 +69,7 @@ import { deepClone } from "../../src/tools/deepClone";
assert>();
- assert(
+ expect(
same(
//NOTE: deepClone for printIfExists or other functions...
deepClone(kcContext),
@@ -81,12 +81,10 @@ import { deepClone } from "../../src/tools/deepClone";
return mock;
})()
)
- );
+ ).toBe(true);
+ });
- console.log(`PASS ${pageId}`);
- }
-
- {
+ it("has a proper API for info.ftl", () => {
const pageId = "info.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
@@ -104,7 +102,7 @@ import { deepClone } from "../../src/tools/deepClone";
>
>();
- assert(
+ expect(
same(
deepClone(kcContext),
(() => {
@@ -115,12 +113,9 @@ import { deepClone } from "../../src/tools/deepClone";
return mock;
})()
)
- );
-
- console.log(`PASS ${pageId}`);
- }
-
- {
+ ).toBe(true);
+ });
+ it("has a proper API for register.ftl", () => {
const pageId = "register.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
@@ -138,7 +133,7 @@ import { deepClone } from "../../src/tools/deepClone";
>
>();
- assert(
+ expect(
same(
deepClone(kcContext),
(() => {
@@ -149,12 +144,9 @@ import { deepClone } from "../../src/tools/deepClone";
return mock;
})()
)
- );
-
- console.log(`PASS ${pageId}`);
- }
-
- {
+ ).toBe(true);
+ });
+ it("has a proper API for my-extra-page-2.ftl", () => {
const pageId = "my-extra-page-2.ftl";
const { kcContext } = getKcContextProxy({ "mockPageId": pageId });
@@ -173,7 +165,7 @@ import { deepClone } from "../../src/tools/deepClone";
kcContext.aNonStandardValue2;
- assert(
+ expect(
same(
deepClone(kcContext),
(() => {
@@ -184,12 +176,9 @@ import { deepClone } from "../../src/tools/deepClone";
return mock;
})()
)
- );
-
- console.log(`PASS ${pageId}`);
- }
-
- {
+ ).toBe(true);
+ });
+ it("has a proper API for my-extra-page-1.ftl", () => {
const pageId = "my-extra-page-1.ftl";
console.log("We expect a warning here =>");
@@ -200,7 +189,7 @@ import { deepClone } from "../../src/tools/deepClone";
assert>();
- assert(
+ expect(
same(
deepClone(kcContext),
(() => {
@@ -211,32 +200,24 @@ import { deepClone } from "../../src/tools/deepClone";
return mock;
})()
)
- );
-
- console.log(`PASS ${pageId}`);
- }
-}
-
-{
- const pageId = "login.ftl";
-
- const { kcContext } = getKcContext({
- "mockPageId": pageId
+ ).toBe(true);
});
+ it("returns the proper mock for login.ftl", () => {
+ const pageId = "login.ftl";
- assert>();
+ const { kcContext } = getKcContext({
+ "mockPageId": pageId
+ });
- assert(same(deepClone(kcContext), deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!)));
+ assert>();
- console.log("PASS no extension");
-}
+ assert(same(deepClone(kcContext), deepClone(kcContextMocks.find(({ pageId: pageId_i }) => pageId_i === pageId)!)));
+ });
+ it("returns the proper mock for login.ftl", () => {
+ const { kcContext } = getKcContext();
-{
- const { kcContext } = getKcContext();
+ assert>();
- assert>();
-
- assert(kcContext === undefined);
-
- console.log("PASS no extension, no mock");
-}
+ assert(kcContext === undefined);
+ });
+});
diff --git a/test/lib/index.ts b/test/lib/index.ts
deleted file mode 100644
index 8df0b5d4..00000000
--- a/test/lib/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-import "./getKcContext";
diff --git a/test/lib/tools/AndByDiscriminatingKey.type.spec.ts b/test/lib/tools/AndByDiscriminatingKey.type.spec.ts
new file mode 100644
index 00000000..8edb9f87
--- /dev/null
+++ b/test/lib/tools/AndByDiscriminatingKey.type.spec.ts
@@ -0,0 +1,94 @@
+import { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
+import { assert } from "tsafe/assert";
+import type { Equals } from "tsafe";
+import { it, describe } from "vitest";
+
+// These test case names are intentionally vague, because I'm not sure what each are testing individually
+describe("AndByDiscriminatingKey", () => {
+ it("Test Case 1", () => {
+ type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
+
+ type Extension = { pageId: "a"; onlyExtA: string } | { pageId: "b"; onlyExtB: string } | { pageId: "only ext"; onlyExt: string };
+
+ type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
+
+ type Expected =
+ | { pageId: "a"; onlyA: string; onlyExtA: string }
+ | { pageId: "b"; onlyB: string; onlyExtB: string }
+ | { pageId: "only base"; onlyBase: string }
+ | { pageId: "only ext"; onlyExt: string };
+
+ assert>();
+
+ const x: Got = {} as any;
+
+ if (x.pageId === "a") {
+ x.onlyA;
+ x.onlyExtA;
+
+ //@ts-expect-error
+ x.onlyB;
+
+ //@ts-expect-error
+ x.onlyBase;
+
+ //@ts-expect-error
+ x.onlyExt;
+ }
+
+ if (x.pageId === "b") {
+ x.onlyB;
+ x.onlyExtB;
+
+ //@ts-expect-error
+ x.onlyA;
+
+ //@ts-expect-error
+ x.onlyBase;
+
+ //@ts-expect-error
+ x.onlyExt;
+ }
+
+ if (x.pageId === "only base") {
+ x.onlyBase;
+
+ //@ts-expect-error
+ x.onlyA;
+
+ //@ts-expect-error
+ x.onlyB;
+
+ //@ts-expect-error
+ x.onlyExt;
+ }
+
+ if (x.pageId === "only ext") {
+ x.onlyExt;
+
+ //@ts-expect-error
+ x.onlyA;
+
+ //@ts-expect-error
+ x.onlyB;
+
+ //@ts-expect-error
+ x.onlyBase;
+ }
+ });
+ it("Test Case 2", () => {
+ type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
+
+ type Extension = { pageId: "only ext"; onlyExt: string };
+
+ type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
+
+ type Expected =
+ | { pageId: "a"; onlyA: string }
+ | { pageId: "b"; onlyB: string }
+ | { pageId: "only base"; onlyBase: string }
+ | { pageId: "only ext"; onlyExt: string };
+
+ assert>();
+ });
+});
diff --git a/test/lib/tools/AndByDiscriminatingKey.type.ts b/test/lib/tools/AndByDiscriminatingKey.type.ts
deleted file mode 100644
index f45e897f..00000000
--- a/test/lib/tools/AndByDiscriminatingKey.type.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import { AndByDiscriminatingKey } from "../../../src/tools/AndByDiscriminatingKey";
-import { assert } from "tsafe/assert";
-import type { Equals } from "tsafe";
-
-{
- type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
-
- type Extension = { pageId: "a"; onlyExtA: string } | { pageId: "b"; onlyExtB: string } | { pageId: "only ext"; onlyExt: string };
-
- type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
-
- type Expected =
- | { pageId: "a"; onlyA: string; onlyExtA: string }
- | { pageId: "b"; onlyB: string; onlyExtB: string }
- | { pageId: "only base"; onlyBase: string }
- | { pageId: "only ext"; onlyExt: string };
-
- assert>();
-
- const x: Got = null as any;
-
- if (x.pageId === "a") {
- x.onlyA;
- x.onlyExtA;
-
- //@ts-expect-error
- x.onlyB;
-
- //@ts-expect-error
- x.onlyBase;
-
- //@ts-expect-error
- x.onlyExt;
- }
-
- if (x.pageId === "b") {
- x.onlyB;
- x.onlyExtB;
-
- //@ts-expect-error
- x.onlyA;
-
- //@ts-expect-error
- x.onlyBase;
-
- //@ts-expect-error
- x.onlyExt;
- }
-
- if (x.pageId === "only base") {
- x.onlyBase;
-
- //@ts-expect-error
- x.onlyA;
-
- //@ts-expect-error
- x.onlyB;
-
- //@ts-expect-error
- x.onlyExt;
- }
-
- if (x.pageId === "only ext") {
- x.onlyExt;
-
- //@ts-expect-error
- x.onlyA;
-
- //@ts-expect-error
- x.onlyB;
-
- //@ts-expect-error
- x.onlyBase;
- }
-}
-
-{
- type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
-
- type Extension = { pageId: "only ext"; onlyExt: string };
-
- type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
-
- type Expected =
- | { pageId: "a"; onlyA: string }
- | { pageId: "b"; onlyB: string }
- | { pageId: "only base"; onlyBase: string }
- | { pageId: "only ext"; onlyExt: string };
-
- assert>();
-}
diff --git a/test/tools/assertIsSameCode.ts b/test/tools/assertIsSameCode.ts
deleted file mode 100644
index b63cb822..00000000
--- a/test/tools/assertIsSameCode.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { assert } from "tsafe/assert";
-
-export function assetIsSameCode(code1: string, code2: string, message?: string): void {
- const removeSpacesAndNewLines = (code: string) => code.replace(/\s/g, "").replace(/\n/g, "");
-
- assert(removeSpacesAndNewLines(code1) === removeSpacesAndNewLines(code2), message);
-}
diff --git a/test/tools/isSameCode.ts b/test/tools/isSameCode.ts
new file mode 100644
index 00000000..6d62a225
--- /dev/null
+++ b/test/tools/isSameCode.ts
@@ -0,0 +1,5 @@
+export function isSameCode(code1: string, code2: string): boolean {
+ const removeSpacesAndNewLines = (code: string) => code.replace(/\s/g, "").replace(/\n/g, "");
+
+ return removeSpacesAndNewLines(code1) === removeSpacesAndNewLines(code2);
+}
From e527f043b08c4090b6dae56c7025a0dc0a10b5df Mon Sep 17 00:00:00 2001
From: William Will <10997562+willwill96@users.noreply.github.com>
Date: Thu, 30 Mar 2023 02:46:44 -0600
Subject: [PATCH 3/6] test: add test for valid jar artifacts
---
test/bin/jar.spec.ts | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 test/bin/jar.spec.ts
diff --git a/test/bin/jar.spec.ts b/test/bin/jar.spec.ts
new file mode 100644
index 00000000..7f19b3d3
--- /dev/null
+++ b/test/bin/jar.spec.ts
@@ -0,0 +1,26 @@
+import jar from "keycloakify/bin/tools/jar";
+import { it, describe, vi } from "vitest";
+
+vi.mock("fs", () => ({ promises: { mkdir: () => {} }, createWriteStream: () => {} }));
+vi.mock("stream", async () => {
+ const readableMock = () => {
+ const mockDecorators = {
+ on: () => mockDecorators,
+ pipe: () => mockDecorators
+ };
+ return {
+ from: () => mockDecorators
+ };
+ };
+
+ return {
+ // @ts-ignore
+ ...(await vi.importActual("stream")),
+ Readable: readableMock()
+ };
+});
+describe("jar", () => {
+ it("creates jar artifacts without error", () => {
+ jar({ artifactId: "artifactId", groupId: "groupId", rootPath: "rootPath", targetPath: "targetPath", version: "1.0.0" });
+ });
+});
From b863d9feb334c40ca373425de86d3f67de51eb44 Mon Sep 17 00:00:00 2001
From: William Will <10997562+willwill96@users.noreply.github.com>
Date: Thu, 30 Mar 2023 02:47:54 -0600
Subject: [PATCH 4/6] chore: add .devcontainer file
---
.gitignore | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 604525fa..c28b34d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,4 +51,7 @@ jspm_packages
/keycloak_email
/build_keycloak
/src/login/i18n/baseMessages/
-/src/account/i18n/baseMessages/
\ No newline at end of file
+/src/account/i18n/baseMessages/
+
+# VS Code devcontainers
+.devcontainer
\ No newline at end of file
From 4ebc1e671f0d6228ef043845eec3990e3b4d286d Mon Sep 17 00:00:00 2001
From: William Will <10997562+willwill96@users.noreply.github.com>
Date: Thu, 30 Mar 2023 22:09:27 +0000
Subject: [PATCH 5/6] feat(config): add ability to customize input/output
directory
---
.gitignore | 4 +-
.prettierignore | 7 ++-
package.json | 4 +-
scripts/test-keycloakify-starter.ts | 29 +++++++++
src/bin/download-builtin-keycloak-theme.ts | 7 +--
src/bin/eject-keycloak-page.ts | 2 +-
src/bin/getThemeSrcDirPath.ts | 33 ----------
src/bin/initialize-email-theme.ts | 12 +---
src/bin/keycloakify/BuildOptions.ts | 64 ++++---------------
src/bin/keycloakify/build-paths.ts | 72 ++++++++++++++++++++++
src/bin/keycloakify/index.ts | 2 +-
src/bin/keycloakify/keycloakify.ts | 28 ++++-----
src/bin/keycloakify/parsed-package-json.ts | 58 +++++++++++++++++
test/bin/generateKeycloakThemeResources.ts | 20 ------
test/bin/main.ts | 25 --------
test/bin/setupCustomReactProject.spec.ts | 62 +++++++++++++++++++
test/bin/setupSampleReactProject.spec.ts | 59 ++++++++++++++++++
test/bin/setupSampleReactProject.ts | 8 +--
vitest.config.ts | 3 +-
19 files changed, 325 insertions(+), 174 deletions(-)
create mode 100644 scripts/test-keycloakify-starter.ts
delete mode 100644 src/bin/getThemeSrcDirPath.ts
create mode 100644 src/bin/keycloakify/build-paths.ts
create mode 100644 src/bin/keycloakify/parsed-package-json.ts
delete mode 100644 test/bin/generateKeycloakThemeResources.ts
delete mode 100644 test/bin/main.ts
create mode 100644 test/bin/setupCustomReactProject.spec.ts
create mode 100644 test/bin/setupSampleReactProject.spec.ts
diff --git a/.gitignore b/.gitignore
index c28b34d0..1c905308 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,9 +41,11 @@ jspm_packages
.DS_Store
/dist
+# Test Build Directories
/dist_test
-
/sample_react_project/
+/sample_custom_react_project/
+/keycloakify_starter_test/
/.yarn_home/
.idea
diff --git a/.prettierignore b/.prettierignore
index 896a774d..48693ecf 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,12 +1,15 @@
node_modules/
/dist/
-/dist_test/
/CHANGELOG.md
/.yarn_home/
/src/test/apps/
/src/tools/types/
-/sample_react_project
/build_keycloak/
/.vscode/
/src/login/i18n/baseMessages/
/src/account/i18n/baseMessages/
+# Test Build Directories
+/dist_test
+/sample_react_project/
+/sample_custom_react_project/
+/keycloakify_starter_test/
\ No newline at end of file
diff --git a/package.json b/package.json
index 8f38ac39..e7a16dda 100644
--- a/package.json
+++ b/package.json
@@ -12,11 +12,11 @@
"prepare": "yarn generate-i18n-messages",
"build": "rimraf dist/ && tsc -p src/bin && tsc -p src/tsconfig.json && tsc-alias -p src/tsconfig.json && yarn grant-exec-perms && yarn copy-files dist/",
"build:watch": "tsc -p src/tsconfig.json && (concurrently \"tsc -p src/tsconfig.json -w\" \"tsc-alias -p src/tsconfig.json\")",
- "test:types": "tsc -p test/tsconfig.json --noEmit",
"grant-exec-perms": "node dist/bin/tools/grant-exec-perms.js",
"copy-files": "copyfiles -u 1 src/**/*.ftl",
"test": "yarn test:types && vitest run",
- "test:sample-app": "yarn build:test && node dist_test/test/bin/main.js",
+ "test:keycloakify-starter": "ts-node scripts/test-keycloakify-starter",
+ "test:types": "tsc -p test/tsconfig.json --noEmit",
"_format": "prettier '**/*.{ts,tsx,json,md}'",
"format": "yarn _format --write",
"format:check": "yarn _format --list-different",
diff --git a/scripts/test-keycloakify-starter.ts b/scripts/test-keycloakify-starter.ts
new file mode 100644
index 00000000..f443fa39
--- /dev/null
+++ b/scripts/test-keycloakify-starter.ts
@@ -0,0 +1,29 @@
+import { execSync } from "child_process";
+import { existsSync, readFileSync, rmSync, writeFileSync } from "fs";
+import path from "path";
+
+const testDir = "keycloakify_starter_test";
+
+if (existsSync(path.join(process.cwd(), testDir))) {
+ rmSync(path.join(process.cwd(), testDir), { recursive: true });
+}
+// Build and link package
+execSync("yarn build");
+const pkgJSON = JSON.parse(readFileSync(path.join(process.cwd(), "package.json")).toString("utf8"));
+pkgJSON.main = "./index.js";
+pkgJSON.types = "./index.d.ts";
+pkgJSON.scripts.prepare = undefined;
+writeFileSync(path.join(process.cwd(), "dist", "package.json"), JSON.stringify(pkgJSON));
+// Wrapped in a try/catch because unlink errors if the package isn't linked
+try {
+ execSync("yarn unlink");
+} catch {}
+execSync("yarn link", { cwd: path.join(process.cwd(), "dist") });
+
+// Clone latest keycloakify-starter and link to keycloakify output
+execSync(`git clone https://github.com/keycloakify/keycloakify-starter.git ${testDir}`);
+execSync("yarn install", { cwd: path.join(process.cwd(), testDir) });
+execSync("yarn link keycloakify", { cwd: path.join(process.cwd(), testDir) });
+
+//Ensure keycloak theme can be built
+execSync("yarn build-keycloak-theme", { cwd: path.join(process.cwd(), testDir) });
diff --git a/src/bin/download-builtin-keycloak-theme.ts b/src/bin/download-builtin-keycloak-theme.ts
index d09188b3..e3ac6ba3 100644
--- a/src/bin/download-builtin-keycloak-theme.ts
+++ b/src/bin/download-builtin-keycloak-theme.ts
@@ -1,11 +1,10 @@
#!/usr/bin/env node
-
-import { keycloakThemeBuildingDirPath } from "./keycloakify";
import { join as pathJoin } from "path";
import { downloadAndUnzip } from "./tools/downloadAndUnzip";
import { promptKeycloakVersion } from "./promptKeycloakVersion";
import { getCliOptions } from "./tools/cliOptions";
import { getLogger } from "./tools/logger";
+import { getKeycloakBuildPath } from "./keycloakify/build-paths";
export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: string; destDirPath: string; isSilent: boolean }) {
const { keycloakVersion, destDirPath } = params;
@@ -26,7 +25,7 @@ async function main() {
const logger = getLogger({ isSilent });
const { keycloakVersion } = await promptKeycloakVersion();
- const destDirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme");
+ const destDirPath = pathJoin(getKeycloakBuildPath(), "src", "main", "resources", "theme");
logger.log(`Downloading builtins theme of Keycloak ${keycloakVersion} here ${destDirPath}`);
@@ -38,5 +37,5 @@ async function main() {
}
if (require.main === module) {
- main().catch(e => console.error(e));
+ main();
}
diff --git a/src/bin/eject-keycloak-page.ts b/src/bin/eject-keycloak-page.ts
index 1d221f92..f6094c54 100644
--- a/src/bin/eject-keycloak-page.ts
+++ b/src/bin/eject-keycloak-page.ts
@@ -16,7 +16,7 @@ import { existsSync } from "fs";
import { join as pathJoin, relative as pathRelative } from "path";
import { kebabCaseToCamelCase } from "./tools/kebabCaseToSnakeCase";
import { assert, Equals } from "tsafe/assert";
-import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
+import { getThemeSrcDirPath } from "./keycloakify/build-paths";
(async () => {
const projectRootDir = getProjectRoot();
diff --git a/src/bin/getThemeSrcDirPath.ts b/src/bin/getThemeSrcDirPath.ts
deleted file mode 100644
index ee9db95b..00000000
--- a/src/bin/getThemeSrcDirPath.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { join as pathJoin } from "path";
-import * as fs from "fs";
-import { crawl } from "./tools/crawl";
-import { exclude } from "tsafe/exclude";
-
-const reactProjectDirPath = process.cwd();
-
-const themeSrcDirBasename = "keycloak-theme";
-
-export function getThemeSrcDirPath() {
- const srcDirPath = pathJoin(reactProjectDirPath, "src");
-
- const themeSrcDirPath: string | undefined = crawl(srcDirPath)
- .map(fileRelativePath => {
- const split = fileRelativePath.split(themeSrcDirBasename);
-
- if (split.length !== 2) {
- return undefined;
- }
-
- return pathJoin(srcDirPath, split[0] + themeSrcDirBasename);
- })
- .filter(exclude(undefined))[0];
-
- if (themeSrcDirPath === undefined) {
- if (fs.existsSync(pathJoin(srcDirPath, "login")) || fs.existsSync(pathJoin(srcDirPath, "account"))) {
- return { "themeSrcDirPath": srcDirPath };
- }
- return { "themeSrcDirPath": undefined };
- }
-
- return { themeSrcDirPath };
-}
diff --git a/src/bin/initialize-email-theme.ts b/src/bin/initialize-email-theme.ts
index 44207026..5f08f811 100644
--- a/src/bin/initialize-email-theme.ts
+++ b/src/bin/initialize-email-theme.ts
@@ -7,17 +7,9 @@ import { promptKeycloakVersion } from "./promptKeycloakVersion";
import * as fs from "fs";
import { getCliOptions } from "./tools/cliOptions";
import { getLogger } from "./tools/logger";
-import { getThemeSrcDirPath } from "./getThemeSrcDirPath";
+import { getEmailThemeSrcDirPath } from "./keycloakify/build-paths";
-export function getEmailThemeSrcDirPath() {
- const { themeSrcDirPath } = getThemeSrcDirPath();
-
- const emailThemeSrcDirPath = themeSrcDirPath === undefined ? undefined : pathJoin(themeSrcDirPath, "email");
-
- return { emailThemeSrcDirPath };
-}
-
-async function main() {
+export async function main() {
const { isSilent } = getCliOptions(process.argv.slice(2));
const logger = getLogger({ isSilent });
diff --git a/src/bin/keycloakify/BuildOptions.ts b/src/bin/keycloakify/BuildOptions.ts
index 6450f766..f0972b8b 100644
--- a/src/bin/keycloakify/BuildOptions.ts
+++ b/src/bin/keycloakify/BuildOptions.ts
@@ -1,51 +1,10 @@
-import { z } from "zod";
import { assert } from "tsafe/assert";
-import type { Equals } from "tsafe";
import { id } from "tsafe/id";
import { parse as urlParse } from "url";
import { typeGuard } from "tsafe/typeGuard";
import { symToStr } from "tsafe/symToStr";
-
-const bundlers = ["mvn", "keycloakify", "none"] as const;
-type Bundler = (typeof bundlers)[number];
-type ParsedPackageJson = {
- name: string;
- version: string;
- homepage?: string;
- keycloakify?: {
- /** @deprecated: use extraLoginPages instead */
- extraPages?: string[];
- extraLoginPages?: string[];
- extraAccountPages?: string[];
- extraThemeProperties?: string[];
- areAppAndKeycloakServerSharingSameDomain?: boolean;
- artifactId?: string;
- groupId?: string;
- bundler?: Bundler;
- keycloakVersionDefaultAssets?: string;
- };
-};
-
-const zParsedPackageJson = z.object({
- "name": z.string(),
- "version": z.string(),
- "homepage": z.string().optional(),
- "keycloakify": z
- .object({
- "extraPages": z.array(z.string()).optional(),
- "extraLoginPages": z.array(z.string()).optional(),
- "extraAccountPages": z.array(z.string()).optional(),
- "extraThemeProperties": z.array(z.string()).optional(),
- "areAppAndKeycloakServerSharingSameDomain": z.boolean().optional(),
- "artifactId": z.string().optional(),
- "groupId": z.string().optional(),
- "bundler": z.enum(bundlers).optional(),
- "keycloakVersionDefaultAssets": z.string().optional()
- })
- .optional()
-});
-
-assert, ParsedPackageJson>>();
+import { Bundler, bundlers, getParsedPackageJson } from "./parsed-package-json";
+import { getAppInputPath, getKeycloakBuildPath } from "./build-paths";
/** Consolidated build option gathered form CLI arguments and config in package.json */
export type BuildOptions = BuildOptions.Standalone | BuildOptions.ExternalAssets;
@@ -62,6 +21,10 @@ export namespace BuildOptions {
artifactId: string;
bundler: Bundler;
keycloakVersionDefaultAssets: string;
+ // Directory of your built react project. Defaults to {cwd}/build
+ appInputPath: string;
+ // Directory that keycloakify outputs to. Defaults to {cwd}/build_keycloak
+ keycloakBuildPath: string;
};
export type Standalone = Common & {
@@ -88,15 +51,10 @@ export namespace BuildOptions {
}
}
-export function readBuildOptions(params: {
- packageJson: string;
- CNAME: string | undefined;
- isExternalAssetsCliParamProvided: boolean;
- isSilent: boolean;
-}): BuildOptions {
- const { packageJson, CNAME, isExternalAssetsCliParamProvided, isSilent } = params;
+export function readBuildOptions(params: { CNAME: string | undefined; isExternalAssetsCliParamProvided: boolean; isSilent: boolean }): BuildOptions {
+ const { CNAME, isExternalAssetsCliParamProvided, isSilent } = params;
- const parsedPackageJson = zParsedPackageJson.parse(JSON.parse(packageJson));
+ const parsedPackageJson = getParsedPackageJson();
const url = (() => {
const { homepage } = parsedPackageJson;
@@ -172,7 +130,9 @@ export function readBuildOptions(params: {
extraAccountPages,
extraThemeProperties,
isSilent,
- "keycloakVersionDefaultAssets": keycloakVersionDefaultAssets ?? "11.0.3"
+ "keycloakVersionDefaultAssets": keycloakVersionDefaultAssets ?? "11.0.3",
+ appInputPath: getAppInputPath(),
+ keycloakBuildPath: getKeycloakBuildPath()
};
})();
diff --git a/src/bin/keycloakify/build-paths.ts b/src/bin/keycloakify/build-paths.ts
new file mode 100644
index 00000000..200139f1
--- /dev/null
+++ b/src/bin/keycloakify/build-paths.ts
@@ -0,0 +1,72 @@
+import * as fs from "fs";
+import { exclude } from "tsafe";
+import { crawl } from "../tools/crawl";
+import { pathJoin } from "../tools/pathJoin";
+import { getParsedPackageJson } from "./parsed-package-json";
+
+const DEFAULT_APP_INPUT_PATH = "build";
+
+const DEFAULT_KEYCLOAK_BUILD_PATH = "build_keycloak";
+
+const THEME_SRC_DIR_BASENAME = "keycloak-theme";
+
+export const getReactProjectDirPath = () => process.cwd();
+
+export const getCnamePath = () => pathJoin(getReactProjectDirPath(), "public", "CNAME");
+
+const parseAppInputPath = (path?: string) => {
+ if (!path) {
+ return pathJoin(process.cwd(), DEFAULT_APP_INPUT_PATH);
+ } else if (path.startsWith("./")) {
+ return pathJoin(process.cwd(), path.replace("./", ""));
+ }
+ return path;
+};
+
+const parseKeycloakBuildPath = (path?: string) => {
+ if (!path) {
+ return pathJoin(process.cwd(), DEFAULT_KEYCLOAK_BUILD_PATH);
+ } else if (path.startsWith("./")) {
+ return pathJoin(process.cwd(), path.replace("./", ""));
+ }
+ return path;
+};
+
+export const getAppInputPath = () => {
+ return parseAppInputPath(getParsedPackageJson().keycloakify?.appInputPath);
+};
+
+export const getKeycloakBuildPath = () => {
+ return parseKeycloakBuildPath(getParsedPackageJson().keycloakify?.keycloakBuildPath);
+};
+export const getThemeSrcDirPath = () => {
+ const srcDirPath = pathJoin(getReactProjectDirPath(), "src");
+
+ const themeSrcDirPath: string | undefined = crawl(srcDirPath)
+ .map(fileRelativePath => {
+ const split = fileRelativePath.split(THEME_SRC_DIR_BASENAME);
+
+ if (split.length !== 2) {
+ return undefined;
+ }
+
+ return pathJoin(srcDirPath, split[0] + THEME_SRC_DIR_BASENAME);
+ })
+ .filter(exclude(undefined))[0];
+ if (themeSrcDirPath === undefined) {
+ if (fs.existsSync(pathJoin(srcDirPath, "login")) || fs.existsSync(pathJoin(srcDirPath, "account"))) {
+ return { "themeSrcDirPath": srcDirPath };
+ }
+ return { "themeSrcDirPath": undefined };
+ }
+
+ return { themeSrcDirPath };
+};
+
+export const getEmailThemeSrcDirPath = () => {
+ const { themeSrcDirPath } = getThemeSrcDirPath();
+
+ const emailThemeSrcDirPath = themeSrcDirPath === undefined ? undefined : pathJoin(themeSrcDirPath, "email");
+
+ return { emailThemeSrcDirPath };
+};
diff --git a/src/bin/keycloakify/index.ts b/src/bin/keycloakify/index.ts
index 13d73c75..258b6e23 100644
--- a/src/bin/keycloakify/index.ts
+++ b/src/bin/keycloakify/index.ts
@@ -4,5 +4,5 @@ export * from "./keycloakify";
import { main } from "./keycloakify";
if (require.main === module) {
- main().catch(e => console.error(e));
+ main();
}
diff --git a/src/bin/keycloakify/keycloakify.ts b/src/bin/keycloakify/keycloakify.ts
index 7d2f6334..b06f51d5 100644
--- a/src/bin/keycloakify/keycloakify.ts
+++ b/src/bin/keycloakify/keycloakify.ts
@@ -10,11 +10,8 @@ import { getCliOptions } from "../tools/cliOptions";
import jar from "../tools/jar";
import { assert } from "tsafe/assert";
import { Equals } from "tsafe";
-import { getEmailThemeSrcDirPath } from "../initialize-email-theme";
-
-const reactProjectDirPath = process.cwd();
-
-export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build_keycloak");
+import { getEmailThemeSrcDirPath } from "./build-paths";
+import { getCnamePath, getAppInputPath, getKeycloakBuildPath, getReactProjectDirPath } from "./build-paths";
export async function main() {
const { isSilent, hasExternalAssets } = getCliOptions(process.argv.slice(2));
@@ -22,9 +19,8 @@ export async function main() {
logger.log("🔏 Building the keycloak theme...⌚");
const buildOptions = readBuildOptions({
- "packageJson": fs.readFileSync(pathJoin(reactProjectDirPath, "package.json")).toString("utf8"),
"CNAME": (() => {
- const cnameFilePath = pathJoin(reactProjectDirPath, "public", "CNAME");
+ const cnameFilePath = getCnamePath();
if (!fs.existsSync(cnameFilePath)) {
return undefined;
@@ -37,7 +33,7 @@ export async function main() {
});
const { doBundlesEmailTemplate } = await generateKeycloakThemeResources({
- keycloakThemeBuildingDirPath,
+ keycloakThemeBuildingDirPath: buildOptions.keycloakBuildPath,
"emailThemeSrcDirPath": (() => {
const { emailThemeSrcDirPath } = getEmailThemeSrcDirPath();
@@ -47,13 +43,13 @@ export async function main() {
return emailThemeSrcDirPath;
})(),
- "reactAppBuildDirPath": pathJoin(reactProjectDirPath, "build"),
+ "reactAppBuildDirPath": getAppInputPath(),
buildOptions,
"keycloakVersion": buildOptions.keycloakVersionDefaultAssets
});
const { jarFilePath } = generateJavaStackFiles({
- keycloakThemeBuildingDirPath,
+ keycloakThemeBuildingDirPath: buildOptions.keycloakBuildPath,
doBundlesEmailTemplate,
buildOptions
});
@@ -65,7 +61,7 @@ export async function main() {
case "keycloakify":
logger.log("🫶 Let keycloakify do its thang");
await jar({
- "rootPath": pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources"),
+ "rootPath": pathJoin(buildOptions.keycloakBuildPath, "src", "main", "resources"),
"version": buildOptions.version,
"groupId": buildOptions.groupId,
"artifactId": buildOptions.artifactId,
@@ -74,7 +70,7 @@ export async function main() {
break;
case "mvn":
logger.log("🫙 Run maven to deliver a jar");
- child_process.execSync("mvn package", { "cwd": keycloakThemeBuildingDirPath });
+ child_process.execSync("mvn package", { "cwd": buildOptions.keycloakBuildPath });
break;
default:
assert>(false);
@@ -84,7 +80,7 @@ export async function main() {
const containerKeycloakVersion = "20.0.1";
generateStartKeycloakTestingContainer({
- keycloakThemeBuildingDirPath,
+ keycloakThemeBuildingDirPath: buildOptions.keycloakBuildPath,
"keycloakVersion": containerKeycloakVersion,
buildOptions
});
@@ -92,7 +88,7 @@ export async function main() {
logger.log(
[
"",
- `✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`,
+ `✅ Your keycloak theme has been generated and bundled into ./${pathRelative(getReactProjectDirPath(), jarFilePath)} 🚀`,
`It is to be placed in "/opt/keycloak/providers" in the container running a quay.io/keycloak/keycloak Docker image.`,
"",
//TODO: Restore when we find a good Helm chart for Keycloak.
@@ -127,8 +123,8 @@ export async function main() {
`To test your theme locally you can spin up a Keycloak ${containerKeycloakVersion} container image with the theme pre loaded by running:`,
"",
`👉 $ .${pathSep}${pathRelative(
- reactProjectDirPath,
- pathJoin(keycloakThemeBuildingDirPath, generateStartKeycloakTestingContainer.basename)
+ getReactProjectDirPath(),
+ pathJoin(getKeycloakBuildPath(), generateStartKeycloakTestingContainer.basename)
)} 👈`,
"",
`Test with different Keycloak versions by editing the .sh file. see available versions here: https://quay.io/repository/keycloak/keycloak?tab=tags`,
diff --git a/src/bin/keycloakify/parsed-package-json.ts b/src/bin/keycloakify/parsed-package-json.ts
new file mode 100644
index 00000000..6f69e970
--- /dev/null
+++ b/src/bin/keycloakify/parsed-package-json.ts
@@ -0,0 +1,58 @@
+import * as fs from "fs";
+import { assert } from "tsafe";
+import type { Equals } from "tsafe";
+import { z } from "zod";
+import { pathJoin } from "../tools/pathJoin";
+
+const reactProjectDirPath = process.cwd();
+export const bundlers = ["mvn", "keycloakify", "none"] as const;
+export type Bundler = (typeof bundlers)[number];
+type ParsedPackageJson = {
+ name: string;
+ version: string;
+ homepage?: string;
+ keycloakify?: {
+ /** @deprecated: use extraLoginPages instead */
+ extraPages?: string[];
+ extraLoginPages?: string[];
+ extraAccountPages?: string[];
+ extraThemeProperties?: string[];
+ areAppAndKeycloakServerSharingSameDomain?: boolean;
+ artifactId?: string;
+ groupId?: string;
+ bundler?: Bundler;
+ keycloakVersionDefaultAssets?: string;
+ appInputPath?: string;
+ keycloakBuildPath?: string;
+ };
+};
+
+const zParsedPackageJson = z.object({
+ "name": z.string(),
+ "version": z.string(),
+ "homepage": z.string().optional(),
+ "keycloakify": z
+ .object({
+ "extraPages": z.array(z.string()).optional(),
+ "extraLoginPages": z.array(z.string()).optional(),
+ "extraAccountPages": z.array(z.string()).optional(),
+ "extraThemeProperties": z.array(z.string()).optional(),
+ "areAppAndKeycloakServerSharingSameDomain": z.boolean().optional(),
+ "artifactId": z.string().optional(),
+ "groupId": z.string().optional(),
+ "bundler": z.enum(bundlers).optional(),
+ "keycloakVersionDefaultAssets": z.string().optional(),
+ "appInputPath": z.string().optional(),
+ "keycloakBuildPath": z.string().optional()
+ })
+ .optional()
+});
+
+assert, ParsedPackageJson>>();
+
+let parsedPackageJson: undefined | ReturnType<(typeof zParsedPackageJson)["parse"]>;
+export const getParsedPackageJson = () => {
+ if (parsedPackageJson) return parsedPackageJson;
+ parsedPackageJson = zParsedPackageJson.parse(JSON.parse(fs.readFileSync(pathJoin(reactProjectDirPath, "package.json")).toString("utf8")));
+ return parsedPackageJson;
+};
diff --git a/test/bin/generateKeycloakThemeResources.ts b/test/bin/generateKeycloakThemeResources.ts
deleted file mode 100644
index f76e7bfd..00000000
--- a/test/bin/generateKeycloakThemeResources.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { join as pathJoin } from "path";
-import { generateKeycloakThemeResources } from "keycloakify/bin/keycloakify/generateKeycloakThemeResources";
-import { setupSampleReactProject, sampleReactProjectDirPath } from "./setupSampleReactProject";
-
-setupSampleReactProject();
-
-generateKeycloakThemeResources({
- "reactAppBuildDirPath": pathJoin(sampleReactProjectDirPath, "build"),
- "keycloakThemeBuildingDirPath": pathJoin(sampleReactProjectDirPath, "build_keycloak_theme"),
- "emailThemeSrcDirPath": undefined,
- "keycloakVersion": "11.0.3",
- "buildOptions": {
- "themeName": "keycloakify-demo-app",
- "extraLoginPages": ["my-custom-page.ftl"],
- "extraThemeProperties": ["env=test"],
- "isStandalone": true,
- "urlPathname": "/keycloakify-demo-app/",
- "isSilent": false
- }
-});
diff --git a/test/bin/main.ts b/test/bin/main.ts
deleted file mode 100644
index 531d4b3d..00000000
--- a/test/bin/main.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { setupSampleReactProject, sampleReactProjectDirPath } from "./setupSampleReactProject";
-import * as st from "scripting-tools";
-import * as fs from "fs";
-import { join as pathJoin } from "path";
-import { getProjectRoot } from "keycloakify/bin/tools/getProjectRoot.js";
-
-(async () => {
- fs.rmSync(sampleReactProjectDirPath, { "recursive": true });
-
- await setupSampleReactProject();
-
- const binDirPath = pathJoin(getProjectRoot(), "dist_test", "src", "bin");
-
- fs.mkdirSync(pathJoin(sampleReactProjectDirPath, "src", "keycloak-theme"), { "recursive": true });
-
- st.execSyncTrace(`node ${pathJoin(binDirPath, "initialize-email-theme")}`, { "cwd": sampleReactProjectDirPath });
-
- st.execSyncTrace(`node ${pathJoin(binDirPath, "download-builtin-keycloak-theme")}`, { "cwd": sampleReactProjectDirPath });
-
- st.execSyncTrace(
- //`node ${pathJoin(binDirPath, "keycloakify")} --external-assets`,
- `node ${pathJoin(binDirPath, "keycloakify")}`,
- { "cwd": sampleReactProjectDirPath }
- );
-})();
diff --git a/test/bin/setupCustomReactProject.spec.ts b/test/bin/setupCustomReactProject.spec.ts
new file mode 100644
index 00000000..3a4dc069
--- /dev/null
+++ b/test/bin/setupCustomReactProject.spec.ts
@@ -0,0 +1,62 @@
+import * as fs from "fs";
+import { getProjectRoot } from "keycloakify/bin/tools/getProjectRoot.js";
+import { join as pathJoin } from "path";
+import { downloadAndUnzip } from "keycloakify/bin/tools/downloadAndUnzip";
+import { main as initializeEmailTheme } from "keycloakify/bin/initialize-email-theme";
+import { it, describe, afterAll, beforeAll, beforeEach, vi } from "vitest";
+import { getKeycloakBuildPath } from "keycloakify/bin/keycloakify/build-paths";
+import { downloadBuiltinKeycloakTheme } from "keycloakify/bin/download-builtin-keycloak-theme";
+
+export const sampleReactProjectDirPath = pathJoin(getProjectRoot(), "sample_custom_react_project");
+
+async function setupSampleReactProject(destDir: string) {
+ await downloadAndUnzip({
+ "url": "https://github.com/keycloakify/keycloakify/releases/download/v0.0.1/sample_build_dir_and_package_json.zip",
+ "destDirPath": destDir
+ });
+}
+const nativeCwd = process.cwd;
+vi.mock("keycloakify/bin/keycloakify/parsed-package-json", async () => ({
+ ...((await vi.importActual("keycloakify/bin/keycloakify/parsed-package-json")) as Record),
+ getParsedPackageJson: () => ({
+ keycloakify: {
+ appInputPath: "./custom_input/build",
+ keycloakBuildDir: "./custom_output"
+ }
+ })
+}));
+
+vi.mock("keycloakify/bin/promptKeycloakVersion", async () => ({
+ ...((await vi.importActual("keycloakify/bin/promptKeycloakVersion")) as Record),
+ promptKeycloakVersion: () => ({ keycloakVersion: "11.0.3" })
+}));
+
+describe("Sample Project", () => {
+ beforeAll(() => {
+ // Monkey patching the cwd to the app location for the duration of this testv
+ process.cwd = () => sampleReactProjectDirPath;
+ });
+
+ afterAll(() => {
+ process.cwd = nativeCwd;
+ });
+ beforeEach(() => {
+ if (fs.existsSync(sampleReactProjectDirPath)) {
+ fs.rmSync(sampleReactProjectDirPath, { "recursive": true });
+ }
+
+ fs.mkdirSync(pathJoin(sampleReactProjectDirPath, "src", "keycloak-theme"), { "recursive": true });
+ fs.mkdirSync(pathJoin(sampleReactProjectDirPath, "src", "login"), { "recursive": true });
+ });
+ it(
+ "Sets up the project with a custom input and output directory without error",
+ async () => {
+ await setupSampleReactProject(pathJoin(sampleReactProjectDirPath, "custom_input"));
+ await initializeEmailTheme();
+
+ const destDirPath = pathJoin(getKeycloakBuildPath(), "src", "main", "resources", "theme");
+ await downloadBuiltinKeycloakTheme({ destDirPath, keycloakVersion: "11.0.3", isSilent: false });
+ },
+ { timeout: 30000 }
+ );
+});
diff --git a/test/bin/setupSampleReactProject.spec.ts b/test/bin/setupSampleReactProject.spec.ts
new file mode 100644
index 00000000..5d85993a
--- /dev/null
+++ b/test/bin/setupSampleReactProject.spec.ts
@@ -0,0 +1,59 @@
+import * as fs from "fs";
+import { getProjectRoot } from "keycloakify/bin/tools/getProjectRoot.js";
+import { join as pathJoin } from "path";
+import { downloadAndUnzip } from "keycloakify/bin/tools/downloadAndUnzip";
+import { main as initializeEmailTheme } from "keycloakify/bin/initialize-email-theme";
+import { it, describe, afterAll, beforeAll, beforeEach, vi } from "vitest";
+import { getKeycloakBuildPath } from "keycloakify/bin/keycloakify/build-paths";
+import { downloadBuiltinKeycloakTheme } from "keycloakify/bin/download-builtin-keycloak-theme";
+
+export const sampleReactProjectDirPath = pathJoin(getProjectRoot(), "sample_react_project");
+
+async function setupSampleReactProject(destDir: string) {
+ await downloadAndUnzip({
+ "url": "https://github.com/keycloakify/keycloakify/releases/download/v0.0.1/sample_build_dir_and_package_json.zip",
+ "destDirPath": destDir
+ });
+}
+
+vi.mock("keycloakify/bin/keycloakify/parsed-package-json", async () => ({
+ ...((await vi.importActual("keycloakify/bin/keycloakify/parsed-package-json")) as Record),
+ getParsedPackageJson: () => ({})
+}));
+
+vi.mock("keycloakify/bin/promptKeycloakVersion", async () => ({
+ ...((await vi.importActual("keycloakify/bin/promptKeycloakVersion")) as Record),
+ promptKeycloakVersion: () => ({ keycloakVersion: "11.0.3" })
+}));
+
+const nativeCwd = process.cwd;
+
+describe("Sample Project", () => {
+ beforeAll(() => {
+ // Monkey patching the cwd to the app location for the duration of this test
+ process.cwd = () => sampleReactProjectDirPath;
+ });
+
+ afterAll(() => {
+ process.cwd = nativeCwd;
+ });
+ beforeEach(() => {
+ if (fs.existsSync(sampleReactProjectDirPath)) {
+ fs.rmSync(sampleReactProjectDirPath, { "recursive": true });
+ }
+
+ fs.mkdirSync(pathJoin(sampleReactProjectDirPath, "src", "keycloak-theme"), { "recursive": true });
+ fs.mkdirSync(pathJoin(sampleReactProjectDirPath, "src", "login"), { "recursive": true });
+ });
+ it(
+ "Sets up the project without error",
+ async () => {
+ await setupSampleReactProject(sampleReactProjectDirPath);
+ await initializeEmailTheme();
+
+ const destDirPath = pathJoin(getKeycloakBuildPath(), "src", "main", "resources", "theme");
+ await downloadBuiltinKeycloakTheme({ destDirPath, keycloakVersion: "11.0.3", isSilent: false });
+ },
+ { timeout: 30000 }
+ );
+});
diff --git a/test/bin/setupSampleReactProject.ts b/test/bin/setupSampleReactProject.ts
index 7b8308e8..12061e68 100644
--- a/test/bin/setupSampleReactProject.ts
+++ b/test/bin/setupSampleReactProject.ts
@@ -1,12 +1,8 @@
-import { getProjectRoot } from "keycloakify/bin/tools/getProjectRoot.js";
-import { join as pathJoin } from "path";
import { downloadAndUnzip } from "keycloakify/bin/tools/downloadAndUnzip";
-export const sampleReactProjectDirPath = pathJoin(getProjectRoot(), "sample_react_project");
-
-export async function setupSampleReactProject() {
+export async function setupSampleReactProject(destDirPath: string) {
await downloadAndUnzip({
"url": "https://github.com/keycloakify/keycloakify/releases/download/v0.0.1/sample_build_dir_and_package_json.zip",
- "destDirPath": sampleReactProjectDirPath
+ "destDirPath": destDirPath
});
}
diff --git a/vitest.config.ts b/vitest.config.ts
index f372a9c9..aec1da63 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -6,6 +6,7 @@ export default defineConfig({
test: {
alias: {
"keycloakify": path.resolve(__dirname, "./src")
- }
+ },
+ watchExclude: ["**/node_modules/**", "**/dist/**", "**/sample_react_project/**", "**/sample_custom_react_project/**"]
}
});
From 83b0838c94f0f73b380743a70a258f622a22478b Mon Sep 17 00:00:00 2001
From: garronej
Date: Fri, 31 Mar 2023 11:49:06 +0200
Subject: [PATCH 6/6] Minor fixes to the Vitest setup
---
.gitignore | 8 +-
scripts/test-keycloakify-starter.ts | 8 +-
test/bin/setupCustomReactProject.spec.ts | 9 +-
test/bin/setupSampleReactProject.spec.ts | 1 +
test/lib/tools/AndByDiscriminatingKey.ts | 91 ++++++++++++++++++
.../tools/AndByDiscriminatingKey.type.spec.ts | 94 -------------------
test/tsconfig.json | 2 +-
vitest.config.ts | 6 +-
8 files changed, 107 insertions(+), 112 deletions(-)
create mode 100644 test/lib/tools/AndByDiscriminatingKey.ts
delete mode 100644 test/lib/tools/AndByDiscriminatingKey.type.spec.ts
diff --git a/.gitignore b/.gitignore
index 1c905308..1bee3e4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,17 +41,13 @@ jspm_packages
.DS_Store
/dist
-# Test Build Directories
-/dist_test
-/sample_react_project/
-/sample_custom_react_project/
/keycloakify_starter_test/
+/sample_custom_react_project/
+/sample_react_project/
/.yarn_home/
.idea
-/keycloak_email
-/build_keycloak
/src/login/i18n/baseMessages/
/src/account/i18n/baseMessages/
diff --git a/scripts/test-keycloakify-starter.ts b/scripts/test-keycloakify-starter.ts
index f443fa39..af512083 100644
--- a/scripts/test-keycloakify-starter.ts
+++ b/scripts/test-keycloakify-starter.ts
@@ -18,12 +18,12 @@ writeFileSync(path.join(process.cwd(), "dist", "package.json"), JSON.stringify(p
try {
execSync("yarn unlink");
} catch {}
-execSync("yarn link", { cwd: path.join(process.cwd(), "dist") });
+execSync("yarn link", { "cwd": path.join(process.cwd(), "dist") });
// Clone latest keycloakify-starter and link to keycloakify output
execSync(`git clone https://github.com/keycloakify/keycloakify-starter.git ${testDir}`);
-execSync("yarn install", { cwd: path.join(process.cwd(), testDir) });
-execSync("yarn link keycloakify", { cwd: path.join(process.cwd(), testDir) });
+execSync("yarn install", { "cwd": path.join(process.cwd(), testDir) });
+execSync("yarn link keycloakify", { "cwd": path.join(process.cwd(), testDir) });
//Ensure keycloak theme can be built
-execSync("yarn build-keycloak-theme", { cwd: path.join(process.cwd(), testDir) });
+execSync("yarn build-keycloak-theme", { "cwd": path.join(process.cwd(), testDir) });
diff --git a/test/bin/setupCustomReactProject.spec.ts b/test/bin/setupCustomReactProject.spec.ts
index 3a4dc069..9d14c6e0 100644
--- a/test/bin/setupCustomReactProject.spec.ts
+++ b/test/bin/setupCustomReactProject.spec.ts
@@ -19,16 +19,16 @@ const nativeCwd = process.cwd;
vi.mock("keycloakify/bin/keycloakify/parsed-package-json", async () => ({
...((await vi.importActual("keycloakify/bin/keycloakify/parsed-package-json")) as Record),
getParsedPackageJson: () => ({
- keycloakify: {
- appInputPath: "./custom_input/build",
- keycloakBuildDir: "./custom_output"
+ "keycloakify": {
+ "appInputPath": "./custom_input/build",
+ "keycloakBuildDir": "./custom_output"
}
})
}));
vi.mock("keycloakify/bin/promptKeycloakVersion", async () => ({
...((await vi.importActual("keycloakify/bin/promptKeycloakVersion")) as Record),
- promptKeycloakVersion: () => ({ keycloakVersion: "11.0.3" })
+ promptKeycloakVersion: () => ({ "keycloakVersion": "11.0.3" })
}));
describe("Sample Project", () => {
@@ -38,6 +38,7 @@ describe("Sample Project", () => {
});
afterAll(() => {
+ fs.rmSync(sampleReactProjectDirPath, { "recursive": true });
process.cwd = nativeCwd;
});
beforeEach(() => {
diff --git a/test/bin/setupSampleReactProject.spec.ts b/test/bin/setupSampleReactProject.spec.ts
index 5d85993a..7c6143a4 100644
--- a/test/bin/setupSampleReactProject.spec.ts
+++ b/test/bin/setupSampleReactProject.spec.ts
@@ -35,6 +35,7 @@ describe("Sample Project", () => {
});
afterAll(() => {
+ fs.rmSync(sampleReactProjectDirPath, { "recursive": true });
process.cwd = nativeCwd;
});
beforeEach(() => {
diff --git a/test/lib/tools/AndByDiscriminatingKey.ts b/test/lib/tools/AndByDiscriminatingKey.ts
new file mode 100644
index 00000000..3c3f73a0
--- /dev/null
+++ b/test/lib/tools/AndByDiscriminatingKey.ts
@@ -0,0 +1,91 @@
+import { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
+import { assert } from "tsafe/assert";
+import type { Equals } from "tsafe";
+
+{
+ type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
+
+ type Extension = { pageId: "a"; onlyExtA: string } | { pageId: "b"; onlyExtB: string } | { pageId: "only ext"; onlyExt: string };
+
+ type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
+
+ type Expected =
+ | { pageId: "a"; onlyA: string; onlyExtA: string }
+ | { pageId: "b"; onlyB: string; onlyExtB: string }
+ | { pageId: "only base"; onlyBase: string }
+ | { pageId: "only ext"; onlyExt: string };
+
+ assert>();
+
+ const x: Got = null as any;
+
+ if (x.pageId === "a") {
+ x.onlyA;
+ x.onlyExtA;
+
+ //@ts-expect-error
+ x.onlyB;
+
+ //@ts-expect-error
+ x.onlyBase;
+
+ //@ts-expect-error
+ x.onlyExt;
+ }
+
+ if (x.pageId === "b") {
+ x.onlyB;
+ x.onlyExtB;
+
+ //@ts-expect-error
+ x.onlyA;
+
+ //@ts-expect-error
+ x.onlyBase;
+
+ //@ts-expect-error
+ x.onlyExt;
+ }
+
+ if (x.pageId === "only base") {
+ x.onlyBase;
+
+ //@ts-expect-error
+ x.onlyA;
+
+ //@ts-expect-error
+ x.onlyB;
+
+ //@ts-expect-error
+ x.onlyExt;
+ }
+
+ if (x.pageId === "only ext") {
+ x.onlyExt;
+
+ //@ts-expect-error
+ x.onlyA;
+
+ //@ts-expect-error
+ x.onlyB;
+
+ //@ts-expect-error
+ x.onlyBase;
+ }
+}
+
+{
+ type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
+
+ type Extension = { pageId: "only ext"; onlyExt: string };
+
+ type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
+
+ type Expected =
+ | { pageId: "a"; onlyA: string }
+ | { pageId: "b"; onlyB: string }
+ | { pageId: "only base"; onlyBase: string }
+ | { pageId: "only ext"; onlyExt: string };
+
+ assert>();
+}
diff --git a/test/lib/tools/AndByDiscriminatingKey.type.spec.ts b/test/lib/tools/AndByDiscriminatingKey.type.spec.ts
deleted file mode 100644
index 8edb9f87..00000000
--- a/test/lib/tools/AndByDiscriminatingKey.type.spec.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { AndByDiscriminatingKey } from "keycloakify/tools/AndByDiscriminatingKey";
-import { assert } from "tsafe/assert";
-import type { Equals } from "tsafe";
-import { it, describe } from "vitest";
-
-// These test case names are intentionally vague, because I'm not sure what each are testing individually
-describe("AndByDiscriminatingKey", () => {
- it("Test Case 1", () => {
- type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
-
- type Extension = { pageId: "a"; onlyExtA: string } | { pageId: "b"; onlyExtB: string } | { pageId: "only ext"; onlyExt: string };
-
- type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
-
- type Expected =
- | { pageId: "a"; onlyA: string; onlyExtA: string }
- | { pageId: "b"; onlyB: string; onlyExtB: string }
- | { pageId: "only base"; onlyBase: string }
- | { pageId: "only ext"; onlyExt: string };
-
- assert>();
-
- const x: Got = {} as any;
-
- if (x.pageId === "a") {
- x.onlyA;
- x.onlyExtA;
-
- //@ts-expect-error
- x.onlyB;
-
- //@ts-expect-error
- x.onlyBase;
-
- //@ts-expect-error
- x.onlyExt;
- }
-
- if (x.pageId === "b") {
- x.onlyB;
- x.onlyExtB;
-
- //@ts-expect-error
- x.onlyA;
-
- //@ts-expect-error
- x.onlyBase;
-
- //@ts-expect-error
- x.onlyExt;
- }
-
- if (x.pageId === "only base") {
- x.onlyBase;
-
- //@ts-expect-error
- x.onlyA;
-
- //@ts-expect-error
- x.onlyB;
-
- //@ts-expect-error
- x.onlyExt;
- }
-
- if (x.pageId === "only ext") {
- x.onlyExt;
-
- //@ts-expect-error
- x.onlyA;
-
- //@ts-expect-error
- x.onlyB;
-
- //@ts-expect-error
- x.onlyBase;
- }
- });
- it("Test Case 2", () => {
- type Base = { pageId: "a"; onlyA: string } | { pageId: "b"; onlyB: string } | { pageId: "only base"; onlyBase: string };
-
- type Extension = { pageId: "only ext"; onlyExt: string };
-
- type Got = AndByDiscriminatingKey<"pageId", Extension, Base>;
-
- type Expected =
- | { pageId: "a"; onlyA: string }
- | { pageId: "b"; onlyB: string }
- | { pageId: "only base"; onlyBase: string }
- | { pageId: "only ext"; onlyExt: string };
-
- assert>();
- });
-});
diff --git a/test/tsconfig.json b/test/tsconfig.json
index 7239f999..8c6c685d 100644
--- a/test/tsconfig.json
+++ b/test/tsconfig.json
@@ -10,7 +10,7 @@
"newLine": "LF",
"noUnusedLocals": true,
"noUnusedParameters": true,
- "incremental": true,
+ "incremental": false,
"strict": true,
"downlevelIteration": true,
"jsx": "react-jsx",
diff --git a/vitest.config.ts b/vitest.config.ts
index aec1da63..1af3eb95 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -3,10 +3,10 @@ import { defineConfig } from "vite";
import path from "path";
export default defineConfig({
- test: {
- alias: {
+ "test": {
+ "alias": {
"keycloakify": path.resolve(__dirname, "./src")
},
- watchExclude: ["**/node_modules/**", "**/dist/**", "**/sample_react_project/**", "**/sample_custom_react_project/**"]
+ "watchExclude": ["**/node_modules/**", "**/dist/**", "**/sample_react_project/**", "**/sample_custom_react_project/**"]
}
});