mirror of
https://github.com/booklore-app/booklore.git
synced 2026-02-18 00:17:53 +01:00
perf: strip unused fields from book list API response (#2741)
* perf: strip unused fields from book list API response * fix: regenerate package-lock.json to sync with package.json
This commit is contained in:
@@ -70,6 +70,8 @@ public class BookMetadata {
|
||||
private List<BookReview> bookReviews;
|
||||
private Double rating;
|
||||
|
||||
private Boolean allMetadataLocked;
|
||||
|
||||
private Boolean titleLocked;
|
||||
private Boolean subtitleLocked;
|
||||
private Boolean publisherLocked;
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.booklore.service.book;
|
||||
|
||||
import org.booklore.mapper.v2.BookMapperV2;
|
||||
import org.booklore.model.dto.Book;
|
||||
import org.booklore.model.dto.BookMetadata;
|
||||
import org.booklore.model.dto.ComicMetadata;
|
||||
import org.booklore.model.entity.BookEntity;
|
||||
import org.booklore.repository.BookRepository;
|
||||
import org.booklore.service.restriction.ContentRestrictionService;
|
||||
@@ -22,13 +24,13 @@ public class BookQueryService {
|
||||
|
||||
public List<Book> getAllBooks(boolean includeDescription) {
|
||||
List<BookEntity> books = bookRepository.findAllWithMetadata();
|
||||
return mapBooksToDto(books, includeDescription, null);
|
||||
return mapBooksToDto(books, includeDescription, null, !includeDescription);
|
||||
}
|
||||
|
||||
public List<Book> getAllBooksByLibraryIds(Set<Long> libraryIds, boolean includeDescription, Long userId) {
|
||||
List<BookEntity> books = bookRepository.findAllWithMetadataByLibraryIds(libraryIds);
|
||||
books = contentRestrictionService.applyRestrictions(books, userId);
|
||||
return mapBooksToDto(books, includeDescription, userId);
|
||||
return mapBooksToDto(books, includeDescription, userId, !includeDescription);
|
||||
}
|
||||
|
||||
public List<BookEntity> findAllWithMetadataByIds(Set<Long> bookIds) {
|
||||
@@ -43,13 +45,13 @@ public class BookQueryService {
|
||||
bookRepository.saveAll(books);
|
||||
}
|
||||
|
||||
private List<Book> mapBooksToDto(List<BookEntity> books, boolean includeDescription, Long userId) {
|
||||
private List<Book> mapBooksToDto(List<BookEntity> books, boolean includeDescription, Long userId, boolean stripForListView) {
|
||||
return books.stream()
|
||||
.map(book -> mapBookToDto(book, includeDescription, userId))
|
||||
.map(book -> mapBookToDto(book, includeDescription, userId, stripForListView))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Book mapBookToDto(BookEntity bookEntity, boolean includeDescription, Long userId) {
|
||||
private Book mapBookToDto(BookEntity bookEntity, boolean includeDescription, Long userId, boolean stripForListView) {
|
||||
Book dto = bookMapperV2.toDTO(bookEntity);
|
||||
|
||||
if (!includeDescription && dto.getMetadata() != null) {
|
||||
@@ -62,6 +64,175 @@ public class BookQueryService {
|
||||
.collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
if (stripForListView) {
|
||||
stripFieldsForListView(dto);
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private void stripFieldsForListView(Book dto) {
|
||||
dto.setLibraryPath(null);
|
||||
|
||||
BookMetadata m = dto.getMetadata();
|
||||
if (m != null) {
|
||||
// Compute allMetadataLocked before stripping lock flags
|
||||
m.setAllMetadataLocked(computeAllMetadataLocked(m));
|
||||
|
||||
// Strip lock flags
|
||||
m.setTitleLocked(null);
|
||||
m.setSubtitleLocked(null);
|
||||
m.setPublisherLocked(null);
|
||||
m.setPublishedDateLocked(null);
|
||||
m.setDescriptionLocked(null);
|
||||
m.setSeriesNameLocked(null);
|
||||
m.setSeriesNumberLocked(null);
|
||||
m.setSeriesTotalLocked(null);
|
||||
m.setIsbn13Locked(null);
|
||||
m.setIsbn10Locked(null);
|
||||
m.setAsinLocked(null);
|
||||
m.setGoodreadsIdLocked(null);
|
||||
m.setComicvineIdLocked(null);
|
||||
m.setHardcoverIdLocked(null);
|
||||
m.setHardcoverBookIdLocked(null);
|
||||
m.setDoubanIdLocked(null);
|
||||
m.setGoogleIdLocked(null);
|
||||
m.setPageCountLocked(null);
|
||||
m.setLanguageLocked(null);
|
||||
m.setAmazonRatingLocked(null);
|
||||
m.setAmazonReviewCountLocked(null);
|
||||
m.setGoodreadsRatingLocked(null);
|
||||
m.setGoodreadsReviewCountLocked(null);
|
||||
m.setHardcoverRatingLocked(null);
|
||||
m.setHardcoverReviewCountLocked(null);
|
||||
m.setDoubanRatingLocked(null);
|
||||
m.setDoubanReviewCountLocked(null);
|
||||
m.setLubimyczytacIdLocked(null);
|
||||
m.setLubimyczytacRatingLocked(null);
|
||||
m.setRanobedbIdLocked(null);
|
||||
m.setRanobedbRatingLocked(null);
|
||||
m.setAudibleIdLocked(null);
|
||||
m.setAudibleRatingLocked(null);
|
||||
m.setAudibleReviewCountLocked(null);
|
||||
m.setExternalUrlLocked(null);
|
||||
m.setCoverLocked(null);
|
||||
m.setAudiobookCoverLocked(null);
|
||||
m.setAuthorsLocked(null);
|
||||
m.setCategoriesLocked(null);
|
||||
m.setMoodsLocked(null);
|
||||
m.setTagsLocked(null);
|
||||
m.setReviewsLocked(null);
|
||||
m.setNarratorLocked(null);
|
||||
m.setAbridgedLocked(null);
|
||||
m.setAgeRatingLocked(null);
|
||||
m.setContentRatingLocked(null);
|
||||
|
||||
// Strip external IDs
|
||||
m.setAsin(null);
|
||||
m.setGoodreadsId(null);
|
||||
m.setComicvineId(null);
|
||||
m.setHardcoverId(null);
|
||||
m.setHardcoverBookId(null);
|
||||
m.setGoogleId(null);
|
||||
m.setLubimyczytacId(null);
|
||||
m.setRanobedbId(null);
|
||||
m.setAudibleId(null);
|
||||
m.setDoubanId(null);
|
||||
|
||||
// Strip unused detail fields
|
||||
m.setSubtitle(null);
|
||||
m.setSeriesTotal(null);
|
||||
m.setAbridged(null);
|
||||
m.setExternalUrl(null);
|
||||
m.setThumbnailUrl(null);
|
||||
m.setProvider(null);
|
||||
m.setAudiobookMetadata(null);
|
||||
m.setBookReviews(null);
|
||||
|
||||
// Strip unused ratings
|
||||
m.setDoubanRating(null);
|
||||
m.setDoubanReviewCount(null);
|
||||
m.setAudibleRating(null);
|
||||
m.setAudibleReviewCount(null);
|
||||
m.setLubimyczytacRating(null);
|
||||
|
||||
// Strip ComicMetadata fields
|
||||
ComicMetadata cm = m.getComicMetadata();
|
||||
if (cm != null) {
|
||||
// Strip comic lock flags
|
||||
cm.setIssueNumberLocked(null);
|
||||
cm.setVolumeNameLocked(null);
|
||||
cm.setVolumeNumberLocked(null);
|
||||
cm.setStoryArcLocked(null);
|
||||
cm.setStoryArcNumberLocked(null);
|
||||
cm.setAlternateSeriesLocked(null);
|
||||
cm.setAlternateIssueLocked(null);
|
||||
cm.setImprintLocked(null);
|
||||
cm.setFormatLocked(null);
|
||||
cm.setBlackAndWhiteLocked(null);
|
||||
cm.setMangaLocked(null);
|
||||
cm.setReadingDirectionLocked(null);
|
||||
cm.setWebLinkLocked(null);
|
||||
cm.setNotesLocked(null);
|
||||
cm.setCreatorsLocked(null);
|
||||
cm.setPencillersLocked(null);
|
||||
cm.setInkersLocked(null);
|
||||
cm.setColoristsLocked(null);
|
||||
cm.setLetterersLocked(null);
|
||||
cm.setCoverArtistsLocked(null);
|
||||
cm.setEditorsLocked(null);
|
||||
cm.setCharactersLocked(null);
|
||||
cm.setTeamsLocked(null);
|
||||
cm.setLocationsLocked(null);
|
||||
|
||||
// Strip non-filter detail fields
|
||||
cm.setIssueNumber(null);
|
||||
cm.setVolumeName(null);
|
||||
cm.setVolumeNumber(null);
|
||||
cm.setStoryArc(null);
|
||||
cm.setStoryArcNumber(null);
|
||||
cm.setAlternateSeries(null);
|
||||
cm.setAlternateIssue(null);
|
||||
cm.setImprint(null);
|
||||
cm.setFormat(null);
|
||||
cm.setBlackAndWhite(null);
|
||||
cm.setManga(null);
|
||||
cm.setReadingDirection(null);
|
||||
cm.setWebLink(null);
|
||||
cm.setNotes(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean computeAllMetadataLocked(BookMetadata m) {
|
||||
Boolean[] bookLocks = {
|
||||
m.getTitleLocked(), m.getSubtitleLocked(), m.getPublisherLocked(),
|
||||
m.getPublishedDateLocked(), m.getDescriptionLocked(), m.getSeriesNameLocked(),
|
||||
m.getSeriesNumberLocked(), m.getSeriesTotalLocked(), m.getIsbn13Locked(),
|
||||
m.getIsbn10Locked(), m.getAsinLocked(), m.getGoodreadsIdLocked(),
|
||||
m.getComicvineIdLocked(), m.getHardcoverIdLocked(), m.getHardcoverBookIdLocked(),
|
||||
m.getDoubanIdLocked(), m.getGoogleIdLocked(), m.getPageCountLocked(),
|
||||
m.getLanguageLocked(), m.getAmazonRatingLocked(), m.getAmazonReviewCountLocked(),
|
||||
m.getGoodreadsRatingLocked(), m.getGoodreadsReviewCountLocked(),
|
||||
m.getHardcoverRatingLocked(), m.getHardcoverReviewCountLocked(),
|
||||
m.getDoubanRatingLocked(), m.getDoubanReviewCountLocked(),
|
||||
m.getLubimyczytacIdLocked(), m.getLubimyczytacRatingLocked(),
|
||||
m.getRanobedbIdLocked(), m.getRanobedbRatingLocked(),
|
||||
m.getAudibleIdLocked(), m.getAudibleRatingLocked(), m.getAudibleReviewCountLocked(),
|
||||
m.getExternalUrlLocked(), m.getCoverLocked(), m.getAudiobookCoverLocked(),
|
||||
m.getAuthorsLocked(), m.getCategoriesLocked(), m.getMoodsLocked(),
|
||||
m.getTagsLocked(), m.getReviewsLocked(), m.getNarratorLocked(),
|
||||
m.getAbridgedLocked(), m.getAgeRatingLocked(), m.getContentRatingLocked()
|
||||
};
|
||||
|
||||
boolean hasAnyLock = false;
|
||||
for (Boolean lock : bookLocks) {
|
||||
if (Boolean.TRUE.equals(lock)) {
|
||||
hasAnyLock = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return hasAnyLock;
|
||||
}
|
||||
}
|
||||
|
||||
471
booklore-ui/package-lock.json
generated
471
booklore-ui/package-lock.json
generated
@@ -463,6 +463,22 @@
|
||||
"typescript": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@angular-eslint/template-parser": {
|
||||
"version": "21.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-21.2.0.tgz",
|
||||
"integrity": "sha512-TCb3qYOC/uXKZCo56cJ6N9sHeWdFhyVqrbbYfFjTi09081T6jllgHDZL5Ms7gOMNY8KywWGGbhxwvzeA0RwTgA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@angular-eslint/bundled-angular-compiler": "21.2.0",
|
||||
"eslint-scope": "^9.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0",
|
||||
"typescript": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@angular-eslint/utils": {
|
||||
"version": "21.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-21.2.0.tgz",
|
||||
@@ -478,6 +494,276 @@
|
||||
"typescript": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@eslint/config-array": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
|
||||
"integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint/object-schema": "^2.1.7",
|
||||
"debug": "^4.3.1",
|
||||
"minimatch": "^3.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@eslint/config-helpers": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
|
||||
"integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint/core": "^0.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@eslint/core": {
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
|
||||
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/json-schema": "^7.0.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@eslint/object-schema": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
|
||||
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@eslint/plugin-kit": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
|
||||
"integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint/core": "^0.17.0",
|
||||
"levn": "^0.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/@typescript-eslint/utils": {
|
||||
"version": "8.55.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz",
|
||||
"integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.9.1",
|
||||
"@typescript-eslint/scope-manager": "8.55.0",
|
||||
"@typescript-eslint/types": "8.55.0",
|
||||
"@typescript-eslint/typescript-estree": "8.55.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0",
|
||||
"typescript": ">=4.8.4 <6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"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"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/eslint": {
|
||||
"version": "9.39.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz",
|
||||
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
"@eslint/config-array": "^0.21.1",
|
||||
"@eslint/config-helpers": "^0.4.2",
|
||||
"@eslint/core": "^0.17.0",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "9.39.2",
|
||||
"@eslint/plugin-kit": "^0.4.1",
|
||||
"@humanfs/node": "^0.16.6",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@humanwhocodes/retry": "^0.4.2",
|
||||
"@types/estree": "^1.0.6",
|
||||
"ajv": "^6.12.4",
|
||||
"chalk": "^4.0.0",
|
||||
"cross-spawn": "^7.0.6",
|
||||
"debug": "^4.3.2",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"eslint-scope": "^8.4.0",
|
||||
"eslint-visitor-keys": "^4.2.1",
|
||||
"espree": "^10.4.0",
|
||||
"esquery": "^1.5.0",
|
||||
"esutils": "^2.0.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"file-entry-cache": "^8.0.0",
|
||||
"find-up": "^5.0.0",
|
||||
"glob-parent": "^6.0.2",
|
||||
"ignore": "^5.2.0",
|
||||
"imurmurhash": "^0.1.4",
|
||||
"is-glob": "^4.0.0",
|
||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||
"lodash.merge": "^4.6.2",
|
||||
"minimatch": "^3.1.2",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.9.3"
|
||||
},
|
||||
"bin": {
|
||||
"eslint": "bin/eslint.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://eslint.org/donate"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"jiti": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"jiti": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/eslint-visitor-keys": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/eslint/node_modules/eslint-scope": {
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
|
||||
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^5.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/eslint/node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/espree": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
|
||||
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.15.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
"eslint-visitor-keys": "^4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@angular-eslint/schematics/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@angular/animations": {
|
||||
"version": "21.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.1.4.tgz",
|
||||
@@ -1880,6 +2166,141 @@
|
||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
|
||||
"integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^10.0.1",
|
||||
"globals": "^14.0.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.1",
|
||||
"minimatch": "^3.1.2",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"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"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/espree": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
|
||||
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.15.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
"eslint-visitor-keys": "^4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/ignore": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "9.39.2",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz",
|
||||
"integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://eslint.org/donate"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/object-schema": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.1.tgz",
|
||||
@@ -5489,6 +5910,24 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chardet": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz",
|
||||
@@ -5715,6 +6154,14 @@
|
||||
"node": "^12.20.0 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
|
||||
@@ -7000,6 +7447,20 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
|
||||
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
@@ -7803,6 +8264,14 @@
|
||||
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/log-symbols": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz",
|
||||
@@ -10300,7 +10769,7 @@
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
||||
@@ -239,6 +239,7 @@ export interface BookMetadata {
|
||||
contentRating?: string | null;
|
||||
ageRatingLocked?: boolean;
|
||||
contentRatingLocked?: boolean;
|
||||
allMetadataLocked?: boolean;
|
||||
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
@@ -88,10 +88,7 @@ export class SortService {
|
||||
hardcoverRating: (book) => book.metadata?.hardcoverRating || null,
|
||||
hardcoverReviewCount: (book) => book.metadata?.hardcoverReviewCount || null,
|
||||
ranobedbRating: (book) => book.metadata?.ranobedbRating || null,
|
||||
locked: (book) =>
|
||||
Object.keys(book.metadata ?? {})
|
||||
.filter((key) => key.endsWith('Locked'))
|
||||
.every((key) => book.metadata?.[key] === true),
|
||||
locked: (book) => book.metadata?.allMetadataLocked ?? false,
|
||||
lastReadTime: (book) => book.lastReadTime ? new Date(book.lastReadTime).getTime() : null,
|
||||
addedOn: (book) => book.addedOn ? new Date(book.addedOn).getTime() : null,
|
||||
fileSizeKb: (book) => book.fileSizeKb || null,
|
||||
|
||||
Reference in New Issue
Block a user