Skip to content

Commit 21f9bbb

Browse files
authored
Merge pull request #854 from 06kellyjac/data_layer
refactor(experimental): abstract data layer
2 parents 1df2381 + 4c2a36d commit 21f9bbb

File tree

20 files changed

+470
-208
lines changed

20 files changed

+470
-208
lines changed

experimental/license-inventory/package-lock.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

experimental/license-inventory/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@types/express": "^5.0.0",
3939
"@types/mongoose": "^5.11.97",
4040
"@types/node": "^22.10.1",
41+
"@types/semver": "^7.5.8",
4142
"@types/supertest": "^6.0.2",
4243
"@typescript-eslint/eslint-plugin": "^8.17.0",
4344
"@typescript-eslint/parser": "^8.17.0",
Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,42 @@
11
import express from 'express';
22
import { logger } from '@/logger';
3-
import apiRouter from '@/routes/api';
3+
import createApiRouter from '@/routes/api';
44
import pinoHTTP from 'pino-http';
55
import bodyParser from 'body-parser';
66
import { rateLimit } from 'express-rate-limit';
77
import helmet from 'helmet';
8+
import { LicenseDataService } from './services/data';
89
// import lusca from 'lusca';
910

1011
// helmet and lusca comparison
1112
// https://github.com/krakenjs/lusca/issues/42#issuecomment-65093906
1213
// TODO: integrate lusca once added sessions/auth
1314

14-
const app = express();
15+
const createApp = (lds: LicenseDataService) => {
16+
const app = express();
1517

16-
const limiter = rateLimit({
17-
windowMs: 15 * 60 * 1000,
18-
limit: 100,
19-
standardHeaders: 'draft-7',
20-
legacyHeaders: false,
21-
// in memory store
22-
});
18+
const limiter = rateLimit({
19+
windowMs: 15 * 60 * 1000,
20+
limit: 100,
21+
standardHeaders: 'draft-7',
22+
legacyHeaders: false,
23+
// in memory store
24+
});
2325

24-
app.use(helmet());
25-
app.use(limiter);
26-
app.use(bodyParser.json());
27-
app.use(
28-
pinoHTTP({
29-
logger,
30-
autoLogging: process.env.NODE_ENV === 'development',
31-
// overrides core logger redaction
32-
// please update in logger.ts
33-
// redact: [],
34-
}),
35-
);
26+
app.use(helmet());
27+
app.use(limiter);
28+
app.use(bodyParser.json());
29+
app.use(
30+
pinoHTTP({
31+
logger,
32+
autoLogging: process.env.NODE_ENV === 'development',
33+
// overrides core logger redaction
34+
// please update in logger.ts
35+
// redact: [],
36+
}),
37+
);
3638

37-
app.use('/api', apiRouter);
38-
39-
export { app };
39+
app.use('/api', createApiRouter(lds));
40+
return app;
41+
};
42+
export { createApp };

experimental/license-inventory/src/db/connect.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { AsyncResult } from '@/types';
2-
import mongoose from 'mongoose';
2+
import mongoose, { type Mongoose } from 'mongoose';
33

4-
export const connectDB = async (dbURI: string): AsyncResult<void> => {
4+
export const connectDB = async (dbURI: string): AsyncResult<Mongoose> => {
55
try {
6-
await mongoose.connect(dbURI);
7-
return { error: null, data: null };
6+
const connection = await mongoose.connect(dbURI);
7+
return { error: null, data: connection };
88
} catch (e: unknown) {
99
if (e instanceof Error) {
1010
return { error: e, data: null };
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { Mongoose, Model } from 'mongoose';
2+
import { licenseSchema, type LicenseSchema } from './schemas/license/license';
3+
4+
export class Database {
5+
mongoose: Mongoose;
6+
License: Model<LicenseSchema>;
7+
constructor(mongoose: Mongoose) {
8+
this.mongoose = mongoose;
9+
this.License = mongoose.model<LicenseSchema>('License', licenseSchema);
10+
}
11+
}
Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { describe, expect, it } from '@jest/globals';
22
import { License } from '@/db/collections';
3-
import { licenseValidation } from './license';
43
import { v4 as uuidv4 } from 'uuid';
54

65
// these tests require a mongodb instance
@@ -16,7 +15,7 @@ describeDB('license', () => {
1615

1716
const insertedLicense = await License.findOne({ _id: _id });
1817
expect(insertedLicense).not.toBeNull();
19-
expect(insertedLicense.name).toBe('hello');
18+
expect(insertedLicense!.name).toBe('hello');
2019
});
2120

2221
it('can insert a complex license', async () => {
@@ -37,30 +36,7 @@ describeDB('license', () => {
3736

3837
const insertedLicense = await License.findOne({ _id: _id });
3938
expect(insertedLicense).not.toBeNull();
40-
expect(insertedLicense.name).toBe('complex');
41-
expect(insertedLicense.chooseALicenseInfo.permissions.commercialUse).toBe(true);
42-
});
43-
44-
it('complex license conforms to output validation', async () => {
45-
const _id = uuidv4();
46-
await License.create({
47-
_id,
48-
name: 'complex2',
49-
spdxID: 'sample2',
50-
chooseALicenseInfo: {
51-
permissions: {
52-
commercialUse: true,
53-
},
54-
conditions: {
55-
networkUseDisclose: false,
56-
},
57-
},
58-
});
59-
60-
const insertedLicense = await (await License.findOne({ _id }).exec()).toJSON();
61-
const { error, data } = licenseValidation.safeParse(insertedLicense);
62-
expect(error).toBeUndefined();
63-
expect(data.id).toBe(_id);
64-
expect(!Object.keys(data).includes('_id'));
39+
expect(insertedLicense!.name).toBe('complex');
40+
expect(insertedLicense!.chooseALicenseInfo?.permissions?.commercialUse).toBe(true);
6541
});
6642
});

experimental/license-inventory/src/db/schemas/license/license.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,6 @@ export const licenseSchema = new Schema<LicenseSchema>(
2424
{
2525
// automatic createdAt updatedAt
2626
timestamps: true,
27-
toObject: {
28-
virtuals: true,
29-
versionKey: false,
30-
transform: (doc, ret) => {
31-
delete ret._id;
32-
},
33-
},
34-
toJSON: {
35-
virtuals: true,
36-
versionKey: false,
37-
transform: (doc, ret) => {
38-
delete ret._id;
39-
},
40-
},
41-
virtuals: {
42-
id: {
43-
get() {
44-
return this._id.toString();
45-
},
46-
},
47-
},
4827
},
4928
);
5029

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { z } from 'zod';
22

3-
const envSchema = z.object({
4-
PORT: z.coerce.number().default(3000),
5-
MONGO_URI: z.string(),
6-
});
3+
const envSchema = z
4+
.object({
5+
PORT: z.coerce.number().default(3000),
6+
MONGO_URI: z.string(),
7+
})
8+
.required();
79

810
const { error, data: env } = envSchema.safeParse(process.env);
911
if (error) {
1012
console.error(error);
1113
throw new Error('failed to validate');
1214
}
1315

14-
export default env;
16+
export default env as z.infer<typeof envSchema>;
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import express from 'express';
2-
import v0Router from './v0';
3-
const router = express.Router();
2+
import createV0Router from './v0';
3+
import { LicenseDataService } from '@/services/data';
44

5-
router.use('/v0', v0Router);
5+
const createRouter = (lds: LicenseDataService) => {
6+
const router = express.Router();
67

7-
export default router;
8+
router.use('/v0', createV0Router(lds));
9+
return router;
10+
};
11+
12+
export default createRouter;
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import express from 'express';
2-
import licensesRouter from './licenses';
3-
const router = express.Router();
2+
import createLicensesRouter from './licenses';
3+
import { LicenseDataService } from '@/services/data';
44

5-
router.use('/licenses', licensesRouter);
5+
const createRouter = (lds: LicenseDataService) => {
6+
const router = express.Router();
67

7-
export default router;
8+
router.use('/licenses', createLicensesRouter(lds));
9+
return router;
10+
};
11+
12+
export default createRouter;

0 commit comments

Comments
 (0)