Compare commits
13 Commits
refactor/t
...
feat/seed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54a7e73981 | ||
|
|
2a3dce6621 | ||
|
|
260f526edc | ||
|
|
20b9b94b53 | ||
|
|
391e5a20f5 | ||
|
|
4b8f3bd8da | ||
|
|
94248076e6 | ||
|
|
eecc3db4e9 | ||
|
|
426e7594f4 | ||
|
|
934dc473f0 | ||
|
|
be57255bf7 | ||
|
|
f89561da54 | ||
|
|
c2c4e620c2 |
@@ -38,7 +38,7 @@
|
|||||||
},
|
},
|
||||||
"packageExtensions": {
|
"packageExtensions": {
|
||||||
"httpsnippet@3.0.1": {
|
"httpsnippet@3.0.1": {
|
||||||
"peerDependencies": {
|
"dependencies": {
|
||||||
"ajv": "6.12.3"
|
"ajv": "6.12.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
"collection": "@nestjs/schematics",
|
"collection": "@nestjs/schematics",
|
||||||
"sourceRoot": "src",
|
"sourceRoot": "src",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"assets": [
|
"assets": [{ "include": "mailer/templates/**/*", "outDir": "dist" }],
|
||||||
"**/*.hbs"
|
|
||||||
],
|
|
||||||
"watchAssets": true
|
"watchAssets": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "hoppscotch-backend",
|
"name": "hoppscotch-backend",
|
||||||
"version": "2024.3.1",
|
"version": "2024.3.3",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
|
"prisma": {
|
||||||
|
"seed": "ts-node prisma/seed.ts"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prebuild": "rimraf dist",
|
"prebuild": "rimraf dist",
|
||||||
"build": "nest build",
|
"build": "nest build",
|
||||||
@@ -66,6 +69,7 @@
|
|||||||
"rxjs": "7.6.0"
|
"rxjs": "7.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@faker-js/faker": "8.4.1",
|
||||||
"@nestjs/cli": "10.2.1",
|
"@nestjs/cli": "10.2.1",
|
||||||
"@nestjs/schematics": "10.0.3",
|
"@nestjs/schematics": "10.0.3",
|
||||||
"@nestjs/testing": "10.2.7",
|
"@nestjs/testing": "10.2.7",
|
||||||
|
|||||||
444
packages/hoppscotch-backend/prisma/seed.ts
Normal file
444
packages/hoppscotch-backend/prisma/seed.ts
Normal file
@@ -0,0 +1,444 @@
|
|||||||
|
import { faker } from '@faker-js/faker';
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
const createUsersAndAccounts = async (
|
||||||
|
entries = 10,
|
||||||
|
withDedicateUsers: { email: string; isAdmin: boolean }[] = [],
|
||||||
|
) => {
|
||||||
|
const createAUser = async (email?, isAdmin?) => {
|
||||||
|
try {
|
||||||
|
const newUser = await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
displayName: faker.person.fullName(),
|
||||||
|
email: email ?? faker.internet.email().toLowerCase(),
|
||||||
|
photoURL: faker.image.avatar(),
|
||||||
|
isAdmin: isAdmin ?? false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await prisma.account.create({
|
||||||
|
data: {
|
||||||
|
userId: newUser.uid,
|
||||||
|
provider: 'magic',
|
||||||
|
providerAccountId: newUser.email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating user/account:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < withDedicateUsers.length; i++) {
|
||||||
|
const user = withDedicateUsers[i];
|
||||||
|
await createAUser(user.email.toLowerCase(), user.isAdmin);
|
||||||
|
}
|
||||||
|
for (let i = 0; i < entries - withDedicateUsers.length; i++) {
|
||||||
|
await createAUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Users created');
|
||||||
|
};
|
||||||
|
|
||||||
|
const createInvitedUsers = async (entries = 10) => {
|
||||||
|
try {
|
||||||
|
const admin = await prisma.user.findFirst({ where: { isAdmin: true } });
|
||||||
|
|
||||||
|
for (let i = 0; i < entries; i++) {
|
||||||
|
await prisma.invitedUsers.create({
|
||||||
|
data: {
|
||||||
|
adminUid: admin.uid,
|
||||||
|
adminEmail: admin.email,
|
||||||
|
inviteeEmail: faker.internet.email().toLowerCase(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Invited users created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating invited users:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createUserCollections = async (
|
||||||
|
parentCollEntries = 10,
|
||||||
|
childCollEntriesOnEachParent = 10,
|
||||||
|
) => {
|
||||||
|
const createACollection = async (userUid, parentID, orderIndex) => {
|
||||||
|
return prisma.userCollection.create({
|
||||||
|
data: {
|
||||||
|
parentID,
|
||||||
|
title: faker.vehicle.vehicle(),
|
||||||
|
orderIndex,
|
||||||
|
type: 'REST',
|
||||||
|
userUid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const users = await prisma.user.findMany();
|
||||||
|
|
||||||
|
for (let u = 0; u < users.length; u++) {
|
||||||
|
const user = users[u];
|
||||||
|
|
||||||
|
for (let i = 0; i < parentCollEntries; i++) {
|
||||||
|
const parentCollection = await createACollection(user.uid, null, i + 1);
|
||||||
|
|
||||||
|
for (let j = 0; j < childCollEntriesOnEachParent; j++) {
|
||||||
|
await createACollection(user.uid, parentCollection.id, j + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('User collections created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating user collections:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createUserRequests = async (entriesPerCollection = 10) => {
|
||||||
|
try {
|
||||||
|
const collections = await prisma.userCollection.findMany();
|
||||||
|
|
||||||
|
for (let i = 0; i < collections.length; i++) {
|
||||||
|
const collection = collections[i];
|
||||||
|
|
||||||
|
for (let j = 0; j < entriesPerCollection; j++) {
|
||||||
|
const requestTitle = faker.git.branch();
|
||||||
|
|
||||||
|
await prisma.userRequest.create({
|
||||||
|
data: {
|
||||||
|
collectionID: collection.id,
|
||||||
|
userUid: collection.userUid,
|
||||||
|
title: requestTitle,
|
||||||
|
request: {
|
||||||
|
v: '4',
|
||||||
|
auth: { authType: 'inherit', authActive: true },
|
||||||
|
body: { body: null, contentType: null },
|
||||||
|
name: requestTitle,
|
||||||
|
method: 'GET',
|
||||||
|
params: [],
|
||||||
|
headers: [],
|
||||||
|
endpoint: 'https://echo.hoppscotch.io',
|
||||||
|
testScript: '',
|
||||||
|
preRequestScript: '',
|
||||||
|
requestVariables: [],
|
||||||
|
},
|
||||||
|
type: collection.type,
|
||||||
|
orderIndex: j + 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('User requests created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating user requests:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createUserEnvironments = async () => {
|
||||||
|
try {
|
||||||
|
const users = await prisma.user.findMany();
|
||||||
|
|
||||||
|
for (let i = 0; i < users.length; i++) {
|
||||||
|
const user = users[i];
|
||||||
|
|
||||||
|
const environments = await prisma.userEnvironment.findMany({
|
||||||
|
where: { userUid: user.uid },
|
||||||
|
});
|
||||||
|
if (environments.length > 1) continue; // skip if already created. (assuming default GLOBAL environments are created by APP itself)
|
||||||
|
|
||||||
|
await prisma.userEnvironment.createMany({
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
userUid: user.uid,
|
||||||
|
name: 'production',
|
||||||
|
variables: [
|
||||||
|
{
|
||||||
|
key: 'product_id',
|
||||||
|
value: faker.number.int({ max: 1000 }),
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isGlobal: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userUid: user.uid,
|
||||||
|
name: 'development',
|
||||||
|
variables: [
|
||||||
|
{
|
||||||
|
key: 'product_id',
|
||||||
|
value: faker.number.int({ max: 1000 }),
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isGlobal: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('User environments created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating user environment:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createTeamsAndTeamMembers = async (
|
||||||
|
entries = 10,
|
||||||
|
memberCountInATeam = 4,
|
||||||
|
) => {
|
||||||
|
const createATeam = async (ownerUid) => {
|
||||||
|
return prisma.team.create({
|
||||||
|
data: {
|
||||||
|
name: faker.airline.airplane().name,
|
||||||
|
members: { create: { userUid: ownerUid, role: 'OWNER' } },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const createATeamMember = async (teamID, userUid) => {
|
||||||
|
try {
|
||||||
|
return prisma.teamMember.create({
|
||||||
|
data: {
|
||||||
|
teamID,
|
||||||
|
userUid,
|
||||||
|
role: +faker.number.binary() === 1 ? 'EDITOR' : 'VIEWER',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const users = await prisma.user.findMany();
|
||||||
|
|
||||||
|
for (let i = 0; i < entries; i++) {
|
||||||
|
const ownerIndex = faker.number.int({ min: 0, max: users.length - 1 });
|
||||||
|
const team = await createATeam(users[ownerIndex].uid); // create a team with owner
|
||||||
|
|
||||||
|
for (let j = 0; j < Math.min(memberCountInATeam, users.length) - 1; ) {
|
||||||
|
const memberIndex = faker.number.int({ min: 0, max: users.length - 1 });
|
||||||
|
|
||||||
|
// check if user already added
|
||||||
|
const existingTeamMember = await prisma.teamMember.findFirst({
|
||||||
|
where: {
|
||||||
|
teamID: team.id,
|
||||||
|
userUid: users[memberIndex].uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (existingTeamMember) continue;
|
||||||
|
|
||||||
|
await createATeamMember(team.id, users[memberIndex].uid);
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Teams and TeamMembers created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating teams and team members:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createTeamEnvironments = async () => {
|
||||||
|
try {
|
||||||
|
const teams = await prisma.team.findMany();
|
||||||
|
|
||||||
|
for (let i = 0; i < teams.length; i++) {
|
||||||
|
const team = teams[i];
|
||||||
|
|
||||||
|
const environments = await prisma.teamEnvironment.findMany({
|
||||||
|
where: { teamID: team.id },
|
||||||
|
});
|
||||||
|
if (environments.length > 1) continue; // skip if already created. (assuming default GLOBAL environments are created by APP itself)
|
||||||
|
|
||||||
|
await prisma.teamEnvironment.createMany({
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
teamID: team.id,
|
||||||
|
name: 'team_env_production',
|
||||||
|
variables: [
|
||||||
|
{
|
||||||
|
key: 'category_id',
|
||||||
|
value: faker.number.int({ max: 1000 }).toString(),
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
teamID: team.id,
|
||||||
|
name: 'team_env_development',
|
||||||
|
variables: [
|
||||||
|
{
|
||||||
|
key: 'category_id',
|
||||||
|
value: faker.number.int({ max: 1000 }).toString(),
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Team environments created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating team environments: ', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createTeamCollections = async (
|
||||||
|
parentCollEntries = 10,
|
||||||
|
childCollEntriesOnEachParent = 10,
|
||||||
|
) => {
|
||||||
|
const createACollection = async (teamID, parentID, orderIndex) => {
|
||||||
|
return prisma.teamCollection.create({
|
||||||
|
data: { parentID, title: faker.vehicle.vehicle(), orderIndex, teamID },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const teams = await prisma.team.findMany();
|
||||||
|
|
||||||
|
for (let t = 0; t < teams.length; t++) {
|
||||||
|
const team = teams[t];
|
||||||
|
|
||||||
|
for (let i = 0; i < parentCollEntries; i++) {
|
||||||
|
const parentCollection = await createACollection(team.id, null, i + 1);
|
||||||
|
|
||||||
|
for (let j = 0; j < childCollEntriesOnEachParent; j++) {
|
||||||
|
await createACollection(team.id, parentCollection.id, j + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Team collections created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating team collection:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const createTeamRequests = async (entriesPerCollection = 10) => {
|
||||||
|
try {
|
||||||
|
const collections = await prisma.teamCollection.findMany();
|
||||||
|
|
||||||
|
for (let i = 0; i < collections.length; i++) {
|
||||||
|
const collection = collections[i];
|
||||||
|
|
||||||
|
for (let j = 0; j < entriesPerCollection; j++) {
|
||||||
|
const requestTitle = faker.git.branch();
|
||||||
|
await prisma.teamRequest.create({
|
||||||
|
data: {
|
||||||
|
collectionID: collection.id,
|
||||||
|
teamID: collection.teamID,
|
||||||
|
title: requestTitle,
|
||||||
|
request: {
|
||||||
|
v: '4',
|
||||||
|
auth: { authType: 'inherit', authActive: true },
|
||||||
|
body: { body: null, contentType: null },
|
||||||
|
name: requestTitle,
|
||||||
|
method: 'GET',
|
||||||
|
params: [],
|
||||||
|
headers: [],
|
||||||
|
endpoint: 'https://echo.hoppscotch.io',
|
||||||
|
testScript: '',
|
||||||
|
preRequestScript: '',
|
||||||
|
requestVariables: [],
|
||||||
|
},
|
||||||
|
orderIndex: j + 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Team requests created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating team requests:', e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function createShortcodes(entriesPerUser = 2) {
|
||||||
|
try {
|
||||||
|
const users = await prisma.user.findMany();
|
||||||
|
|
||||||
|
for (let i = 0; i < users.length; i++) {
|
||||||
|
const user = users[i];
|
||||||
|
|
||||||
|
for (let j = 0; j < entriesPerUser; j++) {
|
||||||
|
const userRequests = await prisma.userRequest.findMany({
|
||||||
|
where: { userUid: user.uid },
|
||||||
|
take: entriesPerUser,
|
||||||
|
});
|
||||||
|
|
||||||
|
let shortCodeRequestObj = {
|
||||||
|
v: '4',
|
||||||
|
id: userRequests[j].id,
|
||||||
|
auth: { authType: 'inherit', authActive: true },
|
||||||
|
body: { body: null, contentType: null },
|
||||||
|
name: 'driver-hack',
|
||||||
|
method: 'GET',
|
||||||
|
params: [],
|
||||||
|
headers: [],
|
||||||
|
endpoint: 'https://echo.hoppscotch.io',
|
||||||
|
testScript: '',
|
||||||
|
preRequestScript: '',
|
||||||
|
requestVariables: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
await prisma.shortcode.create({
|
||||||
|
data: {
|
||||||
|
id: faker.string.alphanumeric(12),
|
||||||
|
creatorUid: user.uid,
|
||||||
|
request: shortCodeRequestObj,
|
||||||
|
embedProperties: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Shortcodes created');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error creating shortcodes:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clearAllData() {
|
||||||
|
try {
|
||||||
|
// Get all model names
|
||||||
|
const modelNames = Object.keys(prisma).filter(
|
||||||
|
(str) => !str.startsWith('_') && !str.startsWith('$'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Iterate through each model and delete all data
|
||||||
|
for (let i = 0; i < modelNames.length; i++) {
|
||||||
|
await prisma[modelNames[i]].deleteMany({});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('All data cleared');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error in clearing data:', e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await clearAllData();
|
||||||
|
|
||||||
|
await createUsersAndAccounts(2, [
|
||||||
|
{ email: 'admin@gmail.com', isAdmin: true },
|
||||||
|
{ email: 'user@gmail.com', isAdmin: false },
|
||||||
|
]);
|
||||||
|
await createInvitedUsers(10);
|
||||||
|
// `userSettings` can be created by APP itself
|
||||||
|
await createUserCollections(10, 10);
|
||||||
|
await createUserRequests(10);
|
||||||
|
// `userHistory` can be created by APP itself
|
||||||
|
await createUserEnvironments();
|
||||||
|
await createShortcodes(3);
|
||||||
|
await createTeamsAndTeamMembers(10, 4);
|
||||||
|
// `teamInvitation` can be created by APP itself
|
||||||
|
await createTeamEnvironments();
|
||||||
|
await createTeamCollections(5, 5);
|
||||||
|
await createTeamRequests(3);
|
||||||
|
})();
|
||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
EMAIL_FAILED,
|
EMAIL_FAILED,
|
||||||
INVALID_EMAIL,
|
INVALID_EMAIL,
|
||||||
ONLY_ONE_ADMIN_ACCOUNT,
|
ONLY_ONE_ADMIN_ACCOUNT,
|
||||||
TEAM_INVALID_ID,
|
|
||||||
TEAM_INVITE_ALREADY_MEMBER,
|
TEAM_INVITE_ALREADY_MEMBER,
|
||||||
TEAM_INVITE_NO_INVITE_FOUND,
|
TEAM_INVITE_NO_INVITE_FOUND,
|
||||||
USERS_NOT_FOUND,
|
USERS_NOT_FOUND,
|
||||||
@@ -319,11 +318,11 @@ export class AdminService {
|
|||||||
const user = await this.userService.findUserByEmail(userEmail);
|
const user = await this.userService.findUserByEmail(userEmail);
|
||||||
if (O.isNone(user)) return E.left(USER_NOT_FOUND);
|
if (O.isNone(user)) return E.left(USER_NOT_FOUND);
|
||||||
|
|
||||||
const teamMember = await this.teamService.getTeamMember(
|
const teamMember = await this.teamService.getTeamMemberTE(
|
||||||
teamID,
|
teamID,
|
||||||
user.value.uid,
|
user.value.uid,
|
||||||
);
|
)();
|
||||||
if (!teamMember) {
|
if (E.isLeft(teamMember)) {
|
||||||
const addedUser = await this.teamService.addMemberToTeamWithEmail(
|
const addedUser = await this.teamService.addMemberToTeamWithEmail(
|
||||||
teamID,
|
teamID,
|
||||||
userEmail,
|
userEmail,
|
||||||
@@ -591,9 +590,9 @@ export class AdminService {
|
|||||||
* @returns an Either of `Team` or error
|
* @returns an Either of `Team` or error
|
||||||
*/
|
*/
|
||||||
async getTeamInfo(teamID: string) {
|
async getTeamInfo(teamID: string) {
|
||||||
const team = await this.teamService.getTeamWithID(teamID);
|
const team = await this.teamService.getTeamWithIDTE(teamID)();
|
||||||
if (!team) return E.left(TEAM_INVALID_ID);
|
if (E.isLeft(team)) return E.left(team.left);
|
||||||
return E.right(team);
|
return E.right(team.right);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -15,11 +15,7 @@ import * as TE from 'fp-ts/TaskEither';
|
|||||||
import * as E from 'fp-ts/Either';
|
import * as E from 'fp-ts/Either';
|
||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
import { Team, TeamMember, TeamMemberRole } from 'src/team/team.model';
|
import { Team, TeamMember, TeamMemberRole } from 'src/team/team.model';
|
||||||
import {
|
import { TEAM_INVITE_NO_INVITE_FOUND, USER_NOT_FOUND } from 'src/errors';
|
||||||
TEAM_INVALID_ID,
|
|
||||||
TEAM_INVITE_NO_INVITE_FOUND,
|
|
||||||
USER_NOT_FOUND,
|
|
||||||
} from 'src/errors';
|
|
||||||
import { GqlUser } from 'src/decorators/gql-user.decorator';
|
import { GqlUser } from 'src/decorators/gql-user.decorator';
|
||||||
import { User } from 'src/user/user.model';
|
import { User } from 'src/user/user.model';
|
||||||
import { UseGuards } from '@nestjs/common';
|
import { UseGuards } from '@nestjs/common';
|
||||||
@@ -54,9 +50,10 @@ export class TeamInvitationResolver {
|
|||||||
description: 'Get the team associated to the invite',
|
description: 'Get the team associated to the invite',
|
||||||
})
|
})
|
||||||
async team(@Parent() teamInvitation: TeamInvitation): Promise<Team> {
|
async team(@Parent() teamInvitation: TeamInvitation): Promise<Team> {
|
||||||
const team = await this.teamService.getTeamWithID(teamInvitation.teamID);
|
return pipe(
|
||||||
if (!team) throwErr(TEAM_INVALID_ID);
|
this.teamService.getTeamWithIDTE(teamInvitation.teamID),
|
||||||
return team;
|
TE.getOrElse(throwErr),
|
||||||
|
)();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField(() => User, {
|
@ResolveField(() => User, {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
} from '../errors';
|
} from '../errors';
|
||||||
import { mockDeep, mockReset } from 'jest-mock-extended';
|
import { mockDeep, mockReset } from 'jest-mock-extended';
|
||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
import { skip } from 'rxjs';
|
|
||||||
|
|
||||||
const mockPrisma = mockDeep<PrismaService>();
|
const mockPrisma = mockDeep<PrismaService>();
|
||||||
|
|
||||||
@@ -756,8 +755,6 @@ describe('getMembersOfTeam', () => {
|
|||||||
|
|
||||||
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
|
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
|
||||||
take: 10,
|
take: 10,
|
||||||
skip: 0,
|
|
||||||
cursor: undefined,
|
|
||||||
where: {
|
where: {
|
||||||
teamID: team.id,
|
teamID: team.id,
|
||||||
},
|
},
|
||||||
@@ -809,8 +806,6 @@ describe('getTeamsOfUser', () => {
|
|||||||
|
|
||||||
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
|
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
|
||||||
take: 10,
|
take: 10,
|
||||||
skip: 0,
|
|
||||||
cursor: undefined,
|
|
||||||
where: {
|
where: {
|
||||||
userUid: dbTeamMember.userUid,
|
userUid: dbTeamMember.userUid,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
} from '../errors';
|
} from '../errors';
|
||||||
import { PubSubService } from '../pubsub/pubsub.service';
|
import { PubSubService } from '../pubsub/pubsub.service';
|
||||||
import { flow, pipe } from 'fp-ts/function';
|
import { flow, pipe } from 'fp-ts/function';
|
||||||
|
import * as TE from 'fp-ts/TaskEither';
|
||||||
import * as TO from 'fp-ts/TaskOption';
|
import * as TO from 'fp-ts/TaskOption';
|
||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
import * as E from 'fp-ts/Either';
|
import * as E from 'fp-ts/Either';
|
||||||
@@ -263,25 +264,37 @@ export class TeamService implements UserDataHandler, OnModuleInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getTeamsOfUser(uid: string, cursor: string | null): Promise<Team[]> {
|
async getTeamsOfUser(uid: string, cursor: string | null): Promise<Team[]> {
|
||||||
const entries = await this.prisma.teamMember.findMany({
|
if (!cursor) {
|
||||||
take: 10,
|
const entries = await this.prisma.teamMember.findMany({
|
||||||
skip: cursor ? 1 : 0,
|
take: 10,
|
||||||
cursor: cursor
|
where: {
|
||||||
? {
|
userUid: uid,
|
||||||
teamID_userUid: {
|
},
|
||||||
teamID: cursor,
|
include: {
|
||||||
userUid: uid,
|
team: true,
|
||||||
},
|
},
|
||||||
}
|
});
|
||||||
: undefined,
|
|
||||||
where: {
|
return entries.map((entry) => entry.team);
|
||||||
userUid: uid,
|
} else {
|
||||||
},
|
const entries = await this.prisma.teamMember.findMany({
|
||||||
include: {
|
take: 10,
|
||||||
team: true,
|
skip: 1,
|
||||||
},
|
cursor: {
|
||||||
});
|
teamID_userUid: {
|
||||||
return entries.map((entry) => entry.team);
|
teamID: cursor,
|
||||||
|
userUid: uid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
userUid: uid,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
team: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return entries.map((entry) => entry.team);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTeamWithID(teamID: string): Promise<Team | null> {
|
async getTeamWithID(teamID: string): Promise<Team | null> {
|
||||||
@@ -298,6 +311,19 @@ export class TeamService implements UserDataHandler, OnModuleInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTeamWithIDTE(teamID: string): TE.TaskEither<'team/invalid_id', Team> {
|
||||||
|
return pipe(
|
||||||
|
() => this.getTeamWithID(teamID),
|
||||||
|
TE.fromTask,
|
||||||
|
TE.chain(
|
||||||
|
TE.fromPredicate(
|
||||||
|
(x): x is Team => !!x,
|
||||||
|
() => TEAM_INVALID_ID,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters out team members that we weren't able to match
|
* Filters out team members that we weren't able to match
|
||||||
* (also deletes the membership)
|
* (also deletes the membership)
|
||||||
@@ -349,6 +375,19 @@ export class TeamService implements UserDataHandler, OnModuleInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTeamMemberTE(teamID: string, userUid: string) {
|
||||||
|
return pipe(
|
||||||
|
() => this.getTeamMember(teamID, userUid),
|
||||||
|
TE.fromTask,
|
||||||
|
TE.chain(
|
||||||
|
TE.fromPredicate(
|
||||||
|
(x): x is TeamMember => !!x,
|
||||||
|
() => TEAM_MEMBER_NOT_FOUND,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async getRoleOfUserInTeam(
|
async getRoleOfUserInTeam(
|
||||||
teamID: string,
|
teamID: string,
|
||||||
userUid: string,
|
userUid: string,
|
||||||
@@ -433,12 +472,25 @@ export class TeamService implements UserDataHandler, OnModuleInit {
|
|||||||
): Promise<TeamMember[]> {
|
): Promise<TeamMember[]> {
|
||||||
let teamMembers: DbTeamMember[];
|
let teamMembers: DbTeamMember[];
|
||||||
|
|
||||||
teamMembers = await this.prisma.teamMember.findMany({
|
if (!cursor) {
|
||||||
take: 10,
|
teamMembers = await this.prisma.teamMember.findMany({
|
||||||
skip: cursor ? 1 : 0,
|
take: 10,
|
||||||
cursor: cursor ? { id: cursor } : undefined,
|
where: {
|
||||||
where: { teamID },
|
teamID,
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
teamMembers = await this.prisma.teamMember.findMany({
|
||||||
|
take: 10,
|
||||||
|
skip: 1,
|
||||||
|
cursor: {
|
||||||
|
id: cursor,
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
teamID,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const members = teamMembers.map(
|
const members = teamMembers.map(
|
||||||
(entry) =>
|
(entry) =>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"extends": "./tsconfig.json",
|
"extends": "./tsconfig.json",
|
||||||
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
|
"exclude": ["node_modules", "test", "dist", "**/*spec.ts", "prisma/seed.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -374,7 +374,8 @@
|
|||||||
"mutations": "Mutations",
|
"mutations": "Mutations",
|
||||||
"schema": "Schema",
|
"schema": "Schema",
|
||||||
"subscriptions": "Subscriptions",
|
"subscriptions": "Subscriptions",
|
||||||
"switch_connection": "Switch connection"
|
"switch_connection": "Switch connection",
|
||||||
|
"url_placeholder": "Enter a GraphQL endpoint URL"
|
||||||
},
|
},
|
||||||
"graphql_collections": {
|
"graphql_collections": {
|
||||||
"title": "GraphQL Collections"
|
"title": "GraphQL Collections"
|
||||||
@@ -598,6 +599,7 @@
|
|||||||
"title": "Request",
|
"title": "Request",
|
||||||
"type": "Request type",
|
"type": "Request type",
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
|
"url_placeholder": "Enter a URL or paste a cURL command",
|
||||||
"variables": "Variables",
|
"variables": "Variables",
|
||||||
"view_my_links": "View my links"
|
"view_my_links": "View my links"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -58,24 +58,6 @@
|
|||||||
"new": "Ajouter un nouveau",
|
"new": "Ajouter un nouveau",
|
||||||
"star": "Ajouter une étoile"
|
"star": "Ajouter une étoile"
|
||||||
},
|
},
|
||||||
"cookies": {
|
|
||||||
"modal": {
|
|
||||||
"new_domain_name": "Nouveau nom de domaine",
|
|
||||||
"set": "Définir un cookie",
|
|
||||||
"cookie_string": "Chaîne de caractères de cookie",
|
|
||||||
"enter_cookie_string": "Saisir la chaîne de caractères du cookie",
|
|
||||||
"cookie_name": "Nom",
|
|
||||||
"cookie_value": "Valeur",
|
|
||||||
"cookie_path": "Chemin d'accès",
|
|
||||||
"cookie_expires": "Expiration",
|
|
||||||
"managed_tab": "Gestion",
|
|
||||||
"raw_tab": "Brut",
|
|
||||||
"interceptor_no_support": "L'intercepteur que vous avez sélectionné ne prend pas en charge les cookies. Sélectionnez un autre intercepteur et réessayez.",
|
|
||||||
"empty_domains": "La liste des domaines est vide",
|
|
||||||
"empty_domain": "Le domaine est vide",
|
|
||||||
"no_cookies_in_domain": "Aucun cookie n'est défini pour ce domaine"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"app": {
|
"app": {
|
||||||
"chat_with_us": "Discuter avec nous",
|
"chat_with_us": "Discuter avec nous",
|
||||||
"contact_us": "Nous contacter",
|
"contact_us": "Nous contacter",
|
||||||
@@ -187,7 +169,7 @@
|
|||||||
},
|
},
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"close_unsaved_tab": "Êtes-vous sûr de vouloir fermer cet onglet ?",
|
"close_unsaved_tab": "Êtes-vous sûr de vouloir fermer cet onglet ?",
|
||||||
"close_unsaved_tabs": "Êtes-vous sûr de vouloir fermer tous les onglets ? {Les onglets non enregistrés seront perdus.",
|
"close_unsaved_tabs": "Êtes-vous sûr de vouloir fermer tous les onglets ? {count} onglets non enregistrés seront perdus",
|
||||||
"exit_team": "Êtes-vous sûr de vouloir quitter cette équipe ?",
|
"exit_team": "Êtes-vous sûr de vouloir quitter cette équipe ?",
|
||||||
"logout": "Êtes-vous sûr de vouloir vous déconnecter?",
|
"logout": "Êtes-vous sûr de vouloir vous déconnecter?",
|
||||||
"remove_collection": "Voulez-vous vraiment supprimer définitivement cette collection ?",
|
"remove_collection": "Voulez-vous vraiment supprimer définitivement cette collection ?",
|
||||||
@@ -207,6 +189,24 @@
|
|||||||
"open_request_in_new_tab": "Ouvrir la demande dans un nouvel onglet",
|
"open_request_in_new_tab": "Ouvrir la demande dans un nouvel onglet",
|
||||||
"set_environment_variable": "Définir comme variable"
|
"set_environment_variable": "Définir comme variable"
|
||||||
},
|
},
|
||||||
|
"cookies": {
|
||||||
|
"modal": {
|
||||||
|
"new_domain_name": "Nouveau nom de domaine",
|
||||||
|
"set": "Définir un cookie",
|
||||||
|
"cookie_string": "Chaîne de caractères de cookie",
|
||||||
|
"enter_cookie_string": "Saisir la chaîne de caractères du cookie",
|
||||||
|
"cookie_name": "Nom",
|
||||||
|
"cookie_value": "Valeur",
|
||||||
|
"cookie_path": "Chemin d'accès",
|
||||||
|
"cookie_expires": "Expiration",
|
||||||
|
"managed_tab": "Gestion",
|
||||||
|
"raw_tab": "Brut",
|
||||||
|
"interceptor_no_support": "L'intercepteur que vous avez sélectionné ne prend pas en charge les cookies. Sélectionnez un autre intercepteur et réessayez.",
|
||||||
|
"empty_domains": "La liste des domaines est vide",
|
||||||
|
"empty_domain": "Le domaine est vide",
|
||||||
|
"no_cookies_in_domain": "Aucun cookie n'est défini pour ce domaine"
|
||||||
|
}
|
||||||
|
},
|
||||||
"count": {
|
"count": {
|
||||||
"header": "En-tête {count}",
|
"header": "En-tête {count}",
|
||||||
"message": "Message {compte}",
|
"message": "Message {compte}",
|
||||||
@@ -410,7 +410,7 @@
|
|||||||
"description": "Inspecter les erreurs possibles",
|
"description": "Inspecter les erreurs possibles",
|
||||||
"environment": {
|
"environment": {
|
||||||
"add_environment": "Ajouter à l'environnement",
|
"add_environment": "Ajouter à l'environnement",
|
||||||
"not_found": "La variable d'environnement “{environnement}“ n'a pas été trouvée."
|
"not_found": "La variable d'environnement “{environment}“ n'a pas été trouvée."
|
||||||
},
|
},
|
||||||
"header": {
|
"header": {
|
||||||
"cookie": "Le navigateur ne permet pas à Hoppscotch de définir l'en-tête Cookie. Pendant que nous travaillons sur l'application de bureau Hoppscotch (bientôt disponible), veuillez utiliser l'en-tête d'autorisation à la place."
|
"cookie": "Le navigateur ne permet pas à Hoppscotch de définir l'en-tête Cookie. Pendant que nous travaillons sur l'application de bureau Hoppscotch (bientôt disponible), veuillez utiliser l'en-tête d'autorisation à la place."
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@hoppscotch/common",
|
"name": "@hoppscotch/common",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2024.3.1",
|
"version": "2024.3.3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "pnpm exec npm-run-all -p -l dev:*",
|
"dev": "pnpm exec npm-run-all -p -l dev:*",
|
||||||
"test": "vitest --run",
|
"test": "vitest --run",
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
"axios": "1.6.2",
|
"axios": "1.6.2",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
"cookie-es": "1.0.0",
|
"cookie-es": "1.0.0",
|
||||||
"dioc": "1.0.1",
|
"dioc": "3.0.1",
|
||||||
"esprima": "4.0.1",
|
"esprima": "4.0.1",
|
||||||
"events": "3.3.0",
|
"events": "3.3.0",
|
||||||
"fp-ts": "2.16.1",
|
"fp-ts": "2.16.1",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ declare module 'vue' {
|
|||||||
AppSpotlightEntryRESTHistory: typeof import('./components/app/spotlight/entry/RESTHistory.vue')['default']
|
AppSpotlightEntryRESTHistory: typeof import('./components/app/spotlight/entry/RESTHistory.vue')['default']
|
||||||
AppSpotlightEntryRESTRequest: typeof import('./components/app/spotlight/entry/RESTRequest.vue')['default']
|
AppSpotlightEntryRESTRequest: typeof import('./components/app/spotlight/entry/RESTRequest.vue')['default']
|
||||||
AppSpotlightEntryRESTTeamRequestEntry: typeof import('./components/app/spotlight/entry/RESTTeamRequestEntry.vue')['default']
|
AppSpotlightEntryRESTTeamRequestEntry: typeof import('./components/app/spotlight/entry/RESTTeamRequestEntry.vue')['default']
|
||||||
|
AppSpotlightSearch: typeof import('./components/app/SpotlightSearch.vue')['default']
|
||||||
AppSupport: typeof import('./components/app/Support.vue')['default']
|
AppSupport: typeof import('./components/app/Support.vue')['default']
|
||||||
Collections: typeof import('./components/collections/index.vue')['default']
|
Collections: typeof import('./components/collections/index.vue')['default']
|
||||||
CollectionsAdd: typeof import('./components/collections/Add.vue')['default']
|
CollectionsAdd: typeof import('./components/collections/Add.vue')['default']
|
||||||
|
|||||||
@@ -54,9 +54,7 @@
|
|||||||
:key="tab.id"
|
:key="tab.id"
|
||||||
:label="tab.label"
|
:label="tab.label"
|
||||||
>
|
>
|
||||||
<div
|
<div class="divide-y divide-dividerLight">
|
||||||
class="divide-y divide-dividerLight rounded border border-divider"
|
|
||||||
>
|
|
||||||
<HoppSmartPlaceholder
|
<HoppSmartPlaceholder
|
||||||
v-if="tab.variables.length === 0"
|
v-if="tab.variables.length === 0"
|
||||||
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
||||||
|
|||||||
@@ -56,9 +56,7 @@
|
|||||||
:key="tab.id"
|
:key="tab.id"
|
||||||
:label="tab.label"
|
:label="tab.label"
|
||||||
>
|
>
|
||||||
<div
|
<div class="divide-y divide-dividerLight">
|
||||||
class="divide-y divide-dividerLight rounded border border-divider"
|
|
||||||
>
|
|
||||||
<HoppSmartPlaceholder
|
<HoppSmartPlaceholder
|
||||||
v-if="tab.variables.length === 0"
|
v-if="tab.variables.length === 0"
|
||||||
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
:src="`/images/states/${colorMode.value}/blockchain.svg`"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
class="w-full rounded border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
class="w-full rounded border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
|
||||||
:placeholder="`${t('request.url')}`"
|
:placeholder="`${t('graphql.url_placeholder')}`"
|
||||||
:disabled="connected"
|
:disabled="connected"
|
||||||
@keyup.enter="onConnectClick"
|
@keyup.enter="onConnectClick"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
>
|
>
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="tab.document.request.endpoint"
|
v-model="tab.document.request.endpoint"
|
||||||
:placeholder="`${t('request.url')}`"
|
:placeholder="`${t('request.url_placeholder')}`"
|
||||||
:auto-complete-source="userHistories"
|
:auto-complete-source="userHistories"
|
||||||
:auto-complete-env="true"
|
:auto-complete-env="true"
|
||||||
:inspection-results="tabResults"
|
:inspection-results="tabResults"
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ export class TeamSearchService extends Service {
|
|||||||
expandingCollections: Ref<string[]> = ref([])
|
expandingCollections: Ref<string[]> = ref([])
|
||||||
expandedCollections: Ref<string[]> = ref([])
|
expandedCollections: Ref<string[]> = ref([])
|
||||||
|
|
||||||
// FUTURE-TODO: ideally this should return the search results / formatted results instead of directly manipulating the result set
|
// TODO: ideally this should return the search results / formatted results instead of directly manipulating the result set
|
||||||
// eg: do the spotlight formatting in the spotlight searcher and not here
|
// eg: do the spotlight formatting in the spotlight searcher and not here
|
||||||
searchTeams = async (query: string, teamID: string) => {
|
searchTeams = async (query: string, teamID: string) => {
|
||||||
if (!query.length) {
|
if (!query.length) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { HoppModule } from "."
|
import { HoppModule } from "."
|
||||||
import { Container, Service } from "dioc"
|
import { Container, ServiceClassInstance } from "dioc"
|
||||||
import { diocPlugin } from "dioc/vue"
|
import { diocPlugin } from "dioc/vue"
|
||||||
import { DebugService } from "~/services/debug.service"
|
import { DebugService } from "~/services/debug.service"
|
||||||
import { platform } from "~/platform"
|
import { platform } from "~/platform"
|
||||||
@@ -22,7 +22,7 @@ if (import.meta.env.DEV) {
|
|||||||
* services. Please use `useService` if within components or try to convert your
|
* services. Please use `useService` if within components or try to convert your
|
||||||
* legacy subsystem into a service if possible.
|
* legacy subsystem into a service if possible.
|
||||||
*/
|
*/
|
||||||
export function getService<T extends typeof Service<any> & { ID: string }>(
|
export function getService<T extends ServiceClassInstance<any>>(
|
||||||
service: T
|
service: T
|
||||||
): InstanceType<T> {
|
): InstanceType<T> {
|
||||||
return serviceContainer.bind(service)
|
return serviceContainer.bind(service)
|
||||||
@@ -30,11 +30,10 @@ export function getService<T extends typeof Service<any> & { ID: string }>(
|
|||||||
|
|
||||||
export default <HoppModule>{
|
export default <HoppModule>{
|
||||||
onVueAppInit(app) {
|
onVueAppInit(app) {
|
||||||
// TODO: look into this
|
|
||||||
// @ts-expect-error Something weird with Vue versions
|
|
||||||
app.use(diocPlugin, {
|
app.use(diocPlugin, {
|
||||||
container: serviceContainer,
|
container: serviceContainer,
|
||||||
})
|
})
|
||||||
|
|
||||||
for (const service of platform.addedServices ?? []) {
|
for (const service of platform.addedServices ?? []) {
|
||||||
serviceContainer.bind(service)
|
serviceContainer.bind(service)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import { AnalyticsPlatformDef } from "./analytics"
|
|||||||
import { InterceptorsPlatformDef } from "./interceptors"
|
import { InterceptorsPlatformDef } from "./interceptors"
|
||||||
import { HoppModule } from "~/modules"
|
import { HoppModule } from "~/modules"
|
||||||
import { InspectorsPlatformDef } from "./inspectors"
|
import { InspectorsPlatformDef } from "./inspectors"
|
||||||
import { Service } from "dioc"
|
import { ServiceClassInstance } from "dioc"
|
||||||
import { IOPlatformDef } from "./io"
|
import { IOPlatformDef } from "./io"
|
||||||
import { SpotlightPlatformDef } from "./spotlight"
|
import { SpotlightPlatformDef } from "./spotlight"
|
||||||
|
|
||||||
export type PlatformDef = {
|
export type PlatformDef = {
|
||||||
ui?: UIPlatformDef
|
ui?: UIPlatformDef
|
||||||
addedHoppModules?: HoppModule[]
|
addedHoppModules?: HoppModule[]
|
||||||
addedServices?: Array<typeof Service<unknown> & { ID: string }>
|
addedServices?: Array<ServiceClassInstance<unknown>>
|
||||||
auth: AuthPlatformDef
|
auth: AuthPlatformDef
|
||||||
analytics?: AnalyticsPlatformDef
|
analytics?: AnalyticsPlatformDef
|
||||||
io: IOPlatformDef
|
io: IOPlatformDef
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Service } from "dioc"
|
import { Container, ServiceClassInstance } from "dioc"
|
||||||
import { Inspector } from "~/services/inspection"
|
import { Inspector } from "~/services/inspection"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -8,8 +8,9 @@ export type PlatformInspectorsDef = {
|
|||||||
// We are keeping this as the only mode for now
|
// We are keeping this as the only mode for now
|
||||||
// So that if we choose to add other modes, we can do without breaking
|
// So that if we choose to add other modes, we can do without breaking
|
||||||
type: "service"
|
type: "service"
|
||||||
service: typeof Service<unknown> & { ID: string } & {
|
// TODO: I don't think this type is effective, we have to come up with a better impl
|
||||||
new (): Service & Inspector
|
service: ServiceClassInstance<unknown> & {
|
||||||
|
new (c: Container): Inspector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Service } from "dioc"
|
import { Container, ServiceClassInstance } from "dioc"
|
||||||
import { Interceptor } from "~/services/interceptor.service"
|
import { Interceptor } from "~/services/interceptor.service"
|
||||||
|
|
||||||
export type PlatformInterceptorDef =
|
export type PlatformInterceptorDef =
|
||||||
| { type: "standalone"; interceptor: Interceptor }
|
| { type: "standalone"; interceptor: Interceptor }
|
||||||
| {
|
| {
|
||||||
type: "service"
|
type: "service"
|
||||||
service: typeof Service<unknown> & { ID: string } & {
|
// TODO: I don't think this type is effective, we have to come up with a better impl
|
||||||
new (): Service & Interceptor
|
service: ServiceClassInstance<unknown> & {
|
||||||
|
new (c: Container): Interceptor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Service } from "dioc"
|
import { Container, ServiceClassInstance } from "dioc"
|
||||||
import { SpotlightSearcher } from "~/services/spotlight"
|
import { SpotlightSearcher } from "~/services/spotlight"
|
||||||
|
|
||||||
export type SpotlightPlatformDef = {
|
export type SpotlightPlatformDef = {
|
||||||
additionalSearchers?: Array<
|
additionalSearchers?: Array<
|
||||||
typeof Service<unknown> & { ID: string } & {
|
ServiceClassInstance<unknown> & {
|
||||||
new (): Service & SpotlightSearcher
|
new (c: Container): SpotlightSearcher
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ export class ExtensionInspectorService extends Service implements Inspector {
|
|||||||
|
|
||||||
private readonly inspection = this.bind(InspectionService)
|
private readonly inspection = this.bind(InspectionService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.inspection.registerInspector(this)
|
this.inspection.registerInspector(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,9 +133,7 @@ export class ExtensionInterceptorService
|
|||||||
|
|
||||||
public selectable = { type: "selectable" as const }
|
public selectable = { type: "selectable" as const }
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.listenForExtensionStatus()
|
this.listenForExtensionStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ export class EnvironmentMenuService extends Service implements ContextMenu {
|
|||||||
|
|
||||||
private readonly contextMenu = this.bind(ContextMenuService)
|
private readonly contextMenu = this.bind(ContextMenuService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.contextMenu.registerMenu(this)
|
this.contextMenu.registerMenu(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ export class ParameterMenuService extends Service implements ContextMenu {
|
|||||||
|
|
||||||
private readonly contextMenu = this.bind(ContextMenuService)
|
private readonly contextMenu = this.bind(ContextMenuService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.contextMenu.registerMenu(this)
|
this.contextMenu.registerMenu(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ export class URLMenuService extends Service implements ContextMenu {
|
|||||||
private readonly contextMenu = this.bind(ContextMenuService)
|
private readonly contextMenu = this.bind(ContextMenuService)
|
||||||
private readonly restTab = this.bind(RESTTabService)
|
private readonly restTab = this.bind(RESTTabService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.contextMenu.registerMenu(this)
|
this.contextMenu.registerMenu(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,6 @@ export class CookieJarService extends Service {
|
|||||||
*/
|
*/
|
||||||
public cookieJar = ref(new Map<string, string[]>())
|
public cookieJar = ref(new Map<string, string[]>())
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
public parseSetCookieString(setCookieString: string) {
|
public parseSetCookieString(setCookieString: string) {
|
||||||
return setCookieParse(setCookieString)
|
return setCookieParse(setCookieString)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ import { Service } from "dioc"
|
|||||||
export class DebugService extends Service {
|
export class DebugService extends Service {
|
||||||
public static readonly ID = "DEBUG_SERVICE"
|
public static readonly ID = "DEBUG_SERVICE"
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
console.log("DebugService is initialized...")
|
console.log("DebugService is initialized...")
|
||||||
|
|
||||||
const container = this.getContainer()
|
const container = this.getContainer()
|
||||||
|
|||||||
@@ -107,9 +107,7 @@ export class InspectionService extends Service {
|
|||||||
|
|
||||||
private readonly restTab = this.bind(RESTTabService)
|
private readonly restTab = this.bind(RESTTabService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.initializeListeners()
|
this.initializeListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,7 @@ export class EnvironmentInspectorService extends Service implements Inspector {
|
|||||||
}
|
}
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.inspection.registerInspector(this)
|
this.inspection.registerInspector(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ export class HeaderInspectorService extends Service implements Inspector {
|
|||||||
private readonly inspection = this.bind(InspectionService)
|
private readonly inspection = this.bind(InspectionService)
|
||||||
private readonly interceptorService = this.bind(InterceptorService)
|
private readonly interceptorService = this.bind(InterceptorService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.inspection.registerInspector(this)
|
this.inspection.registerInspector(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ export class ResponseInspectorService extends Service implements Inspector {
|
|||||||
|
|
||||||
private readonly inspection = this.bind(InspectionService)
|
private readonly inspection = this.bind(InspectionService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.inspection.registerInspector(this)
|
this.inspection.registerInspector(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -178,9 +178,7 @@ export class InterceptorService extends Service {
|
|||||||
return this.interceptors.get(this.currentInterceptorID.value)
|
return this.interceptors.get(this.currentInterceptorID.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
// If the current interceptor is unselectable, select the first selectable one, else null
|
// If the current interceptor is unselectable, select the first selectable one, else null
|
||||||
watch([() => this.interceptors, this.currentInterceptorID], () => {
|
watch([() => this.interceptors, this.currentInterceptorID], () => {
|
||||||
if (!this.currentInterceptorID.value) return
|
if (!this.currentInterceptorID.value) return
|
||||||
|
|||||||
@@ -109,10 +109,6 @@ export class OauthAuthService extends Service {
|
|||||||
public static readonly ID = "OAUTH_AUTH_SERVICE"
|
public static readonly ID = "OAUTH_AUTH_SERVICE"
|
||||||
|
|
||||||
static redirectURI = `${window.location.origin}/oauth`
|
static redirectURI = `${window.location.origin}/oauth`
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const generateRandomString = () => {
|
export const generateRandomString = () => {
|
||||||
|
|||||||
@@ -89,10 +89,6 @@ export class PersistenceService extends Service {
|
|||||||
|
|
||||||
public hoppLocalConfigStorage: StorageLike = localStorage
|
public hoppLocalConfigStorage: StorageLike = localStorage
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
private showErrorToast(localStorageKey: string) {
|
private showErrorToast(localStorageKey: string) {
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
toast.error(
|
toast.error(
|
||||||
|
|||||||
@@ -27,10 +27,6 @@ export class SecretEnvironmentService extends Service {
|
|||||||
*/
|
*/
|
||||||
public secretEnvironments = reactive(new Map<string, SecretVariable[]>())
|
public secretEnvironments = reactive(new Map<string, SecretVariable[]>())
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new secret environment.
|
* Add a new secret environment.
|
||||||
* @param id ID of the environment
|
* @param id ID of the environment
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
import { nextTick, reactive, ref } from "vue"
|
import { nextTick, reactive, ref } from "vue"
|
||||||
import { SpotlightSearcherResult } from "../../.."
|
import { SpotlightSearcherResult } from "../../.."
|
||||||
import { TestContainer } from "dioc/testing"
|
import { TestContainer } from "dioc/testing"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
async function flushPromises() {
|
async function flushPromises() {
|
||||||
return await new Promise((r) => setTimeout(r))
|
return await new Promise((r) => setTimeout(r))
|
||||||
@@ -32,12 +33,15 @@ describe("StaticSpotlightSearcherService", () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: dioc > v3 does not recommend using constructors, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text"],
|
searchFields: ["text"],
|
||||||
fieldWeights: {},
|
fieldWeights: {},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,12 +98,15 @@ describe("StaticSpotlightSearcherService", () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: dioc > v3 does not recommend using constructors, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text"],
|
searchFields: ["text"],
|
||||||
fieldWeights: {},
|
fieldWeights: {},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,12 +166,15 @@ describe("StaticSpotlightSearcherService", () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: dioc > v3 does not recommend using constructors, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text"],
|
searchFields: ["text"],
|
||||||
fieldWeights: {},
|
fieldWeights: {},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,12 +234,15 @@ describe("StaticSpotlightSearcherService", () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: dioc > v3 does not recommend using constructors, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text"],
|
searchFields: ["text"],
|
||||||
fieldWeights: {},
|
fieldWeights: {},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,12 +298,15 @@ describe("StaticSpotlightSearcherService", () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: dioc > v3 does not recommend using constructors, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text"],
|
searchFields: ["text"],
|
||||||
fieldWeights: {},
|
fieldWeights: {},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,12 +370,15 @@ describe("StaticSpotlightSearcherService", () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: dioc > v3 does not recommend using constructors, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternate"],
|
searchFields: ["text", "alternate"],
|
||||||
fieldWeights: {},
|
fieldWeights: {},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Service } from "dioc"
|
import { Container, Service } from "dioc"
|
||||||
import {
|
import {
|
||||||
type SpotlightSearcher,
|
type SpotlightSearcher,
|
||||||
type SpotlightSearcherResult,
|
type SpotlightSearcherResult,
|
||||||
@@ -67,8 +67,12 @@ export abstract class StaticSpotlightSearcherService<
|
|||||||
|
|
||||||
private _documents: Record<string, Doc> = {}
|
private _documents: Record<string, Doc> = {}
|
||||||
|
|
||||||
constructor(private opts: StaticSpotlightSearcherOptions<Doc>) {
|
// TODO: This pattern is no longer recommended in dioc > 3, move to something else
|
||||||
super()
|
constructor(
|
||||||
|
c: Container,
|
||||||
|
private opts: StaticSpotlightSearcherOptions<Doc>
|
||||||
|
) {
|
||||||
|
super(c)
|
||||||
|
|
||||||
this.minisearch = new MiniSearch({
|
this.minisearch = new MiniSearch({
|
||||||
fields: opts.searchFields as string[],
|
fields: opts.searchFields as string[],
|
||||||
|
|||||||
@@ -50,9 +50,7 @@ export class CollectionsSpotlightSearcherService
|
|||||||
private readonly spotlight = this.bind(SpotlightService)
|
private readonly spotlight = this.bind(SpotlightService)
|
||||||
private readonly workspaceService = this.bind(WorkspaceService)
|
private readonly workspaceService = this.bind(WorkspaceService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import IconEdit from "~icons/lucide/edit"
|
|||||||
import IconLayers from "~icons/lucide/layers"
|
import IconLayers from "~icons/lucide/layers"
|
||||||
import IconTrash2 from "~icons/lucide/trash-2"
|
import IconTrash2 from "~icons/lucide/trash-2"
|
||||||
|
|
||||||
import { Service } from "dioc"
|
import { Container, Service } from "dioc"
|
||||||
import * as TE from "fp-ts/TaskEither"
|
import * as TE from "fp-ts/TaskEither"
|
||||||
import { pipe } from "fp-ts/function"
|
import { pipe } from "fp-ts/function"
|
||||||
import { cloneDeep } from "lodash-es"
|
import { cloneDeep } from "lodash-es"
|
||||||
@@ -164,15 +164,18 @@ export class EnvironmentsSpotlightSearcherService extends StaticSpotlightSearche
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: This pattern is no longer recommended in dioc > 3, move to something else
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
@@ -277,9 +280,7 @@ export class SwitchEnvSpotlightSearcherService
|
|||||||
private readonly workspaceService = this.bind(WorkspaceService)
|
private readonly workspaceService = this.bind(WorkspaceService)
|
||||||
private teamEnvironmentList: TeamEnvironment[] = []
|
private teamEnvironmentList: TeamEnvironment[] = []
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import IconBook from "~icons/lucide/book"
|
|||||||
import IconLifeBuoy from "~icons/lucide/life-buoy"
|
import IconLifeBuoy from "~icons/lucide/life-buoy"
|
||||||
import IconZap from "~icons/lucide/zap"
|
import IconZap from "~icons/lucide/zap"
|
||||||
import { platform } from "~/platform"
|
import { platform } from "~/platform"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string | string[]
|
text: string | string[]
|
||||||
@@ -89,15 +90,18 @@ export class GeneralSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: This is not recommended as of dioc > 3. Move to onServiceInit instead
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ export class HistorySpotlightSearcherService
|
|||||||
}
|
}
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,7 @@ export class InterceptorSpotlightSearcherService
|
|||||||
private readonly spotlight = this.bind(SpotlightService)
|
private readonly spotlight = this.bind(SpotlightService)
|
||||||
private interceptorService = this.bind(InterceptorService)
|
private interceptorService = this.bind(InterceptorService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
} from "./base/static.searcher"
|
} from "./base/static.searcher"
|
||||||
|
|
||||||
import IconShare from "~icons/lucide/share"
|
import IconShare from "~icons/lucide/share"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string
|
text: string
|
||||||
@@ -39,15 +40,18 @@ export class MiscellaneousSpotlightSearcherService extends StaticSpotlightSearch
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constructors are no longer recommended as of dioc > 3, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
} from "./base/static.searcher"
|
} from "./base/static.searcher"
|
||||||
|
|
||||||
import IconArrowRight from "~icons/lucide/arrow-right"
|
import IconArrowRight from "~icons/lucide/arrow-right"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string
|
text: string
|
||||||
@@ -61,15 +62,18 @@ export class NavigationSpotlightSearcherService extends StaticSpotlightSearcherS
|
|||||||
|
|
||||||
private docKeys = Object.keys(this.documents)
|
private docKeys = Object.keys(this.documents)
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constructors are no longer recommended as of dioc > 3, use onServiceInit instead
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import IconRotateCCW from "~icons/lucide/rotate-ccw"
|
|||||||
import IconSave from "~icons/lucide/save"
|
import IconSave from "~icons/lucide/save"
|
||||||
import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue"
|
import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue"
|
||||||
import { RESTTabService } from "~/services/tab/rest"
|
import { RESTTabService } from "~/services/tab/rest"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string | string[]
|
text: string | string[]
|
||||||
@@ -224,15 +225,18 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constructors are no longer recommended as of dioc > 3, use onServiceInit instead
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
|
|
||||||
import IconDownload from "~icons/lucide/download"
|
import IconDownload from "~icons/lucide/download"
|
||||||
import IconCopy from "~icons/lucide/copy"
|
import IconCopy from "~icons/lucide/copy"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string
|
text: string
|
||||||
@@ -56,15 +57,18 @@ export class ResponseSpotlightSearcherService extends StaticSpotlightSearcherSer
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constructors are no longer recommended as of dioc > 3, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import IconMonitor from "~icons/lucide/monitor"
|
|||||||
import IconMoon from "~icons/lucide/moon"
|
import IconMoon from "~icons/lucide/moon"
|
||||||
import IconSun from "~icons/lucide/sun"
|
import IconSun from "~icons/lucide/sun"
|
||||||
import IconCheckCircle from "~icons/lucide/check-circle"
|
import IconCheckCircle from "~icons/lucide/check-circle"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string | string[]
|
text: string | string[]
|
||||||
@@ -100,15 +101,18 @@ export class SettingsSpotlightSearcherService extends StaticSpotlightSearcherSer
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constuctors are no longer recommended as of dioc > 3, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import IconXSquare from "~icons/lucide/x-square"
|
|||||||
import { invokeAction } from "~/helpers/actions"
|
import { invokeAction } from "~/helpers/actions"
|
||||||
import { RESTTabService } from "~/services/tab/rest"
|
import { RESTTabService } from "~/services/tab/rest"
|
||||||
import { GQLTabService } from "~/services/tab/graphql"
|
import { GQLTabService } from "~/services/tab/graphql"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string | string[]
|
text: string | string[]
|
||||||
@@ -89,15 +90,18 @@ export class TabSpotlightSearcherService extends StaticSpotlightSearcherService<
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constructors are no longer recommended as of dioc > 3, use onServiceInit instead
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ export class TeamsSpotlightSearcherService
|
|||||||
|
|
||||||
private readonly tabs = this.bind(RESTTabService)
|
private readonly tabs = this.bind(RESTTabService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { useStreamStatic } from "~/composables/stream"
|
|||||||
import IconLogin from "~icons/lucide/log-in"
|
import IconLogin from "~icons/lucide/log-in"
|
||||||
import IconLogOut from "~icons/lucide/log-out"
|
import IconLogOut from "~icons/lucide/log-out"
|
||||||
import { activeActions$, invokeAction } from "~/helpers/actions"
|
import { activeActions$, invokeAction } from "~/helpers/actions"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string
|
text: string
|
||||||
@@ -59,15 +60,18 @@ export class UserSpotlightSearcherService extends StaticSpotlightSearcherService
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constructors are no longer recommended as of dioc > 3, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit(): void {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import {
|
|||||||
StaticSpotlightSearcherService,
|
StaticSpotlightSearcherService,
|
||||||
} from "./base/static.searcher"
|
} from "./base/static.searcher"
|
||||||
|
|
||||||
import { Service } from "dioc"
|
import { Container, Service } from "dioc"
|
||||||
import * as E from "fp-ts/Either"
|
import * as E from "fp-ts/Either"
|
||||||
import MiniSearch from "minisearch"
|
import MiniSearch from "minisearch"
|
||||||
import IconCheckCircle from "~/components/app/spotlight/entry/IconSelected.vue"
|
import IconCheckCircle from "~/components/app/spotlight/entry/IconSelected.vue"
|
||||||
@@ -102,15 +102,18 @@ export class WorkspaceSpotlightSearcherService extends StaticSpotlightSearcherSe
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
// TODO: Constructors are no longer recommended as of dioc > 3, move to onServiceInit
|
||||||
super({
|
constructor(c: Container) {
|
||||||
|
super(c, {
|
||||||
searchFields: ["text", "alternates"],
|
searchFields: ["text", "alternates"],
|
||||||
fieldWeights: {
|
fieldWeights: {
|
||||||
text: 2,
|
text: 2,
|
||||||
alternates: 1,
|
alternates: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override onServiceInit() {
|
||||||
this.setDocuments(this.documents)
|
this.setDocuments(this.documents)
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
@@ -166,9 +169,7 @@ export class SwitchWorkspaceSpotlightSearcherService
|
|||||||
private readonly spotlight = this.bind(SpotlightService)
|
private readonly spotlight = this.bind(SpotlightService)
|
||||||
private readonly workspaceService = this.bind(WorkspaceService)
|
private readonly workspaceService = this.bind(WorkspaceService)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ import { reactive } from "vue"
|
|||||||
class MockTabService extends TabService<{ request: string }> {
|
class MockTabService extends TabService<{ request: string }> {
|
||||||
public static readonly ID = "MOCK_TAB_SERVICE"
|
public static readonly ID = "MOCK_TAB_SERVICE"
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
|
|
||||||
this.tabMap = reactive(
|
this.tabMap = reactive(
|
||||||
new Map([
|
new Map([
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -3,12 +3,15 @@ import { getDefaultGQLRequest } from "~/helpers/graphql/default"
|
|||||||
import { HoppGQLDocument, HoppGQLSaveContext } from "~/helpers/graphql/document"
|
import { HoppGQLDocument, HoppGQLSaveContext } from "~/helpers/graphql/document"
|
||||||
import { TabService } from "./tab"
|
import { TabService } from "./tab"
|
||||||
import { computed } from "vue"
|
import { computed } from "vue"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
export class GQLTabService extends TabService<HoppGQLDocument> {
|
export class GQLTabService extends TabService<HoppGQLDocument> {
|
||||||
public static readonly ID = "GQL_TAB_SERVICE"
|
public static readonly ID = "GQL_TAB_SERVICE"
|
||||||
|
|
||||||
constructor() {
|
// TODO: Moving this to `onServiceInit` breaks `persistableTabState`
|
||||||
super()
|
// Figure out how to fix this
|
||||||
|
constructor(c: Container) {
|
||||||
|
super(c)
|
||||||
|
|
||||||
this.tabMap.set("test", {
|
this.tabMap.set("test", {
|
||||||
id: "test",
|
id: "test",
|
||||||
|
|||||||
@@ -3,12 +3,15 @@ import { computed } from "vue"
|
|||||||
import { getDefaultRESTRequest } from "~/helpers/rest/default"
|
import { getDefaultRESTRequest } from "~/helpers/rest/default"
|
||||||
import { HoppRESTDocument, HoppRESTSaveContext } from "~/helpers/rest/document"
|
import { HoppRESTDocument, HoppRESTSaveContext } from "~/helpers/rest/document"
|
||||||
import { TabService } from "./tab"
|
import { TabService } from "./tab"
|
||||||
|
import { Container } from "dioc"
|
||||||
|
|
||||||
export class RESTTabService extends TabService<HoppRESTDocument> {
|
export class RESTTabService extends TabService<HoppRESTDocument> {
|
||||||
public static readonly ID = "REST_TAB_SERVICE"
|
public static readonly ID = "REST_TAB_SERVICE"
|
||||||
|
|
||||||
constructor() {
|
// TODO: Moving this to `onServiceInit` breaks `persistableTabState`
|
||||||
super()
|
// Figure out how to fix this
|
||||||
|
constructor(c: Container) {
|
||||||
|
super(c)
|
||||||
|
|
||||||
this.tabMap.set("test", {
|
this.tabMap.set("test", {
|
||||||
id: "test",
|
id: "test",
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ export class WorkspaceService extends Service<WorkspaceServiceEvent> {
|
|||||||
-1
|
-1
|
||||||
)
|
)
|
||||||
|
|
||||||
constructor() {
|
override onServiceInit() {
|
||||||
super()
|
|
||||||
// Dispose the managed team list adapter when the user logs out
|
// Dispose the managed team list adapter when the user logs out
|
||||||
// and initialize it when the user logs in
|
// and initialize it when the user logs in
|
||||||
watch(
|
watch(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@hoppscotch/selfhost-desktop",
|
"name": "@hoppscotch/selfhost-desktop",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2024.3.0",
|
"version": "2024.3.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:vite": "vite",
|
"dev:vite": "vite",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"@vueuse/core": "10.5.0",
|
"@vueuse/core": "10.5.0",
|
||||||
"axios": "0.21.4",
|
"axios": "0.21.4",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
"dioc": "1.0.1",
|
"dioc": "3.0.1",
|
||||||
"environments.api": "link:@platform/environments/environments.api",
|
"environments.api": "link:@platform/environments/environments.api",
|
||||||
"event": "link:@tauri-apps/api/event",
|
"event": "link:@tauri-apps/api/event",
|
||||||
"fp-ts": "2.16.1",
|
"fp-ts": "2.16.1",
|
||||||
@@ -78,4 +78,4 @@
|
|||||||
"vite-plugin-vue-layouts": "0.7.0",
|
"vite-plugin-vue-layouts": "0.7.0",
|
||||||
"vue-tsc": "1.8.8"
|
"vue-tsc": "1.8.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1260,7 +1260,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hoppscotch-desktop"
|
name = "hoppscotch-desktop"
|
||||||
version = "24.3.1"
|
version = "24.3.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cocoa 0.25.0",
|
"cocoa 0.25.0",
|
||||||
"hex_color",
|
"hex_color",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "hoppscotch-desktop"
|
name = "hoppscotch-desktop"
|
||||||
version = "24.3.0"
|
version = "24.3.3"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
license = ""
|
license = ""
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "Hoppscotch",
|
"productName": "Hoppscotch",
|
||||||
"version": "24.3.1"
|
"version": "24.3.3"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|||||||
@@ -138,10 +138,6 @@ export class NativeInterceptorService extends Service implements Interceptor {
|
|||||||
|
|
||||||
public cookieJarService = this.bind(CookieJarService)
|
public cookieJarService = this.bind(CookieJarService)
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
|
|
||||||
public runRequest(req: any) {
|
public runRequest(req: any) {
|
||||||
const processedReq = preProcessRequest(req)
|
const processedReq = preProcessRequest(req)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@hoppscotch/selfhost-web",
|
"name": "@hoppscotch/selfhost-web",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2024.3.1",
|
"version": "2024.3.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:vite": "vite",
|
"dev:vite": "vite",
|
||||||
|
|||||||
@@ -52,7 +52,8 @@
|
|||||||
"title": "Server is restarting"
|
"title": "Server is restarting"
|
||||||
},
|
},
|
||||||
"save_changes": "Save Changes",
|
"save_changes": "Save Changes",
|
||||||
"title": "Configurations"
|
"title": "Configurations",
|
||||||
|
"update_failure": "Failed to update server configurations"
|
||||||
},
|
},
|
||||||
"data_sharing": {
|
"data_sharing": {
|
||||||
"description": "Share anonymous data usage to improve Hoppscotch",
|
"description": "Share anonymous data usage to improve Hoppscotch",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "hoppscotch-sh-admin",
|
"name": "hoppscotch-sh-admin",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "2024.3.1",
|
"version": "2024.3.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "pnpm exec npm-run-all -p -l dev:*",
|
"dev": "pnpm exec npm-run-all -p -l dev:*",
|
||||||
|
|||||||
@@ -69,18 +69,18 @@
|
|||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { Config, SsoAuthProviders } from '~/composables/useConfigHandler';
|
import { ServerConfigs, SsoAuthProviders } from '~/helpers/configs';
|
||||||
import IconEye from '~icons/lucide/eye';
|
import IconEye from '~icons/lucide/eye';
|
||||||
import IconEyeOff from '~icons/lucide/eye-off';
|
import IconEyeOff from '~icons/lucide/eye-off';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
@@ -93,7 +93,7 @@ const capitalize = (text: string) =>
|
|||||||
type ProviderFieldKeys = keyof ProviderFields;
|
type ProviderFieldKeys = keyof ProviderFields;
|
||||||
|
|
||||||
type ProviderFields = {
|
type ProviderFields = {
|
||||||
[Field in keyof Config['providers'][SsoAuthProviders]['fields']]: boolean;
|
[Field in keyof ServerConfigs['providers'][SsoAuthProviders]['fields']]: boolean;
|
||||||
} & Partial<{ tenant: boolean }>;
|
} & Partial<{ tenant: boolean }>;
|
||||||
|
|
||||||
type ProviderFieldMetadata = {
|
type ProviderFieldMetadata = {
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { Config } from '~/composables/useConfigHandler';
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
|
|||||||
@@ -38,17 +38,17 @@
|
|||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { Config } from '~/composables/useConfigHandler';
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
import IconShieldQuestion from '~icons/lucide/shield-question';
|
import IconShieldQuestion from '~icons/lucide/shield-question';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
|
|||||||
@@ -17,20 +17,21 @@ import { useMutation } from '@urql/vue';
|
|||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { useToast } from '~/composables/toast';
|
import { useToast } from '~/composables/toast';
|
||||||
import { Config, useConfigHandler } from '~/composables/useConfigHandler';
|
import { useConfigHandler } from '~/composables/useConfigHandler';
|
||||||
import {
|
import {
|
||||||
EnableAndDisableSsoDocument,
|
EnableAndDisableSsoDocument,
|
||||||
ResetInfraConfigsDocument,
|
ResetInfraConfigsDocument,
|
||||||
UpdateInfraConfigsDocument,
|
|
||||||
ToggleAnalyticsCollectionDocument,
|
ToggleAnalyticsCollectionDocument,
|
||||||
|
UpdateInfraConfigsDocument,
|
||||||
} from '~/helpers/backend/graphql';
|
} from '~/helpers/backend/graphql';
|
||||||
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
workingConfigs?: Config;
|
workingConfigs?: ServerConfigs;
|
||||||
reset?: boolean;
|
reset?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,18 +58,18 @@
|
|||||||
import { useVModel } from '@vueuse/core';
|
import { useVModel } from '@vueuse/core';
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import { Config } from '~/composables/useConfigHandler';
|
import { ServerConfigs } from '~/helpers/configs';
|
||||||
import IconEye from '~icons/lucide/eye';
|
import IconEye from '~icons/lucide/eye';
|
||||||
import IconEyeOff from '~icons/lucide/eye-off';
|
import IconEyeOff from '~icons/lucide/eye-off';
|
||||||
|
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
config: Config;
|
config: ServerConfigs;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:config', v: Config): void;
|
(e: 'update:config', v: ServerConfigs): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const workingConfigs = useVModel(props, 'config', emit);
|
const workingConfigs = useVModel(props, 'config', emit);
|
||||||
@@ -87,7 +87,7 @@ const smtpConfigs = computed({
|
|||||||
// Mask sensitive fields
|
// Mask sensitive fields
|
||||||
type Field = {
|
type Field = {
|
||||||
name: string;
|
name: string;
|
||||||
key: keyof Config['mailConfigs']['fields'];
|
key: keyof ServerConfigs['mailConfigs']['fields'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const smtpConfigFields = reactive<Field[]>([
|
const smtpConfigFields = reactive<Field[]>([
|
||||||
@@ -100,10 +100,10 @@ const maskState = reactive<Record<string, boolean>>({
|
|||||||
mailer_from_address: true,
|
mailer_from_address: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const toggleMask = (fieldKey: keyof Config['mailConfigs']['fields']) => {
|
const toggleMask = (fieldKey: keyof ServerConfigs['mailConfigs']['fields']) => {
|
||||||
maskState[fieldKey] = !maskState[fieldKey];
|
maskState[fieldKey] = !maskState[fieldKey];
|
||||||
};
|
};
|
||||||
|
|
||||||
const isMasked = (fieldKey: keyof Config['mailConfigs']['fields']) =>
|
const isMasked = (fieldKey: keyof ServerConfigs['mailConfigs']['fields']) =>
|
||||||
maskState[fieldKey];
|
maskState[fieldKey];
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,83 +1,39 @@
|
|||||||
import { AnyVariables, UseMutationResponse } from '@urql/vue';
|
import { AnyVariables, UseMutationResponse } from '@urql/vue';
|
||||||
import { cloneDeep } from 'lodash-es';
|
import { cloneDeep } from 'lodash-es';
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
import { useI18n } from '~/composables/i18n';
|
import { useI18n } from '~/composables/i18n';
|
||||||
import {
|
import {
|
||||||
AllowedAuthProvidersDocument,
|
AllowedAuthProvidersDocument,
|
||||||
|
AuthProvider,
|
||||||
EnableAndDisableSsoArgs,
|
EnableAndDisableSsoArgs,
|
||||||
EnableAndDisableSsoMutation,
|
EnableAndDisableSsoMutation,
|
||||||
InfraConfigArgs,
|
InfraConfigArgs,
|
||||||
InfraConfigEnum,
|
InfraConfigEnum,
|
||||||
InfraConfigsDocument,
|
InfraConfigsDocument,
|
||||||
ResetInfraConfigsMutation,
|
ResetInfraConfigsMutation,
|
||||||
|
ServiceStatus,
|
||||||
ToggleAnalyticsCollectionMutation,
|
ToggleAnalyticsCollectionMutation,
|
||||||
UpdateInfraConfigsMutation,
|
UpdateInfraConfigsMutation,
|
||||||
} from '~/helpers/backend/graphql';
|
} from '~/helpers/backend/graphql';
|
||||||
|
import {
|
||||||
|
ALL_CONFIGS,
|
||||||
|
ConfigSection,
|
||||||
|
ConfigTransform,
|
||||||
|
GITHUB_CONFIGS,
|
||||||
|
GOOGLE_CONFIGS,
|
||||||
|
MAIL_CONFIGS,
|
||||||
|
MICROSOFT_CONFIGS,
|
||||||
|
ServerConfigs,
|
||||||
|
UpdatedConfigs,
|
||||||
|
} from '~/helpers/configs';
|
||||||
import { useToast } from './toast';
|
import { useToast } from './toast';
|
||||||
import { useClientHandler } from './useClientHandler';
|
import { useClientHandler } from './useClientHandler';
|
||||||
|
|
||||||
// Types
|
|
||||||
export type SsoAuthProviders = 'google' | 'microsoft' | 'github';
|
|
||||||
|
|
||||||
export type Config = {
|
|
||||||
providers: {
|
|
||||||
google: {
|
|
||||||
name: SsoAuthProviders;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
client_id: string;
|
|
||||||
client_secret: string;
|
|
||||||
callback_url: string;
|
|
||||||
scope: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
github: {
|
|
||||||
name: SsoAuthProviders;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
client_id: string;
|
|
||||||
client_secret: string;
|
|
||||||
callback_url: string;
|
|
||||||
scope: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
microsoft: {
|
|
||||||
name: SsoAuthProviders;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
client_id: string;
|
|
||||||
client_secret: string;
|
|
||||||
callback_url: string;
|
|
||||||
scope: string;
|
|
||||||
tenant: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
mailConfigs: {
|
|
||||||
name: string;
|
|
||||||
enabled: boolean;
|
|
||||||
fields: {
|
|
||||||
mailer_smtp_url: string;
|
|
||||||
mailer_from_address: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
dataSharingConfigs: {
|
|
||||||
name: string;
|
|
||||||
enabled: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
type UpdatedConfigs = {
|
|
||||||
name: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Composable that handles all operations related to server configurations
|
/** Composable that handles all operations related to server configurations
|
||||||
* @param updatedConfigs A Config Object contatining the updated configs
|
* @param updatedConfigs A Config Object contatining the updated configs
|
||||||
*/
|
*/
|
||||||
export function useConfigHandler(updatedConfigs?: Config) {
|
export function useConfigHandler(updatedConfigs?: ServerConfigs) {
|
||||||
const t = useI18n();
|
const t = useI18n();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
@@ -90,24 +46,9 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
} = useClientHandler(
|
} = useClientHandler(
|
||||||
InfraConfigsDocument,
|
InfraConfigsDocument,
|
||||||
{
|
{
|
||||||
configNames: [
|
configNames: ALL_CONFIGS.flat().map(
|
||||||
'GOOGLE_CLIENT_ID',
|
({ name }) => name
|
||||||
'GOOGLE_CLIENT_SECRET',
|
) as InfraConfigEnum[],
|
||||||
'GOOGLE_CALLBACK_URL',
|
|
||||||
'GOOGLE_SCOPE',
|
|
||||||
'MICROSOFT_CLIENT_ID',
|
|
||||||
'MICROSOFT_CLIENT_SECRET',
|
|
||||||
'MICROSOFT_CALLBACK_URL',
|
|
||||||
'MICROSOFT_SCOPE',
|
|
||||||
'MICROSOFT_TENANT',
|
|
||||||
'GITHUB_CLIENT_ID',
|
|
||||||
'GITHUB_CLIENT_SECRET',
|
|
||||||
'GITHUB_CALLBACK_URL',
|
|
||||||
'GITHUB_SCOPE',
|
|
||||||
'MAILER_SMTP_URL',
|
|
||||||
'MAILER_ADDRESS_FROM',
|
|
||||||
'ALLOW_ANALYTICS_COLLECTION',
|
|
||||||
] as InfraConfigEnum[],
|
|
||||||
},
|
},
|
||||||
(x) => x.infraConfigs
|
(x) => x.infraConfigs
|
||||||
);
|
);
|
||||||
@@ -125,14 +66,14 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Current and working configs
|
// Current and working configs
|
||||||
const currentConfigs = ref<Config>();
|
const currentConfigs = ref<ServerConfigs>();
|
||||||
const workingConfigs = ref<Config>();
|
const workingConfigs = ref<ServerConfigs>();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await fetchInfraConfigs();
|
await fetchInfraConfigs();
|
||||||
await fetchAllowedAuthProviders();
|
await fetchAllowedAuthProviders();
|
||||||
|
|
||||||
const getFieldValue = (name: string) =>
|
const getFieldValue = (name: InfraConfigEnum) =>
|
||||||
infraConfigs.value.find((x) => x.name === name)?.value ?? '';
|
infraConfigs.value.find((x) => x.name === name)?.value ?? '';
|
||||||
|
|
||||||
// Transforming the fetched data into a Configs object
|
// Transforming the fetched data into a Configs object
|
||||||
@@ -140,42 +81,42 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
providers: {
|
providers: {
|
||||||
google: {
|
google: {
|
||||||
name: 'google',
|
name: 'google',
|
||||||
enabled: allowedAuthProviders.value.includes('GOOGLE'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Google),
|
||||||
fields: {
|
fields: {
|
||||||
client_id: getFieldValue('GOOGLE_CLIENT_ID'),
|
client_id: getFieldValue(InfraConfigEnum.GoogleClientId),
|
||||||
client_secret: getFieldValue('GOOGLE_CLIENT_SECRET'),
|
client_secret: getFieldValue(InfraConfigEnum.GoogleClientSecret),
|
||||||
callback_url: getFieldValue('GOOGLE_CALLBACK_URL'),
|
callback_url: getFieldValue(InfraConfigEnum.GoogleCallbackUrl),
|
||||||
scope: getFieldValue('GOOGLE_SCOPE'),
|
scope: getFieldValue(InfraConfigEnum.GoogleScope),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
github: {
|
github: {
|
||||||
name: 'github',
|
name: 'github',
|
||||||
enabled: allowedAuthProviders.value.includes('GITHUB'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Github),
|
||||||
fields: {
|
fields: {
|
||||||
client_id: getFieldValue('GITHUB_CLIENT_ID'),
|
client_id: getFieldValue(InfraConfigEnum.GithubClientId),
|
||||||
client_secret: getFieldValue('GITHUB_CLIENT_SECRET'),
|
client_secret: getFieldValue(InfraConfigEnum.GithubClientSecret),
|
||||||
callback_url: getFieldValue('GITHUB_CALLBACK_URL'),
|
callback_url: getFieldValue(InfraConfigEnum.GoogleCallbackUrl),
|
||||||
scope: getFieldValue('GITHUB_SCOPE'),
|
scope: getFieldValue(InfraConfigEnum.GithubScope),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
microsoft: {
|
microsoft: {
|
||||||
name: 'microsoft',
|
name: 'microsoft',
|
||||||
enabled: allowedAuthProviders.value.includes('MICROSOFT'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Microsoft),
|
||||||
fields: {
|
fields: {
|
||||||
client_id: getFieldValue('MICROSOFT_CLIENT_ID'),
|
client_id: getFieldValue(InfraConfigEnum.MicrosoftClientId),
|
||||||
client_secret: getFieldValue('MICROSOFT_CLIENT_SECRET'),
|
client_secret: getFieldValue(InfraConfigEnum.MicrosoftClientSecret),
|
||||||
callback_url: getFieldValue('MICROSOFT_CALLBACK_URL'),
|
callback_url: getFieldValue(InfraConfigEnum.MicrosoftCallbackUrl),
|
||||||
scope: getFieldValue('MICROSOFT_SCOPE'),
|
scope: getFieldValue(InfraConfigEnum.MicrosoftScope),
|
||||||
tenant: getFieldValue('MICROSOFT_TENANT'),
|
tenant: getFieldValue(InfraConfigEnum.MicrosoftTenant),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mailConfigs: {
|
mailConfigs: {
|
||||||
name: 'email',
|
name: 'email',
|
||||||
enabled: allowedAuthProviders.value.includes('EMAIL'),
|
enabled: allowedAuthProviders.value.includes(AuthProvider.Email),
|
||||||
fields: {
|
fields: {
|
||||||
mailer_smtp_url: getFieldValue('MAILER_SMTP_URL'),
|
mailer_smtp_url: getFieldValue(InfraConfigEnum.MailerSmtpUrl),
|
||||||
mailer_from_address: getFieldValue('MAILER_ADDRESS_FROM'),
|
mailer_from_address: getFieldValue(InfraConfigEnum.MailerAddressFrom),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dataSharingConfigs: {
|
dataSharingConfigs: {
|
||||||
@@ -191,138 +132,13 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
workingConfigs.value = cloneDeep(currentConfigs.value);
|
workingConfigs.value = cloneDeep(currentConfigs.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Transforming the working configs back into the format required by the mutations
|
/*
|
||||||
const updatedInfraConfigs = computed(() => {
|
Check if any of the config fields are empty
|
||||||
let config: UpdatedConfigs[] = [
|
*/
|
||||||
{
|
|
||||||
name: '',
|
|
||||||
value: '',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (updatedConfigs?.providers.google.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_CLIENT_ID',
|
|
||||||
value: updatedConfigs?.providers.google.fields.client_id ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_CLIENT_SECRET',
|
|
||||||
value: updatedConfigs?.providers.google.fields.client_secret ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_CALLBACK_URL',
|
|
||||||
value: updatedConfigs?.providers.google.fields.callback_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GOOGLE_SCOPE',
|
|
||||||
value: updatedConfigs?.providers.google.fields.scope ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'GOOGLE_CLIENT_ID' &&
|
|
||||||
item.name !== 'GOOGLE_CLIENT_SECRET' &&
|
|
||||||
item.name !== 'GOOGLE_CALLBACK_URL' &&
|
|
||||||
item.name !== 'GOOGLE_SCOPE'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (updatedConfigs?.providers.microsoft.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_CLIENT_ID',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.client_id ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_CLIENT_SECRET',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.client_secret ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_CALLBACK_URL',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.callback_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_SCOPE',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.scope ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MICROSOFT_TENANT',
|
|
||||||
value: updatedConfigs?.providers.microsoft.fields.tenant ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'MICROSOFT_CLIENT_ID' &&
|
|
||||||
item.name !== 'MICROSOFT_CLIENT_SECRET' &&
|
|
||||||
item.name !== 'MICROSOFT_CALLBACK_URL' &&
|
|
||||||
item.name !== 'MICROSOFT_SCOPE' &&
|
|
||||||
item.name !== 'MICROSOFT_TENANT'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updatedConfigs?.providers.github.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'GITHUB_CLIENT_ID',
|
|
||||||
value: updatedConfigs?.providers.github.fields.client_id ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_CLIENT_SECRET',
|
|
||||||
value: updatedConfigs?.providers.github.fields.client_secret ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_CALLBACK_URL',
|
|
||||||
value: updatedConfigs?.providers.github.fields.callback_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'GITHUB_SCOPE',
|
|
||||||
value: updatedConfigs?.providers.github.fields.scope ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'GITHUB_CLIENT_ID' &&
|
|
||||||
item.name !== 'GITHUB_CLIENT_SECRET' &&
|
|
||||||
item.name !== 'GITHUB_CALLBACK_URL' &&
|
|
||||||
item.name !== 'GITHUB_SCOPE'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updatedConfigs?.mailConfigs.enabled) {
|
|
||||||
config.push(
|
|
||||||
{
|
|
||||||
name: 'MAILER_SMTP_URL',
|
|
||||||
value: updatedConfigs?.mailConfigs.fields.mailer_smtp_url ?? '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'MAILER_ADDRESS_FROM',
|
|
||||||
value: updatedConfigs?.mailConfigs.fields.mailer_from_address ?? '',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
config = config.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !== 'MAILER_SMTP_URL' && item.name !== 'MAILER_ADDRESS_FROM'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
config = config.filter((item) => item.name !== '');
|
|
||||||
|
|
||||||
return config;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Checking if any of the config fields are empty
|
|
||||||
const isFieldEmpty = (field: string) => field.trim() === '';
|
const isFieldEmpty = (field: string) => field.trim() === '';
|
||||||
|
|
||||||
type ConfigSection = {
|
const AreAnyConfigFieldsEmpty = (config: ServerConfigs): boolean => {
|
||||||
enabled: boolean;
|
|
||||||
fields: Record<string, string>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AreAnyConfigFieldsEmpty = (config: Config): boolean => {
|
|
||||||
const sections: Array<ConfigSection> = [
|
const sections: Array<ConfigSection> = [
|
||||||
config.providers.github,
|
config.providers.github,
|
||||||
config.providers.google,
|
config.providers.google,
|
||||||
@@ -337,28 +153,44 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Transforming the working configs back into the format required by the mutations
|
// Transforming the working configs back into the format required by the mutations
|
||||||
const updatedAllowedAuthProviders = computed(() => {
|
const transformInfraConfigs = () => {
|
||||||
return [
|
const updatedWorkingConfigs: ConfigTransform[] = [
|
||||||
{
|
{
|
||||||
provider: 'GOOGLE',
|
config: GOOGLE_CONFIGS,
|
||||||
status: updatedConfigs?.providers.google.enabled ? 'ENABLE' : 'DISABLE',
|
enabled: updatedConfigs?.providers.google.enabled,
|
||||||
|
fields: updatedConfigs?.providers.google.fields,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: 'MICROSOFT',
|
config: GITHUB_CONFIGS,
|
||||||
status: updatedConfigs?.providers.microsoft.enabled
|
enabled: updatedConfigs?.providers.github.enabled,
|
||||||
? 'ENABLE'
|
fields: updatedConfigs?.providers.github.fields,
|
||||||
: 'DISABLE',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: 'GITHUB',
|
config: MICROSOFT_CONFIGS,
|
||||||
status: updatedConfigs?.providers.github.enabled ? 'ENABLE' : 'DISABLE',
|
enabled: updatedConfigs?.providers.microsoft.enabled,
|
||||||
|
fields: updatedConfigs?.providers.microsoft.fields,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provider: 'EMAIL',
|
config: MAIL_CONFIGS,
|
||||||
status: updatedConfigs?.mailConfigs.enabled ? 'ENABLE' : 'DISABLE',
|
enabled: updatedConfigs?.mailConfigs.enabled,
|
||||||
|
fields: updatedConfigs?.mailConfigs.fields,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
|
||||||
|
const transformedConfigs: UpdatedConfigs[] = [];
|
||||||
|
|
||||||
|
updatedWorkingConfigs.forEach(({ config, enabled, fields }) => {
|
||||||
|
config.forEach(({ name, key }) => {
|
||||||
|
if (enabled && fields) {
|
||||||
|
const value =
|
||||||
|
typeof fields === 'string' ? fields : String(fields[key]);
|
||||||
|
transformedConfigs.push({ name, value });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return transformedConfigs;
|
||||||
|
};
|
||||||
|
|
||||||
// Generic function to handle mutation execution and error handling
|
// Generic function to handle mutation execution and error handling
|
||||||
const executeMutation = async <T, V>(
|
const executeMutation = async <T, V>(
|
||||||
@@ -379,27 +211,59 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
// Updating the auth provider configurations
|
// Updating the auth provider configurations
|
||||||
const updateAuthProvider = (
|
const updateAuthProvider = (
|
||||||
updateProviderStatus: UseMutationResponse<EnableAndDisableSsoMutation>
|
updateProviderStatus: UseMutationResponse<EnableAndDisableSsoMutation>
|
||||||
) =>
|
) => {
|
||||||
executeMutation(
|
const updatedAllowedAuthProviders: EnableAndDisableSsoArgs[] = [
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Google,
|
||||||
|
status: updatedConfigs?.providers.google.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Microsoft,
|
||||||
|
status: updatedConfigs?.providers.microsoft.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Github,
|
||||||
|
status: updatedConfigs?.providers.github.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provider: AuthProvider.Email,
|
||||||
|
status: updatedConfigs?.mailConfigs.enabled
|
||||||
|
? ServiceStatus.Enable
|
||||||
|
: ServiceStatus.Disable,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return executeMutation(
|
||||||
updateProviderStatus,
|
updateProviderStatus,
|
||||||
{
|
{
|
||||||
providerInfo:
|
providerInfo: updatedAllowedAuthProviders,
|
||||||
updatedAllowedAuthProviders.value as EnableAndDisableSsoArgs[],
|
|
||||||
},
|
},
|
||||||
'configs.auth_providers.update_failure'
|
'configs.auth_providers.update_failure'
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Updating the infra configurations
|
// Updating the infra configurations
|
||||||
const updateInfraConfigs = (
|
const updateInfraConfigs = (
|
||||||
updateInfraConfigsMutation: UseMutationResponse<UpdateInfraConfigsMutation>
|
updateInfraConfigsMutation: UseMutationResponse<UpdateInfraConfigsMutation>
|
||||||
) =>
|
) => {
|
||||||
executeMutation(
|
const infraConfigs: InfraConfigArgs[] = updatedConfigs
|
||||||
|
? transformInfraConfigs()
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return executeMutation(
|
||||||
updateInfraConfigsMutation,
|
updateInfraConfigsMutation,
|
||||||
{
|
{
|
||||||
infraConfigs: updatedInfraConfigs.value as InfraConfigArgs[],
|
infraConfigs,
|
||||||
},
|
},
|
||||||
'configs.mail_configs.update_failure'
|
'configs.update_failure'
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Resetting the infra configurations
|
// Resetting the infra configurations
|
||||||
const resetInfraConfigs = (
|
const resetInfraConfigs = (
|
||||||
@@ -411,7 +275,6 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
'configs.reset.failure'
|
'configs.reset.failure'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Updating the data sharing configurations
|
|
||||||
const updateDataSharingConfigs = (
|
const updateDataSharingConfigs = (
|
||||||
toggleDataSharingMutation: UseMutationResponse<ToggleAnalyticsCollectionMutation>
|
toggleDataSharingMutation: UseMutationResponse<ToggleAnalyticsCollectionMutation>
|
||||||
) =>
|
) =>
|
||||||
@@ -419,8 +282,8 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
toggleDataSharingMutation,
|
toggleDataSharingMutation,
|
||||||
{
|
{
|
||||||
status: updatedConfigs?.dataSharingConfigs.enabled
|
status: updatedConfigs?.dataSharingConfigs.enabled
|
||||||
? 'ENABLE'
|
? ServiceStatus.Enable
|
||||||
: 'DISABLE',
|
: ServiceStatus.Disable,
|
||||||
},
|
},
|
||||||
'configs.data_sharing.update_failure'
|
'configs.data_sharing.update_failure'
|
||||||
);
|
);
|
||||||
@@ -428,8 +291,6 @@ export function useConfigHandler(updatedConfigs?: Config) {
|
|||||||
return {
|
return {
|
||||||
currentConfigs,
|
currentConfigs,
|
||||||
workingConfigs,
|
workingConfigs,
|
||||||
updatedInfraConfigs,
|
|
||||||
updatedAllowedAuthProviders,
|
|
||||||
updateAuthProvider,
|
updateAuthProvider,
|
||||||
updateDataSharingConfigs,
|
updateDataSharingConfigs,
|
||||||
updateInfraConfigs,
|
updateInfraConfigs,
|
||||||
|
|||||||
160
packages/hoppscotch-sh-admin/src/helpers/configs.ts
Normal file
160
packages/hoppscotch-sh-admin/src/helpers/configs.ts
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
import { InfraConfigEnum } from './backend/graphql';
|
||||||
|
|
||||||
|
export type SsoAuthProviders = 'google' | 'microsoft' | 'github';
|
||||||
|
|
||||||
|
export type ServerConfigs = {
|
||||||
|
providers: {
|
||||||
|
google: {
|
||||||
|
name: SsoAuthProviders;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
callback_url: string;
|
||||||
|
scope: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
github: {
|
||||||
|
name: SsoAuthProviders;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
callback_url: string;
|
||||||
|
scope: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
microsoft: {
|
||||||
|
name: SsoAuthProviders;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
client_id: string;
|
||||||
|
client_secret: string;
|
||||||
|
callback_url: string;
|
||||||
|
scope: string;
|
||||||
|
tenant: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mailConfigs: {
|
||||||
|
name: string;
|
||||||
|
enabled: boolean;
|
||||||
|
fields: {
|
||||||
|
mailer_smtp_url: string;
|
||||||
|
mailer_from_address: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
dataSharingConfigs: {
|
||||||
|
name: string;
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UpdatedConfigs = {
|
||||||
|
name: InfraConfigEnum;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConfigTransform = {
|
||||||
|
config: Config[];
|
||||||
|
enabled?: boolean;
|
||||||
|
fields?: Record<string, string | boolean> | string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConfigSection = {
|
||||||
|
enabled: boolean;
|
||||||
|
fields: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Config = {
|
||||||
|
name: InfraConfigEnum;
|
||||||
|
key: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GOOGLE_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleClientId,
|
||||||
|
key: 'client_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleClientSecret,
|
||||||
|
key: 'client_secret',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleCallbackUrl,
|
||||||
|
key: 'callback_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GoogleScope,
|
||||||
|
key: 'scope',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MICROSOFT_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftClientId,
|
||||||
|
key: 'client_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftClientSecret,
|
||||||
|
key: 'client_secret',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftCallbackUrl,
|
||||||
|
key: 'callback_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftScope,
|
||||||
|
key: 'scope',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MicrosoftTenant,
|
||||||
|
key: 'tenant',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const GITHUB_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubClientId,
|
||||||
|
key: 'client_id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubClientSecret,
|
||||||
|
key: 'client_secret',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubCallbackUrl,
|
||||||
|
key: 'callback_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.GithubScope,
|
||||||
|
key: 'scope',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const MAIL_CONFIGS: Config[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MailerSmtpUrl,
|
||||||
|
key: 'mailer_smtp_url',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.MailerAddressFrom,
|
||||||
|
key: 'mailer_from_address',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const DATA_SHARING_CONFIGS: Omit<Config, 'key'>[] = [
|
||||||
|
{
|
||||||
|
name: InfraConfigEnum.AllowAnalyticsCollection,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const ALL_CONFIGS = [
|
||||||
|
GOOGLE_CONFIGS,
|
||||||
|
MICROSOFT_CONFIGS,
|
||||||
|
GITHUB_CONFIGS,
|
||||||
|
MAIL_CONFIGS,
|
||||||
|
DATA_SHARING_CONFIGS,
|
||||||
|
];
|
||||||
@@ -208,13 +208,14 @@ const deleteUserMutation = async (id: string | null) => {
|
|||||||
if (result.error) {
|
if (result.error) {
|
||||||
toast.error(t('state.delete_user_failure'));
|
toast.error(t('state.delete_user_failure'));
|
||||||
} else {
|
} else {
|
||||||
const deletedUsers = result.data?.removeUsersByAdmin || [];
|
const deletedUser = result.data?.removeUsersByAdmin || [];
|
||||||
|
handleUserDeletion(deletedUser);
|
||||||
|
|
||||||
handleUserDeletion(deletedUsers);
|
const { isDeleted } = deletedUser[0];
|
||||||
|
if (isDeleted) router.push('/users');
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDeletion.value = false;
|
confirmDeletion.value = false;
|
||||||
deleteUserUID.value = null;
|
deleteUserUID.value = null;
|
||||||
|
|
||||||
!result.error && router.push('/users');
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
34120
pnpm-lock.yaml
generated
34120
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user