mirror of
https://github.com/logto-io/logto.git
synced 2024-12-23 20:33:16 -05:00
76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
|
import { sql } from 'slonik';
|
||
|
|
||
|
import type { AlterationScript } from '../lib/types/alteration.js';
|
||
|
|
||
|
const alteration: AlterationScript = {
|
||
|
up: async (pool) => {
|
||
|
await pool.query(sql`
|
||
|
create table applications_roles (
|
||
|
application_id varchar(21) not null references applications (id) on update cascade on delete cascade,
|
||
|
role_id varchar(21) not null references roles (id) on update cascade on delete cascade,
|
||
|
primary key (application_id, role_id)
|
||
|
);
|
||
|
`);
|
||
|
const applications = await pool.any<{ id: string; roleNames: string[] }>(sql`
|
||
|
select * from applications where jsonb_array_length(role_names) > 0
|
||
|
`);
|
||
|
const roles = await pool.any<{ id: string; name: string }>(sql`
|
||
|
select * from roles
|
||
|
`);
|
||
|
|
||
|
for (const application of applications) {
|
||
|
for (const roleName of application.roleNames) {
|
||
|
if (!roleName) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
const role = roles.find(({ name }) => name === roleName);
|
||
|
|
||
|
if (!role) {
|
||
|
throw new Error(`Unable to find role: ${roleName}`);
|
||
|
}
|
||
|
|
||
|
// eslint-disable-next-line no-await-in-loop
|
||
|
await pool.query(sql`
|
||
|
insert into applications_roles (application_id, role_id) values (${application.id}, ${role.id})
|
||
|
`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
await pool.query(sql`
|
||
|
alter table applications drop column role_names
|
||
|
`);
|
||
|
},
|
||
|
down: async (pool) => {
|
||
|
await pool.query(sql`
|
||
|
alter table applications add column role_names jsonb not null default '[]'::jsonb
|
||
|
`);
|
||
|
|
||
|
const relations = await pool.any<{ applicationId: string; roleId: string }>(sql`
|
||
|
select * from applications_roles
|
||
|
`);
|
||
|
const roles = await pool.any<{ id: string; name: string }>(sql`
|
||
|
select * from roles
|
||
|
`);
|
||
|
|
||
|
for (const relation of relations) {
|
||
|
const role = roles.find(({ id }) => id === relation.roleId);
|
||
|
|
||
|
if (!role) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// eslint-disable-next-line no-await-in-loop
|
||
|
await pool.query(sql`
|
||
|
update applications set role_names = role_names || '[${role.name}]'::jsonb where id = ${relation.applicationId}
|
||
|
`);
|
||
|
}
|
||
|
|
||
|
await pool.query(sql`
|
||
|
drop table applications_roles;
|
||
|
`);
|
||
|
},
|
||
|
};
|
||
|
|
||
|
export default alteration;
|