@ms-cloudpack/remote-cache 0.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/README.md +22 -0
- package/lib/RemoteCacheClient.d.ts +21 -0
- package/lib/RemoteCacheClient.d.ts.map +1 -0
- package/lib/RemoteCacheClient.js +37 -0
- package/lib/RemoteCacheClient.js.map +1 -0
- package/lib/authentication/KeyRingLocalTokenCache.d.ts +13 -0
- package/lib/authentication/KeyRingLocalTokenCache.d.ts.map +1 -0
- package/lib/authentication/KeyRingLocalTokenCache.js +26 -0
- package/lib/authentication/KeyRingLocalTokenCache.js.map +1 -0
- package/lib/authentication/acquireSasToken.d.ts +3 -0
- package/lib/authentication/acquireSasToken.d.ts.map +1 -0
- package/lib/authentication/acquireSasToken.js +24 -0
- package/lib/authentication/acquireSasToken.js.map +1 -0
- package/lib/authentication/createBlobStorageUrl.d.ts +2 -0
- package/lib/authentication/createBlobStorageUrl.d.ts.map +1 -0
- package/lib/authentication/createBlobStorageUrl.js +4 -0
- package/lib/authentication/createBlobStorageUrl.js.map +1 -0
- package/lib/authentication/getAuthenticatedConnectionString.d.ts +3 -0
- package/lib/authentication/getAuthenticatedConnectionString.d.ts.map +1 -0
- package/lib/authentication/getAuthenticatedConnectionString.js +12 -0
- package/lib/authentication/getAuthenticatedConnectionString.js.map +1 -0
- package/lib/authentication/getSasToken.d.ts +12 -0
- package/lib/authentication/getSasToken.d.ts.map +1 -0
- package/lib/authentication/getSasToken.js +15 -0
- package/lib/authentication/getSasToken.js.map +1 -0
- package/lib/authentication/isExpired.d.ts +2 -0
- package/lib/authentication/isExpired.d.ts.map +1 -0
- package/lib/authentication/isExpired.js +10 -0
- package/lib/authentication/isExpired.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -0
- package/lib/tsdoc-metadata.json +11 -0
- package/lib/types/ConnectionStringOptions.d.ts +9 -0
- package/lib/types/ConnectionStringOptions.d.ts.map +1 -0
- package/lib/types/ConnectionStringOptions.js +2 -0
- package/lib/types/ConnectionStringOptions.js.map +1 -0
- package/lib/types/LocalTokenCacheProvider.d.ts +5 -0
- package/lib/types/LocalTokenCacheProvider.d.ts.map +1 -0
- package/lib/types/LocalTokenCacheProvider.js +2 -0
- package/lib/types/LocalTokenCacheProvider.js.map +1 -0
- package/lib/types/RemoteCacheClientOptions.d.ts +5 -0
- package/lib/types/RemoteCacheClientOptions.d.ts.map +1 -0
- package/lib/types/RemoteCacheClientOptions.js +2 -0
- package/lib/types/RemoteCacheClientOptions.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# @ms-cloudpack/remote-cache
|
|
2
|
+
|
|
3
|
+
This package is a wrapper around the Azure Storage SDK that provides a simple interface for uploading and downloading files and folders to and from Azure Blob Storage. It also includes a helper function for generating a SAS token for a storage account.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { getAuthenticatedConnectionString, RemoteCacheClient } from '@ms-cloudpack/remote-cache';
|
|
9
|
+
|
|
10
|
+
const connectionString = await getAuthenticatedConnectionString({
|
|
11
|
+
storageAccount: 'my-storage-account',
|
|
12
|
+
container: 'my-container',
|
|
13
|
+
permissions: { read: true, write: false },
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const client = new RemoteCacheClient({
|
|
17
|
+
container: 'my-container',
|
|
18
|
+
connectionString,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
await client.downloadFolder('my-folder', 'download-it-to-this-path');
|
|
22
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';
|
|
2
|
+
export declare class RemoteCacheClient {
|
|
3
|
+
private readonly logger;
|
|
4
|
+
private readonly config;
|
|
5
|
+
constructor({ container, connectionString }: RemoteCacheClientOptions);
|
|
6
|
+
/**
|
|
7
|
+
* Uploads the folder to the remote cache.
|
|
8
|
+
* @param folderName - The name of the folder to upload.
|
|
9
|
+
* @param path - The path to the folder to upload.
|
|
10
|
+
* @returns - A promise that resolves when the folder has been uploaded.
|
|
11
|
+
*/
|
|
12
|
+
uploadFolder(folderName: string, path: string): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Downloads the folder from the remote cache.
|
|
15
|
+
* @param folderName - The name of the folder to download.
|
|
16
|
+
* @param path - The path to download the folder to.
|
|
17
|
+
* @returns - A promise that resolves when the folder has been downloaded.
|
|
18
|
+
*/
|
|
19
|
+
downloadFolder(folderName: string, path: string): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=RemoteCacheClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteCacheClient.d.ts","sourceRoot":"","sources":["../src/RemoteCacheClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAGpF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsD;IAC7E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAKrB;gBAEU,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,wBAAwB;IAerE;;;;;OAKG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAI7C;;;;;OAKG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAGhD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { makeLogger, put, fetch } from 'backfill/lib/api.js';
|
|
2
|
+
export class RemoteCacheClient {
|
|
3
|
+
constructor({ container, connectionString }) {
|
|
4
|
+
this.logger = makeLogger('mute', process.stdout, process.stderr);
|
|
5
|
+
this.config = {
|
|
6
|
+
incrementalCaching: true,
|
|
7
|
+
internalCacheFolder: '',
|
|
8
|
+
outputGlob: ['**/*'],
|
|
9
|
+
cacheStorageConfig: {
|
|
10
|
+
provider: 'azure-blob',
|
|
11
|
+
options: {
|
|
12
|
+
connectionString,
|
|
13
|
+
container,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Uploads the folder to the remote cache.
|
|
20
|
+
* @param folderName - The name of the folder to upload.
|
|
21
|
+
* @param path - The path to the folder to upload.
|
|
22
|
+
* @returns - A promise that resolves when the folder has been uploaded.
|
|
23
|
+
*/
|
|
24
|
+
uploadFolder(folderName, path) {
|
|
25
|
+
return put(path, folderName, this.logger, this.config);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Downloads the folder from the remote cache.
|
|
29
|
+
* @param folderName - The name of the folder to download.
|
|
30
|
+
* @param path - The path to download the folder to.
|
|
31
|
+
* @returns - A promise that resolves when the folder has been downloaded.
|
|
32
|
+
*/
|
|
33
|
+
downloadFolder(folderName, path) {
|
|
34
|
+
return fetch(path, folderName, this.logger, this.config);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=RemoteCacheClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteCacheClient.js","sourceRoot":"","sources":["../src/RemoteCacheClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAI7D,MAAM,OAAO,iBAAiB;IAS5B,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAA4B;QARpD,WAAM,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAS3E,IAAI,CAAC,MAAM,GAAG;YACZ,kBAAkB,EAAE,IAAI;YACxB,mBAAmB,EAAE,EAAE;YACvB,UAAU,EAAE,CAAC,MAAM,CAAC;YACpB,kBAAkB,EAAE;gBAClB,QAAQ,EAAE,YAAY;gBACtB,OAAO,EAAE;oBACP,gBAAgB;oBAChB,SAAS;iBACV;aACF;SACF,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,UAAkB,EAAE,IAAY;QAC3C,OAAO,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,UAAkB,EAAE,IAAY;QAC7C,OAAO,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;CACF","sourcesContent":["import { makeLogger, put, fetch } from 'backfill/lib/api.js';\nimport type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';\nimport type { AzureBlobCacheStorageConfig } from 'backfill-config';\n\nexport class RemoteCacheClient {\n private readonly logger = makeLogger('mute', process.stdout, process.stderr);\n private readonly config: {\n cacheStorageConfig: AzureBlobCacheStorageConfig;\n incrementalCaching: boolean;\n internalCacheFolder: string;\n outputGlob: string[];\n };\n\n constructor({ container, connectionString }: RemoteCacheClientOptions) {\n this.config = {\n incrementalCaching: true,\n internalCacheFolder: '', // not used by azure-blob\n outputGlob: ['**/*'],\n cacheStorageConfig: {\n provider: 'azure-blob',\n options: {\n connectionString,\n container,\n },\n },\n };\n }\n\n /**\n * Uploads the folder to the remote cache.\n * @param folderName - The name of the folder to upload.\n * @param path - The path to the folder to upload.\n * @returns - A promise that resolves when the folder has been uploaded.\n */\n uploadFolder(folderName: string, path: string) {\n return put(path, folderName, this.logger, this.config);\n }\n\n /**\n * Downloads the folder from the remote cache.\n * @param folderName - The name of the folder to download.\n * @param path - The path to download the folder to.\n * @returns - A promise that resolves when the folder has been downloaded.\n */\n downloadFolder(folderName: string, path: string) {\n return fetch(path, folderName, this.logger, this.config);\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LocalTokenCacheProvider } from '../types/LocalTokenCacheProvider.js';
|
|
2
|
+
import type { ConnectionStringOptions } from '../types/ConnectionStringOptions.js';
|
|
3
|
+
/**
|
|
4
|
+
* This class is responsible to read and store tokens in a key ring provided by operating system.
|
|
5
|
+
*/
|
|
6
|
+
export declare class KeyRingLocalTokenCache implements LocalTokenCacheProvider {
|
|
7
|
+
private readonly entry;
|
|
8
|
+
private readonly entryOptions;
|
|
9
|
+
constructor(options: ConnectionStringOptions);
|
|
10
|
+
get(): string | undefined;
|
|
11
|
+
set(value: string): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=KeyRingLocalTokenCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyRingLocalTokenCache.d.ts","sourceRoot":"","sources":["../../src/authentication/KeyRingLocalTokenCache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAGnF;;GAEG;AACH,qBAAa,sBAAuB,YAAW,uBAAuB;IACpE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;gBAEzD,OAAO,EAAE,uBAAuB;IAW5C,GAAG;IAcH,GAAG,CAAC,KAAK,EAAE,MAAM;CAGlB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ContainerSASPermissions } from '@azure/storage-blob';
|
|
2
|
+
import { Entry } from '@napi-rs/keyring';
|
|
3
|
+
/**
|
|
4
|
+
* This class is responsible to read and store tokens in a key ring provided by operating system.
|
|
5
|
+
*/
|
|
6
|
+
export class KeyRingLocalTokenCache {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.entryOptions = {
|
|
9
|
+
service: `cloudpack-cache-${options.storageAccount}`,
|
|
10
|
+
username: `container:${options.container};permission:${ContainerSASPermissions.from(options.permissions).toString()}`,
|
|
11
|
+
};
|
|
12
|
+
this.entry = new Entry(this.entryOptions.service, this.entryOptions.username);
|
|
13
|
+
}
|
|
14
|
+
get() {
|
|
15
|
+
const result = this.entry.getPassword();
|
|
16
|
+
console.debug(`KeyRingLocalTokenCache.get service:${this.entryOptions.service} username:${this.entryOptions.username} result:${result}`);
|
|
17
|
+
if (!result) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
set(value) {
|
|
23
|
+
this.entry.setPassword(value);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=KeyRingLocalTokenCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyRingLocalTokenCache.js","sourceRoot":"","sources":["../../src/authentication/KeyRingLocalTokenCache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,sBAAsB;IAIjC,YAAY,OAAgC;QAC1C,IAAI,CAAC,YAAY,GAAG;YAClB,OAAO,EAAE,mBAAmB,OAAO,CAAC,cAAc,EAAE;YACpD,QAAQ,EAAE,aAAa,OAAO,CAAC,SAAS,eAAe,uBAAuB,CAAC,IAAI,CACjF,OAAO,CAAC,WAAW,CACpB,CAAC,QAAQ,EAAE,EAAE;SACf,CAAC;QAEF,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChF,CAAC;IAED,GAAG;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QAExC,OAAO,CAAC,KAAK,CACX,sCAAsC,IAAI,CAAC,YAAY,CAAC,OAAO,aAAa,IAAI,CAAC,YAAY,CAAC,QAAQ,WAAW,MAAM,EAAE,CAC1H,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE;YACX,OAAO,SAAS,CAAC;SAClB;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,KAAa;QACf,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;CACF","sourcesContent":["import { ContainerSASPermissions } from '@azure/storage-blob';\nimport type { LocalTokenCacheProvider } from '../types/LocalTokenCacheProvider.js';\nimport type { ConnectionStringOptions } from '../types/ConnectionStringOptions.js';\nimport { Entry } from '@napi-rs/keyring';\n\n/**\n * This class is responsible to read and store tokens in a key ring provided by operating system.\n */\nexport class KeyRingLocalTokenCache implements LocalTokenCacheProvider {\n private readonly entry: Entry;\n private readonly entryOptions: { service: string; username: string };\n\n constructor(options: ConnectionStringOptions) {\n this.entryOptions = {\n service: `cloudpack-cache-${options.storageAccount}`,\n username: `container:${options.container};permission:${ContainerSASPermissions.from(\n options.permissions,\n ).toString()}`,\n };\n\n this.entry = new Entry(this.entryOptions.service, this.entryOptions.username);\n }\n\n get() {\n const result = this.entry.getPassword();\n\n console.debug(\n `KeyRingLocalTokenCache.get service:${this.entryOptions.service} username:${this.entryOptions.username} result:${result}`,\n );\n\n if (!result) {\n return undefined;\n }\n\n return result;\n }\n\n set(value: string) {\n this.entry.setPassword(value);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acquireSasToken.d.ts","sourceRoot":"","sources":["../../src/authentication/acquireSasToken.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAGnF,wBAAsB,eAAe,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,uBAAuB,mBA2BjH"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BlobServiceClient, ContainerSASPermissions, SASProtocol, generateBlobSASQueryParameters, } from '@azure/storage-blob';
|
|
2
|
+
import { InteractiveBrowserCredential } from '@azure/identity';
|
|
3
|
+
import { createBlobStorageUrl } from './createBlobStorageUrl.js';
|
|
4
|
+
export async function acquireSasToken({ storageAccount: account, container, permissions }) {
|
|
5
|
+
const credential = new InteractiveBrowserCredential({
|
|
6
|
+
redirectUri: 'http://localhost:1337',
|
|
7
|
+
});
|
|
8
|
+
const blobStorage = new BlobServiceClient(createBlobStorageUrl(account), credential);
|
|
9
|
+
const containerClient = blobStorage.getContainerClient(container);
|
|
10
|
+
const startsOn = new Date(); // now
|
|
11
|
+
const twentyFourHoursInMs = 86400000;
|
|
12
|
+
const expiresOn = new Date(startsOn.valueOf() + twentyFourHoursInMs); // in 24 hours
|
|
13
|
+
const userDelegationKey = await blobStorage.getUserDelegationKey(startsOn, expiresOn);
|
|
14
|
+
const sasQueryParams = generateBlobSASQueryParameters({
|
|
15
|
+
containerName: containerClient.containerName,
|
|
16
|
+
permissions: ContainerSASPermissions.from(permissions),
|
|
17
|
+
expiresOn,
|
|
18
|
+
startsOn,
|
|
19
|
+
ipRange: { start: '0.0.0.0', end: '255.255.255.255' },
|
|
20
|
+
protocol: SASProtocol.Https,
|
|
21
|
+
}, userDelegationKey, account);
|
|
22
|
+
return sasQueryParams.toString();
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=acquireSasToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acquireSasToken.js","sourceRoot":"","sources":["../../src/authentication/acquireSasToken.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,WAAW,EACX,8BAA8B,GAC/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAA2B;IAChH,MAAM,UAAU,GAAG,IAAI,4BAA4B,CAAC;QAClD,WAAW,EAAE,uBAAuB;KACrC,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,IAAI,iBAAiB,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC;IACrF,MAAM,eAAe,GAAG,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAElE,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM;IACnC,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,mBAAmB,CAAC,CAAC,CAAC,cAAc;IAEpF,MAAM,iBAAiB,GAAG,MAAM,WAAW,CAAC,oBAAoB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAEtF,MAAM,cAAc,GAAG,8BAA8B,CACnD;QACE,aAAa,EAAE,eAAe,CAAC,aAAa;QAC5C,WAAW,EAAE,uBAAuB,CAAC,IAAI,CAAC,WAAW,CAAC;QACtD,SAAS;QACT,QAAQ;QACR,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,iBAAiB,EAAE;QACrD,QAAQ,EAAE,WAAW,CAAC,KAAK;KAC5B,EACD,iBAAiB,EACjB,OAAO,CACR,CAAC;IAEF,OAAO,cAAc,CAAC,QAAQ,EAAE,CAAC;AACnC,CAAC","sourcesContent":["import {\n BlobServiceClient,\n ContainerSASPermissions,\n SASProtocol,\n generateBlobSASQueryParameters,\n} from '@azure/storage-blob';\nimport { InteractiveBrowserCredential } from '@azure/identity';\nimport type { ConnectionStringOptions } from '../types/ConnectionStringOptions.js';\nimport { createBlobStorageUrl } from './createBlobStorageUrl.js';\n\nexport async function acquireSasToken({ storageAccount: account, container, permissions }: ConnectionStringOptions) {\n const credential = new InteractiveBrowserCredential({\n redirectUri: 'http://localhost:1337',\n });\n const blobStorage = new BlobServiceClient(createBlobStorageUrl(account), credential);\n const containerClient = blobStorage.getContainerClient(container);\n\n const startsOn = new Date(); // now\n const twentyFourHoursInMs = 86400000;\n const expiresOn = new Date(startsOn.valueOf() + twentyFourHoursInMs); // in 24 hours\n\n const userDelegationKey = await blobStorage.getUserDelegationKey(startsOn, expiresOn);\n\n const sasQueryParams = generateBlobSASQueryParameters(\n {\n containerName: containerClient.containerName,\n permissions: ContainerSASPermissions.from(permissions),\n expiresOn,\n startsOn,\n ipRange: { start: '0.0.0.0', end: '255.255.255.255' },\n protocol: SASProtocol.Https,\n },\n userDelegationKey,\n account,\n );\n\n return sasQueryParams.toString();\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createBlobStorageUrl.d.ts","sourceRoot":"","sources":["../../src/authentication/createBlobStorageUrl.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,UAEnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createBlobStorageUrl.js","sourceRoot":"","sources":["../../src/authentication/createBlobStorageUrl.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,OAAO,WAAW,OAAO,wBAAwB,CAAC;AACpD,CAAC","sourcesContent":["export function createBlobStorageUrl(account: string) {\n return `https://${account}.blob.core.windows.net`;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAuthenticatedConnectionString.d.ts","sourceRoot":"","sources":["../../src/authentication/getAuthenticatedConnectionString.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAMnF,wBAAsB,gCAAgC,CAAC,uBAAuB,EAAE,uBAAuB,mBAMtG"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createBlobStorageUrl } from './createBlobStorageUrl.js';
|
|
2
|
+
import { getSasToken } from './getSasToken.js';
|
|
3
|
+
import { KeyRingLocalTokenCache } from './KeyRingLocalTokenCache.js';
|
|
4
|
+
import { acquireSasToken } from './acquireSasToken.js';
|
|
5
|
+
import { isExpired } from './isExpired.js';
|
|
6
|
+
export async function getAuthenticatedConnectionString(connectionStringOptions) {
|
|
7
|
+
const tokenCache = new KeyRingLocalTokenCache(connectionStringOptions);
|
|
8
|
+
const sasToken = await getSasToken({ connectionStringOptions }, { tokenCache, acquireSasToken, isExpired });
|
|
9
|
+
const { storageAccount } = connectionStringOptions;
|
|
10
|
+
return `BlobEndpoint=${createBlobStorageUrl(storageAccount)};SharedAccessSignature=${sasToken}`;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=getAuthenticatedConnectionString.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAuthenticatedConnectionString.js","sourceRoot":"","sources":["../../src/authentication/getAuthenticatedConnectionString.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,gCAAgC,CAAC,uBAAgD;IACrG,MAAM,UAAU,GAAG,IAAI,sBAAsB,CAAC,uBAAuB,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,uBAAuB,EAAE,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;IAE5G,MAAM,EAAE,cAAc,EAAE,GAAG,uBAAuB,CAAC;IACnD,OAAO,gBAAgB,oBAAoB,CAAC,cAAc,CAAC,0BAA0B,QAAQ,EAAE,CAAC;AAClG,CAAC","sourcesContent":["import { createBlobStorageUrl } from './createBlobStorageUrl.js';\nimport type { ConnectionStringOptions } from '../types/ConnectionStringOptions.js';\nimport { getSasToken } from './getSasToken.js';\nimport { KeyRingLocalTokenCache } from './KeyRingLocalTokenCache.js';\nimport { acquireSasToken } from './acquireSasToken.js';\nimport { isExpired } from './isExpired.js';\n\nexport async function getAuthenticatedConnectionString(connectionStringOptions: ConnectionStringOptions) {\n const tokenCache = new KeyRingLocalTokenCache(connectionStringOptions);\n const sasToken = await getSasToken({ connectionStringOptions }, { tokenCache, acquireSasToken, isExpired });\n\n const { storageAccount } = connectionStringOptions;\n return `BlobEndpoint=${createBlobStorageUrl(storageAccount)};SharedAccessSignature=${sasToken}`;\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LocalTokenCacheProvider } from '../types/LocalTokenCacheProvider.js';
|
|
2
|
+
import type { ConnectionStringOptions } from '../types/ConnectionStringOptions.js';
|
|
3
|
+
export interface GetSasTokenOptions {
|
|
4
|
+
connectionStringOptions: ConnectionStringOptions;
|
|
5
|
+
}
|
|
6
|
+
export interface GetSasTokenDependencies {
|
|
7
|
+
tokenCache: LocalTokenCacheProvider;
|
|
8
|
+
acquireSasToken: (options: ConnectionStringOptions) => Promise<string>;
|
|
9
|
+
isExpired: (token: string) => boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function getSasToken({ connectionStringOptions }: GetSasTokenOptions, { tokenCache, acquireSasToken, isExpired }: GetSasTokenDependencies): Promise<string | undefined>;
|
|
12
|
+
//# sourceMappingURL=getSasToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSasToken.d.ts","sourceRoot":"","sources":["../../src/authentication/getSasToken.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAEnF,MAAM,WAAW,kBAAkB;IACjC,uBAAuB,EAAE,uBAAuB,CAAC;CAClD;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,uBAAuB,CAAC;IACpC,eAAe,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED,wBAAsB,WAAW,CAC/B,EAAE,uBAAuB,EAAE,EAAE,kBAAkB,EAC/C,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,EAAE,uBAAuB,+BAcpE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export async function getSasToken({ connectionStringOptions }, { tokenCache, acquireSasToken, isExpired }) {
|
|
2
|
+
try {
|
|
3
|
+
const localToken = tokenCache.get();
|
|
4
|
+
if (localToken && !isExpired(localToken)) {
|
|
5
|
+
return localToken;
|
|
6
|
+
}
|
|
7
|
+
const token = await acquireSasToken(connectionStringOptions);
|
|
8
|
+
tokenCache.set(token);
|
|
9
|
+
return token;
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
console.error(`Failed to get SAS token for storage account.`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=getSasToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSasToken.js","sourceRoot":"","sources":["../../src/authentication/getSasToken.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,EAAE,uBAAuB,EAAsB,EAC/C,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,EAA2B;IAEnE,IAAI;QACF,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;QACpC,IAAI,UAAU,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE;YACxC,OAAO,UAAU,CAAC;SACnB;QAED,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,uBAAuB,CAAC,CAAC;QAC7D,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC;KACd;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;KAC/D;AACH,CAAC","sourcesContent":["import type { LocalTokenCacheProvider } from '../types/LocalTokenCacheProvider.js';\nimport type { ConnectionStringOptions } from '../types/ConnectionStringOptions.js';\n\nexport interface GetSasTokenOptions {\n connectionStringOptions: ConnectionStringOptions;\n}\n\nexport interface GetSasTokenDependencies {\n tokenCache: LocalTokenCacheProvider;\n acquireSasToken: (options: ConnectionStringOptions) => Promise<string>;\n isExpired: (token: string) => boolean;\n}\n\nexport async function getSasToken(\n { connectionStringOptions }: GetSasTokenOptions,\n { tokenCache, acquireSasToken, isExpired }: GetSasTokenDependencies,\n) {\n try {\n const localToken = tokenCache.get();\n if (localToken && !isExpired(localToken)) {\n return localToken;\n }\n\n const token = await acquireSasToken(connectionStringOptions);\n tokenCache.set(token);\n return token;\n } catch (error) {\n console.error(`Failed to get SAS token for storage account.`);\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isExpired.d.ts","sourceRoot":"","sources":["../../src/authentication/isExpired.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,WAQzC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isExpired.js","sourceRoot":"","sources":["../../src/authentication/isExpired.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,EAAE;QACP,OAAO,IAAI,CAAC;KACb;IACD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,OAAO,MAAM,GAAG,GAAG,CAAC;AACtB,CAAC","sourcesContent":["export function isExpired(sasToken: string) {\n const se = new URLSearchParams(sasToken).get('se');\n if (!se) {\n return true;\n }\n const expiry = new Date(se);\n const now = new Date();\n return expiry < now;\n}\n"]}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { RemoteCacheClient } from './RemoteCacheClient.js';
|
|
2
|
+
export { getAuthenticatedConnectionString } from './authentication/getAuthenticatedConnectionString.js';
|
|
3
|
+
export type { ConnectionStringOptions } from './types/ConnectionStringOptions.js';
|
|
4
|
+
export type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AAExG,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAClF,YAAY,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC"}
|
package/lib/index.js
ADDED
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC","sourcesContent":["export { RemoteCacheClient } from './RemoteCacheClient.js';\nexport { getAuthenticatedConnectionString } from './authentication/getAuthenticatedConnectionString.js';\n\nexport type { ConnectionStringOptions } from './types/ConnectionStringOptions.js';\nexport type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
|
2
|
+
// It should be published with your NPM package. It should not be tracked by Git.
|
|
3
|
+
{
|
|
4
|
+
"tsdocVersion": "0.12",
|
|
5
|
+
"toolPackages": [
|
|
6
|
+
{
|
|
7
|
+
"packageName": "@microsoft/api-extractor",
|
|
8
|
+
"packageVersion": "7.36.3"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionStringOptions.d.ts","sourceRoot":"","sources":["../../src/types/ConnectionStringOptions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE;QACX,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConnectionStringOptions.js","sourceRoot":"","sources":["../../src/types/ConnectionStringOptions.ts"],"names":[],"mappings":"","sourcesContent":["export interface ConnectionStringOptions {\n storageAccount: string;\n container: string;\n permissions: {\n read: boolean;\n write: boolean;\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalTokenCacheProvider.d.ts","sourceRoot":"","sources":["../../src/types/LocalTokenCacheProvider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,GAAG,IAAI,MAAM,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalTokenCacheProvider.js","sourceRoot":"","sources":["../../src/types/LocalTokenCacheProvider.ts"],"names":[],"mappings":"","sourcesContent":["export interface LocalTokenCacheProvider {\n get(): string | undefined;\n set(value: string): void;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteCacheClientOptions.d.ts","sourceRoot":"","sources":["../../src/types/RemoteCacheClientOptions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteCacheClientOptions.js","sourceRoot":"","sources":["../../src/types/RemoteCacheClientOptions.ts"],"names":[],"mappings":"","sourcesContent":["export interface RemoteCacheClientOptions {\n connectionString: string;\n container: string;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ms-cloudpack/remote-cache",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Manages syncing the local Cloudpack cached assets to/from a remote storage service.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "./lib/index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./lib/index.d.ts",
|
|
12
|
+
"import": "./lib/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@ms-cloudpack/eslint-plugin-internal": "*",
|
|
17
|
+
"@ms-cloudpack/scripts": "*"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"api": "cloudpack-scripts api",
|
|
21
|
+
"build:watch": "cloudpack-scripts build-watch",
|
|
22
|
+
"build": "cloudpack-scripts build",
|
|
23
|
+
"lint:update": "cloudpack-scripts lint-update",
|
|
24
|
+
"lint": "cloudpack-scripts lint",
|
|
25
|
+
"test:watch": "cloudpack-scripts test-watch",
|
|
26
|
+
"test": "cloudpack-scripts test"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"lib/**/!(*.test.*)"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@azure/identity": "^3.2.3",
|
|
33
|
+
"@azure/storage-blob": "^12.15.0",
|
|
34
|
+
"@napi-rs/keyring": "^1.1.3",
|
|
35
|
+
"backfill": "^6.1.27",
|
|
36
|
+
"backfill-config": "^6.3.1"
|
|
37
|
+
}
|
|
38
|
+
}
|