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

fix(core): resolve some core no-restricted-syntax lint error (#1606)

* fix(core): resolve some core no-restricted-syntax lint error

resolve some core no-restricted-syntax lint error

* fix(core): cr fix
This commit is contained in:
simeng-li 2022-07-20 18:28:48 +08:00 committed by GitHub
parent 28b2861de8
commit c56ddec84a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 68 additions and 55 deletions

View file

@ -115,8 +115,7 @@
"eslintConfig": { "eslintConfig": {
"extends": "@silverhand", "extends": "@silverhand",
"rules": { "rules": {
"complexity": "off", "complexity": "off"
"no-restricted-syntax": "off"
} }
}, },
"prettier": "@silverhand/eslint-config/.prettierrc" "prettier": "@silverhand/eslint-config/.prettierrc"

View file

@ -1,7 +1,7 @@
import { SchemaValuePrimitive, SchemaValue } from '@logto/schemas'; import { SchemaValuePrimitive, SchemaValue } from '@logto/schemas';
import { Falsy, notFalsy } from '@silverhand/essentials'; import { Falsy, notFalsy } from '@silverhand/essentials';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { sql, SqlSqlToken, SqlToken, QueryResult } from 'slonik'; import { sql, SqlSqlToken, SqlToken, QueryResult, IdentifierSqlToken } from 'slonik';
import { FieldIdentifiers, Table } from './types'; import { FieldIdentifiers, Table } from './types';
@ -15,6 +15,8 @@ export const excludeAutoSetFields = <T extends string>(fields: readonly T[]) =>
Object.freeze( Object.freeze(
fields.filter( fields.filter(
(field): field is ExcludeAutoSetFields<T> => (field): field is ExcludeAutoSetFields<T> =>
// Read only string arrays
// eslint-disable-next-line no-restricted-syntax
!(autoSetFields as readonly string[]).includes(field) !(autoSetFields as readonly string[]).includes(field)
) )
); );
@ -52,20 +54,18 @@ export const convertToPrimitiveOrSql = (
throw new Error(`Cannot convert ${key} to primitive`); throw new Error(`Cannot convert ${key} to primitive`);
}; };
export const convertToIdentifiers = <T extends Table>( export const convertToIdentifiers = <T extends Table>({ table, fields }: T, withPrefix = false) => {
{ table, fields }: T, const fieldsIdentifiers = Object.entries<string>(fields).map<
withPrefix = false [keyof T['fields'], IdentifierSqlToken]
) => ({ >(([key, value]) => [key, sql.identifier(withPrefix ? [table, value] : [value])]);
return {
table: sql.identifier([table]), table: sql.identifier([table]),
fields: Object.entries<string>(fields).reduce( // Key value inferred from the original fields directly
(previous, [key, value]) => ({ // eslint-disable-next-line no-restricted-syntax
...previous, fields: Object.fromEntries(fieldsIdentifiers) as FieldIdentifiers<keyof T['fields']>,
[key]: sql.identifier(withPrefix ? [table, value] : [value]), };
}), };
// eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter
{} as FieldIdentifiers<keyof T['fields']>
),
});
export const convertToTimestamp = (time = dayjs()) => sql`to_timestamp(${time.valueOf() / 1000})`; export const convertToTimestamp = (time = dayjs()) => sql`to_timestamp(${time.valueOf() / 1000})`;

View file

@ -47,14 +47,16 @@ const mockedIncreasePasscodeTryCount = increasePasscodeTryCount as jest.MockedFu
beforeAll(() => { beforeAll(() => {
mockedFindUnconsumedPasscodesByJtiAndType.mockResolvedValue([]); mockedFindUnconsumedPasscodesByJtiAndType.mockResolvedValue([]);
mockedInsertPasscode.mockImplementation(async (data) => ({ mockedInsertPasscode.mockImplementation(async (data): Promise<Passcode> => {
return {
phone: null,
email: null,
consumed: false,
tryCount: 0,
...data, ...data,
createdAt: Date.now(), createdAt: Date.now(),
phone: data.phone ?? null, };
email: data.email ?? null, });
consumed: data.consumed ?? false,
tryCount: data.tryCount ?? 0,
}));
}); });
afterEach(() => { afterEach(() => {

View file

@ -81,7 +81,7 @@ export default function koaGuard<
WithGuardedRequestContext<ContextT, GuardQueryT, GuardBodyT, GuardParametersT>, WithGuardedRequestContext<ContextT, GuardQueryT, GuardBodyT, GuardParametersT>,
GuardResponseT GuardResponseT
> = async (ctx, next) => { > = async (ctx, next) => {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, no-restricted-syntax
ctx.guard = { ctx.guard = {
query: tryParse('query', query, ctx.request.query), query: tryParse('query', query, ctx.request.query),
body: tryParse('body', body, ctx.request.body), body: tryParse('body', body, ctx.request.body),

View file

@ -22,6 +22,7 @@ export default function koaI18next<
return async (ctx, next) => { return async (ctx, next) => {
const languages = detectLanguage(ctx); const languages = detectLanguage(ctx);
// Cannot patch type def directly, see https://github.com/microsoft/TypeScript/issues/36146 // Cannot patch type def directly, see https://github.com/microsoft/TypeScript/issues/36146
// eslint-disable-next-line no-restricted-syntax
const languageUtils = i18next.services.languageUtils as LanguageUtils; const languageUtils = i18next.services.languageUtils as LanguageUtils;
const foundLanguage = languages const foundLanguage = languages
.map((code) => languageUtils.formatLanguageCode(code)) .map((code) => languageUtils.formatLanguageCode(code))

View file

@ -45,6 +45,8 @@ export default function koaOIDCErrorHandler<StateT, ContextT>(): Middleware<Stat
case errors.InvalidGrant: case errors.InvalidGrant:
throw new RequestError( throw new RequestError(
{ {
// Manually mapped all OIDC error name to the LogtoErrorCode
// eslint-disable-next-line no-restricted-syntax
code: `oidc.${decamelize(name)}` as LogtoErrorCode, code: `oidc.${decamelize(name)}` as LogtoErrorCode,
status, status,
expose, expose,

View file

@ -35,26 +35,32 @@ export default function koaSlonikErrorHandler<StateT, ContextT>(): Middleware<St
throw error; throw error;
} }
switch (error.constructor) { if (error instanceof InsertionError) {
case InsertionError:
throw new RequestError({ throw new RequestError({
code: 'entity.create_failed', code: 'entity.create_failed',
// Assert generic type of the Class instance
// eslint-disable-next-line no-restricted-syntax
name: (error as InsertionError<SchemaLike>).schema.tableSingular, name: (error as InsertionError<SchemaLike>).schema.tableSingular,
}); });
case UpdateError: }
if (error instanceof UpdateError) {
throw new RequestError({ throw new RequestError({
code: 'entity.not_exists', code: 'entity.not_exists',
name: (error as InsertionError<SchemaLike>).schema.tableSingular, // Assert generic type of the Class instance
// eslint-disable-next-line no-restricted-syntax
name: (error as UpdateError<SchemaLike>).schema.tableSingular,
}); });
case DeletionError: }
case NotFoundError:
if (error instanceof DeletionError || error instanceof NotFoundError) {
throw new RequestError({ throw new RequestError({
code: 'entity.not_found', code: 'entity.not_found',
status: 404, status: 404,
}); });
default:
throw error;
} }
throw error;
} }
}; };
} }

View file

@ -123,6 +123,7 @@ export default function swaggerRoutes<T extends AnonymousRouter, R extends Route
) { ) {
router.get('/swagger.json', async (ctx, next) => { router.get('/swagger.json', async (ctx, next) => {
// Use `as` here since we'll check typing with integration tests // Use `as` here since we'll check typing with integration tests
// eslint-disable-next-line no-restricted-syntax
const additionalSwagger = load( const additionalSwagger = load(
await readFile('static/yaml/additional-swagger.yaml', { encoding: 'utf-8' }) await readFile('static/yaml/additional-swagger.yaml', { encoding: 'utf-8' })
) as OpenAPIV3.Document; ) as OpenAPIV3.Document;
@ -130,11 +131,11 @@ export default function swaggerRoutes<T extends AnonymousRouter, R extends Route
const routes = allRouters.flatMap<RouteObject>((router) => const routes = allRouters.flatMap<RouteObject>((router) =>
router.stack.flatMap<RouteObject>(({ path: routerPath, stack, methods }) => router.stack.flatMap<RouteObject>(({ path: routerPath, stack, methods }) =>
methods methods
.map((method) => method.toLowerCase())
// There is no need to show the HEAD method. // There is no need to show the HEAD method.
.filter((method) => method !== 'HEAD') .filter((method): method is OpenAPIV3.HttpMethods => method !== 'head')
.map((method) => { .map((httpMethod) => {
const path = `/api${routerPath}`; const path = `/api${routerPath}`;
const httpMethod = method.toLowerCase() as OpenAPIV3.HttpMethods;
const additionalPathItem = additionalSwagger.paths[path] ?? {}; const additionalPathItem = additionalSwagger.paths[path] ?? {};
const additionalResponses = additionalPathItem[httpMethod]?.responses; const additionalResponses = additionalPathItem[httpMethod]?.responses;

View file

@ -29,11 +29,10 @@ interface GrantBody {
} }
const getLogType = (grantType: unknown) => { const getLogType = (grantType: unknown) => {
if ( const allowedGrantType = new Set<unknown>([GrantType.AuthorizationCode, GrantType.RefreshToken]);
!grantType ||
![GrantType.AuthorizationCode, GrantType.RefreshToken].includes(grantType as GrantType)
) {
// Only log token exchange by authorization code or refresh token. // Only log token exchange by authorization code or refresh token.
if (!grantType || !allowedGrantType.has(grantType)) {
return; return;
} }

View file

@ -128,6 +128,8 @@ export function createRequester({
if (provider) { if (provider) {
route(anonymousRouter, provider); route(anonymousRouter, provider);
} else { } else {
// For test use only
// eslint-disable-next-line no-restricted-syntax
(route as RouteLauncher<AnonymousRouter>)(anonymousRouter); (route as RouteLauncher<AnonymousRouter>)(anonymousRouter);
} }
} }

View file

@ -12,7 +12,6 @@ import {
ZodOptional, ZodOptional,
ZodString, ZodString,
ZodStringDef, ZodStringDef,
ZodType,
ZodUnion, ZodUnion,
ZodUnknown, ZodUnknown,
} from 'zod'; } from 'zod';
@ -129,7 +128,9 @@ export const zodTypeToSwagger = (config: unknown): OpenAPIV3.SchemaObject => {
if (config instanceof ZodUnion) { if (config instanceof ZodUnion) {
return { return {
oneOf: (config.options as ZodType[]).map((option) => zodTypeToSwagger(option)), // ZodUnion.options type is any
// eslint-disable-next-line no-restricted-syntax
oneOf: (config.options as unknown[]).map((option) => zodTypeToSwagger(option)),
}; };
} }