@toa.io/extensions.storages 0.23.0-dev.0 → 0.24.0-alpha.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/package.json +5 -4
- package/transpiled/Aspect.d.ts +8 -0
- package/transpiled/Aspect.js +21 -0
- package/transpiled/Aspect.js.map +1 -0
- package/transpiled/Entry.d.ts +14 -0
- package/transpiled/Entry.js +3 -0
- package/transpiled/Entry.js.map +1 -0
- package/transpiled/Factory.d.ts +10 -0
- package/transpiled/Factory.js +50 -0
- package/transpiled/Factory.js.map +1 -0
- package/transpiled/Provider.d.ts +8 -0
- package/transpiled/Provider.js +3 -0
- package/transpiled/Provider.js.map +1 -0
- package/transpiled/Scanner.d.ts +26 -0
- package/transpiled/Scanner.js +98 -0
- package/transpiled/Scanner.js.map +1 -0
- package/transpiled/Storage.d.ts +28 -0
- package/transpiled/Storage.js +176 -0
- package/transpiled/Storage.js.map +1 -0
- package/transpiled/deployment.d.ts +6 -0
- package/transpiled/deployment.js +52 -0
- package/transpiled/deployment.js.map +1 -0
- package/transpiled/index.d.ts +4 -0
- package/transpiled/index.js +10 -0
- package/transpiled/index.js.map +1 -0
- package/transpiled/manifest.d.ts +1 -0
- package/transpiled/manifest.js +9 -0
- package/transpiled/manifest.js.map +1 -0
- package/transpiled/providers/FileSystem.d.ts +11 -0
- package/transpiled/providers/FileSystem.js +41 -0
- package/transpiled/providers/FileSystem.js.map +1 -0
- package/transpiled/providers/S3.d.ts +13 -0
- package/transpiled/providers/S3.js +75 -0
- package/transpiled/providers/S3.js.map +1 -0
- package/transpiled/providers/Temporary.d.ts +5 -0
- package/transpiled/providers/Temporary.js +15 -0
- package/transpiled/providers/Temporary.js.map +1 -0
- package/transpiled/providers/Test.d.ts +5 -0
- package/transpiled/providers/Test.js +18 -0
- package/transpiled/providers/Test.js.map +1 -0
- package/transpiled/providers/index.d.ts +5 -0
- package/transpiled/providers/index.js +14 -0
- package/transpiled/providers/index.js.map +1 -0
- package/transpiled/test/util.d.ts +10 -0
- package/transpiled/test/util.js +61 -0
- package/transpiled/test/util.js.map +1 -0
- package/transpiled/tsconfig.tsbuildinfo +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.storages",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0-alpha.10",
|
|
4
4
|
"description": "Toa Storages",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"test": "jest",
|
|
25
|
-
"transpile": "
|
|
25
|
+
"transpile": "npx tsc"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@toa.io/streams": "0.
|
|
28
|
+
"@toa.io/streams": "0.24.0-alpha.10",
|
|
29
29
|
"@types/fs-extra": "11.0.3",
|
|
30
30
|
"dotenv": "16.3.1"
|
|
31
31
|
},
|
|
@@ -33,10 +33,11 @@
|
|
|
33
33
|
"@aws-sdk/client-s3": "3.435.0",
|
|
34
34
|
"@aws-sdk/lib-storage": "3.437.0",
|
|
35
35
|
"@toa.io/generic": "0.20.0-alpha.2",
|
|
36
|
+
"@toa.io/http": "0.24.0-alpha.10",
|
|
36
37
|
"error-value": "0.3.0",
|
|
37
38
|
"fs-extra": "11.1.1",
|
|
38
39
|
"matchacho": "0.3.5",
|
|
39
40
|
"msgpackr": "1.9.9"
|
|
40
41
|
},
|
|
41
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "c1e7032d6124a5558b7e6a4e70ab4c4a8a77e3e5"
|
|
42
43
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Connector, type extensions } from '@toa.io/core';
|
|
2
|
+
import { type Storage, type Storages } from './Storage';
|
|
3
|
+
export declare class Aspect extends Connector implements extensions.Aspect {
|
|
4
|
+
readonly name = "storages";
|
|
5
|
+
private readonly storages;
|
|
6
|
+
constructor(storages: Storages);
|
|
7
|
+
invoke(name: string, method: keyof Storage, ...args: any[]): any;
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Aspect = void 0;
|
|
4
|
+
const core_1 = require("@toa.io/core");
|
|
5
|
+
class Aspect extends core_1.Connector {
|
|
6
|
+
name = 'storages';
|
|
7
|
+
storages;
|
|
8
|
+
constructor(storages) {
|
|
9
|
+
super();
|
|
10
|
+
this.storages = storages;
|
|
11
|
+
}
|
|
12
|
+
invoke(name, method, ...args) {
|
|
13
|
+
if (!(name in this.storages))
|
|
14
|
+
throw new Error(`Storage '${name}' is not defined`);
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
16
|
+
// @ts-expect-error
|
|
17
|
+
return this.storages[name][method](...args);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.Aspect = Aspect;
|
|
21
|
+
//# sourceMappingURL=Aspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aspect.js","sourceRoot":"","sources":["../source/Aspect.ts"],"names":[],"mappings":";;;AAAA,uCAAyD;AAGzD,MAAa,MAAO,SAAQ,gBAAS;IACnB,IAAI,GAAG,UAAU,CAAA;IAEhB,QAAQ,CAAU;IAEnC,YAAoB,QAAkB;QACpC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAEM,MAAM,CAAE,IAAY,EAAE,MAAqB,EAAE,GAAG,IAAW;QAChE,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,kBAAkB,CAAC,CAAA;QAErD,6DAA6D;QAC7D,mBAAmB;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC7C,CAAC;CACF;AAnBD,wBAmBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Entry.js","sourceRoot":"","sources":["../source/Entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Storage } from './Storage';
|
|
2
|
+
import { Aspect } from './Aspect';
|
|
3
|
+
export declare class Factory {
|
|
4
|
+
private readonly declaration;
|
|
5
|
+
constructor();
|
|
6
|
+
aspect(): Aspect;
|
|
7
|
+
createStorage(name: string, ref: string): Storage;
|
|
8
|
+
private createStorages;
|
|
9
|
+
private resolveSecrets;
|
|
10
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Factory = void 0;
|
|
4
|
+
const msgpackr_1 = require("msgpackr");
|
|
5
|
+
const providers_1 = require("./providers");
|
|
6
|
+
const Storage_1 = require("./Storage");
|
|
7
|
+
const Aspect_1 = require("./Aspect");
|
|
8
|
+
class Factory {
|
|
9
|
+
declaration;
|
|
10
|
+
constructor() {
|
|
11
|
+
const env = process.env.TOA_STORAGES;
|
|
12
|
+
if (env === undefined)
|
|
13
|
+
throw new Error('TOA_STORAGES is not defined');
|
|
14
|
+
this.declaration = (0, msgpackr_1.decode)(Buffer.from(env, 'base64'));
|
|
15
|
+
}
|
|
16
|
+
aspect() {
|
|
17
|
+
const storages = this.createStorages();
|
|
18
|
+
return new Aspect_1.Aspect(storages);
|
|
19
|
+
}
|
|
20
|
+
createStorage(name, ref) {
|
|
21
|
+
const url = new URL(ref);
|
|
22
|
+
const Provider = providers_1.providers[url.protocol];
|
|
23
|
+
if (Provider === undefined)
|
|
24
|
+
throw new Error(`No provider found for '${url.protocol}'`);
|
|
25
|
+
const secrets = this.resolveSecrets(name, Provider);
|
|
26
|
+
const provider = new Provider(url, secrets);
|
|
27
|
+
return new Storage_1.Storage(provider);
|
|
28
|
+
}
|
|
29
|
+
createStorages() {
|
|
30
|
+
const storages = {};
|
|
31
|
+
for (const [name, ref] of Object.entries(this.declaration))
|
|
32
|
+
storages[name] = this.createStorage(name, ref);
|
|
33
|
+
return storages;
|
|
34
|
+
}
|
|
35
|
+
resolveSecrets(name, Class) {
|
|
36
|
+
if (Class.SECRETS === undefined)
|
|
37
|
+
return {};
|
|
38
|
+
const secrets = {};
|
|
39
|
+
for (const secret of Class.SECRETS) {
|
|
40
|
+
const variable = `TOA_STORAGES_${name.toUpperCase()}_${secret.toUpperCase()}`;
|
|
41
|
+
const value = process.env[variable];
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
throw new Error(`${variable} is not defined`);
|
|
44
|
+
secrets[secret] = value;
|
|
45
|
+
}
|
|
46
|
+
return secrets;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.Factory = Factory;
|
|
50
|
+
//# sourceMappingURL=Factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Factory.js","sourceRoot":"","sources":["../source/Factory.ts"],"names":[],"mappings":";;;AAAA,uCAAiC;AACjC,2CAA2D;AAC3D,uCAAkD;AAClD,qCAAiC;AAEjC,MAAa,OAAO;IACD,WAAW,CAAwB;IAEpD;QACE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAA;QAEpC,IAAI,GAAG,KAAK,SAAS;YACnB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAEhD,IAAI,CAAC,WAAW,GAAG,IAAA,iBAAM,EAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAA2B,CAAA;IACjF,CAAC;IAEM,MAAM;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;QAEtC,OAAO,IAAI,eAAM,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;IAEM,aAAa,CAAE,IAAY,EAAE,GAAW;QAC7C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACxB,MAAM,QAAQ,GAAG,qBAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAExC,IAAI,QAAQ,KAAK,SAAS;YACxB,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAA;QAE5D,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAEnD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAE3C,OAAO,IAAI,iBAAO,CAAC,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAEO,cAAc;QACpB,MAAM,QAAQ,GAAa,EAAE,CAAA;QAE7B,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;YACxD,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAEhD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEO,cAAc,CAAE,IAAY,EAAE,KAAoB;QACxD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;YAC7B,OAAO,EAAE,CAAA;QAEX,MAAM,OAAO,GAA2B,EAAE,CAAA;QAE1C,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE;YAClC,MAAM,QAAQ,GAAG,gBAAgB,IAAI,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAA;YAC7E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAEnC,IAAI,KAAK,KAAK,SAAS;gBACrB,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,iBAAiB,CAAC,CAAA;YAE/C,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,CAAA;SACxB;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AA3DD,0BA2DC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type Readable } from 'node:stream';
|
|
3
|
+
export interface Provider {
|
|
4
|
+
get: (path: string) => Promise<Readable | null>;
|
|
5
|
+
put: (path: string, filename: string, stream: Readable) => Promise<void>;
|
|
6
|
+
delete: (path: string) => Promise<void>;
|
|
7
|
+
move: (from: string, to: string) => Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Provider.js","sourceRoot":"","sources":["../source/Provider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { PassThrough, type TransformCallback } from 'node:stream';
|
|
4
|
+
export declare class Scanner extends PassThrough {
|
|
5
|
+
size: number;
|
|
6
|
+
type: string;
|
|
7
|
+
error: Error | null;
|
|
8
|
+
private readonly hash;
|
|
9
|
+
private readonly claim?;
|
|
10
|
+
private readonly accept?;
|
|
11
|
+
private position;
|
|
12
|
+
private detected;
|
|
13
|
+
private readonly chunks;
|
|
14
|
+
constructor(control?: TypeControl);
|
|
15
|
+
digest(): string;
|
|
16
|
+
_transform(buffer: Buffer, encoding: BufferEncoding, callback: TransformCallback): void;
|
|
17
|
+
private readonly process;
|
|
18
|
+
private complete;
|
|
19
|
+
private verify;
|
|
20
|
+
private match;
|
|
21
|
+
private interrupt;
|
|
22
|
+
}
|
|
23
|
+
export interface TypeControl {
|
|
24
|
+
claim?: string;
|
|
25
|
+
accept?: string;
|
|
26
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Scanner = void 0;
|
|
4
|
+
const node_stream_1 = require("node:stream");
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const http_1 = require("@toa.io/http");
|
|
7
|
+
const error_value_1 = require("error-value");
|
|
8
|
+
class Scanner extends node_stream_1.PassThrough {
|
|
9
|
+
size = 0;
|
|
10
|
+
type = 'application/octet-stream';
|
|
11
|
+
error = null;
|
|
12
|
+
hash = (0, node_crypto_1.createHash)('md5');
|
|
13
|
+
claim;
|
|
14
|
+
accept;
|
|
15
|
+
position = 0;
|
|
16
|
+
detected = false;
|
|
17
|
+
chunks = [];
|
|
18
|
+
constructor(control) {
|
|
19
|
+
super();
|
|
20
|
+
this.claim = control?.claim;
|
|
21
|
+
this.accept = control?.accept;
|
|
22
|
+
}
|
|
23
|
+
digest() {
|
|
24
|
+
return this.hash.digest('hex');
|
|
25
|
+
}
|
|
26
|
+
_transform(buffer, encoding, callback) {
|
|
27
|
+
super._transform(buffer, encoding, callback);
|
|
28
|
+
this.process(buffer);
|
|
29
|
+
}
|
|
30
|
+
process = (buffer) => {
|
|
31
|
+
this.size += buffer.length;
|
|
32
|
+
this.hash.update(buffer);
|
|
33
|
+
if (this.detected)
|
|
34
|
+
return;
|
|
35
|
+
if (this.position + buffer.length > HEADER_SIZE)
|
|
36
|
+
buffer = buffer.subarray(0, HEADER_SIZE - this.position);
|
|
37
|
+
this.chunks.push(buffer);
|
|
38
|
+
this.position += buffer.length;
|
|
39
|
+
if (this.position === HEADER_SIZE)
|
|
40
|
+
this.complete();
|
|
41
|
+
};
|
|
42
|
+
complete() {
|
|
43
|
+
const header = Buffer.concat(this.chunks).toString('hex');
|
|
44
|
+
const signature = SIGNATURES
|
|
45
|
+
.find(({ hex, off }) => header.slice(off, off + hex.length) === hex);
|
|
46
|
+
const type = signature?.type ?? this.claim;
|
|
47
|
+
if (type !== undefined) {
|
|
48
|
+
this.match(type);
|
|
49
|
+
this.type = type;
|
|
50
|
+
}
|
|
51
|
+
this.verify(signature);
|
|
52
|
+
this.detected = true;
|
|
53
|
+
}
|
|
54
|
+
verify(signature) {
|
|
55
|
+
if (this.claim === undefined || this.claim === 'application/octet-stream')
|
|
56
|
+
return;
|
|
57
|
+
const mismatch = signature === undefined
|
|
58
|
+
? KNOWN_TYPES.has(this.claim)
|
|
59
|
+
: this.claim !== signature.type;
|
|
60
|
+
if (mismatch)
|
|
61
|
+
this.interrupt(ERR_TYPE_MISMATCH);
|
|
62
|
+
}
|
|
63
|
+
match(type) {
|
|
64
|
+
if (this.accept === undefined)
|
|
65
|
+
return;
|
|
66
|
+
const unacceptable = (0, http_1.negotiate)(this.accept, [type]) === null;
|
|
67
|
+
if (unacceptable)
|
|
68
|
+
this.interrupt(ERR_NOT_ACCEPTABLE);
|
|
69
|
+
}
|
|
70
|
+
interrupt(error) {
|
|
71
|
+
this.error = error;
|
|
72
|
+
this.end();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.Scanner = Scanner;
|
|
76
|
+
// https://en.wikipedia.org/wiki/List_of_file_signatures
|
|
77
|
+
const SIGNATURES = [
|
|
78
|
+
{ hex: 'ffd8ffe0', off: 0, type: 'image/jpeg' },
|
|
79
|
+
{ hex: 'ffd8ffe1', off: 0, type: 'image/jpeg' },
|
|
80
|
+
{ hex: 'ffd8ffee', off: 0, type: 'image/jpeg' },
|
|
81
|
+
{ hex: 'ffd8ffdb', off: 0, type: 'image/jpeg' },
|
|
82
|
+
{ hex: '89504e47', off: 0, type: 'image/png' },
|
|
83
|
+
{ hex: '47494638', off: 0, type: 'image/gif' },
|
|
84
|
+
{ hex: '52494646', off: 0, type: 'image/webp' },
|
|
85
|
+
{ hex: '4a584c200d0a870a', off: 8, type: 'image/jxl' },
|
|
86
|
+
{ hex: '6674797068656963', off: 8, type: 'image/heic' },
|
|
87
|
+
{ hex: '6674797061766966', off: 8, type: 'image/avif' }
|
|
88
|
+
/*
|
|
89
|
+
When adding a new signature, include a copyright-free sample file in the `.tests` directory
|
|
90
|
+
and update the 'signatures' test group in `Storage.test.ts`.
|
|
91
|
+
*/
|
|
92
|
+
];
|
|
93
|
+
const HEADER_SIZE = SIGNATURES
|
|
94
|
+
.reduce((max, { off, hex }) => Math.max(max, off + hex.length), 0) / 2;
|
|
95
|
+
const KNOWN_TYPES = new Set(SIGNATURES.map(({ type }) => type));
|
|
96
|
+
const ERR_TYPE_MISMATCH = (0, error_value_1.Err)('TYPE_MISMATCH');
|
|
97
|
+
const ERR_NOT_ACCEPTABLE = (0, error_value_1.Err)('NOT_ACCEPTABLE');
|
|
98
|
+
//# sourceMappingURL=Scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scanner.js","sourceRoot":"","sources":["../source/Scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Readable } from 'node:stream';
|
|
3
|
+
import type { TypeControl } from './Scanner';
|
|
4
|
+
import type { Provider } from './Provider';
|
|
5
|
+
import type { Entry } from './Entry';
|
|
6
|
+
export declare class Storage {
|
|
7
|
+
private readonly provider;
|
|
8
|
+
constructor(provider: Provider);
|
|
9
|
+
put(path: string, stream: Readable, type?: TypeControl): Maybe<Entry>;
|
|
10
|
+
get(path: string): Maybe<Entry>;
|
|
11
|
+
fetch(path: string): Maybe<Readable>;
|
|
12
|
+
delete(path: string): Maybe<void>;
|
|
13
|
+
list(path: string): Promise<string[]>;
|
|
14
|
+
permute(path: string, ids: string[]): Maybe<void>;
|
|
15
|
+
conceal(path: string): Maybe<void>;
|
|
16
|
+
reveal(path: string): Maybe<void>;
|
|
17
|
+
diversify(path: string, name: string, stream: Readable): Maybe<void>;
|
|
18
|
+
annotate(path: string, key: string, value?: unknown): Maybe<void>;
|
|
19
|
+
private transit;
|
|
20
|
+
private persist;
|
|
21
|
+
private create;
|
|
22
|
+
private save;
|
|
23
|
+
private enroll;
|
|
24
|
+
private parse;
|
|
25
|
+
}
|
|
26
|
+
type Maybe<T> = Promise<T | Error>;
|
|
27
|
+
export type Storages = Record<string, Storage>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Storage = void 0;
|
|
4
|
+
const node_stream_1 = require("node:stream");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const msgpackr_1 = require("msgpackr");
|
|
7
|
+
const generic_1 = require("@toa.io/generic");
|
|
8
|
+
const error_value_1 = require("error-value");
|
|
9
|
+
const Scanner_1 = require("./Scanner");
|
|
10
|
+
class Storage {
|
|
11
|
+
provider;
|
|
12
|
+
constructor(provider) {
|
|
13
|
+
this.provider = provider;
|
|
14
|
+
}
|
|
15
|
+
async put(path, stream, type) {
|
|
16
|
+
const scanner = new Scanner_1.Scanner(type);
|
|
17
|
+
const pipe = stream.pipe(scanner);
|
|
18
|
+
const tempname = await this.transit(pipe);
|
|
19
|
+
if (scanner.error !== null)
|
|
20
|
+
return scanner.error;
|
|
21
|
+
const id = scanner.digest();
|
|
22
|
+
await this.persist(tempname, id);
|
|
23
|
+
return await this.create(path, id, scanner.size, scanner.type);
|
|
24
|
+
}
|
|
25
|
+
async get(path) {
|
|
26
|
+
const metapath = node_path_1.posix.join(ENTRIES, path, META);
|
|
27
|
+
const result = await this.provider.get(metapath);
|
|
28
|
+
if (result === null)
|
|
29
|
+
return ERR_NOT_FOUND;
|
|
30
|
+
else
|
|
31
|
+
return (0, msgpackr_1.decode)(await (0, generic_1.buffer)(result));
|
|
32
|
+
}
|
|
33
|
+
async fetch(path) {
|
|
34
|
+
const { rel, id, variant } = this.parse(path);
|
|
35
|
+
if (variant === null && rel !== '') {
|
|
36
|
+
const entry = await this.get(path);
|
|
37
|
+
if (entry instanceof Error)
|
|
38
|
+
return entry;
|
|
39
|
+
}
|
|
40
|
+
const blob = variant === null
|
|
41
|
+
? node_path_1.posix.join(BLOBs, id)
|
|
42
|
+
: node_path_1.posix.join(ENTRIES, rel, id, variant);
|
|
43
|
+
const stream = await this.provider.get(blob);
|
|
44
|
+
if (stream === null)
|
|
45
|
+
return ERR_NOT_FOUND;
|
|
46
|
+
else
|
|
47
|
+
return stream;
|
|
48
|
+
}
|
|
49
|
+
async delete(path) {
|
|
50
|
+
const entry = await this.get(path);
|
|
51
|
+
if (entry instanceof Error)
|
|
52
|
+
return entry;
|
|
53
|
+
await this.conceal(path);
|
|
54
|
+
await this.provider.delete(node_path_1.posix.join(ENTRIES, path));
|
|
55
|
+
}
|
|
56
|
+
async list(path) {
|
|
57
|
+
const listfile = node_path_1.posix.join(ENTRIES, path, LIST);
|
|
58
|
+
const stream = await this.provider.get(listfile);
|
|
59
|
+
return stream === null ? [] : (0, msgpackr_1.decode)(await (0, generic_1.buffer)(stream));
|
|
60
|
+
}
|
|
61
|
+
async permute(path, ids) {
|
|
62
|
+
const unique = new Set(ids);
|
|
63
|
+
const dir = node_path_1.posix.join(ENTRIES, path);
|
|
64
|
+
const list = await this.list(path);
|
|
65
|
+
if (list.length !== ids.length || unique.size !== ids.length)
|
|
66
|
+
return ERR_PERMUTATION_MISMATCH;
|
|
67
|
+
for (const id of ids)
|
|
68
|
+
if (!list.includes(id))
|
|
69
|
+
return ERR_PERMUTATION_MISMATCH;
|
|
70
|
+
await this.provider.put(dir, LIST, node_stream_1.Readable.from((0, msgpackr_1.encode)(ids)));
|
|
71
|
+
}
|
|
72
|
+
async conceal(path) {
|
|
73
|
+
const { id, rel } = this.parse(path);
|
|
74
|
+
const dir = node_path_1.posix.join(ENTRIES, rel);
|
|
75
|
+
const list = await this.list(rel);
|
|
76
|
+
const index = list.indexOf(id);
|
|
77
|
+
if (index === -1)
|
|
78
|
+
return ERR_NOT_FOUND;
|
|
79
|
+
list.splice(index, 1);
|
|
80
|
+
await this.provider.put(dir, LIST, node_stream_1.Readable.from((0, msgpackr_1.encode)(list)));
|
|
81
|
+
}
|
|
82
|
+
async reveal(path) {
|
|
83
|
+
const { id, rel } = this.parse(path);
|
|
84
|
+
return await this.enroll(rel, id);
|
|
85
|
+
}
|
|
86
|
+
async diversify(path, name, stream) {
|
|
87
|
+
const scanner = new Scanner_1.Scanner();
|
|
88
|
+
const pipe = stream.pipe(scanner);
|
|
89
|
+
await this.provider.put(node_path_1.posix.join(ENTRIES, path), name, pipe);
|
|
90
|
+
if (scanner.error !== null)
|
|
91
|
+
return scanner.error;
|
|
92
|
+
const { size, type } = scanner;
|
|
93
|
+
const entry = await this.get(path);
|
|
94
|
+
if (entry instanceof Error)
|
|
95
|
+
return entry;
|
|
96
|
+
entry.variants = entry.variants.filter((variant) => variant.name !== name);
|
|
97
|
+
entry.variants.push({ name, size, type });
|
|
98
|
+
await this.save(path, entry);
|
|
99
|
+
}
|
|
100
|
+
async annotate(path, key, value) {
|
|
101
|
+
const entry = await this.get(path);
|
|
102
|
+
if (entry instanceof Error)
|
|
103
|
+
return entry;
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
105
|
+
if (value === undefined)
|
|
106
|
+
delete entry.meta[key];
|
|
107
|
+
else
|
|
108
|
+
entry.meta[key] = value;
|
|
109
|
+
await this.save(path, entry);
|
|
110
|
+
}
|
|
111
|
+
async transit(stream) {
|
|
112
|
+
const tempname = (0, generic_1.newid)();
|
|
113
|
+
await this.provider.put(TEMP, tempname, stream);
|
|
114
|
+
return tempname;
|
|
115
|
+
}
|
|
116
|
+
async persist(tempname, id) {
|
|
117
|
+
const temp = node_path_1.posix.join(TEMP, tempname);
|
|
118
|
+
const blob = node_path_1.posix.join(BLOBs, id);
|
|
119
|
+
await this.provider.move(temp, blob);
|
|
120
|
+
}
|
|
121
|
+
// eslint-disable-next-line max-params
|
|
122
|
+
async create(path, id, size, type) {
|
|
123
|
+
const entry = {
|
|
124
|
+
id,
|
|
125
|
+
size,
|
|
126
|
+
type,
|
|
127
|
+
created: Date.now(),
|
|
128
|
+
variants: [],
|
|
129
|
+
meta: {}
|
|
130
|
+
};
|
|
131
|
+
const metafile = node_path_1.posix.join(path, entry.id);
|
|
132
|
+
const existing = await this.get(metafile);
|
|
133
|
+
if (existing instanceof Error)
|
|
134
|
+
await this.save(metafile, entry);
|
|
135
|
+
await this.enroll(path, id, true);
|
|
136
|
+
return entry;
|
|
137
|
+
}
|
|
138
|
+
async save(rel, entry) {
|
|
139
|
+
const buffer = (0, msgpackr_1.encode)(entry);
|
|
140
|
+
const stream = node_stream_1.Readable.from(buffer);
|
|
141
|
+
await this.provider.put(node_path_1.posix.join(ENTRIES, rel), META, stream);
|
|
142
|
+
}
|
|
143
|
+
async enroll(path, id, addition = false) {
|
|
144
|
+
const dir = node_path_1.posix.join(ENTRIES, path);
|
|
145
|
+
const list = await this.list(path);
|
|
146
|
+
const index = list.indexOf(id);
|
|
147
|
+
if (index !== -1)
|
|
148
|
+
if (addition)
|
|
149
|
+
list.splice(index, 1);
|
|
150
|
+
else
|
|
151
|
+
return;
|
|
152
|
+
else if (!addition) {
|
|
153
|
+
const entry = await this.get(node_path_1.posix.join(path, id));
|
|
154
|
+
if (entry instanceof Error)
|
|
155
|
+
return entry;
|
|
156
|
+
}
|
|
157
|
+
list.push(id);
|
|
158
|
+
await this.provider.put(dir, LIST, node_stream_1.Readable.from((0, msgpackr_1.encode)(list)));
|
|
159
|
+
}
|
|
160
|
+
parse(path) {
|
|
161
|
+
const [last, ...segments] = path.split('/').reverse();
|
|
162
|
+
const [id, ...rest] = last.split('.');
|
|
163
|
+
const variant = rest.length > 0 ? rest.join('.') : null;
|
|
164
|
+
const rel = segments.reverse().join('/');
|
|
165
|
+
return { rel, id, variant };
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
exports.Storage = Storage;
|
|
169
|
+
const ERR_NOT_FOUND = (0, error_value_1.Err)('NOT_FOUND');
|
|
170
|
+
const ERR_PERMUTATION_MISMATCH = (0, error_value_1.Err)('PERMUTATION_MISMATCH');
|
|
171
|
+
const TEMP = '/temp';
|
|
172
|
+
const BLOBs = '/blobs';
|
|
173
|
+
const ENTRIES = '/entries';
|
|
174
|
+
const LIST = '.list';
|
|
175
|
+
const META = '.meta';
|
|
176
|
+
//# sourceMappingURL=Storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Storage.js","sourceRoot":"","sources":["../source/Storage.ts"],"names":[],"mappings":";;;AAAA,6CAAsC;AACtC,yCAAiC;AACjC,uCAAyC;AACzC,6CAA+C;AAC/C,6CAAiC;AACjC,uCAAmC;AAKnC,MAAa,OAAO;IACD,QAAQ,CAAU;IAEnC,YAAoB,QAAkB;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,IAAY,EAAE,MAAgB,EAAE,IAAkB;QAClE,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAEzC,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI;YACxB,OAAO,OAAO,CAAC,KAAK,CAAA;QAEtB,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAA;QAE3B,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;QAEhC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,IAAY;QAC5B,MAAM,QAAQ,GAAG,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAEhD,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,aAAa,CAAA;;YACpC,OAAO,IAAA,iBAAM,EAAC,MAAM,IAAA,gBAAM,EAAC,MAAM,CAAC,CAAC,CAAA;IAC1C,CAAC;IAEM,KAAK,CAAC,KAAK,CAAE,IAAY;QAC9B,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAE7C,IAAI,OAAO,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAElC,IAAI,KAAK,YAAY,KAAK;gBACxB,OAAO,KAAK,CAAA;SACf;QAED,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI;YAC3B,CAAC,CAAC,iBAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;YACvB,CAAC,CAAC,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;QAEzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAE5C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,aAAa,CAAA;;YACpC,OAAO,MAAM,CAAA;IACpB,CAAC;IAEM,KAAK,CAAC,MAAM,CAAE,IAAY;QAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAElC,IAAI,KAAK,YAAY,KAAK;YACxB,OAAO,KAAK,CAAA;QAEd,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;IACvD,CAAC;IAEM,KAAK,CAAC,IAAI,CAAE,IAAY;QAC7B,MAAM,QAAQ,GAAG,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAEhD,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,iBAAM,EAAC,MAAM,IAAA,gBAAM,EAAC,MAAM,CAAC,CAAC,CAAA;IAC5D,CAAC;IAEM,KAAK,CAAC,OAAO,CAAE,IAAY,EAAE,GAAa;QAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,MAAM,GAAG,GAAG,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QACrC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAElC,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,MAAM;YAC1D,OAAO,wBAAwB,CAAA;QAEjC,KAAK,MAAM,EAAE,IAAI,GAAG;YAClB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpB,OAAO,wBAAwB,CAAA;QAEnC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,sBAAQ,CAAC,IAAI,CAAC,IAAA,iBAAM,EAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IAChE,CAAC;IAEM,KAAK,CAAC,OAAO,CAAE,IAAY;QAChC,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACpC,MAAM,GAAG,GAAG,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QACpC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAE9B,IAAI,KAAK,KAAK,CAAC,CAAC;YACd,OAAO,aAAa,CAAA;QAEtB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QAErB,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,sBAAQ,CAAC,IAAI,CAAC,IAAA,iBAAM,EAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC;IAEM,KAAK,CAAC,MAAM,CAAE,IAAY;QAC/B,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAEpC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IACnC,CAAC;IAEM,KAAK,CAAC,SAAS,CAAE,IAAY,EAAE,IAAY,EAAE,MAAgB;QAClE,MAAM,OAAO,GAAG,IAAI,iBAAO,EAAE,CAAA;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAEjC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QAE9D,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI;YACxB,OAAO,OAAO,CAAC,KAAK,CAAA;QAEtB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;QAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAElC,IAAI,KAAK,YAAY,KAAK;YACxB,OAAO,KAAK,CAAA;QAEd,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QAC1E,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAEzC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAE,IAAY,EAAE,GAAW,EAAE,KAAe;QAC/D,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAElC,IAAI,KAAK,YAAY,KAAK;YACxB,OAAO,KAAK,CAAA;QAEd,gEAAgE;QAChE,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;;YAC1C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QAE5B,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC9B,CAAC;IAEO,KAAK,CAAC,OAAO,CAAE,MAAgB;QACrC,MAAM,QAAQ,GAAG,IAAA,eAAK,GAAE,CAAA;QAExB,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAE/C,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEO,KAAK,CAAC,OAAO,CAAE,QAAgB,EAAE,EAAU;QACjD,MAAM,IAAI,GAAG,iBAAK,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,iBAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QAElC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IACtC,CAAC;IAED,sCAAsC;IAC9B,KAAK,CAAC,MAAM,CAAE,IAAY,EAAE,EAAU,EAAE,IAAY,EAAE,IAAY;QACxE,MAAM,KAAK,GAAU;YACnB,EAAE;YACF,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;YACnB,QAAQ,EAAE,EAAE;YACZ,IAAI,EAAE,EAAE;SACT,CAAA;QAED,MAAM,QAAQ,GAAG,iBAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;QAC3C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAEzC,IAAI,QAAQ,YAAY,KAAK;YAC3B,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAElC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;QAEjC,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,KAAK,CAAC,IAAI,CAAE,GAAW,EAAE,KAAY;QAC3C,MAAM,MAAM,GAAG,IAAA,iBAAM,EAAC,KAAK,CAAC,CAAA;QAC5B,MAAM,MAAM,GAAG,sBAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAEpC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IACjE,CAAC;IAEO,KAAK,CAAC,MAAM,CAAE,IAAY,EAAE,EAAU,EAAE,WAAoB,KAAK;QACvE,MAAM,GAAG,GAAG,iBAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QACrC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAE9B,IAAI,KAAK,KAAK,CAAC,CAAC;YACd,IAAI,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;;gBAC9B,OAAM;aACR,IAAI,CAAC,QAAQ,EAAE;YAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;YAElD,IAAI,KAAK,YAAY,KAAK;gBACxB,OAAO,KAAK,CAAA;SACf;QAED,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAEb,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,sBAAQ,CAAC,IAAI,CAAC,IAAA,iBAAM,EAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjE,CAAC;IAEO,KAAK,CAAE,IAAY;QACzB,MAAM,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAA;QACrD,MAAM,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACvD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAExC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,CAAA;IAC7B,CAAC;CACF;AAhND,0BAgNC;AAED,MAAM,aAAa,GAAG,IAAA,iBAAG,EAAC,WAAW,CAAC,CAAA;AACtC,MAAM,wBAAwB,GAAG,IAAA,iBAAG,EAAC,sBAAsB,CAAC,CAAA;AAE5D,MAAM,IAAI,GAAG,OAAO,CAAA;AACpB,MAAM,KAAK,GAAG,QAAQ,CAAA;AACtB,MAAM,OAAO,GAAG,UAAU,CAAA;AAC1B,MAAM,IAAI,GAAG,OAAO,CAAA;AACpB,MAAM,IAAI,GAAG,OAAO,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Dependency } from '@toa.io/operations';
|
|
2
|
+
import type { context } from '@toa.io/norm';
|
|
3
|
+
export declare function deployment(instances: Instance[], annotation: Annotation): Dependency;
|
|
4
|
+
type Annotation = Record<string, string>;
|
|
5
|
+
export type Instance = context.Dependency<string[]>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deployment = void 0;
|
|
4
|
+
const msgpackr_1 = require("msgpackr");
|
|
5
|
+
const providers_1 = require("./providers");
|
|
6
|
+
function deployment(instances, annotation) {
|
|
7
|
+
validate(instances, annotation);
|
|
8
|
+
const value = (0, msgpackr_1.encode)(annotation).toString('base64');
|
|
9
|
+
const pointer = { name: 'TOA_STORAGES', value };
|
|
10
|
+
const secrets = getSecrets(annotation);
|
|
11
|
+
return {
|
|
12
|
+
variables: { global: [pointer, ...secrets] }
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
exports.deployment = deployment;
|
|
16
|
+
function validate(instances, annotation) {
|
|
17
|
+
if (annotation === undefined)
|
|
18
|
+
throw new Error('Storages annotation is required by: ' +
|
|
19
|
+
`'${instances.map((i) => i.component.locator.id).join("', '")}'`);
|
|
20
|
+
for (const instance of instances)
|
|
21
|
+
contains(instance, annotation);
|
|
22
|
+
for (const ref of Object.values(annotation)) {
|
|
23
|
+
const url = new URL(ref);
|
|
24
|
+
if (!(url.protocol in providers_1.providers))
|
|
25
|
+
throw new Error(`Unknown storage provider '${url.protocol}'`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function contains(instance, annotation) {
|
|
29
|
+
for (const name of instance.manifest)
|
|
30
|
+
if (!(name in annotation))
|
|
31
|
+
throw new Error(`Missing '${name}' storage annotation ` +
|
|
32
|
+
`declared in '${instance.component.locator.id}'`);
|
|
33
|
+
}
|
|
34
|
+
function getSecrets(annotation) {
|
|
35
|
+
const secrets = [];
|
|
36
|
+
for (const [storage, ref] of Object.entries(annotation)) {
|
|
37
|
+
const url = new URL(ref);
|
|
38
|
+
const Provider = providers_1.providers[url.protocol];
|
|
39
|
+
if (Provider.SECRETS === undefined)
|
|
40
|
+
continue;
|
|
41
|
+
for (const secret of Provider.SECRETS)
|
|
42
|
+
secrets.push({
|
|
43
|
+
name: `TOA_STORAGES_${storage.toUpperCase()}_${secret.toUpperCase()}`,
|
|
44
|
+
secret: {
|
|
45
|
+
name: `toa-storages-${storage}`,
|
|
46
|
+
key: secret
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return secrets;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=deployment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment.js","sourceRoot":"","sources":["../source/deployment.ts"],"names":[],"mappings":";;;AAAA,uCAAiC;AACjC,2CAAuC;AAIvC,SAAgB,UAAU,CAAE,SAAqB,EAAE,UAAsB;IACvE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;IAE/B,MAAM,KAAK,GAAG,IAAA,iBAAM,EAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACnD,MAAM,OAAO,GAAa,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAA;IACzD,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;IAEtC,OAAO;QACL,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,EAAE;KAC7C,CAAA;AACH,CAAC;AAVD,gCAUC;AAED,SAAS,QAAQ,CAAE,SAAqB,EAAE,UAAsB;IAC9D,IAAI,UAAU,KAAK,SAAS;QAC1B,MAAM,IAAI,KAAK,CAAC,sCAAsC;YACpD,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAErE,KAAK,MAAM,QAAQ,IAAI,SAAS;QAC9B,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IAEhC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;QAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QAExB,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,IAAI,qBAAS,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAA;KAChE;AACH,CAAC;AAED,SAAS,QAAQ,CAAE,QAAkB,EAAE,UAAsB;IAC3D,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,QAAQ;QAClC,IAAI,CAAC,CAAC,IAAI,IAAI,UAAU,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,uBAAuB;gBACrD,gBAAgB,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAA;AACzD,CAAC;AAED,SAAS,UAAU,CAAE,UAAsB;IACzC,MAAM,OAAO,GAAe,EAAE,CAAA;IAE9B,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;QACvD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACxB,MAAM,QAAQ,GAAG,qBAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAExC,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS;YAChC,SAAQ;QAEV,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO;YACnC,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,gBAAgB,OAAO,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE;gBACrE,MAAM,EAAE;oBACN,IAAI,EAAE,gBAAgB,OAAO,EAAE;oBAC/B,GAAG,EAAE,MAAM;iBACZ;aACiB,CAAC,CAAA;KACxB;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.manifest = exports.deployment = exports.Factory = void 0;
|
|
4
|
+
var Factory_1 = require("./Factory");
|
|
5
|
+
Object.defineProperty(exports, "Factory", { enumerable: true, get: function () { return Factory_1.Factory; } });
|
|
6
|
+
var deployment_1 = require("./deployment");
|
|
7
|
+
Object.defineProperty(exports, "deployment", { enumerable: true, get: function () { return deployment_1.deployment; } });
|
|
8
|
+
var manifest_1 = require("./manifest");
|
|
9
|
+
Object.defineProperty(exports, "manifest", { enumerable: true, get: function () { return manifest_1.manifest; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";;;AAAA,qCAAmC;AAA1B,kGAAA,OAAO,OAAA;AAChB,2CAAyC;AAAhC,wGAAA,UAAU,OAAA;AACnB,uCAAqC;AAA5B,oGAAA,QAAQ,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function manifest(manifest: string | string[] | null): string[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.manifest = void 0;
|
|
4
|
+
const matchacho_1 = require("matchacho");
|
|
5
|
+
function manifest(manifest) {
|
|
6
|
+
return (0, matchacho_1.match)(manifest, String, (name) => [name], Array, manifest, null, []);
|
|
7
|
+
}
|
|
8
|
+
exports.manifest = manifest;
|
|
9
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../source/manifest.ts"],"names":[],"mappings":";;;AAAA,yCAAiC;AAEjC,SAAgB,QAAQ,CAAE,QAAkC;IAC1D,OAAO,IAAA,iBAAK,EAAC,QAAQ,EACnB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAChC,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,EAAE,CAAC,CAAA;AACb,CAAC;AALD,4BAKC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type Readable } from 'node:stream';
|
|
3
|
+
import { type Provider } from '../Provider';
|
|
4
|
+
export declare class FileSystem implements Provider {
|
|
5
|
+
protected readonly path: string;
|
|
6
|
+
constructor(url: URL);
|
|
7
|
+
get(path: string): Promise<Readable | null>;
|
|
8
|
+
put(rel: string, filename: string, stream: Readable): Promise<void>;
|
|
9
|
+
delete(path: string): Promise<void>;
|
|
10
|
+
move(from: string, to: string): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FileSystem = void 0;
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
10
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
|
+
class FileSystem {
|
|
12
|
+
path;
|
|
13
|
+
constructor(url) {
|
|
14
|
+
if (url.host !== '')
|
|
15
|
+
throw new Error('File system URL must not contain host');
|
|
16
|
+
this.path = url.pathname;
|
|
17
|
+
}
|
|
18
|
+
async get(path) {
|
|
19
|
+
path = (0, node_path_1.join)(this.path, path);
|
|
20
|
+
if (!await fs_extra_1.default.exists(path))
|
|
21
|
+
return null;
|
|
22
|
+
return (0, node_fs_1.createReadStream)(path);
|
|
23
|
+
}
|
|
24
|
+
async put(rel, filename, stream) {
|
|
25
|
+
const dir = (0, node_path_1.join)(this.path, rel);
|
|
26
|
+
const path = (0, node_path_1.join)(dir, filename);
|
|
27
|
+
await fs_extra_1.default.ensureDir(dir);
|
|
28
|
+
await promises_1.default.writeFile(path, stream);
|
|
29
|
+
}
|
|
30
|
+
async delete(path) {
|
|
31
|
+
await fs_extra_1.default.remove((0, node_path_1.join)(this.path, path));
|
|
32
|
+
}
|
|
33
|
+
async move(from, to) {
|
|
34
|
+
from = (0, node_path_1.join)(this.path, from);
|
|
35
|
+
to = (0, node_path_1.join)(this.path, to);
|
|
36
|
+
await fs_extra_1.default.ensureDir((0, node_path_1.dirname)(to));
|
|
37
|
+
await promises_1.default.rename(from, to);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.FileSystem = FileSystem;
|
|
41
|
+
//# sourceMappingURL=FileSystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileSystem.js","sourceRoot":"","sources":["../../source/providers/FileSystem.ts"],"names":[],"mappings":";;;;;;AACA,yCAAyC;AACzC,qCAA0C;AAC1C,gEAAiC;AACjC,wDAA0B;AAG1B,MAAa,UAAU;IACF,IAAI,CAAQ;IAE/B,YAAoB,GAAQ;QAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE;YACjB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;QAE1D,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAA;IAC1B,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,IAAY;QAC5B,IAAI,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAE5B,IAAI,CAAC,MAAM,kBAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACzB,OAAO,IAAI,CAAA;QAEb,OAAO,IAAA,0BAAgB,EAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,GAAW,EAAE,QAAgB,EAAE,MAAgB;QAC/D,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;QAEhC,MAAM,kBAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACxB,MAAM,kBAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;IAClC,CAAC;IAEM,KAAK,CAAC,MAAM,CAAE,IAAY;QAC/B,MAAM,kBAAG,CAAC,MAAM,CAAC,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;IACzC,CAAC;IAEM,KAAK,CAAC,IAAI,CAAE,IAAY,EAAE,EAAU;QACzC,IAAI,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC5B,EAAE,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAExB,MAAM,kBAAG,CAAC,SAAS,CAAC,IAAA,mBAAO,EAAC,EAAE,CAAC,CAAC,CAAA;QAChC,MAAM,kBAAE,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IAC3B,CAAC;CACF;AAtCD,gCAsCC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type Readable } from 'node:stream';
|
|
3
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
|
4
|
+
import { type Provider } from '../Provider';
|
|
5
|
+
export declare class S3 implements Provider {
|
|
6
|
+
protected readonly bucket: string;
|
|
7
|
+
protected readonly client: S3Client;
|
|
8
|
+
constructor(url: URL, secrets: Record<string, string>);
|
|
9
|
+
get(key: string): Promise<Readable | null>;
|
|
10
|
+
put(path: string, filename: string, stream: Readable): Promise<void>;
|
|
11
|
+
delete(key: string): Promise<void>;
|
|
12
|
+
move(from: string, keyTo: string): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.S3 = void 0;
|
|
4
|
+
const posix_1 = require("node:path/posix");
|
|
5
|
+
const lib_storage_1 = require("@aws-sdk/lib-storage");
|
|
6
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
7
|
+
class S3 {
|
|
8
|
+
bucket;
|
|
9
|
+
client;
|
|
10
|
+
constructor(url, secrets) {
|
|
11
|
+
this.bucket = url.pathname.split('/')[1];
|
|
12
|
+
if (this.bucket === undefined || this.bucket === '')
|
|
13
|
+
throw new Error('S3 bucket not specified');
|
|
14
|
+
const s3Config = {
|
|
15
|
+
credentials: {
|
|
16
|
+
accessKeyId: secrets.ACCESS_KEY_ID,
|
|
17
|
+
secretAccessKey: secrets.SECRET_ACCESS_KEY
|
|
18
|
+
},
|
|
19
|
+
region: url.host,
|
|
20
|
+
endpoint: url.searchParams.get('endpoint') ?? undefined
|
|
21
|
+
};
|
|
22
|
+
this.client = new client_s3_1.S3Client(s3Config);
|
|
23
|
+
}
|
|
24
|
+
async get(key) {
|
|
25
|
+
try {
|
|
26
|
+
const fileResponse = await this.client.send(new client_s3_1.GetObjectCommand({
|
|
27
|
+
Bucket: this.bucket,
|
|
28
|
+
Key: key
|
|
29
|
+
}));
|
|
30
|
+
return fileResponse.Body;
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
if (err?.Code === 'NoSuchKey')
|
|
34
|
+
return null;
|
|
35
|
+
else
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async put(path, filename, stream) {
|
|
40
|
+
const key = (0, posix_1.join)(path, filename);
|
|
41
|
+
await new lib_storage_1.Upload({
|
|
42
|
+
client: this.client,
|
|
43
|
+
params: {
|
|
44
|
+
Bucket: this.bucket,
|
|
45
|
+
Key: key,
|
|
46
|
+
Body: stream
|
|
47
|
+
}
|
|
48
|
+
}).done();
|
|
49
|
+
}
|
|
50
|
+
async delete(key) {
|
|
51
|
+
const listResponse = await this.client.send(new client_s3_1.ListObjectsV2Command({
|
|
52
|
+
Bucket: this.bucket,
|
|
53
|
+
Prefix: key.substring(1)
|
|
54
|
+
}));
|
|
55
|
+
if (listResponse.Contents !== undefined && listResponse.Contents.length > 0)
|
|
56
|
+
await this.client.send(new client_s3_1.DeleteObjectsCommand({
|
|
57
|
+
Bucket: this.bucket,
|
|
58
|
+
Delete: {
|
|
59
|
+
Objects: listResponse.Contents.map(({ Key }) => ({ Key }))
|
|
60
|
+
}
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
async move(from, keyTo) {
|
|
64
|
+
const keyFrom = (0, posix_1.join)(this.bucket, from);
|
|
65
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
66
|
+
await this.client.send(new client_s3_1.CopyObjectCommand({
|
|
67
|
+
Bucket: this.bucket,
|
|
68
|
+
Key: keyTo,
|
|
69
|
+
CopySource: keyFrom
|
|
70
|
+
}));
|
|
71
|
+
await this.delete(from);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.S3 = S3;
|
|
75
|
+
//# sourceMappingURL=S3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"S3.js","sourceRoot":"","sources":["../../source/providers/S3.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Temporary = void 0;
|
|
4
|
+
const node_os_1 = require("node:os");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const FileSystem_1 = require("./FileSystem");
|
|
7
|
+
class Temporary extends FileSystem_1.FileSystem {
|
|
8
|
+
path;
|
|
9
|
+
constructor(url) {
|
|
10
|
+
super(url);
|
|
11
|
+
this.path = (0, node_path_1.join)((0, node_os_1.tmpdir)(), url.pathname);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.Temporary = Temporary;
|
|
15
|
+
//# sourceMappingURL=Temporary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Temporary.js","sourceRoot":"","sources":["../../source/providers/Temporary.ts"],"names":[],"mappings":";;;AAAA,qCAAgC;AAChC,yCAAgC;AAEhC,6CAAyC;AAEzC,MAAa,SAAU,SAAQ,uBAAU;IACX,IAAI,CAAQ;IAExC,YAAoB,GAAQ;QAC1B,KAAK,CAAC,GAAG,CAAC,CAAA;QAEV,IAAI,CAAC,IAAI,GAAG,IAAA,gBAAI,EAAC,IAAA,gBAAM,GAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC1C,CAAC;CACF;AARD,8BAQC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Test = void 0;
|
|
7
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
+
const Temporary_1 = require("./Temporary");
|
|
9
|
+
class Test extends Temporary_1.Temporary {
|
|
10
|
+
static SECRETS = ['USERNAME', 'PASSWORD'];
|
|
11
|
+
constructor(url, secrets) {
|
|
12
|
+
super(url);
|
|
13
|
+
(0, node_assert_1.default)(secrets.USERNAME !== undefined, 'Missing USERNAME');
|
|
14
|
+
(0, node_assert_1.default)(secrets.PASSWORD !== undefined, 'Missing PASSWORD');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.Test = Test;
|
|
18
|
+
//# sourceMappingURL=Test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Test.js","sourceRoot":"","sources":["../../source/providers/Test.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAgC;AAChC,2CAAuC;AAEvC,MAAa,IAAK,SAAQ,qBAAS;IAC1B,MAAM,CAAU,OAAO,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IAEzD,YAAoB,GAAQ,EAAE,OAA+B;QAC3D,KAAK,CAAC,GAAG,CAAC,CAAA;QAEV,IAAA,qBAAM,EAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,kBAAkB,CAAC,CAAA;QAC1D,IAAA,qBAAM,EAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,kBAAkB,CAAC,CAAA;IAC5D,CAAC;;AARH,oBASC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.providers = void 0;
|
|
4
|
+
const FileSystem_1 = require("./FileSystem");
|
|
5
|
+
const S3_1 = require("./S3");
|
|
6
|
+
const Temporary_1 = require("./Temporary");
|
|
7
|
+
const Test_1 = require("./Test");
|
|
8
|
+
exports.providers = {
|
|
9
|
+
'file:': FileSystem_1.FileSystem,
|
|
10
|
+
'tmp:': Temporary_1.Temporary,
|
|
11
|
+
'test:': Test_1.Test,
|
|
12
|
+
's3:': S3_1.S3
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/providers/index.ts"],"names":[],"mappings":";;;AACA,6CAAyC;AACzC,6BAAyB;AACzB,2CAAuC;AACvC,iCAA6B;AAEhB,QAAA,SAAS,GAAkC;IACtD,OAAO,EAAE,uBAAU;IACnB,MAAM,EAAE,qBAAS;IACjB,OAAO,EAAE,WAAI;IACb,KAAK,EAAE,OAAE;CACV,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { type ReadStream } from 'node:fs';
|
|
4
|
+
export declare const cases: Case[];
|
|
5
|
+
export declare function rnd(): string;
|
|
6
|
+
export declare function open(rel: string): ReadStream;
|
|
7
|
+
export declare function read(rel: string): Promise<Buffer>;
|
|
8
|
+
type SuiteInit = (url: URL, secrets: Record<string, string>) => Promise<void> | void;
|
|
9
|
+
type Case = [string, URL, Record<string, string>, SuiteInit?];
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.read = exports.open = exports.rnd = exports.cases = void 0;
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
10
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
11
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
12
|
+
dotenv_1.default.config({ path: (0, node_path_1.join)(__dirname, '.env') });
|
|
13
|
+
const suites = [
|
|
14
|
+
{
|
|
15
|
+
run: true,
|
|
16
|
+
ref: 'tmp:///toa-storages-temp'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
run: process.env.RUN_S3 === '1',
|
|
20
|
+
ref: 's3://us-west-1/test-bucket?endpoint=http://s3.localhost.localstack.cloud:4566',
|
|
21
|
+
secrets: {
|
|
22
|
+
ACCESS_KEY_ID: 'developer',
|
|
23
|
+
SECRET_ACCESS_KEY: 'secret'
|
|
24
|
+
},
|
|
25
|
+
init: initS3
|
|
26
|
+
}
|
|
27
|
+
// add more providers here, use `run` as a condition to run the test
|
|
28
|
+
// e.g.: `run: process.env.ACCESS_KEY_ID !== undefined`
|
|
29
|
+
];
|
|
30
|
+
function map(suite) {
|
|
31
|
+
const url = new URL(suite.ref);
|
|
32
|
+
return [url.protocol, url, suite.secrets ?? {}, suite.init];
|
|
33
|
+
}
|
|
34
|
+
exports.cases = suites.filter(({ run }) => run).map(map);
|
|
35
|
+
function rnd() {
|
|
36
|
+
return Math.random().toString(36).slice(2);
|
|
37
|
+
}
|
|
38
|
+
exports.rnd = rnd;
|
|
39
|
+
function open(rel) {
|
|
40
|
+
const path = (0, node_path_1.join)(__dirname, rel);
|
|
41
|
+
return (0, node_fs_1.createReadStream)(path);
|
|
42
|
+
}
|
|
43
|
+
exports.open = open;
|
|
44
|
+
async function read(rel) {
|
|
45
|
+
const path = (0, node_path_1.join)(__dirname, rel);
|
|
46
|
+
return await promises_1.default.readFile(path);
|
|
47
|
+
}
|
|
48
|
+
exports.read = read;
|
|
49
|
+
async function initS3(url, secrets) {
|
|
50
|
+
const client = new client_s3_1.S3Client({
|
|
51
|
+
credentials: {
|
|
52
|
+
accessKeyId: secrets.ACCESS_KEY_ID,
|
|
53
|
+
secretAccessKey: secrets.SECRET_ACCESS_KEY
|
|
54
|
+
},
|
|
55
|
+
region: url.host,
|
|
56
|
+
endpoint: url.searchParams.get('endpoint') ?? undefined
|
|
57
|
+
});
|
|
58
|
+
const command = new client_s3_1.CreateBucketCommand({ Bucket: url.pathname.substring(1) });
|
|
59
|
+
await client.send(command).catch(() => undefined);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../source/test/util.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAgC;AAChC,gEAAiC;AACjC,qCAA2D;AAC3D,kDAAkE;AAClE,oDAA2B;AAE3B,gBAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAA,gBAAI,EAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,CAAA;AAEhD,MAAM,MAAM,GAAY;IACtB;QACE,GAAG,EAAE,IAAI;QACT,GAAG,EAAE,0BAA0B;KAChC;IACD;QACE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG;QAC/B,GAAG,EAAE,+EAA+E;QACpF,OAAO,EAAE;YACP,aAAa,EAAE,WAAW;YAC1B,iBAAiB,EAAE,QAAQ;SAC5B;QACD,IAAI,EAAE,MAAM;KACb;IACD,oEAAoE;IACpE,uDAAuD;CACxD,CAAA;AAED,SAAS,GAAG,CAAE,KAAY;IACxB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAE9B,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;AAC7D,CAAC;AAEY,QAAA,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;AAE7D,SAAgB,GAAG;IACjB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAC5C,CAAC;AAFD,kBAEC;AAED,SAAgB,IAAI,CAAE,GAAW;IAC/B,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,GAAG,CAAC,CAAA;IAEjC,OAAO,IAAA,0BAAgB,EAAC,IAAI,CAAC,CAAA;AAC/B,CAAC;AAJD,oBAIC;AAEM,KAAK,UAAU,IAAI,CAAE,GAAW;IACrC,MAAM,IAAI,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,GAAG,CAAC,CAAA;IAEjC,OAAO,MAAM,kBAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;AAChC,CAAC;AAJD,oBAIC;AAED,KAAK,UAAU,MAAM,CAAE,GAAQ,EAAE,OAA+B;IAC9D,MAAM,MAAM,GAAG,IAAI,oBAAQ,CAAC;QAC1B,WAAW,EAAE;YACX,WAAW,EAAE,OAAO,CAAC,aAAa;YAClC,eAAe,EAAE,OAAO,CAAC,iBAAiB;SAC3C;QACD,MAAM,EAAE,GAAG,CAAC,IAAI;QAChB,QAAQ,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,SAAS;KACxD,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,IAAI,+BAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAE9E,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;AACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"4.9.5"}
|