basic test implemented
This commit is contained in:
parent
5cdb1e978d
commit
71d7c0531d
@ -5,7 +5,8 @@
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:ava/recommended"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
|
File diff suppressed because one or more lines are too long
5
jest.config.js
Normal file
5
jest.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
10857
package-lock.json
generated
10857
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@ -4,7 +4,7 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"test": "jest --watchAll",
|
||||
"start": "nodemon --exec \"npx ts-node\" ./src/server.ts"
|
||||
},
|
||||
"author": "",
|
||||
@ -17,18 +17,24 @@
|
||||
"dcc-utils": "^0.2.0",
|
||||
"express": "^4.17.1",
|
||||
"jsrsasign": "^10.4.0",
|
||||
"nodemon": "^2.0.13",
|
||||
"typescript": "^4.4.3"
|
||||
"mock-fs": "^5.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/jsrsasign": "^8.0.13",
|
||||
"@types/node": "^16.9.6",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.2",
|
||||
"@typescript-eslint/parser": "^4.31.2",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-plugin-ava": "^13.0.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"ts-node": "^10.2.1"
|
||||
"jest": "^27.2.2",
|
||||
"nodemon": "^2.0.13",
|
||||
"ts-jest": "^27.0.5",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
{"rules":[{"name":"vaccine_end_day_complete","type":"EU/1/20/1525","value":"365"},{"name":"vaccine_start_day_complete","type":"EU/1/20/1525","value":"15"},{"name":"vaccine_end_day_not_complete","type":"EU/1/20/1525","value":"365"},{"name":"vaccine_start_day_not_complete","type":"EU/1/20/1525","value":"15"},{"name":"vaccine_end_day_complete","type":"EU/1/21/1529","value":"365"},{"name":"vaccine_start_day_complete","type":"EU/1/21/1529","value":"0"},{"name":"vaccine_end_day_not_complete","type":"EU/1/21/1529","value":"84"},{"name":"vaccine_start_day_not_complete","type":"EU/1/21/1529","value":"15"},{"name":"vaccine_end_day_complete","type":"EU/1/20/1507","value":"365"},{"name":"vaccine_start_day_complete","type":"EU/1/20/1507","value":"0"},{"name":"vaccine_end_day_not_complete","type":"EU/1/20/1507","value":"42"},{"name":"vaccine_start_day_not_complete","type":"EU/1/20/1507","value":"15"},{"name":"vaccine_end_day_complete","type":"EU/1/20/1528","value":"365"},{"name":"vaccine_start_day_complete","type":"EU/1/20/1528","value":"0"},{"name":"vaccine_end_day_not_complete","type":"EU/1/20/1528","value":"42"},{"name":"vaccine_start_day_not_complete","type":"EU/1/20/1528","value":"15"},{"name":"rapid_test_start_hours","type":"GENERIC","value":"0"},{"name":"rapid_test_end_hours","type":"GENERIC","value":"48"},{"name":"molecular_test_start_hours","type":"GENERIC","value":"0"},{"name":"molecular_test_end_hours","type":"GENERIC","value":"48"},{"name":"recovery_cert_start_day","type":"GENERIC","value":"0"},{"name":"recovery_cert_end_day","type":"GENERIC","value":"180"},{"name":"ios","type":"APP_MIN_VERSION","value":"1.1.0"},{"name":"android","type":"APP_MIN_VERSION","value":"1.1.0"}],"lastupdateDate":1632564259533}
|
@ -0,0 +1,7 @@
|
||||
describe('CertificateDownloader',()=>{
|
||||
describe('getCertificates()',()=>{
|
||||
it('placeholder',()=>{
|
||||
expect(false).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
@ -27,11 +27,9 @@ export class CertificateDownloader{
|
||||
}
|
||||
return this.certificatesCollection;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
if(error.errno == -2){
|
||||
if(error.message == 'ENOENT: no such file or directory, open \'rules.json\''){
|
||||
await fs.writeFile(this.keyStorage,'{}');
|
||||
} else {
|
||||
console.log(error);
|
||||
return this.getCertificates();
|
||||
}
|
||||
}
|
||||
}
|
58
src/Services/SettingsDownloader/RuleDownloader.spec.ts
Normal file
58
src/Services/SettingsDownloader/RuleDownloader.spec.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { RuleDownloader } from './RuleDownloader';
|
||||
import mock from 'mock-fs';
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
jest.mock('axios');
|
||||
const mockRules = [{'name':'vaccine_end_day_complete','type':'EU/1/20/1525','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/20/1525','value':'15'},{'name':'vaccine_end_day_not_complete','type':'EU/1/20/1525','value':'365'},{'name':'vaccine_start_day_not_complete','type':'EU/1/20/1525','value':'15'},{'name':'vaccine_end_day_complete','type':'EU/1/21/1529','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/21/1529','value':'0'},{'name':'vaccine_end_day_not_complete','type':'EU/1/21/1529','value':'84'},{'name':'vaccine_start_day_not_complete','type':'EU/1/21/1529','value':'15'},{'name':'vaccine_end_day_complete','type':'EU/1/20/1507','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/20/1507','value':'0'},{'name':'vaccine_end_day_not_complete','type':'EU/1/20/1507','value':'42'},{'name':'vaccine_start_day_not_complete','type':'EU/1/20/1507','value':'15'},{'name':'vaccine_end_day_complete','type':'EU/1/20/1528','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/20/1528','value':'0'},{'name':'vaccine_end_day_not_complete','type':'EU/1/20/1528','value':'42'},{'name':'vaccine_start_day_not_complete','type':'EU/1/20/1528','value':'15'},{'name':'rapid_test_start_hours','type':'GENERIC','value':'0'},{'name':'rapid_test_end_hours','type':'GENERIC','value':'48'},{'name':'molecular_test_start_hours','type':'GENERIC','value':'0'},{'name':'molecular_test_end_hours','type':'GENERIC','value':'48'},{'name':'recovery_cert_start_day','type':'GENERIC','value':'0'},{'name':'recovery_cert_end_day','type':'GENERIC','value':'180'},{'name':'ios','type':'APP_MIN_VERSION','value':'1.1.0'},{'name':'android','type':'APP_MIN_VERSION','value':'1.1.0'}];
|
||||
|
||||
const ruleDownloader = new RuleDownloader();
|
||||
|
||||
const mockedAxios = axios as jest.Mocked<typeof axios>;
|
||||
const successResposnse: AxiosResponse = {
|
||||
// data:[{'name':'vaccine_end_day_complete','type':'EU/1/20/1525','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/20/1525','value':'15'},{'name':'vaccine_end_day_not_complete','type':'EU/1/20/1525','value':'365'},{'name':'vaccine_start_day_not_complete','type':'EU/1/20/1525','value':'15'},{'name':'vaccine_end_day_complete','type':'EU/1/21/1529','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/21/1529','value':'0'},{'name':'vaccine_end_day_not_complete','type':'EU/1/21/1529','value':'84'},{'name':'vaccine_start_day_not_complete','type':'EU/1/21/1529','value':'15'},{'name':'vaccine_end_day_complete','type':'EU/1/20/1507','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/20/1507','value':'0'},{'name':'vaccine_end_day_not_complete','type':'EU/1/20/1507','value':'42'},{'name':'vaccine_start_day_not_complete','type':'EU/1/20/1507','value':'15'},{'name':'vaccine_end_day_complete','type':'EU/1/20/1528','value':'365'},{'name':'vaccine_start_day_complete','type':'EU/1/20/1528','value':'0'},{'name':'vaccine_end_day_not_complete','type':'EU/1/20/1528','value':'42'},{'name':'vaccine_start_day_not_complete','type':'EU/1/20/1528','value':'15'},{'name':'rapid_test_start_hours','type':'GENERIC','value':'0'},{'name':'rapid_test_end_hours','type':'GENERIC','value':'48'},{'name':'molecular_test_start_hours','type':'GENERIC','value':'0'},{'name':'molecular_test_end_hours','type':'GENERIC','value':'48'},{'name':'recovery_cert_start_day','type':'GENERIC','value':'0'},{'name':'recovery_cert_end_day','type':'GENERIC','value':'180'},{'name':'ios','type':'APP_MIN_VERSION','value':'1.1.0'},{'name':'android','type':'APP_MIN_VERSION','value':'1.1.0'}],
|
||||
data: mockRules,
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
headers:{
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-control': 'private',
|
||||
'Strict-Transport-Security': 'max-age=63072000; includeSubDomains; preload'
|
||||
},
|
||||
config: {}
|
||||
};
|
||||
|
||||
describe('RuleDownloader', ()=>{
|
||||
describe('getRules',()=>{
|
||||
test('Testing getRules basic outcome: file loaded from local source and is still valid',async ()=>{
|
||||
mock({
|
||||
'./rules.json': Buffer.from(JSON.stringify({rules:mockRules,lastupdateDate:Date.now()}))
|
||||
});
|
||||
const rules = await ruleDownloader.getRules();
|
||||
mock.restore();
|
||||
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
||||
});
|
||||
test('Testing getRules basic outcome: file loaded from local source and is still valid',async ()=>{
|
||||
mockedAxios.get.mockResolvedValue(successResposnse);
|
||||
const date = Date.now() - 86400010;
|
||||
mock({
|
||||
'./rules.json': Buffer.from(JSON.stringify({rules:mockRules,lastupdateDate:date}))
|
||||
});
|
||||
expect(axios.get).not.toHaveBeenCalled();
|
||||
const rules = await ruleDownloader.getRules();
|
||||
expect(axios.get).toHaveBeenCalled();
|
||||
mock.restore();
|
||||
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
||||
});
|
||||
test('Testing getRules basic outcome: file loaded from local source and is still valid',async ()=>{
|
||||
mock({});
|
||||
try {
|
||||
mockedAxios.get.mockResolvedValue(successResposnse);
|
||||
const rules = await ruleDownloader.getRules();
|
||||
mock.restore();
|
||||
expect(JSON.stringify(rules)).toBe(JSON.stringify(mockRules));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
});
|
@ -5,12 +5,8 @@ export class RuleDownloader {
|
||||
static instance: RuleDownloader;
|
||||
private readonly baseUrl = 'https://get.dgc.gov.it';
|
||||
private readonly timeSpan = 86400000;
|
||||
// private readonly timeSpan = 1;
|
||||
private readonly keyStorage = 'rules.json'
|
||||
// private readonly timeSpan = 1000;
|
||||
public rules:unknown[] = []
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
constructor(){}
|
||||
|
||||
public async getRules(): Promise<unknown[]> {
|
||||
let data = '{}';
|
||||
@ -26,11 +22,9 @@ export class RuleDownloader {
|
||||
}
|
||||
return this.rules;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
if(error.code == 'ENONET'){
|
||||
if(error.message == 'ENOENT: no such file or directory, open \'rules.json\''){
|
||||
await fs.writeFile(this.keyStorage,'{}');
|
||||
} else {
|
||||
console.log(error);
|
||||
return this.getRules();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,7 +36,7 @@ export class RuleDownloader {
|
||||
this.rules = jsonData;
|
||||
// localStorage.setItem(this.keyStorage, JSON.stringify({rules:this.rules,lastupdateDate:Date.now()}));
|
||||
const file = await fs.open(this.keyStorage,'w');
|
||||
file.writeFile(JSON.stringify({rules:this.rules,lastupdateDate:Date.now()}));
|
||||
await file.writeFile(JSON.stringify({rules:this.rules,lastupdateDate:Date.now()}));
|
||||
await file.close();
|
||||
return jsonData;
|
||||
}
|
@ -128,4 +128,5 @@ export class VaccineVerifier {
|
||||
if(now.isAfter(endValidity)) return {valid:false, message:'Certificate not more valid', type:'test'};
|
||||
return {valid:true, message:'Certificate is valid', type:'test'};
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { CertificateDownloader } from './CertificateDownloader';
|
||||
import { RuleDownloader } from './RuleDownloader';
|
||||
import { CertificateDownloader } from '../SettingsDownloader/CertificateDownloader';
|
||||
import { RuleDownloader } from '../SettingsDownloader/RuleDownloader';
|
||||
import { VaccineVerifier } from './VaccineVerifier';
|
||||
import {DCC} from 'dcc-utils';
|
||||
import jsrsasign from 'jsrsasign';
|
@ -1,5 +1,5 @@
|
||||
import { Request, Response } from 'express';
|
||||
import Verifier from '../../utils/dgcVerifier/Verifier';
|
||||
import Verifier from '../../Services/dgcVerifier/Verifier';
|
||||
let verifier:Verifier;
|
||||
Verifier.instanceVerifier().then((ver:Verifier)=>verifier=ver).catch(console.error);
|
||||
|
||||
|
@ -1,389 +0,0 @@
|
||||
{
|
||||
"country-2-codes": [
|
||||
"AD",
|
||||
"AE",
|
||||
"AF",
|
||||
"AG",
|
||||
"AI",
|
||||
"AL",
|
||||
"AM",
|
||||
"AO",
|
||||
"AQ",
|
||||
"AR",
|
||||
"AS",
|
||||
"AT",
|
||||
"AU",
|
||||
"AW",
|
||||
"AX",
|
||||
"AZ",
|
||||
"BA",
|
||||
"BB",
|
||||
"BD",
|
||||
"BE",
|
||||
"BF",
|
||||
"BG",
|
||||
"BH",
|
||||
"BI",
|
||||
"BJ",
|
||||
"BL",
|
||||
"BM",
|
||||
"BN",
|
||||
"BO",
|
||||
"BQ",
|
||||
"BR",
|
||||
"BS",
|
||||
"BT",
|
||||
"BV",
|
||||
"BW",
|
||||
"BY",
|
||||
"BZ",
|
||||
"CA",
|
||||
"CC",
|
||||
"CD",
|
||||
"CF",
|
||||
"CG",
|
||||
"CH",
|
||||
"CI",
|
||||
"CK",
|
||||
"CL",
|
||||
"CM",
|
||||
"CN",
|
||||
"CO",
|
||||
"CR",
|
||||
"CU",
|
||||
"CV",
|
||||
"CW",
|
||||
"CX",
|
||||
"CY",
|
||||
"CZ",
|
||||
"DE",
|
||||
"DJ",
|
||||
"DK",
|
||||
"DM",
|
||||
"DO",
|
||||
"DZ",
|
||||
"EC",
|
||||
"EE",
|
||||
"EG",
|
||||
"EH",
|
||||
"ER",
|
||||
"ES",
|
||||
"ET",
|
||||
"FI",
|
||||
"FJ",
|
||||
"FK",
|
||||
"FM",
|
||||
"FO",
|
||||
"FR",
|
||||
"GA",
|
||||
"GB",
|
||||
"GD",
|
||||
"GE",
|
||||
"GF",
|
||||
"GG",
|
||||
"GH",
|
||||
"GI",
|
||||
"GL",
|
||||
"GM",
|
||||
"GN",
|
||||
"GP",
|
||||
"GQ",
|
||||
"GR",
|
||||
"GS",
|
||||
"GT",
|
||||
"GU",
|
||||
"GW",
|
||||
"GY",
|
||||
"HK",
|
||||
"HM",
|
||||
"HN",
|
||||
"HR",
|
||||
"HT",
|
||||
"HU",
|
||||
"ID",
|
||||
"IE",
|
||||
"IL",
|
||||
"IM",
|
||||
"IN",
|
||||
"IO",
|
||||
"IQ",
|
||||
"IR",
|
||||
"IS",
|
||||
"IT",
|
||||
"JE",
|
||||
"JM",
|
||||
"JO",
|
||||
"JP",
|
||||
"KE",
|
||||
"KG",
|
||||
"KH",
|
||||
"KI",
|
||||
"KM",
|
||||
"KN",
|
||||
"KP",
|
||||
"KR",
|
||||
"KW",
|
||||
"KY",
|
||||
"KZ",
|
||||
"LA",
|
||||
"LB",
|
||||
"LC",
|
||||
"LI",
|
||||
"LK",
|
||||
"LR",
|
||||
"LS",
|
||||
"LT",
|
||||
"LU",
|
||||
"LV",
|
||||
"LY",
|
||||
"MA",
|
||||
"MC",
|
||||
"MD",
|
||||
"ME",
|
||||
"MF",
|
||||
"MG",
|
||||
"MH",
|
||||
"MK",
|
||||
"ML",
|
||||
"MM",
|
||||
"MN",
|
||||
"MO",
|
||||
"MP",
|
||||
"MQ",
|
||||
"MR",
|
||||
"MS",
|
||||
"MT",
|
||||
"MU",
|
||||
"MV",
|
||||
"MW",
|
||||
"MX",
|
||||
"MY",
|
||||
"MZ",
|
||||
"NA",
|
||||
"NC",
|
||||
"NE",
|
||||
"NF",
|
||||
"NG",
|
||||
"NI",
|
||||
"NL",
|
||||
"NO",
|
||||
"NP",
|
||||
"NR",
|
||||
"NU",
|
||||
"NZ",
|
||||
"OM",
|
||||
"PA",
|
||||
"PE",
|
||||
"PF",
|
||||
"PG",
|
||||
"PH",
|
||||
"PK",
|
||||
"PL",
|
||||
"PM",
|
||||
"PN",
|
||||
"PR",
|
||||
"PS",
|
||||
"PT",
|
||||
"PW",
|
||||
"PY",
|
||||
"QA",
|
||||
"RE",
|
||||
"RO",
|
||||
"RS",
|
||||
"RU",
|
||||
"RW",
|
||||
"SA",
|
||||
"SB",
|
||||
"SC",
|
||||
"SD",
|
||||
"SE",
|
||||
"SG",
|
||||
"SH",
|
||||
"SI",
|
||||
"SJ",
|
||||
"SK",
|
||||
"SL",
|
||||
"SM",
|
||||
"SN",
|
||||
"SO",
|
||||
"SR",
|
||||
"SS",
|
||||
"ST",
|
||||
"SV",
|
||||
"SX",
|
||||
"SY",
|
||||
"SZ",
|
||||
"TC",
|
||||
"TD",
|
||||
"TF",
|
||||
"TG",
|
||||
"TH",
|
||||
"TJ",
|
||||
"TK",
|
||||
"TL",
|
||||
"TM",
|
||||
"TN",
|
||||
"TO",
|
||||
"TR",
|
||||
"TT",
|
||||
"TV",
|
||||
"TW",
|
||||
"TZ",
|
||||
"UA",
|
||||
"UG",
|
||||
"UM",
|
||||
"US",
|
||||
"UY",
|
||||
"UZ",
|
||||
"VA",
|
||||
"VC",
|
||||
"VE",
|
||||
"VG",
|
||||
"VI",
|
||||
"VN",
|
||||
"VU",
|
||||
"WF",
|
||||
"WS",
|
||||
"YE",
|
||||
"YT",
|
||||
"ZA",
|
||||
"ZM",
|
||||
"ZW"
|
||||
],
|
||||
"disease-agent-targeted": [
|
||||
"840539006"
|
||||
],
|
||||
"covid-19-lab-test-manufacturer-and-name": [
|
||||
"1065",
|
||||
"1097",
|
||||
"1114",
|
||||
"1144",
|
||||
"1162",
|
||||
"1173",
|
||||
"1180",
|
||||
"1190",
|
||||
"1199",
|
||||
"1201",
|
||||
"1215",
|
||||
"1218",
|
||||
"1223",
|
||||
"1225",
|
||||
"1232",
|
||||
"1236",
|
||||
"1242",
|
||||
"1244",
|
||||
"1253",
|
||||
"1257",
|
||||
"1263",
|
||||
"1266",
|
||||
"1267",
|
||||
"1268",
|
||||
"1271",
|
||||
"1278",
|
||||
"1295",
|
||||
"1296",
|
||||
"1304",
|
||||
"1319",
|
||||
"1331",
|
||||
"1333",
|
||||
"1341",
|
||||
"1343",
|
||||
"1360",
|
||||
"1363",
|
||||
"1365",
|
||||
"1375",
|
||||
"1392",
|
||||
"1420",
|
||||
"1437",
|
||||
"1443",
|
||||
"1456",
|
||||
"1466",
|
||||
"1468",
|
||||
"1481",
|
||||
"1484",
|
||||
"1489",
|
||||
"1490",
|
||||
"1501",
|
||||
"1574",
|
||||
"1604",
|
||||
"1606",
|
||||
"1654",
|
||||
"1736",
|
||||
"1747",
|
||||
"1763",
|
||||
"1764",
|
||||
"1767",
|
||||
"1769",
|
||||
"1815",
|
||||
"1822",
|
||||
"1833",
|
||||
"1844",
|
||||
"1870",
|
||||
"1884",
|
||||
"1906",
|
||||
"1919",
|
||||
"1934",
|
||||
"2010",
|
||||
"2017",
|
||||
"2029",
|
||||
"2074",
|
||||
"2098",
|
||||
"2101",
|
||||
"2103",
|
||||
"2104",
|
||||
"2108",
|
||||
"2109",
|
||||
"2116",
|
||||
"2128",
|
||||
"2130",
|
||||
"2139",
|
||||
"2183",
|
||||
"308",
|
||||
"344",
|
||||
"345",
|
||||
"768"
|
||||
],
|
||||
"covid-19-lab-result": [
|
||||
"260373001",
|
||||
"260415000"
|
||||
],
|
||||
"covid-19-lab-test-type": [
|
||||
"LP217198-3",
|
||||
"LP6464-4"
|
||||
],
|
||||
"vaccines-covid-19-auth-holders": [
|
||||
"Bharat-Biotech",
|
||||
"Gamaleya-Research-Institute",
|
||||
"ORG-100001417",
|
||||
"ORG-100001699",
|
||||
"ORG-100006270",
|
||||
"ORG-100010771",
|
||||
"ORG-100013793",
|
||||
"ORG-100020693",
|
||||
"ORG-100024420",
|
||||
"ORG-100030215",
|
||||
"ORG-100031184",
|
||||
"ORG-100032020",
|
||||
"Sinovac-Biotech",
|
||||
"Vector-Institute"
|
||||
],
|
||||
"vaccines-covid-19-names": [
|
||||
"BBIBP-CorV",
|
||||
"CVnCoV",
|
||||
"Convidecia",
|
||||
"CoronaVac",
|
||||
"Covaxin",
|
||||
"EU/1/20/1507",
|
||||
"EU/1/20/1525",
|
||||
"EU/1/20/1528",
|
||||
"EU/1/21/1529",
|
||||
"EpiVacCorona",
|
||||
"Inactivated-SARS-CoV-2-Vero-Cell",
|
||||
"Sputnik-V"
|
||||
],
|
||||
"sct-vaccines-covid-19": [
|
||||
"1119305005",
|
||||
"1119349007",
|
||||
"J07BX03"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user