forked from cerc-io/snowballtools-base
Add script to load fixture data in database (#34)
* Add fixture data and populate database with it * Use node to run commands in package scripts * Move test directory out of src directory * Save projects with user and organization relation * Refactor and add generalized function to load data * Populate userOrganization entity with test data * Change project id type from number to string --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
committed by
Ashwin Phatak
co-authored by
neeraj
parent
3829485672
commit
890603061f
@@ -21,16 +21,21 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "DEBUG=snowball:* ts-node ./src/index.ts",
|
||||
"build": "tsc",
|
||||
"start": "DEBUG=snowball:* node --enable-source-maps ./dist/index.js",
|
||||
"start:dev": "DEBUG=snowball:* ts-node ./src/index.ts",
|
||||
"copy-assets": "copyfiles -u 1 src/**/*.gql dist/",
|
||||
"clean": "rm -rf ./dist",
|
||||
"build": "yarn clean && tsc && yarn copy-assets",
|
||||
"lint": "eslint .",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check ."
|
||||
"format:check": "prettier --check .",
|
||||
"db:load:fixtures": "ts-node ./test/initialize-db.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^6.18.1",
|
||||
"@typescript-eslint/parser": "^6.18.1",
|
||||
"copyfiles": "^2.4.1",
|
||||
"better-sqlite3": "^9.2.2",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"name": "Snowball Tools"
|
||||
},
|
||||
{
|
||||
"name": "AirFoil"
|
||||
}
|
||||
]
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
[
|
||||
{
|
||||
"ownerIndex":0,
|
||||
"organizationIndex":0,
|
||||
"name": "testProject",
|
||||
"repository": "test",
|
||||
"prodBranch": "main",
|
||||
"description": "test",
|
||||
"template": "test",
|
||||
"framework": "test",
|
||||
"webhooks": []
|
||||
},
|
||||
{
|
||||
"ownerIndex":1,
|
||||
"organizationIndex":0,
|
||||
"name": "testProject-2",
|
||||
"repository": "test-2",
|
||||
"prodBranch": "main",
|
||||
"description": "test-2",
|
||||
"template": "test-2",
|
||||
"framework": "test-2",
|
||||
"webhooks": []
|
||||
},
|
||||
{
|
||||
"ownerIndex":2,
|
||||
"organizationIndex":0,
|
||||
"name": "iglootools",
|
||||
"repository": "test-3",
|
||||
"prodBranch": "main",
|
||||
"description": "test-3",
|
||||
"template": "test-3",
|
||||
"framework": "test-3",
|
||||
"webhooks": []
|
||||
},
|
||||
{
|
||||
"ownerIndex":1,
|
||||
"organizationIndex":0,
|
||||
"name": "iglootools-2",
|
||||
"repository": "test-4",
|
||||
"prodBranch": "main",
|
||||
"description": "test-4",
|
||||
"template": "test-4",
|
||||
"framework": "test-4",
|
||||
"webhooks": []
|
||||
},
|
||||
{
|
||||
"ownerIndex":0,
|
||||
"organizationIndex":1,
|
||||
"name": "snowball-2",
|
||||
"repository": "test-5",
|
||||
"prodBranch": "main",
|
||||
"description": "test-5",
|
||||
"template": "test-5",
|
||||
"framework": "test-5",
|
||||
"webhooks": []
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"role": "Owner",
|
||||
"memberIndex": 0,
|
||||
"organizationIndex": 0
|
||||
},
|
||||
{
|
||||
"role": "Maintainer",
|
||||
"memberIndex": 1,
|
||||
"organizationIndex": 0
|
||||
},
|
||||
{
|
||||
"role": "Owner",
|
||||
"memberIndex": 2,
|
||||
"organizationIndex": 0
|
||||
},
|
||||
{
|
||||
"role": "Owner",
|
||||
"memberIndex": 0,
|
||||
"organizationIndex": 1
|
||||
}
|
||||
]
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"name": "Saugat Yadav",
|
||||
"email": "saugaty@airfoil.studio"
|
||||
},
|
||||
{
|
||||
"name": "Gideon Low",
|
||||
"email": "gideonl@airfoil.studio"
|
||||
},
|
||||
{
|
||||
"name": "Sushan Yadav",
|
||||
"email": "sushany@airfoil.studio"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,94 @@
|
||||
import { DataSource, DeepPartial, EntityTarget, ObjectLiteral } from 'typeorm';
|
||||
import * as fs from 'fs/promises';
|
||||
import debug from 'debug';
|
||||
import path from 'path';
|
||||
|
||||
import { User } from '../src/entity/User';
|
||||
import { Organization } from '../src/entity/Organization';
|
||||
import { Project } from '../src/entity/Project';
|
||||
import { UserOrganization } from '../src/entity/UserOrganization';
|
||||
import { EnvironmentVariable } from '../src/entity/EnvironmentVariable';
|
||||
import { Domain } from '../src/entity/Domain';
|
||||
import { ProjectMember } from '../src/entity/ProjectMember';
|
||||
import { Deployment } from '../src/entity/Deployment';
|
||||
|
||||
const log = debug('snowball:initialize-database');
|
||||
|
||||
const USER_DATA_PATH = './fixtures/users.json';
|
||||
const PROJECT_DATA_PATH = './fixtures/projects.json';
|
||||
const ORGANIZATION_DATA_PATH = './fixtures/organizations.json';
|
||||
const USER_ORGANIZATION_DATA_PATH = './fixtures/user-orgnizations.json';
|
||||
|
||||
const loadAndSaveData = async <Entity extends ObjectLiteral>(entityType: EntityTarget<Entity>, dataSource: DataSource, filePath: string) => {
|
||||
const entitiesData = await fs.readFile(filePath, 'utf-8');
|
||||
const entities = JSON.parse(entitiesData) as DeepPartial<Entity>[];
|
||||
const entityRepository = dataSource.getRepository(entityType);
|
||||
|
||||
const savedEntity:Entity[] = [];
|
||||
|
||||
for (const entityData of entities) {
|
||||
const entity = entityRepository.create(entityData);
|
||||
const dbEntity = await entityRepository.save(entity);
|
||||
savedEntity.push(dbEntity);
|
||||
}
|
||||
|
||||
return savedEntity;
|
||||
};
|
||||
|
||||
const generateTestData = async (dataSource: DataSource) => {
|
||||
const savedUsers = await loadAndSaveData(User, dataSource, path.resolve(__dirname, USER_DATA_PATH));
|
||||
const savedOrgs = await loadAndSaveData(Organization, dataSource, path.resolve(__dirname, ORGANIZATION_DATA_PATH));
|
||||
|
||||
const projectsData = await fs.readFile(path.resolve(__dirname, PROJECT_DATA_PATH), 'utf-8');
|
||||
const projects = JSON.parse(projectsData);
|
||||
const projectRepository = dataSource.getRepository(Project);
|
||||
|
||||
for (const projectData of projects) {
|
||||
const project = projectRepository.create(projectData as DeepPartial<Project>);
|
||||
project.owner = savedUsers[projectData.ownerIndex];
|
||||
project.organization = savedOrgs[projectData.organizationIndex];
|
||||
await projectRepository.save(project);
|
||||
}
|
||||
|
||||
const userOrgData = await fs.readFile(path.resolve(__dirname, USER_ORGANIZATION_DATA_PATH), 'utf-8');
|
||||
const userOrgs = JSON.parse(userOrgData);
|
||||
const userOrgRepository = dataSource.getRepository(UserOrganization);
|
||||
|
||||
for (const userOrgData of userOrgs) {
|
||||
const userOrg = userOrgRepository.create(userOrgData as DeepPartial<UserOrganization>);
|
||||
userOrg.member = savedUsers[userOrgData.memberIndex];
|
||||
userOrg.organization = savedOrgs[userOrgData.organizationIndex];
|
||||
|
||||
await userOrgRepository.save(userOrg);
|
||||
}
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const dataSource = new DataSource({
|
||||
type: 'better-sqlite3',
|
||||
database: 'db/snowball',
|
||||
synchronize: true,
|
||||
logging: true,
|
||||
entities: [
|
||||
User,
|
||||
Organization,
|
||||
Project,
|
||||
UserOrganization,
|
||||
EnvironmentVariable,
|
||||
Domain,
|
||||
ProjectMember,
|
||||
Deployment
|
||||
]
|
||||
});
|
||||
|
||||
await dataSource.initialize();
|
||||
|
||||
await generateTestData(dataSource);
|
||||
};
|
||||
|
||||
main().then(() => {
|
||||
log('Data loaded successfully');
|
||||
})
|
||||
.catch((err) => {
|
||||
log(err);
|
||||
});
|
||||
@@ -15,10 +15,10 @@ const Domains = () => {
|
||||
const { projects } = useOutletContext<ProjectsOutletContext>();
|
||||
|
||||
const currProject = useMemo(() => {
|
||||
return projects.find((data) => {
|
||||
return Number(data?.id) === Number(id);
|
||||
return projects.find((project) => {
|
||||
return project.id === id;
|
||||
});
|
||||
}, [id]);
|
||||
}, [id, projects]);
|
||||
|
||||
const linkedRepo = useMemo(() => {
|
||||
return currProject?.repositories.find(
|
||||
@@ -27,10 +27,10 @@ const Domains = () => {
|
||||
}, [currProject]);
|
||||
|
||||
const domains = currProject?.deployments
|
||||
.filter((deployment: any) => {
|
||||
.filter((deployment) => {
|
||||
return deployment.domain != null;
|
||||
})
|
||||
.map((deployment: any) => deployment.domain);
|
||||
.map((deployment) => deployment.domain);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
+4
-2
@@ -39,8 +39,10 @@ export const EnvironmentVariablesTabPanel = () => {
|
||||
const { projects } = useOutletContext<ProjectsOutletContext>();
|
||||
|
||||
const currProject = useMemo(() => {
|
||||
return projects.find((data) => Number(data.id) === Number(id));
|
||||
}, [id]);
|
||||
return projects.find((project) => {
|
||||
return project.id === id;
|
||||
});
|
||||
}, [id, projects]);
|
||||
|
||||
const {
|
||||
handleSubmit,
|
||||
|
||||
@@ -7,22 +7,17 @@ import HorizontalLine from '../../components/HorizontalLine';
|
||||
import ProjectTabs from '../../components/projects/project/ProjectTabs';
|
||||
import { ProjectsOutletContext } from '../../types/project';
|
||||
|
||||
const getProject = (projects: any, id: number) => {
|
||||
return projects.find((project: any) => {
|
||||
return Number(project.id) === id;
|
||||
});
|
||||
};
|
||||
|
||||
const Project = () => {
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { projects } = useOutletContext<ProjectsOutletContext>();
|
||||
|
||||
const project = useMemo(
|
||||
() => getProject(projects, Number(id)),
|
||||
[id, projects],
|
||||
);
|
||||
const project = useMemo(() => {
|
||||
return projects.find((project) => {
|
||||
return project.id === id;
|
||||
});
|
||||
}, [id, projects]);
|
||||
|
||||
return (
|
||||
<div className="h-full">
|
||||
|
||||
@@ -6,7 +6,7 @@ export interface ProjectDetails {
|
||||
description: string;
|
||||
url: string;
|
||||
domain: string | null;
|
||||
id: number;
|
||||
id: string;
|
||||
createdAt: string;
|
||||
createdBy: string;
|
||||
deployments: DeploymentDetails[];
|
||||
@@ -31,6 +31,7 @@ export interface MemberPermission {
|
||||
export interface DeploymentDetails {
|
||||
title: string;
|
||||
isProduction: boolean;
|
||||
domain: DomainDetails;
|
||||
status: Status;
|
||||
branch: string;
|
||||
environment: Environments;
|
||||
|
||||
Reference in New Issue
Block a user