0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

feat(core): add connector usage to GET APIs response (#4097)

* feat: add GET /connectors/:id/usage to get passwordless connector usage
* refactor(core): get usage when possible when transpiling connector
This commit is contained in:
Darcy Ye 2023-06-30 16:22:34 +08:00 committed by GitHub
parent 876b0687f6
commit e0ee44d5d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 20 deletions

View file

@ -32,12 +32,14 @@ export default function socialRoutes<T extends AuthedMeRouter>(
const connectors = await getLogtoConnectors();
const { socialSignInConnectorTargets } = await findDefaultSignInExperience();
ctx.body = connectors
ctx.body = await Promise.all(
connectors
.filter(
({ type, metadata: { target } }) =>
type === ConnectorType.Social && socialSignInConnectorTargets.includes(target)
)
.map((connector) => transpileLogtoConnector(connector));
.map(async (connector) => transpileLogtoConnector(connector))
);
return next();
});

View file

@ -152,7 +152,7 @@ export default function connectorRoutes<T extends AuthedRouter>(
}
const connector = await getLogtoConnectorById(insertConnectorId);
ctx.body = transpileLogtoConnector(connector);
ctx.body = await transpileLogtoConnector(connector);
return next();
}
@ -186,7 +186,9 @@ export default function connectorRoutes<T extends AuthedRouter>(
? connectors.filter(({ metadata: { target } }) => target === filterTarget)
: connectors;
ctx.body = filteredConnectors.map((connector) => transpileLogtoConnector(connector));
ctx.body = await Promise.all(
filteredConnectors.map(async (connector) => transpileLogtoConnector(connector))
);
return next();
}
@ -208,7 +210,7 @@ export default function connectorRoutes<T extends AuthedRouter>(
// Hide demo connector
assertThat(!demoConnectorIds.includes(connector.metadata.id), 'connector.not_found');
ctx.body = transpileLogtoConnector(connector);
ctx.body = await transpileLogtoConnector(connector);
return next();
}
@ -308,7 +310,7 @@ export default function connectorRoutes<T extends AuthedRouter>(
jsonbMode: 'replace',
});
const connector = await getLogtoConnectorById(id);
ctx.body = transpileLogtoConnector(connector);
ctx.body = await transpileLogtoConnector(connector);
return next();
}

View file

@ -6,31 +6,50 @@ import type { ConnectorFactory } 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 { getConnectorPackagesFromDirectory } from '@logto/cli/lib/utils.js';
import { demoConnectorIds } from '@logto/connector-kit';
import {
demoConnectorIds,
ConnectorType,
type EmailConnector,
type SmsConnector,
} from '@logto/connector-kit';
import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas';
import { findPackage } from '@logto/shared';
import { deduplicate, pick } from '@silverhand/essentials';
import { conditional, deduplicate, pick, trySafe } from '@silverhand/essentials';
import { EnvSet } from '#src/env-set/index.js';
import RequestError from '#src/errors/RequestError/index.js';
import type { LogtoConnector } from './types.js';
import { type LogtoConnector } from './types.js';
export const transpileLogtoConnector = ({
dbEntry,
metadata,
type,
}: LogtoConnector): ConnectorResponse => {
const isDemo = demoConnectorIds.includes(dbEntry.connectorId);
const { config } = dbEntry;
export const isPasswordlessLogtoConnector = (
connector: LogtoConnector
): connector is LogtoConnector<EmailConnector | SmsConnector> =>
connector.type !== ConnectorType.Social;
export const transpileLogtoConnector = async (
connector: LogtoConnector,
extraInfo?: Record<string, unknown>
): Promise<ConnectorResponse> => {
const usagePayload = conditional(
/** Should do the check in advance since only passwordless connectors could have `getUsage` method. */
isPasswordlessLogtoConnector(connector) &&
connector.getUsage && {
usage: await trySafe(connector.getUsage(new Date(connector.dbEntry.createdAt))),
}
);
const { dbEntry, metadata, type } = connector;
const { config, connectorId: id } = dbEntry;
const isDemo = demoConnectorIds.includes(id);
return {
type,
...metadata,
...pick(dbEntry, 'id', 'connectorId', 'syncProfile', 'metadata'),
isDemo,
extraInfo,
// Hide demo connector config
config: isDemo ? {} : config,
...usagePayload,
};
};

View file

@ -20,6 +20,7 @@ export const connectorResponseGuard = Connectors.guard
type: z.nativeEnum(ConnectorType),
isDemo: z.boolean().optional(),
extraInfo: z.record(z.unknown()).optional(),
usage: z.number().optional(),
})
);