diff --git a/week-1/mandatory/2-classes-db/task.md b/week-1/mandatory/2-classes-db/task.md index 735de6ae..93f9559e 100644 --- a/week-1/mandatory/2-classes-db/task.md +++ b/week-1/mandatory/2-classes-db/task.md @@ -7,9 +7,18 @@ Below you will find a set of tasks for you to complete to consolidate and extend To submit this homework write the correct commands for each question here: ```sql - - -``` +1- select * from rooms where rate >100; +2-select * from reservations where checkin_date between '2020-09-01' and '2020-09-30' and checkout_date - checkin_date >3; +3-select * from customers where city like 'M%'; +4-insert into room_types( room_type, def_rate) values ('PENTHOUSE', 185.00); +5-insert into rooms( room_no, room_type, rate) values (501,'PENTHOUSE', 185.00), (502,'PENTHOUSE', 185.00); +6-insert into rooms( room_no, room_type, rate) values (503,'PREMIER PLUS', 143.00); +7- select count(room_no) + from reservations where checkin_date between '2020-08-01'and '2020-08-31' + 8- select sum(checkout_date - checkin_date) from reservations where room_no between 201 and 299; + 9- select count(*), sum(total), avg(total) from invoices where total >300; + 10- select sum(checkout_date - checkin_date) from reservations group by room_no/100 ; + ``` When you have finished all of the questions - open a pull request with your answers to the `Databases-Homework` repository. diff --git a/week-2/mandatory/2-ecommerce-db/task.md b/week-2/mandatory/2-ecommerce-db/task.md index c48d2286..4a7f2a43 100644 --- a/week-2/mandatory/2-ecommerce-db/task.md +++ b/week-2/mandatory/2-ecommerce-db/task.md @@ -33,18 +33,62 @@ Open the file `cyf_ecommerce.sql` in VSCode and examine the SQL code. Take a pie ## Task Once you understand the database that you are going to work with, solve the following challenge by writing SQL queries using everything you learned about SQL: - 1. Retrieve all the customers' names and addresses who live in the United States +select name, address from customers where country ='United States'; + 2. Retrieve all the customers in ascending name sequence +select * from customers order by name ; + 3. Retrieve all the products whose name contains the word `socks` +select * from products where product_name like '%socks%'; + 4. Retrieve all the products which cost more than 100 showing product id, name, unit price and supplier id. +select a.prod_id, p.product_name, a.unit_price, a.supp_id from products p join product_availability a on (a.prod_id = p.id) where a.unit_price >100 ; + 5. Retrieve the 5 most expensive products +select * from product_availability order by unit_price DESC limit 5; + 6. Retrieve all the products with their corresponding suppliers. The result should only contain the columns `product_name`, `unit_price` and `supplier_name` +select p.product_name, a.unit_price, s.supplier_name from products p join product_availability a on (a.prod_id = p.id) join suppliers s on (a.supp_id = s.id) ; + 7. Retrieve all the products sold by suppliers based in the United Kingdom. The result should only contain the columns `product_name` and `supplier_name`. +select p.product_name, s.supplier_name from products p join product_availability a on(a.prod_id = p.id) join suppliers s on (a.supp_id = s.id) where s.country = 'United Kingdom'; + 8. Retrieve all orders, including order items, from customer ID `1`. Include order id, reference, date and total cost (calculated as quantity * unit price). + +select o.order_reference, o.order_date from orders o join order_items i on (i.order_id = o.id) join product_availability a on (a.prod_id = i.product_id) where o.customer_id = 1; +////////////I don't understand what they exactly want from this question //////////////// + 9. Retrieve all orders, including order items, from customer named `Hope Crosby` +select o.* from orders o join customers c on (o. customer_id = c.id) where c.name = 'Hope Crosby'; +////// what do yo mean by including order items //////////////////////////// + 10. Retrieve all the products in the order `ORD006`. The result should only contain the columns `product_name`, `unit_price` and `quantity`. +select p.product_name , a.unit_price, i.quantity from orders o join order_items i on(i.order_id = o.id) join product_availability a on (i.supplier_id = a.supp_id) join products p on (p.id = a. prod_id) +where o.order_reference = 'ORD006'; + 11. Retrieve all the products with their supplier for all orders of all customers. The result should only contain the columns `name` (from customer), `order_reference`, `order_date`, `product_name`, `supplier_name` and `quantity`. +select c.name, o.order_reference, o.order_date, s.supplier_name , i.quantity +from customers c join +orders o on(c.id= o.customer_id) join + order_items i on (o.id = i. order_id) join + products p on (i.product_id = p.id) join + suppliers s on (s.id =i.supplier_id); + 12. Retrieve the names of all customers who bought a product from a supplier based in China. +select c.name from customers c join orders o on(c.id= o.customer_id) join + order_items i on (o.id = i. order_id) join + suppliers s on (s.id =i.supplier_id) + where s.country = 'China'; + + 13. List all orders giving customer name, order reference, order date and order total amount (quantity * unit price) in descending order of total. +select c.name, o.order_reference, o.order_date, sum (quantity * unit_price) as total + from customers c join orders o on(c.id= o.customer_id) join + order_items i on (o.id = i. order_id) join + product_availability a on (i.supplier_id = a.supp_id) + group by c.name, o.order_reference, o.order_date + ORDER BY totaL DESC ; + + diff --git a/week-3/cyf-hotels-api/.gitignore b/week-3/cyf-hotels-api/.gitignore new file mode 100644 index 00000000..3c3629e6 --- /dev/null +++ b/week-3/cyf-hotels-api/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/week-3/cyf-hotels-api/build-hotel.sql b/week-3/cyf-hotels-api/build-hotel.sql new file mode 100644 index 00000000..4ff7b12a --- /dev/null +++ b/week-3/cyf-hotels-api/build-hotel.sql @@ -0,0 +1,386 @@ +-- build the cyfhotel database +-- + +drop table invoices; +drop table reservations; +drop table customers; +drop table rooms; +drop table room_types; + +CREATE TABLE room_types ( + room_type VARCHAR(30) PRIMARY KEY, + def_rate NUMERIC(6,2) +); + +INSERT INTO room_types VALUES('FAMILY',123.00); +INSERT INTO room_types VALUES('PREMIER',110.00); +INSERT INTO room_types VALUES('PREMIER PLUS',123.00); +INSERT INTO room_types VALUES('PREMIUM',85.00); +INSERT INTO room_types VALUES('PREMIUM PLUS',98.00); + +CREATE TABLE rooms ( + room_no integer primary key, -- always assigned a value + rate NUMERIC(6,2) not null, -- standard room rate per night + room_type varchar(30), -- room classification + no_guests integer, -- maximum people that can be accommodated + foreign key (room_type) references room_types(room_type) +); + +INSERT INTO rooms VALUES(101,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(102,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(103,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(104,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(105,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(106,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(107,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(108,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(109,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(110,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(111,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(112,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(201,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(202,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(203,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(204,85.00,'PREMIUM',2); +INSERT INTO rooms VALUES(205,85.00,'PREMIUM',3); +INSERT INTO rooms VALUES(206,85.00,'PREMIUM',3); +INSERT INTO rooms VALUES(207,85.00,'PREMIUM',3); +INSERT INTO rooms VALUES(208,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(209,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(210,98.00,'PREMIUM PLUS',2); +INSERT INTO rooms VALUES(211,98.00,'PREMIUM PLUS',3); +INSERT INTO rooms VALUES(212,98.00,'PREMIUM PLUS',3); +INSERT INTO rooms VALUES(301,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(302,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(303,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(304,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(305,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(306,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(307,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(308,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(309,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(310,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(311,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(312,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(401,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(402,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(403,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(404,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(405,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(406,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(407,110.00,'PREMIER',2); +INSERT INTO rooms VALUES(408,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(409,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(410,123.00,'PREMIER PLUS',2); +INSERT INTO rooms VALUES(411,123.00,'FAMILY',4); +INSERT INTO rooms VALUES(412,123.00,'FAMILY',4); + +CREATE TABLE customers ( + id SERIAL PRIMARY KEY, + name VARCHAR(30) NOT NULL, + email VARCHAR(120) NOT NULL, + phone VARCHAR(20), + address VARCHAR(120), + city VARCHAR(30), + postcode VARCHAR(12), + country VARCHAR(20) +); + +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('John Smith','j.smith@johnsmith.org','0151 123 4567','11 New Road','Liverpool','L10 2AB','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Sue Jones','s.jones1234@gmail.com','0201 234 5678','120 Old Street','London','N10 3CD','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Alice Evans','alice.evans001@hotmail.com','0161 345 6789','3 High Road','Manchester','m13 4ef','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mohammed Trungpa','mo.trungpa@hotmail.com','0161 456 7890','25 Blue Road','Manchester','M25 6GH','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Steven King','steve.king123@hotmail.com','01245 134 4678','19 Bed Street','Newtown', 'xy2 3ac','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Nadia Sethuraman','nadia.sethuraman@mail.com',NULL,'135 Green Street','Manchester','M10 4BG','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Melinda Marsh','mel.marsh-123@gmail.com','070 1513 5671','7 Preston Road','Oldham','OL3 5XZ','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Martín Sommer','martin.sommer@dfgg.net','(91) 555 22 82','C/ Romero, 33','Madrid',28016,'Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Laurence Lebihan','laurence.lebihan@xmzx.net','91.24.4555','12, rue des Bouchers','Marseille',13008,'France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Keith Stewart','keith.stewart@gmail.com','078 4679 1282','84 Town Lane','Tadworth','td5 7ng','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Carlos Porter','carlos.porter@ortynuf.com','070 2679 6812','81 Bath Rd','Salisbury','SA61 4GD','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Carine Schmitt','carine.schmitt@dftu.net','40.32.2555','54, rue Royale', 'Nantes','44000','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jean King','jean.king@hjgp.net','07025 551 838','8489 Strong St.', 'Las Vegas','83030','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Peter Ferguson','peter.ferguson@mxnx.net','03 9520 4555','636 St Kilda Road, Level 3', 'Melbourne','3004','Australia'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Janine Labrune','janine.labrune@dlsh.net','40.67.8555','67, rue des Cinquante Otages', 'Nantes','44000','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jonas Bergulfsen','jonas.bergulfsen@dxbn.net','07-98 9555','Erling Skakkes gate 78', 'Stavern','4110','Norway'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Susan Nelson','susan.nelson@fsve.net','0415 555 1450','5677 Strong St.', 'San Rafael','97562','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Zbyszek Piestrzeniewicz','zbyszek.piestrzeniewicz@askt.net','(26) 642-7555','ul. Filtrowa 68', 'Warszawa','01-012','Poland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Roland Keitel','roland.keitel@riys.net','+49 69 66 90 2555','Lyonerstr. 34', 'Frankfurt','60528','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Julie Murphy','julie.murphy@lrtc.net','0650 555 5787','5557 North Pendale Street', 'San Francisco','94217','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Kwai Lee','kwai.lee@imic.net','0212 555 7818','897 Long Airport Avenue', 'NYC','10022','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Diego Freyre','diego.freyre@amyr.net','(91) 555 94 44','C/ Moralzarzal, 86', 'Madrid','28034','Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Christina Berglund','christina.berglund@cggp.net','0921-12 3555','Berguvsvägen 8', 'Luleå','S-958 22','Sweden'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jytte Petersen','jytte.petersen@cpbn.net','31 12 3555','Vinbæltet 34', 'Kobenhavn','1734','Denmark'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mary Saveley','mary.saveley@yppl.net','78.32.5555','2, rue du Commerce', 'Lyon','69004','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Eric Natividad','eric.natividad@swll.net','+65 221 7555','Bronz Sok., Bronz Apt. 3/6 Tesvikiye', 'Singapore','079903','Singapore'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jeff Young','jeff.young@hahh.net','0212 555 7413','4092 Furth Circle, Suite 400', 'NYC','10022','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Kelvin Leong','kelvin.leong@mqzy.net','0215 555 1555','7586 Pompton St.', 'Allentown','70267','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Juri Hashimoto','juri.hashimoto@fttv.net','0650 555 6809','9408 Furth Circle', 'Burlingame','94217','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Wendy Victorino','wendy.victorino@ueai.net','+65 224 1555','106 Linden Road Sandown, 2nd Floor', 'Singapore','069045','Singapore'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Veysel Oeztan','veysel.oeztan@vqkn.net','+47 2267 3215','Brehmen St. 121, PR 334 Sentrum', 'Bergen','N 5804','Norway'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Keith Franco','keith.franco@dlha.net','2035557845','149 Spinnaker Dr., Suite 101', 'New Haven','97823','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Isabel de Castro','isabel.de.castro@fpro.net','(1) 356-5555','Estrada da saúde n. 58', 'Lisboa','1756','Portugal'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Martine Rancé','martine.rancé@xeqs.net','20.16.1555','184, chaussée de Tournai', 'Lille','59000','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Marie Bertrand','marie.bertrand@glut.net','(1) 42.34.2555','265, boulevard Charonne', 'Paris','75012','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jerry Tseng','jerry.tseng@etea.net','6175555555','4658 Baden Av.', 'Cambridge','51247','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Julie King','julie.king@yhfj.net','2035552570','25593 South Bay Ln.', 'Bridgewater','97562','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mory Kentary','mory.kentary@nqfg.net','+81 06 6342 5555','1-6-20 Dojima', 'Kita-ku',' 530-0003','Japan'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Michael Frick','michael.frick@jdep.net','2125551500','2678 Kingston Rd., Suite 101', 'NYC','10022','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Matti Karttunen','matti.karttunen@xkig.net','90-224 8555','Keskuskatu 45', 'Helsinki','21240','Finland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Rachel Ashworth','rachel.ashworth@rzyb.net','(171) 555-1555','Fauntleroy Circus', 'Manchester','EC2 5NT','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Dean Cassidy','dean.cassidy@sntj.net','+353 1862 1555','25 Maiden Lane, Floor No. 4', 'Dublin','2','Ireland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Leslie Taylor','leslie.taylor@tunp.net','6175558428','16780 Pompton St.', 'Brickhaven','58339','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Elizabeth Devon','elizabeth.devon@bpcb.net','(171) 555-2282','12, Berkeley Gardens Blvd', 'Liverpool','WX1 6LT','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Yoshi Tamuri','yoshi.tamuri@juuq.net','(604) 555-3392','1900 Oak St.', 'Vancouver','V3F 2K1','Canada'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Miguel Barajas','miguel.barajas@rsyq.net','6175557555','7635 Spinnaker Dr.', 'Brickhaven','58339','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Julie Young','julie.young@rmhl.net','6265557265','78934 Hillside Dr.', 'Pasadena','90003','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Brydey Walker','brydey.walker@kwtj.net','+612 9411 1555','Suntec Tower Three, 8 Temasek', 'Singapore','038988','Singapore'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Frédérique Citeaux','frédérique.citeaux@vekn.net','88.60.1555','24, place Kléber', 'Strasbourg','67000','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mike Gao','mike.gao@pdrv.net','+852 2251 1555','Bank of China Tower, 1 Garden Road', 'Central Hong Kong',NULL,'Hong Kong'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Eduardo Saavedra','eduardo.saavedra@tiqa.net','(93) 203 4555','Rambla de Cataluña, 23', 'Barcelona','08022','Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mary Young','mary.young@ratm.net','3105552373','4097 Douglas Av.', 'Glendale','92561','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Horst Kloss','horst.kloss@bpzv.net','0372-555188','Taucherstraße 10', 'Cunewalde','01307','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Palle Ibsen','palle.ibsen@bjqn.net','86 21 3555','Smagsloget 45', 'Århus','8200','Denmark'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jean Fresnière','jean.fresnière@uxsm.net','(514) 555-8054','43 rue St. Laurent', 'Montréal','H1J 1C3','Canada'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Alejandra Camino','alejandra.camino@omet.net','(91) 745 6555','Gran Vía, 1', 'Madrid','28001','Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Valarie Thompson','valarie.thompson@brll.net','7605558146','361 Furth Circle', 'San Diego','91217','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Helen Bennett','helen.bennett@quet.net','(198) 555-8888','Garden House, Crowther Way 23', 'Cowes','PO31 7PJ','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Annette Roulet','annette.roulet@lgha.net','61.77.6555','1 rue Alsace-Lorraine', 'Toulouse','31000','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Renate Messner','renate.messner@ebse.net','069-0555984','Magazinweg 7', 'Frankfurt','60528','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Paolo Accorti','paolo.accorti@xcuw.net','011-4988555','Via Monte Bianco 34', 'Torino','10100','Italy'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Daniel Da Silva','daniel.da.silva@hijy.net','+33 1 46 62 7555','27 rue du Colonel Pierre Avia', 'Paris','75508','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Daniel Tonini','daniel.tonini@mxvw.net','30.59.8555','67, avenue de lEurope', 'Versailles','78000','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Henriette Pfalzheim','henriette.pfalzheim@hmib.net','0221-5554327','Mehrheimerstr. 369', 'Köln','50739','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Elizabeth Lincoln','elizabeth.lincoln@elct.net','(604) 555-4555','23 Tsawassen Blvd.', 'Tsawassen','T2F 8M4','Canada'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Peter Franken','peter.franken@fszx.net','089-0877555','Berliner Platz 43', 'München','80805','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Anna O''Hara','anna.o"hara@hzjw.net','02 9936 8555','201 Miller Street, Level 15', 'North Sydney','2060','Australia'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Giovanni Rovelli','giovanni.rovelli@xrbz.net','035-640555','Via Ludovico il Moro 22', 'Bergamo','24100','Italy'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Adrian Huxley','adrian.huxley@hmep.net','+61 2 9495 8555','Monitor Money Building, 815 Pacific Hwy', 'Chatswood','2067','Australia'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Marta Hernandez','marta.hernandez@xqti.net','6175558555','39323 Spinnaker Dr.', 'Cambridge','51247','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Ed Harrison','ed.harrison@svjb.net','+41 26 425 50 01','Rte des Arsenaux 41', 'Fribourg','1700','Switzerland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mihael Holz','mihael.holz@dnji.net','0897-034555','Grenzacherweg 237', 'Genève','1203','Switzerland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jan Klaeboe','jan.klaeboe@mpnl.net','+47 2212 1555','Drammensveien 126A, PB 211 Sentrum', 'Oslo','N 0106','Norway'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Bradley Schuyler','bradley.schuyler@stie.net','+31 20 491 9555','Kingsfordweg 151', 'Amsterdam','1043 GR','Netherlands'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mel Andersen','mel.andersen@nggg.net','030-0074555','Obere Str. 57', 'Berlin','12209','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Pirkko Koskitalo','pirkko.koskitalo@rcva.net','981-443655','Torikatu 38', 'Oulu','90110','Finland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Catherine Dewey','catherine.dewey@ndft.net','(02) 5554 67','Rue Joseph-Bens 532', 'Bruxelles','B-1180','Belgium'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Steve Frick','steve.frick@unam.net','9145554562','3758 North Pendale Street', 'White Plains','24067','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Wing Huang','wing.huang@romc.net','5085559555','4575 Hillside Dr.', 'New Bedford','50553','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Julie Brown','julie.brown@zbfm.net','6505551386','7734 Strong St.', 'San Francisco','94217','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Mike Graham','mike.graham@nlpt.net','+64 9 312 5555','162-164 Grafton Road, Level 2', 'Auckland ',NULL,'New Zealand'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Ann Brown','ann.brown@xwkb.net','(171) 555-0297','35 King George', 'London','WX3 6FW','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('William Brown','william.brown@wrbo.net','2015559350','7476 Moss Rd.', 'Newark','94019','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Ben Calaghan','ben.calaghan@bprq.net','61-7-3844-6555','31 Duncan St. West End', 'South Brisbane','4101','Australia'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Kalle Suominen','kalle.suominen@acif.net','+358 9 8045 555','Software Engineering Center, SEC Oy', 'Espoo','FIN-02271','Finland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Philip Cramer','philip.cramer@gmlf.net','0555-09555','Maubelstr. 90', 'Brandenburg','14776','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Francisca Cervantes','francisca.cervantes@sxxp.net','2155554695','782 First Street', 'Philadelphia','71270','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Jesus Fernandez','jesus.fernandez@cgxs.net','+34 913 728 555','Merchants House, 27-30 Merchant''s Quay', 'Madrid','28023','Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Brian Chandler','brian.chandler@wdgi.net','2155554369','6047 Douglas Av.', 'Los Angeles','91003','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Patricia McKenna','patricia.mckenna@eert.net','2967 555','8 Johnstown Road', 'Cork',NULL,'Ireland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Laurence Lebihan','laurence.lebihan@xmzx.net','91.24.4555','12, rue des Bouchers', 'Marseille','13008','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Paul Henriot','paul.henriot@uwua.net','26.47.1555','59 rue de l''Abbaye', 'Reims','51100','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Armand Kuger','armand.kuger@axkq.net','+27 21 550 3555','1250 Pretorius Street', 'Hatfield','0028','South Africa'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Wales MacKinlay','wales.mackinlay@omis.net','64-9-3763555','199 Great North Road', 'Auckland',NULL,'New Zealand'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Karin Josephs','karin.josephs@gyfv.net','0251-555259','Luisenstr. 48', 'Münster','44087','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Juri Yoshido','juri.yoshido@klqb.net','6175559555','8616 Spinnaker Dr.', 'Boston','51003','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Dorothy Young','dorothy.young@cwtg.net','6035558647','2304 Long Airport Avenue', 'Nashua','62005','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Lino Rodriguez','lino.rodriguez@xscn.net','(1) 354-2555','Jardim das rosas n. 32', 'Lisboa','1675','Portugal'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Braun Urs','braun.urs@aols.net','0452-076555','Hauptstr. 29', 'Bern','3012','Switzerland'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Allen Nelson','allen.nelson@eruo.net','6175558555','7825 Douglas Av.', 'Brickhaven','58339','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Pascale Cartrain','pascale.cartrain@oggv.net','(071) 23 67 2555','Boulevard Tirou, 255', 'Charleroi','B-6000','Belgium'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Georg Pipps','georg.pipps@uyvb.net','6562-9555','Geislweg 14', 'Salzburg','5020','Austria'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Arnold Cruz','arnold.cruz@awqa.net','+63 2 555 3587','15 McCallum Street, NatWest Center #13-03', 'Makati City','1227 MM','Philippines'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Maurizio Moroni','maurizio.moroni@nqnk.net','0522-556555','Strada Provinciale 124', 'Reggio Emilia','42100','Italy'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Akiko Shimamura','akiko.shimamura@pipl.net','+81 3 3584 0555','2-2-8 Roppongi', 'Minato-ku','106-0032','Japan'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Dominique Perrier','dominique.perrier@bdim.net','(1) 47.55.6555','25, rue Lauriston', 'Paris','75016','France'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Rita Müller','rita.müller@gfsn.net','0711-555361','Adenauerallee 900', 'Stuttgart','70563','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Sarah McRoy','sarah.mcroy@fjnn.net','04 499 9555','101 Lambton Quay, Level 11', 'Wellington',NULL,'New Zealand'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Michael Donnermeyer','michael.donnermeyer@lvpk.net',' +49 89 61 08 9555','Hansastr. 15', 'Munich','80686','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Maria Hernandez','maria.hernandez@uzkx.net','2125558493','5905 Pompton St., Suite 750', 'NYC','10022','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Alexander Feuer','alexander.feuer@hzrr.net','0342-555176','Heerstr. 22', 'Leipzig','04179','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Dan Lewis','dan.lewis@bqfi.net','2035554407','2440 Pompton St.', 'Glendale','97561','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Martha Larsson','martha.larsson@abhf.net','0695-34 6555','Åkergatan 24', 'Bräcke','S-844 67','Sweden'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Sue Frick','sue.frick@npgp.net','4085553659','3086 Ingle Ln.', 'San Jose','94217','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Roland Mendel','roland.mendel@wclf.net','7675-3555','Kirchgasse 6', 'Graz','8010','Austria'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Leslie Murphy','leslie.murphy@lbgq.net','2035559545','567 North Pendale Street', 'New Haven','97823','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Yu Choi','yu.choi@vmpd.net','2125551957','5290 North Pendale Street, Suite 200', 'NYC','10022','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Martín Sommer','martín.sommer@wcoa.net','(91) 555 22 82','C/ Araquil, 67', 'Madrid','28023','Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Sven Ottlieb','sven.ottlieb@dqyj.net','0241-039123','Walserweg 21', 'Aachen','52066','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Violeta Benitez','violeta.benitez@yqsd.net','5085552555','1785 First Street', 'New Bedford','50553','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Carmen Anton','carmen.anton@bhmy.net','+34 913 728555','c/ Gobelas, 19-1 Urb. La Florida', 'Madrid','28023','Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Sean Clenahan','sean.clenahan@gzyw.net','61-9-3844-6555','7 Allen Street', 'Glen Waverly','3150','Australia'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Franco Ricotti','franco.ricotti@ycbk.net','+39 022515555','20093 Cologno Monzese, Alessandro Volta 16', 'Milan',NULL,'Italy'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Steve Thompson','steve.thompson@nirj.net','3105553722','3675 Furth Circle', 'Burbank','94019','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Hanna Moos','hanna.moos@fmga.net','0621-08555','Forsterstr. 57', 'Mannheim','68306','Germany'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Alexander Semenov','alexander.semenov@xgru.net','+7 812 293 0521','2 Pobedy Square', 'Saint Petersburg','196143','Russia'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Raanan Altagar,G M','raanan.altagar,g.m@mlap.net','+ 972 9 959 8555','3 Hagalim Blv.', 'Herzlia','47625','Israel'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('José Pedro Roel','josé.pedro.roel@qjmk.net','(95) 555 82 82','C/ Romero, 33', 'Sevilla','41101','Spain'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Rosa Salazar','rosa.salazar@fzik.net','2155559857','11328 Douglas Av.', 'Philadelphia','71270','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Sue Taylor','sue.taylor@wllx.net','4155554312','2793 Furth Circle', 'Brisbane','94217','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Thomas Smith','thomas.smith@nvze.net','(171) 555-7555','120 Hanover Sq.', 'London','WA1 1DP','UK'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Valarie Franco','valarie.franco@qait.net','6175552555','6251 Ingle Ln.', 'Boston','51003','USA'); +INSERT INTO customers (name, email, phone, address, city, postcode, country) VALUES ('Tony Snowden','tony.snowden@rzcz.net','+64 9 5555500','Arenales 1938 3''A''', 'Auckland',NULL,'New Zealand'); + +CREATE TABLE reservations ( + id SERIAL PRIMARY KEY, + cust_id INTEGER NOT NULL, + room_no INTEGER, + checkin_date DATE NOT NULL, + checkout_date DATE, + no_guests INTEGER, + booking_date DATE, + CONSTRAINT res_guest_fk FOREIGN KEY (cust_id) REFERENCES customers(id), + CONSTRAINT res_room_fk FOREIGN KEY (room_no) REFERENCES rooms(room_no) +); + +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(3,'2018-06-19',204,'2018-06-22',1,'2018-06-02'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(4,'2018-07-09',311,'2018-07-11',2,'2018-06-26'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(4,'2018-07-16',312,'2018-07-19',2,'2018-06-26'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(5,'2018-06-21',104,'2018-06-23',2,'2018-06-01'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(6,'2018-06-25',211,'2018-06-28',2,'2018-05-27'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(119,'2018-08-22',101,'2018-08-27',2,'2018-07-31'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(102,'2018-06-23',202,'2018-06-28',2,'2018-06-14'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(115,'2018-06-01',106,'2018-06-04',1,'2018-05-04'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(64,'2018-08-19',402,'2018-08-22',2,'2018-08-03'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(2,'2018-06-14',208,'2018-06-20',2,'2018-06-09'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(86,'2018-06-20',108,'2018-06-21',1,'2018-05-25'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(31,'2018-08-31',302,'2018-09-02',1,'2018-08-02'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(25,'2018-06-25',206,'2018-06-28',2,'2018-06-15'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(32,'2018-08-10',405,'2018-08-11',1,'2018-07-20'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(30,'2018-07-10',404,'2018-07-11',1,'2018-06-11'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(83,'2018-08-02',103,'2018-08-04',1,'2018-07-22'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(25,'2018-06-30',103,'2018-07-04',1,'2018-06-15'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(15,'2018-06-13',201,'2018-06-15',2,'2018-05-23'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(131,'2018-07-21',301,'2018-07-27',2,'2018-06-24'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(117,'2018-07-22',101,'2018-07-26',2,'2018-07-06'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(51,'2018-08-07',107,'2018-08-11',1,'2018-08-01'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(25,'2018-06-19',109,'2018-06-21',1,'2018-05-26'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(46,'2018-08-04',301,'2018-08-08',2,'2018-07-19'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(38,'2018-07-20',411,'2018-07-22',2,'2018-07-07'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(19,'2018-08-04',312,'2018-08-09',2,'2018-07-11'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(97,'2018-06-22',210,'2018-06-28',2,'2018-06-22'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(76,'2018-08-22',102,'2018-08-24',2,'2018-08-16'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(108,'2018-08-27',308,'2018-08-30',1,'2018-08-11'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(51,'2018-06-09',409,'2018-06-10',2,'2018-06-02'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(82,'2018-08-28',305,'2018-08-30',1,'2018-08-09'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(77,'2018-06-14',112,'2018-06-15',1,'2018-05-16'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(52,'2018-07-24',305,'2018-07-25',1,'2018-07-11'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(14,'2018-08-31',301,'2018-09-02',1,'2018-08-26'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(23,'2018-07-14',304,'2018-07-15',1,'2018-06-28'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(114,'2018-06-12',203,'2018-06-16',1,'2018-06-05'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(58,'2018-06-20',110,'2018-06-25',2,'2018-06-15'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(30,'2018-06-05',408,'2018-06-06',1,'2018-05-25'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(129,'2018-07-04',306,'2018-07-05',2,'2018-06-13'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(129,'2018-07-03',206,'2018-07-05',2,'2018-06-28'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(123,'2018-08-31',312,'2018-09-04',1,'2018-08-24'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(20,'2018-07-03',410,'2018-07-08',2,'2018-06-11'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(110,'2018-08-10',301,'2018-08-11',2,'2018-07-13'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(104,'2018-06-01',309,'2018-06-07',2,'2018-05-24'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(5,'2018-06-17',311,'2018-06-22',2,'2018-06-08'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(9,'2018-07-15',305,'2018-07-21',1,'2018-07-08'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(104,'2018-06-15',301,'2018-06-16',1,'2018-06-01'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(31,'2018-08-03',111,'2018-08-04',1,'2018-07-11'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(54,'2018-06-21',111,'2018-06-26',2,'2018-06-03'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(16,'2018-08-01',308,'2018-08-07',1,'2018-07-30'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(37,'2018-06-23',402,'2018-06-28',2,'2018-06-02'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(117,'2018-08-20',206,'2018-08-21',1,'2018-08-19'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(115,'2018-06-08',203,'2018-06-11',1,'2018-05-06'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(126,'2018-09-02',104,'2018-09-07',1,'2018-08-07'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(97,'2018-08-15',404,'2018-08-18',1,'2018-07-29'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(109,'2018-06-19',202,'2018-06-21',1,'2018-06-14'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(91,'2018-07-21',211,'2018-07-26',2,'2018-07-10'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(97,'2018-07-12',309,'2018-07-14',1,'2018-06-18'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(88,'2018-07-16',206,'2018-07-17',1,'2018-07-13'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(30,'2018-05-30',109,'2018-06-05',1,'2018-05-19'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(20,'2018-08-27',311,'2018-08-31',1,'2018-08-19'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(77,'2018-06-21',110,'2018-06-24',2,'2018-06-11'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(121,'2018-06-04',312,'2018-06-05',1,'2018-05-28'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(15,'2018-08-04',307,'2018-08-08',1,'2018-07-18'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(79,'2018-08-07',303,'2018-08-10',2,'2018-07-30'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(80,'2018-06-02',107,'2018-06-06',2,'2018-05-29'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(40,'2018-09-02',310,'2018-09-05',1,'2018-08-06'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(9,'2018-08-22',105,'2018-08-25',1,'2018-08-22'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(64,'2018-06-12',104,'2018-06-18',1,'2018-06-12'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(43,'2018-05-30',204,'2018-06-04',2,'2018-05-05'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(26,'2018-08-09',205,'2018-08-12',1,'2018-07-19'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(41,'2018-07-26',302,'2018-07-31',2,'2018-07-03'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(75,'2018-06-17',111,'2018-06-21',2,'2018-06-01'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(65,'2018-06-12',411,'2018-06-14',2,'2018-05-30'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(96,'2018-08-25',205,'2018-08-31',1,'2018-08-22'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(14,'2018-06-29',303,'2018-07-05',1,'2018-06-16'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(35,'2018-08-09',411,'2018-08-14',2,'2018-07-17'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(115,'2018-06-11',202,'2018-06-13',1,'2018-05-27'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(119,'2018-08-26',303,'2018-08-28',2,'2018-08-12'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(38,'2018-08-07',210,'2018-08-12',2,'2018-08-07'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(96,'2018-08-22',106,'2018-08-27',1,'2018-08-19'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(24,'2018-08-07',402,'2018-08-08',1,'2018-07-25'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(106,'2018-07-24',206,'2018-07-29',1,'2018-07-10'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(130,'2018-06-20',209,'2018-06-21',1,'2018-05-29'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(84,'2018-06-14',111,'2018-06-16',2,'2018-06-03'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(108,'2018-06-29',405,'2018-06-30',2,'2018-06-14'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(12,'2018-08-26',401,'2018-08-29',1,'2018-08-06'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(67,'2018-07-18',401,'2018-07-19',1,'2018-07-01'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(63,'2018-08-12',412,'2018-08-17',1,'2018-08-07'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(2,'2018-06-09',412,'2018-06-11',2,'2018-06-05'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(66,'2018-07-31',305,'2018-08-03',1,'2018-07-25'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(9,'2018-06-19',102,'2018-06-20',1,'2018-06-04'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(44,'2018-07-29',410,'2018-08-02',2,'2018-07-12'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(129,'2018-08-02',203,'2018-08-06',1,'2018-07-17'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(29,'2018-06-24',212,'2018-06-27',1,'2018-06-18'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(55,'2018-09-02',311,'2018-09-06',2,'2018-08-27'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(13,'2018-06-29',104,'2018-06-30',2,'2018-06-04'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(116,'2018-08-18',302,'2018-08-20',1,'2018-08-12'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(70,'2018-06-20',404,'2018-06-22',1,'2018-06-08'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(49,'2018-06-30',402,'2018-07-04',1,'2018-06-05'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(18,'2018-07-18',211,'2018-07-20',2,'2018-07-01'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(95,'2018-06-02',411,'2018-06-07',1,'2018-05-25'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(93,'2018-08-11',207,'2018-08-15',1,'2018-07-24'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(13,'2018-06-19',405,'2018-06-21',1,'2018-05-24'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(98,'2018-08-30',207,'2018-09-05',2,'2018-08-23'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(108,'2018-08-24',303,'2018-08-26',1,'2018-08-05'); +INSERT INTO reservations (cust_id,checkin_date,room_no,checkout_date,no_guests,booking_date) VALUES(84,'2018-07-03',401,'2018-07-09',1,'2018-06-21'); + +-- PL/pgSQL function to fix dates in the hotel database to make them current with the course run. + +drop function if exists fixup_dates(); + +create function fixup_dates() returns integer as +$$ +declare + date_adj integer; +begin + select current_date - max(booking_date) + 30 + into date_adj + from reservations; + + update reservations set + booking_date = least(current_date, booking_date + date_adj), + checkin_date = checkin_date + date_adj, + checkout_date = checkout_date + date_adj; + + return null; +end +$$ language plpgsql; + +select fixup_dates(); + +update reservations set room_no = null where checkin_date > current_date; + +CREATE TABLE invoices ( + id SERIAL PRIMARY KEY, + res_id INTEGER NOT NULL, + total NUMERIC(10,2), + invoice_date DATE, + paid BOOLEAN DEFAULT FALSE, + FOREIGN KEY (res_id) REFERENCES reservations(id) +); + +INSERT INTO invoices (res_id, total, invoice_date, paid) + SELECT res.id, + rm.rate * (res.checkout_date - res.checkin_date), + res.checkout_date, + (rm.rate * (res.checkout_date - res.checkin_date) % 11) != 2 + FROM reservations res JOIN + rooms rm ON (res.room_no = rm.room_no) + WHERE res.checkout_date <= CURRENT_DATE + ORDER BY res.checkout_date; + diff --git a/week-3/cyf-hotels-api/package-lock.json b/week-3/cyf-hotels-api/package-lock.json new file mode 100644 index 00000000..b2788bd2 --- /dev/null +++ b/week-3/cyf-hotels-api/package-lock.json @@ -0,0 +1,485 @@ +{ + "name": "week-3", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "pg": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.3.3.tgz", + "integrity": "sha512-wmUyoQM/Xzmo62wgOdQAn5tl7u+IA1ZYK7qbuppi+3E+Gj4hlUxVHjInulieWrd0SfHi/ADriTb5ILJ/lsJrSg==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.3.0", + "pg-pool": "^3.2.1", + "pg-protocol": "^1.2.5", + "pg-types": "^2.1.0", + "pgpass": "1.x", + "semver": "4.3.2" + } + }, + "pg-connection-string": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.3.0.tgz", + "integrity": "sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w==" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", + "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" + }, + "pg-protocol": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.5.tgz", + "integrity": "sha512-1uYCckkuTfzz/FCefvavRywkowa6M5FohNMF5OjKrqo9PSR8gYc8poVmwwYQaBxhmQdBjhtP514eXy9/Us2xKg==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/week-3/cyf-hotels-api/package.json b/week-3/cyf-hotels-api/package.json new file mode 100644 index 00000000..536ef0c6 --- /dev/null +++ b/week-3/cyf-hotels-api/package.json @@ -0,0 +1,15 @@ +{ + "name": "week-3", + "version": "1.0.0", + "description": "", + "main": "server.js", + "scripts": { + "start": "node server" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.17.1", + "pg": "^8.3.3" + } +} \ No newline at end of file diff --git a/week-3/cyf-hotels-api/server.js b/week-3/cyf-hotels-api/server.js new file mode 100644 index 00000000..71a0e92c --- /dev/null +++ b/week-3/cyf-hotels-api/server.js @@ -0,0 +1,27 @@ +const express = require("express"); +const app = express(); +const bodyParser = require("body-parser"); +app.use(bodyParser.json()); + +app.listen(3000, function () { + console.log("Server is listening on port 3000. Ready to accept requests!"); +}); +const { Pool } = require('pg'); + +const db = new Pool({ + user: 'razan', // replace with you username + host: 'localhost', + database: 'cyf_hotel', + password: '123', + port: 5432 + +}); + +app.get("/customers", function (req, res) { + var sql = "select * from customers"; + db.query(sql, function (err, result) { + res.json({ // return rows to browser + customers: result.rows + }); + }); +}); \ No newline at end of file diff --git a/week-3/mandatory/2-api/task.md b/week-3/mandatory/2-api/task.md index 924f54de..4b46894e 100644 --- a/week-3/mandatory/2-api/task.md +++ b/week-3/mandatory/2-api/task.md @@ -10,24 +10,22 @@ To submit you should open a pull request with all of your code in this folder. In the following homework, you will create new API endpoints in the NodeJS application `cyf-ecommerce-api` that you created for last week's homework for the Database 2 class. -- If you don't have it already, add a new GET endpoint `/products` to load all the product names along with their prices and supplier names. +- If you don't have it already, add a new GET endpoint /products to load all the product names along with their supplier names. -- Update the previous GET endpoint `/products` to filter the list of products by name using a query parameter, for example `/products?name=Cup`. This endpoint should still work even if you don't use the `name` query parameter! +Update the previous GET endpoint /products to filter the list of products by name using a query parameter, for example /products?name=Cup. This endpoint should still work even if you don't use the name query parameter! -- Add a new GET endpoint `/customers/:customerId` to load a single customer by ID. +Add a new GET endpoint /customers/:customerId to load a single customer by ID. -- Add a new POST endpoint `/customers` to create a new customer with name, address, city and country. +Add a new POST endpoint /customers to create a new customer. -- Add a new POST endpoint `/products` to create a new product. +Add a new POST endpoint /products to create a new product (with a product name, a price and a supplier id). Check that the price is a positive integer and that the supplier ID exists in the database, otherwise return an error. -- Add a new POST endpoint `/availability` to create a new product availability (with a price and a supplier id). Check that the price is a positive integer and that both the product and supplier ID's exist in the database, otherwise return an error. +Add a new POST endpoint /customers/:customerId/orders to create a new order (including an order date, and an order reference) for a customer. Check that the customerId corresponds to an existing customer or return an error. -- Add a new POST endpoint `/customers/:customerId/orders` to create a new order (including an order date, and an order reference) for a customer. Check that the customerId corresponds to an existing customer or return an error. +Add a new PUT endpoint /customers/:customerId to update an existing customer (name, address, city and country). -- Add a new PUT endpoint `/customers/:customerId` to update an existing customer (name, address, city and country). +Add a new DELETE endpoint /orders/:orderId to delete an existing order along all the associated order items. -- Add a new DELETE endpoint `/orders/:orderId` to delete an existing order along with all the associated order items. +Add a new DELETE endpoint /customers/:customerId to delete an existing customer only if this customer doesn't have orders. -- Add a new DELETE endpoint `/customers/:customerId` to delete an existing customer only if this customer doesn't have orders. - -- Add a new GET endpoint `/customers/:customerId/orders` to load all the orders along with the items in the orders of a specific customer. Especially, the following information should be returned: order references, order dates, product names, unit prices, suppliers and quantities. +Add a new GET endpoint /customers/:customerId/orders to load all the orders along the items in the orders of a specific customer. Especially, the following information should be returned: order references, order dates, product names, unit prices, suppliers and quantities. \ No newline at end of file diff --git a/week-3/mandatory/cyf-ecommerce-api/.gitignore b/week-3/mandatory/cyf-ecommerce-api/.gitignore new file mode 100644 index 00000000..3c3629e6 --- /dev/null +++ b/week-3/mandatory/cyf-ecommerce-api/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/week-3/mandatory/cyf-ecommerce-api/cyf_ecommerce.sql b/week-3/mandatory/cyf-ecommerce-api/cyf_ecommerce.sql new file mode 100644 index 00000000..3d039c9c --- /dev/null +++ b/week-3/mandatory/cyf-ecommerce-api/cyf_ecommerce.sql @@ -0,0 +1,148 @@ +drop table if exists order_items; +drop table if exists orders; +drop table if exists customers; +drop table if exists products; +drop table if exists suppliers; + +CREATE TABLE customers ( + id SERIAL PRIMARY KEY, + name VARCHAR(50) NOT NULL, + address VARCHAR(120), + city VARCHAR(30), + country VARCHAR(20) +); + +CREATE TABLE suppliers ( + id SERIAL PRIMARY KEY, + supplier_name VARCHAR(100) NOT NULL, + country VARCHAR(20) NOT NULL +); + +CREATE TABLE products ( + id SERIAL PRIMARY KEY, + product_name VARCHAR(100) NOT NULL, + unit_price INT NOT NULL, + supplier_id INT REFERENCES suppliers(id) +); + +CREATE TABLE orders ( + id SERIAL PRIMARY KEY, + order_date DATE NOT NULL, + order_reference VARCHAR(10) NOT NULL, + customer_id INT REFERENCES customers(id) +); + +CREATE TABLE order_items ( + id SERIAL PRIMARY KEY, + order_id INT REFERENCES orders(id), + product_id INT REFERENCES products(id), + quantity INT NOT NULL +); + +/////////////////////homework solution //////////////////////// +1-SELECT name, address FROM customers WHERE country ='United States'; + +2-SELECT * FROM customers ORDER BY name ; + +3-SELECT * FROM products WHERE unit_price > 100; + +4-SELECT * FROM products WHERE product_name LIKE '%socks%'; + +5-SELECT * FROM products +ORDER BY unit_price DESC + limit 5; + +6-SELECT products.product_name, products.unit_price, supplier_name FROM products +INNER JOIN suppliers ON products.supplier_id = suppliers.id ; + +7-SELECT products.product_name, supplier_name FROM products +INNER JOIN suppliers ON products.supplier_id = suppliers.id WHERE suppliers.country = 'United Kingdom'; +8- SELECT * FROM orders WHERE id = 1; + +9-SELECT orders.* , customers.name FROM orders +INNER JOIN customers ON orders.customer_id = customers.id WHERE customers.name = 'Hope Crosby'; + +10-SELECT products.product_name, products.unit_price, order_items.quantity ,orders.order_reference FROM order_items +INNER JOIN orders ON order_items.order_id = orders.id +INNER JOIN products ON order_items.product_id = products.id +WHERE orders.order_reference = 'ORD006'; + +11-SELECT customers.name, orders.order_reference, orders.order_date, products.product_name, suppliers.supplier_name , order_items.quantity FROM +customers INNER JOIN orders ON orders.customer_id = customers.id +INNER JOIN order_items ON order_items.order_id = orders.id +INNER JOIN products ON order_items.product_id = products.id +INNER JOIN suppliers ON products.supplier_id = suppliers.id; + +12- SELECT DISTINCT customers.name FROM +customers INNER JOIN orders ON orders.customer_id = customers.id +INNER JOIN order_items ON order_items.order_id = orders.id +INNER JOIN products ON order_items.product_id = products.id +INNER JOIN suppliers ON products.supplier_id = suppliers.id +WHERE suppliers.country = 'China'; +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +INSERT INTO customers (name, address, city, country) VALUES ('Guy Crawford','770-2839 Ligula Road','Paris','France'); +INSERT INTO customers (name, address, city, country) VALUES ('Hope Crosby','P.O. Box 276, 4976 Sit Rd.','Steyr','United Kingdom'); +INSERT INTO customers (name, address, city, country) VALUES ('Britanney Kirkland','P.O. Box 577, 5601 Sem, St.','Little Rock','United Kingdom'); +INSERT INTO customers (name, address, city, country) VALUES ('Amber Tran','6967 Ac Road','Villafranca Asti','United States'); +INSERT INTO customers (name, address, city, country) VALUES ('Edan Higgins','Ap #840-3255 Tincidunt St.','Arles','United States'); +INSERT INTO customers (name, address, city, country) VALUES ('Quintessa Austin','597-2737 Nunc Rd.','Saint-Marc','United Kingdom'); + +INSERT INTO suppliers (supplier_name, country) VALUES ('Amazon', 'United States'); +INSERT INTO suppliers (supplier_name, country) VALUES ('Taobao', 'China'); +INSERT INTO suppliers (supplier_name, country) VALUES ('Argos', 'United Kingdom'); +INSERT INTO suppliers (supplier_name, country) VALUES ('Sainsburys', 'United Kingdom'); + +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Tee Shirt Olympic Games', 20, 1); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Tee Shirt Olympic Games', 18, 2); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Tee Shirt Olympic Games', 21, 3); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Mobile Phone X', 299, 1); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Mobile Phone X', 249, 4); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Super warm socks', 10, 1); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Super warm socks', 5, 2); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Super warm socks', 8, 3); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Super warm socks', 10, 4); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Le Petit Prince', 10, 1); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Le Petit Prince', 10, 4); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Ball', 14, 1); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Ball', 15, 4); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Ball', 20, 2); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Javascript Book', 40, 1); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Javascript Book', 39, 3); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Javascript Book', 41, 2); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Coffee Cup', 3, 1); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Coffee Cup', 4, 2); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Coffee Cup', 4, 3); +INSERT INTO products (product_name, unit_price, supplier_id) VALUES ('Coffee Cup', 5, 4); + +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-06-01', 'ORD001', 1); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-07-15', 'ORD002', 1); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-07-11', 'ORD003', 1); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-05-24', 'ORD004', 2); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-05-30', 'ORD005', 3); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-07-05', 'ORD006', 4); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-04-05', 'ORD007', 4); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-07-23', 'ORD008', 5); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-07-24', 'ORD009', 5); +INSERT INTO orders (order_date, order_reference, customer_id) VALUES ('2019-05-10', 'ORD010', 5); + +INSERT INTO order_items (order_id, product_id, quantity) VALUES(1, 2, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(1, 7, 5); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(2, 8, 4); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(2, 11, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(3, 20, 10); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(3, 14, 2); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(4, 4, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(5, 16, 2); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(5, 10, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(6, 19, 3); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(6, 17, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(6, 11, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(6, 9, 3); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(7, 8, 15); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(8, 1, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(8, 5, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(9, 13, 2); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(10, 14, 1); +INSERT INTO order_items (order_id, product_id, quantity) VALUES(10, 6, 5); + + diff --git a/week-3/mandatory/cyf-ecommerce-api/homework.js b/week-3/mandatory/cyf-ecommerce-api/homework.js new file mode 100644 index 00000000..a6c990c6 --- /dev/null +++ b/week-3/mandatory/cyf-ecommerce-api/homework.js @@ -0,0 +1,244 @@ +const express = require("express"); +const app = express(); +app.use(express.json()) + +const { Pool } = require('pg'); + +const pool = new Pool({ + user: 'postgres', + host: 'localhost', + database: 'cyf_ecommerce', + password: 'razan', + port: 5432 +}); + +app.get("/customers", function(req, res) { + pool.query('SELECT * FROM customers', (error, result) => { + res.json(result.rows); + }) + }) + ////////////////////////////////////////////////////////////// + app.get("/orders", function(req, res) { + pool.query('SELECT * FROM orders', (error, result) => { + res.json(result.rows); + }) + }) + ///////////////////////////////////////////////////////////// + app.get("/products", function(req, res) { + pool.query('SELECT * FROM products', (error, result) => { + res.json(result.rows); + }) + }) + /////////////////////////////////////////////////////////// +app.get("/suppliers", function(req, res) { + pool.query('SELECT * FROM suppliers', (error, result) => { + res.json(result.rows); + }) +}) +///////If you don't have it already, add a new GET endpoint /products to load all the product names along with their supplier names./////// + app.get("/products", function(req, res) { + pool.query( 'SELECT products.product_name, supplier_name FROM products ' + + ' INNER JOIN suppliers ON products.supplier_id = suppliers.id ', (error, result) => { + res.json(result.rows); + +}) +}) +//////Update the previous GET endpoint /products to filter the list of products by name using a query parameter, for example /products?name=Cup. This endpoint should still work even if you don't use the name query parameter!//////// +app.get("/products", function(req, res) { +console.log(req.query.name); + const name = req.query.name + +let query1= "SELECT products.product_name, supplier_name FROM products INNER JOIN suppliers ON products.supplier_id = suppliers.id" +let query2 = "SELECT products.product_name, supplier_name FROM products INNER JOIN suppliers ON products.supplier_id = suppliers.id where name like $1" + + if(name){ /////////there is problem in this one it return undefined from the postman ////// +pool +.query(query2, [`%${name.toLowerCase()}%`]) +.then((result) => res.json(result.rows)) +.catch((e) => console.error(e)) + +} +else{ + pool.query(query1, (error, result)=>{ + + res.json(result.rows) + } + ) + } +}) + +//////Add a new GET endpoint /customers/:customerId to load a single customer by ID.//////// +app.get("/customers/:customerId", function (req, res) { + const custId =Number(req.params.customerId); + + if(custId<0){ + return res.status(400).send(" please enter positive number") + } + + pool + .query("SELECT * FROM customers WHERE id=$1", [custId]) + .then((result) => res.json(result.rows)) + .catch((e) => console.error(e)); + }); + //////////// get order by orders id ////////////////////////////////////////////////// + app.get("/orders/:order_id", function (req, res) { + const orderId =Number(req.params.order_id); + + if(orderId<0){ + return res.status(400).send(" please enter positive number") + } + + pool + .query("SELECT * FROM orders WHERE id=$1", [orderId]) + .then((result) => res.json(result.rows)) + .catch((e) => console.error(e)); + }); +////Add a new POST endpoint /customers to create a new customer./////// + app.post("/customers", function (req, res) { + console.log(req.body); + const newName = req.body.name; + const newAddress = req.body.address; + const newCity = req.body.city; + const newCountry = req.body.country; + + pool + .query("SELECT * FROM customers WHERE name=$1", [newName]) + .then((result) => { + if (result.rows.length > 0) { + return res + .status(400) + .send("An customers with the same name already exists!"); + } else { + const query = + "INSERT INTO customers (name, address, city, country) VALUES ($1, $2, $3, $4)"; + + pool + .query(query, [newName, newAddress, newCity,newCountry ]) + .then(() => res.send("Customer created!")) + .catch((e) => console.error(e)); + } + }); + }); + //////// Add a new POST endpoint /products to create a new product (with a product name, a price and a supplier id). Check that the price is a positive integer and that the supplier ID exists in the database, otherwise return an error./////// + app.post("/products", function (req, res) { + console.log(req.body); + const newName = req.body.product_name ; + const newPrice = req.body.unit_price ; + const newId = req.body.supplier_id ; + + if(!Number.isInteger(newPrice) || newPrice <= 0){ + return res.status(400).send(" please enter positive number") + + } + pool + .query("SELECT * FROM products WHERE supplier_id=$1", [newId]) + .then((result) => { + if (result.rows.length < 0) { + return res + .status(400) + .send("An supplier doesn't exists!"); + } else { + const query = + "INSERT INTO products(product_name, unit_price, supplier_id) VALUES ($1, $2, $3)"; + + pool + .query(query, [newName, newPrice, newId ]) + .then(() => res.send("Customer created!")) + .catch((e) => console.error(e)); + } + }); + }); + ////////Add a new POST endpoint /customers/:customerId/orders to create a new order (including an order date, and an order reference) for a customer. Check that the customerId corresponds to an existing customer or return an error///////// + app.post("/customers/:customerId/orders", function (req, res) { + console.log(req.body); + const custId = req.params.customer_id ; + const newDate = req.body.order_date ; + const newRef = req.body.order_reference ; + + + pool + .query("SELECT * FROM orders WHERE customer_id =$1", [custId]) + .then((result) => { + if (result.rows.length < 0) { + return res + .status(400) + .send("An customers doesn't exists!"); + } else { + //////////////////HOW TO KEEP THE ORIGINAL VALUE FOR CUSTOMER_ID/////////////// + const query = + "INSERT INTO orders (order_date, order_reference ,customer_id ) VALUES ($1, $2,$3 )"; + + pool + .query(query, [newDate, newRef, custId ]) + .then(() => res.send("Order created!")) + .catch((e) => console.error(e)); + } + }); + }); + ///////////////Add a new PUT endpoint /customers/:customerId to update an existing customer (name, address, city and country).///////////////// + app.put("/customers/:customerId", function (req, res) { + const custId = req.params.customerId; + const newName = req.body.name; + const newAddress = req.body.address; + const newCity = req.body.city; + const newCountry = req.body.country; + + pool + .query("UPDATE customers SET name=$2 , address =$3, city= $4, country= $5 WHERE id=$1 ", [ custId,newName, newAddress, newCity, newCountry]) + .then((result) => res.json(result.rows)) + .catch((e) => console.error(e)); + }); + /////////Add a new DELETE endpoint /orders/:orderId to delete an existing order along all the associated order items.///////////////////// + app.delete("/orders/:order_id", function (req, res) { + const orderId = req.params.order_id; + + pool + .query("DELETE FROM order_items WHERE order_id =$1", [orderId]) + .then(() => { + pool + .query("DELETE FROM orders WHERE id=$1", [orderId]) + .then(() => res.send(`Customer ${orderId} deleted!`)) + .catch((e) => console.error(e)); + }) + .catch((e) => console.error(e)); + }); + + + + + ////////Add a new DELETE endpoint /customers/:customerId to delete an existing customer only if this customer doesn't have orders./// + app.delete("/customers/:customer_id", function (req, res) { + const customerId = req.params.customer_id; + + + pool + .query("SELECT * FROM orders WHERE customer_id =$1", [customerId]) + + .then((result) => { + if (result.rows.length > 0) { + return res + .status(400) + .send("This customer has order!"); + } else { + + pool + .query("DELETE FROM customers WHERE id =$1", [customerId]) + .then(() => res.send(`Customer ${customerId} deleted!`)) + .catch((e) => console.error(e)); + } + }); + }); +////Add a new GET endpoint /customers/:customerId/orders to load all the orders along the items in the orders of a specific customer. Especially, the following information should be returned: order references, order dates, product names, unit prices, suppliers and quantities.//// + app.get("/customers/:customer_id/orders", function (req, res) { + console.log(req.body); + const custId = req.params.customer_id ; + + pool + .query("SELECT orders.order_reference, orders.order_date, products.product_name, products.unit_price, suppliers.supplier_name , order_items.quantity FROM orders INNER JOIN order_items ON order_items.order_id = orders.id INNER JOIN products ON order_items.product_id = products.id INNER JOIN suppliers ON products.supplier_id = suppliers.id where customer_id=$1", [custId]) + .then((result) => res.json(result.rows)) + .catch((e) => console.error(e)); + }) +app.listen(3000, ()=> { + console.log("Server is listening on port 3000."); +}) + \ No newline at end of file diff --git a/week-3/mandatory/cyf-ecommerce-api/package-lock.json b/week-3/mandatory/cyf-ecommerce-api/package-lock.json new file mode 100644 index 00000000..703c648d --- /dev/null +++ b/week-3/mandatory/cyf-ecommerce-api/package-lock.json @@ -0,0 +1,1359 @@ +{ + "name": "cyf-ecommerce-api", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + } + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "requires": { + "ini": "^1.3.5" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + } + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "requires": { + "package-json": "^6.3.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nodemon": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz", + "integrity": "sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==", + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "pg": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.4.1.tgz", + "integrity": "sha512-NRsH0aGMXmX1z8Dd0iaPCxWUw4ffu+lIAmGm+sTCwuDDWkpEgRCAHZYDwqaNhC5hG5DRMOjSUFasMWhvcmLN1A==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.4.0", + "pg-pool": "^3.2.1", + "pg-protocol": "^1.3.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + } + }, + "pg-connection-string": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", + "integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", + "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" + }, + "pg-protocol": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.3.0.tgz", + "integrity": "sha512-64/bYByMrhWULUaCd+6/72c9PMWhiVFs3EVxl9Ct6a3v/U8+rKgqP2w+kKg/BIGgMJyB+Bk/eNivT32Al+Jghw==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", + "requires": { + "split2": "^3.1.1" + } + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "registry-auth-token": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz", + "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==", + "requires": { + "rc": "^1.2.8" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "requires": { + "rc": "^1.2.8" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "requires": { + "debug": "^2.2.0" + } + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "requires": { + "string-width": "^4.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/week-3/mandatory/cyf-ecommerce-api/package.json b/week-3/mandatory/cyf-ecommerce-api/package.json new file mode 100644 index 00000000..719b752a --- /dev/null +++ b/week-3/mandatory/cyf-ecommerce-api/package.json @@ -0,0 +1,17 @@ +{ + "name": "cyf-ecommerce-api", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node homework.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.17.1", + "nodemon": "^2.0.6", + "pg": "^8.4.1" + } +}