@next-k8s/tickets 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- package/.dockerignore +1 -0
- package/CHANGELOG.md +72 -0
- package/Dockerfile +7 -0
- package/build/__mocks__/nats-client.js +12 -0
- package/build/app.js +31 -0
- package/build/events/publishers/tickets/created.js +12 -0
- package/build/events/publishers/tickets/updated.js +12 -0
- package/build/index.js +45 -0
- package/build/models/ticket.js +37 -0
- package/build/nats-client.js +42 -0
- package/build/routes/__test__/create.test.js +85 -0
- package/build/routes/__test__/find.test.js +30 -0
- package/build/routes/__test__/get.test.js +43 -0
- package/build/routes/__test__/update.test.js +95 -0
- package/build/routes/create.js +33 -0
- package/build/routes/find.js +22 -0
- package/build/routes/get.js +28 -0
- package/build/routes/index.js +10 -0
- package/build/routes/update.js +41 -0
- package/build/test/setup.js +34 -0
- package/build/test/utils.js +33 -0
- package/package.json +53 -0
- package/pnpm-lock.yaml +3641 -0
- package/src/__mocks__/nats-client.ts +10 -0
- package/src/app.ts +21 -0
- package/src/events/publishers/tickets/created.ts +7 -0
- package/src/events/publishers/tickets/updated.ts +7 -0
- package/src/index.ts +31 -0
- package/src/models/ticket.ts +42 -0
- package/src/nats-client.ts +30 -0
- package/src/routes/__test__/create.test.ts +83 -0
- package/src/routes/__test__/find.test.ts +18 -0
- package/src/routes/__test__/get.test.ts +34 -0
- package/src/routes/__test__/update.test.ts +101 -0
- package/src/routes/create.ts +24 -0
- package/src/routes/find.ts +11 -0
- package/src/routes/get.ts +16 -0
- package/src/routes/index.ts +8 -0
- package/src/routes/update.ts +29 -0
- package/src/test/setup.ts +24 -0
- package/src/test/utils.ts +18 -0
- package/tsconfig.json +101 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
const common_1 = require("@next-k8s/common");
|
16
|
+
const express_1 = __importDefault(require("express"));
|
17
|
+
const express_validator_1 = require("express-validator");
|
18
|
+
const mongoose_1 = require("mongoose");
|
19
|
+
const ticket_1 = __importDefault(require("../models/ticket"));
|
20
|
+
const updated_1 = __importDefault(require("../events/publishers/tickets/updated"));
|
21
|
+
const nats_client_1 = __importDefault(require("../nats-client"));
|
22
|
+
const router = express_1.default.Router();
|
23
|
+
const validateInput = [
|
24
|
+
(0, express_validator_1.body)('title').not().isEmpty().withMessage('Title is required'),
|
25
|
+
(0, express_validator_1.body)('price').isInt({ gt: -1, lt: Number.MAX_SAFE_INTEGER }).withMessage('Price must be an integer of cents or units')
|
26
|
+
];
|
27
|
+
router.put('/api/tickets/:id', common_1.requireAuth, validateInput, common_1.validateRequest, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
28
|
+
if (!(0, mongoose_1.isValidObjectId)(req.params.id))
|
29
|
+
throw new common_1.BadRequestError('Invalid Ticket ID');
|
30
|
+
const ticket = yield ticket_1.default.findById(req.params.id);
|
31
|
+
if (!ticket)
|
32
|
+
throw new common_1.NotFoundError();
|
33
|
+
if (ticket.owner !== req.currentUser.id)
|
34
|
+
throw new common_1.UnauthorizedError();
|
35
|
+
const { title, price } = req.body;
|
36
|
+
ticket.set({ title, price });
|
37
|
+
yield ticket.save();
|
38
|
+
yield new updated_1.default(nats_client_1.default.client).publish({ id: ticket.id, title: ticket.title, price: ticket.price, owner: ticket.owner });
|
39
|
+
res.json(ticket);
|
40
|
+
}));
|
41
|
+
exports.default = router;
|
@@ -0,0 +1,34 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
const mongodb_memory_server_1 = require("mongodb-memory-server");
|
16
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
17
|
+
jest.mock('../nats-client.ts');
|
18
|
+
let mongo;
|
19
|
+
process.env.JWT_KEY = '!SuperSecretDevToken!';
|
20
|
+
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
21
|
+
mongo = yield mongodb_memory_server_1.MongoMemoryServer.create();
|
22
|
+
const uri = yield mongo.getUri();
|
23
|
+
yield mongoose_1.default.connect(uri);
|
24
|
+
}));
|
25
|
+
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
26
|
+
jest.clearAllMocks();
|
27
|
+
const collections = yield mongoose_1.default.connection.db.collections();
|
28
|
+
for (const collection of collections)
|
29
|
+
yield collection.deleteMany({});
|
30
|
+
}));
|
31
|
+
afterAll(() => __awaiter(void 0, void 0, void 0, function* () {
|
32
|
+
yield mongoose_1.default.connection.close();
|
33
|
+
yield mongo.stop();
|
34
|
+
}));
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
exports.createTicket = exports.getTokenCookie = void 0;
|
16
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
17
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
18
|
+
const supertest_1 = __importDefault(require("supertest"));
|
19
|
+
const getTokenCookie = () => __awaiter(void 0, void 0, void 0, function* () {
|
20
|
+
const payload = { id: new mongoose_1.default.Types.ObjectId().toHexString(), email: 'test@test.com' };
|
21
|
+
const token = jsonwebtoken_1.default.sign(payload, process.env.JWT_KEY);
|
22
|
+
const cookie = Buffer.from(JSON.stringify({ jwt: token })).toString('base64');
|
23
|
+
return `session=${cookie}`;
|
24
|
+
});
|
25
|
+
exports.getTokenCookie = getTokenCookie;
|
26
|
+
const createTicket = (app, cookie, title = 'Test Event', price = 20000, expectedStatusCode = 201) => {
|
27
|
+
return (0, supertest_1.default)(app)
|
28
|
+
.post('/api/tickets')
|
29
|
+
.set('Cookie', cookie ? [cookie] : [])
|
30
|
+
.send({ title, price })
|
31
|
+
.expect(expectedStatusCode);
|
32
|
+
};
|
33
|
+
exports.createTicket = createTicket;
|
package/package.json
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
{
|
2
|
+
"name": "@next-k8s/tickets",
|
3
|
+
"version": "1.0.9",
|
4
|
+
"main": "index.js",
|
5
|
+
"license": "MIT",
|
6
|
+
"scripts": {
|
7
|
+
"start": "ts-node-dev --transpile-only --exit-child --watch src src/index.ts",
|
8
|
+
"build": "tsc",
|
9
|
+
"test": "jest --no-cache",
|
10
|
+
"test:watch": "jest --watchAll --no-cache"
|
11
|
+
},
|
12
|
+
"publishConfig": {
|
13
|
+
"access": "public"
|
14
|
+
},
|
15
|
+
"jest": {
|
16
|
+
"preset": "ts-jest",
|
17
|
+
"testEnvironment": "node",
|
18
|
+
"roots": [
|
19
|
+
"src"
|
20
|
+
],
|
21
|
+
"setupFilesAfterEnv": [
|
22
|
+
"./src/test/setup.ts"
|
23
|
+
]
|
24
|
+
},
|
25
|
+
"dependencies": {
|
26
|
+
"@next-k8s/common": "^0.1.23",
|
27
|
+
"@types/cookie-session": "^2.0.44",
|
28
|
+
"@types/express": "^4.17.13",
|
29
|
+
"@types/jsonwebtoken": "^8.5.8",
|
30
|
+
"body-parser": "^1.20.0",
|
31
|
+
"cookie-session": "^2.0.0",
|
32
|
+
"express": "^4.18.1",
|
33
|
+
"express-async-errors": "^3.1.1",
|
34
|
+
"express-validator": "^6.14.1",
|
35
|
+
"jsonwebtoken": "^8.5.1",
|
36
|
+
"mongoose": "^6.3.5",
|
37
|
+
"mongoose-bcrypt": "^1.9.0",
|
38
|
+
"node-nats-streaming": "^0.3.2",
|
39
|
+
"ts-node-dev": "^2.0.0",
|
40
|
+
"typescript": "^4.7.3"
|
41
|
+
},
|
42
|
+
"devDependencies": {
|
43
|
+
"@types/body-parser": "^1.19.2",
|
44
|
+
"@types/jest": "^28.1.1",
|
45
|
+
"@types/mongoose": "^5.11.97",
|
46
|
+
"@types/supertest": "^2.0.12",
|
47
|
+
"jest": "^28.1.1",
|
48
|
+
"mongodb-memory-server": "^8.6.0",
|
49
|
+
"supertest": "^6.2.3",
|
50
|
+
"ts-jest": "^28.0.4"
|
51
|
+
},
|
52
|
+
"gitHead": "e28ae26195b5a105e974ff366741832500b17b31"
|
53
|
+
}
|