rl-core-api 0.14.3 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/bootstrap/bootstrapWorker.util.d.ts +6 -0
- package/dist/core/bootstrap/bootstrapWorker.util.js +27 -0
- package/dist/core/config/env.schema.d.ts +7 -0
- package/dist/core/config/env.schema.js +4 -0
- package/dist/core/export/export.controller.d.ts +14 -0
- package/dist/core/export/export.controller.js +86 -0
- package/dist/core/export/export.module.d.ts +2 -0
- package/dist/core/export/export.module.js +24 -0
- package/dist/core/export/export.processor.d.ts +16 -0
- package/dist/core/export/export.processor.js +62 -0
- package/dist/core/export/export.service.d.ts +13 -0
- package/dist/core/export/export.service.js +54 -0
- package/dist/core/export/exportAccepted.response.d.ts +4 -0
- package/dist/core/export/exportAccepted.response.js +24 -0
- package/dist/core/export/exportApi.module.d.ts +2 -0
- package/dist/core/export/exportApi.module.js +25 -0
- package/dist/core/export/exportCleanup.service.d.ts +9 -0
- package/dist/core/export/exportCleanup.service.js +49 -0
- package/dist/core/export/exportColumn.interface.d.ts +11 -0
- package/dist/core/export/exportColumn.interface.js +9 -0
- package/dist/core/export/exportEngine.service.d.ts +15 -0
- package/dist/core/export/exportEngine.service.js +151 -0
- package/dist/core/export/exportHandler.interface.d.ts +32 -0
- package/dist/core/export/exportHandler.interface.js +7 -0
- package/dist/core/export/exportHandler.registry.d.ts +13 -0
- package/dist/core/export/exportHandler.registry.js +58 -0
- package/dist/core/export/exportStorage.service.d.ts +13 -0
- package/dist/core/export/exportStorage.service.js +87 -0
- package/dist/core/export/exportWorker.module.d.ts +2 -0
- package/dist/core/export/exportWorker.module.js +22 -0
- package/dist/core/export/requestExport.command.d.ts +6 -0
- package/dist/core/export/requestExport.command.js +51 -0
- package/dist/core/query/paginateWithFilter.util.d.ts +1 -0
- package/dist/core/query/paginateWithFilter.util.js +3 -2
- package/dist/core/queue/job.interface.d.ts +3 -0
- package/dist/core/queue/job.producer.d.ts +7 -5
- package/dist/core/queue/job.producer.js +40 -15
- package/dist/core/queue/jobWorkerHost.js +6 -1
- package/dist/core/queue/queue.constants.d.ts +6 -0
- package/dist/core/queue/queue.constants.js +7 -1
- package/dist/core/queue/queue.module.js +4 -1
- package/dist/core/queue/queueAdmin.controller.d.ts +4 -4
- package/dist/core/queue/queueAdmin.controller.js +22 -12
- package/dist/core/queue/queueAdmin.response.d.ts +1 -0
- package/dist/core/queue/queueAdmin.response.js +8 -0
- package/dist/core/queue/queueAdmin.service.d.ts +5 -4
- package/dist/core/queue/queueAdmin.service.js +12 -10
- package/dist/core/queue/redisJobEvents.bridge.d.ts +10 -0
- package/dist/core/queue/redisJobEvents.bridge.js +61 -0
- package/dist/core/queue/redisJobEvents.publisher.d.ts +14 -0
- package/dist/core/queue/redisJobEvents.publisher.js +43 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.js +46 -3
- package/dist/rlCore.module.d.ts +1 -0
- package/dist/rlCore.module.js +30 -0
- package/package.json +2 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { INestApplicationContext } from "@nestjs/common";
|
|
2
|
+
import { IEntryNestModule } from "@nestjs/core";
|
|
3
|
+
export interface BootstrapWorkerOptions {
|
|
4
|
+
name?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const bootstrapWorker: (workerModule: IEntryNestModule, options?: BootstrapWorkerOptions) => Promise<INestApplicationContext>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bootstrapWorker = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const core_1 = require("@nestjs/core");
|
|
6
|
+
const exportHandler_registry_1 = require("../export/exportHandler.registry");
|
|
7
|
+
const winston_config_1 = require("../logger/winston.config");
|
|
8
|
+
const bootstrapWorker = async (workerModule, options = {}) => {
|
|
9
|
+
const app = await core_1.NestFactory.createApplicationContext(workerModule, {
|
|
10
|
+
logger: (0, winston_config_1.createAppLogger)(),
|
|
11
|
+
});
|
|
12
|
+
const logger = new common_1.Logger("Worker");
|
|
13
|
+
app.enableShutdownHooks();
|
|
14
|
+
const name = options.name ?? "consumer";
|
|
15
|
+
const handlers = resolveExportHandlers(app);
|
|
16
|
+
logger.log(`Consumer "${name}" no ar${handlers.length > 0 ? ` — relatórios: ${handlers.join(", ")}` : ""}`);
|
|
17
|
+
return app;
|
|
18
|
+
};
|
|
19
|
+
exports.bootstrapWorker = bootstrapWorker;
|
|
20
|
+
const resolveExportHandlers = (app) => {
|
|
21
|
+
try {
|
|
22
|
+
return app.get(exportHandler_registry_1.ExportHandlerRegistry, { strict: false }).names();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -62,6 +62,13 @@ export declare const envSchema: z.ZodObject<{
|
|
|
62
62
|
REDIS_HOST: z.ZodOptional<z.ZodString>;
|
|
63
63
|
REDIS_PORT: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
64
64
|
REDIS_PASSWORD: z.ZodOptional<z.ZodString>;
|
|
65
|
+
EXPORT_DIR: z.ZodDefault<z.ZodString>;
|
|
66
|
+
EXPORT_TTL_HOURS: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
67
|
+
EXPORT_CLEANUP_ENABLED: z.ZodDefault<z.ZodPipe<z.ZodEnum<{
|
|
68
|
+
true: "true";
|
|
69
|
+
false: "false";
|
|
70
|
+
}>, z.ZodTransform<boolean, "true" | "false">>>;
|
|
71
|
+
EXPORT_MAX_ROWS: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
65
72
|
TOKEN_CLEANUP_CRON: z.ZodDefault<z.ZodString>;
|
|
66
73
|
AUDIT_SLOW_REQUEST_MS: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
67
74
|
AUDIT_IP_SALT: z.ZodOptional<z.ZodString>;
|
|
@@ -81,6 +81,10 @@ exports.envSchema = zod_1.z
|
|
|
81
81
|
REDIS_HOST: zod_1.z.string().min(1).optional(),
|
|
82
82
|
REDIS_PORT: zod_1.z.coerce.number().int().positive().default(6379),
|
|
83
83
|
REDIS_PASSWORD: zod_1.z.string().optional(),
|
|
84
|
+
EXPORT_DIR: zod_1.z.string().min(1).default("export"),
|
|
85
|
+
EXPORT_TTL_HOURS: zod_1.z.coerce.number().int().positive().default(3),
|
|
86
|
+
EXPORT_CLEANUP_ENABLED: booleanFromString.default(true),
|
|
87
|
+
EXPORT_MAX_ROWS: zod_1.z.coerce.number().int().positive().default(500_000),
|
|
84
88
|
TOKEN_CLEANUP_CRON: zod_1.z.string().default("0 */6 * * *"),
|
|
85
89
|
AUDIT_SLOW_REQUEST_MS: zod_1.z.coerce.number().int().positive().default(1000),
|
|
86
90
|
AUDIT_IP_SALT: zod_1.z.string().optional(),
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StreamableFile } from "@nestjs/common";
|
|
2
|
+
import type { Response } from "express";
|
|
3
|
+
import { AuthenticatedUser } from "../auth/authenticatedUser.interface";
|
|
4
|
+
import { ExportService } from "./export.service";
|
|
5
|
+
import { ExportAcceptedResponse } from "./exportAccepted.response";
|
|
6
|
+
import { ExportStorageService } from "./exportStorage.service";
|
|
7
|
+
import { RequestExportCommand } from "./requestExport.command";
|
|
8
|
+
export declare class ExportController {
|
|
9
|
+
private readonly exports;
|
|
10
|
+
private readonly storage;
|
|
11
|
+
constructor(exports: ExportService, storage: ExportStorageService);
|
|
12
|
+
request(user: AuthenticatedUser, handler: string, command: RequestExportCommand): Promise<ExportAcceptedResponse>;
|
|
13
|
+
download(user: AuthenticatedUser, jobId: string, response: Response): Promise<StreamableFile>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ExportController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
18
|
+
const fs_1 = require("fs");
|
|
19
|
+
const currentUser_decorator_1 = require("../auth/decorators/currentUser.decorator");
|
|
20
|
+
const permissions_guard_1 = require("../auth/guards/permissions.guard");
|
|
21
|
+
const export_service_1 = require("./export.service");
|
|
22
|
+
const exportAccepted_response_1 = require("./exportAccepted.response");
|
|
23
|
+
const exportStorage_service_1 = require("./exportStorage.service");
|
|
24
|
+
const requestExport_command_1 = require("./requestExport.command");
|
|
25
|
+
const XLSX_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
26
|
+
const sanitizeFileName = (name) => name.replace(/["\\/\r\n]+/g, "_").slice(0, 120) || "relatorio.xlsx";
|
|
27
|
+
let ExportController = class ExportController {
|
|
28
|
+
constructor(exports, storage) {
|
|
29
|
+
this.exports = exports;
|
|
30
|
+
this.storage = storage;
|
|
31
|
+
}
|
|
32
|
+
async request(user, handler, command) {
|
|
33
|
+
const ref = await this.exports.request(user, handler, command);
|
|
34
|
+
return { jobId: ref.jobId, name: ref.name };
|
|
35
|
+
}
|
|
36
|
+
async download(user, jobId, response) {
|
|
37
|
+
const status = await this.exports.status(jobId, user.id);
|
|
38
|
+
if (status.state === "failed") {
|
|
39
|
+
throw new common_1.ConflictException(status.error?.message ?? "A geração do relatório falhou");
|
|
40
|
+
}
|
|
41
|
+
if (status.state !== "completed" || !status.summary) {
|
|
42
|
+
throw new common_1.ConflictException("O relatório ainda está sendo gerado");
|
|
43
|
+
}
|
|
44
|
+
if (!(await this.storage.exists(user.id, jobId))) {
|
|
45
|
+
throw new common_1.GoneException("Este relatório expirou. Gere novamente para baixar.");
|
|
46
|
+
}
|
|
47
|
+
const fileName = sanitizeFileName(status.summary.fileName);
|
|
48
|
+
response.setHeader("Content-Type", XLSX_CONTENT_TYPE);
|
|
49
|
+
response.setHeader("Content-Disposition", `attachment; filename="${fileName}"`);
|
|
50
|
+
return new common_1.StreamableFile((0, fs_1.createReadStream)(this.storage.pathFor(user.id, jobId)));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
exports.ExportController = ExportController;
|
|
54
|
+
__decorate([
|
|
55
|
+
(0, common_1.Post)(":handler"),
|
|
56
|
+
(0, common_1.HttpCode)(common_1.HttpStatus.ACCEPTED),
|
|
57
|
+
(0, swagger_1.ApiParam)({ name: "handler", example: "funkos" }),
|
|
58
|
+
(0, swagger_1.ApiResponse)({ status: 202, type: exportAccepted_response_1.ExportAcceptedResponse }),
|
|
59
|
+
__param(0, (0, currentUser_decorator_1.CurrentUser)()),
|
|
60
|
+
__param(1, (0, common_1.Param)("handler")),
|
|
61
|
+
__param(2, (0, common_1.Body)()),
|
|
62
|
+
__metadata("design:type", Function),
|
|
63
|
+
__metadata("design:paramtypes", [Object, String, requestExport_command_1.RequestExportCommand]),
|
|
64
|
+
__metadata("design:returntype", Promise)
|
|
65
|
+
], ExportController.prototype, "request", null);
|
|
66
|
+
__decorate([
|
|
67
|
+
(0, common_1.Get)(":jobId"),
|
|
68
|
+
(0, swagger_1.ApiParam)({ name: "jobId", example: "184" }),
|
|
69
|
+
(0, swagger_1.ApiOkResponse)({ description: "A planilha", type: common_1.StreamableFile }),
|
|
70
|
+
(0, swagger_1.ApiResponse)({ status: 409, description: "Ainda em geração" }),
|
|
71
|
+
(0, swagger_1.ApiResponse)({ status: 410, description: "O arquivo expirou" }),
|
|
72
|
+
__param(0, (0, currentUser_decorator_1.CurrentUser)()),
|
|
73
|
+
__param(1, (0, common_1.Param)("jobId")),
|
|
74
|
+
__param(2, (0, common_1.Res)({ passthrough: true })),
|
|
75
|
+
__metadata("design:type", Function),
|
|
76
|
+
__metadata("design:paramtypes", [Object, String, Object]),
|
|
77
|
+
__metadata("design:returntype", Promise)
|
|
78
|
+
], ExportController.prototype, "download", null);
|
|
79
|
+
exports.ExportController = ExportController = __decorate([
|
|
80
|
+
(0, swagger_1.ApiTags)("Exports"),
|
|
81
|
+
(0, swagger_1.ApiBearerAuth)(),
|
|
82
|
+
(0, common_1.UseGuards)(permissions_guard_1.PermissionsGuard),
|
|
83
|
+
(0, common_1.Controller)({ path: "exports", version: "1" }),
|
|
84
|
+
__metadata("design:paramtypes", [export_service_1.ExportService,
|
|
85
|
+
exportStorage_service_1.ExportStorageService])
|
|
86
|
+
], ExportController);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ExportModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const core_1 = require("@nestjs/core");
|
|
12
|
+
const exportEngine_service_1 = require("./exportEngine.service");
|
|
13
|
+
const exportHandler_registry_1 = require("./exportHandler.registry");
|
|
14
|
+
const exportStorage_service_1 = require("./exportStorage.service");
|
|
15
|
+
let ExportModule = class ExportModule {
|
|
16
|
+
};
|
|
17
|
+
exports.ExportModule = ExportModule;
|
|
18
|
+
exports.ExportModule = ExportModule = __decorate([
|
|
19
|
+
(0, common_1.Module)({
|
|
20
|
+
imports: [core_1.DiscoveryModule],
|
|
21
|
+
providers: [exportHandler_registry_1.ExportHandlerRegistry, exportEngine_service_1.ExportEngineService, exportStorage_service_1.ExportStorageService],
|
|
22
|
+
exports: [exportHandler_registry_1.ExportHandlerRegistry, exportEngine_service_1.ExportEngineService, exportStorage_service_1.ExportStorageService],
|
|
23
|
+
})
|
|
24
|
+
], ExportModule);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Logger } from "@nestjs/common";
|
|
2
|
+
import { ExportEngineService } from "./exportEngine.service";
|
|
3
|
+
import { ExportJobPayload, ExportJobSummary } from "./exportHandler.interface";
|
|
4
|
+
import { ExportHandlerRegistry } from "./exportHandler.registry";
|
|
5
|
+
import { ExportStorageService } from "./exportStorage.service";
|
|
6
|
+
import { JobContext } from "../queue/job.interface";
|
|
7
|
+
import { JobEventsService } from "../queue/jobEvents.service";
|
|
8
|
+
import { JobWorkerHost } from "../queue/jobWorkerHost";
|
|
9
|
+
export declare class ExportProcessor extends JobWorkerHost<ExportJobPayload, ExportJobSummary> {
|
|
10
|
+
private readonly registry;
|
|
11
|
+
private readonly engine;
|
|
12
|
+
private readonly storage;
|
|
13
|
+
protected readonly logger: Logger;
|
|
14
|
+
constructor(jobEvents: JobEventsService, registry: ExportHandlerRegistry, engine: ExportEngineService, storage: ExportStorageService);
|
|
15
|
+
handle(job: JobContext<ExportJobPayload>): Promise<ExportJobSummary>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var ExportProcessor_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.ExportProcessor = void 0;
|
|
14
|
+
const bullmq_1 = require("@nestjs/bullmq");
|
|
15
|
+
const common_1 = require("@nestjs/common");
|
|
16
|
+
const bullmq_2 = require("bullmq");
|
|
17
|
+
const exportEngine_service_1 = require("./exportEngine.service");
|
|
18
|
+
const exportHandler_registry_1 = require("./exportHandler.registry");
|
|
19
|
+
const exportStorage_service_1 = require("./exportStorage.service");
|
|
20
|
+
const jobEvents_service_1 = require("../queue/jobEvents.service");
|
|
21
|
+
const jobWorkerHost_1 = require("../queue/jobWorkerHost");
|
|
22
|
+
const queue_constants_1 = require("../queue/queue.constants");
|
|
23
|
+
let ExportProcessor = ExportProcessor_1 = class ExportProcessor extends jobWorkerHost_1.JobWorkerHost {
|
|
24
|
+
constructor(jobEvents, registry, engine, storage) {
|
|
25
|
+
super(jobEvents);
|
|
26
|
+
this.registry = registry;
|
|
27
|
+
this.engine = engine;
|
|
28
|
+
this.storage = storage;
|
|
29
|
+
this.logger = new common_1.Logger(ExportProcessor_1.name);
|
|
30
|
+
}
|
|
31
|
+
async handle(job) {
|
|
32
|
+
const { jobId, ownerId, payload } = job;
|
|
33
|
+
const handler = this.registry.find(payload.handler);
|
|
34
|
+
if (!handler) {
|
|
35
|
+
throw new bullmq_2.UnrecoverableError(`Relatório "${payload.handler}" não registrado neste consumer`);
|
|
36
|
+
}
|
|
37
|
+
const sink = await this.storage.openWriteStream(ownerId, jobId);
|
|
38
|
+
try {
|
|
39
|
+
const { totalRows } = await this.engine.run(handler, payload, ownerId, sink, async (processed) => {
|
|
40
|
+
await job.report(processed, 0, `${processed} linha(s)`);
|
|
41
|
+
});
|
|
42
|
+
return { fileName: payload.fileName, totalRows };
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
sink.destroy();
|
|
46
|
+
await this.storage.remove(ownerId, jobId).catch(() => undefined);
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
exports.ExportProcessor = ExportProcessor;
|
|
52
|
+
exports.ExportProcessor = ExportProcessor = ExportProcessor_1 = __decorate([
|
|
53
|
+
(0, bullmq_1.Processor)(queue_constants_1.EXPORTS_QUEUE, {
|
|
54
|
+
concurrency: queue_constants_1.EXPORT_CONCURRENCY,
|
|
55
|
+
lockDuration: queue_constants_1.EXPORT_LOCK_DURATION_MS,
|
|
56
|
+
autorun: false,
|
|
57
|
+
}),
|
|
58
|
+
__metadata("design:paramtypes", [jobEvents_service_1.JobEventsService,
|
|
59
|
+
exportHandler_registry_1.ExportHandlerRegistry,
|
|
60
|
+
exportEngine_service_1.ExportEngineService,
|
|
61
|
+
exportStorage_service_1.ExportStorageService])
|
|
62
|
+
], ExportProcessor);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AuthenticatedUser } from "../auth/authenticatedUser.interface";
|
|
2
|
+
import { ExportJobSummary } from "./exportHandler.interface";
|
|
3
|
+
import { ExportHandlerRegistry } from "./exportHandler.registry";
|
|
4
|
+
import { RequestExportCommand } from "./requestExport.command";
|
|
5
|
+
import { JobRef, JobStatus } from "../queue/job.interface";
|
|
6
|
+
import { JobProducer } from "../queue/job.producer";
|
|
7
|
+
export declare class ExportService {
|
|
8
|
+
private readonly registry;
|
|
9
|
+
private readonly producer;
|
|
10
|
+
constructor(registry: ExportHandlerRegistry, producer: JobProducer);
|
|
11
|
+
request(user: AuthenticatedUser, name: string, command: RequestExportCommand): Promise<JobRef>;
|
|
12
|
+
status(jobId: string, ownerId: string): Promise<JobStatus<ExportJobSummary>>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ExportService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const exportHandler_registry_1 = require("./exportHandler.registry");
|
|
15
|
+
const parseFilter_util_1 = require("../query/parseFilter.util");
|
|
16
|
+
const job_producer_1 = require("../queue/job.producer");
|
|
17
|
+
const queue_constants_1 = require("../queue/queue.constants");
|
|
18
|
+
let ExportService = class ExportService {
|
|
19
|
+
constructor(registry, producer) {
|
|
20
|
+
this.registry = registry;
|
|
21
|
+
this.producer = producer;
|
|
22
|
+
}
|
|
23
|
+
async request(user, name, command) {
|
|
24
|
+
const handler = this.registry.require(name);
|
|
25
|
+
if (handler.permission && !user.permissions.includes(handler.permission)) {
|
|
26
|
+
throw new common_1.ForbiddenException("Você não tem permissão para exportar este relatório");
|
|
27
|
+
}
|
|
28
|
+
if (!this.producer.isAvailable(queue_constants_1.EXPORTS_QUEUE)) {
|
|
29
|
+
throw new common_1.ServiceUnavailableException("Geração de relatórios indisponível neste ambiente");
|
|
30
|
+
}
|
|
31
|
+
const filter = (0, parseFilter_util_1.parseFilter)(command.filter, handler.catalog, user.permissions);
|
|
32
|
+
const payload = {
|
|
33
|
+
handler: handler.name,
|
|
34
|
+
filter,
|
|
35
|
+
search: command.search,
|
|
36
|
+
sortBy: command.sortBy,
|
|
37
|
+
sortDir: command.sortDir,
|
|
38
|
+
fileName: handler.buildFileName(),
|
|
39
|
+
};
|
|
40
|
+
return await this.producer.enqueue(handler.name, payload, {
|
|
41
|
+
ownerId: user.id,
|
|
42
|
+
queue: queue_constants_1.EXPORTS_QUEUE,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async status(jobId, ownerId) {
|
|
46
|
+
return await this.producer.status(jobId, ownerId, queue_constants_1.EXPORTS_QUEUE);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.ExportService = ExportService;
|
|
50
|
+
exports.ExportService = ExportService = __decorate([
|
|
51
|
+
(0, common_1.Injectable)(),
|
|
52
|
+
__metadata("design:paramtypes", [exportHandler_registry_1.ExportHandlerRegistry,
|
|
53
|
+
job_producer_1.JobProducer])
|
|
54
|
+
], ExportService);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ExportAcceptedResponse = void 0;
|
|
13
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
14
|
+
class ExportAcceptedResponse {
|
|
15
|
+
}
|
|
16
|
+
exports.ExportAcceptedResponse = ExportAcceptedResponse;
|
|
17
|
+
__decorate([
|
|
18
|
+
(0, swagger_1.ApiProperty)({ example: "184" }),
|
|
19
|
+
__metadata("design:type", String)
|
|
20
|
+
], ExportAcceptedResponse.prototype, "jobId", void 0);
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, swagger_1.ApiProperty)({ example: "funkos" }),
|
|
23
|
+
__metadata("design:type", String)
|
|
24
|
+
], ExportAcceptedResponse.prototype, "name", void 0);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ExportApiModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const export_controller_1 = require("./export.controller");
|
|
12
|
+
const export_module_1 = require("./export.module");
|
|
13
|
+
const export_service_1 = require("./export.service");
|
|
14
|
+
const exportCleanup_service_1 = require("./exportCleanup.service");
|
|
15
|
+
let ExportApiModule = class ExportApiModule {
|
|
16
|
+
};
|
|
17
|
+
exports.ExportApiModule = ExportApiModule;
|
|
18
|
+
exports.ExportApiModule = ExportApiModule = __decorate([
|
|
19
|
+
(0, common_1.Module)({
|
|
20
|
+
imports: [export_module_1.ExportModule],
|
|
21
|
+
controllers: [export_controller_1.ExportController],
|
|
22
|
+
providers: [export_service_1.ExportService, exportCleanup_service_1.ExportCleanupService],
|
|
23
|
+
exports: [export_service_1.ExportService],
|
|
24
|
+
})
|
|
25
|
+
], ExportApiModule);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EnvService } from "../config/env.service";
|
|
2
|
+
import { ExportStorageService } from "./exportStorage.service";
|
|
3
|
+
export declare class ExportCleanupService {
|
|
4
|
+
private readonly storage;
|
|
5
|
+
private readonly env;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
constructor(storage: ExportStorageService, env: EnvService);
|
|
8
|
+
sweep(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var ExportCleanupService_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.ExportCleanupService = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const schedule_1 = require("@nestjs/schedule");
|
|
16
|
+
const env_service_1 = require("../config/env.service");
|
|
17
|
+
const exportStorage_service_1 = require("./exportStorage.service");
|
|
18
|
+
const HOUR_IN_MS = 60 * 60 * 1000;
|
|
19
|
+
let ExportCleanupService = ExportCleanupService_1 = class ExportCleanupService {
|
|
20
|
+
constructor(storage, env) {
|
|
21
|
+
this.storage = storage;
|
|
22
|
+
this.env = env;
|
|
23
|
+
this.logger = new common_1.Logger(ExportCleanupService_1.name);
|
|
24
|
+
}
|
|
25
|
+
async sweep() {
|
|
26
|
+
if (!this.env.get("EXPORT_CLEANUP_ENABLED")) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const maxAgeMs = this.env.get("EXPORT_TTL_HOURS") * HOUR_IN_MS;
|
|
30
|
+
try {
|
|
31
|
+
await this.storage.removeExpired(maxAgeMs);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
this.logger.error(`Falha na faxina de relatórios: ${error.message}`, error.stack);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.ExportCleanupService = ExportCleanupService;
|
|
39
|
+
__decorate([
|
|
40
|
+
(0, schedule_1.Cron)(schedule_1.CronExpression.EVERY_30_MINUTES),
|
|
41
|
+
__metadata("design:type", Function),
|
|
42
|
+
__metadata("design:paramtypes", []),
|
|
43
|
+
__metadata("design:returntype", Promise)
|
|
44
|
+
], ExportCleanupService.prototype, "sweep", null);
|
|
45
|
+
exports.ExportCleanupService = ExportCleanupService = ExportCleanupService_1 = __decorate([
|
|
46
|
+
(0, common_1.Injectable)(),
|
|
47
|
+
__metadata("design:paramtypes", [exportStorage_service_1.ExportStorageService,
|
|
48
|
+
env_service_1.EnvService])
|
|
49
|
+
], ExportCleanupService);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExportColumnFormat = void 0;
|
|
4
|
+
var ExportColumnFormat;
|
|
5
|
+
(function (ExportColumnFormat) {
|
|
6
|
+
ExportColumnFormat["Date"] = "DATE";
|
|
7
|
+
ExportColumnFormat["DateTime"] = "DATETIME";
|
|
8
|
+
ExportColumnFormat["Currency"] = "CURRENCY";
|
|
9
|
+
})(ExportColumnFormat || (exports.ExportColumnFormat = ExportColumnFormat = {}));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { WriteStream } from "fs";
|
|
2
|
+
import { DataSource } from "typeorm";
|
|
3
|
+
import { EnvService } from "../config/env.service";
|
|
4
|
+
import { ExportHandler, ExportJobPayload } from "./exportHandler.interface";
|
|
5
|
+
export interface ExportEngineResult {
|
|
6
|
+
totalRows: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class ExportEngineService {
|
|
9
|
+
private readonly dataSource;
|
|
10
|
+
private readonly env;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
constructor(dataSource: DataSource, env: EnvService);
|
|
13
|
+
run(handler: ExportHandler, payload: ExportJobPayload, ownerId: string, sink: WriteStream, onProgress: (processed: number) => Promise<void>): Promise<ExportEngineResult>;
|
|
14
|
+
private buildQuery;
|
|
15
|
+
}
|