@loopstack/api 0.8.1 → 0.10.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/CHANGELOG.md +24 -0
- package/LICENSE +43 -21
- package/dist/controllers/config.controller.d.ts +3 -3
- package/dist/controllers/config.controller.js +25 -21
- package/dist/controllers/config.controller.js.map +1 -1
- package/dist/controllers/dashboard.controller.d.ts +7 -0
- package/dist/controllers/dashboard.controller.js +51 -0
- package/dist/controllers/dashboard.controller.js.map +1 -0
- package/dist/controllers/pipeline.controller.js.map +1 -1
- package/dist/controllers/workspace.controller.js +0 -1
- package/dist/controllers/workspace.controller.js.map +1 -1
- package/dist/dtos/dashboard.dto.d.ts +12 -0
- package/dist/dtos/dashboard.dto.js +96 -0
- package/dist/dtos/dashboard.dto.js.map +1 -0
- package/dist/dtos/pipeline-config.dto.d.ts +0 -1
- package/dist/dtos/pipeline-config.dto.js +0 -9
- package/dist/dtos/pipeline-config.dto.js.map +1 -1
- package/dist/dtos/pipeline-create.dto.d.ts +1 -1
- package/dist/dtos/pipeline-create.dto.js +3 -2
- package/dist/dtos/pipeline-create.dto.js.map +1 -1
- package/dist/dtos/pipeline-item.dto.d.ts +1 -0
- package/dist/dtos/pipeline-item.dto.js +9 -0
- package/dist/dtos/pipeline-item.dto.js.map +1 -1
- package/dist/dtos/pipeline.dto.d.ts +1 -0
- package/dist/dtos/pipeline.dto.js +9 -0
- package/dist/dtos/pipeline.dto.js.map +1 -1
- package/dist/loopstack-api.module.js +11 -6
- package/dist/loopstack-api.module.js.map +1 -1
- package/dist/services/dashboard.service.d.ts +18 -0
- package/dist/services/dashboard.service.js +83 -0
- package/dist/services/dashboard.service.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -7
- package/dist/controllers/auth.controller.d.ts +0 -9
- package/dist/controllers/auth.controller.js +0 -61
- package/dist/controllers/auth.controller.js.map +0 -1
- package/dist/guards/dev-auth.guard.d.ts +0 -8
- package/dist/guards/dev-auth.guard.js +0 -34
- package/dist/guards/dev-auth.guard.js.map +0 -1
- package/dist/guards/jwt-auth.guard.d.ts +0 -4
- package/dist/guards/jwt-auth.guard.js +0 -18
- package/dist/guards/jwt-auth.guard.js.map +0 -1
- package/dist/interfaces/api-request.type.d.ts +0 -6
- package/dist/interfaces/api-request.type.js +0 -3
- package/dist/interfaces/api-request.type.js.map +0 -1
|
@@ -11,7 +11,6 @@ const common_1 = require("@nestjs/common");
|
|
|
11
11
|
const loop_api_module_definition_1 = require("./loop-api.module-definition");
|
|
12
12
|
const pipeline_controller_1 = require("./controllers/pipeline.controller");
|
|
13
13
|
const pipeline_api_service_1 = require("./services/pipeline-api.service");
|
|
14
|
-
const config_1 = require("@nestjs/config");
|
|
15
14
|
const typeorm_1 = require("@nestjs/typeorm");
|
|
16
15
|
const workspace_controller_1 = require("./controllers/workspace.controller");
|
|
17
16
|
const workspace_api_service_1 = require("./services/workspace-api.service");
|
|
@@ -35,6 +34,8 @@ const ws_event_emitter_service_1 = require("./services/ws-event-emitter.service"
|
|
|
35
34
|
const event_emitter_1 = require("@nestjs/event-emitter");
|
|
36
35
|
const microservices_1 = require("@nestjs/microservices");
|
|
37
36
|
const config_controller_1 = require("./controllers/config.controller");
|
|
37
|
+
const dashboard_controller_1 = require("./controllers/dashboard.controller");
|
|
38
|
+
const dashboard_service_1 = require("./services/dashboard.service");
|
|
38
39
|
var cookieParser = require('cookie-parser');
|
|
39
40
|
let LoopstackApiModule = class LoopstackApiModule extends loop_api_module_definition_1.ConfigurableModuleClass {
|
|
40
41
|
static setup(app, options = {}) {
|
|
@@ -68,9 +69,6 @@ exports.LoopstackApiModule = LoopstackApiModule;
|
|
|
68
69
|
exports.LoopstackApiModule = LoopstackApiModule = __decorate([
|
|
69
70
|
(0, common_1.Module)({
|
|
70
71
|
imports: [
|
|
71
|
-
config_1.ConfigModule.forRoot({
|
|
72
|
-
isGlobal: true,
|
|
73
|
-
}),
|
|
74
72
|
typeorm_1.TypeOrmModule.forFeature([
|
|
75
73
|
shared_1.PipelineEntity,
|
|
76
74
|
shared_1.WorkspaceEntity,
|
|
@@ -90,7 +88,7 @@ exports.LoopstackApiModule = LoopstackApiModule = __decorate([
|
|
|
90
88
|
},
|
|
91
89
|
]),
|
|
92
90
|
event_emitter_1.EventEmitterModule.forRoot(),
|
|
93
|
-
core_1.LoopCoreModule
|
|
91
|
+
core_1.LoopCoreModule,
|
|
94
92
|
passport_1.PassportModule,
|
|
95
93
|
jwt_1.JwtModule.register({
|
|
96
94
|
secret: process.env.JWT_SECRET ?? 'NO SECRET',
|
|
@@ -104,6 +102,7 @@ exports.LoopstackApiModule = LoopstackApiModule = __decorate([
|
|
|
104
102
|
document_controller_1.DocumentController,
|
|
105
103
|
namespace_controller_1.NamespaceController,
|
|
106
104
|
config_controller_1.ConfigController,
|
|
105
|
+
dashboard_controller_1.DashboardController,
|
|
107
106
|
],
|
|
108
107
|
providers: [
|
|
109
108
|
auth_service_1.AuthService,
|
|
@@ -116,8 +115,14 @@ exports.LoopstackApiModule = LoopstackApiModule = __decorate([
|
|
|
116
115
|
workflow_api_service_1.WorkflowApiService,
|
|
117
116
|
document_api_service_1.DocumentApiService,
|
|
118
117
|
namespace_api_service_1.NamespaceApiService,
|
|
118
|
+
dashboard_service_1.DashboardService,
|
|
119
|
+
],
|
|
120
|
+
exports: [
|
|
121
|
+
pipeline_api_service_1.PipelineApiService,
|
|
122
|
+
workspace_api_service_1.WorkspaceApiService,
|
|
123
|
+
processor_api_service_1.ProcessorApiService,
|
|
124
|
+
dashboard_service_1.DashboardService,
|
|
119
125
|
],
|
|
120
|
-
exports: [pipeline_api_service_1.PipelineApiService, workspace_api_service_1.WorkspaceApiService, processor_api_service_1.ProcessorApiService],
|
|
121
126
|
})
|
|
122
127
|
], LoopstackApiModule);
|
|
123
128
|
//# sourceMappingURL=loopstack-api.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loopstack-api.module.js","sourceRoot":"","sources":["../src/loopstack-api.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA0E;AAC1E,6EAAuE;AACvE,2EAAuE;AACvE,0EAAqE;AACrE,
|
|
1
|
+
{"version":3,"file":"loopstack-api.module.js","sourceRoot":"","sources":["../src/loopstack-api.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Repository } from 'typeorm';
|
|
2
|
+
import { PipelineEntity, WorkflowEntity } from '@loopstack/shared';
|
|
3
|
+
export interface DashboardStats {
|
|
4
|
+
workspaceCount: number;
|
|
5
|
+
totalAutomations: number;
|
|
6
|
+
totalAutomationRuns: number;
|
|
7
|
+
completedRuns: number;
|
|
8
|
+
errorRuns: number;
|
|
9
|
+
inProgressRuns: number;
|
|
10
|
+
recentErrors: WorkflowEntity[];
|
|
11
|
+
recentRuns: PipelineEntity[];
|
|
12
|
+
}
|
|
13
|
+
export declare class DashboardService {
|
|
14
|
+
private readonly pipelineRepository;
|
|
15
|
+
private readonly workflowRepository;
|
|
16
|
+
constructor(pipelineRepository: Repository<PipelineEntity>, workflowRepository: Repository<WorkflowEntity>);
|
|
17
|
+
getDashboardStats(user: string | null): Promise<DashboardStats>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
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.DashboardService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const typeorm_1 = require("typeorm");
|
|
18
|
+
const typeorm_2 = require("@nestjs/typeorm");
|
|
19
|
+
const shared_1 = require("@loopstack/shared");
|
|
20
|
+
let DashboardService = class DashboardService {
|
|
21
|
+
pipelineRepository;
|
|
22
|
+
workflowRepository;
|
|
23
|
+
constructor(pipelineRepository, workflowRepository) {
|
|
24
|
+
this.pipelineRepository = pipelineRepository;
|
|
25
|
+
this.workflowRepository = workflowRepository;
|
|
26
|
+
}
|
|
27
|
+
async getDashboardStats(user) {
|
|
28
|
+
const workspaceCount = 0;
|
|
29
|
+
const automations = 0;
|
|
30
|
+
const userFilter = user === null ? (0, typeorm_1.IsNull)() : user;
|
|
31
|
+
const baseQuery = this.pipelineRepository
|
|
32
|
+
.createQueryBuilder('pipeline')
|
|
33
|
+
.where({ createdBy: userFilter });
|
|
34
|
+
const [total, completed, failed, inProgress, recentRuns, recentErrors] = await Promise.all([
|
|
35
|
+
baseQuery.clone().getCount(),
|
|
36
|
+
baseQuery
|
|
37
|
+
.clone()
|
|
38
|
+
.andWhere({ status: shared_1.PipelineState.Completed })
|
|
39
|
+
.getCount(),
|
|
40
|
+
baseQuery.clone().andWhere({ status: shared_1.PipelineState.Failed }).getCount(),
|
|
41
|
+
baseQuery
|
|
42
|
+
.clone()
|
|
43
|
+
.andWhere(new typeorm_1.Brackets((qb) => {
|
|
44
|
+
qb.where({ status: shared_1.PipelineState.Running })
|
|
45
|
+
.orWhere({ status: shared_1.PipelineState.Pending })
|
|
46
|
+
.orWhere({ status: shared_1.PipelineState.Canceled })
|
|
47
|
+
.orWhere({ status: shared_1.PipelineState.Paused });
|
|
48
|
+
}))
|
|
49
|
+
.getCount(),
|
|
50
|
+
baseQuery
|
|
51
|
+
.clone()
|
|
52
|
+
.orderBy('pipeline.createdAt', 'DESC')
|
|
53
|
+
.take(7)
|
|
54
|
+
.getMany(),
|
|
55
|
+
this.workflowRepository
|
|
56
|
+
.createQueryBuilder('workflow')
|
|
57
|
+
.where({ createdBy: userFilter })
|
|
58
|
+
.andWhere({ status: shared_1.WorkflowState.Failed })
|
|
59
|
+
.orderBy('workflow.createdAt', 'DESC')
|
|
60
|
+
.take(7)
|
|
61
|
+
.getMany(),
|
|
62
|
+
]);
|
|
63
|
+
return {
|
|
64
|
+
workspaceCount,
|
|
65
|
+
totalAutomations: automations,
|
|
66
|
+
totalAutomationRuns: total,
|
|
67
|
+
completedRuns: completed,
|
|
68
|
+
errorRuns: failed,
|
|
69
|
+
inProgressRuns: inProgress,
|
|
70
|
+
recentErrors,
|
|
71
|
+
recentRuns,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
exports.DashboardService = DashboardService;
|
|
76
|
+
exports.DashboardService = DashboardService = __decorate([
|
|
77
|
+
(0, common_1.Injectable)(),
|
|
78
|
+
__param(0, (0, typeorm_2.InjectRepository)(shared_1.PipelineEntity)),
|
|
79
|
+
__param(1, (0, typeorm_2.InjectRepository)(shared_1.WorkflowEntity)),
|
|
80
|
+
__metadata("design:paramtypes", [typeorm_1.Repository,
|
|
81
|
+
typeorm_1.Repository])
|
|
82
|
+
], DashboardService);
|
|
83
|
+
//# sourceMappingURL=dashboard.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.service.js","sourceRoot":"","sources":["../../src/services/dashboard.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,qCAAuD;AACvD,6CAAmD;AACnD,8CAK2B;AAcpB,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IAGR;IAEA;IAJnB,YAEmB,kBAA8C,EAE9C,kBAA8C;QAF9C,uBAAkB,GAAlB,kBAAkB,CAA4B;QAE9C,uBAAkB,GAAlB,kBAAkB,CAA4B;IAC9D,CAAC;IAEJ,KAAK,CAAC,iBAAiB,CAAC,IAAmB;QAEzC,MAAM,cAAc,GAAG,CAAC,CAAC;QAGzB,MAAM,WAAW,GAAG,CAAC,CAAC;QAKtB,MAAM,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAA,gBAAM,GAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACnD,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB;aACtC,kBAAkB,CAAC,UAAU,CAAC;aAC9B,KAAK,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;QAEpC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,GACpE,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;YAC5B,SAAS;iBACN,KAAK,EAAE;iBACP,QAAQ,CAAC,EAAE,MAAM,EAAE,sBAAa,CAAC,SAAS,EAAE,CAAC;iBAC7C,QAAQ,EAAE;YACb,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,sBAAa,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACvE,SAAS;iBACN,KAAK,EAAE;iBACP,QAAQ,CACP,IAAI,kBAAQ,CAAC,CAAC,EAAE,EAAE,EAAE;gBAClB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,sBAAa,CAAC,OAAO,EAAE,CAAC;qBACxC,OAAO,CAAC,EAAE,MAAM,EAAE,sBAAa,CAAC,OAAO,EAAE,CAAC;qBAC1C,OAAO,CAAC,EAAE,MAAM,EAAE,sBAAa,CAAC,QAAQ,EAAE,CAAC;qBAC3C,OAAO,CAAC,EAAE,MAAM,EAAE,sBAAa,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/C,CAAC,CAAC,CACH;iBACA,QAAQ,EAAE;YACb,SAAS;iBACN,KAAK,EAAE;iBACP,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC;iBACrC,IAAI,CAAC,CAAC,CAAC;iBACP,OAAO,EAAE;YACZ,IAAI,CAAC,kBAAkB;iBACpB,kBAAkB,CAAC,UAAU,CAAC;iBAC9B,KAAK,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;iBAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,sBAAa,CAAC,MAAM,EAAE,CAAC;iBAC1C,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC;iBACrC,IAAI,CAAC,CAAC,CAAC;iBACP,OAAO,EAAE;SACb,CAAC,CAAC;QAEL,OAAO;YACL,cAAc;YACd,gBAAgB,EAAE,WAAW;YAC7B,mBAAmB,EAAE,KAAK;YAC1B,aAAa,EAAE,SAAS;YACxB,SAAS,EAAE,MAAM;YACjB,cAAc,EAAE,UAAU;YAC1B,YAAY;YACZ,UAAU;SACX,CAAC;IACJ,CAAC;CACF,CAAA;AAnEY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,0BAAgB,EAAC,uBAAc,CAAC,CAAA;IAEhC,WAAA,IAAA,0BAAgB,EAAC,uBAAc,CAAC,CAAA;qCADI,oBAAU;QAEV,oBAAU;GALtC,gBAAgB,CAmE5B"}
|