@basaltkit/storage-azure 1.0.0 → 1.0.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/LICENSE +1 -1
- package/README.md +6 -0
- package/dist/index.d.ts +5 -8
- package/dist/index.js +65 -54
- package/package.json +9 -10
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://basaltkit-docs.pages.dev">
|
|
3
|
+
<img src="https://basaltkit-docs.pages.dev/social-card.png" alt="Basalt" width="440">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
1
7
|
# @basaltkit/storage-azure
|
|
2
8
|
|
|
3
9
|
An **Azure Blob Storage** driver for [`@basaltkit/storage`](https://www.npmjs.com/package/@basaltkit/storage): stores files in Azure Blob without changing your app code. You need this module when you run on Azure and want Blob Storage instead of S3, GCS, or local disk.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { type PutOptions, type StorageDriver } from '@basaltkit/storage';
|
|
3
2
|
/** The subset of an `@azure/storage-blob` BlockBlobClient this driver uses. */
|
|
4
|
-
interface AzureBlobLike {
|
|
3
|
+
export interface AzureBlobLike {
|
|
5
4
|
uploadData(data: Buffer, options?: {
|
|
6
5
|
blobHTTPHeaders?: {
|
|
7
6
|
blobContentType?: string;
|
|
@@ -18,7 +17,7 @@ interface AzureBlobLike {
|
|
|
18
17
|
}): Promise<string>;
|
|
19
18
|
}
|
|
20
19
|
/** The subset of an `@azure/storage-blob` ContainerClient this driver uses. */
|
|
21
|
-
interface AzureContainerLike {
|
|
20
|
+
export interface AzureContainerLike {
|
|
22
21
|
getBlockBlobClient(path: string): AzureBlobLike;
|
|
23
22
|
listBlobsFlat(options?: {
|
|
24
23
|
prefix?: string;
|
|
@@ -26,7 +25,7 @@ interface AzureContainerLike {
|
|
|
26
25
|
name: string;
|
|
27
26
|
}>;
|
|
28
27
|
}
|
|
29
|
-
interface AzureDriverOptions {
|
|
28
|
+
export interface AzureDriverOptions {
|
|
30
29
|
container: string;
|
|
31
30
|
connectionString?: string;
|
|
32
31
|
/** Injectable container — defaults to `@azure/storage-blob`. Tests pass a fake. */
|
|
@@ -37,7 +36,7 @@ interface AzureDriverOptions {
|
|
|
37
36
|
* (an optional peer dependency) via an injectable container client, so its
|
|
38
37
|
* logic is unit-tested without touching Azure.
|
|
39
38
|
*/
|
|
40
|
-
declare class AzureBlobStorageDriver implements StorageDriver {
|
|
39
|
+
export declare class AzureBlobStorageDriver implements StorageDriver {
|
|
41
40
|
private readonly options;
|
|
42
41
|
readonly name = "azure";
|
|
43
42
|
private containerPromise;
|
|
@@ -51,5 +50,3 @@ declare class AzureBlobStorageDriver implements StorageDriver {
|
|
|
51
50
|
disconnect(): Promise<void>;
|
|
52
51
|
private container;
|
|
53
52
|
}
|
|
54
|
-
|
|
55
|
-
export { type AzureBlobLike, AzureBlobStorageDriver, type AzureContainerLike, type AzureDriverOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,54 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
import { StorageFileNotFoundError } from '@basaltkit/storage';
|
|
2
|
+
const isNotFound = (error) => error?.statusCode === 404 ||
|
|
3
|
+
error?.code === 'BlobNotFound';
|
|
4
|
+
/**
|
|
5
|
+
* Azure Blob Storage driver for `@basaltkit/storage`. Uses `@azure/storage-blob`
|
|
6
|
+
* (an optional peer dependency) via an injectable container client, so its
|
|
7
|
+
* logic is unit-tested without touching Azure.
|
|
8
|
+
*/
|
|
9
|
+
export class AzureBlobStorageDriver {
|
|
10
|
+
options;
|
|
11
|
+
name = 'azure';
|
|
12
|
+
containerPromise;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
async put(path, content, options) {
|
|
17
|
+
const data = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
|
18
|
+
await (await this.container())
|
|
19
|
+
.getBlockBlobClient(path)
|
|
20
|
+
.uploadData(data, options?.contentType !== undefined ? { blobHTTPHeaders: { blobContentType: options.contentType } } : {});
|
|
21
|
+
}
|
|
22
|
+
async get(path) {
|
|
23
|
+
try {
|
|
24
|
+
return await (await this.container()).getBlockBlobClient(path).downloadToBuffer();
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
if (isNotFound(error))
|
|
28
|
+
throw new StorageFileNotFoundError(path);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async exists(path) {
|
|
33
|
+
return (await this.container()).getBlockBlobClient(path).exists();
|
|
34
|
+
}
|
|
35
|
+
async delete(path) {
|
|
36
|
+
const result = await (await this.container()).getBlockBlobClient(path).deleteIfExists();
|
|
37
|
+
return result.succeeded;
|
|
38
|
+
}
|
|
39
|
+
async list(prefix) {
|
|
40
|
+
const names = [];
|
|
41
|
+
for await (const blob of (await this.container()).listBlobsFlat({ prefix }))
|
|
42
|
+
names.push(blob.name);
|
|
43
|
+
return names;
|
|
44
|
+
}
|
|
45
|
+
async temporaryUrl(path, expiresInMs) {
|
|
46
|
+
return (await this.container())
|
|
47
|
+
.getBlockBlobClient(path)
|
|
48
|
+
.generateSasUrl({ permissions: 'r', expiresOn: new Date(Date.now() + expiresInMs) });
|
|
49
|
+
}
|
|
50
|
+
async disconnect() { }
|
|
51
|
+
container() {
|
|
52
|
+
if (!this.containerPromise) {
|
|
53
|
+
this.containerPromise = this.options.client
|
|
54
|
+
? Promise.resolve(this.options.client)
|
|
55
|
+
: (async () => {
|
|
56
|
+
if (!this.options.connectionString)
|
|
57
|
+
throw new Error('connectionString is required for the Azure driver.');
|
|
58
|
+
const specifier = '@azure/storage-blob';
|
|
59
|
+
const mod = (await import(specifier));
|
|
60
|
+
return mod.BlobServiceClient.fromConnectionString(this.options.connectionString).getContainerClient(this.options.container);
|
|
61
|
+
})();
|
|
62
|
+
}
|
|
63
|
+
return this.containerPromise;
|
|
64
|
+
}
|
|
65
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basaltkit/storage-azure",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Azure Blob Storage driver for @basaltkit/storage — put/get/list/delete/SAS URLs over @azure/storage-blob, with an injectable client for testing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,16 +14,15 @@
|
|
|
14
14
|
"dist"
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@basaltkit/storage": "^1.
|
|
17
|
+
"@basaltkit/storage": "^1.2.1"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@azure/storage-blob": "^12.0.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "^
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"vitest": "^3.1.0",
|
|
23
|
+
"@types/node": "^26.3.0",
|
|
24
|
+
"typescript": "^7.0.2",
|
|
25
|
+
"vitest": "^4.1.11",
|
|
27
26
|
"@basaltkit/tsconfig": "^0.24.0"
|
|
28
27
|
},
|
|
29
28
|
"publishConfig": {
|
|
@@ -31,11 +30,11 @@
|
|
|
31
30
|
},
|
|
32
31
|
"repository": {
|
|
33
32
|
"type": "git",
|
|
34
|
-
"url": "git+https://github.com/
|
|
33
|
+
"url": "git+https://github.com/basaltkit/basalt.git",
|
|
35
34
|
"directory": "packages/storage-azure"
|
|
36
35
|
},
|
|
37
|
-
"homepage": "https://github.com/
|
|
38
|
-
"bugs": "https://github.com/
|
|
36
|
+
"homepage": "https://github.com/basaltkit/basalt/tree/main/packages/storage-azure#readme",
|
|
37
|
+
"bugs": "https://github.com/basaltkit/basalt/issues",
|
|
39
38
|
"keywords": [
|
|
40
39
|
"basalt",
|
|
41
40
|
"typescript",
|
|
@@ -44,7 +43,7 @@
|
|
|
44
43
|
"blob"
|
|
45
44
|
],
|
|
46
45
|
"scripts": {
|
|
47
|
-
"build": "
|
|
46
|
+
"build": "tsc -p tsconfig.build.json",
|
|
48
47
|
"test": "vitest run",
|
|
49
48
|
"typecheck": "tsc --noEmit"
|
|
50
49
|
}
|