@milaboratories/pl-drivers 1.2.34 → 1.3.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/dist/clients/download.d.ts +5 -2
- package/dist/clients/download.d.ts.map +1 -1
- package/dist/clients/helpers.d.ts +2 -2
- package/dist/clients/helpers.d.ts.map +1 -1
- package/dist/drivers/helpers/ls_list_entry.d.ts +8 -13
- package/dist/drivers/helpers/ls_list_entry.d.ts.map +1 -1
- package/dist/drivers/helpers/ls_storage_entry.d.ts +6 -8
- package/dist/drivers/helpers/ls_storage_entry.d.ts.map +1 -1
- package/dist/drivers/ls.d.ts +40 -12
- package/dist/drivers/ls.d.ts.map +1 -1
- package/dist/drivers/types.d.ts +80 -0
- package/dist/drivers/types.d.ts.map +1 -0
- package/dist/drivers/upload.d.ts +18 -26
- package/dist/drivers/upload.d.ts.map +1 -1
- package/dist/helpers/validate.d.ts +2 -0
- package/dist/helpers/validate.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +943 -918
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/clients/download.test.ts +5 -14
- package/src/clients/download.ts +13 -5
- package/src/clients/helpers.ts +13 -43
- package/src/drivers/download_blob.test.ts +4 -4
- package/src/drivers/helpers/ls_list_entry.test.ts +5 -7
- package/src/drivers/helpers/ls_list_entry.ts +31 -36
- package/src/drivers/helpers/ls_storage_entry.ts +18 -62
- package/src/drivers/logs.test.ts +3 -3
- package/src/drivers/ls.test.ts +112 -30
- package/src/drivers/ls.ts +233 -83
- package/src/drivers/types.ts +41 -0
- package/src/drivers/upload.test.ts +43 -82
- package/src/drivers/upload.ts +59 -111
- package/src/helpers/validate.ts +6 -0
- package/src/index.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-drivers",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Drivers and a low-level clients for log streaming, downloading and uploading files from and to pl",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"undici": "^6.19.8",
|
|
28
28
|
"zod": "^3.23.8",
|
|
29
29
|
"@milaboratories/ts-helpers": "^1.1.0",
|
|
30
|
-
"@milaboratories/
|
|
31
|
-
"@milaboratories/pl-
|
|
32
|
-
"@milaboratories/
|
|
33
|
-
"@milaboratories/pl-tree": "^1.4.
|
|
30
|
+
"@milaboratories/pl-client": "^2.5.3",
|
|
31
|
+
"@milaboratories/pl-model-common": "^1.4.0",
|
|
32
|
+
"@milaboratories/computable": "^2.2.0",
|
|
33
|
+
"@milaboratories/pl-tree": "^1.4.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"typescript": "~5.5.4",
|
|
@@ -20,22 +20,13 @@ test('client download from a local file', async () => {
|
|
|
20
20
|
|
|
21
21
|
const clientDownload = client.getDriver({
|
|
22
22
|
name: 'ClientDownload',
|
|
23
|
-
init: (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
) =>
|
|
28
|
-
new ClientDownload(
|
|
29
|
-
grpcTransport,
|
|
30
|
-
httpDispatcher,
|
|
31
|
-
new ConsoleLoggerAdapter(),
|
|
32
|
-
{ tmp: storageRoot }
|
|
33
|
-
)
|
|
23
|
+
init: (pl: PlClient, grpcTransport: GrpcTransport, httpDispatcher: Dispatcher) =>
|
|
24
|
+
new ClientDownload(grpcTransport, httpDispatcher, new ConsoleLoggerAdapter(), [
|
|
25
|
+
{ storageId: 'tmp', localPath: storageRoot }
|
|
26
|
+
])
|
|
34
27
|
});
|
|
35
28
|
|
|
36
|
-
const localFile = await clientDownload.readLocalFile(
|
|
37
|
-
`storage://tmp/${fName}`
|
|
38
|
-
);
|
|
29
|
+
const localFile = await clientDownload.readLocalFile(`storage://tmp/${fName}`);
|
|
39
30
|
|
|
40
31
|
expect(localFile.size).toBe(2);
|
|
41
32
|
expect(await text(localFile.content)).toBe('42');
|
package/src/clients/download.ts
CHANGED
|
@@ -14,11 +14,14 @@ import {
|
|
|
14
14
|
} from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol';
|
|
15
15
|
import { ResourceInfo } from '@milaboratories/pl-tree';
|
|
16
16
|
import { DownloadHelper, DownloadResponse } from '../helpers/download';
|
|
17
|
+
import { LocalStorageProjection } from '../drivers/types';
|
|
18
|
+
import { validateAbsolute } from '../helpers/validate';
|
|
17
19
|
|
|
18
20
|
const storageProtocol = 'storage://';
|
|
19
21
|
const localPathRegex = /storage:\/\/(?<storageId>.*?)\/(?<localPath>.*)/;
|
|
20
22
|
|
|
21
23
|
export class UnknownStorageError extends Error {}
|
|
24
|
+
|
|
22
25
|
export class WrongLocalFileUrl extends Error {}
|
|
23
26
|
|
|
24
27
|
/** Gets URLs for downloading from pl-core, parses them and reads or downloads
|
|
@@ -26,15 +29,21 @@ export class WrongLocalFileUrl extends Error {}
|
|
|
26
29
|
export class ClientDownload {
|
|
27
30
|
public readonly grpcClient: DownloadClient;
|
|
28
31
|
private readonly downloadHelper: DownloadHelper;
|
|
32
|
+
private readonly localStorageIdsToRoot: Map<string, string>;
|
|
29
33
|
|
|
30
34
|
constructor(
|
|
31
35
|
public readonly grpcTransport: GrpcTransport,
|
|
32
36
|
public readonly httpClient: Dispatcher,
|
|
33
37
|
public readonly logger: MiLogger,
|
|
34
|
-
|
|
38
|
+
/** Pl storages available locally */
|
|
39
|
+
localProjections: LocalStorageProjection[]
|
|
35
40
|
) {
|
|
41
|
+
for (const lp of localProjections) if (lp.localPath !== '') validateAbsolute(lp.localPath);
|
|
36
42
|
this.grpcClient = new DownloadClient(this.grpcTransport);
|
|
37
43
|
this.downloadHelper = new DownloadHelper(httpClient);
|
|
44
|
+
this.localStorageIdsToRoot = new Map(
|
|
45
|
+
localProjections.map((lp) => [lp.storageId, lp.localPath])
|
|
46
|
+
);
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
close() {}
|
|
@@ -83,12 +92,11 @@ export class ClientDownload {
|
|
|
83
92
|
|
|
84
93
|
const [_, storageId, localPath] = parsed;
|
|
85
94
|
|
|
86
|
-
|
|
95
|
+
const storageRoot = this.localStorageIdsToRoot.get(storageId);
|
|
96
|
+
if (storageRoot === undefined)
|
|
87
97
|
throw new UnknownStorageError(`Unknown storage location: ${storageId}`);
|
|
88
98
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
const fullPath = path.join(storageRoot, localPath);
|
|
99
|
+
const fullPath = storageRoot === '' ? localPath : path.join(storageRoot, localPath);
|
|
92
100
|
const stat = await fsp.stat(fullPath);
|
|
93
101
|
const size = stat.size;
|
|
94
102
|
|
package/src/clients/helpers.ts
CHANGED
|
@@ -7,78 +7,48 @@ import { ClientLogs } from './logs';
|
|
|
7
7
|
import { ClientProgress } from './progress';
|
|
8
8
|
import { ClientUpload } from './upload';
|
|
9
9
|
import { ClientLs } from './ls_api';
|
|
10
|
-
|
|
11
|
-
export const PL_STORAGE_TO_PATH = process.env.PL_STORAGE_TO_PATH
|
|
12
|
-
? Object.fromEntries(
|
|
13
|
-
process.env.PL_STORAGE_TO_PATH.split(';').map((kv) => kv.split(':'))
|
|
14
|
-
)
|
|
15
|
-
: {};
|
|
10
|
+
import { LocalStorageProjection } from '../drivers/types';
|
|
16
11
|
|
|
17
12
|
export function createDownloadClient(
|
|
18
13
|
logger: MiLogger,
|
|
19
14
|
client: PlClient,
|
|
20
|
-
|
|
15
|
+
localProjections: LocalStorageProjection[]
|
|
21
16
|
) {
|
|
22
|
-
|
|
23
|
-
localStorageIdsToRoot = PL_STORAGE_TO_PATH;
|
|
24
|
-
const clientDownload = client.getDriver({
|
|
17
|
+
return client.getDriver({
|
|
25
18
|
name: 'DownloadBlob',
|
|
26
|
-
init: (
|
|
27
|
-
|
|
28
|
-
grpcTransport: GrpcTransport,
|
|
29
|
-
httpDispatcher: Dispatcher
|
|
30
|
-
) =>
|
|
31
|
-
new ClientDownload(
|
|
32
|
-
grpcTransport,
|
|
33
|
-
httpDispatcher,
|
|
34
|
-
logger,
|
|
35
|
-
localStorageIdsToRoot!
|
|
36
|
-
)
|
|
19
|
+
init: (_: PlClient, grpcTransport: GrpcTransport, httpDispatcher: Dispatcher) =>
|
|
20
|
+
new ClientDownload(grpcTransport, httpDispatcher, logger, localProjections)
|
|
37
21
|
});
|
|
38
|
-
|
|
39
|
-
return clientDownload;
|
|
40
22
|
}
|
|
41
23
|
|
|
42
24
|
export function createLogsClient(client: PlClient, logger: MiLogger) {
|
|
43
25
|
return client.getDriver({
|
|
44
26
|
name: 'StreamLogs',
|
|
45
|
-
init: (
|
|
46
|
-
|
|
47
|
-
grpcTransport: GrpcTransport,
|
|
48
|
-
httpDispatcher: Dispatcher
|
|
49
|
-
) => new ClientLogs(grpcTransport, httpDispatcher, logger)
|
|
27
|
+
init: (_: PlClient, grpcTransport: GrpcTransport, httpDispatcher: Dispatcher) =>
|
|
28
|
+
new ClientLogs(grpcTransport, httpDispatcher, logger)
|
|
50
29
|
});
|
|
51
30
|
}
|
|
52
31
|
|
|
53
32
|
export function createUploadProgressClient(client: PlClient, logger: MiLogger) {
|
|
54
33
|
return client.getDriver({
|
|
55
34
|
name: 'UploadProgress',
|
|
56
|
-
init: (
|
|
57
|
-
|
|
58
|
-
grpcTransport: GrpcTransport,
|
|
59
|
-
httpDispatcher: Dispatcher
|
|
60
|
-
) => new ClientProgress(grpcTransport, httpDispatcher, client, logger)
|
|
35
|
+
init: (_: PlClient, grpcTransport: GrpcTransport, httpDispatcher: Dispatcher) =>
|
|
36
|
+
new ClientProgress(grpcTransport, httpDispatcher, client, logger)
|
|
61
37
|
});
|
|
62
38
|
}
|
|
63
39
|
|
|
64
40
|
export function createUploadBlobClient(client: PlClient, logger: MiLogger) {
|
|
65
41
|
return client.getDriver({
|
|
66
42
|
name: 'UploadBlob',
|
|
67
|
-
init: (
|
|
68
|
-
|
|
69
|
-
grpcTransport: GrpcTransport,
|
|
70
|
-
httpDispatcher: Dispatcher
|
|
71
|
-
) => new ClientUpload(grpcTransport, httpDispatcher, client, logger)
|
|
43
|
+
init: (_: PlClient, grpcTransport: GrpcTransport, httpDispatcher: Dispatcher) =>
|
|
44
|
+
new ClientUpload(grpcTransport, httpDispatcher, client, logger)
|
|
72
45
|
});
|
|
73
46
|
}
|
|
74
47
|
|
|
75
48
|
export function createLsFilesClient(client: PlClient, logger: MiLogger) {
|
|
76
49
|
return client.getDriver({
|
|
77
50
|
name: 'LsFiles',
|
|
78
|
-
init: (
|
|
79
|
-
|
|
80
|
-
grpcTransport: GrpcTransport,
|
|
81
|
-
_httpDispatcher: Dispatcher
|
|
82
|
-
) => new ClientLs(grpcTransport, logger)
|
|
51
|
+
init: (_client: PlClient, grpcTransport: GrpcTransport, _httpDispatcher: Dispatcher) =>
|
|
52
|
+
new ClientLs(grpcTransport, logger)
|
|
83
53
|
});
|
|
84
54
|
}
|
|
@@ -32,7 +32,7 @@ test.skip('should download a blob and read its content', async () => {
|
|
|
32
32
|
|
|
33
33
|
const driver = new DownloadDriver(
|
|
34
34
|
logger,
|
|
35
|
-
createDownloadClient(logger, client),
|
|
35
|
+
createDownloadClient(logger, client, []),
|
|
36
36
|
createLogsClient(client, logger),
|
|
37
37
|
dir,
|
|
38
38
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
@@ -60,7 +60,7 @@ test.skip('should get on demand blob without downloading a blob', async () => {
|
|
|
60
60
|
const dir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-download-2-'));
|
|
61
61
|
const driver = new DownloadDriver(
|
|
62
62
|
logger,
|
|
63
|
-
createDownloadClient(logger, client),
|
|
63
|
+
createDownloadClient(logger, client, []),
|
|
64
64
|
createLogsClient(client, logger),
|
|
65
65
|
dir,
|
|
66
66
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
@@ -85,7 +85,7 @@ test.skip('should get undefined when releasing a blob from a small cache and the
|
|
|
85
85
|
const dir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-download-3-'));
|
|
86
86
|
const driver = new DownloadDriver(
|
|
87
87
|
logger,
|
|
88
|
-
createDownloadClient(logger, client),
|
|
88
|
+
createDownloadClient(logger, client, []),
|
|
89
89
|
createLogsClient(client, logger),
|
|
90
90
|
dir,
|
|
91
91
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
@@ -122,7 +122,7 @@ test.skip('should get the blob when releasing a blob, but a cache is big enough
|
|
|
122
122
|
const dir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-download-4-'));
|
|
123
123
|
const driver = new DownloadDriver(
|
|
124
124
|
logger,
|
|
125
|
-
createDownloadClient(logger, client),
|
|
125
|
+
createDownloadClient(logger, client, []),
|
|
126
126
|
createLogsClient(client, logger),
|
|
127
127
|
dir,
|
|
128
128
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
HmacSha256Signer
|
|
4
|
-
} from '@milaboratories/ts-helpers';
|
|
5
|
-
import { fromFileHandle, toFileHandle, toListItem } from './ls_list_entry';
|
|
1
|
+
import { ConsoleLoggerAdapter, HmacSha256Signer } from '@milaboratories/ts-helpers';
|
|
2
|
+
import { parseUploadHandle, toFileHandle, toListItem } from './ls_list_entry';
|
|
6
3
|
import type { Dirent, Stats } from 'node:fs';
|
|
4
|
+
import { ImportFileHandleUpload } from '@milaboratories/pl-model-common';
|
|
7
5
|
|
|
8
6
|
test('toFileHandle should ok when encode data for UploadBlob', () => {
|
|
9
7
|
const signer = new HmacSha256Signer('abc');
|
|
@@ -20,8 +18,8 @@ test('toFileHandle should ok when encode data for UploadBlob', () => {
|
|
|
20
18
|
fullName: 'C:\\programFiles\\file.txt',
|
|
21
19
|
lastModified: { seconds: 150n, nanos: 260 }
|
|
22
20
|
}
|
|
23
|
-
});
|
|
24
|
-
const got =
|
|
21
|
+
}) as ImportFileHandleUpload;
|
|
22
|
+
const got = parseUploadHandle(handle);
|
|
25
23
|
|
|
26
24
|
expect(got.modificationTime).toEqual('150');
|
|
27
25
|
expect(got.localPath).toEqual('C:\\programFiles\\file.txt');
|
|
@@ -2,13 +2,15 @@ import { MiLogger, notEmpty, Signer } from '@milaboratories/ts-helpers';
|
|
|
2
2
|
import * as sdk from '@milaboratories/pl-model-common';
|
|
3
3
|
import { Timestamp } from '../../proto/google/protobuf/timestamp';
|
|
4
4
|
import { Dirent, Stats } from 'node:fs';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { ImportFileHandleIndexData, ImportFileHandleUploadData } from '../types';
|
|
5
7
|
|
|
6
8
|
/** A duck-typing interface for grpc results. */
|
|
7
9
|
export interface ListResponse {
|
|
8
10
|
items: ListItem[];
|
|
9
11
|
delimiter: string;
|
|
10
12
|
}
|
|
11
|
-
|
|
13
|
+
/** @deprecated */
|
|
12
14
|
export interface ListItem {
|
|
13
15
|
isDir: boolean;
|
|
14
16
|
name: string;
|
|
@@ -18,15 +20,14 @@ export interface ListItem {
|
|
|
18
20
|
directory: string;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
/**
|
|
23
|
+
/** @deprecated */
|
|
22
24
|
export function toLsEntries(info: {
|
|
23
25
|
storageName: string;
|
|
24
26
|
list: ListResponse;
|
|
25
27
|
signer: Signer;
|
|
26
28
|
remote: boolean;
|
|
27
29
|
}): sdk.ListFilesResult {
|
|
28
|
-
const parent =
|
|
29
|
-
info.list.items.length > 0 ? info.list.items[0]?.directory : undefined;
|
|
30
|
+
const parent = info.list.items.length > 0 ? info.list.items[0]?.directory : undefined;
|
|
30
31
|
|
|
31
32
|
return {
|
|
32
33
|
parent: parent,
|
|
@@ -34,6 +35,7 @@ export function toLsEntries(info: {
|
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
/** @deprecated */
|
|
37
39
|
function toLsEntry(
|
|
38
40
|
item: ListItem,
|
|
39
41
|
info: {
|
|
@@ -58,6 +60,7 @@ function toLsEntry(
|
|
|
58
60
|
};
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
/** @deprecated */
|
|
61
64
|
export function toFileHandle(info: {
|
|
62
65
|
storageName: string;
|
|
63
66
|
item: ListItem;
|
|
@@ -65,10 +68,10 @@ export function toFileHandle(info: {
|
|
|
65
68
|
remote: boolean;
|
|
66
69
|
}): sdk.ImportFileHandle {
|
|
67
70
|
if (info.remote) {
|
|
68
|
-
return
|
|
71
|
+
return createIndexImportHandle(info.storageName, info.item.fullName);
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
return
|
|
74
|
+
return createUploadImportHandle(
|
|
72
75
|
info.item.fullName,
|
|
73
76
|
info.signer,
|
|
74
77
|
info.item.size,
|
|
@@ -76,50 +79,44 @@ export function toFileHandle(info: {
|
|
|
76
79
|
);
|
|
77
80
|
}
|
|
78
81
|
|
|
79
|
-
export
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
modificationTime: string;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
function createIndexHandle(info: {
|
|
91
|
-
storageName: string;
|
|
92
|
-
item: ListItem;
|
|
93
|
-
}): sdk.ImportFileHandleIndex {
|
|
94
|
-
const data = encodeURIComponent(
|
|
95
|
-
JSON.stringify({
|
|
96
|
-
storageId: info.storageName,
|
|
97
|
-
path: info.item.fullName
|
|
98
|
-
})
|
|
99
|
-
);
|
|
82
|
+
export function createIndexImportHandle(
|
|
83
|
+
storageName: string,
|
|
84
|
+
path: string
|
|
85
|
+
): sdk.ImportFileHandleIndex {
|
|
86
|
+
const data: ImportFileHandleIndexData = {
|
|
87
|
+
storageId: storageName,
|
|
88
|
+
path: path
|
|
89
|
+
};
|
|
100
90
|
|
|
101
|
-
return `index://index/${data}`;
|
|
91
|
+
return `index://index/${encodeURIComponent(JSON.stringify(data))}`;
|
|
102
92
|
}
|
|
103
93
|
|
|
104
|
-
export function
|
|
94
|
+
export function createUploadImportHandle(
|
|
105
95
|
localPath: string,
|
|
106
96
|
signer: Signer,
|
|
107
97
|
sizeBytes: bigint,
|
|
108
98
|
modificationTimeSeconds: bigint
|
|
109
99
|
): sdk.ImportFileHandleUpload {
|
|
110
|
-
const data:
|
|
100
|
+
const data: ImportFileHandleUploadData = {
|
|
111
101
|
localPath,
|
|
112
102
|
pathSignature: signer.sign(localPath),
|
|
113
103
|
sizeBytes: String(sizeBytes),
|
|
114
104
|
modificationTime: String(modificationTimeSeconds)
|
|
115
105
|
};
|
|
116
106
|
|
|
117
|
-
return `upload://upload/${encodeURIComponent(JSON.stringify(data))}
|
|
107
|
+
return `upload://upload/${encodeURIComponent(JSON.stringify(data))}`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function parseUploadHandle(handle: sdk.ImportFileHandleUpload): ImportFileHandleUploadData {
|
|
111
|
+
const url = new URL(handle);
|
|
112
|
+
return ImportFileHandleUploadData.parse(
|
|
113
|
+
JSON.parse(decodeURIComponent(url.pathname.substring(1)))
|
|
114
|
+
);
|
|
118
115
|
}
|
|
119
116
|
|
|
120
|
-
export function
|
|
117
|
+
export function parseIndexHandle(handle: sdk.ImportFileHandleIndex): ImportFileHandleIndexData {
|
|
121
118
|
const url = new URL(handle);
|
|
122
|
-
return JSON.parse(decodeURIComponent(url.pathname.substring(1)));
|
|
119
|
+
return ImportFileHandleIndexData.parse(JSON.parse(decodeURIComponent(url.pathname.substring(1))));
|
|
123
120
|
}
|
|
124
121
|
|
|
125
122
|
export function toListItem(
|
|
@@ -132,9 +129,7 @@ export function toListItem(
|
|
|
132
129
|
}
|
|
133
130
|
): ListItem | undefined {
|
|
134
131
|
if (!(info.dirent.isFile() || info.dirent.isDirectory())) {
|
|
135
|
-
logger.warn(
|
|
136
|
-
`tried to get non-dir and non-file ${info.dirent.name}, skip it`
|
|
137
|
-
);
|
|
132
|
+
logger.warn(`tried to get non-dir and non-file ${info.dirent.name}, skip it`);
|
|
138
133
|
return;
|
|
139
134
|
}
|
|
140
135
|
|
|
@@ -1,38 +1,17 @@
|
|
|
1
1
|
import * as sdk from '@milaboratories/pl-model-common';
|
|
2
|
-
import {
|
|
3
|
-
bigintToResourceId,
|
|
4
|
-
ResourceId,
|
|
5
|
-
ResourceType
|
|
6
|
-
} from '@milaboratories/pl-client';
|
|
2
|
+
import { bigintToResourceId, ResourceId, ResourceType } from '@milaboratories/pl-client';
|
|
7
3
|
import { assertNever } from '@milaboratories/ts-helpers';
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
* Converts local and remote storages to StorageEntries.
|
|
11
|
-
*/
|
|
12
|
-
export function toStorageEntry(
|
|
13
|
-
locals: Record<string, string>,
|
|
14
|
-
remotes: Record<string, ResourceId>
|
|
15
|
-
): sdk.StorageEntry[] {
|
|
16
|
-
const localEntries = Object.entries(locals).map(localToEntry);
|
|
17
|
-
const remoteEntries = Object.entries(remotes).map(remoteToEntry);
|
|
18
|
-
|
|
19
|
-
return localEntries.concat(remoteEntries);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type StorageHandleData =
|
|
23
|
-
| RemoteStorageHandleData
|
|
24
|
-
| LocalStorageHandleData;
|
|
5
|
+
export type StorageHandleData = RemoteStorageHandleData | LocalStorageHandleData;
|
|
25
6
|
|
|
26
7
|
/**
|
|
27
8
|
* Gets a storage handle and gives an underlying data from it.
|
|
28
9
|
*/
|
|
29
|
-
export function
|
|
30
|
-
handle: sdk.StorageHandle
|
|
31
|
-
): StorageHandleData {
|
|
10
|
+
export function parseStorageHandle(handle: sdk.StorageHandle): StorageHandleData {
|
|
32
11
|
if (isRemoteStorageHandle(handle)) {
|
|
33
|
-
return
|
|
12
|
+
return parseRemoteStorageHandle(handle);
|
|
34
13
|
} else if (isLocalStorageHandle(handle)) {
|
|
35
|
-
return
|
|
14
|
+
return parseLocalStorageHandle(handle);
|
|
36
15
|
}
|
|
37
16
|
|
|
38
17
|
assertNever(handle);
|
|
@@ -43,42 +22,31 @@ export function fromStorageHandle(
|
|
|
43
22
|
//
|
|
44
23
|
|
|
45
24
|
export type LocalStorageHandleData = {
|
|
46
|
-
|
|
25
|
+
isRemote: false;
|
|
47
26
|
name: string;
|
|
48
|
-
|
|
27
|
+
rootPath: string;
|
|
49
28
|
};
|
|
50
29
|
|
|
51
|
-
function localToEntry([name, path]: [string, string]): sdk.StorageEntry {
|
|
52
|
-
return {
|
|
53
|
-
name: name,
|
|
54
|
-
handle: toLocalHandle(name, path),
|
|
55
|
-
initialFullPath: path
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
30
|
const localHandleRegex = /^local:\/\/(?<name>.*)\/(?<path>.*)$/;
|
|
60
31
|
|
|
61
|
-
export function isLocalStorageHandle(
|
|
62
|
-
handle: sdk.StorageHandle
|
|
63
|
-
): handle is sdk.StorageHandleLocal {
|
|
32
|
+
export function isLocalStorageHandle(handle: sdk.StorageHandle): handle is sdk.StorageHandleLocal {
|
|
64
33
|
return localHandleRegex.test(handle);
|
|
65
34
|
}
|
|
66
35
|
|
|
67
|
-
function
|
|
36
|
+
export function createLocalStorageHandle(name: string, path: string): sdk.StorageHandleLocal {
|
|
68
37
|
return `local://${name}/${encodeURIComponent(path)}`;
|
|
69
38
|
}
|
|
70
39
|
|
|
71
|
-
function
|
|
40
|
+
function parseLocalStorageHandle(handle: string): LocalStorageHandleData {
|
|
72
41
|
const parsed = handle.match(localHandleRegex);
|
|
73
|
-
if (parsed == null)
|
|
74
|
-
throw new Error(`Local list handle wasn't parsed: ${handle}`);
|
|
42
|
+
if (parsed == null) throw new Error(`Local list handle wasn't parsed: ${handle}`);
|
|
75
43
|
|
|
76
44
|
const { name, path } = parsed.groups!;
|
|
77
45
|
|
|
78
46
|
return {
|
|
79
|
-
|
|
47
|
+
rootPath: decodeURIComponent(path),
|
|
80
48
|
name,
|
|
81
|
-
|
|
49
|
+
isRemote: false
|
|
82
50
|
};
|
|
83
51
|
}
|
|
84
52
|
|
|
@@ -87,20 +55,12 @@ function fromLocalHandle(handle: string): LocalStorageHandleData {
|
|
|
87
55
|
//
|
|
88
56
|
|
|
89
57
|
export type RemoteStorageHandleData = {
|
|
90
|
-
|
|
58
|
+
isRemote: true;
|
|
91
59
|
name: string;
|
|
92
60
|
id: ResourceId;
|
|
93
61
|
type: ResourceType;
|
|
94
62
|
};
|
|
95
63
|
|
|
96
|
-
function remoteToEntry([name, rId]: [string, ResourceId]): sdk.StorageEntry {
|
|
97
|
-
return {
|
|
98
|
-
name: name,
|
|
99
|
-
handle: toRemoteHandle(name, rId),
|
|
100
|
-
initialFullPath: ''
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
64
|
const remoteHandleRegex = /^remote:\/\/(?<name>.*)\/(?<resourceId>.*)$/;
|
|
105
65
|
|
|
106
66
|
export function isRemoteStorageHandle(
|
|
@@ -109,24 +69,20 @@ export function isRemoteStorageHandle(
|
|
|
109
69
|
return remoteHandleRegex.test(handle);
|
|
110
70
|
}
|
|
111
71
|
|
|
112
|
-
function
|
|
113
|
-
name: string,
|
|
114
|
-
rId: ResourceId
|
|
115
|
-
): sdk.StorageHandleRemote {
|
|
72
|
+
export function createRemoteStorageHandle(name: string, rId: ResourceId): sdk.StorageHandleRemote {
|
|
116
73
|
return `remote://${name}/${BigInt(rId)}`;
|
|
117
74
|
}
|
|
118
75
|
|
|
119
|
-
function
|
|
76
|
+
function parseRemoteStorageHandle(handle: string): RemoteStorageHandleData {
|
|
120
77
|
const parsed = handle.match(remoteHandleRegex);
|
|
121
|
-
if (parsed == null)
|
|
122
|
-
throw new Error(`Remote list handle wasn't parsed: ${handle}`);
|
|
78
|
+
if (parsed == null) throw new Error(`Remote list handle wasn't parsed: ${handle}`);
|
|
123
79
|
const { name, resourceId } = parsed.groups!;
|
|
124
80
|
|
|
125
81
|
return {
|
|
126
82
|
id: bigintToResourceId(BigInt(resourceId)),
|
|
127
83
|
type: storageType(name),
|
|
128
84
|
name,
|
|
129
|
-
|
|
85
|
+
isRemote: true
|
|
130
86
|
};
|
|
131
87
|
}
|
|
132
88
|
|
package/src/drivers/logs.test.ts
CHANGED
|
@@ -39,7 +39,7 @@ test('should get all logs', async () => {
|
|
|
39
39
|
const dir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-logs-1-'));
|
|
40
40
|
const download = new DownloadDriver(
|
|
41
41
|
logger,
|
|
42
|
-
createDownloadClient(logger, client),
|
|
42
|
+
createDownloadClient(logger, client, []),
|
|
43
43
|
createLogsClient(client, logger),
|
|
44
44
|
dir,
|
|
45
45
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
@@ -91,7 +91,7 @@ test('should get last line with a prefix', async () => {
|
|
|
91
91
|
const dir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-logs-2-'));
|
|
92
92
|
const download = new DownloadDriver(
|
|
93
93
|
logger,
|
|
94
|
-
createDownloadClient(logger, client),
|
|
94
|
+
createDownloadClient(logger, client, []),
|
|
95
95
|
createLogsClient(client, logger),
|
|
96
96
|
dir,
|
|
97
97
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
@@ -145,7 +145,7 @@ test('should get log smart object and get log lines from that', async () => {
|
|
|
145
145
|
const dir = await fsp.mkdtemp(path.join(os.tmpdir(), 'test-logs-3-'));
|
|
146
146
|
const download = new DownloadDriver(
|
|
147
147
|
logger,
|
|
148
|
-
createDownloadClient(logger, client),
|
|
148
|
+
createDownloadClient(logger, client, []),
|
|
149
149
|
createLogsClient(client, logger),
|
|
150
150
|
dir,
|
|
151
151
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|