Compare commits
66 Commits
Author | SHA1 | Date | |
---|---|---|---|
28036f1da5 | |||
0dacf2fe30 | |||
32f5ef5e5c | |||
98d91bbde7 | |||
7a92a75d83 | |||
f5556a02fc | |||
1050f4d928 | |||
9276b08f4b | |||
a501af669c | |||
85343fcefe | |||
b11dfde6e6 | |||
38d2108f02 | |||
2b67544517 | |||
0d443ca88e | |||
71f7a5819d | |||
5f4abee615 | |||
f5ee949006 | |||
7e85085558 | |||
55a0b27f16 | |||
eb0e814f94 | |||
b7fe20c5a5 | |||
2b23d03ca5 | |||
7075be20c8 | |||
3ce8b06246 | |||
ee5c29f30f | |||
242dad3ea0 | |||
d8701925df | |||
e2d669ce31 | |||
af93664c71 | |||
daa3efa534 | |||
2c7c8397f0 | |||
821ba2cbe2 | |||
a17ddb02fa | |||
b89557e8d8 | |||
cad1f8b957 | |||
f82cc788bf | |||
06f9cd3e68 | |||
5113a838e7 | |||
645a84c82a | |||
925fc43d0f | |||
8e33d24c63 | |||
984ef63661 | |||
a8daf175ea | |||
055263a3da | |||
9990b0ab05 | |||
423397ce3e | |||
954567712c | |||
9f52eb8123 | |||
744b198fb4 | |||
15eab797c3 | |||
8ff86b1e29 | |||
e1b8760ee3 | |||
bd0d890b2c | |||
2a2118d769 | |||
9839b64650 | |||
2bf55e12f9 | |||
2249fa9232 | |||
f673a65304 | |||
0163459ad6 | |||
b21123cc9d | |||
7800d125b2 | |||
89ea648f18 | |||
ab7ac3c2d0 | |||
b16319d962 | |||
f8012d5dfb | |||
45a2015597 |
21
.github/workflows/ci.yaml
vendored
21
.github/workflows/ci.yaml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: macos-10.15
|
runs-on: macos-10.15
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node: [ '14', '13', '12' ]
|
node: [ '15', '14', '13' ]
|
||||||
name: Test with Node v${{ matrix.node }}
|
name: Test with Node v${{ matrix.node }}
|
||||||
steps:
|
steps:
|
||||||
- name: Tell if project is using npm or yarn
|
- name: Tell if project is using npm or yarn
|
||||||
@ -25,14 +25,13 @@ jobs:
|
|||||||
- uses: actions/setup-node@v2.1.3
|
- uses: actions/setup-node@v2.1.3
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
|
- uses: bahmutov/npm-install@v1
|
||||||
- if: steps.step1.outputs.npm_or_yarn == 'yarn'
|
- if: steps.step1.outputs.npm_or_yarn == 'yarn'
|
||||||
run: |
|
run: |
|
||||||
yarn install --frozen-lockfile
|
|
||||||
yarn build
|
yarn build
|
||||||
yarn test
|
yarn test
|
||||||
- if: steps.step1.outputs.npm_or_yarn == 'npm'
|
- if: steps.step1.outputs.npm_or_yarn == 'npm'
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
|
||||||
npm run build
|
npm run build
|
||||||
npm test
|
npm test
|
||||||
check_if_version_upgraded:
|
check_if_version_upgraded:
|
||||||
@ -55,11 +54,10 @@ jobs:
|
|||||||
needs: check_if_version_upgraded
|
needs: check_if_version_upgraded
|
||||||
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true'
|
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true'
|
||||||
steps:
|
steps:
|
||||||
- uses: garronej/github_actions_toolkit@v2.2
|
- uses: garronej/github_actions_toolkit@v2.4
|
||||||
with:
|
with:
|
||||||
action_name: update_changelog
|
action_name: update_changelog
|
||||||
branch: ${{ github.ref }}
|
branch: ${{ github.ref }}
|
||||||
commit_author_email: ts_ci@github.com
|
|
||||||
|
|
||||||
create_github_release:
|
create_github_release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -104,16 +102,13 @@ jobs:
|
|||||||
- uses: actions/setup-node@v2.1.3
|
- uses: actions/setup-node@v2.1.3
|
||||||
with:
|
with:
|
||||||
node-version: '15'
|
node-version: '15'
|
||||||
|
registry-url: https://registry.npmjs.org/
|
||||||
|
- uses: bahmutov/npm-install@v1
|
||||||
- run: |
|
- run: |
|
||||||
PACKAGE_MANAGER=npm
|
PACKAGE_MANAGER=npm
|
||||||
if [ -f "./yarn.lock" ]; then
|
if [ -f "./yarn.lock" ]; then
|
||||||
PACKAGE_MANAGER=yarn
|
PACKAGE_MANAGER=yarn
|
||||||
fi
|
fi
|
||||||
if [ "$PACKAGE_MANAGER" = "yarn" ]; then
|
|
||||||
yarn install --frozen-lockfile
|
|
||||||
else
|
|
||||||
npm ci
|
|
||||||
fi
|
|
||||||
$PACKAGE_MANAGER run build
|
$PACKAGE_MANAGER run build
|
||||||
- run: npx -y -p denoify@0.6.5 denoify_enable_short_npm_import_path
|
- run: npx -y -p denoify@0.6.5 denoify_enable_short_npm_import_path
|
||||||
env:
|
env:
|
||||||
@ -124,13 +119,11 @@ jobs:
|
|||||||
echo "This version is already published"
|
echo "This version is already published"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
if [ "$NPM_TOKEN" = "" ]; then
|
if [ "$NODE_AUTH_TOKEN" = "" ]; then
|
||||||
echo "Can't publish on NPM, You must first create a secret called NPM_TOKEN that contains your NPM auth token. https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets"
|
echo "Can't publish on NPM, You must first create a secret called NPM_TOKEN that contains your NPM auth token. https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets"
|
||||||
false
|
false
|
||||||
fi
|
fi
|
||||||
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' > .npmrc
|
|
||||||
npm publish
|
npm publish
|
||||||
rm .npmrc
|
|
||||||
env:
|
env:
|
||||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||||
VERSION: ${{ needs.check_if_version_upgraded.outputs.to_version }}
|
VERSION: ${{ needs.check_if_version_upgraded.outputs.to_version }}
|
68
CHANGELOG.md
68
CHANGELOG.md
@ -1,3 +1,71 @@
|
|||||||
|
### **1.1.6** (2021-06-21)
|
||||||
|
|
||||||
|
- Fix: Alert messages sometimes includes HTML that is not rendered
|
||||||
|
- Update dist
|
||||||
|
|
||||||
|
### **1.1.5** (2021-06-15)
|
||||||
|
|
||||||
|
- #11: Provide socials in the register
|
||||||
|
|
||||||
|
### **1.1.4** (2021-06-15)
|
||||||
|
|
||||||
|
- Merge pull request #12 from InseeFrLab/email-typo
|
||||||
|
|
||||||
|
Fix typo on email
|
||||||
|
- Fix typo on email
|
||||||
|
|
||||||
|
### **1.1.3** (2021-06-14)
|
||||||
|
|
||||||
|
- Add missing key in Login for providers
|
||||||
|
|
||||||
|
### **1.1.2** (2021-06-14)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### **1.1.1** (2021-06-14)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## **1.1.0** (2021-06-14)
|
||||||
|
|
||||||
|
- Add login-idp-link-confirm.ftl
|
||||||
|
- Fix login-update-profile.ftl
|
||||||
|
- Add login-update-profile.ftl page
|
||||||
|
- Fix default background bug
|
||||||
|
- Remove unused 'markdown' dependency
|
||||||
|
- Fix warning related to powerhooks_useGlobalState_kcLanguageTag
|
||||||
|
- Update README.md
|
||||||
|
|
||||||
|
### **1.0.4** (2021-05-28)
|
||||||
|
|
||||||
|
- Instructions for custom themes with custom components
|
||||||
|
|
||||||
|
### **1.0.3** (2021-05-23)
|
||||||
|
|
||||||
|
- Instuction about how to integrate with non CRA projects
|
||||||
|
- Add mention to awesome list
|
||||||
|
|
||||||
|
### **1.0.2** (2021-05-01)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### **1.0.1** (2021-05-01)
|
||||||
|
|
||||||
|
- Fix: LoginOtp (and not otc)
|
||||||
|
|
||||||
|
# **1.0.0** (2021-05-01)
|
||||||
|
|
||||||
|
- #4: Guide for implementing a missing page
|
||||||
|
- Support OTP #4
|
||||||
|
|
||||||
|
### **0.4.4** (2021-04-29)
|
||||||
|
|
||||||
|
- Fix previous release
|
||||||
|
|
||||||
|
### **0.4.3** (2021-04-29)
|
||||||
|
|
||||||
|
- Add infos about the plugin that defines authorizedMailDomains
|
||||||
|
|
||||||
### **0.4.2** (2021-04-29)
|
### **0.4.2** (2021-04-29)
|
||||||
|
|
||||||
- Client side validation of allowed email domains
|
- Client side validation of allowed email domains
|
||||||
|
70
README.md
70
README.md
@ -9,6 +9,10 @@
|
|||||||
<img src="https://img.shields.io/bundlephobia/minzip/keycloakify">
|
<img src="https://img.shields.io/bundlephobia/minzip/keycloakify">
|
||||||
<img src="https://img.shields.io/npm/dw/keycloakify">
|
<img src="https://img.shields.io/npm/dw/keycloakify">
|
||||||
<img src="https://img.shields.io/npm/l/keycloakify">
|
<img src="https://img.shields.io/npm/l/keycloakify">
|
||||||
|
<img src="https://camo.githubusercontent.com/0f9fcc0ac1b8617ad4989364f60f78b2d6b32985ad6a508f215f14d8f897b8d3/68747470733a2f2f62616467656e2e6e65742f62616467652f547970655363726970742f7374726963742532302546302539462539322541412f626c7565">
|
||||||
|
<a href="https://github.com/thomasdarimont/awesome-keycloak">
|
||||||
|
<img src="https://awesome.re/mentioned-badge.svg"/>
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@ -41,7 +45,7 @@ Here is `keycloakify` for you 🍸
|
|||||||
<img src="https://user-images.githubusercontent.com/6702424/114332075-c5e37900-9b45-11eb-910b-48a05b3d90d9.gif">
|
<img src="https://user-images.githubusercontent.com/6702424/114332075-c5e37900-9b45-11eb-910b-48a05b3d90d9.gif">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
*NOTE: No autocomplete here just because it was an incognito window.*
|
**TL;DR**: [Here](https://github.com/garronej/keycloakify-demo-app) is a Hello World React project with Keycloakify set up.
|
||||||
|
|
||||||
If you already have a Keycloak custom theme, it can be easily ported to Keycloakify.
|
If you already have a Keycloak custom theme, it can be easily ported to Keycloakify.
|
||||||
|
|
||||||
@ -49,6 +53,8 @@ If you already have a Keycloak custom theme, it can be easily ported to Keycloak
|
|||||||
|
|
||||||
|
|
||||||
- [Motivations](#motivations)
|
- [Motivations](#motivations)
|
||||||
|
- [Requirements](#requirements)
|
||||||
|
- [My framework doesn’t seem to be supported, what can I do?](#my-framework-doesnt-seem-to-be-supported-what-can-i-do)
|
||||||
- [How to use](#how-to-use)
|
- [How to use](#how-to-use)
|
||||||
- [Setting up the build tool](#setting-up-the-build-tool)
|
- [Setting up the build tool](#setting-up-the-build-tool)
|
||||||
- [Changing just the look of the default Keycloak theme](#changing-just-the-look-of-the-default-keycloak-theme)
|
- [Changing just the look of the default Keycloak theme](#changing-just-the-look-of-the-default-keycloak-theme)
|
||||||
@ -56,8 +62,8 @@ If you already have a Keycloak custom theme, it can be easily ported to Keycloak
|
|||||||
- [Hot reload](#hot-reload)
|
- [Hot reload](#hot-reload)
|
||||||
- [Enable loading in a blink of an eye of login pages ⚡ (--external-assets)](#enable-loading-in-a-blink-of-an-eye-of-login-pages----external-assets)
|
- [Enable loading in a blink of an eye of login pages ⚡ (--external-assets)](#enable-loading-in-a-blink-of-an-eye-of-login-pages----external-assets)
|
||||||
- [Support for Terms and conditions](#support-for-terms-and-conditions)
|
- [Support for Terms and conditions](#support-for-terms-and-conditions)
|
||||||
|
- [Some pages still have the default theme. Why?](#some-pages-still-have-the-default-theme-why)
|
||||||
- [GitHub Actions](#github-actions)
|
- [GitHub Actions](#github-actions)
|
||||||
- [Requirements](#requirements)
|
|
||||||
- [Limitations](#limitations)
|
- [Limitations](#limitations)
|
||||||
- [`process.env.PUBLIC_URL` not supported.](#processenvpublic_url-not-supported)
|
- [`process.env.PUBLIC_URL` not supported.](#processenvpublic_url-not-supported)
|
||||||
- [`@font-face` importing fonts from the `src/` dir](#font-face-importing-fonts-from-thesrc-dir)
|
- [`@font-face` importing fonts from the `src/` dir](#font-face-importing-fonts-from-thesrc-dir)
|
||||||
@ -67,9 +73,29 @@ If you already have a Keycloak custom theme, it can be easily ported to Keycloak
|
|||||||
- [Kickstart video](#kickstart-video)
|
- [Kickstart video](#kickstart-video)
|
||||||
- [Email domain whitelist](#email-domain-whitelist)
|
- [Email domain whitelist](#email-domain-whitelist)
|
||||||
|
|
||||||
# How to use
|
# Requirements
|
||||||
|
|
||||||
**TL;DR**: [Here](https://github.com/garronej/keycloakify-demo-app) is a Hello World React project with Keycloakify set up.
|
Tested with the following Keycloak versions:
|
||||||
|
- [11.0.3](https://hub.docker.com/layers/jboss/keycloak/11.0.3/images/sha256-4438f1e51c1369371cb807dffa526e1208086b3ebb9cab009830a178de949782?context=explore)
|
||||||
|
- [12.0.4](https://hub.docker.com/layers/jboss/keycloak/12.0.4/images/sha256-67e0c88e69bd0c7aef972c40bdeb558a974013a28b3668ca790ed63a04d70584?context=explore)
|
||||||
|
|
||||||
|
This tool will be maintained to stay compatible with Keycloak v11 and up, however, the default pages you will get
|
||||||
|
(before you customize it) will always be the ones of Keycloak v11.
|
||||||
|
|
||||||
|
This tool assumes you are bundling your app with Webpack (tested with 4.44.2) .
|
||||||
|
It assumes there is a `build/` directory at the root of your react project directory containing a `index.html` file
|
||||||
|
and a `build/static/` directory generated by webpack.
|
||||||
|
For more information see [this issue](https://github.com/InseeFrLab/keycloakify/issues/5#issuecomment-832296432)
|
||||||
|
## My framework doesn’t seem to be supported, what can I do?
|
||||||
|
|
||||||
|
Currently Keycloakify is only compatible with `create-react-app` apps.
|
||||||
|
It doesn’t mean that you can't use Keycloakify if you are using Next.js, Express or any other
|
||||||
|
framework that involves SSR but your Keycloak theme will need to be a standalone project.
|
||||||
|
Find specific instructions about how to get started [**here**](https://github.com/garronej/keycloakify-demo-app#keycloak-theme-only).
|
||||||
|
|
||||||
|
To share your styles between your main app and your login pages you will need to externalize your design system by making it a
|
||||||
|
separate module. Checkout [ts_ci](https://github.com/garronej/ts_ci), it can help with that.
|
||||||
|
# How to use
|
||||||
## Setting up the build tool
|
## Setting up the build tool
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -178,6 +204,19 @@ You can find an example of such customization [here](https://github.com/InseeFrL
|
|||||||
|
|
||||||
And you can test the result in production by trying the login register page of [Onyxia](https://datalab.sspcloud.fr)
|
And you can test the result in production by trying the login register page of [Onyxia](https://datalab.sspcloud.fr)
|
||||||
|
|
||||||
|
Note that you don’t have to re write **all** components, only the ones that you most need customized.
|
||||||
|
Look at [here for example](https://github.com/InseeFrLab/onyxia-ui/blob/3bf18aa82b198fc6ba7998c30abf0a9ae54a58b1/src/app/components/KcApp/KcApp.tsx#L112-L120).
|
||||||
|
We want to have our very own login and register page, so we wrote customs [Login.tsx](https://github.com/InseeFrLab/onyxia-ui/blob/master/src/app/components/KcApp/Login.tsx) and [Register.txs](https://github.com/InseeFrLab/onyxia-ui/blob/master/src/app/components/KcApp/Register.tsx), we import them [here](https://github.com/InseeFrLab/onyxia-ui/blob/3bf18aa82b198fc6ba7998c30abf0a9ae54a58b1/src/app/components/KcApp/KcApp.tsx#L9-L10) and use them [here](https://github.com/InseeFrLab/onyxia-ui/blob/3bf18aa82b198fc6ba7998c30abf0a9ae54a58b1/src/app/components/KcApp/KcApp.tsx#L113-L114).
|
||||||
|
We don't want to bother, however, customizing `login-reset-password.ftl`. We are fine using the component from [the default theme](https://github.com/InseeFrLab/onyxia-ui/blob/3bf18aa82b198fc6ba7998c30abf0a9ae54a58b1/src/app/components/KcApp/KcApp.tsx#L13) with just some [CSS customization](https://github.com/InseeFrLab/onyxia-ui/blob/3bf18aa82b198fc6ba7998c30abf0a9ae54a58b1/src/app/components/KcApp/KcApp.tsx#L103-L110).
|
||||||
|
|
||||||
|
WARNING: If you chose to go this way use:
|
||||||
|
```json
|
||||||
|
"dependencies": {
|
||||||
|
"keycloakify": "~X.Y.Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
in your `package.json` instead of `^X.Y.Z`. A minor update of Keycloakify might break your app.
|
||||||
|
|
||||||
### Hot reload
|
### Hot reload
|
||||||
|
|
||||||
Rebuild the theme each time you make a change to see the result is not practical.
|
Rebuild the theme each time you make a change to see the result is not practical.
|
||||||
@ -230,6 +269,15 @@ First you need to enable the required action on the Keycloak server admin consol
|
|||||||
|
|
||||||
Then to load your own therms of services using [like this](https://github.com/garronej/keycloakify-demo-app/blob/8168c928a66605f2464f9bd28a4dc85fb0a231f9/src/index.tsx#L42-L66).
|
Then to load your own therms of services using [like this](https://github.com/garronej/keycloakify-demo-app/blob/8168c928a66605f2464f9bd28a4dc85fb0a231f9/src/index.tsx#L42-L66).
|
||||||
|
|
||||||
|
# Some pages still have the default theme. Why?
|
||||||
|
|
||||||
|
This project only support the most common user facing pages of Keycloak login.
|
||||||
|
[Here](https://user-images.githubusercontent.com/6702424/116787906-227fe700-aaa7-11eb-92ee-22e7673717c2.png) is the complete list of pages (you get them after running `yarn test`)
|
||||||
|
and [here](https://github.com/InseeFrLab/keycloakify/tree/main/src/lib/components) are the pages currently implemented by this module.
|
||||||
|
If you need to customize pages that are not supported yet you can submit an issue about it and wait for me get it implemented.
|
||||||
|
If you can't wait, PR are welcome! [Here](https://github.com/InseeFrLab/keycloakify/commit/0163459ad6b1ad0afcc34fae5f3cc28dbcf8b4a7) is the commit that adds support
|
||||||
|
for the `login-otp.ftl` page. You can use it as a model for implementing other pages.
|
||||||
|
|
||||||
# GitHub Actions
|
# GitHub Actions
|
||||||
|
|
||||||

|

|
||||||
@ -237,18 +285,6 @@ Then to load your own therms of services using [like this](https://github.com/ga
|
|||||||
[Here is a demo repo](https://github.com/garronej/keycloakify-demo-app) to show how to automate
|
[Here is a demo repo](https://github.com/garronej/keycloakify-demo-app) to show how to automate
|
||||||
the building and publishing of the theme (the .jar file).
|
the building and publishing of the theme (the .jar file).
|
||||||
|
|
||||||
# Requirements
|
|
||||||
|
|
||||||
Tested with the following Keycloak versions:
|
|
||||||
- [11.0.3](https://hub.docker.com/layers/jboss/keycloak/11.0.3/images/sha256-4438f1e51c1369371cb807dffa526e1208086b3ebb9cab009830a178de949782?context=explore)
|
|
||||||
- [12.0.4](https://hub.docker.com/layers/jboss/keycloak/12.0.4/images/sha256-67e0c88e69bd0c7aef972c40bdeb558a974013a28b3668ca790ed63a04d70584?context=explore)
|
|
||||||
|
|
||||||
This tool will be maintained to stay compatible with Keycloak v11 and up, however, the default pages you will get
|
|
||||||
(before you customize it) will always be the ones of Keycloak v11.
|
|
||||||
|
|
||||||
This tool assumes you are bundling your app with Webpack (tested with 4.44.2) .
|
|
||||||
It assumes there is a `build/` directory at the root of your react project directory containing a `index.html` file
|
|
||||||
and a `build/static/` directory generated by webpack.
|
|
||||||
|
|
||||||
**All this is defaults with [`create-react-app`](https://create-react-app.dev)** (tested with 4.0.3)
|
**All this is defaults with [`create-react-app`](https://create-react-app.dev)** (tested with 4.0.3)
|
||||||
|
|
||||||
@ -261,6 +297,8 @@ and a `build/static/` directory generated by webpack.
|
|||||||
You won't be able to [import things from your public directory **in your JavaScript code**](https://create-react-app.dev/docs/using-the-public-folder/#adding-assets-outside-of-the-module-system).
|
You won't be able to [import things from your public directory **in your JavaScript code**](https://create-react-app.dev/docs/using-the-public-folder/#adding-assets-outside-of-the-module-system).
|
||||||
(This isn't recommended anyway).
|
(This isn't recommended anyway).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## `@font-face` importing fonts from the `src/` dir
|
## `@font-face` importing fonts from the `src/` dir
|
||||||
|
|
||||||
If you are building the theme with [--external-assets](#enable-loading-in-a-blink-of-a-eye-of-login-pages-)
|
If you are building the theme with [--external-assets](#enable-loading-in-a-blink-of-a-eye-of-login-pages-)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "keycloakify",
|
"name": "keycloakify",
|
||||||
"version": "0.4.2",
|
"version": "1.1.6",
|
||||||
"description": "Keycloak theme generator for Reacts app",
|
"description": "Keycloak theme generator for Reacts app",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -51,10 +51,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cheerio": "^1.0.0-rc.5",
|
"cheerio": "^1.0.0-rc.5",
|
||||||
"evt": "2.0.0-beta.15",
|
"evt": "2.0.0-beta.15",
|
||||||
"markdown": "^0.5.0",
|
|
||||||
"minimal-polyfills": "^2.1.6",
|
"minimal-polyfills": "^2.1.6",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"powerhooks": "^0.0.36",
|
"powerhooks": "^0.1.0",
|
||||||
"react-markdown": "^5.0.3",
|
"react-markdown": "^5.0.3",
|
||||||
"scripting-tools": "^0.19.13",
|
"scripting-tools": "^0.19.13",
|
||||||
"tss-react": "^0.0.12"
|
"tss-react": "^0.0.12"
|
||||||
|
112
src/bin/build-keycloak-theme/build-keycloak-theme.ts
Normal file
112
src/bin/build-keycloak-theme/build-keycloak-theme.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { generateKeycloakThemeResources } from "./generateKeycloakThemeResources";
|
||||||
|
import { generateJavaStackFiles } from "./generateJavaStackFiles";
|
||||||
|
import type { ParsedPackageJson } from "./generateJavaStackFiles";
|
||||||
|
import { join as pathJoin, relative as pathRelative, basename as pathBasename } from "path";
|
||||||
|
import * as child_process from "child_process";
|
||||||
|
import { generateDebugFiles, containerLaunchScriptBasename } from "./generateDebugFiles";
|
||||||
|
import { URL } from "url";
|
||||||
|
|
||||||
|
|
||||||
|
const reactProjectDirPath = process.cwd();
|
||||||
|
|
||||||
|
const doUseExternalAssets = process.argv[2]?.toLowerCase() === "--external-assets";
|
||||||
|
|
||||||
|
const parsedPackageJson: ParsedPackageJson = require(pathJoin(reactProjectDirPath, "package.json"));
|
||||||
|
|
||||||
|
export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build_keycloak");
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
|
||||||
|
console.log("🔏 Building the keycloak theme...⌚");
|
||||||
|
|
||||||
|
generateKeycloakThemeResources({
|
||||||
|
keycloakThemeBuildingDirPath,
|
||||||
|
"reactAppBuildDirPath": pathJoin(reactProjectDirPath, "build"),
|
||||||
|
"themeName": parsedPackageJson.name,
|
||||||
|
...(() => {
|
||||||
|
|
||||||
|
const url = (() => {
|
||||||
|
|
||||||
|
const { homepage } = parsedPackageJson;
|
||||||
|
|
||||||
|
return homepage === undefined ?
|
||||||
|
undefined :
|
||||||
|
new URL(homepage);
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
return {
|
||||||
|
"urlPathname":
|
||||||
|
url === undefined ?
|
||||||
|
"/" :
|
||||||
|
url.pathname.replace(/([^/])$/, "$1/"),
|
||||||
|
"urlOrigin": !doUseExternalAssets ? undefined : (() => {
|
||||||
|
|
||||||
|
if (url === undefined) {
|
||||||
|
console.error("ERROR: You must specify 'homepage' in your package.json");
|
||||||
|
process.exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.origin;
|
||||||
|
|
||||||
|
})()
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
})()
|
||||||
|
});
|
||||||
|
|
||||||
|
const { jarFilePath } = generateJavaStackFiles({
|
||||||
|
parsedPackageJson,
|
||||||
|
keycloakThemeBuildingDirPath
|
||||||
|
});
|
||||||
|
|
||||||
|
child_process.execSync(
|
||||||
|
"mvn package",
|
||||||
|
{ "cwd": keycloakThemeBuildingDirPath }
|
||||||
|
);
|
||||||
|
|
||||||
|
generateDebugFiles({
|
||||||
|
keycloakThemeBuildingDirPath,
|
||||||
|
"packageJsonName": parsedPackageJson.name
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log([
|
||||||
|
'',
|
||||||
|
`✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`,
|
||||||
|
`It is to be placed in "/opt/jboss/keycloak/standalone/deployments" in the container running a jboss/keycloak Docker image. (Tested with 11.0.3)`,
|
||||||
|
'',
|
||||||
|
'Using Helm (https://github.com/codecentric/helm-charts), edit to reflect:',
|
||||||
|
'',
|
||||||
|
'value.yaml: ',
|
||||||
|
' extraInitContainers: |',
|
||||||
|
' - name: realm-ext-provider',
|
||||||
|
' image: curlimages/curl',
|
||||||
|
' imagePullPolicy: IfNotPresent',
|
||||||
|
' command:',
|
||||||
|
' - sh',
|
||||||
|
' args:',
|
||||||
|
' - -c',
|
||||||
|
` - curl -L -f -S -o /extensions/${pathBasename(jarFilePath)} https://AN.URL.FOR/${pathBasename(jarFilePath)}`,
|
||||||
|
' volumeMounts:',
|
||||||
|
' - name: extensions',
|
||||||
|
' mountPath: /extensions',
|
||||||
|
' ',
|
||||||
|
' extraVolumeMounts: |',
|
||||||
|
' - name: extensions',
|
||||||
|
' mountPath: /opt/jboss/keycloak/standalone/deployments',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'To test your theme locally, with hot reloading, you can spin up a Keycloak container image with the theme loaded by running:',
|
||||||
|
'',
|
||||||
|
`👉 $ ./${pathRelative(reactProjectDirPath, pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename))} 👈`,
|
||||||
|
'',
|
||||||
|
'To enable the theme within keycloak log into the admin console ( 👉 http://localhost:8080 username: admin, password: admin 👈), create a realm (called "myrealm" for example),',
|
||||||
|
`go to your realm settings, click on the theme tab then select ${parsedPackageJson.name}.`,
|
||||||
|
`More details: https://www.keycloak.org/getting-started/getting-started-docker`,
|
||||||
|
'',
|
||||||
|
'Once your container is up and configured 👉 http://localhost:8080/auth/realms/myrealm/account 👈',
|
||||||
|
'',
|
||||||
|
].join("\n"));
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { join as pathJoin, dirname as pathDirname, basename as pathBasename } from "path";
|
||||||
|
|
||||||
|
export const containerLaunchScriptBasename = "start_keycloak_testing_container.sh";
|
||||||
|
|
||||||
|
/** Files for being able to run a hot reload keycloak container */
|
||||||
|
export function generateDebugFiles(
|
||||||
|
params: {
|
||||||
|
packageJsonName: string;
|
||||||
|
keycloakThemeBuildingDirPath: string;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
|
||||||
|
const { packageJsonName, keycloakThemeBuildingDirPath } = params;
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
pathJoin(keycloakThemeBuildingDirPath, "Dockerfile"),
|
||||||
|
Buffer.from(
|
||||||
|
[
|
||||||
|
"FROM jboss/keycloak:11.0.3",
|
||||||
|
"",
|
||||||
|
"USER root",
|
||||||
|
"",
|
||||||
|
"WORKDIR /",
|
||||||
|
"",
|
||||||
|
"ADD configuration /opt/jboss/keycloak/standalone/configuration/",
|
||||||
|
"",
|
||||||
|
'ENTRYPOINT [ "/opt/jboss/tools/docker-entrypoint.sh" ]',
|
||||||
|
].join("\n"),
|
||||||
|
"utf8"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const dockerImage = `${packageJsonName}/keycloak-hot-reload`;
|
||||||
|
const containerName = "keycloak-testing-container";
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename),
|
||||||
|
Buffer.from(
|
||||||
|
[
|
||||||
|
"#!/bin/bash",
|
||||||
|
"",
|
||||||
|
`cd ${keycloakThemeBuildingDirPath}`,
|
||||||
|
"",
|
||||||
|
`docker rm ${containerName} || true`,
|
||||||
|
"",
|
||||||
|
`docker build . -t ${dockerImage}`,
|
||||||
|
"",
|
||||||
|
"docker run \\",
|
||||||
|
" -p 8080:8080 \\",
|
||||||
|
` --name ${containerName} \\`,
|
||||||
|
" -e KEYCLOAK_USER=admin \\",
|
||||||
|
" -e KEYCLOAK_PASSWORD=admin \\",
|
||||||
|
` -v ${pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", packageJsonName)
|
||||||
|
}:/opt/jboss/keycloak/themes/${packageJsonName}:rw \\`,
|
||||||
|
` -it ${dockerImage}:latest`,
|
||||||
|
""
|
||||||
|
].join("\n"),
|
||||||
|
"utf8"
|
||||||
|
),
|
||||||
|
{ "mode": 0o755 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const standaloneHaFilePath = pathJoin(keycloakThemeBuildingDirPath, "configuration", "standalone-ha.xml");
|
||||||
|
|
||||||
|
try { fs.mkdirSync(pathDirname(standaloneHaFilePath)); } catch { }
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
standaloneHaFilePath,
|
||||||
|
fs.readFileSync(pathJoin(__dirname, pathBasename(standaloneHaFilePath)))
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
@ -1,74 +1 @@
|
|||||||
|
export * from "./generateDebugFiles";
|
||||||
import * as fs from "fs";
|
|
||||||
import { join as pathJoin, dirname as pathDirname, basename as pathBasename } from "path";
|
|
||||||
|
|
||||||
export const containerLaunchScriptBasename = "start_keycloak_testing_container.sh";
|
|
||||||
|
|
||||||
/** Files for being able to run a hot reload keycloak container */
|
|
||||||
export function generateDebugFiles(
|
|
||||||
params: {
|
|
||||||
packageJsonName: string;
|
|
||||||
keycloakThemeBuildingDirPath: string;
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
|
|
||||||
const { packageJsonName, keycloakThemeBuildingDirPath } = params;
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
pathJoin(keycloakThemeBuildingDirPath, "Dockerfile"),
|
|
||||||
Buffer.from(
|
|
||||||
[
|
|
||||||
"FROM jboss/keycloak:11.0.3",
|
|
||||||
"",
|
|
||||||
"USER root",
|
|
||||||
"",
|
|
||||||
"WORKDIR /",
|
|
||||||
"",
|
|
||||||
"ADD configuration /opt/jboss/keycloak/standalone/configuration/",
|
|
||||||
"",
|
|
||||||
'ENTRYPOINT [ "/opt/jboss/tools/docker-entrypoint.sh" ]',
|
|
||||||
].join("\n"),
|
|
||||||
"utf8"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const dockerImage = `${packageJsonName}/keycloak-hot-reload`;
|
|
||||||
const containerName = "keycloak-testing-container";
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename),
|
|
||||||
Buffer.from(
|
|
||||||
[
|
|
||||||
"#!/bin/bash",
|
|
||||||
"",
|
|
||||||
`cd ${keycloakThemeBuildingDirPath}`,
|
|
||||||
"",
|
|
||||||
`docker rm ${containerName} || true`,
|
|
||||||
"",
|
|
||||||
`docker build . -t ${dockerImage}`,
|
|
||||||
"",
|
|
||||||
"docker run \\",
|
|
||||||
" -p 8080:8080 \\",
|
|
||||||
` --name ${containerName} \\`,
|
|
||||||
" -e KEYCLOAK_USER=admin \\",
|
|
||||||
" -e KEYCLOAK_PASSWORD=admin \\",
|
|
||||||
` -v ${pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", packageJsonName)
|
|
||||||
}:/opt/jboss/keycloak/themes/${packageJsonName}:rw \\`,
|
|
||||||
` -it ${dockerImage}:latest`,
|
|
||||||
""
|
|
||||||
].join("\n"),
|
|
||||||
"utf8"
|
|
||||||
),
|
|
||||||
{ "mode": 0o755 }
|
|
||||||
);
|
|
||||||
|
|
||||||
const standaloneHaFilePath = pathJoin(keycloakThemeBuildingDirPath, "configuration", "standalone-ha.xml");
|
|
||||||
|
|
||||||
try { fs.mkdirSync(pathDirname(standaloneHaFilePath)); } catch { }
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
standaloneHaFilePath,
|
|
||||||
fs.readFileSync(pathJoin(__dirname, pathBasename(standaloneHaFilePath)))
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
193
src/bin/build-keycloak-theme/generateFtl/generateFtl.ts
Normal file
193
src/bin/build-keycloak-theme/generateFtl/generateFtl.ts
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import cheerio from "cheerio";
|
||||||
|
import {
|
||||||
|
replaceImportsFromStaticInJsCode,
|
||||||
|
replaceImportsInInlineCssCode,
|
||||||
|
generateCssCodeToDefineGlobals
|
||||||
|
} from "../replaceImportFromStatic";
|
||||||
|
import fs from "fs";
|
||||||
|
import { join as pathJoin } from "path";
|
||||||
|
import { objectKeys } from "evt/tools/typeSafety/objectKeys";
|
||||||
|
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
|
||||||
|
|
||||||
|
export const pageIds = [
|
||||||
|
"login.ftl", "register.ftl", "info.ftl",
|
||||||
|
"error.ftl", "login-reset-password.ftl",
|
||||||
|
"login-verify-email.ftl", "terms.ftl",
|
||||||
|
"login-otp.ftl", "login-update-profile.ftl",
|
||||||
|
"login-idp-link-confirm.ftl"
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type PageId = typeof pageIds[number];
|
||||||
|
|
||||||
|
function loadAdjacentFile(fileBasename: string) {
|
||||||
|
return fs.readFileSync(pathJoin(__dirname, fileBasename))
|
||||||
|
.toString("utf8");
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadFtlFile(ftlFileBasename: PageId | "common.ftl") {
|
||||||
|
try {
|
||||||
|
|
||||||
|
return loadAdjacentFile(ftlFileBasename)
|
||||||
|
.match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1];
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function generateFtlFilesCodeFactory(
|
||||||
|
params: {
|
||||||
|
cssGlobalsToDefine: Record<string, string>;
|
||||||
|
indexHtmlCode: string;
|
||||||
|
urlPathname: string;
|
||||||
|
urlOrigin: undefined | string;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
|
||||||
|
const { cssGlobalsToDefine, indexHtmlCode, urlPathname, urlOrigin } = params;
|
||||||
|
|
||||||
|
const $ = cheerio.load(indexHtmlCode);
|
||||||
|
|
||||||
|
$("script:not([src])").each((...[, element]) => {
|
||||||
|
|
||||||
|
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
|
||||||
|
"jsCode": $(element).html()!,
|
||||||
|
urlOrigin
|
||||||
|
});
|
||||||
|
|
||||||
|
$(element).text(fixedJsCode);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$("style").each((...[, element]) => {
|
||||||
|
|
||||||
|
const { fixedCssCode } = replaceImportsInInlineCssCode({
|
||||||
|
"cssCode": $(element).html()!,
|
||||||
|
"urlPathname": params.urlPathname,
|
||||||
|
urlOrigin
|
||||||
|
});
|
||||||
|
|
||||||
|
$(element).text(fixedCssCode);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
([
|
||||||
|
["link", "href"],
|
||||||
|
["script", "src"],
|
||||||
|
] as const).forEach(([selector, attrName]) =>
|
||||||
|
$(selector).each((...[, element]) => {
|
||||||
|
|
||||||
|
const href = $(element).attr(attrName);
|
||||||
|
|
||||||
|
if (href === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(element).attr(
|
||||||
|
attrName,
|
||||||
|
urlOrigin !== undefined ?
|
||||||
|
href.replace(/^\//, `${urlOrigin}/`) :
|
||||||
|
href.replace(
|
||||||
|
new RegExp(`^${urlPathname.replace(/\//g, "\\/")}`),
|
||||||
|
"${url.resourcesPath}/build/"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
|
||||||
|
const ftlCommonPlaceholders = {
|
||||||
|
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadFtlFile("common.ftl"),
|
||||||
|
'<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->':
|
||||||
|
[
|
||||||
|
'<#if scripts??>',
|
||||||
|
' <#list scripts as script>',
|
||||||
|
' <script src="${script}" type="text/javascript"></script>',
|
||||||
|
' </#list>',
|
||||||
|
'</#if>'
|
||||||
|
].join("\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const pageSpecificCodePlaceholder = "<!-- dIddLqMeOedErIdLsPdNdI9dSl42sw -->";
|
||||||
|
|
||||||
|
$("head").prepend(
|
||||||
|
[
|
||||||
|
...(Object.keys(cssGlobalsToDefine).length === 0 ? [] : [
|
||||||
|
'',
|
||||||
|
'<style>',
|
||||||
|
generateCssCodeToDefineGlobals({
|
||||||
|
cssGlobalsToDefine,
|
||||||
|
urlPathname
|
||||||
|
}).cssCodeToPrependInHead,
|
||||||
|
'</style>',
|
||||||
|
''
|
||||||
|
]),
|
||||||
|
...["Object.deepAssign.js", "String.htmlUnescape.js"].map(
|
||||||
|
fileBasename => [
|
||||||
|
"<script>",
|
||||||
|
loadAdjacentFile(fileBasename),
|
||||||
|
"</script>"
|
||||||
|
].join("\n")
|
||||||
|
),
|
||||||
|
'<script>',
|
||||||
|
` window.${ftlValuesGlobalName}= Object.assign(`,
|
||||||
|
` {},`,
|
||||||
|
` ${objectKeys(ftlCommonPlaceholders)[0]}`,
|
||||||
|
' );',
|
||||||
|
'</script>',
|
||||||
|
'',
|
||||||
|
pageSpecificCodePlaceholder,
|
||||||
|
'',
|
||||||
|
objectKeys(ftlCommonPlaceholders)[1]
|
||||||
|
].join("\n"),
|
||||||
|
);
|
||||||
|
|
||||||
|
const partiallyFixedIndexHtmlCode = $.html();
|
||||||
|
|
||||||
|
function generateFtlFilesCode(
|
||||||
|
params: {
|
||||||
|
pageId: PageId;
|
||||||
|
}
|
||||||
|
): { ftlCode: string; } {
|
||||||
|
|
||||||
|
const { pageId } = params;
|
||||||
|
|
||||||
|
const $ = cheerio.load(partiallyFixedIndexHtmlCode);
|
||||||
|
|
||||||
|
const ftlPlaceholders = {
|
||||||
|
'{ "x": "kxOlLqMeOed9sdLdIdOxd444" }': loadFtlFile(pageId),
|
||||||
|
...ftlCommonPlaceholders
|
||||||
|
};
|
||||||
|
|
||||||
|
let ftlCode = $.html()
|
||||||
|
.replace(
|
||||||
|
pageSpecificCodePlaceholder,
|
||||||
|
[
|
||||||
|
'<script>',
|
||||||
|
` Object.deepAssign(`,
|
||||||
|
` window.${ftlValuesGlobalName},`,
|
||||||
|
` { "pageId": "${pageId}" }`,
|
||||||
|
' );',
|
||||||
|
` Object.deepAssign(`,
|
||||||
|
` window.${ftlValuesGlobalName},`,
|
||||||
|
` ${objectKeys(ftlPlaceholders)[0]}`,
|
||||||
|
' );',
|
||||||
|
'</script>'
|
||||||
|
].join("\n")
|
||||||
|
);
|
||||||
|
|
||||||
|
objectKeys(ftlPlaceholders)
|
||||||
|
.forEach(id => ftlCode = ftlCode.replace(id, ftlPlaceholders[id]));
|
||||||
|
|
||||||
|
return { ftlCode };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return { generateFtlFilesCode };
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,191 +1 @@
|
|||||||
|
export * from "./generateFtl";
|
||||||
|
|
||||||
import cheerio from "cheerio";
|
|
||||||
import {
|
|
||||||
replaceImportsFromStaticInJsCode,
|
|
||||||
replaceImportsInInlineCssCode,
|
|
||||||
generateCssCodeToDefineGlobals
|
|
||||||
} from "../replaceImportFromStatic";
|
|
||||||
import fs from "fs";
|
|
||||||
import { join as pathJoin } from "path";
|
|
||||||
import { objectKeys } from "evt/tools/typeSafety/objectKeys";
|
|
||||||
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
|
|
||||||
|
|
||||||
export const pageIds = [
|
|
||||||
"login.ftl", "register.ftl", "info.ftl",
|
|
||||||
"error.ftl", "login-reset-password.ftl",
|
|
||||||
"login-verify-email.ftl", "terms.ftl"
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
export type PageId = typeof pageIds[number];
|
|
||||||
|
|
||||||
function loadAdjacentFile(fileBasename: string) {
|
|
||||||
return fs.readFileSync(pathJoin(__dirname, fileBasename))
|
|
||||||
.toString("utf8");
|
|
||||||
};
|
|
||||||
|
|
||||||
function loadFtlFile(ftlFileBasename: PageId | "common.ftl") {
|
|
||||||
try {
|
|
||||||
|
|
||||||
return loadAdjacentFile(ftlFileBasename)
|
|
||||||
.match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1];
|
|
||||||
|
|
||||||
} catch {
|
|
||||||
return "{}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function generateFtlFilesCodeFactory(
|
|
||||||
params: {
|
|
||||||
cssGlobalsToDefine: Record<string, string>;
|
|
||||||
indexHtmlCode: string;
|
|
||||||
urlPathname: string;
|
|
||||||
urlOrigin: undefined | string;
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
|
|
||||||
const { cssGlobalsToDefine, indexHtmlCode, urlPathname, urlOrigin } = params;
|
|
||||||
|
|
||||||
const $ = cheerio.load(indexHtmlCode);
|
|
||||||
|
|
||||||
$("script:not([src])").each((...[, element]) => {
|
|
||||||
|
|
||||||
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
|
|
||||||
"jsCode": $(element).html()!,
|
|
||||||
urlOrigin
|
|
||||||
});
|
|
||||||
|
|
||||||
$(element).text(fixedJsCode);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$("style").each((...[, element]) => {
|
|
||||||
|
|
||||||
const { fixedCssCode } = replaceImportsInInlineCssCode({
|
|
||||||
"cssCode": $(element).html()!,
|
|
||||||
"urlPathname": params.urlPathname,
|
|
||||||
urlOrigin
|
|
||||||
});
|
|
||||||
|
|
||||||
$(element).text(fixedCssCode);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
([
|
|
||||||
["link", "href"],
|
|
||||||
["script", "src"],
|
|
||||||
] as const).forEach(([selector, attrName]) =>
|
|
||||||
$(selector).each((...[, element]) => {
|
|
||||||
|
|
||||||
const href = $(element).attr(attrName);
|
|
||||||
|
|
||||||
if (href === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$(element).attr(
|
|
||||||
attrName,
|
|
||||||
urlOrigin !== undefined ?
|
|
||||||
href.replace(/^\//, `${urlOrigin}/`) :
|
|
||||||
href.replace(
|
|
||||||
new RegExp(`^${urlPathname.replace(/\//g, "\\/")}`),
|
|
||||||
"${url.resourcesPath}/build/"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
|
|
||||||
const ftlCommonPlaceholders = {
|
|
||||||
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadFtlFile("common.ftl"),
|
|
||||||
'<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->':
|
|
||||||
[
|
|
||||||
'<#if scripts??>',
|
|
||||||
' <#list scripts as script>',
|
|
||||||
' <script src="${script}" type="text/javascript"></script>',
|
|
||||||
' </#list>',
|
|
||||||
'</#if>'
|
|
||||||
].join("\n")
|
|
||||||
};
|
|
||||||
|
|
||||||
const pageSpecificCodePlaceholder = "<!-- dIddLqMeOedErIdLsPdNdI9dSl42sw -->";
|
|
||||||
|
|
||||||
$("head").prepend(
|
|
||||||
[
|
|
||||||
...(Object.keys(cssGlobalsToDefine).length === 0 ? [] : [
|
|
||||||
'',
|
|
||||||
'<style>',
|
|
||||||
generateCssCodeToDefineGlobals({
|
|
||||||
cssGlobalsToDefine,
|
|
||||||
urlPathname
|
|
||||||
}).cssCodeToPrependInHead,
|
|
||||||
'</style>',
|
|
||||||
''
|
|
||||||
]),
|
|
||||||
...["Object.deepAssign.js", "String.htmlUnescape.js"].map(
|
|
||||||
fileBasename => [
|
|
||||||
"<script>",
|
|
||||||
loadAdjacentFile(fileBasename),
|
|
||||||
"</script>"
|
|
||||||
].join("\n")
|
|
||||||
),
|
|
||||||
'<script>',
|
|
||||||
` window.${ftlValuesGlobalName}= Object.assign(`,
|
|
||||||
` {},`,
|
|
||||||
` ${objectKeys(ftlCommonPlaceholders)[0]}`,
|
|
||||||
' );',
|
|
||||||
'</script>',
|
|
||||||
'',
|
|
||||||
pageSpecificCodePlaceholder,
|
|
||||||
'',
|
|
||||||
objectKeys(ftlCommonPlaceholders)[1]
|
|
||||||
].join("\n"),
|
|
||||||
);
|
|
||||||
|
|
||||||
const partiallyFixedIndexHtmlCode = $.html();
|
|
||||||
|
|
||||||
function generateFtlFilesCode(
|
|
||||||
params: {
|
|
||||||
pageId: PageId;
|
|
||||||
}
|
|
||||||
): { ftlCode: string; } {
|
|
||||||
|
|
||||||
const { pageId } = params;
|
|
||||||
|
|
||||||
const $ = cheerio.load(partiallyFixedIndexHtmlCode);
|
|
||||||
|
|
||||||
const ftlPlaceholders = {
|
|
||||||
'{ "x": "kxOlLqMeOed9sdLdIdOxd444" }': loadFtlFile(pageId),
|
|
||||||
...ftlCommonPlaceholders
|
|
||||||
};
|
|
||||||
|
|
||||||
let ftlCode = $.html()
|
|
||||||
.replace(
|
|
||||||
pageSpecificCodePlaceholder,
|
|
||||||
[
|
|
||||||
'<script>',
|
|
||||||
` Object.deepAssign(`,
|
|
||||||
` window.${ftlValuesGlobalName},`,
|
|
||||||
` { "pageId": "${pageId}" }`,
|
|
||||||
' );',
|
|
||||||
` Object.deepAssign(`,
|
|
||||||
` window.${ftlValuesGlobalName},`,
|
|
||||||
` ${objectKeys(ftlPlaceholders)[0]}`,
|
|
||||||
' );',
|
|
||||||
'</script>'
|
|
||||||
].join("\n")
|
|
||||||
);
|
|
||||||
|
|
||||||
objectKeys(ftlPlaceholders)
|
|
||||||
.forEach(id => ftlCode = ftlCode.replace(id, ftlPlaceholders[id]));
|
|
||||||
|
|
||||||
return { ftlCode };
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return { generateFtlFilesCode };
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,11 @@
|
|||||||
|
<script>const _=
|
||||||
|
{
|
||||||
|
"idpAlias": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${idpAlias}";
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
return "";
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
</script>
|
37
src/bin/build-keycloak-theme/generateFtl/login-otp.ftl
Normal file
37
src/bin/build-keycloak-theme/generateFtl/login-otp.ftl
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<script>const _=
|
||||||
|
{
|
||||||
|
"otpLogin": {
|
||||||
|
"userOtpCredentials": (function(){
|
||||||
|
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
<#attempt>
|
||||||
|
<#list otpLogin.userOtpCredentials as otpCredential>
|
||||||
|
out.push({
|
||||||
|
"id": (function (){
|
||||||
|
|
||||||
|
<#attempt>
|
||||||
|
return "${otpCredential.id}";
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
|
||||||
|
})(),
|
||||||
|
"userLabel": (function (){
|
||||||
|
|
||||||
|
<#attempt>
|
||||||
|
return "${otpCredential.userLabel}";
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
|
||||||
|
})()
|
||||||
|
});
|
||||||
|
</#list>
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
|
||||||
|
return out;
|
||||||
|
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,67 @@
|
|||||||
|
<script>const _=
|
||||||
|
{
|
||||||
|
"user": {
|
||||||
|
"editUsernameAllowed": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return ${user.editUsernameAllowed?c};
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"username": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${user.username!''}" || undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"email": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${user.email!''}" || undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"firstName": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${user.firstName!''}" || undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"lastName": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${user.lastName!''}" || undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})()
|
||||||
|
},
|
||||||
|
"messagesPerField": {
|
||||||
|
"printIfExists": function (key, x) {
|
||||||
|
switch(key){
|
||||||
|
case "username": return (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${messagesPerField.printIfExists('username','1')}" ? x : undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})();
|
||||||
|
case "email": return (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${messagesPerField.printIfExists('email','1')}" ? x : undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})();
|
||||||
|
case "firstName": return (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${messagesPerField.printIfExists('firstName','1')}" ? x : undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})();
|
||||||
|
case "lastName": return (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${messagesPerField.printIfExists('lastName','1')}" ? x : undefined;
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
@ -170,7 +170,7 @@
|
|||||||
out.push((function (){
|
out.push((function (){
|
||||||
|
|
||||||
<#attempt>
|
<#attempt>
|
||||||
return "${authorizedMailDomains}";
|
return "${authorizedMailDomain}";
|
||||||
<#recover>
|
<#recover>
|
||||||
</#attempt>
|
</#attempt>
|
||||||
|
|
||||||
@ -185,5 +185,59 @@
|
|||||||
return out;
|
return out;
|
||||||
|
|
||||||
})(),
|
})(),
|
||||||
|
"social": {
|
||||||
|
"displayInfo": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return ${social.displayInfo?c};
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"providers": (()=>{
|
||||||
|
|
||||||
|
<#attempt>
|
||||||
|
<#if social.providers??>
|
||||||
|
|
||||||
|
var out= [];
|
||||||
|
|
||||||
|
<#attempt>
|
||||||
|
<#list social.providers as p>
|
||||||
|
out.push({
|
||||||
|
"loginUrl": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${p.loginUrl?no_esc}";
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"alias": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${p.alias}";
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"providerId": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${p.providerId}";
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})(),
|
||||||
|
"displayName": (function (){
|
||||||
|
<#attempt>
|
||||||
|
return "${p.displayName}";
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
})()
|
||||||
|
});
|
||||||
|
</#list>
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
|
||||||
|
return out;
|
||||||
|
|
||||||
|
</#if>
|
||||||
|
<#recover>
|
||||||
|
</#attempt>
|
||||||
|
|
||||||
|
})()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -1,115 +1,10 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { generateKeycloakThemeResources } from "./generateKeycloakThemeResources";
|
export * from "./build-keycloak-theme";
|
||||||
import { generateJavaStackFiles } from "./generateJavaStackFiles";
|
import { main } from "./build-keycloak-theme";
|
||||||
import type { ParsedPackageJson } from "./generateJavaStackFiles";
|
|
||||||
import { join as pathJoin, relative as pathRelative, basename as pathBasename } from "path";
|
|
||||||
import * as child_process from "child_process";
|
|
||||||
import { generateDebugFiles, containerLaunchScriptBasename } from "./generateDebugFiles";
|
|
||||||
import { URL } from "url";
|
|
||||||
|
|
||||||
|
|
||||||
const reactProjectDirPath = process.cwd();
|
|
||||||
|
|
||||||
const doUseExternalAssets = process.argv[2]?.toLowerCase() === "--external-assets";
|
|
||||||
|
|
||||||
const parsedPackageJson: ParsedPackageJson = require(pathJoin(reactProjectDirPath, "package.json"));
|
|
||||||
|
|
||||||
export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build_keycloak");
|
|
||||||
|
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|
||||||
console.log("🔏 Building the keycloak theme...⌚");
|
main();
|
||||||
|
|
||||||
generateKeycloakThemeResources({
|
}
|
||||||
keycloakThemeBuildingDirPath,
|
|
||||||
"reactAppBuildDirPath": pathJoin(reactProjectDirPath, "build"),
|
|
||||||
"themeName": parsedPackageJson.name,
|
|
||||||
...(() => {
|
|
||||||
|
|
||||||
const url = (() => {
|
|
||||||
|
|
||||||
const { homepage } = parsedPackageJson;
|
|
||||||
|
|
||||||
return homepage === undefined ?
|
|
||||||
undefined :
|
|
||||||
new URL(homepage);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
return {
|
|
||||||
"urlPathname":
|
|
||||||
url === undefined ?
|
|
||||||
"/" :
|
|
||||||
url.pathname.replace(/([^/])$/, "$1/"),
|
|
||||||
"urlOrigin": !doUseExternalAssets ? undefined : (() => {
|
|
||||||
|
|
||||||
if (url === undefined) {
|
|
||||||
console.error("ERROR: You must specify 'homepage' in your package.json");
|
|
||||||
process.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return url.origin;
|
|
||||||
|
|
||||||
})()
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
})()
|
|
||||||
});
|
|
||||||
|
|
||||||
const { jarFilePath } = generateJavaStackFiles({
|
|
||||||
parsedPackageJson,
|
|
||||||
keycloakThemeBuildingDirPath
|
|
||||||
});
|
|
||||||
|
|
||||||
child_process.execSync(
|
|
||||||
"mvn package",
|
|
||||||
{ "cwd": keycloakThemeBuildingDirPath }
|
|
||||||
);
|
|
||||||
|
|
||||||
generateDebugFiles({
|
|
||||||
keycloakThemeBuildingDirPath,
|
|
||||||
"packageJsonName": parsedPackageJson.name
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log([
|
|
||||||
'',
|
|
||||||
`✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`,
|
|
||||||
`It is to be placed in "/opt/jboss/keycloak/standalone/deployments" in the container running a jboss/keycloak Docker image. (Tested with 11.0.3)`,
|
|
||||||
'',
|
|
||||||
'Using Helm (https://github.com/codecentric/helm-charts), edit to reflect:',
|
|
||||||
'',
|
|
||||||
'value.yaml: ',
|
|
||||||
' extraInitContainers: |',
|
|
||||||
' - name: realm-ext-provider',
|
|
||||||
' image: curlimages/curl',
|
|
||||||
' imagePullPolicy: IfNotPresent',
|
|
||||||
' command:',
|
|
||||||
' - sh',
|
|
||||||
' args:',
|
|
||||||
' - -c',
|
|
||||||
` - curl -L -f -S -o /extensions/${pathBasename(jarFilePath)} https://AN.URL.FOR/${pathBasename(jarFilePath)}`,
|
|
||||||
' volumeMounts:',
|
|
||||||
' - name: extensions',
|
|
||||||
' mountPath: /extensions',
|
|
||||||
' ',
|
|
||||||
' extraVolumeMounts: |',
|
|
||||||
' - name: extensions',
|
|
||||||
' mountPath: /opt/jboss/keycloak/standalone/deployments',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'To test your theme locally, with hot reloading, you can spin up a Keycloak container image with the theme loaded by running:',
|
|
||||||
'',
|
|
||||||
`👉 $ ./${pathRelative(reactProjectDirPath, pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename))} 👈`,
|
|
||||||
'',
|
|
||||||
'To enable the theme within keycloak log into the admin console ( 👉 http://localhost:8080 username: admin, password: admin 👈), create a realm (called "myrealm" for example),',
|
|
||||||
`go to your realm settings, click on the theme tab then select ${parsedPackageJson.name}.`,
|
|
||||||
`More details: https://www.keycloak.org/getting-started/getting-started-docker`,
|
|
||||||
'',
|
|
||||||
'Once your container is up and configured 👉 http://localhost:8080/auth/realms/myrealm/account 👈',
|
|
||||||
'',
|
|
||||||
].join("\n"));
|
|
||||||
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ import { downloadAndUnzip } from "./tools/downloadAndUnzip";
|
|||||||
import { join as pathJoin } from "path";
|
import { join as pathJoin } from "path";
|
||||||
|
|
||||||
export const builtinThemesUrl =
|
export const builtinThemesUrl =
|
||||||
"https://github.com/garronej/keycloakify/releases/download/v0.0.1/keycloak_11.0.3_builtin_themes_with_light_mods.zip";
|
"https://github.com/garronej/keycloakify/releases/download/v0.0.1/keycloak_11.0.3_builtin_themes.zip";
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
|
|
||||||
|
@ -9,8 +9,11 @@ import { Error } from "./Error";
|
|||||||
import { LoginResetPassword } from "./LoginResetPassword";
|
import { LoginResetPassword } from "./LoginResetPassword";
|
||||||
import { LoginVerifyEmail } from "./LoginVerifyEmail";
|
import { LoginVerifyEmail } from "./LoginVerifyEmail";
|
||||||
import { Terms } from "./Terms";
|
import { Terms } from "./Terms";
|
||||||
|
import { LoginOtp } from "./LoginOtp";
|
||||||
|
import { LoginUpdateProfile } from "./LoginUpdateProfile";
|
||||||
|
import { LoginIdpLinkConfirm } from "./LoginIdpLinkConfirm";
|
||||||
|
|
||||||
export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContext; } & KcProps ) => {
|
export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContext; } & KcProps) => {
|
||||||
switch (kcContext.pageId) {
|
switch (kcContext.pageId) {
|
||||||
case "login.ftl": return <Login {...{ kcContext, ...props }} />;
|
case "login.ftl": return <Login {...{ kcContext, ...props }} />;
|
||||||
case "register.ftl": return <Register {...{ kcContext, ...props }} />;
|
case "register.ftl": return <Register {...{ kcContext, ...props }} />;
|
||||||
@ -18,6 +21,9 @@ export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContext; } &
|
|||||||
case "error.ftl": return <Error {...{ kcContext, ...props }} />;
|
case "error.ftl": return <Error {...{ kcContext, ...props }} />;
|
||||||
case "login-reset-password.ftl": return <LoginResetPassword {...{ kcContext, ...props }} />;
|
case "login-reset-password.ftl": return <LoginResetPassword {...{ kcContext, ...props }} />;
|
||||||
case "login-verify-email.ftl": return <LoginVerifyEmail {...{ kcContext, ...props }} />;
|
case "login-verify-email.ftl": return <LoginVerifyEmail {...{ kcContext, ...props }} />;
|
||||||
case "terms.ftl": return <Terms {...{ kcContext, ...props }}/>;
|
case "terms.ftl": return <Terms {...{ kcContext, ...props }} />;
|
||||||
|
case "login-otp.ftl": return <LoginOtp {...{ kcContext, ...props }} />;
|
||||||
|
case "login-update-profile.ftl": return <LoginUpdateProfile {...{ kcContext, ...props }} />;
|
||||||
|
case "login-idp-link-confirm.ftl": return <LoginIdpLinkConfirm {...{ kcContext, ...props }} />;
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -120,7 +120,7 @@ export const Login = memo(({ kcContext, ...props }: { kcContext: KcContext.Login
|
|||||||
<ul className={cx(props.kcFormSocialAccountListClass, social.providers.length > 4 && props.kcFormSocialAccountDoubleListClass)}>
|
<ul className={cx(props.kcFormSocialAccountListClass, social.providers.length > 4 && props.kcFormSocialAccountDoubleListClass)}>
|
||||||
{
|
{
|
||||||
social.providers.map(p =>
|
social.providers.map(p =>
|
||||||
<li className={cx(props.kcFormSocialAccountListLinkClass)}>
|
<li key={p.providerId} className={cx(props.kcFormSocialAccountListLinkClass)}>
|
||||||
<a href={p.loginUrl} id={`zocial-${p.alias}`} className={cx("zocial", p.providerId)}>
|
<a href={p.loginUrl} id={`zocial-${p.alias}`} className={cx("zocial", p.providerId)}>
|
||||||
<span>{p.displayName}</span>
|
<span>{p.displayName}</span>
|
||||||
</a>
|
</a>
|
||||||
|
58
src/lib/components/LoginIdpLinkConfirm.tsx
Normal file
58
src/lib/components/LoginIdpLinkConfirm.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
import { memo } from "react";
|
||||||
|
import { Template } from "./Template";
|
||||||
|
import type { KcProps } from "./KcProps";
|
||||||
|
import type { KcContext } from "../KcContext";
|
||||||
|
import { useKcMessage } from "../i18n/useKcMessage";
|
||||||
|
import { cx } from "tss-react";
|
||||||
|
|
||||||
|
export const LoginIdpLinkConfirm = memo(({ kcContext, ...props }: { kcContext: KcContext.LoginIdpLinkConfirm; } & KcProps) => {
|
||||||
|
|
||||||
|
const { msg } = useKcMessage();
|
||||||
|
|
||||||
|
const { url, idpAlias } = kcContext;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Template
|
||||||
|
{...{ kcContext, ...props }}
|
||||||
|
headerNode={msg("confirmLinkIdpTitle")}
|
||||||
|
formNode={
|
||||||
|
<form id="kc-register-form" action={url.loginAction} method="post">
|
||||||
|
<div className={cx(props.kcFormGroupClass)}>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className={cx(
|
||||||
|
props.kcButtonClass,
|
||||||
|
props.kcButtonDefaultClass,
|
||||||
|
props.kcButtonBlockClass,
|
||||||
|
props.kcButtonLargeClass
|
||||||
|
)}
|
||||||
|
name="submitAction"
|
||||||
|
id="updateProfile"
|
||||||
|
value="updateProfile"
|
||||||
|
>
|
||||||
|
{msg("confirmLinkIdpReviewProfile")}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className={cx(
|
||||||
|
props.kcButtonClass,
|
||||||
|
props.kcButtonDefaultClass,
|
||||||
|
props.kcButtonBlockClass,
|
||||||
|
props.kcButtonLargeClass
|
||||||
|
)}
|
||||||
|
name="submitAction"
|
||||||
|
id="linkAccount"
|
||||||
|
value="linkAccount"
|
||||||
|
>
|
||||||
|
{msg("confirmLinkIdpContinue", idpAlias)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
145
src/lib/components/LoginOtp.tsx
Normal file
145
src/lib/components/LoginOtp.tsx
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import { useEffect, memo } from "react";
|
||||||
|
import { Template } from "./Template";
|
||||||
|
import type { KcProps } from "./KcProps";
|
||||||
|
import type { KcContext } from "../KcContext";
|
||||||
|
import { useKcMessage } from "../i18n/useKcMessage";
|
||||||
|
import { appendHead } from "../tools/appendHead";
|
||||||
|
import { join as pathJoin } from "path";
|
||||||
|
import { cx } from "tss-react";
|
||||||
|
|
||||||
|
export const LoginOtp = memo(({ kcContext, ...props }: { kcContext: KcContext.LoginOtp; } & KcProps) => {
|
||||||
|
|
||||||
|
const { otpLogin, url } = kcContext;
|
||||||
|
|
||||||
|
const { msg, msgStr } = useKcMessage();
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
|
||||||
|
let isCleanedUp = false;
|
||||||
|
|
||||||
|
appendHead({
|
||||||
|
"type": "javascript",
|
||||||
|
"src": pathJoin(
|
||||||
|
kcContext.url.resourcesCommonPath,
|
||||||
|
"node_modules/jquery/dist/jquery.min.js"
|
||||||
|
)
|
||||||
|
}).then(() => {
|
||||||
|
|
||||||
|
if (isCleanedUp) return;
|
||||||
|
|
||||||
|
evaluateInlineScript();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => { isCleanedUp = true };
|
||||||
|
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Template
|
||||||
|
{...{ kcContext, ...props }}
|
||||||
|
headerNode={msg("doLogIn")}
|
||||||
|
formNode={
|
||||||
|
|
||||||
|
<form
|
||||||
|
id="kc-otp-login-form"
|
||||||
|
className={cx(props.kcFormClass)}
|
||||||
|
action={url.loginAction}
|
||||||
|
method="post"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
otpLogin.userOtpCredentials.length > 1 &&
|
||||||
|
<div className={cx(props.kcFormGroupClass)}>
|
||||||
|
<div className={cx(props.kcInputWrapperClass)}>
|
||||||
|
{
|
||||||
|
otpLogin.userOtpCredentials.map(otpCredential =>
|
||||||
|
<div key={otpCredential.id} className={cx(props.kcSelectOTPListClass)}>
|
||||||
|
<input type="hidden" value="${otpCredential.id}" />
|
||||||
|
<div className={cx(props.kcSelectOTPListItemClass)}>
|
||||||
|
<span className={cx(props.kcAuthenticatorOtpCircleClass)} />
|
||||||
|
<h2 className={cx(props.kcSelectOTPItemHeadingClass)}>
|
||||||
|
{otpCredential.userLabel}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
<div className={cx(props.kcFormGroupClass)}>
|
||||||
|
<div className={cx(props.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="otp" className={cx(props.kcLabelClass)}>
|
||||||
|
{msg("loginOtpOneTime")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(props.kcInputWrapperClass)}>
|
||||||
|
<input
|
||||||
|
id="otp"
|
||||||
|
name="otp"
|
||||||
|
autoComplete="off"
|
||||||
|
type="text"
|
||||||
|
className={cx(props.kcInputClass)}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(props.kcFormGroupClass)}>
|
||||||
|
<div id="kc-form-options" className={cx(props.kcFormOptionsClass)}>
|
||||||
|
<div className={cx(props.kcFormOptionsWrapperClass)} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
|
||||||
|
<input
|
||||||
|
className={cx(
|
||||||
|
props.kcButtonClass,
|
||||||
|
props.kcButtonPrimaryClass,
|
||||||
|
props.kcButtonBlockClass,
|
||||||
|
props.kcButtonLargeClass
|
||||||
|
)}
|
||||||
|
name="login"
|
||||||
|
id="kc-login"
|
||||||
|
type="submit"
|
||||||
|
value={msgStr("doLogIn")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form >
|
||||||
|
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
declare const $: any;
|
||||||
|
|
||||||
|
function evaluateInlineScript() {
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
// Card Single Select
|
||||||
|
$('.card-pf-view-single-select').click(function (this: any) {
|
||||||
|
if ($(this).hasClass('active')) { $(this).removeClass('active'); $(this).children().removeAttr('name'); }
|
||||||
|
else {
|
||||||
|
$('.card-pf-view-single-select').removeClass('active');
|
||||||
|
$('.card-pf-view-single-select').children().removeAttr('name');
|
||||||
|
$(this).addClass('active'); $(this).children().attr('name', 'selectedCredentialId');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var defaultCred = $('.card-pf-view-single-select')[0];
|
||||||
|
if (defaultCred) {
|
||||||
|
defaultCred.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
130
src/lib/components/LoginUpdateProfile.tsx
Normal file
130
src/lib/components/LoginUpdateProfile.tsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import { memo } from "react";
|
||||||
|
import { Template } from "./Template";
|
||||||
|
import type { KcProps } from "./KcProps";
|
||||||
|
import type { KcContext } from "../KcContext";
|
||||||
|
import { useKcMessage } from "../i18n/useKcMessage";
|
||||||
|
import { cx } from "tss-react";
|
||||||
|
|
||||||
|
export const LoginUpdateProfile = memo(({ kcContext, ...props }: { kcContext: KcContext.LoginUpdateProfile; } & KcProps) => {
|
||||||
|
|
||||||
|
const { msg, msgStr } = useKcMessage();
|
||||||
|
|
||||||
|
const { url, user, messagesPerField, isAppInitiatedAction } = kcContext;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Template
|
||||||
|
{...{ kcContext, ...props }}
|
||||||
|
headerNode={msg("loginProfileTitle")}
|
||||||
|
formNode={
|
||||||
|
<form id="kc-update-profile-form" className={cx(props.kcFormClass)} action={url.loginAction} method="post">
|
||||||
|
{user.editUsernameAllowed &&
|
||||||
|
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("username", props.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(props.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="username" className={cx(props.kcLabelClass)}>
|
||||||
|
{msg("username")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(props.kcInputWrapperClass)}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="username"
|
||||||
|
name="username"
|
||||||
|
defaultValue={user.username ?? ""}
|
||||||
|
className={cx(props.kcInputClass)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("email", props.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(props.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="email" className={cx(props.kcLabelClass)}>
|
||||||
|
{msg("email")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(props.kcInputWrapperClass)}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="email"
|
||||||
|
name="email"
|
||||||
|
defaultValue={user.email ?? ""}
|
||||||
|
className={cx(props.kcInputClass)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("firstName", props.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(props.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="firstName" className={cx(props.kcLabelClass)}>
|
||||||
|
{msg("firstName")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(props.kcInputWrapperClass)}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="firstName"
|
||||||
|
name="firstName"
|
||||||
|
defaultValue={user.firstName ?? ""}
|
||||||
|
className={cx(props.kcInputClass)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(props.kcFormGroupClass, messagesPerField.printIfExists("lastName", props.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(props.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="lastName" className={cx(props.kcLabelClass)}>
|
||||||
|
{msg("lastName")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(props.kcInputWrapperClass)}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="lastName"
|
||||||
|
name="lastName"
|
||||||
|
defaultValue={user.lastName ?? ""}
|
||||||
|
className={cx(props.kcInputClass)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(props.kcFormGroupClass)}>
|
||||||
|
<div id="kc-form-options" className={cx(props.kcFormOptionsClass)}>
|
||||||
|
<div className={cx(props.kcFormOptionsWrapperClass)} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="kc-form-buttons" className={cx(props.kcFormButtonsClass)}>
|
||||||
|
{
|
||||||
|
isAppInitiatedAction ?
|
||||||
|
<>
|
||||||
|
<input
|
||||||
|
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonLargeClass)}
|
||||||
|
type="submit"
|
||||||
|
defaultValue={msgStr("doSubmit")}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
className={cx(props.kcButtonClass, props.kcButtonDefaultClass, props.kcButtonLargeClass)}
|
||||||
|
type="submit"
|
||||||
|
name="cancel-aia"
|
||||||
|
value="true"
|
||||||
|
>
|
||||||
|
{msg("doCancel")}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
:
|
||||||
|
<input
|
||||||
|
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
|
||||||
|
type="submit"
|
||||||
|
defaultValue={msgStr("doSubmit")}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -269,7 +269,10 @@ export const Template = memo((props: TemplateProps) => {
|
|||||||
{message.type === "warning" && <span className={cx(props.kcFeedbackWarningIcon)}></span>}
|
{message.type === "warning" && <span className={cx(props.kcFeedbackWarningIcon)}></span>}
|
||||||
{message.type === "error" && <span className={cx(props.kcFeedbackErrorIcon)}></span>}
|
{message.type === "error" && <span className={cx(props.kcFeedbackErrorIcon)}></span>}
|
||||||
{message.type === "info" && <span className={cx(props.kcFeedbackInfoIcon)}></span>}
|
{message.type === "info" && <span className={cx(props.kcFeedbackInfoIcon)}></span>}
|
||||||
<span className="kc-feedback-text">{message.summary}</span>
|
<span
|
||||||
|
className="kc-feedback-text"
|
||||||
|
dangerouslySetInnerHTML={{ "__html": message.summary }}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{formNode}
|
{formNode}
|
||||||
|
@ -10,7 +10,7 @@ const wrap = createUseGlobalState(
|
|||||||
kcContext?.locale?.current ??
|
kcContext?.locale?.current ??
|
||||||
navigator.language
|
navigator.language
|
||||||
),
|
),
|
||||||
{ "persistance": "cookie" }
|
{ "persistance": "localStorage" }
|
||||||
);
|
);
|
||||||
|
|
||||||
export const { useKcLanguageTag } = wrap;
|
export const { useKcLanguageTag } = wrap;
|
||||||
|
@ -17,7 +17,8 @@ type ExtractAfterStartingWith<Prefix extends string, StrEnum> =
|
|||||||
export type KcContext =
|
export type KcContext =
|
||||||
KcContext.Login | KcContext.Register | KcContext.Info |
|
KcContext.Login | KcContext.Register | KcContext.Info |
|
||||||
KcContext.Error | KcContext.LoginResetPassword | KcContext.LoginVerifyEmail |
|
KcContext.Error | KcContext.LoginResetPassword | KcContext.LoginVerifyEmail |
|
||||||
KcContext.Terms;
|
KcContext.Terms | KcContext.LoginOtp | KcContext.LoginUpdateProfile |
|
||||||
|
KcContext.LoginIdpLinkConfirm;
|
||||||
|
|
||||||
export declare namespace KcContext {
|
export declare namespace KcContext {
|
||||||
|
|
||||||
@ -124,7 +125,20 @@ export declare namespace KcContext {
|
|||||||
passwordRequired: boolean;
|
passwordRequired: boolean;
|
||||||
recaptchaRequired: boolean;
|
recaptchaRequired: boolean;
|
||||||
recaptchaSiteKey?: string;
|
recaptchaSiteKey?: string;
|
||||||
|
/**
|
||||||
|
* Defined when you use the keycloak-mail-whitelisting keycloak plugin
|
||||||
|
* (https://github.com/micedre/keycloak-mail-whitelisting)
|
||||||
|
*/
|
||||||
authorizedMailDomains?: string[];
|
authorizedMailDomains?: string[];
|
||||||
|
social: {
|
||||||
|
displayInfo: boolean;
|
||||||
|
providers?: {
|
||||||
|
loginUrl: string;
|
||||||
|
alias: string;
|
||||||
|
providerId: string;
|
||||||
|
displayName: string;
|
||||||
|
}[]
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Info = Common & {
|
export type Info = Common & {
|
||||||
@ -161,6 +175,36 @@ export declare namespace KcContext {
|
|||||||
pageId: "terms.ftl";
|
pageId: "terms.ftl";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type LoginOtp = Common & {
|
||||||
|
pageId: "login-otp.ftl";
|
||||||
|
otpLogin: {
|
||||||
|
userOtpCredentials: { id: string; userLabel: string; }[];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LoginUpdateProfile = Common & {
|
||||||
|
pageId: "login-update-profile.ftl";
|
||||||
|
user: {
|
||||||
|
editUsernameAllowed: boolean;
|
||||||
|
username?: string;
|
||||||
|
email?: string;
|
||||||
|
firstName?: string;
|
||||||
|
lastName?: string;
|
||||||
|
};
|
||||||
|
messagesPerField: {
|
||||||
|
printIfExists<T>(
|
||||||
|
key: "username" | "email" | "firstName" | "lastName",
|
||||||
|
x: T
|
||||||
|
): T | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LoginIdpLinkConfirm = Common & {
|
||||||
|
pageId: "login-idp-link-confirm.ftl";
|
||||||
|
idpAlias: string;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doExtends<KcContext["pageId"], PageId>();
|
doExtends<KcContext["pageId"], PageId>();
|
||||||
|
@ -1,213 +1 @@
|
|||||||
|
export * from "./kcContextMocks";
|
||||||
|
|
||||||
import type { KcContext } from "../KcContext";
|
|
||||||
import { getEvtKcLanguage } from "../i18n/useKcLanguageTag";
|
|
||||||
import { getKcLanguageTagLabel } from "../i18n/KcLanguageTag";
|
|
||||||
//NOTE: Aside because we want to be able to import them from node
|
|
||||||
import { resourcesCommonPath, resourcesPath } from "./urlResourcesPath";
|
|
||||||
|
|
||||||
const kcCommonContext: KcContext.Common = {
|
|
||||||
"url": {
|
|
||||||
"loginAction": "#",
|
|
||||||
"resourcesPath": `${process.env["PUBLIC_URL"]}/${resourcesPath}`,
|
|
||||||
"resourcesCommonPath": `${process.env["PUBLIC_URL"]}/${resourcesCommonPath}`,
|
|
||||||
"loginRestartFlowUrl": "/auth/realms/myrealm/login-actions/restart?client_id=account&tab_id=HoAx28ja4xg",
|
|
||||||
"loginUrl": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg",
|
|
||||||
},
|
|
||||||
"realm": {
|
|
||||||
"displayName": "myrealm",
|
|
||||||
"displayNameHtml": "myrealm",
|
|
||||||
"internationalizationEnabled": true,
|
|
||||||
"registrationEmailAsUsername": true,
|
|
||||||
},
|
|
||||||
"locale": {
|
|
||||||
"supported": [
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=de",
|
|
||||||
"languageTag": "de"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=no",
|
|
||||||
"languageTag": "no"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=ru",
|
|
||||||
"languageTag": "ru"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=sv",
|
|
||||||
"languageTag": "sv"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=pt-BR",
|
|
||||||
"languageTag": "pt-BR"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=lt",
|
|
||||||
"languageTag": "lt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=en",
|
|
||||||
"languageTag": "en"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=it",
|
|
||||||
"languageTag": "it"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=fr",
|
|
||||||
"languageTag": "fr"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=zh-CN",
|
|
||||||
"languageTag": "zh-CN"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=es",
|
|
||||||
"languageTag": "es"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=cs",
|
|
||||||
"languageTag": "cs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=ja",
|
|
||||||
"languageTag": "ja"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=sk",
|
|
||||||
"languageTag": "sk"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=pl",
|
|
||||||
"languageTag": "pl"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=ca",
|
|
||||||
"languageTag": "ca"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=nl",
|
|
||||||
"languageTag": "nl"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=tr",
|
|
||||||
"languageTag": "tr"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"current": null as any
|
|
||||||
},
|
|
||||||
"auth": {
|
|
||||||
"showUsername": false,
|
|
||||||
"showResetCredentials": false,
|
|
||||||
"showTryAnotherWayLink": false
|
|
||||||
},
|
|
||||||
"scripts": [],
|
|
||||||
"message": {
|
|
||||||
"type": "success",
|
|
||||||
"summary": "This is a test message"
|
|
||||||
},
|
|
||||||
"isAppInitiatedAction": false,
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.defineProperty(
|
|
||||||
kcCommonContext.locale!,
|
|
||||||
"current",
|
|
||||||
{
|
|
||||||
"get": () => getKcLanguageTagLabel(getEvtKcLanguage().state),
|
|
||||||
"enumerable": true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const kcLoginContext: KcContext.Login = {
|
|
||||||
...kcCommonContext,
|
|
||||||
"pageId": "login.ftl",
|
|
||||||
"url": {
|
|
||||||
...kcCommonContext.url,
|
|
||||||
"loginResetCredentialsUrl": "/auth/realms/myrealm/login-actions/reset-credentials?client_id=account&tab_id=HoAx28ja4xg",
|
|
||||||
"registrationUrl": "/auth/realms/myrealm/login-actions/registration?client_id=account&tab_id=HoAx28ja4xg"
|
|
||||||
},
|
|
||||||
"realm": {
|
|
||||||
...kcCommonContext.realm,
|
|
||||||
"loginWithEmailAllowed": true,
|
|
||||||
"rememberMe": true,
|
|
||||||
"password": true,
|
|
||||||
"resetPasswordAllowed": true,
|
|
||||||
"registrationAllowed": true
|
|
||||||
},
|
|
||||||
"auth": kcCommonContext.auth!,
|
|
||||||
"social": {
|
|
||||||
"displayInfo": true
|
|
||||||
},
|
|
||||||
"usernameEditDisabled": false,
|
|
||||||
"login": {
|
|
||||||
"rememberMe": false
|
|
||||||
},
|
|
||||||
"registrationDisabled": false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const kcRegisterContext: KcContext.Register = {
|
|
||||||
...kcCommonContext,
|
|
||||||
"url": {
|
|
||||||
...kcLoginContext.url,
|
|
||||||
"registrationAction": "http://localhost:8080/auth/realms/myrealm/login-actions/registration?session_code=gwZdUeO7pbYpFTRxiIxRg_QtzMbtFTKrNu6XW_f8asM&execution=12146ce0-b139-4bbd-b25b-0eccfee6577e&client_id=account&tab_id=uS8lYfebLa0"
|
|
||||||
},
|
|
||||||
"messagesPerField": {
|
|
||||||
"printIfExists": (...[, x]) => x
|
|
||||||
},
|
|
||||||
"scripts": [],
|
|
||||||
"isAppInitiatedAction": false,
|
|
||||||
"pageId": "register.ftl",
|
|
||||||
"register": {
|
|
||||||
"formData": {}
|
|
||||||
},
|
|
||||||
"passwordRequired": true,
|
|
||||||
"recaptchaRequired": false,
|
|
||||||
"authorizedMailDomains": [
|
|
||||||
"example.com",
|
|
||||||
"another-example.com",
|
|
||||||
"*.yet-another-example.com",
|
|
||||||
"*.example.com",
|
|
||||||
"hello-world.com"
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
export const kcInfoContext: KcContext.Info = {
|
|
||||||
...kcCommonContext,
|
|
||||||
"pageId": "info.ftl",
|
|
||||||
"messageHeader": "<Message header>",
|
|
||||||
"requiredActions": undefined,
|
|
||||||
"skipLink": false,
|
|
||||||
"actionUri": "#",
|
|
||||||
"client": {
|
|
||||||
"baseUrl": "#"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const kcErrorContext: KcContext.Error = {
|
|
||||||
...kcCommonContext,
|
|
||||||
"pageId": "error.ftl",
|
|
||||||
"client": {
|
|
||||||
"baseUrl": "#"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const kcLoginResetPasswordContext: KcContext.LoginResetPassword = {
|
|
||||||
...kcCommonContext,
|
|
||||||
"pageId": "login-reset-password.ftl",
|
|
||||||
"realm": {
|
|
||||||
...kcCommonContext.realm,
|
|
||||||
"loginWithEmailAllowed": false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const kcLoginVerifyEmailContext: KcContext.LoginVerifyEmail = {
|
|
||||||
...kcCommonContext,
|
|
||||||
"pageId": "login-verify-email.ftl"
|
|
||||||
};
|
|
||||||
|
|
||||||
export const kcTermsContext: KcContext.Terms = {
|
|
||||||
...kcCommonContext,
|
|
||||||
"pageId": "terms.ftl"
|
|
||||||
};
|
|
||||||
|
|
252
src/lib/kcContextMocks/kcContextMocks.ts
Normal file
252
src/lib/kcContextMocks/kcContextMocks.ts
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
|
||||||
|
import type { KcContext } from "../KcContext";
|
||||||
|
import { getEvtKcLanguage } from "../i18n/useKcLanguageTag";
|
||||||
|
import { getKcLanguageTagLabel } from "../i18n/KcLanguageTag";
|
||||||
|
//NOTE: Aside because we want to be able to import them from node
|
||||||
|
import { resourcesCommonPath, resourcesPath } from "./urlResourcesPath";
|
||||||
|
|
||||||
|
const kcCommonContext: KcContext.Common = {
|
||||||
|
"url": {
|
||||||
|
"loginAction": "#",
|
||||||
|
"resourcesPath": `${process.env["PUBLIC_URL"]}/${resourcesPath}`,
|
||||||
|
"resourcesCommonPath": `${process.env["PUBLIC_URL"]}/${resourcesCommonPath}`,
|
||||||
|
"loginRestartFlowUrl": "/auth/realms/myrealm/login-actions/restart?client_id=account&tab_id=HoAx28ja4xg",
|
||||||
|
"loginUrl": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg",
|
||||||
|
},
|
||||||
|
"realm": {
|
||||||
|
"displayName": "myrealm",
|
||||||
|
"displayNameHtml": "myrealm",
|
||||||
|
"internationalizationEnabled": true,
|
||||||
|
"registrationEmailAsUsername": true,
|
||||||
|
},
|
||||||
|
"locale": {
|
||||||
|
"supported": [
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=de",
|
||||||
|
"languageTag": "de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=no",
|
||||||
|
"languageTag": "no"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=ru",
|
||||||
|
"languageTag": "ru"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=sv",
|
||||||
|
"languageTag": "sv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=pt-BR",
|
||||||
|
"languageTag": "pt-BR"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=lt",
|
||||||
|
"languageTag": "lt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=en",
|
||||||
|
"languageTag": "en"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=it",
|
||||||
|
"languageTag": "it"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=fr",
|
||||||
|
"languageTag": "fr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=zh-CN",
|
||||||
|
"languageTag": "zh-CN"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=es",
|
||||||
|
"languageTag": "es"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=cs",
|
||||||
|
"languageTag": "cs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=ja",
|
||||||
|
"languageTag": "ja"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=sk",
|
||||||
|
"languageTag": "sk"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=pl",
|
||||||
|
"languageTag": "pl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=ca",
|
||||||
|
"languageTag": "ca"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=nl",
|
||||||
|
"languageTag": "nl"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "/auth/realms/myrealm/login-actions/authenticate?client_id=account&tab_id=HoAx28ja4xg&execution=ee6c2834-46a4-4a20-a1b6-f6d6f6451b36&kc_locale=tr",
|
||||||
|
"languageTag": "tr"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"current": null as any
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"showUsername": false,
|
||||||
|
"showResetCredentials": false,
|
||||||
|
"showTryAnotherWayLink": false
|
||||||
|
},
|
||||||
|
"scripts": [],
|
||||||
|
"message": {
|
||||||
|
"type": "success",
|
||||||
|
"summary": "This is a test message"
|
||||||
|
},
|
||||||
|
"isAppInitiatedAction": false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(
|
||||||
|
kcCommonContext.locale!,
|
||||||
|
"current",
|
||||||
|
{
|
||||||
|
"get": () => getKcLanguageTagLabel(getEvtKcLanguage().state),
|
||||||
|
"enumerable": true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const kcLoginContext: KcContext.Login = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "login.ftl",
|
||||||
|
"url": {
|
||||||
|
...kcCommonContext.url,
|
||||||
|
"loginResetCredentialsUrl": "/auth/realms/myrealm/login-actions/reset-credentials?client_id=account&tab_id=HoAx28ja4xg",
|
||||||
|
"registrationUrl": "/auth/realms/myrealm/login-actions/registration?client_id=account&tab_id=HoAx28ja4xg"
|
||||||
|
},
|
||||||
|
"realm": {
|
||||||
|
...kcCommonContext.realm,
|
||||||
|
"loginWithEmailAllowed": true,
|
||||||
|
"rememberMe": true,
|
||||||
|
"password": true,
|
||||||
|
"resetPasswordAllowed": true,
|
||||||
|
"registrationAllowed": true
|
||||||
|
},
|
||||||
|
"auth": kcCommonContext.auth!,
|
||||||
|
"social": {
|
||||||
|
"displayInfo": true
|
||||||
|
},
|
||||||
|
"usernameEditDisabled": false,
|
||||||
|
"login": {
|
||||||
|
"rememberMe": false
|
||||||
|
},
|
||||||
|
"registrationDisabled": false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcRegisterContext: KcContext.Register = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"url": {
|
||||||
|
...kcLoginContext.url,
|
||||||
|
"registrationAction": "http://localhost:8080/auth/realms/myrealm/login-actions/registration?session_code=gwZdUeO7pbYpFTRxiIxRg_QtzMbtFTKrNu6XW_f8asM&execution=12146ce0-b139-4bbd-b25b-0eccfee6577e&client_id=account&tab_id=uS8lYfebLa0"
|
||||||
|
},
|
||||||
|
"messagesPerField": {
|
||||||
|
"printIfExists": (...[, x]) => x
|
||||||
|
},
|
||||||
|
"scripts": [],
|
||||||
|
"isAppInitiatedAction": false,
|
||||||
|
"pageId": "register.ftl",
|
||||||
|
"register": {
|
||||||
|
"formData": {}
|
||||||
|
},
|
||||||
|
"passwordRequired": true,
|
||||||
|
"recaptchaRequired": false,
|
||||||
|
"authorizedMailDomains": [
|
||||||
|
"example.com",
|
||||||
|
"another-example.com",
|
||||||
|
"*.yet-another-example.com",
|
||||||
|
"*.example.com",
|
||||||
|
"hello-world.com"
|
||||||
|
],
|
||||||
|
"social": {
|
||||||
|
"displayInfo": true
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcInfoContext: KcContext.Info = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "info.ftl",
|
||||||
|
"messageHeader": "<Message header>",
|
||||||
|
"requiredActions": undefined,
|
||||||
|
"skipLink": false,
|
||||||
|
"actionUri": "#",
|
||||||
|
"client": {
|
||||||
|
"baseUrl": "#"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcErrorContext: KcContext.Error = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "error.ftl",
|
||||||
|
"client": {
|
||||||
|
"baseUrl": "#"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcLoginResetPasswordContext: KcContext.LoginResetPassword = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "login-reset-password.ftl",
|
||||||
|
"realm": {
|
||||||
|
...kcCommonContext.realm,
|
||||||
|
"loginWithEmailAllowed": false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcLoginVerifyEmailContext: KcContext.LoginVerifyEmail = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "login-verify-email.ftl"
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcTermsContext: KcContext.Terms = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "terms.ftl"
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcLoginOtpContext: KcContext.LoginOtp = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "login-otp.ftl",
|
||||||
|
"otpLogin": {
|
||||||
|
"userOtpCredentials": [
|
||||||
|
{
|
||||||
|
"id": "id1",
|
||||||
|
"userLabel": "label1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "id2",
|
||||||
|
"userLabel": "label2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcLoginUpdateProfileContext: KcContext.LoginUpdateProfile = {
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "login-update-profile.ftl",
|
||||||
|
"user": {
|
||||||
|
"editUsernameAllowed": true,
|
||||||
|
"username": "anUsername",
|
||||||
|
"email": "foo@example.com",
|
||||||
|
"firstName": "aFirstName",
|
||||||
|
"lastName": "aLastName"
|
||||||
|
},
|
||||||
|
"messagesPerField": {
|
||||||
|
"printIfExists": () => undefined
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcLoginIdpLinkConfirmContext: KcContext.LoginIdpLinkConfirm ={
|
||||||
|
...kcCommonContext,
|
||||||
|
"pageId": "login-idp-link-confirm.ftl",
|
||||||
|
"idpAlias": "FranceConnect"
|
||||||
|
};
|
@ -62,7 +62,7 @@ export function createKeycloakAdapter(
|
|||||||
"success": { "value": () => { } },
|
"success": { "value": () => { } },
|
||||||
"error": { "value": () => { } }
|
"error": { "value": () => { } }
|
||||||
}
|
}
|
||||||
);
|
) as any;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"login": options => {
|
"login": options => {
|
||||||
|
358
yarn.lock
358
yarn.lock
@ -3,72 +3,71 @@
|
|||||||
|
|
||||||
|
|
||||||
"@babel/code-frame@^7.0.0":
|
"@babel/code-frame@^7.0.0":
|
||||||
version "7.12.13"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
|
||||||
integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
|
integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/highlight" "^7.12.13"
|
"@babel/highlight" "^7.14.5"
|
||||||
|
|
||||||
"@babel/helper-module-imports@^7.7.0":
|
"@babel/helper-module-imports@^7.12.13":
|
||||||
version "7.12.13"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0"
|
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3"
|
||||||
integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==
|
integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/types" "^7.12.13"
|
"@babel/types" "^7.14.5"
|
||||||
|
|
||||||
"@babel/helper-plugin-utils@^7.12.13":
|
"@babel/helper-plugin-utils@^7.14.5":
|
||||||
version "7.13.0"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af"
|
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
|
||||||
integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==
|
integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
|
||||||
|
|
||||||
"@babel/helper-validator-identifier@^7.12.11":
|
"@babel/helper-validator-identifier@^7.14.5":
|
||||||
version "7.12.11"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8"
|
||||||
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
|
integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==
|
||||||
|
|
||||||
"@babel/highlight@^7.12.13":
|
"@babel/highlight@^7.14.5":
|
||||||
version "7.13.10"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1"
|
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9"
|
||||||
integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==
|
integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-validator-identifier" "^7.12.11"
|
"@babel/helper-validator-identifier" "^7.14.5"
|
||||||
chalk "^2.0.0"
|
chalk "^2.0.0"
|
||||||
js-tokens "^4.0.0"
|
js-tokens "^4.0.0"
|
||||||
|
|
||||||
"@babel/plugin-syntax-jsx@^7.12.1":
|
"@babel/plugin-syntax-jsx@^7.12.13":
|
||||||
version "7.12.13"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz#044fb81ebad6698fe62c478875575bcbb9b70f15"
|
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201"
|
||||||
integrity sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g==
|
integrity sha512-ohuFIsOMXJnbOMRfX7/w7LocdR6R7whhuRD4ax8IipLcLPlZGJKkBxgHp++U4N/vKyU16/YDQr2f5seajD3jIw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-plugin-utils" "^7.12.13"
|
"@babel/helper-plugin-utils" "^7.14.5"
|
||||||
|
|
||||||
"@babel/runtime@^7.7.2":
|
"@babel/runtime@^7.13.10", "@babel/runtime@^7.7.2":
|
||||||
version "7.13.10"
|
version "7.14.6"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d"
|
||||||
integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
|
integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==
|
||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.13.4"
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@babel/types@^7.12.13":
|
"@babel/types@^7.14.5":
|
||||||
version "7.13.0"
|
version "7.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80"
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff"
|
||||||
integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==
|
integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-validator-identifier" "^7.12.11"
|
"@babel/helper-validator-identifier" "^7.14.5"
|
||||||
lodash "^4.17.19"
|
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@emotion/babel-plugin@^11.0.0":
|
"@emotion/babel-plugin@^11.0.0":
|
||||||
version "11.2.0"
|
version "11.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.2.0.tgz#f25c6df8ec045dad5ae6ca63df0791673b98c920"
|
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.3.0.tgz#3a16850ba04d8d9651f07f3fb674b3436a4fb9d7"
|
||||||
integrity sha512-lsnQBnl3l4wu/FJoyHnYRpHJeIPNkOBMbtDUIXcO8luulwRKZXPvA10zd2eXVN6dABIWNX4E34en/jkejIg/yA==
|
integrity sha512-UZKwBV2rADuhRp+ZOGgNWg2eYgbzKzQXfQPtJbu/PLy8onurxlNCLvxMQEvlr1/GudguPI5IU9qIY1+2z1M5bA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-module-imports" "^7.7.0"
|
"@babel/helper-module-imports" "^7.12.13"
|
||||||
"@babel/plugin-syntax-jsx" "^7.12.1"
|
"@babel/plugin-syntax-jsx" "^7.12.13"
|
||||||
"@babel/runtime" "^7.7.2"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@emotion/hash" "^0.8.0"
|
"@emotion/hash" "^0.8.0"
|
||||||
"@emotion/memoize" "^0.7.5"
|
"@emotion/memoize" "^0.7.5"
|
||||||
"@emotion/serialize" "^1.0.0"
|
"@emotion/serialize" "^1.0.2"
|
||||||
babel-plugin-macros "^2.6.1"
|
babel-plugin-macros "^2.6.1"
|
||||||
convert-source-map "^1.5.0"
|
convert-source-map "^1.5.0"
|
||||||
escape-string-regexp "^4.0.0"
|
escape-string-regexp "^4.0.0"
|
||||||
@ -77,9 +76,9 @@
|
|||||||
stylis "^4.0.3"
|
stylis "^4.0.3"
|
||||||
|
|
||||||
"@emotion/cache@^11.1.3":
|
"@emotion/cache@^11.1.3":
|
||||||
version "11.1.3"
|
version "11.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.1.3.tgz#c7683a9484bcd38d5562f2b9947873cf66829afd"
|
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.4.0.tgz#293fc9d9a7a38b9aad8e9337e5014366c3b09ac0"
|
||||||
integrity sha512-n4OWinUPJVaP6fXxWZD9OUeQ0lY7DvtmtSuqtRWT0Ofo/sBLCVSgb4/Oa0Q5eFxcwablRKjUXqXtNZVyEwCAuA==
|
integrity sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@emotion/memoize" "^0.7.4"
|
"@emotion/memoize" "^0.7.4"
|
||||||
"@emotion/sheet" "^1.0.0"
|
"@emotion/sheet" "^1.0.0"
|
||||||
@ -108,10 +107,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
|
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
|
||||||
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
|
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
|
||||||
|
|
||||||
"@emotion/serialize@^1.0.0":
|
"@emotion/serialize@^1.0.0", "@emotion/serialize@^1.0.2":
|
||||||
version "1.0.1"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.1.tgz#322cdebfdbb5a88946f17006548191859b9b0855"
|
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.2.tgz#77cb21a0571c9f68eb66087754a65fa97bfcd965"
|
||||||
integrity sha512-TXlKs5sgUKhFlszp/rg4lIAZd7UUSmJpwaf9/lAEFcUh2vPi32i7x4wk7O8TN8L8v2Ol8k0CxnhRBY0zQalTxA==
|
integrity sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@emotion/hash" "^0.8.0"
|
"@emotion/hash" "^0.8.0"
|
||||||
"@emotion/memoize" "^0.7.4"
|
"@emotion/memoize" "^0.7.4"
|
||||||
@ -147,9 +146,9 @@
|
|||||||
"@types/unist" "*"
|
"@types/unist" "*"
|
||||||
|
|
||||||
"@types/node@^10.0.0":
|
"@types/node@^10.0.0":
|
||||||
version "10.17.55"
|
version "10.17.60"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.55.tgz#a147f282edec679b894d4694edb5abeb595fecbd"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
|
||||||
integrity sha512-koZJ89uLZufDvToeWO5BrC4CR4OUfHnUz2qoPs/daQH6qq3IN62QFxCTZ+bKaCE0xaoCAJYE4AXre8AbghCrhg==
|
integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==
|
||||||
|
|
||||||
"@types/parse-json@^4.0.0":
|
"@types/parse-json@^4.0.0":
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
@ -162,9 +161,9 @@
|
|||||||
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
||||||
|
|
||||||
"@types/react@^17.0.0":
|
"@types/react@^17.0.0":
|
||||||
version "17.0.3"
|
version "17.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451"
|
||||||
integrity sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==
|
integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/prop-types" "*"
|
"@types/prop-types" "*"
|
||||||
"@types/scheduler" "*"
|
"@types/scheduler" "*"
|
||||||
@ -180,11 +179,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
|
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
|
||||||
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
|
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
|
||||||
|
|
||||||
abbrev@1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
|
||||||
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
|
|
||||||
|
|
||||||
ansi-regex@^5.0.0:
|
ansi-regex@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||||
@ -219,9 +213,9 @@ bail@^1.0.0:
|
|||||||
integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==
|
integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
boolbase@^1.0.0:
|
boolbase@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
@ -265,29 +259,29 @@ character-reference-invalid@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
|
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
|
||||||
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
|
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
|
||||||
|
|
||||||
cheerio-select-tmp@^0.1.0:
|
cheerio-select@^1.5.0:
|
||||||
version "0.1.1"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646"
|
resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.5.0.tgz#faf3daeb31b17c5e1a9dabcee288aaf8aafa5823"
|
||||||
integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==
|
integrity sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==
|
||||||
dependencies:
|
dependencies:
|
||||||
css-select "^3.1.2"
|
css-select "^4.1.3"
|
||||||
css-what "^4.0.0"
|
css-what "^5.0.1"
|
||||||
domelementtype "^2.1.0"
|
domelementtype "^2.2.0"
|
||||||
domhandler "^4.0.0"
|
domhandler "^4.2.0"
|
||||||
domutils "^2.4.4"
|
domutils "^2.7.0"
|
||||||
|
|
||||||
cheerio@^1.0.0-rc.5:
|
cheerio@^1.0.0-rc.5:
|
||||||
version "1.0.0-rc.5"
|
version "1.0.0-rc.10"
|
||||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f"
|
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e"
|
||||||
integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==
|
integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==
|
||||||
dependencies:
|
dependencies:
|
||||||
cheerio-select-tmp "^0.1.0"
|
cheerio-select "^1.5.0"
|
||||||
dom-serializer "~1.2.0"
|
dom-serializer "^1.3.2"
|
||||||
domhandler "^4.0.0"
|
domhandler "^4.2.0"
|
||||||
entities "~2.1.0"
|
htmlparser2 "^6.1.0"
|
||||||
htmlparser2 "^6.0.0"
|
parse5 "^6.0.1"
|
||||||
parse5 "^6.0.0"
|
parse5-htmlparser2-tree-adapter "^6.0.1"
|
||||||
parse5-htmlparser2-tree-adapter "^6.0.0"
|
tslib "^2.2.0"
|
||||||
|
|
||||||
cliui@^7.0.2:
|
cliui@^7.0.2:
|
||||||
version "7.0.4"
|
version "7.0.4"
|
||||||
@ -328,9 +322,9 @@ concat-map@0.0.1:
|
|||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
convert-source-map@^1.5.0:
|
convert-source-map@^1.5.0:
|
||||||
version "1.7.0"
|
version "1.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
|
||||||
integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
|
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.1"
|
safe-buffer "~5.1.1"
|
||||||
|
|
||||||
@ -363,26 +357,26 @@ cosmiconfig@^6.0.0:
|
|||||||
path-type "^4.0.0"
|
path-type "^4.0.0"
|
||||||
yaml "^1.7.2"
|
yaml "^1.7.2"
|
||||||
|
|
||||||
css-select@^3.1.2:
|
css-select@^4.1.3:
|
||||||
version "3.1.2"
|
version "4.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8"
|
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067"
|
||||||
integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==
|
integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==
|
||||||
dependencies:
|
dependencies:
|
||||||
boolbase "^1.0.0"
|
boolbase "^1.0.0"
|
||||||
css-what "^4.0.0"
|
css-what "^5.0.0"
|
||||||
domhandler "^4.0.0"
|
domhandler "^4.2.0"
|
||||||
domutils "^2.4.3"
|
domutils "^2.6.0"
|
||||||
nth-check "^2.0.0"
|
nth-check "^2.0.0"
|
||||||
|
|
||||||
css-what@^4.0.0:
|
css-what@^5.0.0, css-what@^5.0.1:
|
||||||
version "4.0.0"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233"
|
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad"
|
||||||
integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==
|
integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==
|
||||||
|
|
||||||
csstype@^3.0.2:
|
csstype@^3.0.2:
|
||||||
version "3.0.7"
|
version "3.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b"
|
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
|
||||||
integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==
|
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
|
||||||
|
|
||||||
d@1, d@^1.0.1:
|
d@1, d@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
@ -399,21 +393,16 @@ debug@^4.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "2.1.2"
|
ms "2.1.2"
|
||||||
|
|
||||||
dom-serializer@^1.0.1, dom-serializer@~1.2.0:
|
dom-serializer@^1.0.1, dom-serializer@^1.3.2:
|
||||||
version "1.2.0"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1"
|
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
|
||||||
integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==
|
integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "^2.0.1"
|
domelementtype "^2.0.1"
|
||||||
domhandler "^4.0.0"
|
domhandler "^4.2.0"
|
||||||
entities "^2.0.0"
|
entities "^2.0.0"
|
||||||
|
|
||||||
domelementtype@^2.0.1, domelementtype@^2.1.0:
|
domelementtype@^2.0.1, domelementtype@^2.2.0:
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e"
|
|
||||||
integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==
|
|
||||||
|
|
||||||
domelementtype@^2.2.0:
|
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
|
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
|
||||||
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
|
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
|
||||||
@ -425,37 +414,21 @@ domhandler@^3.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "^2.0.1"
|
domelementtype "^2.0.1"
|
||||||
|
|
||||||
domhandler@^4.0.0:
|
domhandler@^4.0.0, domhandler@^4.2.0:
|
||||||
version "4.0.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e"
|
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059"
|
||||||
integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==
|
integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==
|
||||||
dependencies:
|
|
||||||
domelementtype "^2.1.0"
|
|
||||||
|
|
||||||
domhandler@^4.1.0:
|
|
||||||
version "4.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43"
|
|
||||||
integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "^2.2.0"
|
domelementtype "^2.2.0"
|
||||||
|
|
||||||
domutils@^2.4.2:
|
domutils@^2.4.2, domutils@^2.5.2, domutils@^2.6.0, domutils@^2.7.0:
|
||||||
version "2.5.2"
|
version "2.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.2.tgz#37ef8ba087dff1a17175e7092e8a042e4b050e6c"
|
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442"
|
||||||
integrity sha512-MHTthCb1zj8f1GVfRpeZUbohQf/HdBos0oX5gZcQFepOZPLLRyj6Wn7XS7EMnY7CVpwv8863u2vyE83Hfu28HQ==
|
integrity sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg==
|
||||||
dependencies:
|
dependencies:
|
||||||
dom-serializer "^1.0.1"
|
dom-serializer "^1.0.1"
|
||||||
domelementtype "^2.2.0"
|
domelementtype "^2.2.0"
|
||||||
domhandler "^4.1.0"
|
domhandler "^4.2.0"
|
||||||
|
|
||||||
domutils@^2.4.3, domutils@^2.4.4:
|
|
||||||
version "2.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.0.tgz#42f49cffdabb92ad243278b331fd761c1c2d3039"
|
|
||||||
integrity sha512-Ho16rzNMOFk2fPwChGh3D2D9OEHAfG19HgmRR2l+WLSsIstNsAYBzePH412bL0y5T44ejABIVfTHQ8nqi/tBCg==
|
|
||||||
dependencies:
|
|
||||||
dom-serializer "^1.0.1"
|
|
||||||
domelementtype "^2.0.1"
|
|
||||||
domhandler "^4.0.0"
|
|
||||||
|
|
||||||
emoji-regex@^8.0.0:
|
emoji-regex@^8.0.0:
|
||||||
version "8.0.0"
|
version "8.0.0"
|
||||||
@ -467,11 +440,6 @@ entities@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||||
|
|
||||||
entities@~2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
|
|
||||||
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
|
|
||||||
|
|
||||||
error-ex@^1.3.1:
|
error-ex@^1.3.1:
|
||||||
version "1.3.2"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||||
@ -579,9 +547,9 @@ get-caller-file@^2.0.5:
|
|||||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||||
|
|
||||||
glob@^7.0.5, glob@^7.1.3:
|
glob@^7.0.5, glob@^7.1.3:
|
||||||
version "7.1.6"
|
version "7.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
|
||||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
fs.realpath "^1.0.0"
|
fs.realpath "^1.0.0"
|
||||||
inflight "^1.0.4"
|
inflight "^1.0.4"
|
||||||
@ -622,14 +590,14 @@ htmlparser2@^5.0:
|
|||||||
domutils "^2.4.2"
|
domutils "^2.4.2"
|
||||||
entities "^2.0.0"
|
entities "^2.0.0"
|
||||||
|
|
||||||
htmlparser2@^6.0.0:
|
htmlparser2@^6.1.0:
|
||||||
version "6.0.1"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.1.tgz#422521231ef6d42e56bd411da8ba40aa36e91446"
|
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
|
||||||
integrity sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w==
|
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "^2.0.1"
|
domelementtype "^2.0.1"
|
||||||
domhandler "^4.0.0"
|
domhandler "^4.0.0"
|
||||||
domutils "^2.4.4"
|
domutils "^2.5.2"
|
||||||
entities "^2.0.0"
|
entities "^2.0.0"
|
||||||
|
|
||||||
import-fresh@^3.1.0:
|
import-fresh@^3.1.0:
|
||||||
@ -682,9 +650,9 @@ is-buffer@^2.0.0:
|
|||||||
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
|
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
|
||||||
|
|
||||||
is-core-module@^2.2.0:
|
is-core-module@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
|
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
|
||||||
integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
|
integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
|
||||||
dependencies:
|
dependencies:
|
||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
|
|
||||||
@ -743,11 +711,6 @@ lodash.camelcase@^4.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||||
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
|
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
|
||||||
|
|
||||||
lodash@^4.17.19:
|
|
||||||
version "4.17.21"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
|
||||||
|
|
||||||
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||||
@ -762,13 +725,6 @@ lru-queue@^0.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
es5-ext "~0.10.2"
|
es5-ext "~0.10.2"
|
||||||
|
|
||||||
markdown@^0.5.0:
|
|
||||||
version "0.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/markdown/-/markdown-0.5.0.tgz#28205b565a8ae7592de207463d6637dc182722b2"
|
|
||||||
integrity sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=
|
|
||||||
dependencies:
|
|
||||||
nopt "~2.1.1"
|
|
||||||
|
|
||||||
mdast-add-list-metadata@1.0.1:
|
mdast-add-list-metadata@1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz#95e73640ce2fc1fa2dcb7ec443d09e2bfe7db4cf"
|
resolved "https://registry.yarnpkg.com/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz#95e73640ce2fc1fa2dcb7ec443d09e2bfe7db4cf"
|
||||||
@ -815,9 +771,9 @@ micromark@~2.11.0:
|
|||||||
parse-entities "^2.0.0"
|
parse-entities "^2.0.0"
|
||||||
|
|
||||||
minimal-polyfills@^2.1.5, minimal-polyfills@^2.1.6:
|
minimal-polyfills@^2.1.5, minimal-polyfills@^2.1.6:
|
||||||
version "2.1.6"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/minimal-polyfills/-/minimal-polyfills-2.1.6.tgz#eab50832add31afd40a22b38fb76d1fdcd2a51e4"
|
resolved "https://registry.yarnpkg.com/minimal-polyfills/-/minimal-polyfills-2.2.1.tgz#7249d7ece666d3b4e1ec1c1b8f949eb9d44e2308"
|
||||||
integrity sha512-vqoxj7eMzsqX0M6/dkgoNFPw6Mztgn5qjSl0bWGboQeU7Y4UPLeyoqQw6JI+0qmBcJYdkr3nK7dqY8u/fgRp5g==
|
integrity sha512-WLmHQrsZob4rVYf8yHapZPNJZ3sspGa/sN8abuSD59b0FifDEE7HMfLUi24z7mPZqTpBXy4Svp+iGvAmclCmXg==
|
||||||
|
|
||||||
minimatch@^3.0.3, minimatch@^3.0.4:
|
minimatch@^3.0.3, minimatch@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
@ -854,13 +810,6 @@ noms@0.0.0:
|
|||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
readable-stream "~1.0.31"
|
readable-stream "~1.0.31"
|
||||||
|
|
||||||
nopt@~2.1.1:
|
|
||||||
version "2.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-2.1.2.tgz#6cccd977b80132a07731d6e8ce58c2c8303cf9af"
|
|
||||||
integrity sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=
|
|
||||||
dependencies:
|
|
||||||
abbrev "1"
|
|
||||||
|
|
||||||
nth-check@^2.0.0:
|
nth-check@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125"
|
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125"
|
||||||
@ -909,14 +858,14 @@ parse-json@^5.0.0:
|
|||||||
json-parse-even-better-errors "^2.3.0"
|
json-parse-even-better-errors "^2.3.0"
|
||||||
lines-and-columns "^1.1.6"
|
lines-and-columns "^1.1.6"
|
||||||
|
|
||||||
parse5-htmlparser2-tree-adapter@^6.0.0:
|
parse5-htmlparser2-tree-adapter@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
||||||
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
|
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
|
||||||
dependencies:
|
dependencies:
|
||||||
parse5 "^6.0.1"
|
parse5 "^6.0.1"
|
||||||
|
|
||||||
parse5@^6.0.0, parse5@^6.0.1:
|
parse5@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||||
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
||||||
@ -927,9 +876,9 @@ path-is-absolute@^1.0.0:
|
|||||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
path-parse@^1.0.6:
|
path-parse@^1.0.6:
|
||||||
version "1.0.6"
|
version "1.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||||
|
|
||||||
path-type@^4.0.0:
|
path-type@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
@ -944,14 +893,15 @@ path@^0.12.7:
|
|||||||
process "^0.11.1"
|
process "^0.11.1"
|
||||||
util "^0.10.3"
|
util "^0.10.3"
|
||||||
|
|
||||||
powerhooks@^0.0.36:
|
powerhooks@^0.1.0:
|
||||||
version "0.0.36"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.0.36.tgz#d973d339ad8ca7ce52ea9d288ebe8e138df7d769"
|
resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.1.4.tgz#82aae8dae5485a154d3ce4e89342a2d68cb2a413"
|
||||||
integrity sha512-0fEGKLfJmuFeEYDGsAlTuvGKKdqOH059xezosmYRoGurfC1bbUlaNJD+TuzOT5cTGURi88DCLcDnhk/2eLyCyA==
|
integrity sha512-ig47hJIW/b75gCS3l2EtK8NVAduNVd9vem8IvaWkuPuZIP4mbDAy4Rc0/hvjXVUPs9OzK7jc/zIQika3tTacYg==
|
||||||
dependencies:
|
dependencies:
|
||||||
evt "2.0.0-beta.15"
|
evt "2.0.0-beta.15"
|
||||||
memoizee "^0.4.15"
|
memoizee "^0.4.15"
|
||||||
resize-observer-polyfill "^1.5.1"
|
resize-observer-polyfill "^1.5.1"
|
||||||
|
tsafe "^0.1.0"
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
@ -1006,9 +956,9 @@ react-markdown@^5.0.3:
|
|||||||
xtend "^4.0.1"
|
xtend "^4.0.1"
|
||||||
|
|
||||||
react@^17.0.1:
|
react@^17.0.1:
|
||||||
version "17.0.1"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
|
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||||
integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==
|
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
@ -1134,9 +1084,9 @@ strip-ansi@^6.0.0:
|
|||||||
ansi-regex "^5.0.0"
|
ansi-regex "^5.0.0"
|
||||||
|
|
||||||
stylis@^4.0.3:
|
stylis@^4.0.3:
|
||||||
version "4.0.7"
|
version "4.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.7.tgz#412a90c28079417f3d27c028035095e4232d2904"
|
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
|
||||||
integrity sha512-OFFeUXFgwnGOKvEXaSv0D0KQ5ADP0n6g3SVONx6I/85JzNZ3u50FRwB3lVIk1QO2HNdI75tbVzc4Z66Gdp9voA==
|
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
|
||||||
|
|
||||||
supports-color@^5.3.0:
|
supports-color@^5.3.0:
|
||||||
version "5.5.0"
|
version "5.5.0"
|
||||||
@ -1171,6 +1121,16 @@ trough@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
|
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
|
||||||
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
|
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
|
||||||
|
|
||||||
|
tsafe@^0.1.0:
|
||||||
|
version "0.1.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-0.1.15.tgz#9e2b6137fb5a49fc7c23cb0bc49ae09bab215f2a"
|
||||||
|
integrity sha512-aAWMOACHXMmwE2zRcQpBv+whxYqB4zvAbs+dzwbnGaGK9NAOQ65m0+WyO+jw/41JzCX7orJU/ieFHTmgehTOKA==
|
||||||
|
|
||||||
|
tslib@^2.2.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
||||||
|
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
||||||
|
|
||||||
tss-react@^0.0.12:
|
tss-react@^0.0.12:
|
||||||
version "0.0.12"
|
version "0.0.12"
|
||||||
resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-0.0.12.tgz#6463617ae5e7f670742e48e497d8825d59e2a2e9"
|
resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-0.0.12.tgz#6463617ae5e7f670742e48e497d8825d59e2a2e9"
|
||||||
@ -1189,9 +1149,9 @@ type@^2.0.0:
|
|||||||
integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==
|
integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==
|
||||||
|
|
||||||
typescript@^4.2.3:
|
typescript@^4.2.3:
|
||||||
version "4.2.3"
|
version "4.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
|
||||||
integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==
|
integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
|
||||||
|
|
||||||
unified@^9.0.0:
|
unified@^9.0.0:
|
||||||
version "9.2.1"
|
version "9.2.1"
|
||||||
@ -1294,9 +1254,9 @@ xtend@^4.0.1, xtend@~4.0.1:
|
|||||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||||
|
|
||||||
y18n@^5.0.5:
|
y18n@^5.0.5:
|
||||||
version "5.0.5"
|
version "5.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||||
integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
|
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
|
||||||
|
|
||||||
yaml@^1.7.2:
|
yaml@^1.7.2:
|
||||||
version "1.10.2"
|
version "1.10.2"
|
||||||
@ -1304,9 +1264,9 @@ yaml@^1.7.2:
|
|||||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||||
|
|
||||||
yargs-parser@^20.2.2:
|
yargs-parser@^20.2.2:
|
||||||
version "20.2.7"
|
version "20.2.9"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||||
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
|
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||||
|
|
||||||
yargs@^16.1.0:
|
yargs@^16.1.0:
|
||||||
version "16.2.0"
|
version "16.2.0"
|
||||||
|
Reference in New Issue
Block a user