@loopstack/remote-file-explorer-module 0.22.3
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/controllers/index.d.ts +2 -0
- package/dist/controllers/index.d.ts.map +1 -0
- package/dist/controllers/index.js +18 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/controllers/remote-file-explorer.controller.d.ts +12 -0
- package/dist/controllers/remote-file-explorer.controller.d.ts.map +1 -0
- package/dist/controllers/remote-file-explorer.controller.js +79 -0
- package/dist/controllers/remote-file-explorer.controller.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/remote-file-explorer.module.d.ts +3 -0
- package/dist/remote-file-explorer.module.d.ts.map +1 -0
- package/dist/remote-file-explorer.module.js +25 -0
- package/dist/remote-file-explorer.module.js.map +1 -0
- package/package.json +73 -0
- package/src/controllers/index.ts +1 -0
- package/src/controllers/remote-file-explorer.controller.ts +55 -0
- package/src/index.ts +2 -0
- package/src/remote-file-explorer.module.ts +12 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/controllers/index.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./remote-file-explorer.controller"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oEAAkD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Repository } from 'typeorm';
|
|
2
|
+
import { CurrentUserInterface, WorkspaceEntity } from '@loopstack/common';
|
|
3
|
+
import { RemoteAgentClient } from '@loopstack/remote-agent-client';
|
|
4
|
+
export declare class RemoteFileExplorerController {
|
|
5
|
+
private readonly remoteAgentClient;
|
|
6
|
+
private readonly workspaceRepository;
|
|
7
|
+
constructor(remoteAgentClient: RemoteAgentClient, workspaceRepository: Repository<WorkspaceEntity>);
|
|
8
|
+
private getAgentUrl;
|
|
9
|
+
getFileTree(workspaceId: string, basePath: string | undefined, user: CurrentUserInterface): Promise<import("@loopstack/remote-agent-client/dist/services/remote-agent-client.service").FileTreeNode[]>;
|
|
10
|
+
readFile(workspaceId: string, filePath: string, user: CurrentUserInterface): Promise<import("@loopstack/remote-agent-client").FileReadResponse>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=remote-file-explorer.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-file-explorer.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/remote-file-explorer.controller.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAe,oBAAoB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,qBAGa,4BAA4B;IAErC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAFnB,iBAAiB,EAAE,iBAAiB,EAEpC,mBAAmB,EAAE,UAAU,CAAC,eAAe,CAAC;YAGrD,WAAW;IAmBnB,WAAW,CACO,WAAW,EAAE,MAAM,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,oBAAoB;IAOrC,QAAQ,CACU,WAAW,EAAE,MAAM,EAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,oBAAoB;CAK5C"}
|
|
@@ -0,0 +1,79 @@
|
|
|
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.RemoteFileExplorerController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
18
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
19
|
+
const typeorm_2 = require("typeorm");
|
|
20
|
+
const common_2 = require("@loopstack/common");
|
|
21
|
+
const remote_agent_client_1 = require("@loopstack/remote-agent-client");
|
|
22
|
+
let RemoteFileExplorerController = class RemoteFileExplorerController {
|
|
23
|
+
remoteAgentClient;
|
|
24
|
+
workspaceRepository;
|
|
25
|
+
constructor(remoteAgentClient, workspaceRepository) {
|
|
26
|
+
this.remoteAgentClient = remoteAgentClient;
|
|
27
|
+
this.workspaceRepository = workspaceRepository;
|
|
28
|
+
}
|
|
29
|
+
async getAgentUrl(workspaceId, userId) {
|
|
30
|
+
const workspace = await this.workspaceRepository.findOne({
|
|
31
|
+
where: { id: workspaceId, createdBy: userId },
|
|
32
|
+
relations: ['environments'],
|
|
33
|
+
});
|
|
34
|
+
if (!workspace) {
|
|
35
|
+
throw new common_1.NotFoundException(`Workspace with ID ${workspaceId} not found`);
|
|
36
|
+
}
|
|
37
|
+
const environment = workspace.environments?.find((e) => !!e.agentUrl);
|
|
38
|
+
if (!environment?.agentUrl) {
|
|
39
|
+
throw new common_1.NotFoundException(`No remote environment configured for workspace ${workspaceId}`);
|
|
40
|
+
}
|
|
41
|
+
return environment.agentUrl;
|
|
42
|
+
}
|
|
43
|
+
async getFileTree(workspaceId, basePath, user) {
|
|
44
|
+
const agentUrl = await this.getAgentUrl(workspaceId, user.userId);
|
|
45
|
+
return this.remoteAgentClient.getFileTree(agentUrl, basePath ?? './src');
|
|
46
|
+
}
|
|
47
|
+
async readFile(workspaceId, filePath, user) {
|
|
48
|
+
const agentUrl = await this.getAgentUrl(workspaceId, user.userId);
|
|
49
|
+
return this.remoteAgentClient.readFile(agentUrl, filePath);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.RemoteFileExplorerController = RemoteFileExplorerController;
|
|
53
|
+
__decorate([
|
|
54
|
+
(0, common_1.Get)('tree'),
|
|
55
|
+
__param(0, (0, common_1.Param)('workspaceId')),
|
|
56
|
+
__param(1, (0, common_1.Query)('path')),
|
|
57
|
+
__param(2, (0, common_2.CurrentUser)()),
|
|
58
|
+
__metadata("design:type", Function),
|
|
59
|
+
__metadata("design:paramtypes", [String, Object, Object]),
|
|
60
|
+
__metadata("design:returntype", Promise)
|
|
61
|
+
], RemoteFileExplorerController.prototype, "getFileTree", null);
|
|
62
|
+
__decorate([
|
|
63
|
+
(0, common_1.Get)('read'),
|
|
64
|
+
__param(0, (0, common_1.Param)('workspaceId')),
|
|
65
|
+
__param(1, (0, common_1.Query)('path')),
|
|
66
|
+
__param(2, (0, common_2.CurrentUser)()),
|
|
67
|
+
__metadata("design:type", Function),
|
|
68
|
+
__metadata("design:paramtypes", [String, String, Object]),
|
|
69
|
+
__metadata("design:returntype", Promise)
|
|
70
|
+
], RemoteFileExplorerController.prototype, "readFile", null);
|
|
71
|
+
exports.RemoteFileExplorerController = RemoteFileExplorerController = __decorate([
|
|
72
|
+
(0, swagger_1.ApiTags)('api/v1/workspaces/:workspaceId/files'),
|
|
73
|
+
(0, common_1.UsePipes)(new common_1.ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true })),
|
|
74
|
+
(0, common_1.Controller)('api/v1/workspaces/:workspaceId/files'),
|
|
75
|
+
__param(1, (0, typeorm_1.InjectRepository)(common_2.WorkspaceEntity)),
|
|
76
|
+
__metadata("design:paramtypes", [remote_agent_client_1.RemoteAgentClient,
|
|
77
|
+
typeorm_2.Repository])
|
|
78
|
+
], RemoteFileExplorerController);
|
|
79
|
+
//# sourceMappingURL=remote-file-explorer.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-file-explorer.controller.js","sourceRoot":"","sources":["../../src/controllers/remote-file-explorer.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4G;AAC5G,6CAA0C;AAC1C,6CAAmD;AACnD,qCAAqC;AACrC,8CAAuF;AACvF,wEAAmE;AAK5D,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IAEpB;IAEA;IAHnB,YACmB,iBAAoC,EAEpC,mBAAgD;QAFhD,sBAAiB,GAAjB,iBAAiB,CAAmB;QAEpC,wBAAmB,GAAnB,mBAAmB,CAA6B;IAChE,CAAC;IAEI,KAAK,CAAC,WAAW,CAAC,WAAmB,EAAE,MAAc;QAC3D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;YACvD,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE;YAC7C,SAAS,EAAE,CAAC,cAAc,CAAC;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,0BAAiB,CAAC,qBAAqB,WAAW,YAAY,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,WAAW,GAAG,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtE,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,0BAAiB,CAAC,kDAAkD,WAAW,EAAE,CAAC,CAAC;QAC/F,CAAC;QAED,OAAO,WAAW,CAAC,QAAQ,CAAC;IAC9B,CAAC;IAGK,AAAN,KAAK,CAAC,WAAW,CACO,WAAmB,EAC1B,QAA4B,EAC5B,IAA0B;QAEzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,QAAQ,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;IAC3E,CAAC;IAGK,AAAN,KAAK,CAAC,QAAQ,CACU,WAAmB,EAC1B,QAAgB,EAChB,IAA0B;QAEzC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7D,CAAC;CACF,CAAA;AA5CY,oEAA4B;AA0BjC;IADL,IAAA,YAAG,EAAC,MAAM,CAAC;IAET,WAAA,IAAA,cAAK,EAAC,aAAa,CAAC,CAAA;IACpB,WAAA,IAAA,cAAK,EAAC,MAAM,CAAC,CAAA;IACb,WAAA,IAAA,oBAAW,GAAE,CAAA;;;;+DAIf;AAGK;IADL,IAAA,YAAG,EAAC,MAAM,CAAC;IAET,WAAA,IAAA,cAAK,EAAC,aAAa,CAAC,CAAA;IACpB,WAAA,IAAA,cAAK,EAAC,MAAM,CAAC,CAAA;IACb,WAAA,IAAA,oBAAW,GAAE,CAAA;;;;4DAIf;uCA3CU,4BAA4B;IAHxC,IAAA,iBAAO,EAAC,sCAAsC,CAAC;IAC/C,IAAA,iBAAQ,EAAC,IAAI,uBAAc,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9F,IAAA,mBAAU,EAAC,sCAAsC,CAAC;IAI9C,WAAA,IAAA,0BAAgB,EAAC,wBAAe,CAAC,CAAA;qCADE,uCAAiB;QAEf,oBAAU;GAJvC,4BAA4B,CA4CxC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./remote-file-explorer.module"), exports);
|
|
18
|
+
__exportStar(require("./controllers"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gEAA8C;AAC9C,gDAA8B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-file-explorer.module.d.ts","sourceRoot":"","sources":["../src/remote-file-explorer.module.ts"],"names":[],"mappings":"AAOA,qBAIa,wBAAwB;CAAG"}
|
|
@@ -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.RemoteFileExplorerModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
12
|
+
const common_2 = require("@loopstack/common");
|
|
13
|
+
const core_1 = require("@loopstack/core");
|
|
14
|
+
const remote_agent_client_1 = require("@loopstack/remote-agent-client");
|
|
15
|
+
const controllers_1 = require("./controllers");
|
|
16
|
+
let RemoteFileExplorerModule = class RemoteFileExplorerModule {
|
|
17
|
+
};
|
|
18
|
+
exports.RemoteFileExplorerModule = RemoteFileExplorerModule;
|
|
19
|
+
exports.RemoteFileExplorerModule = RemoteFileExplorerModule = __decorate([
|
|
20
|
+
(0, common_1.Module)({
|
|
21
|
+
imports: [core_1.LoopCoreModule, remote_agent_client_1.RemoteAgentClientModule, typeorm_1.TypeOrmModule.forFeature([common_2.WorkspaceEntity])],
|
|
22
|
+
controllers: [controllers_1.RemoteFileExplorerController],
|
|
23
|
+
})
|
|
24
|
+
], RemoteFileExplorerModule);
|
|
25
|
+
//# sourceMappingURL=remote-file-explorer.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-file-explorer.module.js","sourceRoot":"","sources":["../src/remote-file-explorer.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,6CAAgD;AAChD,8CAAoD;AACpD,0CAAiD;AACjD,wEAAyE;AACzE,+CAA6D;AAMtD,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;CAAG,CAAA;AAA3B,4DAAwB;mCAAxB,wBAAwB;IAJpC,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,qBAAc,EAAE,6CAAuB,EAAE,uBAAa,CAAC,UAAU,CAAC,CAAC,wBAAe,CAAC,CAAC,CAAC;QAC/F,WAAW,EAAE,CAAC,0CAA4B,CAAC;KAC5C,CAAC;GACW,wBAAwB,CAAG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@loopstack/remote-file-explorer-module",
|
|
3
|
+
"displayName": "Loopstack Remote File Explorer Module",
|
|
4
|
+
"description": "Remote file browsing for Loopstack workspaces — proxies file tree and content requests to remote agents",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"loopstack",
|
|
7
|
+
"file-explorer",
|
|
8
|
+
"remote-agent",
|
|
9
|
+
"workflow"
|
|
10
|
+
],
|
|
11
|
+
"version": "0.22.3",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Jakob Klippel",
|
|
15
|
+
"url": "https://www.linkedin.com/in/jakob-klippel/"
|
|
16
|
+
},
|
|
17
|
+
"main": "dist/index.js",
|
|
18
|
+
"types": "dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": "./dist/index.js",
|
|
21
|
+
"./src/*": "./src/*"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "nest build",
|
|
25
|
+
"compile": "tsc --noEmit",
|
|
26
|
+
"format": "prettier --write .",
|
|
27
|
+
"lint": "eslint .",
|
|
28
|
+
"test": "jest --passWithNoTests",
|
|
29
|
+
"watch": "nest build --watch"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@loopstack/common": "^0.26.0",
|
|
33
|
+
"@loopstack/core": "^0.26.0",
|
|
34
|
+
"@loopstack/remote-agent-client": "^0.23.1",
|
|
35
|
+
"@nestjs/common": "^11.1.19",
|
|
36
|
+
"@nestjs/typeorm": "^11.0.1",
|
|
37
|
+
"typeorm": "^0.3.22"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"src"
|
|
42
|
+
],
|
|
43
|
+
"jest": {
|
|
44
|
+
"moduleFileExtensions": [
|
|
45
|
+
"js",
|
|
46
|
+
"json",
|
|
47
|
+
"ts"
|
|
48
|
+
],
|
|
49
|
+
"rootDir": "src",
|
|
50
|
+
"testRegex": ".*\\.spec\\.ts$",
|
|
51
|
+
"transform": {
|
|
52
|
+
"^.+\\.ts$": "ts-jest"
|
|
53
|
+
},
|
|
54
|
+
"collectCoverageFrom": [
|
|
55
|
+
"**/*.(t|j)s"
|
|
56
|
+
],
|
|
57
|
+
"coverageDirectory": "../coverage",
|
|
58
|
+
"testEnvironment": "node",
|
|
59
|
+
"maxWorkers": 1
|
|
60
|
+
},
|
|
61
|
+
"loopstack": {
|
|
62
|
+
"modules": [
|
|
63
|
+
{
|
|
64
|
+
"path": "src/remote-file-explorer.module.ts",
|
|
65
|
+
"className": "RemoteFileExplorerModule"
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"installModes": [
|
|
69
|
+
"add",
|
|
70
|
+
"install"
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './remote-file-explorer.controller';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Controller, Get, NotFoundException, Param, Query, UsePipes, ValidationPipe } from '@nestjs/common';
|
|
2
|
+
import { ApiTags } from '@nestjs/swagger';
|
|
3
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
4
|
+
import { Repository } from 'typeorm';
|
|
5
|
+
import { CurrentUser, CurrentUserInterface, WorkspaceEntity } from '@loopstack/common';
|
|
6
|
+
import { RemoteAgentClient } from '@loopstack/remote-agent-client';
|
|
7
|
+
|
|
8
|
+
@ApiTags('api/v1/workspaces/:workspaceId/files')
|
|
9
|
+
@UsePipes(new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }))
|
|
10
|
+
@Controller('api/v1/workspaces/:workspaceId/files')
|
|
11
|
+
export class RemoteFileExplorerController {
|
|
12
|
+
constructor(
|
|
13
|
+
private readonly remoteAgentClient: RemoteAgentClient,
|
|
14
|
+
@InjectRepository(WorkspaceEntity)
|
|
15
|
+
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
private async getAgentUrl(workspaceId: string, userId: string): Promise<string> {
|
|
19
|
+
const workspace = await this.workspaceRepository.findOne({
|
|
20
|
+
where: { id: workspaceId, createdBy: userId },
|
|
21
|
+
relations: ['environments'],
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (!workspace) {
|
|
25
|
+
throw new NotFoundException(`Workspace with ID ${workspaceId} not found`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const environment = workspace.environments?.find((e) => !!e.agentUrl);
|
|
29
|
+
if (!environment?.agentUrl) {
|
|
30
|
+
throw new NotFoundException(`No remote environment configured for workspace ${workspaceId}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return environment.agentUrl;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Get('tree')
|
|
37
|
+
async getFileTree(
|
|
38
|
+
@Param('workspaceId') workspaceId: string,
|
|
39
|
+
@Query('path') basePath: string | undefined,
|
|
40
|
+
@CurrentUser() user: CurrentUserInterface,
|
|
41
|
+
) {
|
|
42
|
+
const agentUrl = await this.getAgentUrl(workspaceId, user.userId);
|
|
43
|
+
return this.remoteAgentClient.getFileTree(agentUrl, basePath ?? './src');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Get('read')
|
|
47
|
+
async readFile(
|
|
48
|
+
@Param('workspaceId') workspaceId: string,
|
|
49
|
+
@Query('path') filePath: string,
|
|
50
|
+
@CurrentUser() user: CurrentUserInterface,
|
|
51
|
+
) {
|
|
52
|
+
const agentUrl = await this.getAgentUrl(workspaceId, user.userId);
|
|
53
|
+
return this.remoteAgentClient.readFile(agentUrl, filePath);
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Module } from '@nestjs/common';
|
|
2
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
3
|
+
import { WorkspaceEntity } from '@loopstack/common';
|
|
4
|
+
import { LoopCoreModule } from '@loopstack/core';
|
|
5
|
+
import { RemoteAgentClientModule } from '@loopstack/remote-agent-client';
|
|
6
|
+
import { RemoteFileExplorerController } from './controllers';
|
|
7
|
+
|
|
8
|
+
@Module({
|
|
9
|
+
imports: [LoopCoreModule, RemoteAgentClientModule, TypeOrmModule.forFeature([WorkspaceEntity])],
|
|
10
|
+
controllers: [RemoteFileExplorerController],
|
|
11
|
+
})
|
|
12
|
+
export class RemoteFileExplorerModule {}
|