diff --git a/app/Controllers/Http/Api/AuthorsController.ts b/app/Controllers/Http/Api/AuthorsController.ts
index 599da80..bc964a9 100644
--- a/app/Controllers/Http/Api/AuthorsController.ts
+++ b/app/Controllers/Http/Api/AuthorsController.ts
@@ -9,12 +9,14 @@ export default class AuthorsController {
// where exists (select * from gba.documents inner join gba.link_documents_persons on "documents"."id" = "link_documents_persons"."document_id"
// where ("link_documents_persons"."role" = 'author') and ("persons"."id" = "link_documents_persons"."person_id"));
const authors = await Person.query()
+ .where('name_type', 'Personal')
.whereHas('datasets', (dQuery) => {
dQuery.wherePivot('role', 'author');
})
.withCount('datasets', (query) => {
query.as('datasets_count');
- });
+ })
+ .orderBy('datasets_count', 'desc');
return authors;
}
diff --git a/app/Controllers/Http/Api/AvatarController.ts b/app/Controllers/Http/Api/AvatarController.ts
index 0b337d9..74fe135 100644
--- a/app/Controllers/Http/Api/AvatarController.ts
+++ b/app/Controllers/Http/Api/AvatarController.ts
@@ -1,104 +1,135 @@
import type { HttpContext } from '@adonisjs/core/http';
import { StatusCodes } from 'http-status-codes';
+import redis from '@adonisjs/redis/services/main';
-const prefixes = ['von', 'van'];
+const PREFIXES = ['von', 'van'];
+const DEFAULT_SIZE = 50;
+const FONT_SIZE_RATIO = 0.4;
+const COLOR_LIGHTENING_PERCENT = 60;
+const COLOR_DARKENING_FACTOR = 0.6;
export default class AvatarController {
public async generateAvatar({ request, response }: HttpContext) {
try {
- const { name, size } = request.only(['name', 'size']);
+ const { name, size = DEFAULT_SIZE } = request.only(['name', 'size']);
+ if (!name) {
+ return response.status(StatusCodes.BAD_REQUEST).json({ error: 'Name is required' });
+ }
+
+ // Build a unique cache key for the given name and size
+ const cacheKey = `avatar:${name.trim().toLowerCase()}-${size}`;
+ const cachedSvg = await redis.get(cacheKey);
+ if (cachedSvg) {
+ this.setResponseHeaders(response);
+ return response.send(cachedSvg);
+ }
const initials = this.getInitials(name);
+ const colors = this.generateColors(name);
+ const svgContent = this.createSvg(size, colors, initials);
- const originalColor = this.getColorFromName(name);
- const backgroundColor = this.lightenColor(originalColor, 60);
- const textColor = this.darkenColor(originalColor);
-
- const svgContent = `
-
- `;
-
- response.header('Content-type', 'image/svg+xml');
- response.header('Cache-Control', 'no-cache');
- response.header('Pragma', 'no-cache');
- response.header('Expires', '0');
+ // // Cache the generated avatar for future use, e.g. 1 hour expiry
+ await redis.setex(cacheKey, 3600, svgContent);
+ this.setResponseHeaders(response);
return response.send(svgContent);
} catch (error) {
- return response.status(StatusCodes.OK).json({ error: error.message });
+ return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({ error: error.message });
}
}
- private getInitials(name: string) {
- const parts = name.split(' ');
- let initials = '';
+ private getInitials(name: string): string {
+ const parts = name
+ .trim()
+ .split(' ')
+ .filter((part) => part.length > 0);
+
+ if (parts.length === 0) {
+ return 'NA';
+ }
if (parts.length >= 2) {
- const firstName = parts[0];
- const lastName = parts[parts.length - 1];
-
- const firstInitial = firstName.charAt(0).toUpperCase();
- const lastInitial = lastName.charAt(0).toUpperCase();
-
- if (prefixes.includes(lastName.toLowerCase()) && lastName === lastName.toUpperCase()) {
- initials = firstInitial + lastName.charAt(1).toUpperCase();
- } else {
- initials = firstInitial + lastInitial;
- }
- } else if (parts.length === 1) {
- initials = parts[0].substring(0, 2).toUpperCase();
+ return this.getMultiWordInitials(parts);
}
-
- return initials;
+ return parts[0].substring(0, 2).toUpperCase();
}
- private getColorFromName(name: string) {
+ private getMultiWordInitials(parts: string[]): string {
+ const firstName = parts[0];
+ const lastName = parts[parts.length - 1];
+ const firstInitial = firstName.charAt(0).toUpperCase();
+ const lastInitial = lastName.charAt(0).toUpperCase();
+
+ if (PREFIXES.includes(lastName.toLowerCase()) && lastName === lastName.toUpperCase()) {
+ return firstInitial + lastName.charAt(1).toUpperCase();
+ }
+ return firstInitial + lastInitial;
+ }
+
+ private generateColors(name: string): { background: string; text: string } {
+ const baseColor = this.getColorFromName(name);
+ return {
+ background: this.lightenColor(baseColor, COLOR_LIGHTENING_PERCENT),
+ text: this.darkenColor(baseColor),
+ };
+ }
+
+ private createSvg(size: number, colors: { background: string; text: string }, initials: string): string {
+ const fontSize = size * FONT_SIZE_RATIO;
+ return `
+
+ `;
+ }
+
+ private setResponseHeaders(response: HttpContext['response']): void {
+ response.header('Content-type', 'image/svg+xml');
+ response.header('Cache-Control', 'no-cache');
+ response.header('Pragma', 'no-cache');
+ response.header('Expires', '0');
+ }
+
+ private getColorFromName(name: string): string {
let hash = 0;
for (let i = 0; i < name.length; i++) {
hash = name.charCodeAt(i) + ((hash << 5) - hash);
}
- let color = '#';
+
+ const colorParts = [];
for (let i = 0; i < 3; i++) {
const value = (hash >> (i * 8)) & 0xff;
- color += ('00' + value.toString(16)).substr(-2);
+ colorParts.push(value.toString(16).padStart(2, '0'));
}
- return color.replace('#', '');
+ return colorParts.join('');
}
- private lightenColor(hexColor: string, percent: number) {
- let r = parseInt(hexColor.substring(0, 2), 16);
- let g = parseInt(hexColor.substring(2, 4), 16);
- let b = parseInt(hexColor.substring(4, 6), 16);
+ private lightenColor(hexColor: string, percent: number): string {
+ const r = parseInt(hexColor.substring(0, 2), 16);
+ const g = parseInt(hexColor.substring(2, 4), 16);
+ const b = parseInt(hexColor.substring(4, 6), 16);
- r = Math.floor((r * (100 + percent)) / 100);
- g = Math.floor((g * (100 + percent)) / 100);
- b = Math.floor((b * (100 + percent)) / 100);
+ const lightenValue = (value: number) => Math.min(255, Math.floor((value * (100 + percent)) / 100));
- r = r < 255 ? r : 255;
- g = g < 255 ? g : 255;
- b = b < 255 ? b : 255;
+ const newR = lightenValue(r);
+ const newG = lightenValue(g);
+ const newB = lightenValue(b);
- const lighterHex = ((r << 16) | (g << 8) | b).toString(16);
-
- return lighterHex.padStart(6, '0');
+ return ((newR << 16) | (newG << 8) | newB).toString(16).padStart(6, '0');
}
- private darkenColor(hexColor: string) {
+ private darkenColor(hexColor: string): string {
const r = parseInt(hexColor.slice(0, 2), 16);
const g = parseInt(hexColor.slice(2, 4), 16);
const b = parseInt(hexColor.slice(4, 6), 16);
- const darkerR = Math.round(r * 0.6);
- const darkerG = Math.round(g * 0.6);
- const darkerB = Math.round(b * 0.6);
+ const darkenValue = (value: number) => Math.round(value * COLOR_DARKENING_FACTOR);
- const darkerColor = ((darkerR << 16) + (darkerG << 8) + darkerB).toString(16);
+ const darkerR = darkenValue(r);
+ const darkerG = darkenValue(g);
+ const darkerB = darkenValue(b);
- return darkerColor.padStart(6, '0');
+ return ((darkerR << 16) + (darkerG << 8) + darkerB).toString(16).padStart(6, '0');
}
}
diff --git a/app/Controllers/Http/Api/DatasetController.ts b/app/Controllers/Http/Api/DatasetController.ts
index 41befe6..b80949d 100644
--- a/app/Controllers/Http/Api/DatasetController.ts
+++ b/app/Controllers/Http/Api/DatasetController.ts
@@ -6,10 +6,15 @@ import { StatusCodes } from 'http-status-codes';
// node ace make:controller Author
export default class DatasetController {
public async index({}: HttpContext) {
- // select * from gba.persons
- // where exists (select * from gba.documents inner join gba.link_documents_persons on "documents"."id" = "link_documents_persons"."document_id"
- // where ("link_documents_persons"."role" = 'author') and ("persons"."id" = "link_documents_persons"."person_id"));
- const datasets = await Dataset.query().where('server_state', 'published').orWhere('server_state', 'deleted');
+ // Select datasets with server_state 'published' or 'deleted' and sort by the last published date
+ const datasets = await Dataset.query()
+ .where(function (query) {
+ query.where('server_state', 'published')
+ .orWhere('server_state', 'deleted');
+ })
+ .preload('titles')
+ .preload('identifier')
+ .orderBy('server_date_published', 'desc');
return datasets;
}
diff --git a/app/Controllers/Http/Api/FileController.ts b/app/Controllers/Http/Api/FileController.ts
index 3c1f3d4..8080479 100644
--- a/app/Controllers/Http/Api/FileController.ts
+++ b/app/Controllers/Http/Api/FileController.ts
@@ -14,7 +14,7 @@ export default class FileController {
// where: { id: id },
// });
if (file) {
- const filePath = '/storage/app/public/' + file.pathName;
+ const filePath = '/storage/app/data/' + file.pathName;
const ext = path.extname(filePath);
const fileName = file.label + ext;
try {
diff --git a/app/Controllers/Http/Api/UserController.ts b/app/Controllers/Http/Api/UserController.ts
index 975e5e2..1d7a14a 100644
--- a/app/Controllers/Http/Api/UserController.ts
+++ b/app/Controllers/Http/Api/UserController.ts
@@ -9,6 +9,24 @@ import BackupCode from '#models/backup_code';
// Here we are generating secret and recovery codes for the user that’s enabling 2FA and storing them to our database.
export default class UserController {
+ public async getSubmitters({ response }: HttpContext) {
+ try {
+ const submitters = await User.query()
+ .preload('roles', (query) => {
+ query.where('name', 'submitter')
+ })
+ .whereHas('roles', (query) => {
+ query.where('name', 'submitter')
+ })
+ .exec();
+ return submitters;
+ } catch (error) {
+ return response.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
+ message: 'Invalid TOTP state',
+ });
+ }
+ }
+
public async enable({ auth, response, request }: HttpContext) {
const user = (await User.find(auth.user?.id)) as User;
// await user.load('totp_secret');
diff --git a/app/Controllers/Http/Api/collections_controller.ts b/app/Controllers/Http/Api/collections_controller.ts
new file mode 100644
index 0000000..04dcdb2
--- /dev/null
+++ b/app/Controllers/Http/Api/collections_controller.ts
@@ -0,0 +1,36 @@
+import type { HttpContext } from '@adonisjs/core/http';
+import Collection from '#models/collection';
+
+export default class CollectionsController {
+ public async show({ params, response }: HttpContext) {
+ // Get the collection id from route parameters
+ const collectionId = params.id;
+
+ // Find the selected collection by id
+ const collection = await Collection.find(collectionId);
+ if (!collection) {
+ return response.status(404).json({ message: 'Collection not found' });
+ }
+
+ // Query for narrower concepts: collections whose parent_id equals the selected collection's id
+ const narrowerCollections = await Collection.query().where('parent_id', collection.id) || [];
+
+ // For broader concept, if the selected collection has a parent_id fetch that record (otherwise null)
+ const broaderCollection: Collection[] | never[] | null = await (async () => {
+ if (collection.parent_id) {
+ // Try to fetch the parent...
+ const parent = await Collection.find(collection.parent_id)
+ // If found, return it wrapped in an array; if not found, return null (or empty array if you prefer)
+ return parent ? [parent] : null
+ }
+ return []
+ })()
+
+ // Return the selected collection along with its narrower and broader concepts in JSON format
+ return response.json({
+ selectedCollection: collection,
+ narrowerCollections,
+ broaderCollection,
+ });
+ }
+}
diff --git a/app/Controllers/Http/Oai/OaiController.ts b/app/Controllers/Http/Oai/OaiController.ts
index 6048ca4..db49a32 100644
--- a/app/Controllers/Http/Oai/OaiController.ts
+++ b/app/Controllers/Http/Oai/OaiController.ts
@@ -19,14 +19,13 @@ import XmlModel from '#app/Library/XmlModel';
import logger from '@adonisjs/core/services/logger';
import ResumptionToken from '#app/Library/Oai/ResumptionToken';
// import Config from '@ioc:Adonis/Core/Config';
-import config from '@adonisjs/core/services/config'
+import config from '@adonisjs/core/services/config';
// import { inject } from '@adonisjs/fold';
-import { inject } from '@adonisjs/core'
+import { inject } from '@adonisjs/core';
// import { TokenWorkerContract } from "MyApp/Models/TokenWorker";
import TokenWorkerContract from '#library/Oai/TokenWorkerContract';
import { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
-
interface XslTParameter {
[key: string]: any;
}
@@ -35,12 +34,14 @@ interface Dictionary {
[index: string]: string;
}
-interface ListParameter {
+interface PagingParameter {
cursor: number;
- totalIds: number;
+ totalLength: number;
start: number;
- reldocIds: (number | null)[];
+ nextDocIds: number[];
+ activeWorkIds: number[];
metadataPrefix: string;
+ queryParams: Object;
}
@inject()
@@ -49,6 +50,7 @@ export default class OaiController {
private sampleRegEx = /^[A-Za-zäüÄÜß0-9\-_.!~]+$/;
private xsltParameter: XslTParameter;
+ private firstPublishedDataset: Dataset | null;
/**
* Holds xml representation of document information to be processed.
*
@@ -57,7 +59,6 @@ export default class OaiController {
private xml: XMLBuilder;
private proc;
-
constructor(public tokenWorker: TokenWorkerContract) {
// Load the XSLT file
this.proc = readFileSync('public/assets2/datasetxml2oai.sef.json');
@@ -85,9 +86,9 @@ export default class OaiController {
let earliestDateFromDb;
// const oaiRequest: OaiParameter = request.body;
try {
- const firstPublishedDataset: Dataset | null = await Dataset.earliestPublicationDate();
- firstPublishedDataset != null &&
- (earliestDateFromDb = firstPublishedDataset.server_date_published.toFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
+ this.firstPublishedDataset = await Dataset.earliestPublicationDate();
+ this.firstPublishedDataset != null &&
+ (earliestDateFromDb = this.firstPublishedDataset.server_date_published.toFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
this.xsltParameter['earliestDatestamp'] = earliestDateFromDb;
// start the request
await this.handleRequest(oaiRequest, request);
@@ -162,22 +163,19 @@ export default class OaiController {
} else if (verb == 'GetRecord') {
await this.handleGetRecord(oaiRequest);
} else if (verb == 'ListRecords') {
- await this.handleListRecords(oaiRequest);
+ // Get browser fingerprint from the request:
+ const browserFingerprint = this.getBrowserFingerprint(request);
+ await this.handleListRecords(oaiRequest, browserFingerprint);
} else if (verb == 'ListIdentifiers') {
- await this.handleListIdentifiers(oaiRequest);
+ // Get browser fingerprint from the request:
+ const browserFingerprint = this.getBrowserFingerprint(request);
+ await this.handleListIdentifiers(oaiRequest, browserFingerprint);
} else if (verb == 'ListSets') {
await this.handleListSets();
} else {
this.handleIllegalVerb();
}
} else {
- // // try {
- // // console.log("Async code example.")
- // const err = new PageNotFoundException("verb not found");
- // throw err;
- // // } catch (error) { // manually catching
- // // next(error); // passing to default middleware error handler
- // // }
throw new OaiModelException(
StatusCodes.INTERNAL_SERVER_ERROR,
'The verb provided in the request is illegal.',
@@ -187,11 +185,11 @@ export default class OaiController {
}
protected handleIdentify() {
- const email = process.env.OAI_EMAIL || 'repository@geosphere.at';
- const repositoryName = 'Tethys RDR';
- const repIdentifier = 'tethys.at';
- const sampleIdentifier = 'oai:' + repIdentifier + ':1'; //$this->_configuration->getSampleIdentifier();
-
+ // Get configuration values from environment or a dedicated configuration service
+ const email = process.env.OAI_EMAIL ?? 'repository@geosphere.at';
+ const repositoryName = process.env.OAI_REPOSITORY_NAME ?? 'Tethys RDR';
+ const repIdentifier = process.env.OAI_REP_IDENTIFIER ?? 'tethys.at';
+ const sampleIdentifier = `oai:${repIdentifier}:1`;
// Dataset::earliestPublicationDate()->server_date_published->format('Y-m-d\TH:i:s\Z') : null;
// earliestDateFromDb!= null && (this.xsltParameter['earliestDatestamp'] = earliestDateFromDb?.server_date_published);
@@ -216,7 +214,7 @@ export default class OaiController {
const sets: { [key: string]: string } = {
'open_access': 'Set for open access licenses',
- 'openaire_data': "OpenAIRE",
+ 'openaire_data': 'OpenAIRE',
'doc-type:ResearchData': 'Set for document type ResearchData',
...(await this.getSetsForDatasetTypes()),
...(await this.getSetsForCollections()),
@@ -234,7 +232,15 @@ export default class OaiController {
const repIdentifier = 'tethys.at';
this.xsltParameter['repIdentifier'] = repIdentifier;
+ // Validate that required parameter exists early
+ if (!('identifier' in oaiRequest)) {
+ throw new BadOaiModelException('The prefix of the identifier argument is unknown.');
+ }
+
+ // Validate and extract the dataset identifier from the request
const dataId = this.validateAndGetIdentifier(oaiRequest);
+
+ // Retrieve dataset with associated XML cache and collection roles
const dataset = await Dataset.query()
.where('publish_id', dataId)
.preload('xmlCache')
@@ -251,59 +257,61 @@ export default class OaiController {
);
}
+ // Validate and set the metadata prefix parameter
const metadataPrefix = this.validateAndGetMetadataPrefix(oaiRequest);
this.xsltParameter['oai_metadataPrefix'] = metadataPrefix;
- // do not deliver datasets which are restricted by document state defined in deliveringStates
+
+ // Ensure that the dataset is in an exportable state
this.validateDatasetState(dataset);
- // add xml elements
+ // Build the XML for the dataset record and add it to the root node
const datasetNode = this.xml.root().ele('Datasets');
await this.createXmlRecord(dataset, datasetNode);
}
- protected async handleListIdentifiers(oaiRequest: Dictionary) {
- !this.tokenWorker.isConnected && (await this.tokenWorker.connect());
+ protected async handleListIdentifiers(oaiRequest: Dictionary, browserFingerprint: string) {
+ if (!this.tokenWorker.isConnected) {
+ await this.tokenWorker.connect();
+ }
const maxIdentifier: number = config.get('oai.max.listidentifiers', 100);
- await this.handleLists(oaiRequest, maxIdentifier);
+ await this.handleLists(oaiRequest, maxIdentifier, browserFingerprint);
}
- protected async handleListRecords(oaiRequest: Dictionary) {
- !this.tokenWorker.isConnected && (await this.tokenWorker.connect());
+ protected async handleListRecords(oaiRequest: Dictionary, browserFingerprint: string) {
+ if (!this.tokenWorker.isConnected) {
+ await this.tokenWorker.connect();
+ }
const maxRecords: number = config.get('oai.max.listrecords', 100);
- await this.handleLists(oaiRequest, maxRecords);
+ await this.handleLists(oaiRequest, maxRecords, browserFingerprint);
}
- private async handleLists(oaiRequest: Dictionary, maxRecords: number) {
- maxRecords = maxRecords || 100;
+ private async handleLists(oaiRequest: Dictionary, maxRecords: number, browserFingerprint: string) {
const repIdentifier = 'tethys.at';
this.xsltParameter['repIdentifier'] = repIdentifier;
const datasetNode = this.xml.root().ele('Datasets');
- // list initialisation
- const numWrapper: ListParameter = {
+ const paginationParams: PagingParameter ={
cursor: 0,
- totalIds: 0,
+ totalLength: 0,
start: maxRecords + 1,
- reldocIds: [],
+ nextDocIds: [],
+ activeWorkIds: [],
metadataPrefix: '',
+ queryParams: {},
};
- // resumptionToken is defined
if ('resumptionToken' in oaiRequest) {
- await this.handleResumptionToken(oaiRequest, maxRecords, numWrapper);
+ await this.handleResumptionToken(oaiRequest, maxRecords, paginationParams);
} else {
- // no resumptionToken is given
- await this.handleNoResumptionToken(oaiRequest, numWrapper);
+ await this.handleNoResumptionToken(oaiRequest, paginationParams, maxRecords);
}
- // handling of document ids
- const restIds = numWrapper.reldocIds as number[];
- const workIds = restIds.splice(0, maxRecords) as number[]; // array_splice(restIds, 0, maxRecords);
+ const nextIds: number[] = paginationParams.nextDocIds;
+ const workIds: number[] = paginationParams.activeWorkIds;
- // no records returned
- if (workIds.length == 0) {
+ if (workIds.length === 0) {
throw new OaiModelException(
StatusCodes.INTERNAL_SERVER_ERROR,
'The combination of the given values results in an empty list.',
@@ -311,169 +319,218 @@ export default class OaiController {
);
}
- const datasets: Dataset[] = await Dataset.query()
+ const datasets = await Dataset.query()
.whereIn('publish_id', workIds)
.preload('xmlCache')
.preload('collections', (builder) => {
builder.preload('collectionRole');
})
.orderBy('publish_id');
-
for (const dataset of datasets) {
await this.createXmlRecord(dataset, datasetNode);
}
-
- // store the further Ids in a resumption-file
- const countRestIds = restIds.length; //84
- if (countRestIds > 0) {
- const token = new ResumptionToken();
- token.startPosition = numWrapper.start; //101
- token.totalIds = numWrapper.totalIds; //184
- token.documentIds = restIds; //101 -184
- token.metadataPrefix = numWrapper.metadataPrefix;
-
- // $tokenWorker->storeResumptionToken($token);
- const res: string = await this.tokenWorker.set(token);
-
- // set parameters for the resumptionToken-node
- // const res = token.ResumptionId;
- this.setParamResumption(res, numWrapper.cursor, numWrapper.totalIds);
- }
+ await this.setResumptionToken(nextIds, paginationParams, browserFingerprint);
}
- private async handleResumptionToken(oaiRequest: Dictionary, maxRecords: number, numWrapper: ListParameter) {
- const resParam = oaiRequest['resumptionToken']; //e.g. "158886496600000"
+ private async handleNoResumptionToken(oaiRequest: Dictionary, paginationParams: PagingParameter, maxRecords: number) {
+ this.validateMetadataPrefix(oaiRequest, paginationParams);
+ const finder: ModelQueryBuilderContract = Dataset.query().whereIn(
+ 'server_state',
+ this.deliveringDocumentStates,
+ );
+ this.applySetFilter(finder, oaiRequest);
+ this.applyDateFilters(finder, oaiRequest);
+ await this.fetchAndSetResults(finder, paginationParams, oaiRequest, maxRecords);
+ }
+
+ private async fetchAndSetResults(
+ finder: ModelQueryBuilderContract,
+ paginationParams: PagingParameter,
+ oaiRequest: Dictionary,
+ maxRecords: number
+ ) {
+ const totalResult = await finder
+ .clone()
+ .count('* as total')
+ .first()
+ .then((res) => res?.$extras.total);
+ paginationParams.totalLength = Number(totalResult);
+
+ const combinedRecords: Dataset[] = await finder.select('publish_id').orderBy('publish_id').offset(0).limit(maxRecords*2);
+
+ paginationParams.activeWorkIds = combinedRecords.slice(0, 100).map((dat) => Number(dat.publish_id));
+ paginationParams.nextDocIds = combinedRecords.slice(100).map((dat) => Number(dat.publish_id));
+
+ // No resumption token was used – set queryParams from the current oaiRequest
+ paginationParams.queryParams = {
+ ...oaiRequest,
+ deliveringStates: this.deliveringDocumentStates,
+ };
+
+ // paginationParams.totalLength = 230;
+ }
+
+ private async handleResumptionToken(oaiRequest: Dictionary, maxRecords: number, paginationParams: PagingParameter) {
+ const resParam = oaiRequest['resumptionToken'];
const token = await this.tokenWorker.get(resParam);
if (!token) {
throw new OaiModelException(StatusCodes.INTERNAL_SERVER_ERROR, 'cache is outdated.', OaiErrorCodes.BADRESUMPTIONTOKEN);
}
- numWrapper.cursor = token.startPosition - 1; //startet dann bei Index 10
- numWrapper.start = token.startPosition + maxRecords;
- numWrapper.totalIds = token.totalIds;
- numWrapper.reldocIds = token.documentIds;
- numWrapper.metadataPrefix = token.metadataPrefix;
+ // this.setResumptionParameters(token, maxRecords, paginationParams);
+ paginationParams.cursor = token.startPosition - 1;
+ paginationParams.start = token.startPosition + maxRecords;
+ paginationParams.totalLength = token.totalIds;
+ paginationParams.activeWorkIds = token.documentIds;
+ paginationParams.metadataPrefix = token.metadataPrefix;
+ paginationParams.queryParams = token.queryParams;
+ this.xsltParameter['oai_metadataPrefix'] = token.metadataPrefix;
- this.xsltParameter['oai_metadataPrefix'] = numWrapper.metadataPrefix;
+ const finder = this.buildDatasetQueryViaToken(token);
+ const nextRecords: Dataset[] = await this.fetchNextRecords(finder, token, maxRecords);
+ paginationParams.nextDocIds = nextRecords.map((dat) => Number(dat.publish_id));
}
- private async handleNoResumptionToken(oaiRequest: Dictionary, numWrapper: ListParameter) {
- // no resumptionToken is given
- if ('metadataPrefix' in oaiRequest) {
- numWrapper.metadataPrefix = oaiRequest['metadataPrefix'];
- } else {
+ private async setResumptionToken(nextIds: number[], paginationParams: PagingParameter, browserFingerprint: string) {
+ const countRestIds = nextIds.length;
+ if (countRestIds > 0) {
+ // const token = this.createResumptionToken(paginationParams, nextIds);
+ const token = new ResumptionToken();
+ token.startPosition = paginationParams.start;
+ token.totalIds = paginationParams.totalLength;
+ token.documentIds = nextIds;
+ token.metadataPrefix = paginationParams.metadataPrefix;
+ token.queryParams = paginationParams.queryParams;
+ const res: string = await this.tokenWorker.set(token, browserFingerprint);
+ this.setParamResumption(res, paginationParams.cursor, paginationParams.totalLength);
+ }
+ }
+
+ private buildDatasetQueryViaToken(token: ResumptionToken) {
+ const finder = Dataset.query();
+ const originalQuery = token.queryParams || {};
+ const deliveringStates = originalQuery.deliveringStates || this.deliveringDocumentStates;
+
+ finder.whereIn('server_state', deliveringStates);
+ this.applySetFilter(finder, originalQuery);
+ this.applyDateFilters(finder, originalQuery);
+
+ return finder;
+ }
+
+ private async fetchNextRecords(finder: ModelQueryBuilderContract, token: ResumptionToken, maxRecords: number) {
+ return finder
+ .select('publish_id')
+ .orderBy('publish_id')
+ .offset(token.startPosition - 1 + maxRecords)
+ .limit(100);
+ }
+
+ private validateMetadataPrefix(oaiRequest: Dictionary, paginationParams: PagingParameter) {
+ if (!('metadataPrefix' in oaiRequest)) {
throw new OaiModelException(
StatusCodes.INTERNAL_SERVER_ERROR,
'The prefix of the metadata argument is unknown.',
OaiErrorCodes.BADARGUMENT,
);
}
- this.xsltParameter['oai_metadataPrefix'] = numWrapper.metadataPrefix;
+ paginationParams.metadataPrefix = oaiRequest['metadataPrefix'];
+ this.xsltParameter['oai_metadataPrefix'] = paginationParams.metadataPrefix;
+ }
- let finder: ModelQueryBuilderContract = Dataset.query();
- // add server state restrictions
- finder.whereIn('server_state', this.deliveringDocumentStates);
- if ('set' in oaiRequest) {
- const set = oaiRequest['set'] as string;
- const setArray = set.split(':');
+ private applySetFilter(finder: ModelQueryBuilderContract, queryParams: any) {
+ if ('set' in queryParams) {
+ const [setType, setValue] = queryParams['set'].split(':');
- if (setArray[0] == 'data-type') {
- if (setArray.length == 2 && setArray[1]) {
- finder.where('type', setArray[1]);
- }
- } else if (setArray[0] == 'open_access') {
- const openAccessLicences = ['CC-BY-4.0', 'CC-BY-SA-4.0'];
- finder.andWhereHas('licenses', (query) => {
- query.whereIn('name', openAccessLicences);
- });
- } else if (setArray[0] == 'ddc') {
- if (setArray.length == 2 && setArray[1] != '') {
- finder.andWhereHas('collections', (query) => {
- query.where('number', setArray[1]);
+ switch (setType) {
+ case 'data-type':
+ setValue && finder.where('type', setValue);
+ break;
+ case 'open_access':
+ finder.andWhereHas('licenses', (query) => {
+ query.whereIn('name', ['CC-BY-4.0', 'CC-BY-SA-4.0']);
});
- }
+ break;
+ case 'ddc':
+ setValue &&
+ finder.andWhereHas('collections', (query) => {
+ query.where('number', setValue);
+ });
+ break;
}
}
+ }
- // const timeZone = "Europe/Vienna"; // Canonical time zone name
- // &from=2020-09-03&until2020-09-03
- // &from=2020-09-11&until=2021-05-11
- if ('from' in oaiRequest && 'until' in oaiRequest) {
- const from = oaiRequest['from'] as string;
- let fromDate = dayjs(from); //.tz(timeZone);
- const until = oaiRequest['until'] as string;
- let untilDate = dayjs(until); //.tz(timeZone);
- if (!fromDate.isValid() || !untilDate.isValid()) {
- throw new OaiModelException(StatusCodes.INTERNAL_SERVER_ERROR, 'Date Parameter is not valid.', OaiErrorCodes.BADARGUMENT);
- }
- fromDate = dayjs.tz(from, 'Europe/Vienna');
- untilDate = dayjs.tz(until, 'Europe/Vienna');
+ private applyDateFilters(finder: ModelQueryBuilderContract, queryParams: any) {
+ const { from, until } = queryParams;
- if (from.length != until.length) {
- throw new OaiModelException(
- StatusCodes.INTERNAL_SERVER_ERROR,
- 'The request has different granularities for the from and until parameters.',
- OaiErrorCodes.BADARGUMENT,
- );
- }
- fromDate.hour() == 0 && (fromDate = fromDate.startOf('day'));
- untilDate.hour() == 0 && (untilDate = untilDate.endOf('day'));
+ if (from && until) {
+ this.handleFromUntilFilter(finder, from, until);
+ } else if (from) {
+ this.handleFromFilter(finder, from);
+ } else if (until) {
+ this.handleUntilFilter(finder, until);
+ }
+ }
- finder.whereBetween('server_date_published', [fromDate.format('YYYY-MM-DD HH:mm:ss'), untilDate.format('YYYY-MM-DD HH:mm:ss')]);
- } else if ('from' in oaiRequest && !('until' in oaiRequest)) {
- const from = oaiRequest['from'] as string;
- let fromDate = dayjs(from);
- if (!fromDate.isValid()) {
- throw new OaiModelException(
- StatusCodes.INTERNAL_SERVER_ERROR,
- 'From date parameter is not valid.',
- OaiErrorCodes.BADARGUMENT,
- );
- }
- fromDate = dayjs.tz(from, 'Europe/Vienna');
- fromDate.hour() == 0 && (fromDate = fromDate.startOf('day'));
+ private handleFromUntilFilter(finder: ModelQueryBuilderContract, from: string, until: string) {
+ const fromDate = this.parseDateWithValidation(from, 'From');
+ const untilDate = this.parseDateWithValidation(until, 'Until');
- const now = dayjs();
- if (fromDate.isAfter(now)) {
- throw new OaiModelException(
- StatusCodes.INTERNAL_SERVER_ERROR,
- 'Given from date is greater than now. The given values results in an empty list.',
- OaiErrorCodes.NORECORDSMATCH,
- );
- } else {
- finder.andWhere('server_date_published', '>=', fromDate.format('YYYY-MM-DD HH:mm:ss'));
- }
- } else if (!('from' in oaiRequest) && 'until' in oaiRequest) {
- const until = oaiRequest['until'] as string;
- let untilDate = dayjs(until);
- if (!untilDate.isValid()) {
- throw new OaiModelException(
- StatusCodes.INTERNAL_SERVER_ERROR,
- 'Until date parameter is not valid.',
- OaiErrorCodes.BADARGUMENT,
- );
- }
- untilDate = dayjs.tz(until, 'Europe/Vienna');
- untilDate.hour() == 0 && (untilDate = untilDate.endOf('day'));
-
- const firstPublishedDataset: Dataset = (await Dataset.earliestPublicationDate()) as Dataset;
- const earliestPublicationDate = dayjs(firstPublishedDataset.server_date_published.toISO()); //format("YYYY-MM-DDThh:mm:ss[Z]"));
- if (earliestPublicationDate.isAfter(untilDate)) {
- throw new OaiModelException(
- StatusCodes.INTERNAL_SERVER_ERROR,
- `earliestDatestamp is greater than given until date.
- The given values results in an empty list.`,
- OaiErrorCodes.NORECORDSMATCH,
- );
- } else {
- finder.andWhere('server_date_published', '<=', untilDate.format('YYYY-MM-DD HH:mm:ss'));
- }
+ if (from.length !== until.length) {
+ throw new OaiModelException(
+ StatusCodes.INTERNAL_SERVER_ERROR,
+ 'The request has different granularities for the from and until parameters.',
+ OaiErrorCodes.BADARGUMENT,
+ );
}
- let reldocIdsDocs = await finder.select('publish_id').orderBy('publish_id');
- numWrapper.reldocIds = reldocIdsDocs.map((dat) => dat.publish_id);
- numWrapper.totalIds = numWrapper.reldocIds.length; //212
+ finder.whereBetween('server_date_published', [fromDate.format('YYYY-MM-DD HH:mm:ss'), untilDate.format('YYYY-MM-DD HH:mm:ss')]);
+ }
+
+ private handleFromFilter(finder: ModelQueryBuilderContract, from: string) {
+ const fromDate = this.parseDateWithValidation(from, 'From');
+ const now = dayjs();
+
+ if (fromDate.isAfter(now)) {
+ throw new OaiModelException(
+ StatusCodes.INTERNAL_SERVER_ERROR,
+ 'Given from date is greater than now. The given values results in an empty list.',
+ OaiErrorCodes.NORECORDSMATCH,
+ );
+ }
+
+ finder.andWhere('server_date_published', '>=', fromDate.format('YYYY-MM-DD HH:mm:ss'));
+ }
+
+ private handleUntilFilter(finder: ModelQueryBuilderContract, until: string) {
+ const untilDate = this.parseDateWithValidation(until, 'Until');
+
+ const earliestPublicationDate = dayjs(this.firstPublishedDataset?.server_date_published.toISO());
+
+ if (earliestPublicationDate.isAfter(untilDate)) {
+ throw new OaiModelException(
+ StatusCodes.INTERNAL_SERVER_ERROR,
+ 'earliestDatestamp is greater than given until date. The given values results in an empty list.',
+ OaiErrorCodes.NORECORDSMATCH,
+ );
+ }
+
+ finder.andWhere('server_date_published', '<=', untilDate.format('YYYY-MM-DD HH:mm:ss'));
+ }
+
+ private parseDateWithValidation(dateStr: string, label: string) {
+ let date = dayjs(dateStr);
+ if (!date.isValid()) {
+ throw new OaiModelException(
+ StatusCodes.INTERNAL_SERVER_ERROR,
+ `${label} date parameter is not valid.`,
+ OaiErrorCodes.BADARGUMENT,
+ );
+ }
+ date = dayjs.tz(dateStr, 'Europe/Vienna');
+ return date.hour() === 0 ? (label === 'From' ? date.startOf('day') : date.endOf('day')) : date;
}
private setParamResumption(res: string, cursor: number, totalIds: number) {
@@ -641,4 +698,30 @@ export default class OaiController {
this.xsltParameter['oai_error_code'] = 'badVerb';
this.xsltParameter['oai_error_message'] = 'The verb provided in the request is illegal.';
}
+
+ /**
+ * Helper method to build a browser fingerprint by combining:
+ * - User-Agent header,
+ * - the IP address,
+ * - Accept-Language header,
+ * - current timestamp rounded to the hour.
+ *
+ * Every new hour, this will return a different fingerprint.
+ */
+ private getBrowserFingerprint(request: Request): string {
+ const userAgent = request.header('user-agent') || 'unknown';
+ // Check for X-Forwarded-For header to use the client IP from the proxy if available.
+ const xForwardedFor = request.header('x-forwarded-for');
+ let ip = request.ip();
+ // console.log(ip);
+ if (xForwardedFor) {
+ // X-Forwarded-For may contain a comma-separated list of IPs; the first one is the client IP.
+ ip = xForwardedFor.split(',')[0].trim();
+ // console.log('xforwardedfor ip' + ip);
+ }
+ const locale = request.header('accept-language') || 'default';
+ // Round the current time to the start of the hour.
+ const timestampHour = dayjs().startOf('hour').format('YYYY-MM-DDTHH');
+ return `${userAgent}-${ip}-${locale}-${timestampHour}`;
+ }
}
diff --git a/app/Controllers/Http/Submitter/DatasetController.ts b/app/Controllers/Http/Submitter/DatasetController.ts
index 6c28008..d7409a8 100644
--- a/app/Controllers/Http/Submitter/DatasetController.ts
+++ b/app/Controllers/Http/Submitter/DatasetController.ts
@@ -8,6 +8,7 @@ import Description from '#models/description';
import Language from '#models/language';
import Coverage from '#models/coverage';
import Collection from '#models/collection';
+import CollectionRole from '#models/collection_role';
import dayjs from 'dayjs';
import Person from '#models/person';
import db from '@adonisjs/lucid/services/db';
@@ -501,7 +502,7 @@ export default class DatasetController {
}
// save collection
- const collection: Collection | null = await Collection.query().where('id', 21).first();
+ const collection: Collection | null = await Collection.query().where('id', 594).first();
collection && (await dataset.useTransaction(trx).related('collections').attach([collection.id]));
// save coverage
@@ -545,7 +546,7 @@ export default class DatasetController {
overwrite: true, // overwrite in case of conflict
disk: 'local',
});
-
+
// save file metadata into db
const newFile = new File();
newFile.pathName = `${datasetFolder}/${fileName}`;
@@ -1183,16 +1184,16 @@ export default class DatasetController {
const datasetFolder = `files/${params.id}`;
// const folderExists = await drive.use('local').exists(datasetFolder);
// if (folderExists) {
- // const dirListing = drive.list(datasetFolder);
- // const folderContents = await dirListing.toArray();
- // if (folderContents.length === 0) {
- // await drive.delete(datasetFolder);
- // }
- await drive.use('local').deleteAll(datasetFolder);
- // delete dataset wirh relation in db
- await dataset.delete();
- session.flash({ message: 'You have deleted 1 dataset!' });
- return response.redirect().toRoute('dataset.list');
+ // const dirListing = drive.list(datasetFolder);
+ // const folderContents = await dirListing.toArray();
+ // if (folderContents.length === 0) {
+ // await drive.delete(datasetFolder);
+ // }
+ await drive.use('local').deleteAll(datasetFolder);
+ // delete dataset wirh relation in db
+ await dataset.delete();
+ session.flash({ message: 'You have deleted 1 dataset!' });
+ return response.redirect().toRoute('dataset.list');
// } else {
// // session.flash({
// // warning: `You cannot delete this dataset! Invalid server_state: "${dataset.server_state}"!`,
@@ -1209,7 +1210,7 @@ export default class DatasetController {
throw error;
} else if (error instanceof Exception) {
// General exception handling
- session.flash({ error: error.message});
+ session.flash({ error: error.message });
return response.redirect().back();
} else {
session.flash({ error: 'An error occurred while deleting the dataset.' });
@@ -1217,4 +1218,34 @@ export default class DatasetController {
}
}
}
+
+ public async categorize({ inertia, request, response }: HttpContext) {
+ const id = request.param('id');
+ // Preload dataset and its "collections" relation
+ const dataset = await Dataset.query().where('id', id).preload('collections').firstOrFail();
+ const validStates = ['inprogress', 'rejected_editor'];
+ if (!validStates.includes(dataset.server_state)) {
+ // session.flash('errors', 'Invalid server state!');
+ return response
+ .flash(
+ 'warning',
+ `Invalid server state. Dataset with id ${id} cannot be edited. Datset has server state ${dataset.server_state}.`,
+ )
+ .redirect()
+ .toRoute('dataset.list');
+ }
+
+ const collectionRoles = await CollectionRole.query()
+ .preload('collections', (coll: Collection) => {
+ // preloa only top level collection with noparent_id
+ coll.whereNull('parent_id').orderBy('number', 'asc');
+ })
+ .exec();
+
+ return inertia.render('Submitter/Dataset/Category', {
+ collectionRoles: collectionRoles,
+ dataset: dataset,
+ relatedCollections: dataset.collections,
+ });
+ }
}
diff --git a/app/Library/Oai/ResumptionToken.ts b/app/Library/Oai/ResumptionToken.ts
index 5eca661..56bbea4 100644
--- a/app/Library/Oai/ResumptionToken.ts
+++ b/app/Library/Oai/ResumptionToken.ts
@@ -4,6 +4,7 @@ export default class ResumptionToken {
private _resumptionId = '';
private _startPosition = 0;
private _totalIds = 0;
+ private _queryParams: Record = {};
get key(): string {
return this.metadataPrefix + this.startPosition + this.totalIds;
@@ -48,4 +49,12 @@ export default class ResumptionToken {
set totalIds(totalIds: number) {
this._totalIds = totalIds;
}
+
+ get queryParams(): Record {
+ return this._queryParams;
+ }
+
+ set queryParams(params: Record) {
+ this._queryParams = params;
+ }
}
diff --git a/app/Library/Oai/TokenWorkerContract.ts b/app/Library/Oai/TokenWorkerContract.ts
index 94dae70..2491817 100644
--- a/app/Library/Oai/TokenWorkerContract.ts
+++ b/app/Library/Oai/TokenWorkerContract.ts
@@ -6,6 +6,6 @@ export default abstract class TokenWorkerContract {
abstract connect(): void;
abstract close(): void;
abstract get(key: string): Promise;
- abstract set(token: ResumptionToken): Promise;
+ abstract set(token: ResumptionToken, browserFingerprint: string): Promise;
}
diff --git a/app/Library/Oai/TokenWorkerSerice.ts b/app/Library/Oai/TokenWorkerSerice.ts
index ee63f97..9cb9ccc 100644
--- a/app/Library/Oai/TokenWorkerSerice.ts
+++ b/app/Library/Oai/TokenWorkerSerice.ts
@@ -40,14 +40,64 @@ export default class TokenWorkerService implements TokenWorkerContract {
return result !== undefined && result !== null;
}
- public async set(token: ResumptionToken): Promise {
- const uniqueName = await this.generateUniqueName();
+ /**
+ * Simplified set method that stores the token using a browser fingerprint key.
+ * If the token for that fingerprint already exists and its documentIds match the new token,
+ * then the fingerprint key is simply returned.
+ */
+ public async set(token: ResumptionToken, browserFingerprint: string): Promise {
+ // Generate a 15-digit unique number string based on the fingerprint
+ const uniqueNumberKey = this.createUniqueNumberFromFingerprint(browserFingerprint, token.documentIds, token.totalIds);
+ // Optionally, you could prefix it if desired, e.g. 'rs_' + uniqueNumberKey
+ const fingerprintKey = uniqueNumberKey;
+
+ // const fingerprintKey = `rs_fp_${browserFingerprint}`;
+ const existingTokenString = await this.cache.get(fingerprintKey);
+
+ if (existingTokenString) {
+ const existingToken = this.parseToken(existingTokenString);
+ if (this.arraysAreEqual(existingToken.documentIds, token.documentIds)) {
+ return fingerprintKey;
+ }
+ }
const serialToken = JSON.stringify(token);
- await this.cache.setEx(uniqueName, this.ttl, serialToken);
- return uniqueName;
+ await this.cache.setEx(fingerprintKey, this.ttl, serialToken);
+ return fingerprintKey;
}
+ // Updated helper method to generate a unique key based on fingerprint and documentIds
+ private createUniqueNumberFromFingerprint(browserFingerprint: string, documentIds: number[], totalIds: number): string {
+ // Combine the fingerprint, document IDs and totalIds to produce the input string
+ const combined = browserFingerprint + ':' + documentIds.join('-') + ':' + totalIds;
+ // Simple hash algorithm
+ let hash = 0;
+ for (let i = 0; i < combined.length; i++) {
+ hash = (hash << 5) - hash + combined.charCodeAt(i);
+ hash |= 0; // Convert to 32-bit integer
+ }
+ // Ensure positive number and limit it to at most 15 digits
+ const positiveHash = Math.abs(hash) % 1000000000000000;
+ // Pad with trailing zeros to ensure a 15-digit string
+ return positiveHash.toString().padEnd(15, '0');
+ }
+
+ // Add a helper function to compare two arrays of numbers with identical order
+ private arraysAreEqual(arr1: number[], arr2: number[]): boolean {
+ if (arr1.length !== arr2.length) {
+ return false;
+ }
+ return arr1.every((num, index) => num === arr2[index]);
+ }
+
+ // public async set(token: ResumptionToken): Promise {
+ // const uniqueName = await this.generateUniqueName();
+
+ // const serialToken = JSON.stringify(token);
+ // await this.cache.setEx(uniqueName, this.ttl, serialToken);
+ // return uniqueName;
+ // }
+
private async generateUniqueName(): Promise {
let fc = 0;
const uniqueId = dayjs().unix().toString();
diff --git a/app/models/dataset.ts b/app/models/dataset.ts
index 73ca3a0..1233a28 100644
--- a/app/models/dataset.ts
+++ b/app/models/dataset.ts
@@ -209,6 +209,15 @@ export default class Dataset extends DatasetExtension {
return mainTitle ? mainTitle.value : null;
}
+ @computed({
+ serializeAs: 'doi_identifier',
+ })
+ public get doiIdentifier() {
+ // return `${this.firstName} ${this.lastName}`;
+ const identifier: DatasetIdentifier = this.identifier;
+ return identifier ? identifier.value : null;
+ }
+
@manyToMany(() => Person, {
pivotForeignKey: 'document_id',
pivotRelatedForeignKey: 'person_id',
diff --git a/app/models/person.ts b/app/models/person.ts
index 3feff8a..4e6b60b 100644
--- a/app/models/person.ts
+++ b/app/models/person.ts
@@ -51,7 +51,7 @@ export default class Person extends BaseModel {
serializeAs: 'name',
})
public get fullName() {
- return `${this.firstName} ${this.lastName}`;
+ return [this.firstName, this.lastName].filter(Boolean).join(' ');
}
// @computed()
@@ -64,10 +64,13 @@ export default class Person extends BaseModel {
// return '2023-03-21 08:45:00';
// }
- @computed()
+
+ @computed({
+ serializeAs: 'dataset_count',
+ })
public get datasetCount() {
const stock = this.$extras.datasets_count; //my pivot column name was "stock"
- return stock;
+ return Number(stock);
}
@computed()
diff --git a/commands/validate_checksum.ts b/commands/validate_checksum.ts
index a2d8096..a11b38b 100644
--- a/commands/validate_checksum.ts
+++ b/commands/validate_checksum.ts
@@ -88,7 +88,7 @@ export default class ValidateChecksum extends BaseCommand {
);
// Construct the file path
- const filePath = '/storage/app/public/' + file.pathName;
+ const filePath = '/storage/app/data/' + file.pathName;
try {
// Calculate the MD5 checksum of the file
diff --git a/config/app.ts b/config/app.ts
index 23ad925..c0e7b2b 100644
--- a/config/app.ts
+++ b/config/app.ts
@@ -80,7 +80,8 @@ export const http = defineConfig({
| headers.
|
*/
- trustProxy: proxyAddr.compile('loopback'),
+ // trustProxy: proxyAddr.compile('loopback'),
+ trustProxy: proxyAddr.compile(['127.0.0.1', '::1/128']),
/*
|--------------------------------------------------------------------------
diff --git a/database/migrations/acl_4_accounts.ts b/database/migrations/acl_4_accounts.ts
index ba2373f..1237635 100644
--- a/database/migrations/acl_4_accounts.ts
+++ b/database/migrations/acl_4_accounts.ts
@@ -18,6 +18,7 @@ export default class Accounts extends BaseSchema {
table.text("two_factor_recovery_codes").nullable();
table.smallint('state').nullable();
table.bigint('last_counter').nullable();
+ table.string('avatar').nullable();
});
}
@@ -43,6 +44,7 @@ export default class Accounts extends BaseSchema {
// two_factor_recovery_codes text COLLATE pg_catalog."default",
// state smallint,
// last_counter bigint,
+// avatar character varying(255),
// )
// ALTER TABLE gba.accounts
@@ -85,3 +87,6 @@ export default class Accounts extends BaseSchema {
// GRANT ALL ON SEQUENCE gba.totp_secrets_id_seq TO tethys_admin;
// ALTER TABLE gba.totp_secrets ALTER COLUMN id SET DEFAULT nextval('gba.totp_secrets_id_seq');
+
+
+// ALTER TABLE "accounts" ADD COLUMN "avatar" VARCHAR(255) NULL
diff --git a/database/migrations/dataset_7_collections.ts b/database/migrations/dataset_7_collections.ts
index 7e2b3a9..4fe4b8b 100644
--- a/database/migrations/dataset_7_collections.ts
+++ b/database/migrations/dataset_7_collections.ts
@@ -54,3 +54,8 @@ export default class Collections extends BaseSchema {
// ON UPDATE CASCADE
// ON DELETE CASCADE
// )
+
+
+// change to normal intzeger:
+// ALTER TABLE collections ALTER COLUMN id DROP DEFAULT;
+// DROP SEQUENCE IF EXISTS collections_id_seq;
diff --git a/package-lock.json b/package-lock.json
index 7baeb0a..528ae02 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -180,9 +180,9 @@
}
},
"node_modules/@adonisjs/auth": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/@adonisjs/auth/-/auth-9.3.1.tgz",
- "integrity": "sha512-FQ1ylsH/PRjqMsnjtplKgcWM7CEfmCGuIRbj0lFzTb9xajRTjjgBLWNIhUW/NocmkZP2T2rjV0TnDT1tQUe44Q==",
+ "version": "9.3.2",
+ "resolved": "https://registry.npmjs.org/@adonisjs/auth/-/auth-9.3.2.tgz",
+ "integrity": "sha512-ZaOeSEsCMZkXlfS3YYp2fXh6Eri/uq87mHmhW/uN8/Iww7VlpJbaacGokwHk1gBvU3hScYNVYwiazn3jkcNygw==",
"license": "MIT",
"dependencies": {
"@adonisjs/presets": "^2.6.4",
@@ -483,16 +483,16 @@
}
},
"node_modules/@adonisjs/http-server": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/@adonisjs/http-server/-/http-server-7.4.0.tgz",
- "integrity": "sha512-2Me8ytUu0Sm0jYJs2SAiYQX3ECF6clOJwPE04cswsAwEnqSFLZkflD3c6rApjLjZO6P1wFlo090HNaZCFrlcMQ==",
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@adonisjs/http-server/-/http-server-7.5.0.tgz",
+ "integrity": "sha512-krO0c1doG20sKUWOtreHbT9mDSmNah4aIG+xp3fRKwpoCxDRao1wQCN4qtpsUJVVJH/qzx4p1cC6kQiJsJrCfg==",
"license": "MIT",
"dependencies": {
"@paralleldrive/cuid2": "^2.2.2",
- "@poppinss/macroable": "^1.0.3",
+ "@poppinss/macroable": "^1.0.4",
"@poppinss/matchit": "^3.1.2",
- "@poppinss/middleware": "^3.2.4",
- "@poppinss/utils": "^6.8.3",
+ "@poppinss/middleware": "^3.2.5",
+ "@poppinss/utils": "^6.9.2",
"@sindresorhus/is": "^7.0.1",
"accepts": "^1.3.8",
"content-disposition": "^0.5.4",
@@ -504,7 +504,7 @@
"mime-types": "^2.1.35",
"on-finished": "^2.4.1",
"proxy-addr": "^2.0.7",
- "qs": "^6.13.1",
+ "qs": "^6.14.0",
"tmp-cache": "^1.1.0",
"type-is": "^1.6.18",
"vary": "^1.1.2",
@@ -1331,9 +1331,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
- "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz",
+ "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==",
"cpu": [
"ppc64"
],
@@ -1347,9 +1347,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
- "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz",
+ "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==",
"cpu": [
"arm"
],
@@ -1363,9 +1363,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
- "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz",
+ "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==",
"cpu": [
"arm64"
],
@@ -1379,9 +1379,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
- "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz",
+ "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==",
"cpu": [
"x64"
],
@@ -1395,9 +1395,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
- "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz",
+ "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==",
"cpu": [
"arm64"
],
@@ -1411,9 +1411,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
- "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz",
+ "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==",
"cpu": [
"x64"
],
@@ -1427,9 +1427,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
- "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz",
+ "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==",
"cpu": [
"arm64"
],
@@ -1443,9 +1443,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
- "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz",
+ "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==",
"cpu": [
"x64"
],
@@ -1459,9 +1459,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
- "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz",
+ "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==",
"cpu": [
"arm"
],
@@ -1475,9 +1475,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
- "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz",
+ "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==",
"cpu": [
"arm64"
],
@@ -1491,9 +1491,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
- "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz",
+ "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==",
"cpu": [
"ia32"
],
@@ -1507,9 +1507,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
- "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz",
+ "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==",
"cpu": [
"loong64"
],
@@ -1523,9 +1523,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
- "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz",
+ "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==",
"cpu": [
"mips64el"
],
@@ -1539,9 +1539,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
- "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz",
+ "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==",
"cpu": [
"ppc64"
],
@@ -1555,9 +1555,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
- "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz",
+ "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==",
"cpu": [
"riscv64"
],
@@ -1571,9 +1571,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
- "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz",
+ "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==",
"cpu": [
"s390x"
],
@@ -1587,9 +1587,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
- "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz",
+ "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==",
"cpu": [
"x64"
],
@@ -1603,9 +1603,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
- "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz",
+ "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==",
"cpu": [
"arm64"
],
@@ -1619,9 +1619,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
- "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz",
+ "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==",
"cpu": [
"x64"
],
@@ -1635,9 +1635,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
- "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz",
+ "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==",
"cpu": [
"arm64"
],
@@ -1651,9 +1651,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
- "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz",
+ "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==",
"cpu": [
"x64"
],
@@ -1667,9 +1667,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
- "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz",
+ "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==",
"cpu": [
"x64"
],
@@ -1683,9 +1683,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
- "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz",
+ "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==",
"cpu": [
"arm64"
],
@@ -1699,9 +1699,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
- "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz",
+ "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==",
"cpu": [
"ia32"
],
@@ -1715,9 +1715,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
- "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz",
+ "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==",
"cpu": [
"x64"
],
@@ -1823,9 +1823,9 @@
}
},
"node_modules/@faker-js/faker": {
- "version": "9.5.0",
- "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.5.0.tgz",
- "integrity": "sha512-3qbjLv+fzuuCg3umxc9/7YjrEXNaKwHgmig949nfyaTx8eL4FAsvFbu+1JcFUj1YAXofhaDn6JdEUBTYuk0Ssw==",
+ "version": "9.5.1",
+ "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.5.1.tgz",
+ "integrity": "sha512-0fzMEDxkExR2cn731kpDaCCnBGBUOIXEi2S1N5l8Hltp6aPf4soTMJ+g4k8r2sI5oB+rpwIW8Uy/6jkwGpnWPg==",
"funding": [
{
"type": "opencollective",
@@ -1839,16 +1839,22 @@
}
},
"node_modules/@fontsource/archivo-black": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@fontsource/archivo-black/-/archivo-black-5.1.1.tgz",
- "integrity": "sha512-3hmXvgYkXDsQ7msb+YrwU+6B5j4q7LBfVev1G4T8I5yRcRTo6H8OEA8tf0vULvcAGfOOhl38aRK/2I2+RLE/rQ==",
- "license": "OFL-1.1"
+ "version": "5.2.5",
+ "resolved": "https://registry.npmjs.org/@fontsource/archivo-black/-/archivo-black-5.2.5.tgz",
+ "integrity": "sha512-tdBRFgA0CgxVqj3mBM96aiXRBoOp51X3IW2e8/t59AVr0NwiBcB+c3C+p5dd7Np/UT/vqdmjb/gK/HaFpulhIA==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
},
"node_modules/@fontsource/inter": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.1.1.tgz",
- "integrity": "sha512-weN3E+rq0Xb3Z93VHJ+Rc7WOQX9ETJPTAJ+gDcaMHtjft67L58sfS65rAjC5tZUXQ2FdZ/V1/sSzCwZ6v05kJw==",
- "license": "OFL-1.1"
+ "version": "5.2.5",
+ "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.2.5.tgz",
+ "integrity": "sha512-kbsPKj0S4p44JdYRFiW78Td8Ge2sBVxi/PIBwmih+RpSXUdvS9nbs1HIiuUSPtRMi14CqLEZ/fbk7dj7vni1Sg==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
},
"node_modules/@headlessui/vue": {
"version": "1.7.23",
@@ -1918,9 +1924,9 @@
}
},
"node_modules/@inertiajs/core": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@inertiajs/core/-/core-2.0.3.tgz",
- "integrity": "sha512-JvXzqc2XAt3WgEDMyxCyXO6bDLMCsBjFsYREU1/+3wtNTib7QKwK71+aF+MrhILpz+kRTi29TsLqnbkPHBAZjw==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@inertiajs/core/-/core-2.0.4.tgz",
+ "integrity": "sha512-gCUqpwBRYOhz0hwBDWca2lkk+Mc+36GvbRoE0rEvYFpzQAMMP0xFhH9h8hr7VWTn+vVOZRuDvakI+4cazwtvCg==",
"license": "MIT",
"dependencies": {
"axios": "^1.6.0",
@@ -1949,12 +1955,12 @@
}
},
"node_modules/@inertiajs/vue3": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@inertiajs/vue3/-/vue3-2.0.3.tgz",
- "integrity": "sha512-2ykoHN+yl6CECY7f/O3S95tZRl7JXTnLTKoPMrR64+a7j32LTHucmkfJi8TnVzE46mqLj6gqH60DVVk1lHu1Yg==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@inertiajs/vue3/-/vue3-2.0.4.tgz",
+ "integrity": "sha512-QbVpWHhIEEjbhPoJmUBvt1SxreZmiPgq2gr1bnvhrGcwtGzDoVTN+1sTO5PBX0SebVQhabHHlJS8SzwoxGLgKw==",
"license": "MIT",
"dependencies": {
- "@inertiajs/core": "2.0.3",
+ "@inertiajs/core": "2.0.4",
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0"
},
@@ -2487,9 +2493,9 @@
}
},
"node_modules/@opensearch-project/opensearch": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/@opensearch-project/opensearch/-/opensearch-3.3.0.tgz",
- "integrity": "sha512-EJSeyVEy4fMLsbIoCYisz2VFRRXBfkxKSEBVSFEzXMT71pAF26+XhQiv+nhzqAu5w18qS1bhAAIMUriT5bThNQ==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@opensearch-project/opensearch/-/opensearch-3.4.0.tgz",
+ "integrity": "sha512-NdVWpBxa2mA8fQvn3jWgoDnIHk/xNtxrPA8joQVBP75CJMEr/379wzDpnIq+HZn3E0zyE0VQOxDV+LbbyGkefA==",
"license": "Apache-2.0",
"dependencies": {
"aws4": "^1.11.0",
@@ -2829,9 +2835,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
- "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz",
+ "integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==",
"cpu": [
"arm"
],
@@ -2842,9 +2848,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
- "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz",
+ "integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==",
"cpu": [
"arm64"
],
@@ -2855,9 +2861,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
- "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz",
+ "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==",
"cpu": [
"arm64"
],
@@ -2868,9 +2874,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
- "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz",
+ "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==",
"cpu": [
"x64"
],
@@ -2881,9 +2887,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
- "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz",
+ "integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==",
"cpu": [
"arm64"
],
@@ -2894,9 +2900,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
- "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz",
+ "integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==",
"cpu": [
"x64"
],
@@ -2907,9 +2913,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
- "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz",
+ "integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==",
"cpu": [
"arm"
],
@@ -2920,9 +2926,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
- "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz",
+ "integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==",
"cpu": [
"arm"
],
@@ -2933,9 +2939,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
- "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz",
+ "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==",
"cpu": [
"arm64"
],
@@ -2946,9 +2952,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
- "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz",
+ "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==",
"cpu": [
"arm64"
],
@@ -2959,9 +2965,9 @@
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
- "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz",
+ "integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==",
"cpu": [
"loong64"
],
@@ -2972,9 +2978,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
- "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz",
+ "integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==",
"cpu": [
"ppc64"
],
@@ -2985,9 +2991,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
- "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz",
+ "integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==",
"cpu": [
"riscv64"
],
@@ -2998,9 +3004,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
- "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz",
+ "integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==",
"cpu": [
"s390x"
],
@@ -3011,9 +3017,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
- "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz",
+ "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==",
"cpu": [
"x64"
],
@@ -3024,9 +3030,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
- "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz",
+ "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==",
"cpu": [
"x64"
],
@@ -3037,9 +3043,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
- "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz",
+ "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==",
"cpu": [
"arm64"
],
@@ -3050,9 +3056,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
- "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz",
+ "integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==",
"cpu": [
"ia32"
],
@@ -3063,9 +3069,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
- "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz",
+ "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==",
"cpu": [
"x64"
],
@@ -3121,9 +3127,9 @@
"license": "CC0-1.0"
},
"node_modules/@swc/wasm": {
- "version": "1.10.18",
- "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.10.18.tgz",
- "integrity": "sha512-TgoMYjQ2/9UfUaw7WuKj7Svew6kaNOqkjV4nKoc2tf34e+7GxL2KPoXvM2b1RkPxNocv85glcQpS9KMk8FqpBA==",
+ "version": "1.11.7",
+ "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.11.7.tgz",
+ "integrity": "sha512-OS11ClTQFldQJRX1RRsT3B3MQVplAdMthXH6ha7WCNAsoP3Rtzq/MUJ7LpkBIUV9Ty8Xk5lPzfeRNscFQ6sFEw==",
"dev": true,
"license": "Apache-2.0"
},
@@ -3153,9 +3159,9 @@
}
},
"node_modules/@tanstack/virtual-core": {
- "version": "3.13.0",
- "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.0.tgz",
- "integrity": "sha512-NBKJP3OIdmZY3COJdWkSonr50FMVIi+aj5ZJ7hI/DTpEKg2RMfo/KvP8A3B/zOSpMgIe52B5E2yn7rryULzA6g==",
+ "version": "3.13.2",
+ "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.2.tgz",
+ "integrity": "sha512-Qzz4EgzMbO5gKrmqUondCjiHcuu4B1ftHb0pjCut661lXZdGoHeze9f/M8iwsK1t5LGR6aNuNGU7mxkowaW6RQ==",
"dev": true,
"license": "MIT",
"funding": {
@@ -3164,13 +3170,13 @@
}
},
"node_modules/@tanstack/vue-virtual": {
- "version": "3.13.0",
- "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.13.0.tgz",
- "integrity": "sha512-EPgcTc41KGJAK2N2Ux2PeUnG3cPpdkldTib05nwq+0zdS2Ihpbq8BsWXz/eXPyNc5noDBh1GBgAe36yMYiW6WA==",
+ "version": "3.13.2",
+ "resolved": "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.13.2.tgz",
+ "integrity": "sha512-z4swzjdhzCh95n9dw9lTvw+t3iwSkYRlVkYkra3C9mul/m5fTzHR7KmtkwH4qXMTXGJUbngtC/bz2cHQIHkO8g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@tanstack/virtual-core": "3.13.0"
+ "@tanstack/virtual-core": "3.13.2"
},
"funding": {
"type": "github",
@@ -3181,17 +3187,17 @@
}
},
"node_modules/@tokenizer/inflate": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.6.tgz",
- "integrity": "sha512-SdR/i05U7Xhnsq36iyIq/ZiGGw4PKzw4ww3bOq80Pjj4wyXpqyTcgrgdDdGlcatnlvzNJx8CQw3hp6QZvkUwhA==",
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz",
+ "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==",
"license": "MIT",
"dependencies": {
- "debug": "^4.3.7",
+ "debug": "^4.4.0",
"fflate": "^0.8.2",
"token-types": "^6.0.0"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
},
"funding": {
"type": "github",
@@ -3328,9 +3334,9 @@
"license": "MIT"
},
"node_modules/@types/chai": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.1.tgz",
- "integrity": "sha512-5T8ajsg3M/FOncpLYW7sdOcD6yf4+722sze/tc4KQV0P8Z2rAr3SAuHCIkYmYpt8VbcQlnz8SxlOlPQYefe4cA==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.0.tgz",
+ "integrity": "sha512-FWnQYdrG9FAC8KgPVhDFfrPL1FBsL3NtIt2WsxKvwu/61K6HiuDF3xAb7c7w/k9ML2QOUHcwTgU7dKLFPK6sBg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3560,9 +3566,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "22.13.4",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.4.tgz",
- "integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==",
+ "version": "22.13.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.9.tgz",
+ "integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.20.0"
@@ -3747,9 +3753,9 @@
"license": "MIT"
},
"node_modules/@types/ws": {
- "version": "8.5.14",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
- "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.0.tgz",
+ "integrity": "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4068,9 +4074,9 @@
}
},
"node_modules/@vavite/multibuild/node_modules/@types/node": {
- "version": "18.19.76",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.76.tgz",
- "integrity": "sha512-yvR7Q9LdPz2vGpmpJX5LolrgRdWvB67MJKDPSgIIzpFbaf9a1j/f5DnLp5VDyHGMR0QZHlTr1afsD87QCXFHKw==",
+ "version": "18.19.79",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.79.tgz",
+ "integrity": "sha512-90K8Oayimbctc5zTPHPfZloc/lGVs7f3phUAAMcTgEPtg8kKquGZDERC8K4vkBYkQQh48msiYUslYtxTWvqcAg==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
@@ -4449,9 +4455,9 @@
}
},
"node_modules/acorn": {
- "version": "8.14.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
- "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "version": "8.14.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -4805,9 +4811,9 @@
"license": "MIT"
},
"node_modules/axios": {
- "version": "1.7.9",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
- "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.1.tgz",
+ "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
@@ -5134,13 +5140,13 @@
}
},
"node_modules/call-bound": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
- "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "get-intrinsic": "^1.2.6"
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
@@ -5182,9 +5188,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001700",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz",
- "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==",
+ "version": "1.0.30001702",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001702.tgz",
+ "integrity": "sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA==",
"dev": true,
"funding": [
{
@@ -6347,9 +6353,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.102",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz",
- "integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==",
+ "version": "1.5.112",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.112.tgz",
+ "integrity": "sha512-oen93kVyqSb3l+ziUgzIOlWt/oOuy4zRmpwestMn4rhFWAoFJeFuCVte9F2fASjeZZo7l/Cif9TiyrdW4CwEMA==",
"dev": true,
"license": "ISC"
},
@@ -6522,9 +6528,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.24.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
- "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
+ "version": "0.25.0",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
+ "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -6534,31 +6540,31 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.24.2",
- "@esbuild/android-arm": "0.24.2",
- "@esbuild/android-arm64": "0.24.2",
- "@esbuild/android-x64": "0.24.2",
- "@esbuild/darwin-arm64": "0.24.2",
- "@esbuild/darwin-x64": "0.24.2",
- "@esbuild/freebsd-arm64": "0.24.2",
- "@esbuild/freebsd-x64": "0.24.2",
- "@esbuild/linux-arm": "0.24.2",
- "@esbuild/linux-arm64": "0.24.2",
- "@esbuild/linux-ia32": "0.24.2",
- "@esbuild/linux-loong64": "0.24.2",
- "@esbuild/linux-mips64el": "0.24.2",
- "@esbuild/linux-ppc64": "0.24.2",
- "@esbuild/linux-riscv64": "0.24.2",
- "@esbuild/linux-s390x": "0.24.2",
- "@esbuild/linux-x64": "0.24.2",
- "@esbuild/netbsd-arm64": "0.24.2",
- "@esbuild/netbsd-x64": "0.24.2",
- "@esbuild/openbsd-arm64": "0.24.2",
- "@esbuild/openbsd-x64": "0.24.2",
- "@esbuild/sunos-x64": "0.24.2",
- "@esbuild/win32-arm64": "0.24.2",
- "@esbuild/win32-ia32": "0.24.2",
- "@esbuild/win32-x64": "0.24.2"
+ "@esbuild/aix-ppc64": "0.25.0",
+ "@esbuild/android-arm": "0.25.0",
+ "@esbuild/android-arm64": "0.25.0",
+ "@esbuild/android-x64": "0.25.0",
+ "@esbuild/darwin-arm64": "0.25.0",
+ "@esbuild/darwin-x64": "0.25.0",
+ "@esbuild/freebsd-arm64": "0.25.0",
+ "@esbuild/freebsd-x64": "0.25.0",
+ "@esbuild/linux-arm": "0.25.0",
+ "@esbuild/linux-arm64": "0.25.0",
+ "@esbuild/linux-ia32": "0.25.0",
+ "@esbuild/linux-loong64": "0.25.0",
+ "@esbuild/linux-mips64el": "0.25.0",
+ "@esbuild/linux-ppc64": "0.25.0",
+ "@esbuild/linux-riscv64": "0.25.0",
+ "@esbuild/linux-s390x": "0.25.0",
+ "@esbuild/linux-x64": "0.25.0",
+ "@esbuild/netbsd-arm64": "0.25.0",
+ "@esbuild/netbsd-x64": "0.25.0",
+ "@esbuild/openbsd-arm64": "0.25.0",
+ "@esbuild/openbsd-x64": "0.25.0",
+ "@esbuild/sunos-x64": "0.25.0",
+ "@esbuild/win32-arm64": "0.25.0",
+ "@esbuild/win32-ia32": "0.25.0",
+ "@esbuild/win32-x64": "0.25.0"
}
},
"node_modules/escalade": {
@@ -6659,9 +6665,9 @@
}
},
"node_modules/eslint-config-prettier": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
- "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.2.tgz",
+ "integrity": "sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg==",
"dev": true,
"license": "MIT",
"bin": {
@@ -7121,9 +7127,9 @@
}
},
"node_modules/fastq": {
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
- "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
"license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
@@ -7178,9 +7184,9 @@
}
},
"node_modules/file-type": {
- "version": "20.1.0",
- "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.1.0.tgz",
- "integrity": "sha512-XoxU+lETfCf+bYK3SXkxFusAvmtYQl1u/ZC4zw1DBLEsHUvh339uwYucgQnnSMz1mRCWYJrCzsbJJ95hsQbZ8A==",
+ "version": "20.4.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.4.0.tgz",
+ "integrity": "sha512-+NZeExsi4G6EWaMbSmvBeCoqsj9EqNvOj1o/0uPVPW4O51FSCmxFlNEp/PitsqBMCbax4cGoaYmnUK5FLTuG4g==",
"license": "MIT",
"dependencies": {
"@tokenizer/inflate": "^0.2.6",
@@ -7278,9 +7284,9 @@
}
},
"node_modules/find-up-simple": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz",
- "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz",
+ "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7443,13 +7449,13 @@
}
},
"node_modules/foreground-child": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
- "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"dev": true,
"license": "ISC",
"dependencies": {
- "cross-spawn": "^7.0.0",
+ "cross-spawn": "^7.0.6",
"signal-exit": "^4.0.1"
},
"engines": {
@@ -7717,17 +7723,17 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
- "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
+ "call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
+ "es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
- "get-proto": "^1.0.0",
+ "get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
@@ -8479,9 +8485,9 @@
}
},
"node_modules/ioredis": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.5.0.tgz",
- "integrity": "sha512-7CutT89g23FfSa8MDoIFs2GYYa0PaNiW/OrT+nRyjRXHDZd17HmIgy+reOQ/yhh72NznNjGuS8kbCAcA4Ro4mw==",
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.0.tgz",
+ "integrity": "sha512-tBZlIIWbndeWBWCXWZiqtOF/yxf6yZX3tAlTJ7nfo5jhd6dctNxF7QnYlZLZ1a0o0pDoen7CgZqO+zjNaFbJAg==",
"license": "MIT",
"dependencies": {
"@ioredis/commands": "^1.1.1",
@@ -10169,10 +10175,13 @@
"license": "BlueOak-1.0.0"
},
"node_modules/package-manager-detector": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.9.tgz",
- "integrity": "sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q==",
- "license": "MIT"
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz",
+ "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "quansync": "^0.2.7"
+ }
},
"node_modules/parent-module": {
"version": "1.0.1",
@@ -10873,9 +10882,9 @@
}
},
"node_modules/prettier": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz",
- "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==",
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
+ "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
"dev": true,
"license": "MIT",
"bin": {
@@ -11065,6 +11074,22 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/quansync": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.8.tgz",
+ "integrity": "sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -11437,9 +11462,9 @@
}
},
"node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"license": "MIT",
"engines": {
"iojs": ">=1.0.0",
@@ -11469,9 +11494,9 @@
"license": "MIT"
},
"node_modules/rollup": {
- "version": "4.34.8",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz",
- "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
+ "version": "4.34.9",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz",
+ "integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==",
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.6"
@@ -11484,25 +11509,25 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.34.8",
- "@rollup/rollup-android-arm64": "4.34.8",
- "@rollup/rollup-darwin-arm64": "4.34.8",
- "@rollup/rollup-darwin-x64": "4.34.8",
- "@rollup/rollup-freebsd-arm64": "4.34.8",
- "@rollup/rollup-freebsd-x64": "4.34.8",
- "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
- "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
- "@rollup/rollup-linux-arm64-gnu": "4.34.8",
- "@rollup/rollup-linux-arm64-musl": "4.34.8",
- "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
- "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
- "@rollup/rollup-linux-s390x-gnu": "4.34.8",
- "@rollup/rollup-linux-x64-gnu": "4.34.8",
- "@rollup/rollup-linux-x64-musl": "4.34.8",
- "@rollup/rollup-win32-arm64-msvc": "4.34.8",
- "@rollup/rollup-win32-ia32-msvc": "4.34.8",
- "@rollup/rollup-win32-x64-msvc": "4.34.8",
+ "@rollup/rollup-android-arm-eabi": "4.34.9",
+ "@rollup/rollup-android-arm64": "4.34.9",
+ "@rollup/rollup-darwin-arm64": "4.34.9",
+ "@rollup/rollup-darwin-x64": "4.34.9",
+ "@rollup/rollup-freebsd-arm64": "4.34.9",
+ "@rollup/rollup-freebsd-x64": "4.34.9",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.34.9",
+ "@rollup/rollup-linux-arm-musleabihf": "4.34.9",
+ "@rollup/rollup-linux-arm64-gnu": "4.34.9",
+ "@rollup/rollup-linux-arm64-musl": "4.34.9",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.34.9",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.34.9",
+ "@rollup/rollup-linux-riscv64-gnu": "4.34.9",
+ "@rollup/rollup-linux-s390x-gnu": "4.34.9",
+ "@rollup/rollup-linux-x64-gnu": "4.34.9",
+ "@rollup/rollup-linux-x64-musl": "4.34.9",
+ "@rollup/rollup-win32-arm64-msvc": "4.34.9",
+ "@rollup/rollup-win32-ia32-msvc": "4.34.9",
+ "@rollup/rollup-win32-x64-msvc": "4.34.9",
"fsevents": "~2.3.2"
}
},
@@ -12788,9 +12813,9 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.11",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz",
- "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==",
+ "version": "5.3.13",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.13.tgz",
+ "integrity": "sha512-JG3pBixF6kx2o0Yfz2K6pqh72DpwTI08nooHd06tcj5WyIt5SsSiUYqRT+kemrGUNSuSzVhwfZ28aO8gogajNQ==",
"dev": true,
"license": "MIT",
"peer": true,
@@ -13176,9 +13201,9 @@
}
},
"node_modules/type-fest": {
- "version": "4.35.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz",
- "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz",
+ "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==",
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=16"
@@ -13285,9 +13310,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
- "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
"dev": true,
"funding": [
{
@@ -13394,13 +13419,13 @@
}
},
"node_modules/vite": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.1.tgz",
- "integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz",
+ "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==",
"license": "MIT",
"dependencies": {
- "esbuild": "^0.24.2",
- "postcss": "^8.5.2",
+ "esbuild": "^0.25.0",
+ "postcss": "^8.5.3",
"rollup": "^4.30.1"
},
"bin": {
@@ -14073,9 +14098,9 @@
"license": "ISC"
},
"node_modules/ws": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
- "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
"dev": true,
"license": "MIT",
"engines": {
diff --git a/resources/js/Components/AsideMenuItem.vue b/resources/js/Components/AsideMenuItem.vue
index 4e52d40..52e4bbc 100644
--- a/resources/js/Components/AsideMenuItem.vue
+++ b/resources/js/Components/AsideMenuItem.vue
@@ -1,162 +1,143 @@
-
-
+
+
diff --git a/resources/js/Components/CardBoxClient.vue b/resources/js/Components/CardBoxClient.vue
index bf17b32..b89ed7a 100644
--- a/resources/js/Components/CardBoxClient.vue
+++ b/resources/js/Components/CardBoxClient.vue
@@ -1,6 +1,6 @@
-
+// const pillText = computed(() => props.text ?? `${props.progress}%`);
+//
@@ -83,7 +87,17 @@ const pillText = computed(() => props.text ?? `${props.progress}%`);
-
+
+
+
+
diff --git a/resources/js/Components/CardBoxDataset.vue b/resources/js/Components/CardBoxDataset.vue
new file mode 100644
index 0000000..72d3f4d
--- /dev/null
+++ b/resources/js/Components/CardBoxDataset.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+ {{ displayTitle }}
+
+
+
+ View Publication
+
+ • {{ relativeDate }}
+
+
+
+
{{ props.dataset.type }}
+
+
+
+
+
diff --git a/resources/js/Components/TableSampleClients.vue b/resources/js/Components/TableSampleClients.vue
index f2a062a..9fb1c01 100644
--- a/resources/js/Components/TableSampleClients.vue
+++ b/resources/js/Components/TableSampleClients.vue
@@ -1,17 +1,19 @@
-
-
- Lorem ipsum dolor sit amet adipiscing elit
- This is sample modal
-
-
-
- Lorem ipsum dolor sit amet adipiscing elit
- This is sample modal
-
-
-
-
- {{ checkedRow.name }}
-
+
+
+
Login: {{ currentClient.login }}
+
Email: {{ currentClient.email }}
+
Created: {{ currentClient?.created_at ? dayjs(currentClient.created_at).format('MMM D, YYYY h:mm A') : 'N/A' }}
+
+
+
-
-
-
- |
- |
- Name |
- Email |
- City |
- Progress |
- Created |
- |
-
-
-
-
-
-
-
- |
-
- {{ client.name }}
- |
-
- {{ client.email }}
- |
-
- {{ client.city }}
- |
-
-
- |
-
- {{ client.created }}
- |
-
-
-
-
-
- |
-
-
-
-
-
-
-
-
- Page {{ currentPageHuman }} of {{ numPages }}
-
-
-
\ No newline at end of file
+
+
+ {{ checkedRow.login }}
+
+
+
+
+
+
+ |
+ |
+ Login |
+ Email |
+ Created |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+ {{ client.login }}
+ |
+
+ {{ client.email }}
+ |
+
+
+ {{ client.created_at ? dayjs(client.created_at).format('MMM D, YYYY h:mm A') : 'N/A' }}
+
+ |
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ Page {{ currentPageHuman }} of {{ numPages }}
+
+
+
diff --git a/resources/js/Components/UserAvatar.vue b/resources/js/Components/UserAvatar.vue
index 8aedd1a..6484d83 100644
--- a/resources/js/Components/UserAvatar.vue
+++ b/resources/js/Components/UserAvatar.vue
@@ -1,4 +1,4 @@
-
-
mainService.datasets);
:number="datasets.length"
label="Publications"
/>
-
@@ -118,25 +107,19 @@ const datasets = computed(() => mainService.datasets);
:name="client.name"
:email="client.email"
:date="client.created_at"
- :text="client.datasetCount"
+ :text="client.identifier_orcid"
+ :count="client.dataset_count"
/>
-
-
-
@@ -146,33 +129,13 @@ const datasets = computed(() => mainService.datasets);
-
+
- Responsive table. Collapses on mobile
+
-
-
-
diff --git a/resources/js/Pages/Editor/Dataset/Doi.vue b/resources/js/Pages/Editor/Dataset/Doi.vue
index 412622b..096afcb 100644
--- a/resources/js/Pages/Editor/Dataset/Doi.vue
+++ b/resources/js/Pages/Editor/Dataset/Doi.vue
@@ -26,17 +26,6 @@ const errors: Ref = computed(() => {
return usePage().props.errors;
});
-// const form = useForm({
-// preferred_reviewer: '',
-// preferred_reviewer_email: '',
-// preferation: 'yes_preferation',
-
-// // preferation: '',
-// // isPreferationRequired: false,
-// });
-
-// const isPreferationRequired = computed(() => form.preferation === 'yes_preferation');
-
const handleSubmit = async (e) => {
e.preventDefault();
// Notification.showInfo(`doi implementation is in developement. Create DOI for dataset ${props.dataset.publish_id} later on`);
diff --git a/resources/js/Pages/Map.vue b/resources/js/Pages/Map.vue
index 15d40e3..4c19625 100644
--- a/resources/js/Pages/Map.vue
+++ b/resources/js/Pages/Map.vue
@@ -1,13 +1,13 @@
diff --git a/resources/js/Pages/Submitter/Dataset/Index.vue b/resources/js/Pages/Submitter/Dataset/Index.vue
index 0cf8ca5..65ab0b1 100644
--- a/resources/js/Pages/Submitter/Dataset/Index.vue
+++ b/resources/js/Pages/Submitter/Dataset/Index.vue
@@ -2,7 +2,7 @@
// import { Head, Link, useForm, usePage } from '@inertiajs/inertia-vue3';
import { Head, usePage } from '@inertiajs/vue3';
import { ComputedRef } from 'vue';
-import { mdiSquareEditOutline, mdiTrashCan, mdiAlertBoxOutline, mdiLockOpen } from '@mdi/js';
+import { mdiSquareEditOutline, mdiTrashCan, mdiAlertBoxOutline, mdiLockOpen, mdiLibraryShelves } from '@mdi/js';
import { computed } from 'vue';
import LayoutAuthenticated from '@/Layouts/LayoutAuthenticated.vue';
import SectionMain from '@/Components/SectionMain.vue';
@@ -139,7 +139,10 @@ const formatServerState = (state: string) => {
:route-name="stardust.route('dataset.release', [dataset.id])" color="info"
:icon="mdiLockOpen" :label="'Release'" small />
+ color="info" :icon="mdiSquareEditOutline" :label="'Edit'" small />
+
diff --git a/resources/js/Stores/main.ts b/resources/js/Stores/main.ts
index 8d51088..39ca0c0 100644
--- a/resources/js/Stores/main.ts
+++ b/resources/js/Stores/main.ts
@@ -2,6 +2,56 @@ import { defineStore } from 'pinia';
import axios from 'axios';
import { Dataset } from '@/Dataset';
import menu from '@/menu';
+// import type Person from '#models/person';
+
+export interface User {
+ id: number;
+ login: string;
+ firstName: string;
+ lastName: string;
+ email: string;
+ password: string;
+ created_at: DateTime;
+ updatedAt: DateTime;
+ lastLoginAt: DateTime;
+ isActive: boolean;
+ isVerified: boolean;
+ roles: string[];
+ permissions: string[];
+ settings: Record;
+ profile: {
+ avatar: string;
+ bio: string;
+ location: string;
+ website: string;
+ social: {
+ twitter: string;
+ facebook: string;
+ linkedin: string;
+ github: string;
+ }
+ };
+ metadata: Record;
+ verifyPassword: (plainPassword: string) => Promise;
+}
+
+interface DateTime {
+ get: (unit: keyof DateTime) => number;
+ getPossibleOffsets: () => DateTime[];
+ toRelativeCalendar: (options?: ToRelativeCalendarOptions) => string | null;
+ toFormat: (format: string) => string;
+ toISO: () => string;
+ toJSON: () => string;
+ toString: () => string;
+ toLocaleString: (options?: Intl.DateTimeFormatOptions) => string;
+ toUTC: () => DateTime;
+ toLocal: () => DateTime;
+ valueOf: () => number;
+ toMillis: () => number;
+ toSeconds: () => number;
+ toUnixInteger: () => number;
+}
+
export interface Person {
id: number;
@@ -9,10 +59,12 @@ export interface Person {
email: string;
name_type: string;
identifier_orcid: string;
- datasetCount: string;
+ dataset_count: number;
created_at: string;
}
+
+
interface TransactionItem {
amount: number;
account: string;
@@ -61,7 +113,7 @@ export const MainService = defineStore('main', {
isFieldFocusRegistered: false,
/* Sample data for starting dashboard(commonly used) */
- clients: [],
+ clients: [] as Array,
history: [] as Array,
// api based data
@@ -184,7 +236,7 @@ export const MainService = defineStore('main', {
this.totpState = state;
},
- async fetchChartData(year: string) {
+ fetchChartData(year: string) {
// sampleDataKey= authors or datasets
axios
.get(`/api/statistic/${year}`)
diff --git a/resources/js/app.ts b/resources/js/app.ts
index 560b28e..e98664d 100644
--- a/resources/js/app.ts
+++ b/resources/js/app.ts
@@ -8,6 +8,7 @@ import { createPinia } from 'pinia';
import { StyleService } from '@/Stores/style.service';
import { LayoutService } from '@/Stores/layout';
import { LocaleStore } from '@/Stores/locale';
+import { MainService } from './Stores/main';
import { darkModeKey, styleKey } from '@/config';
import type { DefineComponent } from 'vue';
import { resolvePageComponent } from '@adonisjs/inertia/helpers';
@@ -80,7 +81,7 @@ const layoutService = LayoutService(pinia);
const localeService = LocaleStore(pinia);
localeService.initializeLocale();
-// const mainService = MainService(pinia);
+const mainService = MainService(pinia);
// mainService.setUser(user);
/* App style */
@@ -90,6 +91,12 @@ styleService.setStyle(localStorage[styleKey] ?? 'basic');
if ((!localStorage[darkModeKey] && window.matchMedia('(prefers-color-scheme: dark)').matches) || localStorage[darkModeKey] === '1') {
styleService.setDarkMode(true);
}
+// mainService.fetch('clients');
+// mainService.fetch('history');
+mainService.fetchApi('clients');
+mainService.fetchApi('authors');
+mainService.fetchApi('datasets');
+mainService.fetchChartData("2022");
/* Collapse mobile aside menu on route change */
Inertia.on('navigate', () => {
diff --git a/resources/js/menu.ts b/resources/js/menu.ts
index b8fa697..544b0cb 100644
--- a/resources/js/menu.ts
+++ b/resources/js/menu.ts
@@ -12,6 +12,7 @@ import {
mdiShieldCrownOutline,
mdiLicense,
mdiFileDocument,
+ mdiLibraryShelves
} from '@mdi/js';
export default [
@@ -111,6 +112,11 @@ export default [
icon: mdiPublish,
label: 'Create Dataset',
},
+ // {
+ // route: 'dataset.categorize',
+ // icon: mdiLibraryShelves,
+ // label: 'Library Classification',
+ // },
],
},
{
diff --git a/start/routes.ts b/start/routes.ts
index af9c289..b93a5de 100644
--- a/start/routes.ts
+++ b/start/routes.ts
@@ -314,9 +314,11 @@ router
.as('dataset.deleteUpdate')
.use([middleware.auth(), middleware.can(['dataset-delete'])]);
router.get('/person', [PersonController, 'index']).as('person.index').use([middleware.auth()]);
- router.get('/dataset/categorize', ({ inertia }: HttpContext) => {
- return inertia.render('Submitter/Dataset/Category');
- });
+ router
+ .get('/dataset/:id/categorize', [DatasetController, 'categorize'])
+ .as('dataset.categorize')
+ .where('id', router.matchers.number())
+ .use([middleware.auth(), middleware.can(['dataset-edit'])]);
})
.prefix('submitter');
diff --git a/start/routes/api.ts b/start/routes/api.ts
index e417e3f..32bc6c2 100644
--- a/start/routes/api.ts
+++ b/start/routes/api.ts
@@ -6,10 +6,12 @@ import HomeController from '#controllers/Http/Api/HomeController';
import FileController from '#controllers/Http/Api/FileController';
import AvatarController from '#controllers/Http/Api/AvatarController';
import UserController from '#controllers/Http/Api/UserController';
+import CollectionsController from '#controllers/Http/Api/collections_controller';
import { middleware } from '../kernel.js';
// API
router
.group(() => {
+ router.get('clients', [UserController, 'getSubmitters']).as('client.index');
router.get('authors', [AuthorsController, 'index']).as('author.index');
router.get('datasets', [DatasetController, 'index']).as('dataset.index');
router.get('persons', [AuthorsController, 'persons']).as('author.persons');
@@ -32,6 +34,8 @@ router
.post('/twofactor_backupcodes/settings/create', [UserController, 'createCodes'])
.as('apps.twofactor_backupcodes.create')
.use(middleware.auth());
+
+ router.get('collections/:id', [CollectionsController, 'show']).as('collection.show')
})
// .namespace('App/Controllers/Http/Api')
.prefix('api');
diff --git a/start/rules/referenceValidation.ts b/start/rules/referenceValidation.ts
index 531418c..dd4030a 100644
--- a/start/rules/referenceValidation.ts
+++ b/start/rules/referenceValidation.ts
@@ -19,12 +19,63 @@ async function checkDoiExists(doi: string): Promise {
}
// Function to check if ISBN exists using the Open Library API
+// async function checkIsbnExists(isbn: string): Promise {
+// try {
+// const response = await axios.get(`https://isbnsearch.org/isbn/${isbn}`);
+// return response.status === 200 && response.data.includes('ISBN'); // Check if response contains ISBN information
+// } catch (error) {
+// return false; // If request fails, ISBN does not exist
+// }
+// }
+
async function checkIsbnExists(isbn: string): Promise {
+ // Try Open Library first
try {
- const response = await axios.get(`https://isbnsearch.org/isbn/${isbn}`);
- return response.status === 200 && response.data.includes('ISBN'); // Check if response contains ISBN information
+ const response = await axios.get(`https://openlibrary.org/api/books?bibkeys=ISBN:${isbn}&format=json&jscmd=data`);
+ const data = response.data;
+ if (Object.keys(data).length > 0) {
+ return true;
+ }
} catch (error) {
- return false; // If request fails, ISBN does not exist
+ // If an error occurs, continue to the next API
+ }
+
+ // Fallback to Google Books API
+ try {
+ const response = await axios.get(`https://www.googleapis.com/books/v1/volumes?q=isbn:${isbn}`);
+ const data = response.data;
+ if (data.totalItems > 0) {
+ return true;
+ }
+ } catch (error) {
+ // If an error occurs, continue to the next API
+ }
+
+ // Lastly use the Koha library by scraping HTML
+ try {
+ const response = await axios.get(`https://bibliothek.geosphere.at/cgi-bin/koha/opac-search.pl?idx=nb&q=${isbn}`);
+ const html = response.data;
+ // Check if zero results are explicitly indicated (German or English)
+ if (html.includes('Keine Treffer gefunden!') || html.includes('Your search returned 0 results')) {
+ return false;
+ }
+ // Try to extract the count from German message
+ let match = html.match(/Ihre Suche erzielte\s*(\d+)\s*Treffer/);
+
+ // If not found, try the English equivalent
+ if (!match) {
+ match = html.match(/Your search returned\s*(\d+)\s*results/);
+ }
+
+ if (match && match[1]) {
+ const count = parseInt(match[1], 10);
+ return count > 0;
+ }
+
+ // Fallback: if no match is found, return false
+ return false;
+ } catch (error) {
+ return false;
}
}
@@ -42,10 +93,10 @@ async function validateReference(value: unknown, options: Options, field: FieldC
try {
const exists = await checkDoiExists(value);
if (!exists) {
- field.report('The {{ field }} must be an existing DOI', 'validateReference', field);
+ field.report('The {{ field }} must be an existing URL', 'validateReference', field);
}
} catch (error) {
- field.report('Error checking DOI existence: ' + error.message, 'validateReference', field);
+ field.report('Error checking URL existence: ' + error.message, 'validateReference', field);
}
}
}