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

refactor: eliminate connector-kit dependency on logto/cloud (#4622)

This commit is contained in:
Darcy Ye 2023-10-10 13:55:21 +08:00 committed by GitHub
parent c913406926
commit f1f75aa37e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 80 additions and 42 deletions

View file

@ -76,6 +76,7 @@
"devDependencies": { "devDependencies": {
"@silverhand/eslint-config": "4.0.1", "@silverhand/eslint-config": "4.0.1",
"@silverhand/ts-config": "4.0.0", "@silverhand/ts-config": "4.0.0",
"@withtyped/server": "^0.12.9",
"@types/inquirer": "^9.0.0", "@types/inquirer": "^9.0.0",
"@types/jest": "^29.4.0", "@types/jest": "^29.4.0",
"@types/node": "^18.11.18", "@types/node": "^18.11.18",

View file

@ -1,3 +1,4 @@
import type { BaseRoutes, Router } from '@withtyped/server';
import chalk from 'chalk'; import chalk from 'chalk';
import { consoleLog } from '../utils.js'; import { consoleLog } from '../utils.js';
@ -7,8 +8,8 @@ import { loadConnector } from './loader.js';
import type { ConnectorFactory, ConnectorPackage } from './types.js'; import type { ConnectorFactory, ConnectorPackage } from './types.js';
import { parseMetadata, validateConnectorModule } from './utils.js'; import { parseMetadata, validateConnectorModule } from './utils.js';
// eslint-disable-next-line @silverhand/fp/no-let // eslint-disable-next-line @silverhand/fp/no-let, @typescript-eslint/no-explicit-any
let cachedConnectorFactories: ConnectorFactory[] | undefined; let cachedConnectorFactories: Array<ConnectorFactory<Router<any, BaseRoutes, string>>> | undefined;
export const loadConnectorFactories = async ( export const loadConnectorFactories = async (
connectorPackages: ConnectorPackage[], connectorPackages: ConnectorPackage[],
@ -46,7 +47,9 @@ export const loadConnectorFactories = async (
// eslint-disable-next-line @silverhand/fp/no-mutation // eslint-disable-next-line @silverhand/fp/no-mutation
cachedConnectorFactories = connectorFactories.filter( cachedConnectorFactories = connectorFactories.filter(
(connectorFactory): connectorFactory is ConnectorFactory => connectorFactory !== undefined // eslint-disable-next-line @typescript-eslint/no-explicit-any
(connectorFactory): connectorFactory is ConnectorFactory<Router<any, BaseRoutes, string>> =>
connectorFactory !== undefined
); );
return cachedConnectorFactories; return cachedConnectorFactories;

View file

@ -1,13 +1,15 @@
import type { AllConnector, CreateConnector } from '@logto/connector-kit'; import type { AllConnector, CreateConnector } from '@logto/connector-kit';
import type { BaseRoutes, Router } from '@withtyped/server';
/** /**
* Dynamic loaded connector type. * Dynamic loaded connector type.
*/ */
export type ConnectorFactory<T extends AllConnector = AllConnector> = Pick< export type ConnectorFactory<
T, // eslint-disable-next-line @typescript-eslint/no-explicit-any
'type' | 'metadata' T extends Router<any, BaseRoutes, string>,
> & { U extends AllConnector = AllConnector,
createConnector: CreateConnector<T>; > = Pick<U, 'type' | 'metadata'> & {
createConnector: CreateConnector<U, T>;
path: string; path: string;
}; };

View file

@ -10,6 +10,7 @@ import type {
GetCloudServiceClient, GetCloudServiceClient,
} from '@logto/connector-kit'; } from '@logto/connector-kit';
import { ConnectorError, ConnectorErrorCodes, ConnectorType } from '@logto/connector-kit'; import { ConnectorError, ConnectorErrorCodes, ConnectorType } from '@logto/connector-kit';
import type { BaseRoutes, Router } from '@withtyped/server';
import { consoleLog } from '../utils.js'; import { consoleLog } from '../utils.js';
@ -90,11 +91,15 @@ export const parseMetadata = async (
}; };
}; };
export const buildRawConnector = async <T extends AllConnector = AllConnector>( export const buildRawConnector = async <
connectorFactory: ConnectorFactory<T>, // eslint-disable-next-line @typescript-eslint/no-explicit-any
T extends Router<any, BaseRoutes, string>,
U extends AllConnector = AllConnector,
>(
connectorFactory: ConnectorFactory<T, U>,
getConnectorConfig?: GetConnectorConfig, getConnectorConfig?: GetConnectorConfig,
getCloudServiceClient?: GetCloudServiceClient getCloudServiceClient?: GetCloudServiceClient<T>
): Promise<{ rawConnector: T; rawMetadata: ConnectorMetadata }> => { ): Promise<{ rawConnector: U; rawMetadata: ConnectorMetadata }> => {
const { createConnector, path: packagePath } = connectorFactory; const { createConnector, path: packagePath } = connectorFactory;
const rawConnector = await createConnector({ const rawConnector = await createConnector({
getConfig: getConnectorConfig ?? notImplemented, getConfig: getConnectorConfig ?? notImplemented,

View file

@ -47,5 +47,8 @@
"prettier": "@silverhand/eslint-config/.prettierrc", "prettier": "@silverhand/eslint-config/.prettierrc",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
},
"devDependencies": {
"@logto/cloud": "0.2.5-d434baa"
} }
} }

View file

@ -1,6 +1,7 @@
import { assert, conditional } from '@silverhand/essentials'; import { assert, conditional } from '@silverhand/essentials';
import { HTTPError } from 'got'; import { HTTPError } from 'got';
import type router from '@logto/cloud/routes';
import type { import type {
CreateConnector, CreateConnector,
EmailConnector, EmailConnector,
@ -20,7 +21,10 @@ import { defaultMetadata, emailEndpoint, usageEndpoint } from './constant.js';
import { logtoEmailConfigGuard } from './types.js'; import { logtoEmailConfigGuard } from './types.js';
const sendMessage = const sendMessage =
(getConfig: GetConnectorConfig, getClient?: GetCloudServiceClient): SendMessageFunction => (
getConfig: GetConnectorConfig,
getClient?: GetCloudServiceClient<typeof router>
): SendMessageFunction =>
async (data, inputConfig) => { async (data, inputConfig) => {
const config = inputConfig ?? (await getConfig(defaultMetadata.id)); const config = inputConfig ?? (await getConfig(defaultMetadata.id));
validateConfig(config, logtoEmailConfigGuard); validateConfig(config, logtoEmailConfigGuard);
@ -47,7 +51,10 @@ const sendMessage =
}; };
const getUsage = const getUsage =
(getConfig: GetConnectorConfig, getClient?: GetCloudServiceClient): GetUsageFunction => (
getConfig: GetConnectorConfig,
getClient?: GetCloudServiceClient<typeof router>
): GetUsageFunction =>
async (startFrom?: Date) => { async (startFrom?: Date) => {
const config = await getConfig(defaultMetadata.id); const config = await getConfig(defaultMetadata.id);
validateConfig(config, logtoEmailConfigGuard); validateConfig(config, logtoEmailConfigGuard);
@ -61,7 +68,7 @@ const getUsage =
return count; return count;
}; };
const createLogtoEmailConnector: CreateConnector<EmailConnector> = async ({ const createLogtoEmailConnector: CreateConnector<EmailConnector, typeof router> = async ({
getConfig, getConfig,
getCloudServiceClient: getClient, getCloudServiceClient: getClient,
}) => { }) => {

View file

@ -1,4 +1,5 @@
import type { ConnectorFactory } from '@logto/cli/lib/connector/index.js'; import type { ConnectorFactory } from '@logto/cli/lib/connector/index.js';
import type router from '@logto/cloud/routes';
import { ConnectorPlatform, DemoConnector } from '@logto/connector-kit'; import { ConnectorPlatform, DemoConnector } from '@logto/connector-kit';
import type { Connector } from '@logto/schemas'; import type { Connector } from '@logto/schemas';
import { ConnectorType } from '@logto/schemas'; import { ConnectorType } from '@logto/schemas';
@ -54,7 +55,7 @@ export const mockLogtoConnector = {
configGuard: any(), configGuard: any(),
}; };
export const mockConnectorFactory: ConnectorFactory = { export const mockConnectorFactory: ConnectorFactory<typeof router> = {
metadata: mockMetadata, metadata: mockMetadata,
type: ConnectorType.Social, type: ConnectorType.Social,
path: 'random_path', path: 'random_path',

View file

@ -1,4 +1,5 @@
import type { ConnectorFactory } from '@logto/cli/lib/connector/index.js'; import type { ConnectorFactory } from '@logto/cli/lib/connector/index.js';
import type router from '@logto/cloud/routes';
import { VerificationCodeType } from '@logto/connector-kit'; import { VerificationCodeType } from '@logto/connector-kit';
import type { EmailConnector, SmsConnector } from '@logto/connector-kit'; import type { EmailConnector, SmsConnector } from '@logto/connector-kit';
import { ConnectorType } from '@logto/schemas'; import { ConnectorType } from '@logto/schemas';
@ -66,7 +67,7 @@ describe('connector services route', () => {
it('should get SMS connector and send test message', async () => { it('should get SMS connector and send test message', async () => {
const sendMessage = jest.fn(); const sendMessage = jest.fn();
const mockedSmsConnectorFactory: ConnectorFactory<SmsConnector> = { const mockedSmsConnectorFactory: ConnectorFactory<typeof router, SmsConnector> = {
...mockConnectorFactory, ...mockConnectorFactory,
metadata: mockMetadata, metadata: mockMetadata,
type: ConnectorType.Sms, type: ConnectorType.Sms,
@ -93,7 +94,7 @@ describe('connector services route', () => {
it('should get email connector and send test message', async () => { it('should get email connector and send test message', async () => {
const sendMessage = jest.fn(); const sendMessage = jest.fn();
const mockedEmailConnectorFactory: ConnectorFactory<EmailConnector> = { const mockedEmailConnectorFactory: ConnectorFactory<typeof router, EmailConnector> = {
...mockConnectorFactory, ...mockConnectorFactory,
metadata: mockMetadata, metadata: mockMetadata,
type: ConnectorType.Email, type: ConnectorType.Email,

View file

@ -1,5 +1,6 @@
import { buildRawConnector, notImplemented } from '@logto/cli/lib/connector/index.js'; import { buildRawConnector, notImplemented } from '@logto/cli/lib/connector/index.js';
import type { ConnectorFactory } from '@logto/cli/lib/connector/index.js'; import type { ConnectorFactory } from '@logto/cli/lib/connector/index.js';
import type CloudRouter from '@logto/cloud/routes';
import { import {
type SmsConnector, type SmsConnector,
type EmailConnector, type EmailConnector,
@ -47,7 +48,11 @@ export default function connectorConfigTestingRoutes<T extends AuthedRouter>(
const connectorFactories = await loadConnectorFactories(); const connectorFactories = await loadConnectorFactories();
const connectorFactory = connectorFactories const connectorFactory = connectorFactories
.filter( .filter(
(factory): factory is ConnectorFactory<SmsConnector> | ConnectorFactory<EmailConnector> => (
factory
): factory is
| ConnectorFactory<typeof CloudRouter, SmsConnector>
| ConnectorFactory<typeof CloudRouter, EmailConnector> =>
factory.type === ConnectorType.Email || factory.type === ConnectorType.Sms factory.type === ConnectorType.Email || factory.type === ConnectorType.Sms
) )
.find(({ metadata: { id } }) => id === factoryId && !demoConnectorIds.includes(id)); .find(({ metadata: { id } }) => id === factoryId && !demoConnectorIds.includes(id));
@ -66,7 +71,7 @@ export default function connectorConfigTestingRoutes<T extends AuthedRouter>(
const { const {
rawConnector: { sendMessage }, rawConnector: { sendMessage },
} = await buildRawConnector<SmsConnector | EmailConnector>( } = await buildRawConnector<typeof CloudRouter, SmsConnector | EmailConnector>(
connectorFactory, connectorFactory,
notImplemented, notImplemented,
conditional(ServiceConnector.Email === connectorFactory.metadata.id && getClient) conditional(ServiceConnector.Email === connectorFactory.metadata.id && getClient)

View file

@ -1,4 +1,5 @@
import { type ConnectorFactory, buildRawConnector } from '@logto/cli/lib/connector/index.js'; import { type ConnectorFactory, buildRawConnector } from '@logto/cli/lib/connector/index.js';
import type router from '@logto/cloud/routes';
import { demoConnectorIds, validateConfig } from '@logto/connector-kit'; import { demoConnectorIds, validateConfig } from '@logto/connector-kit';
import { Connectors, ConnectorType, connectorResponseGuard, type JsonObject } from '@logto/schemas'; import { Connectors, ConnectorType, connectorResponseGuard, type JsonObject } from '@logto/schemas';
import { generateStandardShortId } from '@logto/shared'; import { generateStandardShortId } from '@logto/shared';
@ -20,7 +21,10 @@ import connectorAuthorizationUriRoutes from './authorization-uri.js';
import connectorConfigTestingRoutes from './config-testing.js'; import connectorConfigTestingRoutes from './config-testing.js';
import connectorFactoryRoutes from './factory.js'; import connectorFactoryRoutes from './factory.js';
const guardConnectorsQuota = async (factory: ConnectorFactory, quota: QuotaLibrary) => { const guardConnectorsQuota = async (
factory: ConnectorFactory<typeof router>,
quota: QuotaLibrary
) => {
if (factory.metadata.isStandard) { if (factory.metadata.isStandard) {
await quota.guardKey('standardConnectorsLimit'); await quota.guardKey('standardConnectorsLimit');
} }

View file

@ -6,6 +6,7 @@ import type { ConnectorFactory } from '@logto/cli/lib/connector/index.js';
import { loadConnectorFactories as _loadConnectorFactories } from '@logto/cli/lib/connector/index.js'; import { loadConnectorFactories as _loadConnectorFactories } from '@logto/cli/lib/connector/index.js';
import { connectorDirectory } from '@logto/cli/lib/constants.js'; import { connectorDirectory } from '@logto/cli/lib/constants.js';
import { getConnectorPackagesFromDirectory } from '@logto/cli/lib/utils.js'; import { getConnectorPackagesFromDirectory } from '@logto/cli/lib/utils.js';
import type router from '@logto/cloud/routes';
import { import {
demoConnectorIds, demoConnectorIds,
ConnectorType, ConnectorType,
@ -59,7 +60,7 @@ export const transpileLogtoConnector = async (
export const transpileConnectorFactory = ({ export const transpileConnectorFactory = ({
metadata, metadata,
type, type,
}: ConnectorFactory): ConnectorFactoryResponse => { }: ConnectorFactory<typeof router>): ConnectorFactoryResponse => {
return { return {
type, type,
...metadata, ...metadata,
@ -67,7 +68,9 @@ export const transpileConnectorFactory = ({
}; };
}; };
const checkDuplicateConnectorFactoriesId = (connectorFactories: ConnectorFactory[]) => { const checkDuplicateConnectorFactoriesId = (
connectorFactories: Array<ConnectorFactory<typeof router>>
) => {
const connectorFactoryIds = connectorFactories.map(({ metadata }) => metadata.id); const connectorFactoryIds = connectorFactories.map(({ metadata }) => metadata.id);
const deduplicatedConnectorFactoryIds = deduplicate(connectorFactoryIds); const deduplicatedConnectorFactoryIds = deduplicate(connectorFactoryIds);

View file

@ -38,13 +38,13 @@
"dependencies": { "dependencies": {
"@logto/language-kit": "workspace:^1.0.0", "@logto/language-kit": "workspace:^1.0.0",
"@silverhand/essentials": "^2.8.4", "@silverhand/essentials": "^2.8.4",
"@withtyped/client": "^0.7.22" "@withtyped/client": "^0.7.22",
"@withtyped/server":"^0.12.9"
}, },
"optionalDependencies": { "optionalDependencies": {
"zod": "^3.20.2" "zod": "^3.20.2"
}, },
"devDependencies": { "devDependencies": {
"@logto/cloud": "0.2.5-a3e852f",
"@jest/types": "^29.0.3", "@jest/types": "^29.0.3",
"@silverhand/eslint-config": "4.0.1", "@silverhand/eslint-config": "4.0.1",
"@silverhand/ts-config": "4.0.0", "@silverhand/ts-config": "4.0.0",

View file

@ -1,7 +1,7 @@
import type router from '@logto/cloud/routes';
import type { LanguageTag } from '@logto/language-kit'; import type { LanguageTag } from '@logto/language-kit';
import { isLanguageTag } from '@logto/language-kit'; import { isLanguageTag } from '@logto/language-kit';
import type Client from '@withtyped/client'; import type Client from '@withtyped/client';
import type { BaseRoutes, Router } from '@withtyped/server';
import type { ZodType } from 'zod'; import type { ZodType } from 'zod';
import { z } from 'zod'; import { z } from 'zod';
@ -199,14 +199,21 @@ export type BaseConnector<Type extends ConnectorType> = {
configGuard: ZodType; configGuard: ZodType;
}; };
export type CreateConnector<T extends AllConnector> = (options: { export type CreateConnector<
T extends AllConnector,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
U extends Router<any, BaseRoutes, string> = Router<any, BaseRoutes, string>,
> = (options: {
getConfig: GetConnectorConfig; getConfig: GetConnectorConfig;
getCloudServiceClient?: GetCloudServiceClient; getCloudServiceClient?: GetCloudServiceClient<U>;
}) => Promise<T>; }) => Promise<T>;
export type GetConnectorConfig = (id: string) => Promise<unknown>; export type GetConnectorConfig = (id: string) => Promise<unknown>;
export type GetCloudServiceClient = () => Promise<Client<typeof router>>; // eslint-disable-next-line @typescript-eslint/no-explicit-any
export type GetCloudServiceClient<T extends Router<any, BaseRoutes, string>> = () => Promise<
Client<T>
>;
export type AllConnector = SmsConnector | EmailConnector | SocialConnector; export type AllConnector = SmsConnector | EmailConnector | SocialConnector;

View file

@ -218,6 +218,9 @@ importers:
'@types/yargs': '@types/yargs':
specifier: ^17.0.13 specifier: ^17.0.13
version: 17.0.13 version: 17.0.13
'@withtyped/server':
specifier: ^0.12.9
version: 0.12.9(zod@3.20.2)
eslint: eslint:
specifier: ^8.44.0 specifier: ^8.44.0
version: 8.44.0 version: 8.44.0
@ -1318,6 +1321,9 @@ importers:
'@jest/types': '@jest/types':
specifier: ^29.5.0 specifier: ^29.5.0
version: 29.5.0 version: 29.5.0
'@logto/cloud':
specifier: 0.2.5-d434baa
version: 0.2.5-d434baa(zod@3.20.2)
'@rollup/plugin-commonjs': '@rollup/plugin-commonjs':
specifier: ^25.0.0 specifier: ^25.0.0
version: 25.0.0(rollup@3.8.0) version: 25.0.0(rollup@3.8.0)
@ -3977,6 +3983,9 @@ importers:
'@withtyped/client': '@withtyped/client':
specifier: ^0.7.22 specifier: ^0.7.22
version: 0.7.22(zod@3.20.2) version: 0.7.22(zod@3.20.2)
'@withtyped/server':
specifier: ^0.12.9
version: 0.12.9(zod@3.20.2)
optionalDependencies: optionalDependencies:
zod: zod:
specifier: ^3.20.2 specifier: ^3.20.2
@ -3985,9 +3994,6 @@ importers:
'@jest/types': '@jest/types':
specifier: ^29.0.3 specifier: ^29.0.3
version: 29.1.2 version: 29.1.2
'@logto/cloud':
specifier: 0.2.5-a3e852f
version: 0.2.5-a3e852f(zod@3.20.2)
'@silverhand/eslint-config': '@silverhand/eslint-config':
specifier: 4.0.1 specifier: 4.0.1
version: 4.0.1(eslint@8.44.0)(prettier@3.0.0)(typescript@5.0.2) version: 4.0.1(eslint@8.44.0)(prettier@3.0.0)(typescript@5.0.2)
@ -7341,16 +7347,6 @@ packages:
- zod - zod
dev: true dev: true
/@logto/cloud@0.2.5-a3e852f(zod@3.20.2):
resolution: {integrity: sha512-dIrEUW7gi477HQpNsq/HT1gdvPK2ZmVuV73u2rH9LXGEIFIVGqmmIaaK3IcOPG110jKCBhTzF0+hKsW9Y3Pjmw==}
engines: {node: ^18.12.0}
dependencies:
'@silverhand/essentials': 2.8.4
'@withtyped/server': 0.12.9(zod@3.20.2)
transitivePeerDependencies:
- zod
dev: true
/@logto/cloud@0.2.5-d434baa(zod@3.20.2): /@logto/cloud@0.2.5-d434baa(zod@3.20.2):
resolution: {integrity: sha512-VmWpqFzpWBrzJPQLvfe0bb7/XjF3lxs/rPbLt3zqBjGPtDXM9FAUn1m/gPbTwzXi5PxGOjlbD7jTl+3+1u4/NQ==} resolution: {integrity: sha512-VmWpqFzpWBrzJPQLvfe0bb7/XjF3lxs/rPbLt3zqBjGPtDXM9FAUn1m/gPbTwzXi5PxGOjlbD7jTl+3+1u4/NQ==}
engines: {node: ^18.12.0} engines: {node: ^18.12.0}