@nahisaho/katashiro-workspace 2.0.8 → 2.0.10
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/docker-workspace.d.ts +72 -0
- package/dist/docker-workspace.d.ts.map +1 -0
- package/dist/docker-workspace.js +595 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/local-workspace.d.ts +57 -0
- package/dist/local-workspace.d.ts.map +1 -0
- package/dist/local-workspace.js +521 -0
- package/dist/types.d.ts +183 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +45 -0
- package/dist/workspace-factory.d.ts +64 -0
- package/dist/workspace-factory.d.ts.map +1 -0
- package/dist/workspace-factory.js +204 -0
- package/package.json +6 -2
- package/tests/local-workspace.test.ts +0 -283
- package/tests/workspace-factory.test.ts +0 -120
- package/tsconfig.json +0 -12
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DockerWorkspace - Dockerコンテナ内ファイルシステムワークスペース
|
|
3
|
+
*
|
|
4
|
+
* @requirement REQ-011-04
|
|
5
|
+
*/
|
|
6
|
+
import type { Workspace, DockerWorkspaceConfig, FileInfo, DirectoryEntry } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* DockerWorkspace - Dockerコンテナ内でのファイル操作
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const workspace = new DockerWorkspace({
|
|
13
|
+
* type: 'docker',
|
|
14
|
+
* containerId: 'container123',
|
|
15
|
+
* workingDir: '/app',
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* await workspace.initialize();
|
|
19
|
+
* const content = await workspace.read('config.json');
|
|
20
|
+
* await workspace.write('output.txt', 'Hello Docker');
|
|
21
|
+
* await workspace.cleanup();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class DockerWorkspace implements Workspace {
|
|
25
|
+
readonly type: "docker";
|
|
26
|
+
readonly workingDir: string;
|
|
27
|
+
readonly readOnly: boolean;
|
|
28
|
+
private docker;
|
|
29
|
+
private container;
|
|
30
|
+
private containerId;
|
|
31
|
+
constructor(config: DockerWorkspaceConfig);
|
|
32
|
+
/**
|
|
33
|
+
* パスを解決
|
|
34
|
+
*/
|
|
35
|
+
private resolvePath;
|
|
36
|
+
/**
|
|
37
|
+
* 書き込み可能か検証
|
|
38
|
+
*/
|
|
39
|
+
private validateWritable;
|
|
40
|
+
/**
|
|
41
|
+
* コンテナ内でコマンドを実行
|
|
42
|
+
*/
|
|
43
|
+
private exec;
|
|
44
|
+
initialize(): Promise<void>;
|
|
45
|
+
cleanup(): Promise<void>;
|
|
46
|
+
read(filePath: string, _encoding?: BufferEncoding): Promise<string>;
|
|
47
|
+
readBuffer(filePath: string): Promise<Buffer>;
|
|
48
|
+
write(filePath: string, content: string): Promise<void>;
|
|
49
|
+
writeBuffer(filePath: string, buffer: Buffer): Promise<void>;
|
|
50
|
+
list(dirPath: string): Promise<FileInfo[]>;
|
|
51
|
+
listEntries(dirPath: string): Promise<DirectoryEntry[]>;
|
|
52
|
+
search(pattern: string): Promise<string[]>;
|
|
53
|
+
exists(filePath: string): Promise<boolean>;
|
|
54
|
+
delete(filePath: string): Promise<void>;
|
|
55
|
+
mkdir(dirPath: string, recursive?: boolean): Promise<void>;
|
|
56
|
+
stat(filePath: string): Promise<FileInfo>;
|
|
57
|
+
copy(src: string, dest: string): Promise<void>;
|
|
58
|
+
move(src: string, dest: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* lsの出力をパース
|
|
61
|
+
*/
|
|
62
|
+
private parseLsOutput;
|
|
63
|
+
/**
|
|
64
|
+
* lsエントリをパース
|
|
65
|
+
*/
|
|
66
|
+
private parseLsEntries;
|
|
67
|
+
/**
|
|
68
|
+
* エラーメッセージをパース
|
|
69
|
+
*/
|
|
70
|
+
private parseError;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=docker-workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-workspace.d.ts","sourceRoot":"","sources":["../src/docker-workspace.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,SAAS,EACT,qBAAqB,EACrB,QAAQ,EACR,cAAc,EACf,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAC/C,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,qBAAqB;IAWzC;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;OAEG;YACW,IAAI;IAkEZ,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAE,cAAwB,GAAG,OAAO,CAAC,MAAM,CAAC;IAW5E,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAW7C,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBvD,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5D,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAgB1C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAYvD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiB1C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO1C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvD,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyBzC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcpD;;OAEG;IACH,OAAO,CAAC,aAAa;IAyBrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAmBtB;;OAEG;IACH,OAAO,CAAC,UAAU;CAkBnB"}
|
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DockerWorkspace - Dockerコンテナ内ファイルシステムワークスペース
|
|
4
|
+
*
|
|
5
|
+
* @requirement REQ-011-04
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
41
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
42
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
43
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
44
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
45
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
46
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
50
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
51
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
52
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
53
|
+
function step(op) {
|
|
54
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
55
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
56
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
57
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
58
|
+
switch (op[0]) {
|
|
59
|
+
case 0: case 1: t = op; break;
|
|
60
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
61
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
62
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
63
|
+
default:
|
|
64
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
65
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
66
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
67
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
68
|
+
if (t[2]) _.ops.pop();
|
|
69
|
+
_.trys.pop(); continue;
|
|
70
|
+
}
|
|
71
|
+
op = body.call(thisArg, _);
|
|
72
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
73
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
77
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
78
|
+
};
|
|
79
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
80
|
+
exports.DockerWorkspace = void 0;
|
|
81
|
+
var dockerode_1 = __importDefault(require("dockerode"));
|
|
82
|
+
var path = __importStar(require("node:path"));
|
|
83
|
+
var types_js_1 = require("./types.js");
|
|
84
|
+
/**
|
|
85
|
+
* DockerWorkspace - Dockerコンテナ内でのファイル操作
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const workspace = new DockerWorkspace({
|
|
90
|
+
* type: 'docker',
|
|
91
|
+
* containerId: 'container123',
|
|
92
|
+
* workingDir: '/app',
|
|
93
|
+
* });
|
|
94
|
+
*
|
|
95
|
+
* await workspace.initialize();
|
|
96
|
+
* const content = await workspace.read('config.json');
|
|
97
|
+
* await workspace.write('output.txt', 'Hello Docker');
|
|
98
|
+
* await workspace.cleanup();
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
var DockerWorkspace = /** @class */ (function () {
|
|
102
|
+
function DockerWorkspace(config) {
|
|
103
|
+
var _a;
|
|
104
|
+
this.type = 'docker';
|
|
105
|
+
this.containerId = config.containerId;
|
|
106
|
+
this.workingDir = config.workingDir;
|
|
107
|
+
this.readOnly = (_a = config.readOnly) !== null && _a !== void 0 ? _a : false;
|
|
108
|
+
this.docker = new dockerode_1.default({
|
|
109
|
+
socketPath: config.socketPath || types_js_1.DEFAULT_DOCKER_SOCKET,
|
|
110
|
+
});
|
|
111
|
+
this.container = this.docker.getContainer(this.containerId);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* パスを解決
|
|
115
|
+
*/
|
|
116
|
+
DockerWorkspace.prototype.resolvePath = function (filePath) {
|
|
117
|
+
if (path.isAbsolute(filePath)) {
|
|
118
|
+
return filePath;
|
|
119
|
+
}
|
|
120
|
+
return path.posix.join(this.workingDir, filePath);
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* 書き込み可能か検証
|
|
124
|
+
*/
|
|
125
|
+
DockerWorkspace.prototype.validateWritable = function () {
|
|
126
|
+
if (this.readOnly) {
|
|
127
|
+
throw new types_js_1.WorkspaceError('READ_ONLY', 'Workspace is read-only');
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* コンテナ内でコマンドを実行
|
|
132
|
+
*/
|
|
133
|
+
DockerWorkspace.prototype.exec = function (cmd) {
|
|
134
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
135
|
+
var exec_1, error_1;
|
|
136
|
+
var _this = this;
|
|
137
|
+
return __generator(this, function (_a) {
|
|
138
|
+
switch (_a.label) {
|
|
139
|
+
case 0:
|
|
140
|
+
_a.trys.push([0, 2, , 3]);
|
|
141
|
+
return [4 /*yield*/, this.container.exec({
|
|
142
|
+
Cmd: cmd,
|
|
143
|
+
AttachStdout: true,
|
|
144
|
+
AttachStderr: true,
|
|
145
|
+
})];
|
|
146
|
+
case 1:
|
|
147
|
+
exec_1 = _a.sent();
|
|
148
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
149
|
+
exec_1.start({ hijack: true, stdin: false }, function (err, stream) {
|
|
150
|
+
if (err) {
|
|
151
|
+
reject(new types_js_1.WorkspaceError('OPERATION_FAILED', "Exec failed: ".concat(err.message)));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (!stream) {
|
|
155
|
+
reject(new types_js_1.WorkspaceError('OPERATION_FAILED', 'No stream returned'));
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
var stdout = '';
|
|
159
|
+
var stderr = '';
|
|
160
|
+
// Docker multiplexed stream handling
|
|
161
|
+
stream.on('data', function (chunk) {
|
|
162
|
+
// Docker stream format: 8-byte header + data
|
|
163
|
+
// First byte: 1=stdout, 2=stderr
|
|
164
|
+
if (chunk.length > 8) {
|
|
165
|
+
var streamType = chunk[0];
|
|
166
|
+
var data = chunk.slice(8).toString('utf-8');
|
|
167
|
+
if (streamType === 1) {
|
|
168
|
+
stdout += data;
|
|
169
|
+
}
|
|
170
|
+
else if (streamType === 2) {
|
|
171
|
+
stderr += data;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
stdout += chunk.toString('utf-8');
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
stream.on('end', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
179
|
+
var inspectResult, _a;
|
|
180
|
+
var _b;
|
|
181
|
+
return __generator(this, function (_c) {
|
|
182
|
+
switch (_c.label) {
|
|
183
|
+
case 0:
|
|
184
|
+
_c.trys.push([0, 2, , 3]);
|
|
185
|
+
return [4 /*yield*/, exec_1.inspect()];
|
|
186
|
+
case 1:
|
|
187
|
+
inspectResult = _c.sent();
|
|
188
|
+
resolve({
|
|
189
|
+
stdout: stdout.trim(),
|
|
190
|
+
stderr: stderr.trim(),
|
|
191
|
+
exitCode: (_b = inspectResult.ExitCode) !== null && _b !== void 0 ? _b : 0,
|
|
192
|
+
});
|
|
193
|
+
return [3 /*break*/, 3];
|
|
194
|
+
case 2:
|
|
195
|
+
_a = _c.sent();
|
|
196
|
+
resolve({ stdout: stdout.trim(), stderr: stderr.trim(), exitCode: 0 });
|
|
197
|
+
return [3 /*break*/, 3];
|
|
198
|
+
case 3: return [2 /*return*/];
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}); });
|
|
202
|
+
stream.on('error', function (error) {
|
|
203
|
+
reject(new types_js_1.WorkspaceError('OPERATION_FAILED', "Stream error: ".concat(error.message)));
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
})];
|
|
207
|
+
case 2:
|
|
208
|
+
error_1 = _a.sent();
|
|
209
|
+
throw new types_js_1.WorkspaceError('CONNECTION_FAILED', "Failed to execute command: ".concat(error_1 instanceof Error ? error_1.message : String(error_1)));
|
|
210
|
+
case 3: return [2 /*return*/];
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
DockerWorkspace.prototype.initialize = function () {
|
|
216
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
217
|
+
var info, error_2;
|
|
218
|
+
return __generator(this, function (_a) {
|
|
219
|
+
switch (_a.label) {
|
|
220
|
+
case 0:
|
|
221
|
+
_a.trys.push([0, 2, , 3]);
|
|
222
|
+
return [4 /*yield*/, this.container.inspect()];
|
|
223
|
+
case 1:
|
|
224
|
+
info = _a.sent();
|
|
225
|
+
if (!info.State.Running) {
|
|
226
|
+
throw new types_js_1.WorkspaceError('CONNECTION_FAILED', "Container ".concat(this.containerId, " is not running"));
|
|
227
|
+
}
|
|
228
|
+
return [3 /*break*/, 3];
|
|
229
|
+
case 2:
|
|
230
|
+
error_2 = _a.sent();
|
|
231
|
+
if (error_2 instanceof types_js_1.WorkspaceError)
|
|
232
|
+
throw error_2;
|
|
233
|
+
throw new types_js_1.WorkspaceError('CONNECTION_FAILED', "Failed to connect to container: ".concat(error_2 instanceof Error ? error_2.message : String(error_2)));
|
|
234
|
+
case 3: return [2 /*return*/];
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
DockerWorkspace.prototype.cleanup = function () {
|
|
240
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
241
|
+
return __generator(this, function (_a) {
|
|
242
|
+
return [2 /*return*/];
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
DockerWorkspace.prototype.read = function (filePath_1) {
|
|
247
|
+
return __awaiter(this, arguments, void 0, function (filePath, _encoding) {
|
|
248
|
+
var resolved, result;
|
|
249
|
+
if (_encoding === void 0) { _encoding = 'utf-8'; }
|
|
250
|
+
return __generator(this, function (_a) {
|
|
251
|
+
switch (_a.label) {
|
|
252
|
+
case 0:
|
|
253
|
+
resolved = this.resolvePath(filePath);
|
|
254
|
+
return [4 /*yield*/, this.exec(['cat', resolved])];
|
|
255
|
+
case 1:
|
|
256
|
+
result = _a.sent();
|
|
257
|
+
if (result.exitCode !== 0) {
|
|
258
|
+
throw this.parseError(result.stderr, filePath);
|
|
259
|
+
}
|
|
260
|
+
return [2 /*return*/, result.stdout];
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
};
|
|
265
|
+
DockerWorkspace.prototype.readBuffer = function (filePath) {
|
|
266
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
267
|
+
var resolved, result;
|
|
268
|
+
return __generator(this, function (_a) {
|
|
269
|
+
switch (_a.label) {
|
|
270
|
+
case 0:
|
|
271
|
+
resolved = this.resolvePath(filePath);
|
|
272
|
+
return [4 /*yield*/, this.exec(['cat', resolved])];
|
|
273
|
+
case 1:
|
|
274
|
+
result = _a.sent();
|
|
275
|
+
if (result.exitCode !== 0) {
|
|
276
|
+
throw this.parseError(result.stderr, filePath);
|
|
277
|
+
}
|
|
278
|
+
return [2 /*return*/, Buffer.from(result.stdout, 'utf-8')];
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
};
|
|
283
|
+
DockerWorkspace.prototype.write = function (filePath, content) {
|
|
284
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
285
|
+
var resolved, dir, encoded, result;
|
|
286
|
+
return __generator(this, function (_a) {
|
|
287
|
+
switch (_a.label) {
|
|
288
|
+
case 0:
|
|
289
|
+
this.validateWritable();
|
|
290
|
+
resolved = this.resolvePath(filePath);
|
|
291
|
+
dir = path.posix.dirname(resolved);
|
|
292
|
+
return [4 /*yield*/, this.exec(['mkdir', '-p', dir])];
|
|
293
|
+
case 1:
|
|
294
|
+
_a.sent();
|
|
295
|
+
encoded = Buffer.from(content, 'utf-8').toString('base64');
|
|
296
|
+
return [4 /*yield*/, this.exec(['sh', '-c', "echo '".concat(encoded, "' | base64 -d > '").concat(resolved, "'")])];
|
|
297
|
+
case 2:
|
|
298
|
+
result = _a.sent();
|
|
299
|
+
if (result.exitCode !== 0) {
|
|
300
|
+
throw this.parseError(result.stderr, filePath);
|
|
301
|
+
}
|
|
302
|
+
return [2 /*return*/];
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
DockerWorkspace.prototype.writeBuffer = function (filePath, buffer) {
|
|
308
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
309
|
+
var resolved, dir, encoded, result;
|
|
310
|
+
return __generator(this, function (_a) {
|
|
311
|
+
switch (_a.label) {
|
|
312
|
+
case 0:
|
|
313
|
+
this.validateWritable();
|
|
314
|
+
resolved = this.resolvePath(filePath);
|
|
315
|
+
dir = path.posix.dirname(resolved);
|
|
316
|
+
return [4 /*yield*/, this.exec(['mkdir', '-p', dir])];
|
|
317
|
+
case 1:
|
|
318
|
+
_a.sent();
|
|
319
|
+
encoded = buffer.toString('base64');
|
|
320
|
+
return [4 /*yield*/, this.exec(['sh', '-c', "echo '".concat(encoded, "' | base64 -d > '").concat(resolved, "'")])];
|
|
321
|
+
case 2:
|
|
322
|
+
result = _a.sent();
|
|
323
|
+
if (result.exitCode !== 0) {
|
|
324
|
+
throw this.parseError(result.stderr, filePath);
|
|
325
|
+
}
|
|
326
|
+
return [2 /*return*/];
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
DockerWorkspace.prototype.list = function (dirPath) {
|
|
332
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
333
|
+
var resolved, result;
|
|
334
|
+
return __generator(this, function (_a) {
|
|
335
|
+
switch (_a.label) {
|
|
336
|
+
case 0:
|
|
337
|
+
resolved = this.resolvePath(dirPath);
|
|
338
|
+
return [4 /*yield*/, this.exec([
|
|
339
|
+
'sh',
|
|
340
|
+
'-c',
|
|
341
|
+
"ls -la --time-style=+%s '".concat(resolved, "' | tail -n +2"),
|
|
342
|
+
])];
|
|
343
|
+
case 1:
|
|
344
|
+
result = _a.sent();
|
|
345
|
+
if (result.exitCode !== 0) {
|
|
346
|
+
throw this.parseError(result.stderr, dirPath);
|
|
347
|
+
}
|
|
348
|
+
return [2 /*return*/, this.parseLsOutput(result.stdout, resolved)];
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
};
|
|
353
|
+
DockerWorkspace.prototype.listEntries = function (dirPath) {
|
|
354
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
355
|
+
var resolved, result;
|
|
356
|
+
return __generator(this, function (_a) {
|
|
357
|
+
switch (_a.label) {
|
|
358
|
+
case 0:
|
|
359
|
+
resolved = this.resolvePath(dirPath);
|
|
360
|
+
return [4 /*yield*/, this.exec(['sh', '-c', "ls -la '".concat(resolved, "' | tail -n +2")])];
|
|
361
|
+
case 1:
|
|
362
|
+
result = _a.sent();
|
|
363
|
+
if (result.exitCode !== 0) {
|
|
364
|
+
throw this.parseError(result.stderr, dirPath);
|
|
365
|
+
}
|
|
366
|
+
return [2 /*return*/, this.parseLsEntries(result.stdout)];
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
DockerWorkspace.prototype.search = function (pattern) {
|
|
372
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
373
|
+
var result;
|
|
374
|
+
return __generator(this, function (_a) {
|
|
375
|
+
switch (_a.label) {
|
|
376
|
+
case 0: return [4 /*yield*/, this.exec([
|
|
377
|
+
'sh',
|
|
378
|
+
'-c',
|
|
379
|
+
"cd '".concat(this.workingDir, "' && find . -type f -name '").concat(pattern, "' 2>/dev/null | head -10000"),
|
|
380
|
+
])];
|
|
381
|
+
case 1:
|
|
382
|
+
result = _a.sent();
|
|
383
|
+
if (result.exitCode !== 0 && result.stderr) {
|
|
384
|
+
throw new types_js_1.WorkspaceError('OPERATION_FAILED', "Search failed: ".concat(result.stderr));
|
|
385
|
+
}
|
|
386
|
+
return [2 /*return*/, result.stdout
|
|
387
|
+
.split('\n')
|
|
388
|
+
.filter(function (line) { return line.trim(); })
|
|
389
|
+
.map(function (line) { return line.replace(/^\.\//, ''); })];
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
};
|
|
394
|
+
DockerWorkspace.prototype.exists = function (filePath) {
|
|
395
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
396
|
+
var resolved, result;
|
|
397
|
+
return __generator(this, function (_a) {
|
|
398
|
+
switch (_a.label) {
|
|
399
|
+
case 0:
|
|
400
|
+
resolved = this.resolvePath(filePath);
|
|
401
|
+
return [4 /*yield*/, this.exec(['test', '-e', resolved])];
|
|
402
|
+
case 1:
|
|
403
|
+
result = _a.sent();
|
|
404
|
+
return [2 /*return*/, result.exitCode === 0];
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
};
|
|
409
|
+
DockerWorkspace.prototype.delete = function (filePath) {
|
|
410
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
411
|
+
var resolved, result;
|
|
412
|
+
return __generator(this, function (_a) {
|
|
413
|
+
switch (_a.label) {
|
|
414
|
+
case 0:
|
|
415
|
+
this.validateWritable();
|
|
416
|
+
resolved = this.resolvePath(filePath);
|
|
417
|
+
return [4 /*yield*/, this.exec(['rm', '-rf', resolved])];
|
|
418
|
+
case 1:
|
|
419
|
+
result = _a.sent();
|
|
420
|
+
if (result.exitCode !== 0) {
|
|
421
|
+
throw this.parseError(result.stderr, filePath);
|
|
422
|
+
}
|
|
423
|
+
return [2 /*return*/];
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
};
|
|
428
|
+
DockerWorkspace.prototype.mkdir = function (dirPath_1) {
|
|
429
|
+
return __awaiter(this, arguments, void 0, function (dirPath, recursive) {
|
|
430
|
+
var resolved, cmd, result;
|
|
431
|
+
if (recursive === void 0) { recursive = true; }
|
|
432
|
+
return __generator(this, function (_a) {
|
|
433
|
+
switch (_a.label) {
|
|
434
|
+
case 0:
|
|
435
|
+
this.validateWritable();
|
|
436
|
+
resolved = this.resolvePath(dirPath);
|
|
437
|
+
cmd = recursive ? ['mkdir', '-p', resolved] : ['mkdir', resolved];
|
|
438
|
+
return [4 /*yield*/, this.exec(cmd)];
|
|
439
|
+
case 1:
|
|
440
|
+
result = _a.sent();
|
|
441
|
+
if (result.exitCode !== 0) {
|
|
442
|
+
throw this.parseError(result.stderr, dirPath);
|
|
443
|
+
}
|
|
444
|
+
return [2 /*return*/];
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
};
|
|
449
|
+
DockerWorkspace.prototype.stat = function (filePath) {
|
|
450
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
451
|
+
var resolved, result, _a, name, size, type, mtime, ctime;
|
|
452
|
+
return __generator(this, function (_b) {
|
|
453
|
+
switch (_b.label) {
|
|
454
|
+
case 0:
|
|
455
|
+
resolved = this.resolvePath(filePath);
|
|
456
|
+
return [4 /*yield*/, this.exec([
|
|
457
|
+
'stat',
|
|
458
|
+
'-c',
|
|
459
|
+
'%n|%s|%F|%Y|%W',
|
|
460
|
+
resolved,
|
|
461
|
+
])];
|
|
462
|
+
case 1:
|
|
463
|
+
result = _b.sent();
|
|
464
|
+
if (result.exitCode !== 0) {
|
|
465
|
+
throw this.parseError(result.stderr, filePath);
|
|
466
|
+
}
|
|
467
|
+
_a = result.stdout.split('|'), name = _a[0], size = _a[1], type = _a[2], mtime = _a[3], ctime = _a[4];
|
|
468
|
+
return [2 /*return*/, {
|
|
469
|
+
name: path.posix.basename(name),
|
|
470
|
+
path: resolved,
|
|
471
|
+
size: parseInt(size, 10),
|
|
472
|
+
isDirectory: type === 'directory',
|
|
473
|
+
modifiedAt: new Date(parseInt(mtime, 10) * 1000),
|
|
474
|
+
createdAt: new Date(parseInt(ctime, 10) * 1000),
|
|
475
|
+
}];
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
};
|
|
480
|
+
DockerWorkspace.prototype.copy = function (src, dest) {
|
|
481
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
482
|
+
var srcResolved, destResolved, dir, result;
|
|
483
|
+
return __generator(this, function (_a) {
|
|
484
|
+
switch (_a.label) {
|
|
485
|
+
case 0:
|
|
486
|
+
this.validateWritable();
|
|
487
|
+
srcResolved = this.resolvePath(src);
|
|
488
|
+
destResolved = this.resolvePath(dest);
|
|
489
|
+
dir = path.posix.dirname(destResolved);
|
|
490
|
+
return [4 /*yield*/, this.exec(['mkdir', '-p', dir])];
|
|
491
|
+
case 1:
|
|
492
|
+
_a.sent();
|
|
493
|
+
return [4 /*yield*/, this.exec(['cp', '-r', srcResolved, destResolved])];
|
|
494
|
+
case 2:
|
|
495
|
+
result = _a.sent();
|
|
496
|
+
if (result.exitCode !== 0) {
|
|
497
|
+
throw this.parseError(result.stderr, src);
|
|
498
|
+
}
|
|
499
|
+
return [2 /*return*/];
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
};
|
|
504
|
+
DockerWorkspace.prototype.move = function (src, dest) {
|
|
505
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
506
|
+
var srcResolved, destResolved, dir, result;
|
|
507
|
+
return __generator(this, function (_a) {
|
|
508
|
+
switch (_a.label) {
|
|
509
|
+
case 0:
|
|
510
|
+
this.validateWritable();
|
|
511
|
+
srcResolved = this.resolvePath(src);
|
|
512
|
+
destResolved = this.resolvePath(dest);
|
|
513
|
+
dir = path.posix.dirname(destResolved);
|
|
514
|
+
return [4 /*yield*/, this.exec(['mkdir', '-p', dir])];
|
|
515
|
+
case 1:
|
|
516
|
+
_a.sent();
|
|
517
|
+
return [4 /*yield*/, this.exec(['mv', srcResolved, destResolved])];
|
|
518
|
+
case 2:
|
|
519
|
+
result = _a.sent();
|
|
520
|
+
if (result.exitCode !== 0) {
|
|
521
|
+
throw this.parseError(result.stderr, src);
|
|
522
|
+
}
|
|
523
|
+
return [2 /*return*/];
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
};
|
|
528
|
+
/**
|
|
529
|
+
* lsの出力をパース
|
|
530
|
+
*/
|
|
531
|
+
DockerWorkspace.prototype.parseLsOutput = function (output, basePath) {
|
|
532
|
+
return output
|
|
533
|
+
.split('\n')
|
|
534
|
+
.filter(function (line) { return line.trim(); })
|
|
535
|
+
.map(function (line) {
|
|
536
|
+
var parts = line.split(/\s+/);
|
|
537
|
+
if (parts.length < 7)
|
|
538
|
+
return null;
|
|
539
|
+
var permissions = parts[0];
|
|
540
|
+
var size = parseInt(parts[4], 10);
|
|
541
|
+
var timestamp = parseInt(parts[5], 10);
|
|
542
|
+
var name = parts.slice(6).join(' ');
|
|
543
|
+
return {
|
|
544
|
+
name: name,
|
|
545
|
+
path: path.posix.join(basePath, name),
|
|
546
|
+
size: isNaN(size) ? 0 : size,
|
|
547
|
+
isDirectory: permissions.startsWith('d'),
|
|
548
|
+
modifiedAt: new Date(timestamp * 1000),
|
|
549
|
+
createdAt: new Date(timestamp * 1000),
|
|
550
|
+
};
|
|
551
|
+
})
|
|
552
|
+
.filter(function (info) { return info !== null; });
|
|
553
|
+
};
|
|
554
|
+
/**
|
|
555
|
+
* lsエントリをパース
|
|
556
|
+
*/
|
|
557
|
+
DockerWorkspace.prototype.parseLsEntries = function (output) {
|
|
558
|
+
return output
|
|
559
|
+
.split('\n')
|
|
560
|
+
.filter(function (line) { return line.trim(); })
|
|
561
|
+
.map(function (line) {
|
|
562
|
+
var parts = line.split(/\s+/);
|
|
563
|
+
if (parts.length < 7)
|
|
564
|
+
return null;
|
|
565
|
+
var permissions = parts[0];
|
|
566
|
+
var name = parts.slice(8).join(' ');
|
|
567
|
+
return {
|
|
568
|
+
name: name,
|
|
569
|
+
isDirectory: permissions.startsWith('d'),
|
|
570
|
+
};
|
|
571
|
+
})
|
|
572
|
+
.filter(function (entry) { return entry !== null; });
|
|
573
|
+
};
|
|
574
|
+
/**
|
|
575
|
+
* エラーメッセージをパース
|
|
576
|
+
*/
|
|
577
|
+
DockerWorkspace.prototype.parseError = function (stderr, filePath) {
|
|
578
|
+
var msg = stderr.toLowerCase();
|
|
579
|
+
if (msg.includes('no such file') || msg.includes('not found')) {
|
|
580
|
+
return new types_js_1.WorkspaceError('NOT_FOUND', "Not found: ".concat(filePath), filePath);
|
|
581
|
+
}
|
|
582
|
+
if (msg.includes('permission denied')) {
|
|
583
|
+
return new types_js_1.WorkspaceError('PERMISSION_DENIED', "Permission denied: ".concat(filePath), filePath);
|
|
584
|
+
}
|
|
585
|
+
if (msg.includes('is a directory')) {
|
|
586
|
+
return new types_js_1.WorkspaceError('IS_DIRECTORY', "Is a directory: ".concat(filePath), filePath);
|
|
587
|
+
}
|
|
588
|
+
if (msg.includes('not a directory')) {
|
|
589
|
+
return new types_js_1.WorkspaceError('NOT_DIRECTORY', "Not a directory: ".concat(filePath), filePath);
|
|
590
|
+
}
|
|
591
|
+
return new types_js_1.WorkspaceError('OPERATION_FAILED', stderr || "Operation failed: ".concat(filePath), filePath);
|
|
592
|
+
};
|
|
593
|
+
return DockerWorkspace;
|
|
594
|
+
}());
|
|
595
|
+
exports.DockerWorkspace = DockerWorkspace;
|