m06_tim 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env +5 -0
- package/client.js +23 -0
- package/index.html +56 -0
- package/lab5-1.js +41 -0
- package/lab5-1.ts +51 -0
- package/lab5-2.ts +8 -0
- package/m06_tim.ts +28 -0
- package/mailservice.js +147 -0
- package/mailservice.ts +104 -0
- package/package.json +11 -0
- package/tsconfig.json +5 -0
package/.env
ADDED
package/client.js
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
const url = 'http://localhost:5000/';
|
2
|
+
document.querySelector('#mailform__send_input').addEventListener('click',async ()=>{
|
3
|
+
await fetch(url,{
|
4
|
+
method: 'POST',
|
5
|
+
headers:{
|
6
|
+
'Content-Type':'application/json',
|
7
|
+
Accept: 'application/json'
|
8
|
+
},
|
9
|
+
body:
|
10
|
+
JSON.stringify({
|
11
|
+
from:mailform__sento_input.value,
|
12
|
+
to:mailform__receiver_input.value,
|
13
|
+
message:mailform__message_input.value
|
14
|
+
})
|
15
|
+
}
|
16
|
+
)
|
17
|
+
.then(resp => resp.json())
|
18
|
+
.then(data => {
|
19
|
+
document.createElement('p').innerText =
|
20
|
+
`sender:${data.sender} receiver:${data.receiver} message:${data.message}`;
|
21
|
+
})
|
22
|
+
.catch(err => console.error("error occuren while fetching:", err))
|
23
|
+
})
|
package/index.html
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<title></title>
|
5
|
+
<meta charset="UTF-8">
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
|
+
<link href="css/style.css" rel="stylesheet">
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<form class="mailform">
|
11
|
+
<!-- <label class="mailform__label" for="mailform__sendfrom_input">send to</label> -->
|
12
|
+
<input type="email" name="mailform__sendfrom_input" id="mailform__sendfrom_input" value=""/>
|
13
|
+
|
14
|
+
<!-- <label class="mailform__label" for="mailform__receiver_input">receiver</label> -->
|
15
|
+
<input type="email" name="mailform__receiver_input" id="mailform__receiver_input" value=""/>
|
16
|
+
<!---->
|
17
|
+
<!-- <label class="mailform__sendto_label" for="mailform__sendto_input">message</label> -->
|
18
|
+
<input type="text" name="mailform__message_input" id="mailform__message_input" placeholder="enter your message"/>
|
19
|
+
|
20
|
+
<input type="submit" id="mailform__send_input" value="send">
|
21
|
+
|
22
|
+
<p id="send_info>"</p>
|
23
|
+
</form>
|
24
|
+
<script>
|
25
|
+
const url = 'http://localhost:5000/';
|
26
|
+
document.querySelector('#mailform__send_input').addEventListener('click', ()=>{
|
27
|
+
console.log('xd1');
|
28
|
+
fetch(url, {
|
29
|
+
method: 'POST',
|
30
|
+
mode: 'no-cors',
|
31
|
+
|
32
|
+
headers:{
|
33
|
+
'Content-Type':'application/json',
|
34
|
+
Accept: 'application/json'
|
35
|
+
},
|
36
|
+
|
37
|
+
body:
|
38
|
+
JSON.stringify({
|
39
|
+
from:document.querySelector("#mailform__sendfrom_input").value,
|
40
|
+
to:document.querySelector("#mailform__receiver_input").value,
|
41
|
+
message:document.querySelector("#mailform__message_input").value
|
42
|
+
})
|
43
|
+
}
|
44
|
+
)
|
45
|
+
.then(resp => {
|
46
|
+
return resp.json()})
|
47
|
+
.then(data => {
|
48
|
+
console.log(data);
|
49
|
+
send_info.innerHTML= `<p> from: ${data.from}, to ${data.to},
|
50
|
+
message: + ${data.message}</p>`})
|
51
|
+
.catch(err => console.error("error occured while fetching:", err))
|
52
|
+
alert('xd');
|
53
|
+
})
|
54
|
+
</script>
|
55
|
+
</body>
|
56
|
+
</html>
|
package/lab5-1.js
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
//todo: add headers, fix imports for logging
|
4
|
+
var http_1 = require("http");
|
5
|
+
var fs_1 = require("fs");
|
6
|
+
var url_1 = require("url");
|
7
|
+
var mailservice_1 = require("./mailservice");
|
8
|
+
var htmlFilePath = "./index.html";
|
9
|
+
var urlPrefix = "http://localhost:5000";
|
10
|
+
(0, http_1.createServer)(function (req, resp) {
|
11
|
+
resp.writeHead(200, { "Content-Type": "text/html" });
|
12
|
+
var url = new url_1.URL(urlPrefix + req.url);
|
13
|
+
if ((url.pathname === "/" || "/css/style.css" || "/favicon.ico") && req.method === "GET") {
|
14
|
+
console.log(url.pathname, req.method);
|
15
|
+
(0, fs_1.readFile)(htmlFilePath, function (err, data) {
|
16
|
+
err != null ?
|
17
|
+
console.error("error occured when reading file: ", err) :
|
18
|
+
resp.end(data);
|
19
|
+
});
|
20
|
+
}
|
21
|
+
else if (req.method === "POST") {
|
22
|
+
console.log("post");
|
23
|
+
var requestBody_1 = "";
|
24
|
+
req.on('data', function (data) {
|
25
|
+
requestBody_1 += data.toString();
|
26
|
+
});
|
27
|
+
req.on('end', function () {
|
28
|
+
console.log("request body:", requestBody_1);
|
29
|
+
var sendMailInfo = JSON.parse(requestBody_1);
|
30
|
+
// const id = req.headers['X-Request-Id'] as string;
|
31
|
+
(0, mailservice_1.sendMailWithConnectionCreation)({ to: "alesha.rom@gmail.com>",
|
32
|
+
from: "iltihomsorok@gmail.com",
|
33
|
+
subject: "xd",
|
34
|
+
text: "kto prochital, tot lox"
|
35
|
+
}).then(function () { return resp.end("xd"); }).catch(function (err) { return console.error(err); });
|
36
|
+
});
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
console.log('xd');
|
40
|
+
}
|
41
|
+
}).listen(5000, function () { console.log("server running on port 5000"); });
|
package/lab5-1.ts
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
//todo: add headers, fix imports for logging
|
2
|
+
import { IncomingMessage, ServerResponse, createServer } from "http";
|
3
|
+
import { readFile } from "fs";
|
4
|
+
// import MailService from "./mailservice";
|
5
|
+
import { MailInterface} from "../interfaces/mailinterface";
|
6
|
+
import Logging from "../lib/logging";
|
7
|
+
import * as Mail from "nodemailer/lib/mailer";
|
8
|
+
import { URL } from "url";
|
9
|
+
import {sendMailWithConnectionCreation} from "./mailservice";
|
10
|
+
|
11
|
+
const htmlFilePath = "./index.html";
|
12
|
+
const urlPrefix = "http://localhost:5000"
|
13
|
+
|
14
|
+
createServer((req:IncomingMessage, resp:ServerResponse)=>{
|
15
|
+
resp.writeHead(200,{"Content-Type":"text/html"});
|
16
|
+
|
17
|
+
const url = new URL(urlPrefix + req.url);
|
18
|
+
|
19
|
+
if ((url.pathname === "/" || "/css/style.css" || "/favicon.ico") && req.method === "GET") {
|
20
|
+
console.log(url.pathname, req.method);
|
21
|
+
readFile(htmlFilePath, (err,data)=>{
|
22
|
+
err != null ?
|
23
|
+
console.error("error occured when reading file: ", err) :
|
24
|
+
resp.end(data);
|
25
|
+
})
|
26
|
+
} else if (req.method === "POST"){
|
27
|
+
console.log("post");
|
28
|
+
let requestBody = "";
|
29
|
+
|
30
|
+
req.on('data',(data)=>{
|
31
|
+
requestBody += data.toString();
|
32
|
+
});
|
33
|
+
|
34
|
+
req.on('end', ()=>{
|
35
|
+
|
36
|
+
console.log("request body:",requestBody);
|
37
|
+
|
38
|
+
const sendMailInfo = JSON.parse(requestBody);
|
39
|
+
|
40
|
+
sendMailWithConnectionCreation(
|
41
|
+
{ to:"alesha.rom@gmail.com>",
|
42
|
+
from:"iltihomsorok@gmail.com",
|
43
|
+
subject: "xd",
|
44
|
+
text: "kto prochital, tot lox"
|
45
|
+
}).then(()=>resp.end("xd")).catch((err)=>console.error(err))
|
46
|
+
})
|
47
|
+
}
|
48
|
+
else {
|
49
|
+
console.log('xd');
|
50
|
+
}
|
51
|
+
}).listen(5000,()=>{console.log("server running on port 5000")})
|
package/lab5-2.ts
ADDED
package/m06_tim.ts
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
import nodemailer from "nodemailer";
|
2
|
+
import { MailInterface } from "../interfaces/mailinterface";
|
3
|
+
|
4
|
+
export async function send(options:MailInterface) {
|
5
|
+
|
6
|
+
const transporter = nodemailer.createTransport({
|
7
|
+
host: process.env.SMTP_HOST,
|
8
|
+
port: Number( process.env.SMTP_PORT) || 0,
|
9
|
+
secure: process.env.SMTP_TLS === 'yes' ? true : false,
|
10
|
+
auth: {
|
11
|
+
user: process.env.SMTP_USERNAME,
|
12
|
+
pass: process.env.SMTP_PASSWORD,
|
13
|
+
},
|
14
|
+
});
|
15
|
+
sendMail(options,transporter);
|
16
|
+
}
|
17
|
+
|
18
|
+
export async function sendMail(options: MailInterface, transporter: nodemailer.Transporter){
|
19
|
+
return await transporter.sendMail({
|
20
|
+
from: `"iltihomsorok" ${process.env.SMTP_SENDER || options.from}`,
|
21
|
+
subject: options.subject,
|
22
|
+
text: options.text
|
23
|
+
})
|
24
|
+
.then(info => {
|
25
|
+
console.log("mail send successfully");
|
26
|
+
return info;
|
27
|
+
}).catch(err => console.error(err));
|
28
|
+
}
|
package/mailservice.js
ADDED
@@ -0,0 +1,147 @@
|
|
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 __generator = (this && this.__generator) || function (thisArg, body) {
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
15
|
+
function step(op) {
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
20
|
+
switch (op[0]) {
|
21
|
+
case 0: case 1: t = op; break;
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
25
|
+
default:
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
30
|
+
if (t[2]) _.ops.pop();
|
31
|
+
_.trys.pop(); continue;
|
32
|
+
}
|
33
|
+
op = body.call(thisArg, _);
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
36
|
+
}
|
37
|
+
};
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
39
|
+
exports.sendMail = exports.sendMailWithConnectionCreation = void 0;
|
40
|
+
var nodemailer = require("nodemailer");
|
41
|
+
function sendMailWithConnectionCreation(options) {
|
42
|
+
return __awaiter(this, void 0, void 0, function () {
|
43
|
+
var transporter;
|
44
|
+
return __generator(this, function (_a) {
|
45
|
+
transporter = nodemailer.createTransport({
|
46
|
+
host: process.env.SMTP_HOST,
|
47
|
+
port: Number(process.env.SMTP_PORT) || 0,
|
48
|
+
secure: process.env.SMTP_TLS === 'yes' ? true : false,
|
49
|
+
auth: {
|
50
|
+
user: process.env.SMTP_USERNAME,
|
51
|
+
pass: process.env.SMTP_PASSWORD,
|
52
|
+
},
|
53
|
+
});
|
54
|
+
sendMail(options, transporter);
|
55
|
+
return [2 /*return*/];
|
56
|
+
});
|
57
|
+
});
|
58
|
+
}
|
59
|
+
exports.sendMailWithConnectionCreation = sendMailWithConnectionCreation;
|
60
|
+
function sendMail(options, transporter) {
|
61
|
+
return __awaiter(this, void 0, void 0, function () {
|
62
|
+
return __generator(this, function (_a) {
|
63
|
+
switch (_a.label) {
|
64
|
+
case 0: return [4 /*yield*/, transporter.sendMail({
|
65
|
+
from: "\"iltihomsorok\" ".concat(process.env.SMTP_SENDER || options.from),
|
66
|
+
subject: options.subject,
|
67
|
+
text: options.text
|
68
|
+
})
|
69
|
+
.then(function (info) {
|
70
|
+
console.log("mail send successfully");
|
71
|
+
return info;
|
72
|
+
}).catch(function (err) { return console.error(err); })];
|
73
|
+
case 1: return [2 /*return*/, _a.sent()];
|
74
|
+
}
|
75
|
+
});
|
76
|
+
});
|
77
|
+
}
|
78
|
+
exports.sendMail = sendMail;
|
79
|
+
// export default class MailService {
|
80
|
+
// private static instance: MailService;
|
81
|
+
// private transporter: nodemailer.Transporter;
|
82
|
+
// private constructor() {}
|
83
|
+
//INTSTANCE CREATE FOR MAIL
|
84
|
+
// static getInstance() {
|
85
|
+
// if (!MailService.instance) {
|
86
|
+
// MailService.instance = new MailService();
|
87
|
+
// }
|
88
|
+
// return MailService.instance;
|
89
|
+
// }
|
90
|
+
//CREATE CONNECTION FOR LOCAL
|
91
|
+
// async createLocalConnection() {
|
92
|
+
// const account = await nodemailer.createTestAccount();
|
93
|
+
// this.transporter = nodemailer.createTransport({
|
94
|
+
// host: account.smtp.host,
|
95
|
+
// port: account.smtp.port,
|
96
|
+
// secure: account.smtp.secure,
|
97
|
+
// auth: {
|
98
|
+
// user: account.user,
|
99
|
+
// pass: account.pass,
|
100
|
+
// },
|
101
|
+
// });
|
102
|
+
// }
|
103
|
+
//CREATE CONNECTION FOR LIVE
|
104
|
+
// async createConnection() {
|
105
|
+
// this.transporter = nodemailer.createTransport({
|
106
|
+
// host: process.env.SMTP_HOST,
|
107
|
+
// port: process.env.SMTP_PORT,
|
108
|
+
// secure: process.env.SMTP_TLS === 'yes' ? true : false,
|
109
|
+
// auth: {
|
110
|
+
// user: process.env.SMTP_USERNAME,
|
111
|
+
// pass: process.env.SMTP_PASSWORD,
|
112
|
+
// },
|
113
|
+
// });
|
114
|
+
// }
|
115
|
+
//
|
116
|
+
//SEND MAIL
|
117
|
+
// async sendMail(
|
118
|
+
// requestId: string | number | string[],
|
119
|
+
// options: MailInterface
|
120
|
+
// ) {
|
121
|
+
// return await this.transporter
|
122
|
+
// .sendMail({
|
123
|
+
// from: `"iltihomsorok" ${process.env.SMTP_SENDER || options.from}`,
|
124
|
+
// subject: options.subject,
|
125
|
+
// text: options.text,
|
126
|
+
// })
|
127
|
+
// .then((info) => { // Logging.info(`${requestId} - Mail sent successfully!!`);
|
128
|
+
// // Logging.info(`${requestId} - [MailResponse]=${info.response} [MessageID]=${info.messageId}`);
|
129
|
+
// // if (process.env.NODE_ENV === 'local') {
|
130
|
+
// // Logging.info(`${requestId} - Nodemailer ethereal URL: ${nodemailer.getTestMessageUrl(
|
131
|
+
// // info
|
132
|
+
// // )}`);
|
133
|
+
// // }
|
134
|
+
// console.log("mail set succesfully");
|
135
|
+
// return info;
|
136
|
+
// }).catch(err => console.error("error when sending message", err));
|
137
|
+
// }
|
138
|
+
// //VERIFY CONNECTION
|
139
|
+
// async verifyConnection() {
|
140
|
+
// return this.transporter.verify();
|
141
|
+
// }
|
142
|
+
// //CREATE TRANSPOTER
|
143
|
+
// getTransporter() {
|
144
|
+
// return this.transporter;
|
145
|
+
// }
|
146
|
+
// }
|
147
|
+
//
|
package/mailservice.ts
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
import * as nodemailer from "nodemailer";
|
2
|
+
import { MailInterface} from "../interfaces/mailinterface";
|
3
|
+
import Logging from "../lib/logging";
|
4
|
+
import { Console } from "console";
|
5
|
+
|
6
|
+
export async function sendMailWithConnectionCreation(options:MailInterface) {
|
7
|
+
|
8
|
+
const transporter = nodemailer.createTransport({
|
9
|
+
host: process.env.SMTP_HOST,
|
10
|
+
port: Number( process.env.SMTP_PORT) || 0,
|
11
|
+
secure: process.env.SMTP_TLS === 'yes' ? true : false,
|
12
|
+
auth: {
|
13
|
+
user: process.env.SMTP_USERNAME,
|
14
|
+
pass: process.env.SMTP_PASSWORD,
|
15
|
+
},
|
16
|
+
});
|
17
|
+
sendMail(options,transporter);
|
18
|
+
}
|
19
|
+
|
20
|
+
export async function sendMail(options: MailInterface, transporter: nodemailer.Transporter){
|
21
|
+
return await transporter.sendMail({
|
22
|
+
from: `"iltihomsorok" ${process.env.SMTP_SENDER || options.from}`,
|
23
|
+
subject: options.subject,
|
24
|
+
text: options.text
|
25
|
+
})
|
26
|
+
.then(info => {
|
27
|
+
console.log("mail send successfully");
|
28
|
+
return info;
|
29
|
+
}).catch(err => console.error(err));
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
// export default class MailService {
|
36
|
+
// private static instance: MailService;
|
37
|
+
// private transporter: nodemailer.Transporter;
|
38
|
+
|
39
|
+
// private constructor() {}
|
40
|
+
//INTSTANCE CREATE FOR MAIL
|
41
|
+
// static getInstance() {
|
42
|
+
// if (!MailService.instance) {
|
43
|
+
// MailService.instance = new MailService();
|
44
|
+
// }
|
45
|
+
// return MailService.instance;
|
46
|
+
// }
|
47
|
+
//CREATE CONNECTION FOR LOCAL
|
48
|
+
// async createLocalConnection() {
|
49
|
+
// const account = await nodemailer.createTestAccount();
|
50
|
+
// this.transporter = nodemailer.createTransport({
|
51
|
+
// host: account.smtp.host,
|
52
|
+
// port: account.smtp.port,
|
53
|
+
// secure: account.smtp.secure,
|
54
|
+
// auth: {
|
55
|
+
// user: account.user,
|
56
|
+
// pass: account.pass,
|
57
|
+
// },
|
58
|
+
// });
|
59
|
+
// }
|
60
|
+
//CREATE CONNECTION FOR LIVE
|
61
|
+
// async createConnection() {
|
62
|
+
// this.transporter = nodemailer.createTransport({
|
63
|
+
// host: process.env.SMTP_HOST,
|
64
|
+
// port: process.env.SMTP_PORT,
|
65
|
+
// secure: process.env.SMTP_TLS === 'yes' ? true : false,
|
66
|
+
// auth: {
|
67
|
+
// user: process.env.SMTP_USERNAME,
|
68
|
+
// pass: process.env.SMTP_PASSWORD,
|
69
|
+
// },
|
70
|
+
// });
|
71
|
+
// }
|
72
|
+
//
|
73
|
+
//SEND MAIL
|
74
|
+
// async sendMail(
|
75
|
+
// requestId: string | number | string[],
|
76
|
+
// options: MailInterface
|
77
|
+
// ) {
|
78
|
+
// return await this.transporter
|
79
|
+
// .sendMail({
|
80
|
+
// from: `"iltihomsorok" ${process.env.SMTP_SENDER || options.from}`,
|
81
|
+
// subject: options.subject,
|
82
|
+
// text: options.text,
|
83
|
+
// })
|
84
|
+
// .then((info) => { // Logging.info(`${requestId} - Mail sent successfully!!`);
|
85
|
+
// // Logging.info(`${requestId} - [MailResponse]=${info.response} [MessageID]=${info.messageId}`);
|
86
|
+
// // if (process.env.NODE_ENV === 'local') {
|
87
|
+
// // Logging.info(`${requestId} - Nodemailer ethereal URL: ${nodemailer.getTestMessageUrl(
|
88
|
+
// // info
|
89
|
+
// // )}`);
|
90
|
+
// // }
|
91
|
+
// console.log("mail set succesfully");
|
92
|
+
// return info;
|
93
|
+
// }).catch(err => console.error("error when sending message", err));
|
94
|
+
// }
|
95
|
+
// //VERIFY CONNECTION
|
96
|
+
// async verifyConnection() {
|
97
|
+
// return this.transporter.verify();
|
98
|
+
// }
|
99
|
+
// //CREATE TRANSPOTER
|
100
|
+
// getTransporter() {
|
101
|
+
// return this.transporter;
|
102
|
+
// }
|
103
|
+
// }
|
104
|
+
//
|
package/package.json
ADDED