@milaboratories/pl-drivers 1.3.0 → 1.3.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pl-drivers",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
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/pl-client": "^2.5.3",
31
- "@milaboratories/pl-model-common": "^1.4.0",
32
30
  "@milaboratories/computable": "^2.2.0",
33
- "@milaboratories/pl-tree": "^1.4.4"
31
+ "@milaboratories/pl-tree": "^1.4.4",
32
+ "@milaboratories/pl-client": "^2.5.3",
33
+ "@milaboratories/pl-model-common": "^1.4.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "typescript": "~5.5.4",
@@ -6,7 +6,18 @@ import { ConsoleLoggerAdapter } from '@milaboratories/ts-helpers';
6
6
  import { GrpcTransport } from '@protobuf-ts/grpc-transport';
7
7
  import { Dispatcher } from 'undici';
8
8
  import { text } from 'node:stream/consumers';
9
- import { ClientDownload } from '../clients/download';
9
+ import { ClientDownload, parseLocalFileUrl } from '../clients/download';
10
+ import { test, expect } from '@jest/globals';
11
+
12
+ test('should parse local file url even on Windows', () => {
13
+ const url = "storage://main/67z%5C2vy%5C65i%5C67z2vy65i0xwhjwsfsef_ex3k3hxe7qdc2cvtdfkdnhdp9kwlt7-7dmcy0kthe6u.json";
14
+ const expectedFullPath = 'C:\\Users\\test\\67z\\2vy\\65i\\67z2vy65i0xwhjwsfsef_ex3k3hxe7qdc2cvtdfkdnhdp9kwlt7-7dmcy0kthe6u.json';
15
+
16
+ const got = parseLocalFileUrl(url, new Map([['main', 'C:\\Users\\test']]))
17
+ .replace(path.sep, '\\'); // for testing on *nix systems
18
+
19
+ expect(got).toEqual(expectedFullPath);
20
+ })
10
21
 
11
22
  test('client download from a local file', async () => {
12
23
  await TestHelpers.withTempRoot(async (client) => {
@@ -18,7 +18,6 @@ import { LocalStorageProjection } from '../drivers/types';
18
18
  import { validateAbsolute } from '../helpers/validate';
19
19
 
20
20
  const storageProtocol = 'storage://';
21
- const localPathRegex = /storage:\/\/(?<storageId>.*?)\/(?<localPath>.*)/;
22
21
 
23
22
  export class UnknownStorageError extends Error {}
24
23
 
@@ -74,29 +73,16 @@ export class ClientDownload {
74
73
  return this.isLocal(downloadUrl)
75
74
  ? await this.readLocalFile(downloadUrl)
76
75
  : await this.downloadHelper.downloadRemoteFile(
77
- downloadUrl,
78
- headersFromProto(headers),
79
- signal
80
- );
76
+ downloadUrl,
77
+ headersFromProto(headers),
78
+ signal
79
+ );
81
80
  }
82
81
 
83
82
  private isLocal = (url: string) => url.startsWith(storageProtocol);
84
83
 
85
84
  async readLocalFile(url: string): Promise<DownloadResponse> {
86
- const parsed = url.match(localPathRegex);
87
- if (parsed === null || parsed.length != 3) {
88
- throw new WrongLocalFileUrl(
89
- `url for local filepath ${url} does not match regex ${localPathRegex}, parsed: ${parsed}`
90
- );
91
- }
92
-
93
- const [_, storageId, localPath] = parsed;
94
-
95
- const storageRoot = this.localStorageIdsToRoot.get(storageId);
96
- if (storageRoot === undefined)
97
- throw new UnknownStorageError(`Unknown storage location: ${storageId}`);
98
-
99
- const fullPath = storageRoot === '' ? localPath : path.join(storageRoot, localPath);
85
+ const fullPath = parseLocalFileUrl(url, this.localStorageIdsToRoot);
100
86
  const stat = await fsp.stat(fullPath);
101
87
  const size = stat.size;
102
88
 
@@ -107,6 +93,25 @@ export class ClientDownload {
107
93
  }
108
94
  }
109
95
 
96
+ export function parseLocalFileUrl(
97
+ url: string,
98
+ localStorageIdsToRoot: Map<string, string>,
99
+ ): string {
100
+ const parsed = new URL(url);
101
+ if (parsed.pathname == '')
102
+ throw new WrongLocalFileUrl(`url for local filepath ${url} does not match url scheme`);
103
+
104
+ const storageId = parsed.host;
105
+ const storageRoot = localStorageIdsToRoot.get(storageId);
106
+ if (storageRoot === undefined)
107
+ throw new UnknownStorageError(`Unknown storage location: ${storageId}`);
108
+
109
+ const localPath = decodeURIComponent(parsed.pathname.slice(1));
110
+ const fullPath = storageRoot === '' ? localPath : path.join(storageRoot, localPath);
111
+
112
+ return fullPath;
113
+ }
114
+
110
115
  export function headersFromProto(
111
116
  headers: DownloadAPI_GetDownloadURL_HTTPHeader[]
112
117
  ): Record<string, string> {