hereya-cli 0.31.0 → 0.32.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/README.md +62 -21
- package/dist/backend/config.d.ts +10 -0
- package/dist/backend/config.js +23 -0
- package/dist/backend/file-storage/common.d.ts +49 -0
- package/dist/backend/file-storage/common.js +1 -0
- package/dist/backend/file-storage/local.d.ts +9 -0
- package/dist/backend/file-storage/local.js +84 -0
- package/dist/backend/file-storage/s3.d.ts +23 -0
- package/dist/backend/file-storage/s3.js +127 -0
- package/dist/backend/file.d.ts +21 -0
- package/dist/backend/file.js +413 -0
- package/dist/backend/index.d.ts +4 -2
- package/dist/backend/index.js +32 -3
- package/dist/backend/local.d.ts +3 -19
- package/dist/backend/local.js +5 -375
- package/dist/backend/s3.d.ts +4 -0
- package/dist/backend/s3.js +7 -0
- package/dist/commands/config/get-backend/index.d.ts +6 -0
- package/dist/commands/config/get-backend/index.js +12 -0
- package/dist/commands/config/use-backend/index.d.ts +9 -0
- package/dist/commands/config/use-backend/index.js +20 -0
- package/dist/infrastructure/aws-config.d.ts +7 -0
- package/dist/infrastructure/aws-config.js +12 -0
- package/dist/infrastructure/aws.d.ts +0 -2
- package/dist/infrastructure/aws.js +19 -11
- package/dist/lib/yaml-utils.d.ts +4 -0
- package/dist/lib/yaml-utils.js +12 -5
- package/oclif.manifest.json +58 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ $ npm install -g hereya-cli
|
|
|
20
20
|
$ hereya COMMAND
|
|
21
21
|
running command...
|
|
22
22
|
$ hereya (--version)
|
|
23
|
-
hereya-cli/0.
|
|
23
|
+
hereya-cli/0.32.0 linux-x64 node-v22.14.0
|
|
24
24
|
$ hereya --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ hereya COMMAND
|
|
@@ -31,6 +31,8 @@ USAGE
|
|
|
31
31
|
<!-- commands -->
|
|
32
32
|
* [`hereya add PACKAGE`](#hereya-add-package)
|
|
33
33
|
* [`hereya bootstrap INFRASTRUCTURETYPE`](#hereya-bootstrap-infrastructuretype)
|
|
34
|
+
* [`hereya config get-backend`](#hereya-config-get-backend)
|
|
35
|
+
* [`hereya config use-backend TYPE`](#hereya-config-use-backend-type)
|
|
34
36
|
* [`hereya deploy`](#hereya-deploy)
|
|
35
37
|
* [`hereya down`](#hereya-down)
|
|
36
38
|
* [`hereya env [NAME]`](#hereya-env-name)
|
|
@@ -82,7 +84,7 @@ EXAMPLES
|
|
|
82
84
|
$ hereya add cloudy/docker_postgres
|
|
83
85
|
```
|
|
84
86
|
|
|
85
|
-
_See code: [src/commands/add/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
87
|
+
_See code: [src/commands/add/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/add/index.ts)_
|
|
86
88
|
|
|
87
89
|
## `hereya bootstrap INFRASTRUCTURETYPE`
|
|
88
90
|
|
|
@@ -107,7 +109,46 @@ EXAMPLES
|
|
|
107
109
|
$ hereya bootstrap local
|
|
108
110
|
```
|
|
109
111
|
|
|
110
|
-
_See code: [src/commands/bootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
112
|
+
_See code: [src/commands/bootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/bootstrap/index.ts)_
|
|
113
|
+
|
|
114
|
+
## `hereya config get-backend`
|
|
115
|
+
|
|
116
|
+
get the current backend type
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
USAGE
|
|
120
|
+
$ hereya config get-backend
|
|
121
|
+
|
|
122
|
+
DESCRIPTION
|
|
123
|
+
get the current backend type
|
|
124
|
+
|
|
125
|
+
EXAMPLES
|
|
126
|
+
$ hereya config get-backend
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
_See code: [src/commands/config/get-backend/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/config/get-backend/index.ts)_
|
|
130
|
+
|
|
131
|
+
## `hereya config use-backend TYPE`
|
|
132
|
+
|
|
133
|
+
set the current backend type
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
USAGE
|
|
137
|
+
$ hereya config use-backend TYPE
|
|
138
|
+
|
|
139
|
+
ARGUMENTS
|
|
140
|
+
TYPE type of backend to use. Possible values: s3, local
|
|
141
|
+
|
|
142
|
+
DESCRIPTION
|
|
143
|
+
set the current backend type
|
|
144
|
+
|
|
145
|
+
EXAMPLES
|
|
146
|
+
$ hereya config use-backend s3
|
|
147
|
+
|
|
148
|
+
$ hereya config use-backend local
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
_See code: [src/commands/config/use-backend/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/config/use-backend/index.ts)_
|
|
111
152
|
|
|
112
153
|
## `hereya deploy`
|
|
113
154
|
|
|
@@ -132,7 +173,7 @@ EXAMPLES
|
|
|
132
173
|
$ hereya deploy
|
|
133
174
|
```
|
|
134
175
|
|
|
135
|
-
_See code: [src/commands/deploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
176
|
+
_See code: [src/commands/deploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/deploy/index.ts)_
|
|
136
177
|
|
|
137
178
|
## `hereya down`
|
|
138
179
|
|
|
@@ -159,7 +200,7 @@ EXAMPLES
|
|
|
159
200
|
$ hereya down
|
|
160
201
|
```
|
|
161
202
|
|
|
162
|
-
_See code: [src/commands/down/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
203
|
+
_See code: [src/commands/down/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/down/index.ts)_
|
|
163
204
|
|
|
164
205
|
## `hereya env [NAME]`
|
|
165
206
|
|
|
@@ -190,7 +231,7 @@ EXAMPLES
|
|
|
190
231
|
$ hereya env -w dev -l
|
|
191
232
|
```
|
|
192
233
|
|
|
193
|
-
_See code: [src/commands/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
234
|
+
_See code: [src/commands/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/env/index.ts)_
|
|
194
235
|
|
|
195
236
|
## `hereya env set [NAME]`
|
|
196
237
|
|
|
@@ -217,7 +258,7 @@ EXAMPLES
|
|
|
217
258
|
$ hereya env set FOO -v bar -w dev
|
|
218
259
|
```
|
|
219
260
|
|
|
220
|
-
_See code: [src/commands/env/set/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
261
|
+
_See code: [src/commands/env/set/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/env/set/index.ts)_
|
|
221
262
|
|
|
222
263
|
## `hereya help [COMMAND]`
|
|
223
264
|
|
|
@@ -263,7 +304,7 @@ EXAMPLES
|
|
|
263
304
|
$ hereya init myProject -w=defaultWorkspace --chdir=./myProject
|
|
264
305
|
```
|
|
265
306
|
|
|
266
|
-
_See code: [src/commands/init/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
307
|
+
_See code: [src/commands/init/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/init/index.ts)_
|
|
267
308
|
|
|
268
309
|
## `hereya remove PACKAGE`
|
|
269
310
|
|
|
@@ -290,7 +331,7 @@ EXAMPLES
|
|
|
290
331
|
$ hereya remove cloudy/docker_postgres
|
|
291
332
|
```
|
|
292
333
|
|
|
293
|
-
_See code: [src/commands/remove/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
334
|
+
_See code: [src/commands/remove/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/remove/index.ts)_
|
|
294
335
|
|
|
295
336
|
## `hereya run CMD`
|
|
296
337
|
|
|
@@ -316,7 +357,7 @@ EXAMPLES
|
|
|
316
357
|
$ hereya run -w uat -- node index.js
|
|
317
358
|
```
|
|
318
359
|
|
|
319
|
-
_See code: [src/commands/run/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
360
|
+
_See code: [src/commands/run/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/run/index.ts)_
|
|
320
361
|
|
|
321
362
|
## `hereya unbootstrap INFRASTRUCTURETYPE`
|
|
322
363
|
|
|
@@ -341,7 +382,7 @@ EXAMPLES
|
|
|
341
382
|
$ hereya unbootstrap local
|
|
342
383
|
```
|
|
343
384
|
|
|
344
|
-
_See code: [src/commands/unbootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
385
|
+
_See code: [src/commands/unbootstrap/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/unbootstrap/index.ts)_
|
|
345
386
|
|
|
346
387
|
## `hereya undeploy`
|
|
347
388
|
|
|
@@ -366,7 +407,7 @@ EXAMPLES
|
|
|
366
407
|
$ hereya undeploy
|
|
367
408
|
```
|
|
368
409
|
|
|
369
|
-
_See code: [src/commands/undeploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
410
|
+
_See code: [src/commands/undeploy/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/undeploy/index.ts)_
|
|
370
411
|
|
|
371
412
|
## `hereya up`
|
|
372
413
|
|
|
@@ -393,7 +434,7 @@ EXAMPLES
|
|
|
393
434
|
$ hereya up
|
|
394
435
|
```
|
|
395
436
|
|
|
396
|
-
_See code: [src/commands/up/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
437
|
+
_See code: [src/commands/up/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/up/index.ts)_
|
|
397
438
|
|
|
398
439
|
## `hereya workspace create NAME`
|
|
399
440
|
|
|
@@ -416,7 +457,7 @@ EXAMPLES
|
|
|
416
457
|
$ hereya workspace create dev
|
|
417
458
|
```
|
|
418
459
|
|
|
419
|
-
_See code: [src/commands/workspace/create/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
460
|
+
_See code: [src/commands/workspace/create/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/create/index.ts)_
|
|
420
461
|
|
|
421
462
|
## `hereya workspace delete NAME`
|
|
422
463
|
|
|
@@ -436,7 +477,7 @@ EXAMPLES
|
|
|
436
477
|
$ hereya workspace delete dev
|
|
437
478
|
```
|
|
438
479
|
|
|
439
|
-
_See code: [src/commands/workspace/delete/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
480
|
+
_See code: [src/commands/workspace/delete/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/delete/index.ts)_
|
|
440
481
|
|
|
441
482
|
## `hereya workspace env [NAME]`
|
|
442
483
|
|
|
@@ -462,7 +503,7 @@ EXAMPLES
|
|
|
462
503
|
$ hereya workspace env myEnv -w dev
|
|
463
504
|
```
|
|
464
505
|
|
|
465
|
-
_See code: [src/commands/workspace/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
506
|
+
_See code: [src/commands/workspace/env/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/env/index.ts)_
|
|
466
507
|
|
|
467
508
|
## `hereya workspace env set`
|
|
468
509
|
|
|
@@ -486,7 +527,7 @@ EXAMPLES
|
|
|
486
527
|
$ hereya workspace env set -w my-workspace -n myVar -v my-value -i aws -s
|
|
487
528
|
```
|
|
488
529
|
|
|
489
|
-
_See code: [src/commands/workspace/env/set/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
530
|
+
_See code: [src/commands/workspace/env/set/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/env/set/index.ts)_
|
|
490
531
|
|
|
491
532
|
## `hereya workspace env unset`
|
|
492
533
|
|
|
@@ -507,7 +548,7 @@ EXAMPLES
|
|
|
507
548
|
$ hereya workspace env unset -w my-workspace -n myVar
|
|
508
549
|
```
|
|
509
550
|
|
|
510
|
-
_See code: [src/commands/workspace/env/unset/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
551
|
+
_See code: [src/commands/workspace/env/unset/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/env/unset/index.ts)_
|
|
511
552
|
|
|
512
553
|
## `hereya workspace install PACKAGE`
|
|
513
554
|
|
|
@@ -534,7 +575,7 @@ EXAMPLES
|
|
|
534
575
|
$ hereya workspace install hereya/aws-cognito
|
|
535
576
|
```
|
|
536
577
|
|
|
537
|
-
_See code: [src/commands/workspace/install/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
578
|
+
_See code: [src/commands/workspace/install/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/install/index.ts)_
|
|
538
579
|
|
|
539
580
|
## `hereya workspace list`
|
|
540
581
|
|
|
@@ -551,7 +592,7 @@ EXAMPLES
|
|
|
551
592
|
$ hereya workspace list
|
|
552
593
|
```
|
|
553
594
|
|
|
554
|
-
_See code: [src/commands/workspace/list/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
595
|
+
_See code: [src/commands/workspace/list/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/list/index.ts)_
|
|
555
596
|
|
|
556
597
|
## `hereya workspace uninstall PACKAGE`
|
|
557
598
|
|
|
@@ -578,5 +619,5 @@ EXAMPLES
|
|
|
578
619
|
$ hereya workspace uninstall hereya/aws-cognito
|
|
579
620
|
```
|
|
580
621
|
|
|
581
|
-
_See code: [src/commands/workspace/uninstall/index.ts](https://github.com/hereya/hereya-cli/blob/v0.
|
|
622
|
+
_See code: [src/commands/workspace/uninstall/index.ts](https://github.com/hereya/hereya-cli/blob/v0.32.0/src/commands/workspace/uninstall/index.ts)_
|
|
582
623
|
<!-- commandsstop -->
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BackendType } from "./index.js";
|
|
2
|
+
export declare function getCurrentBackendType(): Promise<BackendType>;
|
|
3
|
+
export declare function setBackendType(type: BackendType): Promise<void>;
|
|
4
|
+
export declare function loadBackendConfig(): Promise<{
|
|
5
|
+
current: BackendType;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function getBackendConfigPath(): string;
|
|
8
|
+
export type BackendConfig = {
|
|
9
|
+
current: BackendType;
|
|
10
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { load, save } from "../lib/yaml-utils.js";
|
|
4
|
+
import { BackendType } from "./index.js";
|
|
5
|
+
export async function getCurrentBackendType() {
|
|
6
|
+
const config = await loadBackendConfig();
|
|
7
|
+
return config.current;
|
|
8
|
+
}
|
|
9
|
+
export async function setBackendType(type) {
|
|
10
|
+
const config = await loadBackendConfig();
|
|
11
|
+
config.current = type;
|
|
12
|
+
await save(config, getBackendConfigPath());
|
|
13
|
+
}
|
|
14
|
+
export async function loadBackendConfig() {
|
|
15
|
+
const { data, found } = await load(getBackendConfigPath());
|
|
16
|
+
if (!found) {
|
|
17
|
+
return { current: BackendType.Local };
|
|
18
|
+
}
|
|
19
|
+
return data;
|
|
20
|
+
}
|
|
21
|
+
export function getBackendConfigPath() {
|
|
22
|
+
return path.join(os.homedir(), '.hereya', 'backend.yaml');
|
|
23
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface FileStorage {
|
|
2
|
+
deleteFile(input: DeleteFileInput): Promise<DeleteFileOutput>;
|
|
3
|
+
/**
|
|
4
|
+
* Get the content of a file given its relative alternative paths
|
|
5
|
+
*/
|
|
6
|
+
getFileContent(input: GetFileContentInput): Promise<GetFileContentOutput>;
|
|
7
|
+
listFileNames(input: ListFileNamesInput): Promise<ListFileNamesOutput>;
|
|
8
|
+
/**
|
|
9
|
+
* Save the content of a file given its relative alternative paths
|
|
10
|
+
*/
|
|
11
|
+
saveFileContent(input: SaveFileContentInput): Promise<SaveFileContentOutput>;
|
|
12
|
+
}
|
|
13
|
+
export type GetFileContentInput = {
|
|
14
|
+
paths: string[];
|
|
15
|
+
};
|
|
16
|
+
export type GetFileContentOutput = {
|
|
17
|
+
content: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
found: true;
|
|
20
|
+
} | {
|
|
21
|
+
found: false;
|
|
22
|
+
};
|
|
23
|
+
export type SaveFileContentInput = {
|
|
24
|
+
content: string;
|
|
25
|
+
paths: string[];
|
|
26
|
+
};
|
|
27
|
+
export type SaveFileContentOutput = {
|
|
28
|
+
error?: string;
|
|
29
|
+
success: false;
|
|
30
|
+
} | {
|
|
31
|
+
success: true;
|
|
32
|
+
};
|
|
33
|
+
export type ListFileNamesInput = {
|
|
34
|
+
directory: string;
|
|
35
|
+
};
|
|
36
|
+
export type ListFileNamesOutput = {
|
|
37
|
+
error?: string;
|
|
38
|
+
success: false;
|
|
39
|
+
} | {
|
|
40
|
+
files: string[];
|
|
41
|
+
success: true;
|
|
42
|
+
};
|
|
43
|
+
export type DeleteFileInput = GetFileContentInput;
|
|
44
|
+
export type DeleteFileOutput = {
|
|
45
|
+
error?: string;
|
|
46
|
+
success: false;
|
|
47
|
+
} | {
|
|
48
|
+
success: true;
|
|
49
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DeleteFileInput, DeleteFileOutput, FileStorage, GetFileContentInput, GetFileContentOutput, ListFileNamesInput, ListFileNamesOutput, SaveFileContentInput, SaveFileContentOutput } from './common.js';
|
|
2
|
+
export declare class LocalFileStorage implements FileStorage {
|
|
3
|
+
private readonly basePath;
|
|
4
|
+
constructor(basePath: string);
|
|
5
|
+
deleteFile(input: DeleteFileInput): Promise<DeleteFileOutput>;
|
|
6
|
+
getFileContent(input: GetFileContentInput): Promise<GetFileContentOutput>;
|
|
7
|
+
listFileNames(input: ListFileNamesInput): Promise<ListFileNamesOutput>;
|
|
8
|
+
saveFileContent(input: SaveFileContentInput): Promise<SaveFileContentOutput>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileExists } from '../../lib/filesystem.js';
|
|
4
|
+
export class LocalFileStorage {
|
|
5
|
+
basePath;
|
|
6
|
+
constructor(basePath) {
|
|
7
|
+
this.basePath = basePath;
|
|
8
|
+
}
|
|
9
|
+
async deleteFile(input) {
|
|
10
|
+
const filePaths = input.paths.map((p) => path.join(this.basePath, p));
|
|
11
|
+
await Promise.all(filePaths.map(async (filePath) => {
|
|
12
|
+
try {
|
|
13
|
+
if (await fileExists(filePath)) {
|
|
14
|
+
await fs.unlink(filePath);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
return { success: true };
|
|
23
|
+
}
|
|
24
|
+
async getFileContent(input) {
|
|
25
|
+
const filePaths = input.paths.map((p) => path.join(this.basePath, p));
|
|
26
|
+
const existingFiles = await Promise.all(filePaths.map(async (filePath) => {
|
|
27
|
+
try {
|
|
28
|
+
if (await fileExists(filePath)) {
|
|
29
|
+
const content = await fs.readFile(filePath, { encoding: 'utf8' });
|
|
30
|
+
return { content, filePath };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}));
|
|
38
|
+
const firstExistingFile = existingFiles.find(Boolean);
|
|
39
|
+
if (firstExistingFile) {
|
|
40
|
+
return { content: firstExistingFile.content, found: true };
|
|
41
|
+
}
|
|
42
|
+
return { found: false };
|
|
43
|
+
}
|
|
44
|
+
async listFileNames(input) {
|
|
45
|
+
try {
|
|
46
|
+
const files = await fs.readdir(path.join(this.basePath, input.directory));
|
|
47
|
+
return { files, success: true };
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
return { error, success: false };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async saveFileContent(input) {
|
|
54
|
+
let filePathToUse = null;
|
|
55
|
+
// Look for an existing file among the provided relative paths.
|
|
56
|
+
const filePaths = input.paths.map((p) => path.join(this.basePath, p));
|
|
57
|
+
const existingFiles = await Promise.all(filePaths.map(async (filePath) => {
|
|
58
|
+
try {
|
|
59
|
+
if (await fileExists(filePath)) {
|
|
60
|
+
return filePath;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}));
|
|
67
|
+
filePathToUse = existingFiles.find(Boolean);
|
|
68
|
+
// If none exists, use the first provided relative path.
|
|
69
|
+
if (!filePathToUse) {
|
|
70
|
+
if (input.paths.length === 0) {
|
|
71
|
+
return { error: 'No file path provided.', success: false };
|
|
72
|
+
}
|
|
73
|
+
filePathToUse = path.join(this.basePath, input.paths[0]);
|
|
74
|
+
await fs.mkdir(path.dirname(filePathToUse), { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
await fs.writeFile(filePathToUse, input.content, { encoding: 'utf8' });
|
|
78
|
+
return { success: true };
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return { error, success: false };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DeleteFileInput, DeleteFileOutput, FileStorage, GetFileContentInput, GetFileContentOutput, ListFileNamesInput, ListFileNamesOutput, SaveFileContentInput, SaveFileContentOutput } from './common.js';
|
|
2
|
+
export declare class S3FileStorage implements FileStorage {
|
|
3
|
+
private readonly bucket;
|
|
4
|
+
private readonly basePath;
|
|
5
|
+
private s3;
|
|
6
|
+
/**
|
|
7
|
+
* @param bucket - The S3 bucket name.
|
|
8
|
+
* @param basePath - The base path inside the bucket to use for keys.
|
|
9
|
+
*/
|
|
10
|
+
constructor(bucket: string, basePath: string);
|
|
11
|
+
deleteFile(input: DeleteFileInput): Promise<DeleteFileOutput>;
|
|
12
|
+
getFileContent(input: GetFileContentInput): Promise<GetFileContentOutput>;
|
|
13
|
+
listFileNames(input: ListFileNamesInput): Promise<ListFileNamesOutput>;
|
|
14
|
+
saveFileContent(input: SaveFileContentInput): Promise<SaveFileContentOutput>;
|
|
15
|
+
/**
|
|
16
|
+
* Build an S3 key by joining the basePath with a relative path.
|
|
17
|
+
*/
|
|
18
|
+
private getKey;
|
|
19
|
+
/**
|
|
20
|
+
* Helper to convert a Readable stream into a string.
|
|
21
|
+
*/
|
|
22
|
+
private streamToString;
|
|
23
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client, } from '@aws-sdk/client-s3';
|
|
2
|
+
export class S3FileStorage {
|
|
3
|
+
bucket;
|
|
4
|
+
basePath;
|
|
5
|
+
s3;
|
|
6
|
+
/**
|
|
7
|
+
* @param bucket - The S3 bucket name.
|
|
8
|
+
* @param basePath - The base path inside the bucket to use for keys.
|
|
9
|
+
*/
|
|
10
|
+
constructor(bucket, basePath) {
|
|
11
|
+
this.bucket = bucket;
|
|
12
|
+
this.basePath = basePath;
|
|
13
|
+
this.s3 = new S3Client({});
|
|
14
|
+
}
|
|
15
|
+
async deleteFile(input) {
|
|
16
|
+
const results = await Promise.all(input.paths.map(async (relativePath) => {
|
|
17
|
+
const key = this.getKey(relativePath);
|
|
18
|
+
try {
|
|
19
|
+
const deleteCommand = new DeleteObjectCommand({ Bucket: this.bucket, Key: key });
|
|
20
|
+
await this.s3.send(deleteCommand);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Ignore errors for individual deletes
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}));
|
|
28
|
+
return { success: results.some(Boolean) };
|
|
29
|
+
}
|
|
30
|
+
async getFileContent(input) {
|
|
31
|
+
const errors = [];
|
|
32
|
+
const results = await Promise.all(input.paths.map(async (relativePath) => {
|
|
33
|
+
const key = this.getKey(relativePath);
|
|
34
|
+
try {
|
|
35
|
+
const command = new GetObjectCommand({ Bucket: this.bucket, Key: key });
|
|
36
|
+
const response = await this.s3.send(command);
|
|
37
|
+
if (response.Body) {
|
|
38
|
+
const content = await this.streamToString(response.Body);
|
|
39
|
+
return { content, found: true };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
errors.push(error.message || 'Error getting file content');
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}));
|
|
47
|
+
const firstValidResult = results.find(Boolean);
|
|
48
|
+
if (firstValidResult) {
|
|
49
|
+
return firstValidResult;
|
|
50
|
+
}
|
|
51
|
+
return { found: false };
|
|
52
|
+
}
|
|
53
|
+
async listFileNames(input) {
|
|
54
|
+
const prefix = this.getKey(input.directory);
|
|
55
|
+
try {
|
|
56
|
+
const listCommand = new ListObjectsV2Command({
|
|
57
|
+
Bucket: this.bucket,
|
|
58
|
+
Prefix: prefix.endsWith('/') ? prefix : prefix + '/',
|
|
59
|
+
});
|
|
60
|
+
const response = await this.s3.send(listCommand);
|
|
61
|
+
const files = (response.Contents || []).map((item) => {
|
|
62
|
+
const key = item.Key || '';
|
|
63
|
+
// Remove the prefix (and an optional leading slash) from the key.
|
|
64
|
+
return key.slice(prefix.length).replace(/^\//, '');
|
|
65
|
+
});
|
|
66
|
+
return { files, success: true };
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return { error: error.message || 'Error listing file names', success: false };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async saveFileContent(input) {
|
|
73
|
+
let keyToUse;
|
|
74
|
+
// Check if any of the keys already exists.
|
|
75
|
+
const results = await Promise.all(input.paths.map(async (relativePath) => {
|
|
76
|
+
const key = this.getKey(relativePath);
|
|
77
|
+
try {
|
|
78
|
+
const headCommand = new HeadObjectCommand({ Bucket: this.bucket, Key: key });
|
|
79
|
+
await this.s3.send(headCommand);
|
|
80
|
+
return key;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error.name === 'NotFound' || error.$metadata?.httpStatusCode === 404) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
89
|
+
keyToUse = results.find(Boolean);
|
|
90
|
+
// If none exists, use the first provided relative path.
|
|
91
|
+
if (!keyToUse) {
|
|
92
|
+
if (input.paths.length === 0) {
|
|
93
|
+
return { error: 'No file path provided.', success: false };
|
|
94
|
+
}
|
|
95
|
+
keyToUse = this.getKey(input.paths[0]);
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const putCommand = new PutObjectCommand({
|
|
99
|
+
Body: input.content,
|
|
100
|
+
Bucket: this.bucket,
|
|
101
|
+
Key: keyToUse,
|
|
102
|
+
});
|
|
103
|
+
await this.s3.send(putCommand);
|
|
104
|
+
return { success: true };
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
return { error: error.message || 'Error saving file content', success: false };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Build an S3 key by joining the basePath with a relative path.
|
|
112
|
+
*/
|
|
113
|
+
getKey(relativePath) {
|
|
114
|
+
return [this.basePath, relativePath].join('/');
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Helper to convert a Readable stream into a string.
|
|
118
|
+
*/
|
|
119
|
+
async streamToString(stream) {
|
|
120
|
+
return new Promise((resolve, reject) => {
|
|
121
|
+
const chunks = [];
|
|
122
|
+
stream.on('data', (chunk) => chunks.push(chunk));
|
|
123
|
+
stream.on('error', reject);
|
|
124
|
+
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Config } from '../lib/config/common.js';
|
|
2
|
+
import { AddPackageToWorkspaceInput, AddPackageToWorkspaceOutput, Backend, CreateWorkspaceInput, CreateWorkspaceOutput, DeleteWorkspaceInput, DeleteWorkspaceOutput, GetProvisioningIdInput, GetProvisioningIdOutput, GetStateInput, GetStateOutput, GetWorkspaceEnvInput, GetWorkspaceEnvOutput, GetWorkspaceOutput, InitProjectInput, InitProjectOutput, RemovePackageFromWorkspaceInput, RemovePackageFromWorkspaceOutput, SetEnvVarInput, SetEnvVarOutput, UnsetEnvVarInput, UnsetEnvVarOutput } from './common.js';
|
|
3
|
+
import { FileStorage } from './file-storage/common.js';
|
|
4
|
+
export declare class FileBackend implements Backend {
|
|
5
|
+
private readonly fileStorage;
|
|
6
|
+
constructor(fileStorage: FileStorage);
|
|
7
|
+
addPackageToWorkspace(input: AddPackageToWorkspaceInput): Promise<AddPackageToWorkspaceOutput>;
|
|
8
|
+
createWorkspace(input: CreateWorkspaceInput): Promise<CreateWorkspaceOutput>;
|
|
9
|
+
deleteWorkspace(input: DeleteWorkspaceInput): Promise<DeleteWorkspaceOutput>;
|
|
10
|
+
getProvisioningId(input: GetProvisioningIdInput): Promise<GetProvisioningIdOutput>;
|
|
11
|
+
getState(input: GetStateInput): Promise<GetStateOutput>;
|
|
12
|
+
getWorkspace(workspace: string): Promise<GetWorkspaceOutput>;
|
|
13
|
+
getWorkspaceEnv(input: GetWorkspaceEnvInput): Promise<GetWorkspaceEnvOutput>;
|
|
14
|
+
init(options: InitProjectInput): Promise<InitProjectOutput>;
|
|
15
|
+
listWorkspaces(): Promise<string[]>;
|
|
16
|
+
removePackageFromWorkspace(input: RemovePackageFromWorkspaceInput): Promise<RemovePackageFromWorkspaceOutput>;
|
|
17
|
+
saveState(config: Config, workspace?: string): Promise<void>;
|
|
18
|
+
setEnvVar(input: SetEnvVarInput): Promise<SetEnvVarOutput>;
|
|
19
|
+
unsetEnvVar(input: UnsetEnvVarInput): Promise<UnsetEnvVarOutput>;
|
|
20
|
+
private saveWorkspace;
|
|
21
|
+
}
|