Compare commits
5 Commits
711462ff59
...
a6a819503f
Author | SHA1 | Date |
---|---|---|
Robbie Antenesse | a6a819503f | |
Robbie Antenesse | 8283c1987a | |
Robbie Antenesse | 63c7d3676d | |
Robbie Antenesse | 707c22dac7 | |
Robbie Antenesse | fe2c9f8b68 |
|
@ -6,7 +6,8 @@ import { modal } from '../partials/modal';
|
|||
|
||||
export const resultDetails = (searchController, result, emit = () => {}) => {
|
||||
const { __ } = searchController.i18n;
|
||||
const modalId = `result_${result.uri}`;
|
||||
const source = result.sources[0];
|
||||
const modalId = `result_${source.uri}`;
|
||||
|
||||
const hasReviews = typeof result.averageRating !== 'undefined' && typeof result.numberOfReviews !== 'undefined';
|
||||
|
||||
|
@ -27,37 +28,41 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
|
||||
const tabNames = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty'];
|
||||
|
||||
const coversHTMLArray = result.covers.map((cover, index, allCovers) => {
|
||||
return html`<div>
|
||||
<img src=${cover.url} alt="${cover.sourceId.replace(':', ' ').toUpperCase()}, Published: ${cover.publishDate}">
|
||||
${typeof allCovers[index - 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index - 1].sourceId}" style="margin-right:8px;">
|
||||
${'<'}
|
||||
</label>`
|
||||
}
|
||||
${typeof allCovers[index + 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index + 1].sourceId}">
|
||||
${'>'}
|
||||
</label>`
|
||||
}
|
||||
</div>`;
|
||||
});
|
||||
|
||||
const modalContent = html`<article class="flex">
|
||||
<div class="sixth-700" style="text-align:center;">
|
||||
<h4>${__('search.covers')}</h4>
|
||||
${typeof result.covers === 'undefined'
|
||||
? html`<span style="font-size:3em;"><i class="icon-loading animate-spin"></i></span>`
|
||||
: html`<div class="tabs ${typeof tabNames[result.covers.length - 1] !== 'undefined' ? tabNames[result.covers.length - 1] : null}">
|
||||
: html`<div class="tabs ${typeof tabNames[result.covers.length - 1] !== 'undefined' ? tabNames[result.covers.length - 1] : tabNames[19]}">
|
||||
${result.covers.map((cover, index) => {
|
||||
return [
|
||||
html`<input id="cover_${cover.uri}" type="radio" name="${modalId}_covers" ${index === 0 ? 'checked' : null} />`,
|
||||
// html`<label class="small pseudo button toggle" for="cover_${cover.uri}">•</label>`,
|
||||
html`<input id="cover_${cover.sourceId}" type="radio" name="${modalId}_covers" ${index === 0 ? 'checked' : null} />`,
|
||||
// html`<label class="small pseudo button toggle" for="cover_${cover.sourceId}">•</label>`,
|
||||
];
|
||||
})}
|
||||
<div class="row">
|
||||
${result.covers.map((cover, index, allCovers) => {
|
||||
return html`<div>
|
||||
<img src=${cover.url} alt="${cover.uri.replace(':', ' ').toUpperCase()}, Published: ${cover.publishDate}">
|
||||
${typeof allCovers[index - 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index - 1].uri}" style="margin-right:8px;">
|
||||
${'<'}
|
||||
</label>`
|
||||
}
|
||||
${typeof allCovers[index + 1] === 'undefined'
|
||||
? null
|
||||
: html`<label class="button" for="cover_${allCovers[index + 1].uri}">
|
||||
${'>'}
|
||||
</label>`
|
||||
}
|
||||
</div>`;
|
||||
})}
|
||||
</div>
|
||||
<div class="row" id="covers_${modalId}">${
|
||||
searchController.openModal === modalId
|
||||
? coversHTMLArray
|
||||
: '' /* Leave the covers column empty until opened to prevent loading too many images */
|
||||
}</div>
|
||||
</div>`
|
||||
}
|
||||
</div>
|
||||
|
@ -72,7 +77,7 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
<h4>Top Reviews</h4>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/book/${result.uri}" class="small button">
|
||||
<a href="/book/${source.uri}" class="small button">
|
||||
<span style="margin-right:8px;"><i class="icon-chat"></i></span>
|
||||
<span>${result.numberOfReviews}</span>
|
||||
<span>${__('search.see_interaction_details')}</span>
|
||||
|
@ -92,27 +97,29 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
|
|||
</p>
|
||||
${!searchController.showShelves ? null : html`<ul>${searchController.shelves.map(shelf => {
|
||||
return html`<li>
|
||||
<button class="pseudo" onclick=${() => searchController.addToShelf({source: 'inventaire', uri: result.uri}, shelf.id)}>
|
||||
<button class="pseudo" onclick=${() => searchController.addToShelf({ id: result.id, ...source }, shelf.id)}>
|
||||
${shelf.name}
|
||||
</button>
|
||||
</li>`;
|
||||
})}</ul>`}
|
||||
<p>
|
||||
<a class="small button" href=${result.link} target="_blank">
|
||||
<a class="small button" href=${source.link} target="_blank">
|
||||
${__('search.see_book_details')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</article>`;
|
||||
|
||||
const onShow = () => {
|
||||
const coversColumn = document.getElementById(`covers_${modalId}`);
|
||||
coversColumn.innerHTML = '';
|
||||
coversHTMLArray.forEach(element => coversColumn.appendChild(element));
|
||||
};
|
||||
|
||||
return modal(modalId, searchController, modalContent, {
|
||||
styles: "width:90%;",
|
||||
buttonHTML, // This should be replaced with buttonHTML containing the ratings and number of reviews etc.
|
||||
headerText: result.name,
|
||||
onShow: () => {
|
||||
if (typeof result.covers === 'undefined') {
|
||||
searchController.getCovers(result.uri).then(() => emit('render'));
|
||||
}
|
||||
},
|
||||
onShow,
|
||||
});
|
||||
}
|
14
package.json
14
package.json
|
@ -20,8 +20,8 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"choo-devtools": "^3.0.3",
|
||||
"concurrently": "^5.1.0",
|
||||
"faker": "^4.1.0",
|
||||
"concurrently": "^5.3.0",
|
||||
"faker": "^5.0.0",
|
||||
"onchange": "^7.0.2",
|
||||
"rimraf": "^3.0.1",
|
||||
"sequelize-erd": "https://github.com/Alamantus/sequelize-erd.git"
|
||||
|
@ -31,13 +31,13 @@
|
|||
"babel-polyfill": "^6.26.0",
|
||||
"choo": "^7.1.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"fastify": "^3.1.1",
|
||||
"fastify": "^3.2.1",
|
||||
"fastify-caching": "^6.0.1",
|
||||
"fastify-compress": "^3.2.2",
|
||||
"fastify-compress": "^3.3.0",
|
||||
"fastify-cookie": "^4.0.2",
|
||||
"fastify-helmet": "^5.0.0",
|
||||
"fastify-helmet": "^5.0.1",
|
||||
"fastify-jwt": "^2.1.3",
|
||||
"fastify-plugin": "^2.1.1",
|
||||
"fastify-plugin": "^2.3.2",
|
||||
"fastify-static": "^3.2.0",
|
||||
"make-promises-safe": "^5.1.0",
|
||||
"marked": "^1.1.1",
|
||||
|
@ -46,7 +46,7 @@
|
|||
"nodemailer": "^6.4.11",
|
||||
"parcel-bundler": "^1.12.4",
|
||||
"parcel-plugin-goodie-bag": "^2.0.0",
|
||||
"pg": "^8.3.0",
|
||||
"pg": "^8.3.2",
|
||||
"pg-hstore": "^2.3.3",
|
||||
"picnic": "^6.5.2",
|
||||
"sass": "^1.26.10",
|
||||
|
|
|
@ -15,6 +15,7 @@ class Inventaire {
|
|||
|
||||
static handleQuickEntity(entityObject) {
|
||||
return {
|
||||
id: null,
|
||||
name: (
|
||||
typeof entityObject.label !== 'undefined'
|
||||
? entityObject.label
|
||||
|
@ -25,22 +26,26 @@ class Inventaire {
|
|||
? entityObject.description
|
||||
: null
|
||||
),
|
||||
source: 'inventaire',
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
sources: [
|
||||
{
|
||||
source: 'inventaire',
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
},
|
||||
],
|
||||
covers: (
|
||||
typeof entityObject.image !== 'undefined'
|
||||
? entityObject.image.map(imageId => {
|
||||
return {
|
||||
uri: imageId.toString(),
|
||||
sourceId: imageId.toString(),
|
||||
url: `${Inventaire.url}/img/entities/${imageId}`,
|
||||
}
|
||||
})
|
||||
|
@ -72,17 +77,21 @@ class Inventaire {
|
|||
: null
|
||||
)
|
||||
),
|
||||
source: 'inventaire',
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
sources: [
|
||||
{
|
||||
source: 'inventaire',
|
||||
uri: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? entityObject.uri
|
||||
: null
|
||||
),
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${Inventaire.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -105,11 +114,11 @@ class Inventaire {
|
|||
}
|
||||
});
|
||||
|
||||
const bookData = await json;
|
||||
let bookData = await json;
|
||||
|
||||
if (typeof bookData.entities !== 'undefined' && typeof bookData.entities[uri] !== 'undefined') {
|
||||
const bookData = Inventaire.handleEntity(bookData.entities[uri], this.lang);
|
||||
bookData['covers'] = await this.getCovers(bookData.uri);
|
||||
bookData = Inventaire.handleEntity(bookData.entities[uri], this.lang);
|
||||
bookData['covers'] = await this.getCovers(bookData.sources[0].uri);
|
||||
|
||||
return bookData;
|
||||
}
|
||||
|
@ -126,7 +135,7 @@ class Inventaire {
|
|||
}
|
||||
|
||||
// Note: property `wdt:P629` is a given entity (uri)'s list of editions (ISBNs).
|
||||
const editionsRequest = fetch(`${Inventaire.url}/api/entities?action=reverse-claims&uri=${encodeURIComponent(uri)}&property=wdt:P629`)
|
||||
const editionsRequest = fetch(`${Inventaire.url}/api/entities?action=reverse-claims&value=${encodeURIComponent(uri)}&property=wdt:P629`)
|
||||
editionsRequest.catch(exception => {
|
||||
console.error(exception);
|
||||
return {
|
||||
|
@ -180,7 +189,7 @@ class Inventaire {
|
|||
}).map(key => {
|
||||
const entity = responseJSON.entities[key];
|
||||
return {
|
||||
uri: entity.uri,
|
||||
sourceId: entity.uri,
|
||||
url: typeof entity.claims['invp:P2'] !== 'undefined' ? `${Inventaire.url}/img/entities/${entity.claims['invp:P2'][0]}` : null,
|
||||
publishDate: typeof entity.claims['wdt:P577'] !== 'undefined' ? entity.claims['wdt:P577'][0] : null,
|
||||
}
|
||||
|
|
|
@ -93,27 +93,6 @@ class BooksController {
|
|||
),
|
||||
};
|
||||
}
|
||||
|
||||
async createBookReference (bookReferencesModel, source, uri) {
|
||||
const inventaire = new Inventaire(this.language);
|
||||
const bookData = await inventaire.getBookData(uri);
|
||||
return await bookReferencesModel.create({
|
||||
values: {
|
||||
name: bookData.name,
|
||||
description: bookData.description,
|
||||
sources: {
|
||||
[source]: uri,
|
||||
},
|
||||
covers: bookData.covers.map(cover => {
|
||||
return {
|
||||
sourceId: uri,
|
||||
url: cover.url,
|
||||
};
|
||||
}),
|
||||
locale: this.language,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BooksController;
|
|
@ -7,12 +7,14 @@ class BookReferenceController {
|
|||
this.lang = language;
|
||||
}
|
||||
|
||||
async createOrUpdateReference(source, sourceId) {
|
||||
async createOrUpdateReference(source, sourceId, skipSearchBySourceCodes = false) {
|
||||
const searchController = new SearchController(this.models);
|
||||
const existingReference = searchController.searchReferencesBySourceCode(source, sourceId);
|
||||
if (!skipSearchBySourceCodes) {
|
||||
const existingReferences = await searchController.searchReferencesBySourceCodes(source, [sourceId]);
|
||||
|
||||
if (existingReference.id !== null) {
|
||||
return existingReference;
|
||||
if (existingReferences.length > 0) {
|
||||
return existingReferences[0];
|
||||
}
|
||||
}
|
||||
|
||||
let dataClass;
|
||||
|
@ -28,15 +30,15 @@ class BookReferenceController {
|
|||
}
|
||||
|
||||
// Get formatted book data from source
|
||||
const bookData = dataClass.getBookData(sourceId);
|
||||
const bookData = await dataClass.getBookData(sourceId);
|
||||
|
||||
if (typeof bookData.uri !== 'undefined') {
|
||||
if (typeof bookData.sources[0].uri !== 'undefined') {
|
||||
// Check for references by exact name and author from source
|
||||
const matchingReference = await searchController.searchReferencesForExactMatch(bookData.name, bookData.description);
|
||||
const matchingReferences = await searchController.searchReferencesForExactMatch(bookData.name, bookData.description);
|
||||
|
||||
if (matchingReference.id !== null) {
|
||||
if (matchingReferences.length > 0) {
|
||||
// If a match is found, update the sources of reference in the database and return it.
|
||||
return await this.addSourceToReference(matchingReference, source, sourceId);
|
||||
return await this.addSourceToReference(matchingReferences[0], source, sourceId);
|
||||
}
|
||||
|
||||
return await this.createReference(bookData, source, sourceId);
|
||||
|
@ -57,12 +59,12 @@ class BookReferenceController {
|
|||
covers: bookData.covers,
|
||||
locale: this.lang,
|
||||
});
|
||||
newReference.totalInteractions = 0;
|
||||
newReference.numReviews = 0;
|
||||
newReference.averageRating = null;
|
||||
newReference.Interactions = [];
|
||||
newReference.Reviews = [];
|
||||
newReference.Ratings = [];
|
||||
// newReference.totalInteractions = 0;
|
||||
// newReference.numReviews = 0;
|
||||
// newReference.averageRating = null;
|
||||
// newReference.Interactions = [];
|
||||
// newReference.Reviews = [];
|
||||
// newReference.Ratings = [];
|
||||
return newReference;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,14 @@ function searchInventaire(searchTerm, language) {
|
|||
message: 'An error occurred when trying read the response from Inventaire as JSON.',
|
||||
}
|
||||
});
|
||||
return json.then(responseJSON => responseJSON.results.map(work => Inventaire.handleEntity(work, language)));
|
||||
return json.then(responseJSON => {
|
||||
return responseJSON.results.map(async work => {
|
||||
const inventaire = new Inventaire(langauge);
|
||||
const bookData = Inventaire.handleEntity(work, language);
|
||||
bookData['covers'] = await inventaire.getCovers(bookData.sources[0].uri);
|
||||
return bookData;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ const { Op, fn, col } = require('sequelize');
|
|||
|
||||
const BooksController = require('../bookData');
|
||||
const { quickSearchInventaire } = require('./Inventaire');
|
||||
const Inventaire = require('../bookData/Inventaire');
|
||||
|
||||
const defaultSearchOptions = {
|
||||
searchBy: 'name', // A column name in the BookReference model, mainly 'name' or 'description'
|
||||
|
@ -57,6 +58,30 @@ class SearchController {
|
|||
};
|
||||
}
|
||||
|
||||
static formatReferenceSources(reference) {
|
||||
const referenceSources = Object.keys(reference.sources);
|
||||
const reformattedSources = referenceSources.map(source => {
|
||||
const uri = reference.sources[source];
|
||||
let link;
|
||||
switch (source) {
|
||||
default:
|
||||
case 'inventaire': {
|
||||
link = `${Inventaire.url}/entity/${uri}`
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
source,
|
||||
uri,
|
||||
link,
|
||||
}
|
||||
});
|
||||
|
||||
reference.sources = reformattedSources;
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
async search(searchTerm, options = defaultSearchOptions) {
|
||||
const searchBy = options.searchBy.replace('title', 'name').replace('author', 'description');
|
||||
const { source, language } = options;
|
||||
|
@ -77,22 +102,23 @@ class SearchController {
|
|||
|
||||
// Add any search results that match refs with the same URI and delete from results array
|
||||
const urisToCheck = searchResults.filter(
|
||||
result => !bookReferences.some(ref => result.uri === ref.sources[source])
|
||||
).map(result => result.uri);
|
||||
result => !bookReferences.some(ref => result.sources[0].uri === ref.sources[source])
|
||||
).map(result => result.sources[0].uri);
|
||||
|
||||
let extraReferences = [];
|
||||
if (urisToCheck.length > 0) {
|
||||
// Need to figure this out
|
||||
extraReferences = await this.searchReferencesBySourceCodes(source, urisToCheck);
|
||||
}
|
||||
searchResults = searchResults.filter( // Only show the rest of the search results
|
||||
result => !extraReferences.some(
|
||||
ref => result.sources[0].uri === ref.sources[source]
|
||||
)
|
||||
);
|
||||
return [
|
||||
...bookReferences,
|
||||
...extraReferences,
|
||||
...searchResults.filter( // Only show the rest of the search results
|
||||
result => !extraReferences.some(
|
||||
ref => result.uri === ref.sources[source]
|
||||
)
|
||||
),
|
||||
...bookReferences.map(match => SearchController.formatReferenceSources(match)),
|
||||
...extraReferences.map(match => SearchController.formatReferenceSources(match)),
|
||||
...searchResults,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -142,15 +168,11 @@ class SearchController {
|
|||
);
|
||||
}
|
||||
|
||||
async searchReferencesBySourceCode(source, sourceId) {
|
||||
const sourceJSONKey = `"${source}"`; // Enable searching withing JSON column.
|
||||
return await this.models.BookReference.findOne({
|
||||
async searchReferencesForExactMatch(name, description) {
|
||||
return await this.models.BookReference.findAll({
|
||||
where: {
|
||||
sources: {
|
||||
[sourceJSONKey]: { // Where the object key is the source
|
||||
[Op.eq]: sourceId,
|
||||
},
|
||||
},
|
||||
name,
|
||||
description,
|
||||
},
|
||||
...this.bookReferenceSearchAttributes,
|
||||
}).then( // Empty results give 1 empty model in an array, so filter those out
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const fetch = require('node-fetch');
|
||||
const BookReferenceController = require('./bookReference');
|
||||
|
||||
class ShelfController {
|
||||
constructor (sequelizeModels, language) { // Language needs to be passed with every request involving books.
|
||||
|
|
|
@ -15,7 +15,21 @@ const fastify = require('fastify')({
|
|||
logger: process.env.NODE_ENV !== 'production',
|
||||
});
|
||||
fastify.decorate('siteConfig', siteConfig); // Insert siteConfig into global fastify instance
|
||||
fastify.register(require('fastify-helmet')); // Add security stuff
|
||||
fastify.register(require('fastify-helmet'), { // Add security stuff
|
||||
contentSecurityPolicy: { // Modify Content Security Policy headers to allow content from specific domains
|
||||
directives: {
|
||||
'default-src': ["'self'"], // Default value
|
||||
'base-uri': ["'self'"], // Default value
|
||||
'block-all-mixed-content': [], // Default value
|
||||
'frame-ancestors': ["'self'"], // Default value
|
||||
'style-src': ["'self'", "https: 'unsafe-inline'"], // Default value
|
||||
'upgrade-insecure-requests': [], // Default value
|
||||
'object-src': ["'none'"], // Default value
|
||||
'script-src': ["'self'", 'polyfill.io', "https: 'unsafe-inline'"], // Allow loading scripts inline (required for Choo) and from polyfill.io
|
||||
'img-src': ["'self'", siteConfig.inventaireDomain, 'openlibrary.org', 'covers.openlibrary.org', "data:"], // Allow images from Inventaire, Open Library, and raw `data:` hashes
|
||||
}
|
||||
}
|
||||
});
|
||||
fastify.register(require('fastify-compress')); // Compress output data for smaller packet delivery
|
||||
fastify.register(require('fastify-static'), { // Enable delivering static content efficiently
|
||||
root: path.resolve(__dirname, '../public'), // all static content will be delivered from the public/ folder
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const BooksController = require('../controllers/bookData');
|
||||
const SearchController = require('../controllers/search');
|
||||
const BookReferenceController = require('../controllers/bookReference');
|
||||
|
||||
async function routes(fastify, options) {
|
||||
fastify.get('/api/books', async (request, reply) => {
|
||||
|
@ -39,9 +40,8 @@ async function routes(fastify, options) {
|
|||
return existingBookReferences[0].id;
|
||||
}
|
||||
|
||||
const books = new BooksController(request.body.source, request.body.uri, request.language);
|
||||
const newBookReference = await books.createBookReference(request.body.source, request.body.uri);
|
||||
console.log('created new bookreference', newBookReference);
|
||||
const bookReference = new BookReferenceController(fastify.models, request.language);
|
||||
const newBookReference = await bookReference.createOrUpdateReference(request.body.source, request.body.uri, true);
|
||||
return newBookReference.id;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -188,10 +188,11 @@ async function routes(fastify, options) {
|
|||
});
|
||||
}
|
||||
|
||||
const shelf = await request.user.getShelf({
|
||||
const shelf = (await request.user.getShelves({
|
||||
where: { id: request.body.shelfId },
|
||||
include: [ fastify.models.ShelfItem ],
|
||||
});
|
||||
limit: 1,
|
||||
}))[0];
|
||||
|
||||
if (!ShelfController.userOwnsShelf(request.user, shelf)) {
|
||||
return reply.code(403).send({
|
||||
|
|
145
yarn.lock
145
yarn.lock
|
@ -1026,7 +1026,17 @@ acorn@^7.0.0, acorn@^7.1.1:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c"
|
||||
integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==
|
||||
|
||||
ajv@^6.11.0, ajv@^6.12.2, ajv@^6.12.3:
|
||||
ajv@^6.11.0, ajv@^6.12.2:
|
||||
version "6.12.4"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234"
|
||||
integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@^6.12.3:
|
||||
version "6.12.3"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706"
|
||||
integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==
|
||||
|
@ -1934,10 +1944,10 @@ concat-stream@~1.6.0:
|
|||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
concurrently@^5.1.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-5.2.0.tgz#ead55121d08a0fc817085584c123cedec2e08975"
|
||||
integrity sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==
|
||||
concurrently@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-5.3.0.tgz#7500de6410d043c912b2da27de3202cb489b1e7b"
|
||||
integrity sha512-8MhqOB6PWlBfA2vJ8a0bSFKATOdWlHiQlk11IfmQBPaHVP8oP2gsh2MObE6UR3hqDHqvaIvLTyceNW6obVuFHQ==
|
||||
dependencies:
|
||||
chalk "^2.4.2"
|
||||
date-fns "^2.0.1"
|
||||
|
@ -2819,10 +2829,10 @@ extsprintf@^1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
faker@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f"
|
||||
integrity sha1-HkW7vsxndLPBlfrSg1EJxtdIzD8=
|
||||
faker@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/faker/-/faker-5.0.0.tgz#ceaf8120e37994007d6fb0e73479bef0406bfe74"
|
||||
integrity sha512-wBY77PYhJOqq2cji+l8Gc8HWW7rKlwJvJgV/fbanGlm92/MImBGX51VLQN/DbDvzexmt+EFjQ4SeytCb45AJ1g==
|
||||
|
||||
falafel@^2.1.0:
|
||||
version "2.2.4"
|
||||
|
@ -2834,7 +2844,7 @@ falafel@^2.1.0:
|
|||
isarray "^2.0.1"
|
||||
object-keys "^1.0.6"
|
||||
|
||||
fast-decode-uri-component@^1.0.0:
|
||||
fast-decode-uri-component@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543"
|
||||
integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==
|
||||
|
@ -2901,13 +2911,13 @@ fastify-caching@^6.0.1:
|
|||
fastify-plugin "^2.0.0"
|
||||
uid-safe "^2.1.5"
|
||||
|
||||
fastify-compress@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/fastify-compress/-/fastify-compress-3.2.2.tgz#5d4cd0b0756f3664d4635f389b26b098fe2ecbd8"
|
||||
integrity sha512-i4HSMIAcWnHvktlC+HI24luGHaO6mTJTDiuzQU6lTxV2QdEXmNxVMWxekm3JAaNBzS+hBuON3fvyWT58AN3MHw==
|
||||
fastify-compress@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/fastify-compress/-/fastify-compress-3.3.0.tgz#83c4965048d77e9469128de25f77064b38bad06e"
|
||||
integrity sha512-g/q7g9JaN14pVe7Op8zwKD/MxyBBXjLkK8Y6UtcwRDwufAlqLO1jZ/srM5JTly5AKnXPnX6ft9Nz/83xYNltrQ==
|
||||
dependencies:
|
||||
encoding-negotiator "^2.0.0"
|
||||
fastify-plugin "^2.0.0"
|
||||
fastify-plugin "^2.2.0"
|
||||
into-stream "^5.1.1"
|
||||
is-deflate "^1.0.0"
|
||||
is-gzip "^2.0.0"
|
||||
|
@ -2930,17 +2940,17 @@ fastify-cookie@^4.0.2:
|
|||
cookie-signature "^1.1.0"
|
||||
fastify-plugin "^2.0.0"
|
||||
|
||||
fastify-error@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fastify-error/-/fastify-error-0.1.0.tgz#7ca9d3708a2b1a74aefed0e5dde1b96d0390f718"
|
||||
integrity sha512-jyCEc3VPEc8/PUwzDQAM2JlXLK2BG6L19mMJzbGij0TfdY1sHF9pCnnAn6Vcoi84TMTBOJynNDQUMUz6cjRmBw==
|
||||
fastify-error@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fastify-error/-/fastify-error-0.2.0.tgz#9a1c28d4f42b6259e7a549671c8e5e2d85660634"
|
||||
integrity sha512-zabxsBatj59ROG0fhP36zNdc5Q1/eYeH9oSF9uvfrurZf8/JKfrJbMcIGrLpLWcf89rS6L91RHWm20A/X85hcA==
|
||||
|
||||
fastify-helmet@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fastify-helmet/-/fastify-helmet-5.0.0.tgz#a8019f009237ca23ccc0aeca72ffc33d8988b781"
|
||||
integrity sha512-kE5qEflGkSu0RRE3WNdt9XMkU2X6zb85jYLW2TKIL7r0p+JJmqaW24xsD248Bn5hfPxDfKSBqCj6MoaLIqYzTw==
|
||||
fastify-helmet@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fastify-helmet/-/fastify-helmet-5.0.1.tgz#1267e1797e4d4022f1be601c4b534849576be624"
|
||||
integrity sha512-e9SVR5n4oRDqn0NCPMjK8AZvEVUsQTittlQ/Pj3IJ0CMNRciOe6NwXiglVpRICU625EStgOqgmWOoWD2nUJNKQ==
|
||||
dependencies:
|
||||
fastify-plugin "^2.0.3"
|
||||
fastify-plugin "^2.1.1"
|
||||
helmet "^4.0.0"
|
||||
|
||||
fastify-jwt@^2.1.3:
|
||||
|
@ -2954,10 +2964,10 @@ fastify-jwt@^2.1.3:
|
|||
jsonwebtoken "^8.3.0"
|
||||
steed "^1.1.3"
|
||||
|
||||
fastify-plugin@^2.0.0, fastify-plugin@^2.0.3, fastify-plugin@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-2.1.1.tgz#1261e3a07c80a9f5a884f3b471e59a5157753232"
|
||||
integrity sha512-U0gBig5qOm6zfq7qrEek3eKGBwn2ipUDvQqB+k5YfkA3/RkU0bhfQPcRxPQqEz2SYQP9pQ2ZgLaL4bxxnCxn+w==
|
||||
fastify-plugin@^2.0.0, fastify-plugin@^2.1.1, fastify-plugin@^2.2.0, fastify-plugin@^2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-2.3.2.tgz#e8a30cae45e1f6b6e02b467eaee866a3459174f1"
|
||||
integrity sha512-oii9LhQmbrEXDyTPDad59kZwSLN++ql9UE6+JWZLyPyibGrgYQPVu/sPJ1qhg68+76gk3MCWBjFX/Nhn/1wTxg==
|
||||
dependencies:
|
||||
semver "^7.3.2"
|
||||
|
||||
|
@ -2971,16 +2981,22 @@ fastify-static@^3.2.0:
|
|||
readable-stream "^3.4.0"
|
||||
send "^0.17.1"
|
||||
|
||||
fastify@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fastify/-/fastify-3.1.1.tgz#0a830f4a929abd7f2b05c08620a609a104300a36"
|
||||
integrity sha512-A7kBZIFAdpE/8MZ9qHpQV9IVPpfX63uWMaPN4p0fetax10C2p56iV/VEB5hOgtlXzayGn+4tf+tNHcZsfrjlnA==
|
||||
fastify-warning@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fastify-warning/-/fastify-warning-0.2.0.tgz#e717776026a4493dc9a2befa44db6d17f618008f"
|
||||
integrity sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw==
|
||||
|
||||
fastify@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/fastify/-/fastify-3.2.1.tgz#119250e50a3f49e1a8036a4abaebef9823b0db1c"
|
||||
integrity sha512-2y2qZzS4bqD1cwaX72ot8DjjUFqqxn/SbgKN1xe4vH2HVy7c6u++6IY8HzBRWJv38p3WiBogLWAObxaISxUlJg==
|
||||
dependencies:
|
||||
abstract-logging "^2.0.0"
|
||||
ajv "^6.12.2"
|
||||
avvio "^7.1.2"
|
||||
fast-json-stringify "^2.2.1"
|
||||
fastify-error "^0.1.0"
|
||||
fastify-error "^0.2.0"
|
||||
fastify-warning "^0.2.0"
|
||||
find-my-way "^3.0.0"
|
||||
flatstr "^1.0.12"
|
||||
light-my-request "^4.0.0"
|
||||
|
@ -3047,11 +3063,11 @@ fill-range@^7.0.1:
|
|||
to-regex-range "^5.0.1"
|
||||
|
||||
find-my-way@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-3.0.1.tgz#3df89fd2b145446c09291e1fd0bb67af1177deda"
|
||||
integrity sha512-tHUHIRGTcfl3phGKLZeD2Xkb+I0QZr4xduSwCJG5Ke11pdJTGuMDtAyAiJzUdWBZJgHA0H42Pb0WF3H321KbRA==
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-3.0.4.tgz#a485973d1a3fdafd989ac9f12fd2d88e83cda268"
|
||||
integrity sha512-Trl/mNAVvTgCpo9ox6yixkwiZUvecKYUQZoAuMCBACsgGqv+FbWe+jE5sBA5+U8LIWrJk/cw8zPV53GPrjTnsw==
|
||||
dependencies:
|
||||
fast-decode-uri-component "^1.0.0"
|
||||
fast-decode-uri-component "^1.0.1"
|
||||
safe-regex2 "^2.0.0"
|
||||
semver-store "^0.3.0"
|
||||
|
||||
|
@ -3375,9 +3391,9 @@ hash.js@^1.0.0, hash.js@^1.0.3:
|
|||
minimalistic-assert "^1.0.1"
|
||||
|
||||
helmet@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.0.0.tgz#34c187894ed001834f997c688f2b2df19846b193"
|
||||
integrity sha512-HyoRKKHhWhO6+EBfgRLkuZR4/+NXc1nJB7x0bWwW89i9eoPciK0qUqyZNOA/zowpgrW9C4+J5toqMkZrpBOlkg==
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/helmet/-/helmet-4.1.0.tgz#6f3a34e8f18502d6e52518428b23aa4ddaf84b38"
|
||||
integrity sha512-KWy75fYN8hOG2Rhl8e5B3WhOzb0by1boQum85TiddIE9iu6gV+TXbUjVC17wfej0o/ZUpqB9kxM0NFCZRMzf+Q==
|
||||
|
||||
hex-color-regex@^1.1.0:
|
||||
version "1.1.0"
|
||||
|
@ -4087,9 +4103,9 @@ levn@~0.3.0:
|
|||
type-check "~0.3.2"
|
||||
|
||||
light-my-request@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-4.0.1.tgz#7e18f2c3f8535123c329b1ae78a5d6750424a096"
|
||||
integrity sha512-kGRfzvSS9P/zEsnu34pUisOz2FAPqkHFJfdezW6HRzLLlzjY+1LTRRuh2d82SkW/M/QWNVWnXTZ0HMUydz2fgg==
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-4.0.2.tgz#e80ebbbac512f0f45b9e54cb274b8f121248b924"
|
||||
integrity sha512-VaiiqR2NtdgYL8zQENPr7FBBVKCGioqa06HYnidj/GC+6jibyZrNCrk6FU8fqe9WWQDqwOtt0UCWLGe0GjyjgA==
|
||||
dependencies:
|
||||
ajv "^6.12.2"
|
||||
cookie "^0.4.0"
|
||||
|
@ -4164,11 +4180,16 @@ lodash.uniq@^4.5.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
lodash@^4.15.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4:
|
||||
lodash@^4.15.0, lodash@^4.17.19, lodash@^4.17.4:
|
||||
version "4.17.19"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
|
||||
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
|
||||
|
||||
lodash@^4.17.15:
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
|
||||
log-symbols@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
|
||||
|
@ -5303,10 +5324,10 @@ pg-types@^2.1.0:
|
|||
postgres-date "~1.0.4"
|
||||
postgres-interval "^1.1.0"
|
||||
|
||||
pg@^8.3.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pg/-/pg-8.3.0.tgz#941383300d38eef51ecb88a0188cec441ab64d81"
|
||||
integrity sha512-jQPKWHWxbI09s/Z9aUvoTbvGgoj98AU7FDCcQ7kdejupn/TcNpx56v2gaOTzXkzOajmOEJEdi9eTh9cA2RVAjQ==
|
||||
pg@^8.3.2:
|
||||
version "8.3.2"
|
||||
resolved "https://registry.yarnpkg.com/pg/-/pg-8.3.2.tgz#52766e41302f5b878fe1efa10d4cdd486f6dff50"
|
||||
integrity sha512-hOoRCTriXS+VWwyXHchRjWb9yv3Koq8irlwwXniqhdgK0AbfWvEnybGS2HIUE+UdCSTuYAM4WGPujFpPg9Vcaw==
|
||||
dependencies:
|
||||
buffer-writer "2.0.0"
|
||||
packet-reader "1.0.0"
|
||||
|
@ -5345,21 +5366,21 @@ pify@^3.0.0:
|
|||
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
|
||||
|
||||
pino-std-serializers@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-2.4.2.tgz#cb5e3e58c358b26f88969d7e619ae54bdfcc1ae1"
|
||||
integrity sha512-WaL504dO8eGs+vrK+j4BuQQq6GLKeCCcHaMB2ItygzVURcL1CycwNEUHTD/lHFHs/NL5qAz2UKrjYWXKSf4aMQ==
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-2.5.0.tgz#40ead781c65a0ce7ecd9c1c33f409d31fe712315"
|
||||
integrity sha512-wXqbqSrIhE58TdrxxlfLwU9eDhrzppQDvGhBEr1gYbzzM4KKo3Y63gSjiDXRKLVS2UOXdPNR2v+KnQgNrs+xUg==
|
||||
|
||||
pino@^6.2.1:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/pino/-/pino-6.5.0.tgz#4d3447c0efa75489936c16071bd3abddbaac7e96"
|
||||
integrity sha512-qDIFPZ2h2AMrp+JIWKFUtejiTv5F/+glbizrG9VNvegSCSK6sqnRmerNM9R98/x3RxwKkIf5kJ9q4chXdBdvJA==
|
||||
version "6.5.1"
|
||||
resolved "https://registry.yarnpkg.com/pino/-/pino-6.5.1.tgz#a245adf960a1f3e88e61a339045d509bccbfb7cc"
|
||||
integrity sha512-76+RUhQkqjUD4AtQcSfEzh6vlsjXmoWZK5gg+2d70aCLXZTbo4/5js4I9rN1Xk6z1h2/7pnOFX10G4c2T4qNiA==
|
||||
dependencies:
|
||||
fast-redact "^2.0.0"
|
||||
fast-safe-stringify "^2.0.7"
|
||||
flatstr "^1.0.12"
|
||||
pino-std-serializers "^2.4.2"
|
||||
quick-format-unescaped "^4.0.1"
|
||||
sonic-boom "^1.0.0"
|
||||
sonic-boom "^1.0.2"
|
||||
|
||||
plucker@0.0.0:
|
||||
version "0.0.0"
|
||||
|
@ -5720,9 +5741,9 @@ postgres-bytea@~1.0.0:
|
|||
integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
|
||||
|
||||
postgres-date@~1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.5.tgz#710b27de5f27d550f6e80b5d34f7ba189213c2ee"
|
||||
integrity sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA==
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.6.tgz#4925e8085b30c2ba1a06ac91b9a3473954a2ce2d"
|
||||
integrity sha512-o2a4gxeFcox+CgB3Ig/kNHBP23PiEXHCXx7pcIIsvzoNz4qv+lKTyiSkjOXIMNUl12MO/mOYl2K6wR9X5K6Plg==
|
||||
|
||||
postgres-interval@^1.1.0:
|
||||
version "1.2.0"
|
||||
|
@ -6549,10 +6570,10 @@ snapdragon@^0.8.1:
|
|||
source-map-resolve "^0.5.0"
|
||||
use "^3.1.0"
|
||||
|
||||
sonic-boom@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.0.2.tgz#8769646fac2ecb58bd0ed60562280aa4211598df"
|
||||
integrity sha512-sRMmXu7uFDXoniGvtLHuQk5KWovLWoi6WKASn7rw0ro41mPf0fOolkGp4NE6680CbxvNh26zWNyFQYYWXe33EA==
|
||||
sonic-boom@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.1.0.tgz#538c2de63aaca1b49254a7ed9d16e4931fab6ad3"
|
||||
integrity sha512-JyOf+Xt7GBN4tAic/DD1Bitw6OMgSHAnswhPeOiLpfRoSjPNjEIi73UF3OxHzhSNn9WavxGuCZzprFCGFSNwog==
|
||||
dependencies:
|
||||
atomic-sleep "^1.0.0"
|
||||
flatstr "^1.0.12"
|
||||
|
|
Loading…
Reference in New Issue