diff --git a/Dockerfile b/Dockerfile index 2d54b81..de295b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,9 +16,10 @@ RUN npm set strict-ssl false RUN npm install --production; RUN npm run postinstall; -RUN mkdir upload && mkdir upload/file +RUN mkdir upload && mkdir upload/file && mkdir download RUN touch swagger-spec.json && chmod 777 swagger-spec.json RUN chmod 777 -R upload +RUN chmod 777 -R download RUN touch error.log && chmod 777 error.log COPY dist* ./ diff --git a/package.json b/package.json index 9a5743d..00c1648 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "mysql": "^2.18.1", "nest-wechatpay-node-v3": "^1.0.1", "nest-winston": "^1.9.3", - "node-xlsx": "^0.23.0", + "node-xlsx": "^0.15.0", "passport": "^0.6.0", "passport-jwt": "^4.0.1", "patch-package": "^7.0.0", diff --git a/src/app.controller.ts b/src/app.controller.ts index e93e3c4..0928f03 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -8,7 +8,7 @@ import { Between, DataSource, IsNull, LessThan, Not, Repository } from 'typeorm' import * as bluebird from 'bluebird'; import { NodeOtherVisitorEntity } from './node-other-visitor.entity'; import * as moment from 'moment'; -import { CommonPageArgs, Roles, RolesGuard, User, ValidationPipe } from './common'; +import { CommonPageArgs, Roles, RolesGuard, User, ValidationPipe, createXlsx } from './common'; import { InjectRepository } from '@nestjs/typeorm'; import axios from 'axios'; import { v4 as uuid } from 'uuid'; @@ -18,6 +18,7 @@ import { AreaEntity } from './area.entity'; import { DeviceEntity } from './device.entity'; import { AuthGuard } from '@nestjs/passport'; import { UserEntity } from './user/user.entity'; +import redis from './redis'; export class Electronics { @ApiProperty({ description: "电子产品名称" }) @@ -338,6 +339,135 @@ export class QueryVisitorByNumberDto { area_code?: string } +const people_table_base = [ + "申请人", + "申请人部门", + "申请日期", + "申请单号", + "来访类型", + "来访区域", + "来访单位", + "访客人数", + "交通方式", + "车牌号", + "起始日期", + "截至日期", + "被访人", + "被访部门", + "厂区名字", + "厂区编号", + "来访事由", + "携带的电子产品", + "访客是否有可能接触受控设备", + "携带电子产品人员", + "是否上E1楼洽谈", + "访客姓名", + "访客身份证号", + "国籍(中国/其他国籍)", + "国籍名称", + "证件类型", + "访客卡编号", + "访客姓名(2)", + "访客身份证号(2)", + "国籍(中国/其他国籍)(2)", + "国籍名称(2)", + "证件类型(2)", + "访客卡编号(2)", + "访客姓名(3)", + "访客身份证号(3)", + "国籍(中国/其他国籍)(3)", + "国籍名称(3)", + "证件类型(3)", + "访客卡编号(3)", + "访客姓名(4)", + "访客身份证号(4)", + "国籍(中国/其他国籍)(4)", + "国籍名称(4)", + "证件类型(4)", + "访客卡编号(4)", + "访客姓名(5)", + "访客身份证号(5)", + "国籍(中国/其他国籍)(5)", + "国籍名称(5)", + "证件类型(5)", + "访客卡编号(5)", +]; + +async function mapTableData(data) { + const new_data = await bluebird.map(data, async item => { + let result = [ + item.applicant, + item.applicant_department, + item.apply_date, + item.code, + item.visitor_type, + item.area, + item.visitor_unit, + item.visitor_number, + item.transport, + item.plate_no, + item.start_date, + item.end_date, + item.visited_staff, + item.visited_department, + item.to_area, + item.to_area_code, + item.purpose, + item.electronics, + item.may_access_sensitive_info, + item.personnel_carrying_electronics, + item.sfslqt, + ]; + if (item.visitor_list && item.visitor_list.length > 0) { + item.visitor_list.forEach((d) => { + // console.log(d) + // result.push(d.name); + // result.push(d.identity_card_no); + // result.push(d.nationality_type); + // result.push(d.nationality); + // result.push(d.id_type); + // result.push(d.card_number); + result = [...result, d.name, + d.identity_card_no, + d.nationality_type, + d.nationality, + d.id_type, + d.card_number] + }) + } + return result; + }); + // console.log(new_data[0]) + // console.log(new_data[1]) + // console.log(new_data[2]) + // console.log(new_data[3]) + // console.log(new_data[3].length) + // console.log(people_table_base.length - 24) + return new_data; +} + +const people_table_base2 = [ + "访客姓名", "访客身份证号", "证件类型", "国籍(中国/其他国籍)", "国籍名称", "厂区名字", "厂区编号", "访客卡编号", "来访时间", "离开时间" +]; + +async function mapTableData2(data) { + const new_data = await bluebird.map(data, async item => { + return [ + item.name, + item.to_area, + item.to_area_code, + item.identity_card_no, + item.id_type, + item.nationality_type, + item.nationality, + item.card_number, + item.start_time ? moment(item.start_time).utcOffset(8).format("YYYY-MM-DD HH:mm:ss") : "", + item.end_time ? moment(item.end_time).utcOffset(8).format("YYYY-MM-DD HH:mm:ss") : "", + ]; + }); + return new_data; +} + @Controller() export class AppController { constructor( @@ -514,6 +644,93 @@ export class AppController { return { list: new_list, count } } + @Get("/visitors/out") + @ApiOperation({ summary: '导出预约记录' }) + @UseGuards(AuthGuard('jwt'), RolesGuard) + @UsePipes(new ValidationPipe()) + @Roles('super_admin', '导出预约记录') + @ApiBearerAuth() + // @ApiResponse({ + // status: 200, + // description: '返回参数说明', + // type: UserEntity, + // }) + async outVisitors(@Query() query_data: QueryVisitorDto, @User() viewer: any) { + const where: any = {}; + if (query_data.applicant) { + where.applicant = query_data.applicant + } + + const user = await this.userRepository.findOne({ where: { id: viewer.id } }) + if (user && user.area_id) { + const area = await this.areaRepository.findOne({ where: { id: user.area_id } }) + where.to_area_code = area.code + } else if (query_data.area_code) { + where.to_area_code = query_data.area_code + } + if (query_data.visited_staff) { + where.visited_staff = query_data.visited_staff + } + if (query_data.start_date) { + // where.start_date = query_data.start_date + where.start_date = Between(query_data.start_date, query_data.end_date) + } + // if (query_data.end_date) { + // where.end_date = query_data.end_date + // } + const query = this.nodeVisitorRepository.createQueryBuilder('node-visitor'); + query.where(where); + // if (organization_name) { + // query + // .leftJoin(OrganizationEntity, 'organization', `organization.id = bill.organization_id`) + // .andWhere(`organization.full_name like "%${organization_name}%"`) + // } + if (query_data.search) { + const string = `%${query_data.search}%`; + const fields = ['applicant', 'applicant_department', 'code', 'visitor_unit', 'plate_no', 'visited_staff', 'visited_department']; + const searchString = fields.join(' like :search OR node-visitor.'); + query.where(`node-visitor.${searchString} like :search`, { + search: string, + }); + } + const order_key = 'node-visitor.created_date'; + let order_value: any = 'DESC'; + const [list, count] = await query + // .skip(query_data.skip) + // .take(query_data.take) + .orderBy(order_key, order_value) + .getManyAndCount(); + // const [list, count] = await this.nodeVisitorRepository.findAndCount({ + // skip: query.skip, + // take: query.take, + // order: { + // created_date: "DESC" + // } + // }) + const new_list = await bluebird.map(list, async (item) => { + const visitor_list = await this.nodeOtherVisitorRepository.find({ + where: { node_visitor_id: item.id }, + order: { + created_date: "DESC" + } + }) + return { + ...item, + visitor_list + } + }, { concurrency: 5 }) + + const token = `peoples-${uuid()}`; + createXlsx( + people_table_base, + await mapTableData(new_list), + token, + '访客信息', + people_table_base, + ); + return { token, success: true }; + } + @Get("/visitor-records") @ApiOperation({ summary: '查看到访记录' }) @UseGuards(AuthGuard('jwt'), RolesGuard) @@ -581,6 +798,82 @@ export class AppController { return { list, count } } + @Get("/visitor-records/out") + @ApiOperation({ summary: '导出到访记录' }) + @UseGuards(AuthGuard('jwt'), RolesGuard) + @UsePipes(new ValidationPipe()) + @Roles('super_admin', '导出到访记录') + @ApiBearerAuth() + async outRecord(@Query() query_data: QueryVisitorDto, @User() viewer: any) { + const where: any = { + start_time: Not(IsNull()) + }; + if (query_data.start_date) { + where.start_date = query_data.start_date + } + if (query_data.end_date) { + where.end_date = query_data.end_date + } + const user = await this.userRepository.findOne({ where: { id: viewer.id } }) + if (user && user.area_id) { + const area = await this.areaRepository.findOne({ where: { id: user.area_id } }) + where.to_area_code = area.code + } else if (query_data.area_code) { + where.to_area_code = query_data.area_code + } + const query = this.nodeOtherVisitorRepository.createQueryBuilder('node-other-visitor'); + query.where(where); + // if (organization_name) { + // query + // .leftJoin(OrganizationEntity, 'organization', `organization.id = bill.organization_id`) + // .andWhere(`organization.full_name like "%${organization_name}%"`) + // } + if (query_data.search) { + const string = `%${query_data.search}%`; + const fields = ['name', 'identity_card_no', 'nationality', 'card_number']; + const searchString = fields.join(' like :search OR node-other-visitor.'); + query.where(`node-other-visitor.${searchString} like :search`, { + search: string, + }); + } + const order_key = 'node-other-visitor.created_date'; + let order_value: any = 'DESC'; + const [list, count] = await query + // .skip(query_data.skip) + // .take(query_data.take) + .orderBy(order_key, order_value) + .getManyAndCount(); + // const [list, count] = await this.nodeVisitorRepository.findAndCount({ + // skip: query.skip, + // take: query.take, + // order: { + // created_date: "DESC" + // } + // }) + // const new_list = await bluebird.map(list, async (item) => { + // const visitor_list = await this.nodeOtherVisitorRepository.find({ + // where: { node_visitor_id: item.id }, + // order: { + // created_date: "DESC" + // } + // }) + // return { + // ...item, + // visitor_list + // } + // }) + + const token = `peoples-${uuid()}`; + createXlsx( + people_table_base2, + await mapTableData2(list), + token, + '访客信息', + people_table_base2, + ); + return { token, success: true }; + } + @Post("/visitor") async create(@Body() data: CreateVisitor) { if (new Date(data.apply_date).toString() == "Invalid Date") { @@ -973,4 +1266,21 @@ export class AppController { res.sendFile(file_path) } + + @Get('xlsx') + async seeXlsx(@Query() { token }: any) { + const result = await redis.get(token); + if (result) { + // const SERVER_URL = this.configService.get('SERVER_URL'); + return { uri: `/file/download?file_token=${token}` }; + // return { uri: `${SERVER_URL}/api/file/download?file_token=${token}` }; + } + return { uri: null }; + } + + @Get('/file/download') + async file_download(@Query() { file_token }: any, @Res() res) { + const result = await redis.get(file_token); + return res.sendFile(result); + } } diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index f702f48..0976d80 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -51,7 +51,7 @@ export class AuthService { } async validateUser(payload: UserJwtPayload): Promise { - console.log(payload) + // console.log(payload) const user = await this.userRepository.findOne({ where: { id: payload.id } }) if (!user) throw new BadRequestException('用户不存在') return { id: payload.id }; diff --git a/src/common/base.func.ts b/src/common/base.func.ts index fb6c446..7d9ba72 100644 --- a/src/common/base.func.ts +++ b/src/common/base.func.ts @@ -1,13 +1,17 @@ import { v4 as uuid } from 'uuid'; -import fs from 'fs'; -import path from 'path'; -// import xlsx from 'node-xlsx'; +import * as fs from 'fs'; +import * as path from 'path'; +import xlsx from 'node-xlsx'; // import { fileClient } from '../lib/oss'; // import redis from '../redis'; import { getRepository } from 'typeorm'; // import { TeamEntity } from '../team/team.entity'; // import { MemberEntity } from '../member/member.entity'; import { eight_hour } from './const'; +import { transRowXlsx } from './xlsx'; +import { Logger } from '@nestjs/common'; +import redis from 'src/redis'; +import { path_download } from './base.path'; export function formatArgs(args: any) { const newArgs = { @@ -114,3 +118,55 @@ export const changeName = (fileName: string) => { export const getEightTime = () => { return new Date(Date.now() + eight_hour); }; + +export const createXlsx = async (base, data, token, name, columns) => { + return setTimeout(async () => { + try { + columns = columns.filter( + column => + column !== '操作' && + column !== '底片' && + column !== '照片' && + column !== '抓拍照片' && + column !== '头像', + ); + const new_data = data.map(item => { + const new_item = columns.map(column => { + let column_index; + base.forEach((rr, index) => { + if (rr === column) { + column_index = index; + } + }); + if (!column_index && column_index !== 0) { + return ''; + } + if (item[column_index] === 0) { + return item[column_index]; + } + return item[column_index] || ''; + }); + return new_item; + }); + // const file_name = '/xlsx/' + token + uuid() + '.xlsx'; + const { new_data: trans_data, cols } = transRowXlsx([ + columns, + ...new_data, + ]); + const buffer = xlsx.build( + [{ name: name || 'Sheet1', data: trans_data }], + { + '!cols': cols, + }, + ); + // const file_path = './download'; + const file_path = path.resolve(__dirname, path_download); + const local_file_name = `${file_path}/${token}.xlsx`; + fs.writeFileSync(local_file_name, buffer); + await redis.set(token, local_file_name, 'EX', 3600); + // return buffer; + } catch (e) { + Logger.error(`导出${name}错误`, e.message); + } + }, 100); +}; \ No newline at end of file diff --git a/src/common/base.path.ts b/src/common/base.path.ts new file mode 100644 index 0000000..a64b084 --- /dev/null +++ b/src/common/base.path.ts @@ -0,0 +1,6 @@ +export let path_download = '../download'; + +if (process.env.NODE_ENV !== 'production') { + path_download = '../../download'; +} + diff --git a/src/common/decorators/roles.decorator.ts b/src/common/decorators/roles.decorator.ts index ed513ae..ad44b13 100644 --- a/src/common/decorators/roles.decorator.ts +++ b/src/common/decorators/roles.decorator.ts @@ -2,7 +2,7 @@ import { SetMetadata } from '@nestjs/common'; /* tslint:disable */ export const Roles = (...roles: string[]) => { - console.log(roles) + // console.log(roles) return SetMetadata('roles', roles) }; diff --git a/src/common/guards/roles.guard.ts b/src/common/guards/roles.guard.ts index 183c943..a363a02 100644 --- a/src/common/guards/roles.guard.ts +++ b/src/common/guards/roles.guard.ts @@ -25,8 +25,6 @@ export class RolesGuard implements CanActivate { user_permissions_key, ); - console.log("result", result) - if (!result) { return false; } @@ -35,7 +33,7 @@ export class RolesGuard implements CanActivate { const hasRole = () => user.roles.some(role => !!roles.find(item => item === role)); - console.log(roles, user.roles) + // console.log(roles, user.roles) return user && user.roles && hasRole(); } } diff --git a/src/common/validation.pipe.ts b/src/common/validation.pipe.ts index faa8e42..694649a 100644 --- a/src/common/validation.pipe.ts +++ b/src/common/validation.pipe.ts @@ -10,7 +10,7 @@ import { plainToClass } from 'class-transformer'; @Injectable() export class ValidationPipe implements PipeTransform { async transform(value, { type, metatype }: ArgumentMetadata) { - console.log(value) + // console.log(value) if (type === 'query' && value.skip && value.take) { value = { ...value, @@ -21,10 +21,10 @@ export class ValidationPipe implements PipeTransform { if (!metatype || !this.toValidate(metatype)) { return value; } - console.log(value) + // console.log(value) const object = plainToClass(metatype, value); const errors = await validate(object); - console.log(errors) + // console.log(errors) if (errors.length > 0) { throw new BadRequestException(errors); // throw new BadRequestException('Validation failed'); diff --git a/src/common/xlsx.ts b/src/common/xlsx.ts new file mode 100644 index 0000000..dec9234 --- /dev/null +++ b/src/common/xlsx.ts @@ -0,0 +1,117 @@ +import nodeXlsx from 'node-xlsx'; +import fs from 'fs'; + +/** + * 生成xlsx + * @param p 生成文件路径 + * @param cols 列名 + * @param data 行,二维数组 + */ +function genXlsx(p, cols, data) { + const d: any = [ + { + name: 'Sheet1', + data: [cols, ...data], + }, + ]; + // !cols 指定列的宽度 + const buffer = nodeXlsx.build(d, { + '!cols': [{ wch: 60 }, { wch: 20 }], + }); + fs.writeFileSync(p, buffer, { flag: 'w' }); +} +// 指定单元格内容样式:四个方向的黑边框 +const contentCellStyle = { + border: { + top: { + style: 'medium', + color: '#000', + }, + bottom: { + style: 'medium', + color: '#000', + }, + left: { + style: 'medium', + color: '#000', + }, + right: { + style: 'medium', + color: '#000', + }, + }, + alignment: { + horizontal: 'center', + }, +}; +// 指定标题单元格样式:加粗居中 +const headerStyle = { + font: { + bold: true, + }, + alignment: { + horizontal: 'center', + }, +}; + +// genXlsx( +// '1.xlsx', +// [ +// { +// v: '表头1', +// s: headerStyle, +// }, +// { +// v: '表头2', +// s: headerStyle, +// }, +// ], +// [ +// [ +// { +// v: 123, +// s: contentCellStyle, +// }, +// { +// v: 456, +// s: contentCellStyle, +// }, +// ], +// ], +// ); + +export const transColumnXlsx = (data: any[]) => { + return data.map(item => { + return { + v: item, + // s: headerStyle, + }; + }); +}; + +export const transRowXlsx = (data: any[][]) => { + const width = 4; + const cols = data[0].map(() => ({ wch: width })); + const new_data = data.map(item => { + const new_item = item.map((index_item, index) => { + if (cols[index].wch < index_item.length * 2) { + cols[index].wch = index_item.length * 2; + } + return { + v: index_item, + s: contentCellStyle, + }; + }); + return new_item; + }); + return { new_data, cols }; +}; + +// export const transRowXlsx = (data: any[]) => { +// return data.map(item => { +// return { +// v: index_item, +// s: contentCellStyle, +// }; +// }); +// }; diff --git a/src/main.ts b/src/main.ts index a93c284..66eaec0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,9 +27,10 @@ import { createAdmin, createRole } from './boot'; async function bootstrap() { console.log("当前运行环境 1.3.1", process.env.NODE_ENV) const app = await NestFactory.create(AppModule); + Logger.debug = () => {}; app.enableCors({ origin(origin, cb) { - console.log('origin', origin); + // console.log('origin', origin); if (process.env.NODE_ENV != "production") { cb(null, true); } else { diff --git a/yarn.lock b/yarn.lock index 41ef0e8..4dd1d10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -495,6 +495,13 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" +"@babel/runtime@^7.14.6": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.5.tgz#230946857c053a36ccc66e1dd03b17dd0c4ed02c" + integrity sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.20.7", "@babel/template@^7.3.3": version "7.20.7" resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz" @@ -1707,6 +1714,19 @@ address@^1.0.0: resolved "https://registry.npmjs.org/address/-/address-1.2.2.tgz" integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== +adler-32@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25" + integrity sha512-/vUqU/UY4MVeFsg+SsK6c+/05RZXIHZMGJA+PX5JyWI0ZRcBpupnRuPLU/NXXoFwMYCPCoxIfElM2eS+DUXCqQ== + dependencies: + exit-on-epipe "~1.0.1" + printj "~1.1.0" + +adler-32@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2" + integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A== + agent-base@6, agent-base@^6.0.0, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" @@ -2136,7 +2156,7 @@ buffer-equal-constant-time@1.0.1: resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== -buffer-from@^1.0.0: +buffer-from@^1.0.0, buffer-from@^1.1.1: version "1.1.2" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== @@ -2235,6 +2255,14 @@ caniuse-lite@^1.0.30001517: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001523.tgz#b838f70b1a98c556776b998fafb47d2b64146d4f" integrity sha512-I5q5cisATTPZ1mc588Z//pj/Ox80ERYDfR71YnvY7raS/NOk8xXlZcB0sF7JdqaV//kOaa6aus7lRfpdnt1eBA== +cfb@^1.1.4: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44" + integrity sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA== + dependencies: + adler-32 "~1.3.0" + crc-32 "~1.2.0" + chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" @@ -2411,6 +2439,11 @@ co@^4.6.0: resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== +codepage@~1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab" + integrity sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA== + collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz" @@ -2572,6 +2605,11 @@ cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +crc-32@~1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + create-require@^1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" @@ -3083,6 +3121,11 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exit-on-epipe@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" + integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== + exit@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" @@ -3368,6 +3411,11 @@ forwarded@0.2.0: resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +frac@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" + integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA== + fresh@0.5.2: version "0.5.2" resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" @@ -4955,12 +5003,14 @@ node-releases@^2.0.8: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== -node-xlsx@^0.23.0: - version "0.23.0" - resolved "https://registry.npmjs.org/node-xlsx/-/node-xlsx-0.23.0.tgz" - integrity sha512-r3KaSZSsSrK92rbPXnX/vDdxURmPPik0rjJ3A+Pybzpjyrk4G6WyGfj8JIz5dMMEpCmWVpmO4qoVPBxnpLv/8Q== +node-xlsx@^0.15.0: + version "0.15.1" + resolved "https://registry.yarnpkg.com/node-xlsx/-/node-xlsx-0.15.1.tgz#1bd0bf0995eab4370eb520abd2d192ae28b42163" + integrity sha512-BAS24NbLjBp4xvXIs4Ps5rZH99Rkgv3CyDqVBN/jQMUT2WyEfzWkcpEWSbnqOi7lEaHIozcrCUQfXKMzRBQLNw== dependencies: - xlsx "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz" + "@babel/runtime" "^7.14.6" + buffer-from "^1.1.1" + xlsx "^0.17.0" normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -5370,6 +5420,11 @@ pretty-format@^29.0.0, pretty-format@^29.5.0: ansi-styles "^5.0.0" react-is "^18.0.0" +printj@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" + integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" @@ -5570,6 +5625,11 @@ reflect-metadata@^0.1.13: resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -5911,6 +5971,13 @@ sqlstring@2.3.1: resolved "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz" integrity sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ== +ssf@~0.11.2: + version "0.11.2" + resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" + integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g== + dependencies: + frac "~1.1.2" + stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" @@ -6668,11 +6735,21 @@ winston@^3.10.0: triple-beam "^1.3.0" winston-transport "^4.5.0" +wmf@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" + integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw== + word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +word@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" + integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA== + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -6695,10 +6772,18 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -"xlsx@https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz": - version "0.19.3" - resolved "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz" - integrity sha512-8IfgFctB7fkvqkTGF2MnrDrC6vzE28Wcc1aSbdDQ+4/WFtzfS73YuapbuaPZwGqpR2e0EeDMIrFOJubQVLWFNA== +xlsx@^0.17.0: + version "0.17.5" + resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.17.5.tgz#78b788fcfc0773d126cdcd7ea069cb7527c1ce81" + integrity sha512-lXNU0TuYsvElzvtI6O7WIVb9Zar1XYw7Xb3VAx2wn8N/n0whBYrCnHMxtFyIiUU1Wjf09WzmLALDfBO5PqTb1g== + dependencies: + adler-32 "~1.2.0" + cfb "^1.1.4" + codepage "~1.15.0" + crc-32 "~1.2.0" + ssf "~0.11.2" + wmf "~1.0.1" + word "~0.3.0" xml2js@^0.4.16: version "0.4.23"