Skip to content

Commit 17b88e3

Browse files
authored
Merge pull request #349 from mnfst/mysql
✨ Mysql connection
2 parents a8b9258 + 488d752 commit 17b88e3

29 files changed

+907
-409
lines changed

.changeset/green-queens-work.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'manifest': minor
3+
---
4+
5+
added MySQL / MariaDB connection, Thanks @stefanolab

package-lock.json

+19-27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"moduleFileExtensions": ["js", "json", "ts"],
3+
"rootDir": ".",
4+
"testEnvironment": "node",
5+
"testRegex": ".e2e-spec.ts$",
6+
"transform": {
7+
"^.+\\.ts$": "ts-jest"
8+
},
9+
"maxWorkers": 1,
10+
"setupFilesAfterEnv": ["./jest.mysql-setup.ts"],
11+
"moduleNameMapper": {
12+
"^@repo/types$": "<rootDir>/../../types/src",
13+
"^@repo/common$": "<rootDir>/../../common/src",
14+
"^@repo/json-schema$": "<rootDir>/../../json-schema/src"
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { Test, TestingModule } from '@nestjs/testing'
2+
import { AppModule } from '../src/app.module'
3+
import { YamlService } from '../src/manifest/services/yaml.service'
4+
import { INestApplication } from '@nestjs/common'
5+
import supertest from 'supertest'
6+
import { load } from 'js-yaml'
7+
import fs from 'fs'
8+
import { SwaggerModule } from '@nestjs/swagger'
9+
import { OpenApiService } from '../src/open-api/services/open-api.service'
10+
import { SeederService } from '../src/seed/services/seeder.service'
11+
import { MySqlContainer, StartedMySqlContainer } from '@testcontainers/mysql'
12+
13+
import path from 'path'
14+
15+
let app: INestApplication
16+
17+
jest.setTimeout(30000) // Increase the timeout because the MySQL container takes a while to start.
18+
19+
beforeAll(async () => {
20+
// Set environment variables for testing.
21+
process.env.NODE_ENV = 'test'
22+
process.env.TOKEN_SECRET_KEY = 'test'
23+
process.env.MANIFEST_HANDLERS_FOLDER = path.join(
24+
__dirname,
25+
'assets',
26+
'handlers'
27+
)
28+
29+
process.env.DB_CONNECTION = 'mysql'
30+
process.env.DB_DROP_SCHEMA = 'true'
31+
32+
// Start a PostgreSQL test container
33+
const mysqlContainer: StartedMySqlContainer = await new MySqlContainer()
34+
.withDatabase('test')
35+
.withUsername('test')
36+
.withRootPassword('test')
37+
.start()
38+
39+
process.env.DB_HOST = mysqlContainer.getHost()
40+
process.env.DB_PORT = mysqlContainer.getPort().toString()
41+
process.env.DB_USERNAME = 'test'
42+
process.env.DB_PASSWORD = 'test'
43+
process.env.DB_DATABASE = 'test'
44+
45+
// Start the NestJS application mocking some services.
46+
const moduleFixture: TestingModule = await Test.createTestingModule({
47+
imports: [AppModule]
48+
})
49+
.overrideProvider(YamlService)
50+
.useValue({
51+
load: () =>
52+
load(
53+
fs.readFileSync(
54+
`${process.cwd()}/e2e/assets/mock-backend.yml`,
55+
'utf8'
56+
)
57+
)
58+
})
59+
.compile()
60+
61+
app = moduleFixture.createNestApplication()
62+
63+
// Seed the database with the mock data.
64+
const seedService = app.get(SeederService)
65+
await seedService.seed('admin')
66+
await seedService.seed('cat')
67+
await seedService.seed('university')
68+
await seedService.seed('author')
69+
await seedService.seed('tag')
70+
await seedService.seed('note')
71+
72+
// Store request object in global scope to use in tests.
73+
global.request = supertest(app.getHttpServer())
74+
75+
// Set the SwaggerModule to serve the OpenAPI doc.
76+
const openApiService = app.get(OpenApiService)
77+
SwaggerModule.setup('api', app, openApiService.generateOpenApiObject())
78+
79+
await app.init()
80+
})
81+
82+
afterAll(async () => {
83+
delete global.request
84+
await app.close()
85+
})

packages/core/manifest/e2e/jest.pg-setup.ts

-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ beforeAll(async () => {
4444
process.env.DB_USERNAME = 'test'
4545
process.env.DB_PASSWORD = 'test'
4646
process.env.DB_DATABASE = 'test'
47-
process.env.DB_TYPE = 'postgres'
4847

4948
// Start the NestJS application mocking some services.
5049
const moduleFixture: TestingModule = await Test.createTestingModule({

packages/core/manifest/e2e/tests/collection-crud.e2e-spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('Collection CRUD (e2e)', () => {
99
birthdate: '2024-01-01',
1010
price: 100,
1111
isGoodBoy: true,
12-
acquiredAt: new Date().toISOString(),
12+
acquiredAt: '2025-01-05T08:19:02.000Z',
1313
1414
favoriteToy: 'ball',
1515
location: { lat: 12, lng: 13 }

packages/core/manifest/package.json

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"description": "The 1-file micro-backend",
55
"author": "Manifest",
66
"license": "MIT",
7+
"main": "dist/manifest/main.js",
8+
"types": "dist/manifest/main.d.ts",
79
"homepage": "https://manifest.build",
810
"repository": {
911
"type": "git",
@@ -45,6 +47,7 @@
4547
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
4648
"test:e2e:sqlite": "jest --config ./e2e/jest-e2e.sqlite-config.json",
4749
"test:e2e:postgres": "jest --config ./e2e/jest-e2e.pg-config.json",
50+
"test:e2e:mysql": "jest --config ./e2e/jest-e2e.mysql-config.json",
4851
"test:e2e": "npm run test:e2e:sqlite && npm run test:e2e:postgres",
4952
"test:e2e:ci": "npm run test:e2e:sqlite -- --ci && npm run test:e2e:postgres -- --ci",
5053
"test:unit": "jest --config ./jest.config.json",
@@ -79,6 +82,7 @@
7982
"jsonwebtoken": "^9.0.2",
8083
"livereload": "^0.9.3",
8184
"mock-fs": "^5.5.0",
85+
"mysql2": "^3.12.0",
8286
"node-fetch": "^3.3.2",
8387
"nodemon": "^3.1.9",
8488
"pg": "^8.13.3",
@@ -97,6 +101,7 @@
97101
"@nestjs/cli": "^10.4.7",
98102
"@nestjs/schematics": "^10.2.3",
99103
"@nestjs/testing": "^10.4.8",
104+
"@testcontainers/mysql": "^10.18.0",
100105
"@testcontainers/postgresql": "^10.18.0",
101106
"@types/bcrypt": "^5.0.2",
102107
"@types/dasherize": "^2.0.3",

packages/core/manifest/src/app.module.ts

+23-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'
22
import { ConfigModule, ConfigService } from '@nestjs/config'
33

44
import { TypeOrmModule } from '@nestjs/typeorm'
5+
import { DatabaseConnection } from '@repo/types'
56
import { EntitySchema } from 'typeorm'
67
import { AuthModule } from './auth/auth.module'
78
import databaseConfig from './config/database'
@@ -29,7 +30,9 @@ import { SdkModule } from './sdk/sdk.module'
2930
import { SqliteConnectionOptions } from 'typeorm/driver/sqlite/SqliteConnectionOptions'
3031
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions'
3132
import { MiddlewareModule } from './middleware/middleware.module'
32-
import { EventModule } from './event/event.module';
33+
import { EventModule } from './event/event.module'
34+
35+
import { MysqlConnectionOptions } from 'typeorm/driver/mysql/MysqlConnectionOptions'
3336

3437
@Module({
3538
imports: [
@@ -45,22 +48,32 @@ import { EventModule } from './event/event.module';
4548
entityLoaderService: EntityLoaderService,
4649
manifestService: ManifestService
4750
) => {
48-
const isPostgres: boolean =
49-
configService.get('DB_CONNECTION') === 'postgres'
50-
51-
let databaseConfig: SqliteConnectionOptions | PostgresConnectionOptions
51+
let dbConnection: DatabaseConnection
52+
let databaseConfig:
53+
| SqliteConnectionOptions
54+
| PostgresConnectionOptions
55+
| MysqlConnectionOptions
5256

53-
if (isPostgres) {
54-
databaseConfig = configService.get('database').postgres
55-
} else {
56-
databaseConfig = configService.get('database').sqlite
57+
switch (configService.get('DB_CONNECTION')) {
58+
case 'postgres':
59+
dbConnection = 'postgres'
60+
databaseConfig = configService.get('database').postgres
61+
break
62+
case 'mysql':
63+
dbConnection = 'mysql'
64+
databaseConfig = configService.get('database').mysql
65+
break
66+
default:
67+
dbConnection = 'sqlite'
68+
databaseConfig = configService.get('database').sqlite
69+
break
5770
}
5871

5972
await manifestService.loadManifest(
6073
configService.get('paths').manifestFile
6174
)
6275
const entities: EntitySchema[] =
63-
entityLoaderService.loadEntities(isPostgres)
76+
entityLoaderService.loadEntities(dbConnection)
6477

6578
return Object.assign(databaseConfig, { entities })
6679
},

0 commit comments

Comments
 (0)