Skip to content

Commit 4c2a36d

Browse files
committed
fix(experimental): enable strict typing
Removed the transforms via Mongoose as they're very hard to typecheck
1 parent 984dc5c commit 4c2a36d

File tree

14 files changed

+117
-89
lines changed

14 files changed

+117
-89
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: 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>;

experimental/license-inventory/src/routes/api/v0/licenses.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ describe(basePath, () => {
4040
const testID = '157c0c6a-5c99-4298-9529-95816da2255a';
4141
it('invalid id - not uuid', async () => {
4242
const mockLDS = genMockLicenseDataService();
43-
mockLDS.getByUUID.mockResolvedValueOnce({ error: null, data: null });
43+
mockLDS.getByUUID.mockRejectedValueOnce(null);
4444
const app = createApp(mockLDS);
4545
await request(app)
4646
.get(genRoute('/' + 'apache-2_0'))
4747
.expect('Content-Type', /json/)
4848
.expect(500);
49+
expect(mockLDS.getByUUID.mock.lastCall).toBeUndefined();
4950
});
5051

5152
it('valid id - no data', async () => {

experimental/license-inventory/src/routes/api/v0/licenses.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const createRouter = (licenseService: LicenseDataService) => {
2525
res.status(500).json({ error: 'failed to create' }).end();
2626
return;
2727
}
28-
res.status(200).json({ created: data }).end();
28+
res.status(201).json(data).end();
2929
});
3030

3131
// READ
@@ -69,13 +69,13 @@ const createRouter = (licenseService: LicenseDataService) => {
6969
params: { id },
7070
} = parseData;
7171

72-
const { error } = await licenseService.patchByUUID(id, licenseData);
72+
const { error, data } = await licenseService.patchByUUID(id, licenseData);
7373
if (error) {
7474
req.log.error(error);
7575
res.status(500).json({ error: 'failed to update' }).end();
7676
return;
7777
}
78-
res.status(204).json({ status: 'ok' }).end();
78+
res.status(204).json(data).end();
7979
});
8080

8181
// DELETE

experimental/license-inventory/src/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { logger } from '@/logger';
22
import { connectDB } from './db/connect';
33
import env from '@/env';
44
import { createApp } from './app';
5-
import { MongoLicenseDataService } from './services/data/mongoose';
5+
import { MongooseLicenseDataService } from './services/data/mongoose';
66
import { Database } from './db';
77

88
const port = env.PORT;
@@ -21,7 +21,7 @@ const run = async () => {
2121
logger.info('started server', { port });
2222
};
2323

24-
const lds = new MongoLicenseDataService(db);
24+
const lds = new MongooseLicenseDataService(db);
2525
const app = createApp(lds);
2626
app.listen(port, running);
2727
};

experimental/license-inventory/src/services/data/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import type { AsyncResult } from '@/types';
2-
import type { License, LicenseCreateUpdate } from './license';
2+
import type { License, LicenseNoID, LicenseNoIDPartial } from './license';
33

44
export interface LicenseDataService {
5-
create: (licenseData: LicenseCreateUpdate) => AsyncResult<null>;
5+
create: (licenseData: LicenseNoID) => AsyncResult<License>;
66

77
getByUUID: (id: string) => AsyncResult<License | null>;
88

9-
patchByUUID: (id: string, licenseData: LicenseCreateUpdate) => AsyncResult<null>;
9+
patchByUUID: (id: string, licenseData: LicenseNoIDPartial) => AsyncResult<License>;
1010

1111
deleteByUUID: (id: string) => AsyncResult<null>;
1212

experimental/license-inventory/src/services/data/license.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,8 @@ export const license = z.object({
4141
});
4242
export type License = z.infer<typeof license>;
4343

44-
export const licenseCreateUpdate = license.omit({ id: true });
45-
export type LicenseCreateUpdate = z.infer<typeof licenseCreateUpdate>;
44+
export const licenseNoID = license.omit({ id: true });
45+
export type LicenseNoID = z.infer<typeof licenseNoID>;
46+
47+
export const licenseNoIDPartial = licenseNoID.partial();
48+
export type LicenseNoIDPartial = z.infer<typeof licenseNoIDPartial>;

0 commit comments

Comments
 (0)