Implement register
This commit is contained in:
parent
09c7b6ac03
commit
2ee12abc43
@ -54,7 +54,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scripting-tools": "^0.19.13",
|
"scripting-tools": "^0.19.13",
|
||||||
"cheerio": "^1.0.0-rc.5",
|
"cheerio": "^1.0.0-rc.5",
|
||||||
"evt": "^1.9.12",
|
"evt": "2.0.0-beta.15",
|
||||||
"minimal-polyfills": "^2.1.6",
|
"minimal-polyfills": "^2.1.6",
|
||||||
"powerhooks": "^0.0.14",
|
"powerhooks": "^0.0.14",
|
||||||
"tss-react": "^0.0.9"
|
"tss-react": "^0.0.9"
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
"resourcesCommonPath": "${url.resourcesCommonPath}",
|
"resourcesCommonPath": "${url.resourcesCommonPath}",
|
||||||
"loginRestartFlowUrl": "${url.loginRestartFlowUrl}",
|
"loginRestartFlowUrl": "${url.loginRestartFlowUrl}",
|
||||||
"loginResetCredentialsUrl": "${url.loginResetCredentialsUrl}",
|
"loginResetCredentialsUrl": "${url.loginResetCredentialsUrl}",
|
||||||
"registrationUrl": "${url.registrationUrl}"
|
"registrationUrl": "${url.registrationUrl}",
|
||||||
|
"registrationAction": "${url.registrationUrl}",
|
||||||
|
"loginUrl": "${url.loginUrl}"
|
||||||
},
|
},
|
||||||
"realm": {
|
"realm": {
|
||||||
"displayName": "${realm.displayName!''}" || undefined,
|
"displayName": "${realm.displayName!''}" || undefined,
|
||||||
@ -168,6 +170,45 @@
|
|||||||
</#if>
|
</#if>
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
})
|
}),
|
||||||
|
"messagesPerField": {
|
||||||
|
"printIfExists": function (key, x) {
|
||||||
|
switch(key){
|
||||||
|
case "userLabel": "${messagesPerField.printIfExists('userLabel','1'}" ? x : undefined;
|
||||||
|
case "username": "${messagesPerField.printIfExists('username','1'}" ? x : undefined;
|
||||||
|
case "email": "${messagesPerField.printIfExists('email','1'}" ? x : undefined;
|
||||||
|
case "firstName": "${messagesPerField.printIfExists('firstName','1'}" ? x : undefined;
|
||||||
|
case "lastName": "${messagesPerField.printIfExists('lastName','1'}" ? x : undefined;
|
||||||
|
case "password": "${messagesPerField.printIfExists('password','1'}" ? x : undefined;
|
||||||
|
case "password-confirm": "${messagesPerField.printIfExists('password-confirm','1'}" ? x : undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"register": {
|
||||||
|
"formData": {
|
||||||
|
"firstName": "${register.formData.firstName!''}" || undefined,
|
||||||
|
"displayName": "${register.formData.displayName!''}" || undefined,
|
||||||
|
"lastName": "${register.formData.lastName!''}" || undefined,
|
||||||
|
"email": "${register.formData.email!''}" || undefined,
|
||||||
|
"username": "${register.formData.username!''}" || undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passwordRequired": (function (){
|
||||||
|
|
||||||
|
<#if passwordRequired??>
|
||||||
|
return true;
|
||||||
|
</#if>
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}),
|
||||||
|
"recaptchaRequired": (function (){
|
||||||
|
|
||||||
|
<#if passwordRequired??>
|
||||||
|
return true;
|
||||||
|
</#if>
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}),
|
||||||
|
"recaptchaSiteKey": "${recaptchaSiteKey}"
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
@ -4,6 +4,7 @@ import { kcContext } from "../kcContext";
|
|||||||
import { assert } from "evt/tools/typeSafety/assert";
|
import { assert } from "evt/tools/typeSafety/assert";
|
||||||
import type { KcPagesProperties } from "./KcProperties";
|
import type { KcPagesProperties } from "./KcProperties";
|
||||||
import { Login } from "./Login";
|
import { Login } from "./Login";
|
||||||
|
import { Register } from "./Register";
|
||||||
|
|
||||||
export type KcAppProps = {
|
export type KcAppProps = {
|
||||||
kcProperties?: KcPagesProperties;
|
kcProperties?: KcPagesProperties;
|
||||||
@ -16,10 +17,8 @@ export const KcApp = memo((props: KcAppProps) => {
|
|||||||
assert(kcContext !== undefined, "App is not currently served by a Keycloak server");
|
assert(kcContext !== undefined, "App is not currently served by a Keycloak server");
|
||||||
|
|
||||||
switch (kcContext.pageBasename) {
|
switch (kcContext.pageBasename) {
|
||||||
case "login.ftl": return <Login kcProperties={kcProperties} />
|
case "login.ftl": return <Login kcProperties={kcProperties} />;
|
||||||
case "register.ftl":
|
case "register.ftl": return <Register kcProperties={kcProperties} />;
|
||||||
alert(`TODO: Implement ${kcContext.pageBasename}`);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
@ -46,7 +46,6 @@ export const Login = memo((props: LoginProps) => {
|
|||||||
displayWide={realm.password && social.providers !== undefined}
|
displayWide={realm.password && social.providers !== undefined}
|
||||||
kcProperties={kcProperties}
|
kcProperties={kcProperties}
|
||||||
headerNode={t("doLogIn")}
|
headerNode={t("doLogIn")}
|
||||||
showUsernameNode={null}
|
|
||||||
formNode={
|
formNode={
|
||||||
<div
|
<div
|
||||||
id="kc-form"
|
id="kc-form"
|
||||||
|
148
src/lib/components/Register.tsx
Normal file
148
src/lib/components/Register.tsx
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import { useState, memo } from "react";
|
||||||
|
import { Template } from "./Template";
|
||||||
|
import type { KcPagesProperties } from "./KcProperties";
|
||||||
|
import { defaultKcPagesProperties } from "./KcProperties";
|
||||||
|
import { assert } from "evt/tools/typeSafety/assert";
|
||||||
|
import { kcContext } from "../kcContext";
|
||||||
|
import { useKcTranslation } from "../i18n/useKcTranslation";
|
||||||
|
import { cx } from "tss-react";
|
||||||
|
|
||||||
|
export type RegisterPageProps = {
|
||||||
|
kcProperties?: KcPagesProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Register = memo((props: RegisterPageProps) => {
|
||||||
|
|
||||||
|
const { kcProperties = {} } = props;
|
||||||
|
|
||||||
|
const { t, tStr } = useKcTranslation();
|
||||||
|
|
||||||
|
Object.assign(kcProperties, defaultKcPagesProperties);
|
||||||
|
|
||||||
|
const [{
|
||||||
|
url,
|
||||||
|
messagesPerField,
|
||||||
|
register,
|
||||||
|
realm,
|
||||||
|
passwordRequired,
|
||||||
|
recaptchaRequired,
|
||||||
|
recaptchaSiteKey
|
||||||
|
}] = useState(() => (
|
||||||
|
assert(
|
||||||
|
kcContext !== undefined,
|
||||||
|
"App is currently being served by keycloak"
|
||||||
|
),
|
||||||
|
kcContext
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Template
|
||||||
|
kcProperties={kcProperties}
|
||||||
|
headerNode={t("registerTitle")}
|
||||||
|
formNode={
|
||||||
|
<form id="kc-register-form" className={cx(kcProperties.kcFormClass)} action={url.registrationAction} method="post">
|
||||||
|
|
||||||
|
<div className={cx(kcProperties.kcFormGroupClass, messagesPerField.printIfExists('firstName', kcProperties.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(kcProperties.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="firstName" className={cx(kcProperties.kcLabelClass)}>{t("firstName")}</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(kcProperties.kcInputWrapperClass)}>
|
||||||
|
<input type="text" id="firstName" className={cx(kcProperties.kcInputClass)} name="firstName"
|
||||||
|
value={register.formData.firstName ?? ""}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(kcProperties.kcFormGroupClass, messagesPerField.printIfExists("lastName", kcProperties.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(kcProperties.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="lastName" className={cx(kcProperties.kcLabelClass)}>{t("lastName")}</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(kcProperties.kcInputWrapperClass)}>
|
||||||
|
<input type="text" id="lastName" className={cx(kcProperties.kcInputClass)} name="lastName"
|
||||||
|
value={register.formData.lastName ?? ""}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(kcProperties.kcFormGroupClass, messagesPerField.printIfExists('email', kcProperties.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(kcProperties.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="email" className={cx(kcProperties.kcLabelClass)}>{t("email")}</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(kcProperties.kcInputWrapperClass)}>
|
||||||
|
<input type="text" id="email" className={cx(kcProperties.kcInputClass)} name="email"
|
||||||
|
value={register.formData.email ?? ""} autoComplete="email"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
!realm.registrationEmailAsUsername &&
|
||||||
|
|
||||||
|
<div className={cx(kcProperties.kcFormGroupClass, messagesPerField.printIfExists('username', kcProperties.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(kcProperties.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="username" className={cx(kcProperties.kcLabelClass)}>{t("username")}</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(kcProperties.kcInputWrapperClass)}>
|
||||||
|
<input type="text" id="username" className={cx(kcProperties.kcInputClass)} name="username"
|
||||||
|
value={register.formData.username ?? ""} autoComplete="username" />
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
passwordRequired &&
|
||||||
|
<>
|
||||||
|
|
||||||
|
<div className={cx(kcProperties.kcFormGroupClass, messagesPerField.printIfExists("password", kcProperties.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(kcProperties.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="password" className={cx(kcProperties.kcLabelClass)}>{t("password")}</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(kcProperties.kcInputWrapperClass)}>
|
||||||
|
<input type="password" id="password" className={cx(kcProperties.kcInputClass)} name="password" autoComplete="new-password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={cx(kcProperties.kcFormGroupClass, messagesPerField.printIfExists("password-confirm", kcProperties.kcFormGroupErrorClass))}>
|
||||||
|
<div className={cx(kcProperties.kcLabelWrapperClass)}>
|
||||||
|
<label htmlFor="password-confirm" className={cx(kcProperties.kcLabelClass)}>{t("passwordConfirm")}</label>
|
||||||
|
</div>
|
||||||
|
<div className={cx(kcProperties.kcInputWrapperClass)}>
|
||||||
|
<input type="password" id="password-confirm" className={cx(kcProperties.kcInputClass)} name="password-confirm" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
|
||||||
|
}
|
||||||
|
{
|
||||||
|
recaptchaRequired &&
|
||||||
|
<div className="form-group">
|
||||||
|
<div className={cx(kcProperties.kcInputWrapperClass)}>
|
||||||
|
<div className="g-recaptcha" data-size="compact" data-sitekey={recaptchaSiteKey}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div className={cx(kcProperties.kcFormGroupClass)}>
|
||||||
|
<div id="kc-form-options" className={cx(kcProperties.kcFormOptionsClass)}>
|
||||||
|
<div className={cx(kcProperties.kcFormOptionsWrapperClass)}>
|
||||||
|
<span><a href={url.loginUrl}>{t("backToLogin")}</a></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="kc-form-buttons" className={cx(kcProperties.kcFormButtonsClass)}>
|
||||||
|
<input className={cx(kcProperties.kcButtonClass, kcProperties.kcButtonPrimaryClass, kcProperties.kcButtonBlockClass, kcProperties.kcButtonLargeClass)} type="submit"
|
||||||
|
value={tStr("doRegister")} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form >
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -23,9 +23,9 @@ export type TemplateProps = {
|
|||||||
displayWide?: boolean;
|
displayWide?: boolean;
|
||||||
showAnotherWayIfPresent?: boolean;
|
showAnotherWayIfPresent?: boolean;
|
||||||
headerNode: ReactNode;
|
headerNode: ReactNode;
|
||||||
showUsernameNode: ReactNode;
|
showUsernameNode?: ReactNode;
|
||||||
formNode: ReactNode;
|
formNode: ReactNode;
|
||||||
displayInfoNode: ReactNode;
|
displayInfoNode?: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -39,9 +39,9 @@ export const Template = memo((props: TemplateProps) => {
|
|||||||
showAnotherWayIfPresent = true,
|
showAnotherWayIfPresent = true,
|
||||||
kcProperties = {},
|
kcProperties = {},
|
||||||
headerNode,
|
headerNode,
|
||||||
showUsernameNode,
|
showUsernameNode = null,
|
||||||
formNode,
|
formNode,
|
||||||
displayInfoNode
|
displayInfoNode = null
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const { t } = useKcTranslation();
|
const { t } = useKcTranslation();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { ftlValuesGlobalName } from "../bin/build-keycloak-theme/ftlValuesGlobalName";
|
import { ftlValuesGlobalName } from "../bin/build-keycloak-theme/ftlValuesGlobalName";
|
||||||
import type { generateFtlFilesCodeFactory } from "../bin/build-keycloak-theme/generateFtl";
|
import type { generateFtlFilesCodeFactory } from "../bin/build-keycloak-theme/generateFtl";
|
||||||
import { id } from "evt/tools/typeSafety/id";
|
import { id } from "evt/tools/typeSafety/id";
|
||||||
import type { KcLanguageTag } from "./i18n/KcLanguageTag";
|
import type { KcLanguageTag } from "./i18n/KcLanguageTag";
|
||||||
|
|
||||||
|
|
||||||
export type KcContext = {
|
export type KcContext = {
|
||||||
@ -14,6 +14,9 @@ export type KcContext = {
|
|||||||
loginRestartFlowUrl: string;
|
loginRestartFlowUrl: string;
|
||||||
loginResetCredentialsUrl: string;
|
loginResetCredentialsUrl: string;
|
||||||
registrationUrl: string;
|
registrationUrl: string;
|
||||||
|
//Specific to register
|
||||||
|
registrationAction: string;
|
||||||
|
loginUrl: string;
|
||||||
};
|
};
|
||||||
realm: {
|
realm: {
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
@ -67,6 +70,32 @@ export type KcContext = {
|
|||||||
rememberMe: boolean;
|
rememberMe: boolean;
|
||||||
};
|
};
|
||||||
registrationDisabled: boolean;
|
registrationDisabled: boolean;
|
||||||
|
//Specific to register
|
||||||
|
messagesPerField: {
|
||||||
|
printIfExists<T>(
|
||||||
|
key:
|
||||||
|
"userLabel" |
|
||||||
|
"username" |
|
||||||
|
"email" |
|
||||||
|
"firstName" |
|
||||||
|
"lastName" |
|
||||||
|
"password" |
|
||||||
|
"password-confirm",
|
||||||
|
x: T
|
||||||
|
): T | undefined;
|
||||||
|
};
|
||||||
|
register: {
|
||||||
|
formData: {
|
||||||
|
firstName?: string;
|
||||||
|
displayName?: string;
|
||||||
|
lastName?: string;
|
||||||
|
email?: string;
|
||||||
|
username?: string;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
passwordRequired: boolean;
|
||||||
|
recaptchaRequired: boolean;
|
||||||
|
recaptchaSiteKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const kcContext = id<KcContext | undefined>((window as any)[ftlValuesGlobalName]);
|
export const kcContext = id<KcContext | undefined>((window as any)[ftlValuesGlobalName]);
|
||||||
|
125
src/lib/kcContext.ts.disabled
Normal file
125
src/lib/kcContext.ts.disabled
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
|
||||||
|
import { ftlValuesGlobalName } from "../bin/build-keycloak-theme/ftlValuesGlobalName";
|
||||||
|
import type { generateFtlFilesCodeFactory } from "../bin/build-keycloak-theme/generateFtl";
|
||||||
|
import { id } from "evt/tools/typeSafety/id";
|
||||||
|
import type { KcLanguageTag } from "./i18n/KcLanguageTag";
|
||||||
|
import { doExtends } from "evt/tools/typeSafety/doExtends";
|
||||||
|
|
||||||
|
export type KcContext = KcContext.Login | KcContext.Register;
|
||||||
|
|
||||||
|
export declare namespace KcContext {
|
||||||
|
|
||||||
|
export type Template = {};
|
||||||
|
|
||||||
|
export type Login = Template & {
|
||||||
|
pageBasename: "login.ftl";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Register = Template & {
|
||||||
|
pageBasename: "register.ftl";
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
type T = KcContext["pageBasename"];
|
||||||
|
type U = Parameters<ReturnType<typeof generateFtlFilesCodeFactory>["generateFtlFilesCode"]>[0]["pageBasename"];
|
||||||
|
|
||||||
|
doExtends<T, U>();
|
||||||
|
doExtends<U, T>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type KcContext = {
|
||||||
|
pageBasename: Parameters<ReturnType<typeof generateFtlFilesCodeFactory>["generateFtlFilesCode"]>[0]["pageBasename"];
|
||||||
|
url: {
|
||||||
|
loginAction: string;
|
||||||
|
resourcesPath: string;
|
||||||
|
resourcesCommonPath: string;
|
||||||
|
loginRestartFlowUrl: string;
|
||||||
|
loginResetCredentialsUrl: string;
|
||||||
|
registrationUrl: string;
|
||||||
|
registrationAction: string;
|
||||||
|
loginUrl: string;
|
||||||
|
};
|
||||||
|
realm: {
|
||||||
|
displayName?: string;
|
||||||
|
displayNameHtml?: string;
|
||||||
|
internationalizationEnabled: boolean;
|
||||||
|
password: boolean;
|
||||||
|
loginWithEmailAllowed: boolean;
|
||||||
|
registrationEmailAsUsername: boolean;
|
||||||
|
rememberMe: boolean;
|
||||||
|
resetPasswordAllowed: boolean;
|
||||||
|
};
|
||||||
|
/** Undefined if !realm.internationalizationEnabled */
|
||||||
|
locale?: {
|
||||||
|
supported: {
|
||||||
|
//url: string;
|
||||||
|
languageTag: KcLanguageTag;
|
||||||
|
/** Is determined by languageTag. Ex: languageTag === "en" => label === "English"
|
||||||
|
* or getLanguageLabel(languageTag) === label
|
||||||
|
*/
|
||||||
|
//label: LanguageLabel;
|
||||||
|
}[];
|
||||||
|
//NOTE: We do not expose this because the language is managed
|
||||||
|
//client side. We use this value however to set the default.
|
||||||
|
//current: LanguageLabel;
|
||||||
|
},
|
||||||
|
auth?: {
|
||||||
|
showUsername: boolean;
|
||||||
|
showResetCredentials: boolean;
|
||||||
|
showTryAnotherWayLink: boolean;
|
||||||
|
attemptedUsername?: boolean;
|
||||||
|
selectedCredential?: string;
|
||||||
|
};
|
||||||
|
scripts: string[];
|
||||||
|
message?: {
|
||||||
|
type: "success" | "warning" | "error" | "info";
|
||||||
|
summary: string;
|
||||||
|
};
|
||||||
|
isAppInitiatedAction: boolean;
|
||||||
|
social: {
|
||||||
|
displayInfo: boolean;
|
||||||
|
providers?: {
|
||||||
|
loginUrl: string;
|
||||||
|
alias: string;
|
||||||
|
providerId: string;
|
||||||
|
displayName: string;
|
||||||
|
}[]
|
||||||
|
};
|
||||||
|
usernameEditDisabled: boolean;
|
||||||
|
login: {
|
||||||
|
username?: string;
|
||||||
|
rememberMe: boolean;
|
||||||
|
};
|
||||||
|
registrationDisabled: boolean;
|
||||||
|
messagesPerField: {
|
||||||
|
printIfExists<T>(
|
||||||
|
key:
|
||||||
|
"userLabel" |
|
||||||
|
"username" |
|
||||||
|
"email" |
|
||||||
|
"firstName" |
|
||||||
|
"lastName" |
|
||||||
|
"password" |
|
||||||
|
"password-confirm",
|
||||||
|
x: T
|
||||||
|
): T | undefined;
|
||||||
|
};
|
||||||
|
register: {
|
||||||
|
formData: {
|
||||||
|
firstName?: string;
|
||||||
|
displayName?: string;
|
||||||
|
lastName?: string;
|
||||||
|
email?: string;
|
||||||
|
username?: string;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
passwordRequired: boolean;
|
||||||
|
recaptchaRequired: boolean;
|
||||||
|
recaptchaSiteKey: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const kcContext = id<KcContext | undefined>((window as any)[ftlValuesGlobalName]);
|
10
yarn.lock
10
yarn.lock
@ -623,7 +623,15 @@ evt@2.0.0-beta.12:
|
|||||||
minimal-polyfills "^2.1.5"
|
minimal-polyfills "^2.1.5"
|
||||||
run-exclusive "^2.2.14"
|
run-exclusive "^2.2.14"
|
||||||
|
|
||||||
evt@^1.9.12, evt@^1.9.2:
|
evt@2.0.0-beta.15:
|
||||||
|
version "2.0.0-beta.15"
|
||||||
|
resolved "https://registry.yarnpkg.com/evt/-/evt-2.0.0-beta.15.tgz#a34ef224c827152c06f29157a9af5a41644e1a36"
|
||||||
|
integrity sha512-AZIuA8ujBsDX/rPC9mJ2sGvrBJAvV2OGj/yzACbuT4pRLKii5PMjYPitNk4xJMKuXSDwvwCsQzuGPDCcbRc60A==
|
||||||
|
dependencies:
|
||||||
|
minimal-polyfills "^2.1.5"
|
||||||
|
run-exclusive "^2.2.14"
|
||||||
|
|
||||||
|
evt@^1.9.2:
|
||||||
version "1.9.12"
|
version "1.9.12"
|
||||||
resolved "https://registry.yarnpkg.com/evt/-/evt-1.9.12.tgz#8d06177259cbcb09ef936e18945bf7ddd087170c"
|
resolved "https://registry.yarnpkg.com/evt/-/evt-1.9.12.tgz#8d06177259cbcb09ef936e18945bf7ddd087170c"
|
||||||
integrity sha512-u8wC4Xif2pcDJ9cEm0wzWCIQb+Y214m1eUgsgm2hVIuXuvC6LToryA0Ecl1O8Slii2E9l6USLsyxXWntjlnIbw==
|
integrity sha512-u8wC4Xif2pcDJ9cEm0wzWCIQb+Y214m1eUgsgm2hVIuXuvC6LToryA0Ecl1O8Slii2E9l6USLsyxXWntjlnIbw==
|
||||||
|
Loading…
x
Reference in New Issue
Block a user