Improve parkio, add domainrproxy
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/cache-manager": "^2.1.0",
|
||||
"@nestjs/common": "^10.0.0",
|
||||
"@nestjs/config": "^3.1.1",
|
||||
"@nestjs/core": "^10.0.0",
|
||||
@@ -28,6 +29,8 @@
|
||||
"@nestjs/swagger": "^7.1.11",
|
||||
"axios": "^1.5.0",
|
||||
"bcrypt": "^5.1.1",
|
||||
"cache-manager": "^5.2.3",
|
||||
"hbs": "^4.2.0",
|
||||
"minio": "^7.1.3",
|
||||
"ramda": "^0.29.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
|
@@ -6,18 +6,22 @@ import { IswordModule } from './isword/isword.module';
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { UsersModule } from './users/users.module';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { DomainrproxyModule } from './domainrproxy/domainrproxy.module';
|
||||
import configuration from './config/configuration';
|
||||
import { CacheModule } from '@nestjs/cache-manager';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
load: [configuration]
|
||||
load: [configuration],
|
||||
}),
|
||||
CacheModule.register({ isGlobal: true }),
|
||||
ParkioModule,
|
||||
IswordModule,
|
||||
AuthModule,
|
||||
UsersModule,
|
||||
DomainrproxyModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
|
@@ -3,6 +3,6 @@ import { Injectable } from '@nestjs/common';
|
||||
@Injectable()
|
||||
export class AppService {
|
||||
getHello(): string {
|
||||
return 'Hello World!';
|
||||
return "Hello World! This is Chip's generalized API for fetching information and things. You can contact me on mastodon @chip@talking.dev.";
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { AuthGuard } from './auth.guard';
|
||||
import { ApiBearerAuth } from '@nestjs/swagger';
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
@@ -28,6 +29,7 @@ export class AuthController {
|
||||
}
|
||||
|
||||
@UseGuards(AuthGuard)
|
||||
@ApiBearerAuth()
|
||||
@Get('profile')
|
||||
getProfile(@Request() req: any) {
|
||||
return req.user;
|
||||
|
@@ -1,3 +1,6 @@
|
||||
export default () => ({
|
||||
port: parseInt(process.env.PORT ?? '', 10) || 3000,
|
||||
// UserAgent should be added to calls made to third party apis
|
||||
userAgent: 'api.us.dev/@chip@talking.dev',
|
||||
rapidApiKey: process.env.RAPID_API_KEY || '',
|
||||
});
|
||||
|
20
src/domainrproxy/domainrproxy.controller.ts
Normal file
20
src/domainrproxy/domainrproxy.controller.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Body, Controller, Get, Param, Post, UseGuards } from '@nestjs/common';
|
||||
import { DomainrproxyService } from './domainrproxy.service';
|
||||
import { AuthGuard } from 'src/auth/auth.guard';
|
||||
|
||||
@Controller('domainrproxy')
|
||||
export class DomainrproxyController {
|
||||
constructor(private readonly proxyService: DomainrproxyService) {}
|
||||
|
||||
@UseGuards(AuthGuard)
|
||||
@Get(':domain')
|
||||
queryDomain(@Param('domain') domain: string) {
|
||||
return this.proxyService.queryForDomain(domain);
|
||||
}
|
||||
|
||||
@UseGuards(AuthGuard)
|
||||
@Post('search')
|
||||
search(@Body() body: { query: string }) {
|
||||
return this.proxyService.search(body.query);
|
||||
}
|
||||
}
|
9
src/domainrproxy/domainrproxy.module.ts
Normal file
9
src/domainrproxy/domainrproxy.module.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DomainrproxyService } from './domainrproxy.service';
|
||||
import { DomainrproxyController } from './domainrproxy.controller';
|
||||
|
||||
@Module({
|
||||
providers: [DomainrproxyService],
|
||||
controllers: [DomainrproxyController]
|
||||
})
|
||||
export class DomainrproxyModule {}
|
48
src/domainrproxy/domainrproxy.service.ts
Normal file
48
src/domainrproxy/domainrproxy.service.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import axios from 'axios';
|
||||
|
||||
@Injectable()
|
||||
export class DomainrproxyService {
|
||||
private readonly logger = new Logger(DomainrproxyService.name);
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
|
||||
queryForDomain = async (domain: string) => {
|
||||
this.logger.verbose(`Handling domainr query for domain ${domain}`);
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: 'https://domainr.p.rapidapi.com/v2/status',
|
||||
params: {
|
||||
domain,
|
||||
'mashape-key': this.configService.get<string>('rapidApiKey'),
|
||||
},
|
||||
headers: {
|
||||
'X-RapidAPI-Key': this.configService.get<string>('rapidApiKey'),
|
||||
'X-RapidAPI-Host': 'domainr.p.rapidapi.com',
|
||||
},
|
||||
};
|
||||
|
||||
const result = await axios.request(options);
|
||||
return result.data;
|
||||
};
|
||||
|
||||
search = async (query: string) => {
|
||||
this.logger.verbose(`Handling domainr search for term ${query}`);
|
||||
const options = {
|
||||
method: 'GET',
|
||||
url: 'https://domainr.p.rapidapi.com/v2/search',
|
||||
params: {
|
||||
query,
|
||||
defaults: 'com,net,org,io,sh,wtf',
|
||||
'mashape-key': this.configService.get<string>('rapidApiKey'),
|
||||
},
|
||||
headers: {
|
||||
'X-RapidAPI-Key': this.configService.get<string>('rapidApiKey'),
|
||||
'X-RapidAPI-Host': 'domainr.p.rapidapi.com',
|
||||
},
|
||||
};
|
||||
|
||||
const result = await axios.request(options);
|
||||
return result.data;
|
||||
};
|
||||
}
|
@@ -1,13 +1,19 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from './app.module';
|
||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { join } from 'path';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
||||
app.useStaticAssets(join(__dirname, '..', 'public'));
|
||||
app.setBaseViewsDir(join(__dirname, '..', 'views'));
|
||||
app.setViewEngine('hbs');
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle('us.dev API')
|
||||
.setDescription("Chip's generalized API")
|
||||
.setVersion('1.0')
|
||||
.addBearerAuth()
|
||||
.build();
|
||||
const document = SwaggerModule.createDocument(app, config);
|
||||
SwaggerModule.setup('api', app, document);
|
||||
|
@@ -1,13 +1,12 @@
|
||||
import { Controller, Get, Param } from '@nestjs/common';
|
||||
import { Controller, Get, Param, Render, Res } from '@nestjs/common';
|
||||
import { ParkioService } from './parkio.service';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ParsedDomain } from './types';
|
||||
|
||||
@ApiTags('parkio')
|
||||
@Controller('parkio')
|
||||
export class ParkioController {
|
||||
constructor(
|
||||
private readonly parkioService: ParkioService
|
||||
) {}
|
||||
constructor(private readonly parkioService: ParkioService) {}
|
||||
|
||||
@Get('auctions')
|
||||
async getAuctions() {
|
||||
@@ -15,7 +14,7 @@ export class ParkioController {
|
||||
}
|
||||
|
||||
@Get('domains')
|
||||
async getDomains () {
|
||||
async getDomains(): Promise<ParsedDomain[]> {
|
||||
return this.parkioService.fetchAllDomains();
|
||||
}
|
||||
|
||||
@@ -24,12 +23,25 @@ export class ParkioController {
|
||||
return {
|
||||
maxLength,
|
||||
domains: (await this.parkioService.fetchAllDomains()).filter(
|
||||
parsedDomain => parsedDomain.domain_length <= maxLength
|
||||
(parsedDomain) => parsedDomain.domain_length <= maxLength,
|
||||
),
|
||||
auctions: (await this.parkioService.fetchAuctions()).filter(
|
||||
parsedAuction => parsedAuction.domain_length <= maxLength
|
||||
(parsedAuction) => parsedAuction.domain_length <= maxLength,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@Get('report')
|
||||
@Render('parkio/dailyreport')
|
||||
async getReport() {
|
||||
const source = {
|
||||
auctions: await this.parkioService.fetchAuctions(),
|
||||
domains: await this.parkioService.fetchAllDomains(),
|
||||
};
|
||||
return {
|
||||
...source,
|
||||
day: new Date().toLocaleDateString(),
|
||||
wordDomains: source.domains.filter((domain) => domain.is_word),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,51 +1,124 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import {
|
||||
Auction,
|
||||
AuctionsResponse,
|
||||
Domain,
|
||||
DomainSet,
|
||||
DomainsResponse,
|
||||
ParkioTld,
|
||||
ParsedAuction,
|
||||
ParsedDomain,
|
||||
TLDs,
|
||||
} from './types';
|
||||
import axios from 'axios';
|
||||
import { filter, map, pipe } from 'ramda';
|
||||
import { IswordService } from 'src/isword/isword.service';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import { Cache } from 'cache-manager';
|
||||
|
||||
const parkIoEndpoints = {
|
||||
domains: 'https://park.io/domains.json',
|
||||
auctions: 'https://park.io/auctions.json',
|
||||
tld: (tld: ParkioTld) => `https://park.io/domains/index/${tld}.json`,
|
||||
tld: (tld: ParkioTld, limit: number = 80_000, page: number = 1) =>
|
||||
`https://park.io/domains/index/${tld}/page:${page}.json?limit=${limit}`,
|
||||
all: (limit: number = 10_000) =>
|
||||
`https://park.io/domains/index/all.json?limit=${limit}`,
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class ParkioService {
|
||||
private readonly logger = new Logger(ParkioService.name);
|
||||
constructor(
|
||||
private readonly isWordService: IswordService
|
||||
private configService: ConfigService,
|
||||
private readonly isWordService: IswordService,
|
||||
@Inject(CACHE_MANAGER) private cacheManager: Cache,
|
||||
) {}
|
||||
|
||||
fetchDomainsForTld = async (tld: ParkioTld) => {};
|
||||
tldRawCacheKey = (tld: ParkioTld) => `${tld}_raw`;
|
||||
|
||||
fetchAllDomains = async (limit: number = 10_000): Promise<ParsedDomain[]> => {
|
||||
let response = await axios.get<DomainsResponse>(parkIoEndpoints.all(limit));
|
||||
setTldDomainsCache = async (
|
||||
tld: ParkioTld,
|
||||
domains: ParsedDomain[],
|
||||
): Promise<void> =>
|
||||
this.cacheManager.set(this.tldRawCacheKey(tld), domains, 300_000);
|
||||
|
||||
// There may have been more than our set limit
|
||||
if (response.data.current === limit) {
|
||||
return await this.fetchAllDomains(limit + 200);
|
||||
getTldDomainsCache = (tld: ParkioTld): Promise<ParsedDomain[] | undefined> =>
|
||||
this.cacheManager.get<ParsedDomain[]>(this.tldRawCacheKey(tld));
|
||||
|
||||
fetchDomainsForTld = async (tld: ParkioTld): Promise<ParsedDomain[]> => {
|
||||
this.logger.verbose(`Fetching domains for ${tld}`);
|
||||
const cacheValue = await this.getTldDomainsCache(tld);
|
||||
if (cacheValue !== undefined) {
|
||||
this.logger.verbose(`${tld} ... cache hit`);
|
||||
return cacheValue;
|
||||
}
|
||||
|
||||
return map(this.parseDomain, response.data.domains);
|
||||
this.logger.verbose(`${tld} ... cache miss`);
|
||||
// Recursively fetch domain
|
||||
const results = await this.fetchDomainPageForTld(tld);
|
||||
// Fire the combined results into the cache
|
||||
this.setTldDomainsCache(tld, results);
|
||||
return results;
|
||||
};
|
||||
|
||||
fetchDomainPageForTld = async (
|
||||
tld: ParkioTld,
|
||||
pageLimit: number = 1_000,
|
||||
page: number = 1,
|
||||
): Promise<ParsedDomain[]> => {
|
||||
this.logger.verbose(`Fetching ${pageLimit} .${tld} domains, page ${page}`);
|
||||
|
||||
const url = parkIoEndpoints.tld(tld, pageLimit, page);
|
||||
const response = await axios.get<DomainsResponse>(url, {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'User-Agent': this.configService.get<string>('userAgent'),
|
||||
},
|
||||
});
|
||||
|
||||
// There may have been more than our set limit
|
||||
if (response.data.nextPage) {
|
||||
return [
|
||||
...response.data.domains.map(this.parseDomain),
|
||||
...(await this.fetchDomainPageForTld(tld, pageLimit, page + 1)),
|
||||
];
|
||||
}
|
||||
|
||||
return response.data.domains.map(this.parseDomain);
|
||||
};
|
||||
|
||||
fetchAllDomains = async (): Promise<ParsedDomain[]> => {
|
||||
const domainResults = await Promise.all(TLDs.map(this.fetchDomainsForTld));
|
||||
return domainResults.reduce((acc, domainResponse) => [
|
||||
...acc,
|
||||
...domainResponse,
|
||||
]);
|
||||
};
|
||||
|
||||
auctionsRawCacheKey = `auctions_raw`;
|
||||
|
||||
setAuctionsCache = async (auctions: ParsedAuction[]): Promise<void> =>
|
||||
this.cacheManager.set(this.auctionsRawCacheKey, auctions);
|
||||
|
||||
getAuctionsCache = async (): Promise<ParsedAuction[] | undefined> =>
|
||||
this.cacheManager.get<ParsedAuction[]>(this.auctionsRawCacheKey);
|
||||
|
||||
fetchAuctions = async (): Promise<ParsedAuction[]> => {
|
||||
this.logger.verbose('Fetching auction data');
|
||||
const cachedValue = await this.getAuctionsCache();
|
||||
if (cachedValue !== undefined) {
|
||||
this.logger.verbose('... cache hit');
|
||||
return cachedValue;
|
||||
}
|
||||
this.logger.verbose('... cache miss');
|
||||
|
||||
const response = await axios.get<AuctionsResponse>(
|
||||
parkIoEndpoints.auctions,
|
||||
);
|
||||
|
||||
return map(this.parseAuction, response.data.auctions);
|
||||
this.logger.verbose('Processing auction response');
|
||||
const results = map(this.parseAuction, response.data.auctions);
|
||||
this.setAuctionsCache(results);
|
||||
return results;
|
||||
};
|
||||
|
||||
lengthFilter = (length: number) => (parsedDomain: ParsedDomain) =>
|
||||
@@ -80,10 +153,12 @@ export class ParkioService {
|
||||
date_registered: domain.date_registered
|
||||
? this.parseDate(domain.date_registered)
|
||||
: undefined,
|
||||
is_word: this.isWordService.isWord(domainName)
|
||||
is_word: this.isWordService.isWord(domainName),
|
||||
};
|
||||
};
|
||||
|
||||
parseDomains = map(this.parseDomain);
|
||||
|
||||
parseDate = (date: string) =>
|
||||
new Date(
|
||||
Date.parse(
|
||||
|
37
views/parkio/dailyreport.hbs
Normal file
37
views/parkio/dailyreport.hbs
Normal file
@@ -0,0 +1,37 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<title>Daily park.io Report</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Daily <a href='https://park.io'>park.io</a> report for {{day}}</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Current Bid</th>
|
||||
<th>Bid Count</th>
|
||||
<th>Closes</th>
|
||||
</tr>
|
||||
{{#each auctions}}
|
||||
<tr>
|
||||
<td><a href='https://park.io/auctions/view/{{name}}'>{{name}}</a></td>
|
||||
<td>${{price}}</td>
|
||||
<td>{{num_bids}}</td>
|
||||
<td>{{close_date}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Domain</th>
|
||||
<th>TLD</th>
|
||||
</tr>
|
||||
{{#each wordDomains}}
|
||||
<tr>
|
||||
<td><a href='https://park.io/auctions/view/{{name}}'>{{name}}</a></td>
|
||||
<td>{{tld}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
69
yarn.lock
69
yarn.lock
@@ -697,6 +697,11 @@
|
||||
semver "^7.3.5"
|
||||
tar "^6.1.11"
|
||||
|
||||
"@nestjs/cache-manager@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/cache-manager/-/cache-manager-2.1.0.tgz#e4dadc4ba9c02c059db4dac5e0b5513466e2895a"
|
||||
integrity sha512-9kep3a8Mq5cMuXN/anGhSYc0P48CRBXk5wyJJRBFxhNkCH8AIzZF4CASGVDIEMmm3OjVcEUHojjyJwCODS17Qw==
|
||||
|
||||
"@nestjs/cli@^10.0.0":
|
||||
version "10.1.17"
|
||||
resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-10.1.17.tgz#c7e90e443e0967be2b12dc912957f89ed4b5c992"
|
||||
@@ -1796,6 +1801,14 @@ bytes@3.1.2:
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
|
||||
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
|
||||
|
||||
cache-manager@^5.2.3:
|
||||
version "5.2.3"
|
||||
resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-5.2.3.tgz#b6a8b4469c57fdfdae1deed7f81ea9e057c7eade"
|
||||
integrity sha512-9OErI8fksFkxAMJ8Mco0aiZSdphyd90HcKiOMJQncSlU1yq/9lHHxrT8PDayxrmr9IIIZPOAEfXuGSD7g29uog==
|
||||
dependencies:
|
||||
lodash.clonedeep "^4.5.0"
|
||||
lru-cache "^9.1.2"
|
||||
|
||||
call-bind@^1.0.0, call-bind@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
||||
@@ -2693,6 +2706,11 @@ for-each@^0.3.3:
|
||||
dependencies:
|
||||
is-callable "^1.1.3"
|
||||
|
||||
foreachasync@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6"
|
||||
integrity sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw==
|
||||
|
||||
fork-ts-checker-webpack-plugin@8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504"
|
||||
@@ -2910,6 +2928,18 @@ graphemer@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
|
||||
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
|
||||
|
||||
handlebars@4.7.7:
|
||||
version "4.7.7"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
|
||||
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
neo-async "^2.6.0"
|
||||
source-map "^0.6.1"
|
||||
wordwrap "^1.0.0"
|
||||
optionalDependencies:
|
||||
uglify-js "^3.1.4"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
@@ -2954,6 +2984,14 @@ has@^1.0.3:
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hbs@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/hbs/-/hbs-4.2.0.tgz#10e40dcc24d5be7342df9636316896617542a32b"
|
||||
integrity sha512-dQwHnrfWlTk5PvG9+a45GYpg0VpX47ryKF8dULVd6DtwOE6TEcYQXQ5QM6nyOx/h7v3bvEQbdn19EDAcfUAgZg==
|
||||
dependencies:
|
||||
handlebars "4.7.7"
|
||||
walk "2.3.15"
|
||||
|
||||
hexoid@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hexoid/-/hexoid-1.0.0.tgz#ad10c6573fb907de23d9ec63a711267d9dc9bc18"
|
||||
@@ -3814,6 +3852,11 @@ locate-path@^6.0.0:
|
||||
dependencies:
|
||||
p-locate "^5.0.0"
|
||||
|
||||
lodash.clonedeep@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||
integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
|
||||
|
||||
lodash.memoize@4.x:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
@@ -3856,6 +3899,11 @@ lru-cache@^6.0.0:
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a"
|
||||
integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==
|
||||
|
||||
lru-cache@^9.1.2:
|
||||
version "9.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.2.tgz#255fdbc14b75589d6d0e73644ca167a8db506835"
|
||||
integrity sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==
|
||||
|
||||
macos-release@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.5.1.tgz#bccac4a8f7b93163a8d163b8ebf385b3c5f55bf9"
|
||||
@@ -3987,7 +4035,7 @@ minimatch@^8.0.2:
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimist@^1.2.6:
|
||||
minimist@^1.2.5, minimist@^1.2.6:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
@@ -4097,7 +4145,7 @@ negotiator@0.6.3:
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
||||
|
||||
neo-async@^2.6.2:
|
||||
neo-async@^2.6.0, neo-async@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||
@@ -5233,6 +5281,11 @@ typescript@^5.1.3:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
|
||||
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
|
||||
|
||||
uglify-js@^3.1.4:
|
||||
version "3.17.4"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c"
|
||||
integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==
|
||||
|
||||
uid@2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/uid/-/uid-2.0.2.tgz#4b5782abf0f2feeefc00fa88006b2b3b7af3e3b9"
|
||||
@@ -5315,6 +5368,13 @@ vary@^1, vary@~1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
||||
|
||||
walk@2.3.15:
|
||||
version "2.3.15"
|
||||
resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.15.tgz#1b4611e959d656426bc521e2da5db3acecae2424"
|
||||
integrity sha512-4eRTBZljBfIISK1Vnt69Gvr2w/wc3U6Vtrw7qiN5iqYJPH7LElcYh/iU4XWhdCy2dZqv1ToMyYlybDylfG/5Vg==
|
||||
dependencies:
|
||||
foreachasync "^3.0.0"
|
||||
|
||||
walker@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f"
|
||||
@@ -5431,6 +5491,11 @@ windows-release@^4.0.0:
|
||||
dependencies:
|
||||
execa "^4.0.2"
|
||||
|
||||
wordwrap@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
|
||||
|
||||
wrap-ansi@^6.0.1:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
|
||||
|
Reference in New Issue
Block a user