0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

refactor: fix build

This commit is contained in:
Gao Sun 2023-01-28 13:05:45 +08:00
parent 54db878760
commit b07252f9b2
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
26 changed files with 109 additions and 31 deletions

View file

@ -76,6 +76,7 @@ export const mockMetadata6: ConnectorMetadata = {
};
export const mockConnector0: Connector = {
tenantId: 'fake_tenant',
id: 'id0',
config: {},
createdAt: 1_234_567_890_123,
@ -85,6 +86,7 @@ export const mockConnector0: Connector = {
};
export const mockConnector1: Connector = {
tenantId: 'fake_tenant',
id: 'id1',
config: {},
createdAt: 1_234_567_890_234,
@ -94,6 +96,7 @@ export const mockConnector1: Connector = {
};
export const mockConnector2: Connector = {
tenantId: 'fake_tenant',
id: 'id2',
config: {},
createdAt: 1_234_567_890_345,
@ -103,6 +106,7 @@ export const mockConnector2: Connector = {
};
export const mockConnector3: Connector = {
tenantId: 'fake_tenant',
id: 'id3',
config: {},
createdAt: 1_234_567_890_456,
@ -112,6 +116,7 @@ export const mockConnector3: Connector = {
};
export const mockConnector4: Connector = {
tenantId: 'fake_tenant',
id: 'id4',
config: {},
createdAt: 1_234_567_890_567,
@ -121,6 +126,7 @@ export const mockConnector4: Connector = {
};
export const mockConnector5: Connector = {
tenantId: 'fake_tenant',
id: 'id5',
config: {},
createdAt: 1_234_567_890_567,
@ -130,6 +136,7 @@ export const mockConnector5: Connector = {
};
export const mockConnector6: Connector = {
tenantId: 'fake_tenant',
id: 'id6',
config: {},
createdAt: 1_234_567_890_567,

View file

@ -36,6 +36,7 @@ export {
const { jest } = import.meta;
export const mockConnector: Connector = {
tenantId: 'fake_tenant',
id: 'id',
config: {},
createdAt: 1_234_567_890_123,
@ -235,6 +236,7 @@ export const socialTarget02 = 'socialTarget-id02';
export const mockSocialConnectors: LogtoConnector[] = [
{
dbEntry: {
tenantId: 'fake_tenant',
id: 'id0',
config: {},
createdAt: 1_234_567_890_123,
@ -251,6 +253,7 @@ export const mockSocialConnectors: LogtoConnector[] = [
},
{
dbEntry: {
tenantId: 'fake_tenant',
id: 'id1',
config: {},
createdAt: 1_234_567_890_123,

View file

@ -1,4 +1,5 @@
import en from '@logto/phrases-ui/lib/locales/en.js';
import { CustomPhrase } from '@logto/schemas';
export const enTag = 'en';
export const trTrTag = 'tr-TR';
@ -6,6 +7,8 @@ export const zhCnTag = 'zh-CN';
export const zhHkTag = 'zh-HK';
export const mockEnCustomPhrase = {
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: enTag,
translation: {
input: {
@ -16,17 +19,21 @@ export const mockEnCustomPhrase = {
confirm_password: 'Confirm password 5',
},
},
};
} satisfies CustomPhrase;
export const mockEnPhrase = {
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: enTag,
translation: {
...en.translation,
...mockEnCustomPhrase.translation,
},
};
} satisfies CustomPhrase;
export const mockTrTrCustomPhrase = {
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: trTrTag,
translation: {
input: {
@ -37,9 +44,11 @@ export const mockTrTrCustomPhrase = {
confirm_password: 'Şifreyi Doğrula 5',
},
},
};
} satisfies CustomPhrase;
export const mockZhCnCustomPhrase = {
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: zhCnTag,
translation: {
input: {
@ -50,9 +59,11 @@ export const mockZhCnCustomPhrase = {
confirm_password: '确认密码 5',
},
},
};
} satisfies CustomPhrase;
export const mockZhHkCustomPhrase = {
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: zhHkTag,
translation: {
input: {
@ -63,4 +74,4 @@ export const mockZhHkCustomPhrase = {
confirm_password: '確認密碼 5',
},
},
};
} satisfies CustomPhrase;

View file

@ -7,6 +7,7 @@ export * from './sign-in-experience.js';
export * from './user.js';
export const mockApplication: Application = {
tenantId: 'fake_tenant',
id: 'foo',
secret: 'randomId',
name: 'foo',
@ -25,6 +26,7 @@ export const mockApplication: Application = {
};
export const mockResource: Resource = {
tenantId: 'fake_tenant',
id: 'logto_api',
name: 'management api',
indicator: 'logto.dev/api',
@ -32,6 +34,7 @@ export const mockResource: Resource = {
};
export const mockResource2: Resource = {
tenantId: 'fake_tenant',
id: 'logto_api2',
name: 'management api',
indicator: 'logto.dev/api',
@ -39,6 +42,7 @@ export const mockResource2: Resource = {
};
export const mockResource3: Resource = {
tenantId: 'fake_tenant',
id: 'logto_api3',
name: 'management api',
indicator: 'logto.dev/api',
@ -46,6 +50,7 @@ export const mockResource3: Resource = {
};
export const mockScope: Scope = {
tenantId: 'fake_tenant',
id: 'scope_id',
name: 'read:users',
description: 'read users',
@ -54,12 +59,14 @@ export const mockScope: Scope = {
};
export const mockRole: Role = {
tenantId: 'fake_tenant',
id: 'role_id',
name: 'admin',
description: 'admin',
};
export const mockSetting: Setting = {
tenantId: 'fake_tenant',
id: 'foo setting',
adminConsole: {
demoChecked: false,
@ -72,6 +79,7 @@ export const mockSetting: Setting = {
};
export const mockPasscode: Passcode = {
tenantId: 'fake_tenant',
id: 'foo',
interactionJti: 'jti',
phone: '888 888 8888',

View file

@ -45,6 +45,7 @@ export const mockSignIn = {
};
export const mockSignInExperience: SignInExperience = {
tenantId: 'fake_tenant',
id: 'foo',
color: {
primaryColor: '#000',

View file

@ -3,6 +3,7 @@ import { userInfoSelectFields, UsersPasswordEncryptionMethod } from '@logto/sche
import { pick } from '@silverhand/essentials';
export const mockUser: User = {
tenantId: 'fake_tenant',
id: 'foo',
username: 'foo',
primaryEmail: 'foo@logto.io',
@ -25,6 +26,7 @@ export const mockUserResponse = pick(mockUser, ...userInfoSelectFields);
export const mockPasswordEncrypted = 'a1b2c3';
export const mockUserWithPassword: User = {
tenantId: 'fake_tenant',
id: 'id',
username: 'username',
primaryEmail: 'foo@logto.io',
@ -45,6 +47,7 @@ export const mockUserWithPassword: User = {
export const mockUserList: User[] = [
{
tenantId: 'fake_tenant',
id: '1',
username: 'foo1',
primaryEmail: 'foo1@logto.io',
@ -61,6 +64,7 @@ export const mockUserList: User[] = [
isSuspended: false,
},
{
tenantId: 'fake_tenant',
id: '2',
username: 'foo2',
primaryEmail: 'foo2@logto.io',
@ -77,6 +81,7 @@ export const mockUserList: User[] = [
isSuspended: false,
},
{
tenantId: 'fake_tenant',
id: '3',
username: 'foo3',
primaryEmail: 'foo3@logto.io',
@ -93,6 +98,7 @@ export const mockUserList: User[] = [
isSuspended: false,
},
{
tenantId: 'fake_tenant',
id: '4',
username: 'bar1',
primaryEmail: 'bar1@logto.io',
@ -109,6 +115,7 @@ export const mockUserList: User[] = [
isSuspended: false,
},
{
tenantId: 'fake_tenant',
id: '5',
username: 'bar2',
primaryEmail: 'bar2@logto.io',

View file

@ -5,6 +5,7 @@ import { MockQueries } from '#src/test-utils/tenant.js';
const connectors: Connector[] = [
{
tenantId: 'fake_tenant',
id: 'id',
config: { foo: 'bar' },
createdAt: 0,

View file

@ -148,6 +148,7 @@ describe('createPasscode', () => {
describe('sendPasscode', () => {
it('should throw error when email and phone are both empty', async () => {
const passcode: Passcode = {
tenantId: 'fake_tenant',
id: 'id',
interactionJti: 'jti',
phone: null,
@ -181,6 +182,7 @@ describe('sendPasscode', () => {
},
]);
const passcode: Passcode = {
tenantId: 'fake_tenant',
id: 'id',
interactionJti: 'jti',
phone: 'phone',
@ -232,6 +234,7 @@ describe('sendPasscode', () => {
},
]);
const passcode: Passcode = {
tenantId: 'fake_tenant',
id: 'passcode_id',
interactionJti: 'jti',
phone: 'phone',
@ -255,6 +258,7 @@ describe('sendPasscode', () => {
describe('verifyPasscode', () => {
const passcode = {
tenantId: 'fake_tenant',
id: 'id',
interactionJti: 'jti',
phone: 'phone',

View file

@ -1,5 +1,5 @@
import resource from '@logto/phrases-ui';
import type { CustomPhrase } from '@logto/schemas';
import { CustomPhrase } from '@logto/schemas';
import deepmerge from 'deepmerge';
import {
@ -57,6 +57,8 @@ it('should ignore empty string values from the custom phrase', async () => {
confirm_password: 'Confirm password 5',
};
const mockEnCustomPhraseWithEmptyStringValues = {
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: enTag,
translation: {
input: {
@ -66,7 +68,7 @@ it('should ignore empty string values from the custom phrase', async () => {
password: '',
},
},
};
} satisfies CustomPhrase;
findCustomPhraseByLanguageTag.mockResolvedValueOnce(mockEnCustomPhraseWithEmptyStringValues);
await expect(getPhrases(enTag, [enTag])).resolves.toEqual(

View file

@ -1,6 +1,7 @@
import { builtInLanguages } from '@logto/phrases-ui';
import type { Branding, LanguageInfo, SignInExperience } from '@logto/schemas';
import {
defaultTenantId,
SignInMode,
ConnectorType,
BrandingStyle,
@ -73,9 +74,12 @@ export const createSignInExperienceLibrary = (
): Promise<SignInExperience & { notification?: string }> => {
const signInExperience = await findDefaultSignInExperience();
// Hard code AdminConsole sign-in methods settings.
// Hard code Admin Console sign-in methods settings.
if (applicationId === adminConsoleApplicationId) {
return {
// If we need to hard code, it implies Logto is running in the single-tenant mode;
// Thus we can hard code Tenant ID as well.
tenantId: defaultTenantId,
...adminConsoleSignInExperience,
branding: {
...adminConsoleSignInExperience.branding,

View file

@ -1,4 +1,4 @@
import { buildIdGenerator } from '@logto/core-kit';
import { buildIdGenerator, generateStandardId } from '@logto/core-kit';
import type { User, CreateUser, Scope } from '@logto/schemas';
import { Users, UsersPasswordEncryptionMethod, defaultRole } from '@logto/schemas';
import type { OmitAutoSetFields } from '@logto/shared';
@ -95,7 +95,9 @@ export const createUserLibrary = (queries: Queries) => {
const user = await insertUserQuery(data);
if (roles.length > 0) {
await insertUsersRoles(roles.map(({ id }) => ({ userId: user.id, roleId: id })));
await insertUsersRoles(
roles.map(({ id }) => ({ id: generateStandardId(), userId: user.id, roleId: id }))
);
}
return user;

View file

@ -1,4 +1,4 @@
import type { ApplicationsRole } from '@logto/schemas';
import type { ApplicationsRole, CreateApplicationsRole } from '@logto/schemas';
import { ApplicationsRoles, RolesScopes } from '@logto/schemas';
import { convertToIdentifiers } from '@logto/shared';
import type { CommonQueryMethods } from 'slonik';
@ -16,7 +16,7 @@ export const createApplicationsRolesQueries = (pool: CommonQueryMethods) => {
where ${fields.applicationId}=${applicationId}
`);
const insertApplicationsRoles = async (applicationsRoles: ApplicationsRole[]) =>
const insertApplicationsRoles = async (applicationsRoles: CreateApplicationsRole[]) =>
pool.query(sql`
insert into ${table} (${fields.applicationId}, ${fields.roleId}) values
${sql.join(

View file

@ -1,4 +1,4 @@
import type { RolesScope } from '@logto/schemas';
import type { CreateRolesScope, RolesScope } from '@logto/schemas';
import { RolesScopes } from '@logto/schemas';
import { convertToIdentifiers } from '@logto/shared';
import type { CommonQueryMethods } from 'slonik';
@ -9,7 +9,7 @@ import { DeletionError } from '#src/errors/SlonikError/index.js';
const { table, fields } = convertToIdentifiers(RolesScopes);
export const createRolesScopesQueries = (pool: CommonQueryMethods) => {
const insertRolesScopes = async (rolesScopes: RolesScope[]) =>
const insertRolesScopes = async (rolesScopes: CreateRolesScope[]) =>
pool.query(sql`
insert into ${table} (${fields.scopeId}, ${fields.roleId}) values
${sql.join(

View file

@ -99,7 +99,7 @@ export const createRolesQueries = (pool: CommonQueryMethods) => {
${conditionalSql(excludeRoleId, (id) => sql`and ${fields.id}<>${id}`)}
`);
const insertRoles = async (roles: Role[]) =>
const insertRoles = async (roles: CreateRole[]) =>
pool.query(sql`
insert into ${table} (${fields.id}, ${fields.name}, ${fields.description}) values
${sql.join(

View file

@ -1,4 +1,4 @@
import type { UsersRole } from '@logto/schemas';
import type { CreateUsersRole, UsersRole } from '@logto/schemas';
import { RolesScopes, UsersRoles } from '@logto/schemas';
import { conditionalSql, convertToIdentifiers } from '@logto/shared';
import type { CommonQueryMethods } from 'slonik';
@ -42,7 +42,7 @@ export const createUsersRolesQueries = (pool: CommonQueryMethods) => {
${conditionalSql(limit, (value) => sql`limit ${value}`)}
`);
const insertUsersRoles = async (usersRoles: UsersRole[]) =>
const insertUsersRoles = async (usersRoles: CreateUsersRole[]) =>
pool.query(sql`
insert into ${table} (${fields.userId}, ${fields.roleId}) values
${sql.join(

View file

@ -1,3 +1,4 @@
import { generateStandardId } from '@logto/core-kit';
import { tryThat } from '@logto/shared';
import { object, string } from 'zod';
@ -89,7 +90,9 @@ export default function adminUserRoleRoutes<T extends AuthedRouter>(
}
await Promise.all(roleIds.map(async (roleId) => findRoleById(roleId)));
await insertUsersRoles(roleIds.map((roleId) => ({ userId, roleId })));
await insertUsersRoles(
roleIds.map((roleId) => ({ id: generateStandardId(), userId, roleId }))
);
ctx.status = 201;
return next();

View file

@ -67,7 +67,9 @@ const mockedQueries = {
},
roles: {
findRolesByRoleNames: jest.fn(
async (): Promise<Role[]> => [{ id: 'role_id', name: 'admin', description: 'none' }]
async (): Promise<Role[]> => [
{ tenantId: 'fake_tenant', id: 'role_id', name: 'admin', description: 'none' },
]
),
},
usersRoles: {

View file

@ -112,7 +112,9 @@ export default function applicationRoutes<T extends AuthedRouter>(
);
if (isAdmin && !originalIsAdmin) {
await insertApplicationsRoles([{ applicationId: id, roleId: adminConsoleAdminRoleId }]);
await insertApplicationsRoles([
{ id: generateStandardId(), applicationId: id, roleId: adminConsoleAdminRoleId },
]);
} else if (!isAdmin && originalIsAdmin) {
await deleteApplicationRole(id, adminConsoleAdminRoleId);
}

View file

@ -1,5 +1,6 @@
import en from '@logto/phrases-ui/lib/locales/en.js';
import type { CustomPhrase, SignInExperience } from '@logto/schemas';
import { CustomPhrase } from '@logto/schemas';
import type { SignInExperience } from '@logto/schemas';
import { pickDefault, createMockUtils } from '@logto/shared/esm';
import { mockZhCnCustomPhrase, trTrTag, zhCnTag } from '#src/__mocks__/custom-phrase.js';
@ -78,11 +79,13 @@ describe('customPhraseRoutes', () => {
it('should return all custom phrases', async () => {
const mockCustomPhrase = {
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: 'zh-HK',
translation: {
input: { username: '用戶名', password: '密碼' },
},
};
} satisfies CustomPhrase;
findAllCustomPhrases.mockImplementationOnce(async () => [mockCustomPhrase]);
const response = await customPhraseRequest.get('/custom-phrases');
expect(response.status).toEqual(200);

View file

@ -1,3 +1,4 @@
import { generateStandardId } from '@logto/core-kit';
import { languageTagGuard } from '@logto/language-kit';
import resource from '@logto/phrases-ui';
import type { Translation } from '@logto/schemas';
@ -79,7 +80,7 @@ export default function customPhraseRoutes<T extends AuthedRouter>(
new RequestError('localization.invalid_translation_structure')
);
ctx.body = await upsertCustomPhrase({ languageTag, translation });
ctx.body = await upsertCustomPhrase({ id: generateStandardId(), languageTag, translation });
return next();
}

View file

@ -8,7 +8,7 @@ import { createRequester } from '#src/utils/test-utils.js';
const { jest } = import.meta;
const mockBody = { key: 'a', payload: { key: 'a', result: LogResult.Success }, createdAt: 123 };
const mockLog: Log = { id: '1', ...mockBody };
const mockLog: Log = { tenantId: 'fake_tenant', id: '1', ...mockBody };
const mockLogs = [mockLog, { id: '2', ...mockBody }];
const logs = {

View file

@ -32,7 +32,12 @@ const { default: detectLanguageSpy } = mockEsm('#src/i18n/detect-language.js', (
const customPhrases = {
findAllCustomLanguageTags: jest.fn(async () => [customizedLanguage]),
findCustomPhraseByLanguageTag: jest.fn(
async (tag: string): Promise<CustomPhrase> => ({ languageTag: tag, translation: {} })
async (tag: string): Promise<CustomPhrase> => ({
tenantId: 'fake_tenant',
id: 'fake_id',
languageTag: tag,
translation: {},
})
),
} satisfies Partial<Queries['customPhrases']>;
const { findAllCustomLanguageTags } = customPhrases;

View file

@ -1,3 +1,4 @@
import { generateStandardId } from '@logto/core-kit';
import type { ScopeResponse } from '@logto/schemas';
import { tryThat } from '@logto/shared';
import { object, string } from 'zod';
@ -110,7 +111,9 @@ export default function roleScopeRoutes<T extends AuthedRouter>(
}
await Promise.all(scopeIds.map(async (scopeId) => findScopeById(scopeId)));
await insertRolesScopes(scopeIds.map((scopeId) => ({ roleId: id, scopeId })));
await insertRolesScopes(
scopeIds.map((scopeId) => ({ id: generateStandardId(), roleId: id, scopeId }))
);
const newRolesScopes = await findRolesScopesByRoleId(id);
const scopes = await findScopesByIds(newRolesScopes.map(({ scopeId }) => scopeId));

View file

@ -1,4 +1,4 @@
import { buildIdGenerator } from '@logto/core-kit';
import { buildIdGenerator, generateStandardId } from '@logto/core-kit';
import type { RoleResponse } from '@logto/schemas';
import { userInfoSelectFields, Roles } from '@logto/schemas';
import { tryThat } from '@logto/shared';
@ -113,7 +113,9 @@ export default function roleRoutes<T extends AuthedRouter>(
if (scopeIds) {
await Promise.all(scopeIds.map(async (scopeId) => findScopeById(scopeId)));
await insertRolesScopes(scopeIds.map((scopeId) => ({ roleId: role.id, scopeId })));
await insertRolesScopes(
scopeIds.map((scopeId) => ({ id: generateStandardId(), roleId: role.id, scopeId }))
);
}
ctx.body = role;
@ -250,7 +252,9 @@ export default function roleRoutes<T extends AuthedRouter>(
}
await Promise.all(userIds.map(async (userId) => findUserById(userId)));
await insertUsersRoles(userIds.map((userId) => ({ roleId: id, userId })));
await insertUsersRoles(
userIds.map((userId) => ({ id: generateStandardId(), roleId: id, userId }))
);
ctx.status = 201;
return next();

View file

@ -6,6 +6,9 @@ import pluralize from 'pluralize';
import type { TableWithType } from './types.js';
// Tenant ID should be optional for create types since it'll be generated by the database trigger
const tenantId = 'tenant_id';
export const generateSchema = ({ name, fields }: TableWithType) => {
const modelName = pluralize(camelcase(name, { pascalCase: true }), 1);
const databaseEntryType = `Create${modelName}`;
@ -15,7 +18,7 @@ export const generateSchema = ({ name, fields }: TableWithType) => {
...fields.map(
({ name, type, isArray, nullable, hasDefaultValue }) =>
` ${camelcase(name)}${conditionalString(
(nullable || hasDefaultValue) && '?'
(nullable || hasDefaultValue || name === tenantId) && '?'
)}: ${type}${conditionalString(isArray && '[]')}${conditionalString(
nullable && !hasDefaultValue && ' | null'
)};`
@ -47,7 +50,7 @@ export const generateSchema = ({ name, fields }: TableWithType) => {
}${conditionalString(isString && maxLength && `.max(${maxLength})`)}${conditionalString(
isArray && '.array()'
)}${conditionalString(nullable && '.nullable()')}${conditionalString(
(nullable || hasDefaultValue) && '.optional()'
(nullable || hasDefaultValue || name === tenantId) && '.optional()'
)},`;
}
),

View file

@ -181,6 +181,7 @@ export const usernameSignInMethod = {
};
export const mockSignInExperience: SignInExperience = {
tenantId: 'default',
id: 'foo',
color: {
primaryColor: '#000',
@ -210,6 +211,7 @@ export const mockSignInExperience: SignInExperience = {
};
export const mockSignInExperienceSettings: SignInExperienceResponse = {
tenantId: 'default',
id: mockSignInExperience.id,
color: mockSignInExperience.color,
branding: mockSignInExperience.branding,