@toa.io/extensions.storages 1.0.0-alpha.0 → 1.0.0-alpha.2
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 +12 -11
- package/readme.md +63 -19
- package/schemas/annotation.cos.yaml +10 -0
- package/schemas/fs.cos.yaml +9 -0
- package/schemas/mem.cos.yaml +6 -0
- package/schemas/s3.cos.yaml +16 -0
- package/schemas/test.cos.yaml +8 -0
- package/schemas/tmp.cos.yaml +9 -0
- package/source/Annotation.ts +39 -0
- package/source/Aspect.ts +6 -4
- package/source/Factory.ts +31 -28
- package/source/Provider.ts +30 -5
- package/source/Scanner.ts +3 -3
- package/source/Storage.test.ts +110 -105
- package/source/Storage.ts +13 -6
- package/source/deployment.ts +21 -29
- package/source/providers/Declaration.ts +10 -0
- package/source/providers/FileSystem.test.ts +1 -9
- package/source/providers/FileSystem.ts +20 -15
- package/source/providers/Memory.ts +41 -0
- package/source/providers/S3.test.ts +133 -0
- package/source/providers/S3.ts +114 -39
- package/source/providers/Temporary.ts +8 -6
- package/source/providers/Test.ts +8 -8
- package/source/providers/index.test.ts +24 -19
- package/source/providers/index.ts +10 -9
- package/source/providers/readme.md +1 -1
- package/source/schemas.test.ts +58 -0
- package/source/schemas.ts +15 -0
- package/source/test/util.ts +25 -54
- package/transpiled/Annotation.d.ts +3 -0
- package/transpiled/Annotation.js +57 -0
- package/transpiled/Annotation.js.map +1 -0
- package/transpiled/Aspect.d.ts +8 -0
- package/transpiled/Aspect.js +25 -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 +9 -0
- package/transpiled/Factory.js +53 -0
- package/transpiled/Factory.js.map +1 -0
- package/transpiled/Provider.d.ts +20 -0
- package/transpiled/Provider.js +36 -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 +32 -0
- package/transpiled/Storage.js +176 -0
- package/transpiled/Storage.js.map +1 -0
- package/transpiled/deployment.d.ts +5 -0
- package/transpiled/deployment.js +68 -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/Declaration.d.ts +14 -0
- package/transpiled/providers/Declaration.js +3 -0
- package/transpiled/providers/Declaration.js.map +1 -0
- package/transpiled/providers/FileSystem.d.ts +15 -0
- package/transpiled/providers/FileSystem.js +44 -0
- package/transpiled/providers/FileSystem.js.map +1 -0
- package/transpiled/providers/Memory.d.ts +13 -0
- package/transpiled/providers/Memory.js +60 -0
- package/transpiled/providers/Memory.js.map +1 -0
- package/transpiled/providers/S3.d.ts +27 -0
- package/transpiled/providers/S3.js +154 -0
- package/transpiled/providers/S3.js.map +1 -0
- package/transpiled/providers/Temporary.d.ts +8 -0
- package/transpiled/providers/Temporary.js +14 -0
- package/transpiled/providers/Temporary.js.map +1 -0
- package/transpiled/providers/Test.d.ts +6 -0
- package/transpiled/providers/Test.js +15 -0
- package/transpiled/providers/Test.js.map +1 -0
- package/transpiled/providers/index.d.ts +13 -0
- package/transpiled/providers/index.js +16 -0
- package/transpiled/providers/index.js.map +1 -0
- package/transpiled/schemas.d.ts +9 -0
- package/transpiled/schemas.js +14 -0
- package/transpiled/schemas.js.map +1 -0
- package/transpiled/test/util.d.ts +29 -0
- package/transpiled/test/util.js +38 -0
- package/transpiled/test/util.js.map +1 -0
- package/transpiled/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as schemas from './schemas'
|
|
2
|
+
|
|
3
|
+
const ok = {
|
|
4
|
+
a: {
|
|
5
|
+
provider: 'tmp',
|
|
6
|
+
directory: 'ok'
|
|
7
|
+
},
|
|
8
|
+
b: {
|
|
9
|
+
provider: 'fs',
|
|
10
|
+
path: 'ok'
|
|
11
|
+
},
|
|
12
|
+
c: {
|
|
13
|
+
provider: 's3',
|
|
14
|
+
bucket: 'my-bucket'
|
|
15
|
+
},
|
|
16
|
+
d: {
|
|
17
|
+
provider: 'mem'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const oh = [
|
|
22
|
+
{
|
|
23
|
+
whatever: {
|
|
24
|
+
provider: 'non-existent'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
whatever: {
|
|
29
|
+
provider: 'fs'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
whatever: {
|
|
34
|
+
provider: 'tmp',
|
|
35
|
+
extra: true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
whatever: {
|
|
40
|
+
|
|
41
|
+
provider: 's3'
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
whatever: {
|
|
46
|
+
provider: 'mem',
|
|
47
|
+
extra: true
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
it('should pass', () => {
|
|
53
|
+
expect(() => schemas.annotation.validate(ok)).not.toThrow()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it.each(oh)('should fail', (value) => {
|
|
57
|
+
expect(() => schemas.annotation.validate(value)).toThrow()
|
|
58
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { resolve } from 'node:path'
|
|
2
|
+
import { namespace } from '@toa.io/schemas'
|
|
3
|
+
import type { Declaration } from './providers'
|
|
4
|
+
import type { Schema } from '@toa.io/schemas'
|
|
5
|
+
import type { Annotation } from './Annotation'
|
|
6
|
+
|
|
7
|
+
const path = resolve(__dirname, '../schemas')
|
|
8
|
+
const ns = namespace(path)
|
|
9
|
+
|
|
10
|
+
export const annotation: Schema<Annotation> = ns.schema<Annotation>('annotation')
|
|
11
|
+
export const s3: Schema<Declaration> = ns.schema<Declaration>('s3')
|
|
12
|
+
export const fs: Schema<Declaration> = ns.schema<Declaration>('fs')
|
|
13
|
+
export const mem: Schema<Declaration> = ns.schema<Declaration>('mem')
|
|
14
|
+
export const tmp: Schema<Declaration> = ns.schema<Declaration>('tmp')
|
|
15
|
+
export const test: Schema<Declaration> = ns.schema<Declaration>('test')
|
package/source/test/util.ts
CHANGED
|
@@ -1,74 +1,45 @@
|
|
|
1
1
|
import { join } from 'node:path'
|
|
2
|
-
import fs from 'node:fs/promises'
|
|
3
|
-
import { createReadStream, type ReadStream } from 'node:fs'
|
|
4
|
-
import { CreateBucketCommand, S3Client } from '@aws-sdk/client-s3'
|
|
5
2
|
import dotenv from 'dotenv'
|
|
3
|
+
import type { ProviderSecrets } from '../Provider'
|
|
4
|
+
import type { providers } from '../providers'
|
|
5
|
+
import type { FileSystemOptions } from '../providers/FileSystem'
|
|
6
|
+
import type { S3Options } from '../providers/S3'
|
|
7
|
+
import type { TemporaryOptions } from '../providers/Temporary'
|
|
6
8
|
|
|
7
9
|
dotenv.config({ path: join(__dirname, '.env') })
|
|
8
10
|
|
|
9
|
-
const suites
|
|
11
|
+
export const suites = [
|
|
10
12
|
{
|
|
11
13
|
run: true,
|
|
12
|
-
|
|
14
|
+
provider: 'tmp',
|
|
15
|
+
options: {
|
|
16
|
+
directory: 'toa-storages-temp'
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
run: true,
|
|
21
|
+
provider: 'mem'
|
|
13
22
|
},
|
|
14
23
|
{
|
|
15
24
|
run: process.env.RUN_S3 === '1',
|
|
16
|
-
|
|
25
|
+
provider: 's3',
|
|
26
|
+
options: {
|
|
27
|
+
endpoint: 'http://localhost:4566',
|
|
28
|
+
region: 'us-west-1',
|
|
29
|
+
bucket: 'test-bucket'
|
|
30
|
+
},
|
|
17
31
|
secrets: {
|
|
18
32
|
ACCESS_KEY_ID: 'developer',
|
|
19
33
|
SECRET_ACCESS_KEY: 'secret'
|
|
20
|
-
}
|
|
21
|
-
init: initS3
|
|
34
|
+
}
|
|
22
35
|
}
|
|
23
36
|
// add more providers here, use `run` as a condition to run the test
|
|
24
37
|
// e.g.: `run: process.env.ACCESS_KEY_ID !== undefined`
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
function map (suite: Suite): Case {
|
|
28
|
-
const url = new URL(suite.ref)
|
|
29
|
-
|
|
30
|
-
return [url.protocol, url, suite.secrets ?? {}, suite.init]
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const cases = suites.filter(({ run }) => run).map(map)
|
|
34
|
-
|
|
35
|
-
export function rnd (): string {
|
|
36
|
-
return Math.random().toString(36).slice(2)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function open (rel: string): ReadStream {
|
|
40
|
-
const path = join(__dirname, rel)
|
|
41
|
-
|
|
42
|
-
return createReadStream(path)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function read (rel: string): Promise<Buffer> {
|
|
46
|
-
const path = join(__dirname, rel)
|
|
47
|
-
|
|
48
|
-
return await fs.readFile(path)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function initS3 (url: URL, secrets: Record<string, string>): Promise<void> {
|
|
52
|
-
const client = new S3Client({
|
|
53
|
-
credentials: {
|
|
54
|
-
accessKeyId: secrets.ACCESS_KEY_ID,
|
|
55
|
-
secretAccessKey: secrets.SECRET_ACCESS_KEY
|
|
56
|
-
},
|
|
57
|
-
region: url.host,
|
|
58
|
-
endpoint: url.searchParams.get('endpoint') ?? undefined
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
const command = new CreateBucketCommand({ Bucket: url.pathname.substring(1) })
|
|
62
|
-
|
|
63
|
-
await client.send(command).catch(() => undefined)
|
|
64
|
-
}
|
|
38
|
+
] satisfies Suite[]
|
|
65
39
|
|
|
66
40
|
interface Suite {
|
|
67
41
|
run: boolean
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
42
|
+
provider: keyof typeof providers
|
|
43
|
+
options?: FileSystemOptions | S3Options | TemporaryOptions
|
|
44
|
+
secrets?: ProviderSecrets
|
|
71
45
|
}
|
|
72
|
-
|
|
73
|
-
type SuiteInit = (url: URL, secrets: Record<string, string>) => Promise<void> | void
|
|
74
|
-
type Case = [string, URL, Record<string, string>, SuiteInit?]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.validateAnnotation = void 0;
|
|
30
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
31
|
+
const providers_1 = require("./providers");
|
|
32
|
+
const schemas = __importStar(require("./schemas"));
|
|
33
|
+
function validateAnnotation(annotation) {
|
|
34
|
+
try {
|
|
35
|
+
schemas.annotation.validate(annotation);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
explain(annotation);
|
|
39
|
+
// if all declarations are valid, re-throw the error
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.validateAnnotation = validateAnnotation;
|
|
44
|
+
/*
|
|
45
|
+
It is required because `oneOf` schema is used for the annotation validation.
|
|
46
|
+
*/
|
|
47
|
+
function explain(annotation) {
|
|
48
|
+
node_assert_1.default.ok(typeof annotation === 'object' && annotation !== null, 'TOA_STORAGES is not an object');
|
|
49
|
+
for (const declaration of Object.values(annotation)) {
|
|
50
|
+
node_assert_1.default.ok(typeof declaration === 'object' && declaration !== null &&
|
|
51
|
+
declaration.provider in providers_1.providers, `Unknown provider '${declaration.provider}'`);
|
|
52
|
+
node_assert_1.default.ok(declaration.provider in schemas, `No schema for provider '${declaration.provider}'`);
|
|
53
|
+
const schema = schemas[declaration.provider];
|
|
54
|
+
schema.validate(declaration, `Storage '${declaration.provider}' annotation`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=Annotation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Annotation.js","sourceRoot":"","sources":["../source/Annotation.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8DAAgC;AAChC,2CAAuC;AACvC,mDAAoC;AAMpC,SAAgB,kBAAkB,CAAE,UAAmB;IACrD,IAAI,CAAC;QACH,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,UAAU,CAAC,CAAA;QAEnB,oDAAoD;QACpD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AATD,gDASC;AAED;;GAEG;AACH,SAAS,OAAO,CAAE,UAAmB;IACnC,qBAAM,CAAC,EAAE,CAAC,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAC7D,+BAA+B,CAAC,CAAA;IAElC,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACpD,qBAAM,CAAC,EAAE,CAAC,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI;YAC/D,WAAW,CAAC,QAAQ,IAAI,qBAAS,EACjC,qBAAqB,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAA;QAE/C,qBAAM,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,IAAI,OAAO,EACvC,2BAA2B,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAA;QAErD,MAAM,MAAM,GAAwB,OAAO,CAAC,WAAW,CAAC,QAAkC,CAAC,CAAA;QAE3F,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,YAAY,WAAW,CAAC,QAAQ,cAAc,CAAC,CAAA;IAC9E,CAAC;AACH,CAAC"}
|
|
@@ -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: unknown[]): unknown;
|
|
8
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
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.Aspect = void 0;
|
|
7
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
+
const core_1 = require("@toa.io/core");
|
|
9
|
+
class Aspect extends core_1.Connector {
|
|
10
|
+
name = 'storages';
|
|
11
|
+
storages;
|
|
12
|
+
constructor(storages) {
|
|
13
|
+
super();
|
|
14
|
+
this.storages = storages;
|
|
15
|
+
}
|
|
16
|
+
invoke(name, method, ...args) {
|
|
17
|
+
const storage = this.storages[name];
|
|
18
|
+
node_assert_1.default.ok(storage !== undefined, `Storage '${name}' is not defined`);
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
20
|
+
// @ts-expect-error
|
|
21
|
+
return storage[method](...args);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.Aspect = Aspect;
|
|
25
|
+
//# sourceMappingURL=Aspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aspect.js","sourceRoot":"","sources":["../source/Aspect.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAgC;AAChC,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,IAAe;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAEnC,qBAAM,CAAC,EAAE,CAAC,OAAO,KAAK,SAAS,EAAE,YAAY,IAAI,kBAAkB,CAAC,CAAA;QAEpE,6DAA6D;QAC7D,mBAAmB;QACnB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IACjC,CAAC;CACF;AApBD,wBAoBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Entry.js","sourceRoot":"","sources":["../source/Entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
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.Factory = void 0;
|
|
7
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
+
const generic_1 = require("@toa.io/generic");
|
|
9
|
+
const providers_1 = require("./providers");
|
|
10
|
+
const Storage_1 = require("./Storage");
|
|
11
|
+
const Aspect_1 = require("./Aspect");
|
|
12
|
+
const deployment_1 = require("./deployment");
|
|
13
|
+
const Annotation_1 = require("./Annotation");
|
|
14
|
+
class Factory {
|
|
15
|
+
annotation;
|
|
16
|
+
constructor() {
|
|
17
|
+
const env = process.env.TOA_STORAGES;
|
|
18
|
+
node_assert_1.default.ok(env !== undefined, 'TOA_STORAGES is not defined');
|
|
19
|
+
this.annotation = (0, generic_1.decode)(env);
|
|
20
|
+
(0, Annotation_1.validateAnnotation)(this.annotation);
|
|
21
|
+
}
|
|
22
|
+
aspect() {
|
|
23
|
+
const storages = this.createStorages();
|
|
24
|
+
return new Aspect_1.Aspect(storages);
|
|
25
|
+
}
|
|
26
|
+
createStorages() {
|
|
27
|
+
const storages = {};
|
|
28
|
+
for (const [name, declaration] of Object.entries(this.annotation))
|
|
29
|
+
storages[name] = this.createStorage(name, declaration);
|
|
30
|
+
return storages;
|
|
31
|
+
}
|
|
32
|
+
createStorage(name, declaration) {
|
|
33
|
+
const { provider: providerId, ...options } = declaration;
|
|
34
|
+
const Provider = providers_1.providers[providerId];
|
|
35
|
+
const secrets = this.resolveSecrets(name, Provider);
|
|
36
|
+
const provider = new Provider(options, secrets);
|
|
37
|
+
return new Storage_1.Storage(provider);
|
|
38
|
+
}
|
|
39
|
+
resolveSecrets(storageName, Class) {
|
|
40
|
+
if (Class.SECRETS === undefined)
|
|
41
|
+
return {};
|
|
42
|
+
const secrets = {};
|
|
43
|
+
for (const secret of Class.SECRETS) {
|
|
44
|
+
const variable = `${deployment_1.SERIALIZATION_PREFIX}_${storageName}_${secret.name}`.toUpperCase();
|
|
45
|
+
const value = process.env[variable];
|
|
46
|
+
node_assert_1.default.ok(secret.optional === true || value !== undefined, `'${variable}' is not defined`);
|
|
47
|
+
secrets[secret.name] = value;
|
|
48
|
+
}
|
|
49
|
+
return secrets;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.Factory = Factory;
|
|
53
|
+
//# sourceMappingURL=Factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Factory.js","sourceRoot":"","sources":["../source/Factory.ts"],"names":[],"mappings":";;;;;;AAAA,8DAAgC;AAChC,6CAAwC;AACxC,2CAAuC;AACvC,uCAAkD;AAClD,qCAAiC;AACjC,6CAAmD;AACnD,6CAAiD;AAKjD,MAAa,OAAO;IACD,UAAU,CAAY;IAEvC;QACE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAA;QAEpC,qBAAM,CAAC,EAAE,CAAC,GAAG,KAAK,SAAS,EAAE,6BAA6B,CAAC,CAAA;QAE3D,IAAI,CAAC,UAAU,GAAG,IAAA,gBAAM,EAAC,GAAG,CAAC,CAAA;QAE7B,IAAA,+BAAkB,EAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACrC,CAAC;IAEM,MAAM;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;QAEtC,OAAO,IAAI,eAAM,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;IAEO,cAAc;QACpB,MAAM,QAAQ,GAAa,EAAE,CAAA;QAE7B,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;YAC/D,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QAExD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEO,aAAa,CAAE,IAAY,EAAE,WAAwB;QAC3D,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,OAAO,EAAE,GAAG,WAAW,CAAA;QACxD,MAAM,QAAQ,GAAwB,qBAAS,CAAC,UAAU,CAAC,CAAA;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACnD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAE/C,OAAO,IAAI,iBAAO,CAAC,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAEO,cAAc,CAAE,WAAmB,EACzC,KAA0B;QAC1B,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;YAC7B,OAAO,EAAE,CAAA;QAEX,MAAM,OAAO,GAAuC,EAAE,CAAA;QAEtD,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,GAAG,iCAAoB,IAAI,WAAW,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;YACtF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAEnC,qBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EACvD,IAAI,QAAQ,kBAAkB,CAAC,CAAA;YAEjC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;QAC9B,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;CACF;AAxDD,0BAwDC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type Readable } from 'node:stream';
|
|
3
|
+
export type ProviderSecrets<K extends string = string> = Record<K | string, string | undefined>;
|
|
4
|
+
export interface ProviderSecret {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly optional?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare abstract class Provider<Options = void> {
|
|
9
|
+
static readonly SECRETS: readonly ProviderSecret[];
|
|
10
|
+
constructor(_: Options, secrets?: ProviderSecrets);
|
|
11
|
+
abstract get(path: string): Promise<Readable | null>;
|
|
12
|
+
abstract put(path: string, filename: string, stream: Readable): Promise<void>;
|
|
13
|
+
abstract delete(path: string): Promise<void>;
|
|
14
|
+
abstract move(from: string, to: string): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export interface ProviderConstructor {
|
|
17
|
+
readonly SECRETS: readonly ProviderSecret[];
|
|
18
|
+
prototype: Provider;
|
|
19
|
+
new (options: any, secrets?: ProviderSecrets): Provider;
|
|
20
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Provider = void 0;
|
|
27
|
+
const assert = __importStar(require("node:assert"));
|
|
28
|
+
class Provider {
|
|
29
|
+
static SECRETS = [];
|
|
30
|
+
constructor(_, secrets) {
|
|
31
|
+
for (const { name, optional = false } of new.target.SECRETS)
|
|
32
|
+
assert.ok(optional || secrets?.[name] !== undefined, `Missing secret '${name}'`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.Provider = Provider;
|
|
36
|
+
//# sourceMappingURL=Provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Provider.js","sourceRoot":"","sources":["../source/Provider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,oDAAqC;AASrC,MAAsB,QAAQ;IACrB,MAAM,CAAU,OAAO,GAA8B,EAAE,CAAA;IAE9D,YAAoB,CAAU,EAAE,OAAyB;QACvD,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO;YACzD,MAAM,CAAC,EAAE,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,mBAAmB,IAAI,GAAG,CAAC,CAAA;IACpF,CAAC;;AANH,4BAeC"}
|
|
@@ -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?: ScanOptions);
|
|
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 ScanOptions {
|
|
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 agent_1 = require("@toa.io/agent");
|
|
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, agent_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,32 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Readable } from 'node:stream';
|
|
3
|
+
import type { ScanOptions } 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, options?: Options): 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
|
+
type Meta = Record<string, string>;
|
|
28
|
+
interface Options extends ScanOptions {
|
|
29
|
+
meta?: Meta;
|
|
30
|
+
}
|
|
31
|
+
export type Storages = Record<string, Storage>;
|
|
32
|
+
export {};
|