Added routes and DB functions for items and images - need to test

main
Ashelyn Dawn 4 years ago
parent 690ab42fb8
commit 502532262e

@ -0,0 +1,44 @@
const router = require('express-promise-router')()
const parseJSON = require('body-parser').json()
const db = require('../db')
const {validationResult} = require('express-validator')
const validate = require('./middleware/validators')
const upload = multer({
storage: multer.memoryStorage(),
limits: {
files: 1,
fileSize: 500000
}
})
router.post('/', parseJSON, validate.urlSlugRestrictions('slug'), async (req, res) => {
const errors = validationResult(req)
if(!errors.isEmpty())
return res.status(422).json({errors: errors.array()})
// TODO: Create session
res.json(user)
})
router.post('/:uuid/images', upload.single('image'), async (req, res) => {
// Handle either image upload body or JSON body
try {
if(req.file)
await db.item.addImage(req.params.uuid, req.file.buffer)
else
await db.item.addImage(req.params.uuid, await b64.decode(req.body.image.split(',')[1]))
} catch (error) {
error.status = 500
throw error
}
res.json(await db.item.findById(req.params.uuid))
})
module.exports = router;

@ -17,3 +17,6 @@ validators.checkEmailNotUsed = body('email').custom(async email=>{
const user = await db.user.findByEmail(email)
if(user) throw new Error('Email already in use')
})
validators.urlSlugRestrictions = field => body(field).isString().isLength({min: 3, max: 20}).matches(/[-a-z0-9_]*/i)
.withMessage('Slug can be between 3-20 characters long, and can include letters, numbers, dash or underscore')

@ -2,13 +2,13 @@ import Link from "next/link"
import PropTypes from "prop-types"
import React from "react"
// import logo from './sos-logo.png'
import logo from './sos-logo.png'
import styles from './style.module.css'
const Header = ({user}) => (
<header className={styles.container}>
<div className={styles.logo}>
{/* <img alt="" src={logo}/> */}
<img alt="" src={logo}/>
</div>
<h1 className={styles.title}>
<Link href="/"><a>Society <span>of</span> Socks</a></Link>

@ -0,0 +1,34 @@
module.exports = [{
mapId: 'imageMap',
idProperty: 'uuid',
properties: [
'featured',
'large_file',
'thumb_file',
'mime_type',
'date_uploaded'
],
associations: [
{name: 'uploader', mapId: 'userMap', columnPrefix: 'user_'}
]
},{
mapId: 'itemMap',
idProperty: 'uuid',
properties: [
'name',
'description',
'urlslug',
'price_cents',
'published'
],
collections: [
{name: 'images', mapId: 'imageMap', columnPrefix: 'imageColumn_'}
]
},{
mapId: 'bareImageMap',
idProperty: 'uuid',
properties: [
'mime_type',
'file'
]
}]

@ -0,0 +1,99 @@
const pg = require('../pg')
const joinjs = require('join-js').default;
const debug = require('debug')('sos:db:user')
const mappings = require('../mappings')
const sharp = require('sharp')
const item = module.exports = {}
item.findById = async (item_uuid) => {
const query = {
text: 'select * from v_item where item_uuid = $1',
values: [
item_uuid
]
}
debug(query);
const {rows} = await pg.query(query)
return joinjs.map(rows, mappings, 'itemMap', 'item_')[0];
}
item.findBySlug = async (item_slug) => {
const query = {
text: 'select * from v_item where item_urlslug = $1',
values: [
item_slug
]
}
debug(query);
const {rows} = await pg.query(query)
return joinjs.map(rows, mappings, 'itemMap', 'item_')[0];
}
item.create = async (name, urlslug, description, price_cents, published) => {
const query = {
text: 'select * from public.create_item($1::text, $2::citext, $2::text, $4::integer, $5::boolean)',
values: [
name,
urlslug,
description,
price_cents,
published
]
}
debug(query)
const {rows} = await pg.query(query)
return joinjs.map(rows, mappings, 'itemMap', 'item_')
}
item.addImage = async (item_uuid, image_buffer, uploader_uuid) => {
// Default param chain: output as png
const source = sharp(image_buffer).png()
// All output images clone the source param chain, and then
// resize before creating a buffer
const [image, thumb] = await Promise.all([
source.clone().toBuffer(),
source.clone().resize({width: 300}).toBuffer()
])
const query = {
text: 'select * from public.add_image_to_item($1, $2, $3, $4, $5)',
values: [
item_uuid,
image,
thumb,
'image/png',
uploader_uuid
]
}
const {rows} = await pg.query(query)
return joinjs.map(rows, mappings, 'itemMap', 'item_')
}
const queries = {
'large': 'select * from get_image_large($1)',
'thumb': 'select * from get_image_thumb($1)'
}
item.getImage = async (image_uuid, size) => {
if(!profileSizeQueries[size])
throw new Error(`Cannot get unknown image size: "${size}"`)
const query = {
text: profileSizeQueries[size],
values: [image_uuid]
}
const {rows} = await pg.query(query)
return joinjs.map(rows, relationMaps, 'bareImageMap', 'image_')[0];
}

@ -55,6 +55,20 @@ create table "cart_item" (
cart_item_time_added timestamptz not null default now()
);
create table "image" (
image_uuid uuid primary key default uuid_generate_v4(),
image_featured boolean not null default false,
image_item_uuid uuid not null references "item" (item_uuid),
image_large_file bytea not null,
image_thumb_file bytea not null,
image_mime_type varchar not null,
image_uploader_uuid uuid not null references "user" (user_uuid),
image_date_uploaded timestamptz not null default now()
);
create unique index only_one_primary_key on "image" (image_item_uuid, image_featured)
where image_featured = true;
create table "category" (
category_uuid uuid primary key default uuid_generate_v4(),
category_name text not null,

@ -36,3 +36,15 @@ create or replace view public.v_category as
left join "category" "child_category" on "category_category".category_category_child_uuid = "child_category".category_uuid
left join "category_item" on "category".category_uuid = "category_item".category_item_category_uuid
left join "item" on "category_item".category_item_item_uuid = "item".item_uuid;
create or replace view public.v_item as
select
"item".*,
"image".image_uuid,
"image".image_featured,
"image".image_mime_type,
"image".image_date_uploaded,
"user".user_email
from "item"
left join "image" on "item".item_uuid = "image".image_item_uuid
left join "user" on "image".image_uploader_uuid = "user".user_uuid;

@ -51,3 +51,94 @@ begin
return query select * from public.validate_session(_session_uuid);
end; $function$;
create or replace function public.create_item(_name text, _urlslug citext, _description text, _price_cents integer, _published boolean)
returns setof public.v_item
language plpgsql
as $function$
declare
_item_uuid uuid;
begin
insert into "item" (
item_name,
item_urlslug,
item_description,
item_price_cents,
item_published
) values (
_name,
_urlslug,
_description,
_price_cents,
_published
) returning item_uuid into _item_uuid;
return query select * from public.v_item where item_uuid = _item_uuid;
end; $function$;
create or replace function public.add_image_to_item(_item_uuid uuid, _large_file bytea, _thumb_file bytea, _mime_type varchar, _uploader_uuid uuid)
returns setof public.v_item
language plpgsql
as $function$
declare
_image_uuid uuid;
begin
insert into "image" (
image_item_uuid,
image_large_file,
image_thumb_file,
image_mime_type,
image_uploader_uuid
) values (
_item_uuid,
_large_file,
_thumb_file,
_mime_type,
_uploader_uuid
) returning image_uuid into _image_uuid;
return query select * from public.v_item where item_uuid = _item_uuid;
end; $function$;
create or replace function public.set_featured_image(_item_uuid uuid, _image_uuid uuid)
returns setof public.v_item
language plpgsql
as $function$
begin
-- Un-feature all other images
update "image" set
image_featured = false
where image_item_uuid = _item_uuid;
update "image" set
image_featured = true
where image_uuid = _image_uuid;
return query select * from public.v_item where item_uuid = _item_uuid;
end; $function$;
create or replace function public.get_image_large(_image_uuid uuid)
returns table (image_uuid uuid, image_mime_type varchar, image_file bytea)
language plpgsql
as $function$
begin
return query select
image_uuid,
image_mime_type,
image_large_file as image_file
from "image"
where "image".image_uuid = _image_uuid;
end; $function$;
create or replace function public.get_image_thumb(_image_uuid uuid)
returns table (image_uuid uuid, image_mime_type varchar, image_file bytea)
language plpgsql
as $function$
begin
return query select
image_uuid,
image_mime_type,
image_large_thumb as image_file
from "image"
where "image".image_uuid = _image_uuid;
end; $function$;

@ -1,4 +1,5 @@
const path = require('path')
const withImages = require('next-images')
class CustomResolver {
constructor(source, target){
@ -29,10 +30,10 @@ class CustomResolver {
}
}
module.exports = {
module.exports = withImages({
webpack: (config) => {
config.resolve.plugins.push(new CustomResolver())
return config
}
}
})

409
package-lock.json generated

@ -1272,6 +1272,11 @@
"picomatch": "^2.0.4"
}
},
"append-field": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
"integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
},
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
@ -1683,6 +1688,11 @@
}
}
},
"base64-async": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/base64-async/-/base64-async-2.1.3.tgz",
"integrity": "sha1-5zHGs86wPRfc+mxB+zcHctSI4TE="
},
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
@ -1716,6 +1726,26 @@
"file-uri-to-path": "1.0.0"
}
},
"bl": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
"integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
"requires": {
"readable-stream": "^3.0.1"
},
"dependencies": {
"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"
}
}
}
},
"bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@ -1885,6 +1915,38 @@
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
"integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug="
},
"busboy": {
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
"requires": {
"dicer": "0.2.5",
"readable-stream": "1.1.x"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
}
}
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@ -2120,6 +2182,15 @@
"object-visit": "^1.0.0"
}
},
"color": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
"integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
"requires": {
"color-convert": "^1.9.1",
"color-string": "^1.5.2"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -2133,6 +2204,15 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
"requires": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
},
"colors": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
@ -2561,6 +2641,14 @@
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
},
"decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"requires": {
"mimic-response": "^2.0.0"
}
},
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@ -2666,6 +2754,38 @@
"resolved": "https://registry.npmjs.org/devalue/-/devalue-2.0.1.tgz",
"integrity": "sha512-I2TiqT5iWBEyB8GRfTDP0hiLZ0YeDJZ+upDxjBfOC2lebO5LezQMv7QvIUTzdb64jQyAKLf1AHADtGN+jw6v8Q=="
},
"dicer": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
"requires": {
"readable-stream": "1.1.x",
"streamsearch": "0.1.2"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
}
}
},
"diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
@ -2924,6 +3044,11 @@
}
}
},
"expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
},
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
@ -3273,6 +3398,11 @@
"readable-stream": "^2.0.0"
}
},
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
@ -3338,6 +3468,11 @@
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
"github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@ -4246,6 +4381,11 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
},
"mimic-response": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
},
"mini-css-extract-plugin": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz",
@ -4378,6 +4518,21 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"multer": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz",
"integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==",
"requires": {
"append-field": "^1.0.0",
"busboy": "^0.2.11",
"concat-stream": "^1.5.2",
"mkdirp": "^0.5.1",
"object-assign": "^4.1.1",
"on-finished": "^2.3.0",
"type-is": "^1.6.4",
"xtend": "^4.0.0"
}
},
"nan": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
@ -4401,6 +4556,11 @@
"to-regex": "^3.0.1"
}
},
"napi-build-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz",
"integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA=="
},
"needle": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.3.2.tgz",
@ -4536,11 +4696,62 @@
}
}
},
"next-images": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/next-images/-/next-images-1.3.1.tgz",
"integrity": "sha512-LZ7TiRFw/pLoNeaWqE8SjhyXYyyO1h9ofVxRe/pcLzLH61xB5LAWCU2kZHFPcq0W4kPtShQ4wDpXIahnTIR3Pw==",
"requires": {
"file-loader": "^5.0.2",
"url-loader": "^3.0.0"
},
"dependencies": {
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
},
"file-loader": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.1.0.tgz",
"integrity": "sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==",
"requires": {
"loader-utils": "^1.4.0",
"schema-utils": "^2.5.0"
}
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"requires": {
"minimist": "^1.2.0"
}
},
"loader-utils": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
"integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^1.0.1"
}
}
}
},
"next-tick": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
},
"node-abi": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.15.0.tgz",
"integrity": "sha512-FeLpTS0F39U7hHZU1srAK4Vx+5AHNVOTP+hxBNQknR/54laTHSFIJkDWDqiquY1LeLUgTfPN7sLPhMubx0PLAg==",
"requires": {
"semver": "^5.4.1"
}
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
@ -4623,6 +4834,11 @@
}
}
},
"noop-logger": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
},
"nopt": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
@ -5658,6 +5874,28 @@
"xtend": "^4.0.0"
}
},
"prebuild-install": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
"integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
"requires": {
"detect-libc": "^1.0.3",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"napi-build-utils": "^1.0.1",
"node-abi": "^2.7.0",
"noop-logger": "^0.1.1",
"npmlog": "^4.0.1",
"pump": "^3.0.0",
"rc": "^1.2.7",
"simple-get": "^3.0.3",
"tar-fs": "^2.0.0",
"tunnel-agent": "^0.6.0",
"which-pm-runs": "^1.0.0"
}
},
"prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
@ -6304,6 +6542,77 @@
"kind-of": "^6.0.2"
}
},
"sharp": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.24.1.tgz",
"integrity": "sha512-1Lph6o7D6bU8WrcbG/kT7cVzi2UBi2xrrBfS/WUaD+ZcGd4MZ7+LbtFoGwbMVJH95d5aziBGyExYF4Urm2pjOQ==",
"requires": {
"color": "^3.1.2",
"detect-libc": "^1.0.3",
"nan": "^2.14.0",
"npmlog": "^4.1.2",
"prebuild-install": "^5.3.3",
"semver": "^7.1.3",
"simple-get": "^3.1.0",
"tar": "^6.0.1",
"tunnel-agent": "^0.6.0"
},
"dependencies": {
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"requires": {
"minipass": "^3.0.0"
}
},
"minipass": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
"integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
"requires": {
"yallist": "^4.0.0"
}
},
"minizlib": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
"integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
}
},
"mkdirp": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz",
"integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g=="
},
"semver": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz",
"integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA=="
},
"tar": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.1.tgz",
"integrity": "sha512-bKhKrrz2FJJj5s7wynxy/fyxpE0CmCjmOQ1KV4KkgXFWOgoIT/NbTMnB1n+LFNrNk0SSBVGGxcK5AGsyC+pW5Q==",
"requires": {
"chownr": "^1.1.3",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.0",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -6327,6 +6636,36 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
},
"simple-concat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
},
"simple-get": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
"requires": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
"requires": {
"is-arrayish": "^0.3.1"
},
"dependencies": {
"is-arrayish": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
}
}
},
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@ -6597,6 +6936,11 @@
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
},
"streamsearch": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@ -6728,6 +7072,41 @@
"yallist": "^3.0.3"
}
},
"tar-fs": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
"integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
"requires": {
"chownr": "^1.1.1",
"mkdirp": "^0.5.1",
"pump": "^3.0.0",
"tar-stream": "^2.0.0"
}
},
"tar-stream": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz",
"integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==",
"requires": {
"bl": "^3.0.0",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"dependencies": {
"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"
}
}
}
},
"terser": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz",
@ -6952,6 +7331,14 @@
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"type": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
@ -7115,6 +7502,23 @@
}
}
},
"url-loader": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-loader/-/url-loader-3.0.0.tgz",
"integrity": "sha512-a84JJbIA5xTFTWyjjcPdnsu+41o/SNE8SpXMdUvXs6Q+LuhCD9E2+0VCiuDWqgo3GGXVlFHzArDmBpj9PgWn4A==",
"requires": {
"loader-utils": "^1.2.3",
"mime": "^2.4.4",
"schema-utils": "^2.5.0"
},
"dependencies": {
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
}
}
},
"url-polyfill": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.7.tgz",
@ -7963,6 +8367,11 @@
"isexe": "^2.0.0"
}
},
"which-pm-runs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
},
"wide-align": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",

@ -13,6 +13,7 @@
"devDependencies": {},
"dependencies": {
"axios": "^0.19.2",
"base64-async": "^2.1.3",
"bcrypt": "^3.0.8",
"body-parser": "^1.19.0",
"cross-env": "^7.0.0",
@ -23,9 +24,12 @@
"express-validator": "^6.4.0",
"join-js": "^1.0.2",
"luxon": "^1.22.0",
"multer": "^1.4.2",
"next": "^9.2.1",
"next-images": "^1.3.1",
"pg": "^7.18.1",
"react": "^16.12.0",
"react-dom": "^16.12.0"
"react-dom": "^16.12.0",
"sharp": "^0.24.1"
}
}

@ -1,8 +1,11 @@
import React from 'react'
import Hero from '~/components/hero'
const Index = () => (
<div>
<>
<Hero/>
<p>Homepage</p>
</div>
</>
)
export default Index

Loading…
Cancel
Save