0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

refactor(connector): put classes definition in types.ts and upgrade silverhand/essentials dependency

This commit is contained in:
Darcy Ye 2022-08-17 16:07:02 +08:00
parent 473b219c3d
commit ee8c533ab0
No known key found for this signature in database
GPG key ID: B46F4C07EDEFC610
5 changed files with 75 additions and 77 deletions

View file

@ -23,7 +23,7 @@
},
"devDependencies": {
"@silverhand/eslint-config": "1.0.0-rc.2",
"@silverhand/essentials": "^1.1.6",
"@silverhand/essentials": "^1.2.0",
"@silverhand/ts-config": "1.0.0-rc.2",
"eslint": "^8.21.0",
"lint-staged": "^13.0.0",

View file

@ -1,72 +0,0 @@
import { Optional } from '@silverhand/essentials';
import { ConnectorMetadata } from './types';
// We will have message type 'ForgotPassword' available in the near future.
type MessageTypes = 'SignIn' | 'Register' | 'Test';
type SendMessageFunction = (
to: string,
type: MessageTypes,
payload: { code: string }
) => Promise<unknown>;
type SendMessageByFunction<T = Record<string, unknown>> = (
config: T,
to: string,
type: MessageTypes,
payload: { code: string }
) => Promise<unknown>;
export type ValidateConfig<T> = (config: unknown) => asserts config is T;
export type GetAuthorizationUri = (payload: {
state: string;
redirectUri: string;
}) => Promise<string>;
export type GetUserInfo = (
data: unknown
) => Promise<{ id: string } & Record<string, Optional<string>>>;
export type GetConnectorConfig = (id: string) => Promise<unknown>;
export type AuthResponseParser<T = Record<string, unknown>> = (response: unknown) => Promise<T>;
abstract class BaseConnector<T> {
public getConfig: GetConnectorConfig;
public metadata!: ConnectorMetadata;
public abstract validateConfig: ValidateConfig<T>;
constructor(getConnectorConfig: GetConnectorConfig) {
this.getConfig = getConnectorConfig;
}
}
abstract class PasswordlessConnector<T> extends BaseConnector<T> {
protected abstract readonly sendMessageBy: SendMessageByFunction<T>;
public sendMessage: SendMessageFunction = async (address, type, data) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy(config, address, type, data);
};
public sendTestMessage?: SendMessageByFunction = async (config, address, type, data) => {
this.validateConfig(config);
return this.sendMessageBy(config, address, type, data);
};
}
export abstract class SmsConnector<T> extends PasswordlessConnector<T> {}
export abstract class EmailConnector<T> extends PasswordlessConnector<T> {}
export abstract class SocialConnector<T> extends BaseConnector<T> {
public abstract getAuthorizationUri: GetAuthorizationUri;
public abstract getUserInfo: GetUserInfo;
protected abstract authResponseParser?: AuthResponseParser;
}

View file

@ -1,3 +1,2 @@
export * from './types';
export * from './error';
export * from './class';

View file

@ -1,5 +1,5 @@
import type { Language } from '@logto/phrases';
import { Nullable } from '@silverhand/essentials';
import { Nullable, Optional } from '@silverhand/essentials';
export enum ConnectorType {
Email = 'Email',
@ -42,3 +42,74 @@ export type ConnectorMetadata = {
readme: string;
configTemplate: string;
};
// We will have message type 'ForgotPassword' available in the near future.
type MessageTypes = 'SignIn' | 'Register' | 'Test';
type SendMessageFunction = (
to: string,
type: MessageTypes,
payload: { code: string }
) => Promise<unknown>;
type SendMessageByFunction<T = Record<string, unknown>> = (
config: T,
to: string,
type: MessageTypes,
payload: { code: string }
) => Promise<unknown>;
export type ValidateConfig<T> = (config: unknown) => asserts config is T;
export type GetAuthorizationUri = (payload: {
state: string;
redirectUri: string;
}) => Promise<string>;
export type GetUserInfo = (
data: unknown
) => Promise<{ id: string } & Record<string, Optional<string>>>;
export type GetConnectorConfig = (id: string) => Promise<unknown>;
export type AuthResponseParser<T = Record<string, unknown>> = (response: unknown) => Promise<T>;
abstract class BaseConnector<T> {
public getConfig: GetConnectorConfig;
public metadata!: ConnectorMetadata;
constructor(getConnectorConfig: GetConnectorConfig) {
this.getConfig = getConnectorConfig;
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
public validateConfig: ValidateConfig<T> = async () => {};
}
abstract class PasswordlessConnector<T> extends BaseConnector<T> {
protected abstract readonly sendMessageBy: SendMessageByFunction<T>;
public sendMessage: SendMessageFunction = async (address, type, data) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy(config, address, type, data);
};
public sendTestMessage?: SendMessageByFunction = async (config, address, type, data) => {
this.validateConfig(config);
return this.sendMessageBy(config, address, type, data);
};
}
export abstract class SmsConnector<T> extends PasswordlessConnector<T> {}
export abstract class EmailConnector<T> extends PasswordlessConnector<T> {}
export abstract class SocialConnector<T> extends BaseConnector<T> {
public abstract getAuthorizationUri: GetAuthorizationUri;
public abstract getUserInfo: GetUserInfo;
protected abstract authResponseParser?: AuthResponseParser;
}

View file

@ -538,7 +538,7 @@ importers:
specifiers:
'@logto/phrases': ^1.0.0-beta.4
'@silverhand/eslint-config': 1.0.0-rc.2
'@silverhand/essentials': ^1.1.6
'@silverhand/essentials': ^1.2.0
'@silverhand/ts-config': 1.0.0-rc.2
eslint: ^8.21.0
lint-staged: ^13.0.0
@ -548,7 +548,7 @@ importers:
'@logto/phrases': link:../phrases
devDependencies:
'@silverhand/eslint-config': 1.0.0-rc.2_swk2g7ygmfleszo5c33j4vooni
'@silverhand/essentials': 1.1.7
'@silverhand/essentials': 1.2.0
'@silverhand/ts-config': 1.0.0-rc.2_typescript@4.7.4
eslint: 8.21.0
lint-staged: 13.0.0