@ms-cloudpack/remote-cache 0.4.7 → 0.5.1-beta.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/AzureRemoteCacheClient-2PRAPCJH.js +52049 -0
- package/dist/AzureRemoteCacheClient-2PRAPCJH.js.map +7 -0
- package/dist/ReporterDecorator-BYNXV72I.js +126 -0
- package/dist/ReporterDecorator-BYNXV72I.js.map +7 -0
- package/dist/chunk-G3ME7OWS.js +49567 -0
- package/dist/chunk-G3ME7OWS.js.map +7 -0
- package/dist/chunk-GFT2G5UO.js +50 -0
- package/dist/chunk-GFT2G5UO.js.map +7 -0
- package/dist/chunk-KKZU5JW4.js +1071 -0
- package/dist/chunk-KKZU5JW4.js.map +7 -0
- package/dist/chunk-VVROC42R.js +182 -0
- package/dist/chunk-VVROC42R.js.map +7 -0
- package/dist/chunk-XKOU5VXX.js +9 -0
- package/dist/chunk-XKOU5VXX.js.map +7 -0
- package/dist/getCredential-MJEIGDVB.js +23981 -0
- package/dist/getCredential-MJEIGDVB.js.map +7 -0
- package/dist/getListOfBlobs-LKU62UR5.js +26 -0
- package/dist/getListOfBlobs-LKU62UR5.js.map +7 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +7 -0
- package/lib/AzureRemoteCacheClient.d.ts +5 -5
- package/lib/decorators/InMemoryDecorator.d.ts +2 -2
- package/lib/decorators/InMemoryDecorator.test.d.ts +2 -0
- package/lib/decorators/ReporterDecorator.d.ts +2 -2
- package/lib/decorators/RetryDecorator.d.ts +2 -2
- package/lib/decorators/RetryDecorator.test.d.ts +2 -0
- package/lib/index.d.ts +1 -1
- package/lib/types/RemoteCacheClient.d.ts +12 -3
- package/package.json +13 -13
- package/lib/AzureRemoteCacheClient.d.ts.map +0 -1
- package/lib/AzureRemoteCacheClient.js +0 -51
- package/lib/AzureRemoteCacheClient.js.map +0 -1
- package/lib/Task.d.ts.map +0 -1
- package/lib/Task.js +0 -2
- package/lib/Task.js.map +0 -1
- package/lib/authentication/getAuthenticationRecord.d.ts.map +0 -1
- package/lib/authentication/getAuthenticationRecord.js +0 -17
- package/lib/authentication/getAuthenticationRecord.js.map +0 -1
- package/lib/authentication/getAuthenticationRecordPath.d.ts.map +0 -1
- package/lib/authentication/getAuthenticationRecordPath.js +0 -10
- package/lib/authentication/getAuthenticationRecordPath.js.map +0 -1
- package/lib/authentication/getCredential.d.ts.map +0 -1
- package/lib/authentication/getCredential.js +0 -61
- package/lib/authentication/getCredential.js.map +0 -1
- package/lib/authentication/saveAuthenticationRecord.d.ts.map +0 -1
- package/lib/authentication/saveAuthenticationRecord.js +0 -17
- package/lib/authentication/saveAuthenticationRecord.js.map +0 -1
- package/lib/cache-persistance/cachePersistencePlugin.d.ts.map +0 -1
- package/lib/cache-persistance/cachePersistencePlugin.js +0 -35
- package/lib/cache-persistance/cachePersistencePlugin.js.map +0 -1
- package/lib/cache-persistance/platforms.d.ts.map +0 -1
- package/lib/cache-persistance/platforms.js +0 -109
- package/lib/cache-persistance/platforms.js.map +0 -1
- package/lib/cache-persistance/provider.d.ts.map +0 -1
- package/lib/cache-persistance/provider.js +0 -26
- package/lib/cache-persistance/provider.js.map +0 -1
- package/lib/createBlobStorageUrl.d.ts.map +0 -1
- package/lib/createBlobStorageUrl.js +0 -4
- package/lib/createBlobStorageUrl.js.map +0 -1
- package/lib/createRemoteCacheClient.d.ts.map +0 -1
- package/lib/createRemoteCacheClient.js +0 -27
- package/lib/createRemoteCacheClient.js.map +0 -1
- package/lib/decorators/InMemoryDecorator.d.ts.map +0 -1
- package/lib/decorators/InMemoryDecorator.js +0 -29
- package/lib/decorators/InMemoryDecorator.js.map +0 -1
- package/lib/decorators/ReporterDecorator.d.ts.map +0 -1
- package/lib/decorators/ReporterDecorator.js +0 -121
- package/lib/decorators/ReporterDecorator.js.map +0 -1
- package/lib/decorators/RetryDecorator.d.ts.map +0 -1
- package/lib/decorators/RetryDecorator.js +0 -27
- package/lib/decorators/RetryDecorator.js.map +0 -1
- package/lib/getListOfBlobs.d.ts.map +0 -1
- package/lib/getListOfBlobs.js +0 -15
- package/lib/getListOfBlobs.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -2
- package/lib/index.js.map +0 -1
- package/lib/retry/blockListIsInvalidRetryPolicy.d.ts.map +0 -1
- package/lib/retry/blockListIsInvalidRetryPolicy.js +0 -8
- package/lib/retry/blockListIsInvalidRetryPolicy.js.map +0 -1
- package/lib/tsdoc-metadata.json +0 -11
- package/lib/types/LoginMethod.d.ts.map +0 -1
- package/lib/types/LoginMethod.js +0 -2
- package/lib/types/LoginMethod.js.map +0 -1
- package/lib/types/PackageToSync.d.ts +0 -7
- package/lib/types/PackageToSync.d.ts.map +0 -1
- package/lib/types/PackageToSync.js +0 -2
- package/lib/types/PackageToSync.js.map +0 -1
- package/lib/types/RemoteCacheClient.d.ts.map +0 -1
- package/lib/types/RemoteCacheClient.js +0 -2
- package/lib/types/RemoteCacheClient.js.map +0 -1
- package/lib/types/RemoteCacheClientOptions.d.ts.map +0 -1
- package/lib/types/RemoteCacheClientOptions.js +0 -2
- package/lib/types/RemoteCacheClientOptions.js.map +0 -1
- package/lib/types/RetryPolicy.d.ts.map +0 -1
- package/lib/types/RetryPolicy.js +0 -2
- package/lib/types/RetryPolicy.js.map +0 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createBlobStorageUrl
|
|
3
|
+
} from "./chunk-XKOU5VXX.js";
|
|
4
|
+
import {
|
|
5
|
+
require_dist
|
|
6
|
+
} from "./chunk-G3ME7OWS.js";
|
|
7
|
+
import "./chunk-KKZU5JW4.js";
|
|
8
|
+
import {
|
|
9
|
+
__toESM
|
|
10
|
+
} from "./chunk-GFT2G5UO.js";
|
|
11
|
+
|
|
12
|
+
// src/getListOfBlobs.ts
|
|
13
|
+
var import_storage_blob = __toESM(require_dist(), 1);
|
|
14
|
+
async function getListOfBlobs({ container, storageAccount, credential }) {
|
|
15
|
+
const blobStorageClient = new import_storage_blob.BlobServiceClient(createBlobStorageUrl(storageAccount), credential);
|
|
16
|
+
const containerClient = blobStorageClient.getContainerClient(container);
|
|
17
|
+
const blobs = /* @__PURE__ */ new Set();
|
|
18
|
+
for await (const blob of containerClient.listBlobsFlat()) {
|
|
19
|
+
blobs.add(blob.name);
|
|
20
|
+
}
|
|
21
|
+
return blobs;
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
getListOfBlobs
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=getListOfBlobs-LKU62UR5.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/getListOfBlobs.ts"],
|
|
4
|
+
"sourcesContent": ["import { createBlobStorageUrl } from './createBlobStorageUrl.js';\nimport type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';\nimport { BlobServiceClient } from '@azure/storage-blob';\n\n/**\n * Gets all the blobs in the remote cache.\n */\nexport async function getListOfBlobs({ container, storageAccount, credential }: RemoteCacheClientOptions) {\n const blobStorageClient = new BlobServiceClient(createBlobStorageUrl(storageAccount), credential);\n const containerClient = blobStorageClient.getContainerClient(container);\n const blobs = new Set<string>();\n for await (const blob of containerClient.listBlobsFlat()) {\n blobs.add(blob.name);\n }\n return blobs;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;AAEA,0BAAkC;AAKlC,eAAsB,eAAe,EAAE,WAAW,gBAAgB,WAAW,GAA6B;AACxG,QAAM,oBAAoB,IAAI,sCAAkB,qBAAqB,cAAc,GAAG,UAAU;AAChG,QAAM,kBAAkB,kBAAkB,mBAAmB,SAAS;AACtE,QAAM,QAAQ,oBAAI,IAAY;AAC9B,mBAAiB,QAAQ,gBAAgB,cAAc,GAAG;AACxD,UAAM,IAAI,KAAK,IAAI;AAAA,EACrB;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import "./chunk-GFT2G5UO.js";
|
|
2
|
+
|
|
3
|
+
// src/decorators/InMemoryDecorator.ts
|
|
4
|
+
var InMemoryDecorator = class {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.cacheClient = options.cacheClient;
|
|
7
|
+
this.list = options.getList();
|
|
8
|
+
}
|
|
9
|
+
async uploadFolder(options) {
|
|
10
|
+
if ((await this.list).has(options.id)) {
|
|
11
|
+
return "already-exist";
|
|
12
|
+
}
|
|
13
|
+
const result = await this.cacheClient.uploadFolder(options);
|
|
14
|
+
if (result === "success") {
|
|
15
|
+
(await this.list).add(options.id);
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
async downloadFolder(options) {
|
|
20
|
+
if (!(await this.list).has(options.id)) {
|
|
21
|
+
return "not-found";
|
|
22
|
+
}
|
|
23
|
+
return this.cacheClient.downloadFolder(options);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// src/decorators/RetryDecorator.ts
|
|
28
|
+
var RetryDecorator = class {
|
|
29
|
+
constructor(options) {
|
|
30
|
+
this.cacheClient = options.cacheClient;
|
|
31
|
+
this.retryManager = options.retryManager;
|
|
32
|
+
}
|
|
33
|
+
printRetryContext(operationName, options, retryContext) {
|
|
34
|
+
if (retryContext) {
|
|
35
|
+
console.warn(
|
|
36
|
+
`Retrying ${operationName} ${options.friendlyName} ... [${retryContext.retryAttempt}/${retryContext.maxRetries}]`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async uploadFolder(options) {
|
|
41
|
+
return this.retryManager.retry((retryContext) => {
|
|
42
|
+
this.printRetryContext("upload", options, retryContext);
|
|
43
|
+
return this.cacheClient.uploadFolder(options);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async downloadFolder(options) {
|
|
47
|
+
return this.retryManager.retry((retryContext) => {
|
|
48
|
+
this.printRetryContext("download", options, retryContext);
|
|
49
|
+
return this.cacheClient.downloadFolder(options);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// src/retry/blockListIsInvalidRetryPolicy.ts
|
|
55
|
+
var blockListIsInvalidRetryPolicy = {
|
|
56
|
+
maxRetries: 1,
|
|
57
|
+
handle: (error) => {
|
|
58
|
+
return error instanceof Error && error.message.indexOf("The specified block list is invalid.") > -1;
|
|
59
|
+
},
|
|
60
|
+
wait: () => 0
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// src/createRemoteCacheClient.ts
|
|
64
|
+
import { RetryManager } from "@ms-cloudpack/retry";
|
|
65
|
+
async function createRemoteCacheClient(params) {
|
|
66
|
+
const { context, options } = params;
|
|
67
|
+
const { container, loginMethod, storageAccount, cachePath } = options;
|
|
68
|
+
const { getCredential } = await import("./getCredential-MJEIGDVB.js");
|
|
69
|
+
const { AzureRemoteCacheClient } = await import("./AzureRemoteCacheClient-2PRAPCJH.js");
|
|
70
|
+
const { ReporterDecorator } = await import("./ReporterDecorator-BYNXV72I.js");
|
|
71
|
+
const { getListOfBlobs } = await import("./getListOfBlobs-LKU62UR5.js");
|
|
72
|
+
const credential = await getCredential(loginMethod, cachePath);
|
|
73
|
+
const remoteCacheClientOptions = {
|
|
74
|
+
storageAccount,
|
|
75
|
+
container,
|
|
76
|
+
credential
|
|
77
|
+
};
|
|
78
|
+
const client = new ReporterDecorator(
|
|
79
|
+
new RetryDecorator({
|
|
80
|
+
retryManager: new RetryManager([blockListIsInvalidRetryPolicy]),
|
|
81
|
+
cacheClient: new InMemoryDecorator({
|
|
82
|
+
cacheClient: new AzureRemoteCacheClient(remoteCacheClientOptions),
|
|
83
|
+
getList: () => getListOfBlobs(remoteCacheClientOptions)
|
|
84
|
+
})
|
|
85
|
+
}),
|
|
86
|
+
context
|
|
87
|
+
);
|
|
88
|
+
return client;
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
createRemoteCacheClient
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/decorators/InMemoryDecorator.ts", "../src/decorators/RetryDecorator.ts", "../src/retry/blockListIsInvalidRetryPolicy.ts", "../src/createRemoteCacheClient.ts"],
|
|
4
|
+
"sourcesContent": ["import type {\n RemoteCacheClient,\n RemoteCacheClientUploadOperationOptions,\n RemoteCacheClientOperationOptions,\n RemoteCacheClientOperationResult,\n} from '../types/RemoteCacheClient.js';\n\n/**\n * A decorator for a RemoteCacheClient that keeps a list of remote resources locally.\n */\nexport class InMemoryDecorator implements RemoteCacheClient {\n private readonly cacheClient: RemoteCacheClient;\n private readonly list: Promise<Set<string>>;\n\n constructor(options: { cacheClient: RemoteCacheClient; getList: () => Promise<Set<string>> }) {\n this.cacheClient = options.cacheClient;\n this.list = options.getList();\n }\n\n async uploadFolder(options: RemoteCacheClientUploadOperationOptions): Promise<RemoteCacheClientOperationResult> {\n if ((await this.list).has(options.id)) {\n // This resource already exists in the remote cache, no need to upload it again.\n return 'already-exist';\n }\n\n const result = await this.cacheClient.uploadFolder(options);\n\n if (result === 'success') {\n // The upload is successful, add the resource to the list.\n (await this.list).add(options.id);\n }\n\n return result;\n }\n\n async downloadFolder(options: RemoteCacheClientOperationOptions): Promise<RemoteCacheClientOperationResult> {\n if (!(await this.list).has(options.id)) {\n // This resource doesn't exist in the remote cache, can't download it.\n return 'not-found';\n }\n\n return this.cacheClient.downloadFolder(options);\n }\n}\n", "import type {\n RemoteCacheClient,\n RemoteCacheClientUploadOperationOptions,\n RemoteCacheClientOperationOptions,\n RemoteCacheClientOperationResult,\n} from '../types/RemoteCacheClient.js';\nimport type { RetryManager } from '@ms-cloudpack/retry';\n\n/**\n * A decorator that retries the upload/download operation if it fails.\n */\nexport class RetryDecorator implements RemoteCacheClient {\n private readonly cacheClient: RemoteCacheClient;\n private readonly retryManager: RetryManager;\n\n constructor(options: { cacheClient: RemoteCacheClient; retryManager: RetryManager }) {\n this.cacheClient = options.cacheClient;\n this.retryManager = options.retryManager;\n }\n\n private printRetryContext(\n operationName: string,\n options: RemoteCacheClientOperationOptions,\n retryContext?: { retryAttempt: number; maxRetries: number },\n ) {\n if (retryContext) {\n console.warn(\n `Retrying ${operationName} ${options.friendlyName} ... [${retryContext.retryAttempt}/${retryContext.maxRetries}]`,\n );\n }\n }\n\n async uploadFolder(options: RemoteCacheClientUploadOperationOptions): Promise<RemoteCacheClientOperationResult> {\n return this.retryManager.retry((retryContext) => {\n this.printRetryContext('upload', options, retryContext);\n return this.cacheClient.uploadFolder(options);\n });\n }\n\n async downloadFolder(options: RemoteCacheClientOperationOptions): Promise<RemoteCacheClientOperationResult> {\n return this.retryManager.retry((retryContext) => {\n this.printRetryContext('download', options, retryContext);\n return this.cacheClient.downloadFolder(options);\n });\n }\n}\n", "import type { RetryPolicy } from '../types/RetryPolicy.js';\n\nexport const blockListIsInvalidRetryPolicy: RetryPolicy = {\n maxRetries: 1,\n handle: (error) => {\n return error instanceof Error && error.message.indexOf('The specified block list is invalid.') > -1;\n },\n wait: () => 0,\n};\n", "import type { TaskReporter } from '@ms-cloudpack/task-reporter';\nimport { InMemoryDecorator } from './decorators/InMemoryDecorator.js';\nimport type { RemoteCacheClient } from './types/RemoteCacheClient.js';\nimport { RetryDecorator } from './decorators/RetryDecorator.js';\nimport { blockListIsInvalidRetryPolicy } from './retry/blockListIsInvalidRetryPolicy.js';\nimport { RetryManager } from '@ms-cloudpack/retry';\nimport type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';\nimport type { TelemetryClient } from '@ms-cloudpack/telemetry';\nimport type { LoginMethod } from './types/LoginMethod.js';\n\nexport interface CreateRemoteCacheClientParams {\n options: {\n storageAccount: string;\n container: string;\n loginMethod: LoginMethod;\n cachePath: string;\n };\n context: {\n reporter: TaskReporter;\n telemetryClient: TelemetryClient;\n };\n}\n\nexport async function createRemoteCacheClient(params: CreateRemoteCacheClientParams): Promise<RemoteCacheClient> {\n const { context, options } = params;\n const { container, loginMethod, storageAccount, cachePath } = options;\n\n const { getCredential } = await import('./authentication/getCredential.js');\n const { AzureRemoteCacheClient } = await import('./AzureRemoteCacheClient.js');\n const { ReporterDecorator } = await import('./decorators/ReporterDecorator.js');\n const { getListOfBlobs } = await import('./getListOfBlobs.js');\n\n const credential = await getCredential(loginMethod, cachePath);\n\n const remoteCacheClientOptions: RemoteCacheClientOptions = {\n storageAccount,\n container,\n credential,\n };\n\n const client = new ReporterDecorator(\n new RetryDecorator({\n retryManager: new RetryManager([blockListIsInvalidRetryPolicy]),\n cacheClient: new InMemoryDecorator({\n cacheClient: new AzureRemoteCacheClient(remoteCacheClientOptions),\n getList: () => getListOfBlobs(remoteCacheClientOptions),\n }),\n }),\n context,\n );\n\n return client;\n}\n"],
|
|
5
|
+
"mappings": ";;;AAUO,IAAM,oBAAN,MAAqD;AAAA,EAI1D,YAAY,SAAkF;AAC5F,SAAK,cAAc,QAAQ;AAC3B,SAAK,OAAO,QAAQ,QAAQ;AAAA,EAC9B;AAAA,EAEA,MAAM,aAAa,SAA6F;AAC9G,SAAK,MAAM,KAAK,MAAM,IAAI,QAAQ,EAAE,GAAG;AAErC,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,MAAM,KAAK,YAAY,aAAa,OAAO;AAE1D,QAAI,WAAW,WAAW;AAExB,OAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,EAAE;AAAA,IAClC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,SAAuF;AAC1G,QAAI,EAAE,MAAM,KAAK,MAAM,IAAI,QAAQ,EAAE,GAAG;AAEtC,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,YAAY,eAAe,OAAO;AAAA,EAChD;AACF;;;AChCO,IAAM,iBAAN,MAAkD;AAAA,EAIvD,YAAY,SAAyE;AACnF,SAAK,cAAc,QAAQ;AAC3B,SAAK,eAAe,QAAQ;AAAA,EAC9B;AAAA,EAEQ,kBACN,eACA,SACA,cACA;AACA,QAAI,cAAc;AAChB,cAAQ;AAAA,QACN,YAAY,aAAa,IAAI,QAAQ,YAAY,SAAS,aAAa,YAAY,IAAI,aAAa,UAAU;AAAA,MAChH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,SAA6F;AAC9G,WAAO,KAAK,aAAa,MAAM,CAAC,iBAAiB;AAC/C,WAAK,kBAAkB,UAAU,SAAS,YAAY;AACtD,aAAO,KAAK,YAAY,aAAa,OAAO;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,SAAuF;AAC1G,WAAO,KAAK,aAAa,MAAM,CAAC,iBAAiB;AAC/C,WAAK,kBAAkB,YAAY,SAAS,YAAY;AACxD,aAAO,KAAK,YAAY,eAAe,OAAO;AAAA,IAChD,CAAC;AAAA,EACH;AACF;;;AC3CO,IAAM,gCAA6C;AAAA,EACxD,YAAY;AAAA,EACZ,QAAQ,CAAC,UAAU;AACjB,WAAO,iBAAiB,SAAS,MAAM,QAAQ,QAAQ,sCAAsC,IAAI;AAAA,EACnG;AAAA,EACA,MAAM,MAAM;AACd;;;ACHA,SAAS,oBAAoB;AAkB7B,eAAsB,wBAAwB,QAAmE;AAC/G,QAAM,EAAE,SAAS,QAAQ,IAAI;AAC7B,QAAM,EAAE,WAAW,aAAa,gBAAgB,UAAU,IAAI;AAE9D,QAAM,EAAE,cAAc,IAAI,MAAM,OAAO,6BAAmC;AAC1E,QAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,sCAA6B;AAC7E,QAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,iCAAmC;AAC9E,QAAM,EAAE,eAAe,IAAI,MAAM,OAAO,8BAAqB;AAE7D,QAAM,aAAa,MAAM,cAAc,aAAa,SAAS;AAE7D,QAAM,2BAAqD;AAAA,IACzD;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAAS,IAAI;AAAA,IACjB,IAAI,eAAe;AAAA,MACjB,cAAc,IAAI,aAAa,CAAC,6BAA6B,CAAC;AAAA,MAC9D,aAAa,IAAI,kBAAkB;AAAA,QACjC,aAAa,IAAI,uBAAuB,wBAAwB;AAAA,QAChE,SAAS,MAAM,eAAe,wBAAwB;AAAA,MACxD,CAAC;AAAA,IACH,CAAC;AAAA,IACD;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';
|
|
2
|
-
import type { RemoteCacheClient, RemoteCacheClientOperationOptions,
|
|
2
|
+
import type { RemoteCacheClient, RemoteCacheClientOperationOptions, RemoteCacheClientUploadOperationOptions } from './types/RemoteCacheClient.js';
|
|
3
3
|
export declare class AzureRemoteCacheClient implements RemoteCacheClient {
|
|
4
4
|
private readonly logger;
|
|
5
5
|
private readonly config;
|
|
6
6
|
constructor({ container, storageAccount, credential }: RemoteCacheClientOptions);
|
|
7
7
|
/**
|
|
8
8
|
* Uploads the folder to the remote cache.
|
|
9
|
-
* @param
|
|
9
|
+
* @param id - The unique identifier of the asset to upload.
|
|
10
10
|
* @param path - The path to the folder to upload.
|
|
11
11
|
* @param globMatches - The glob pattern to use when uploading the folder.
|
|
12
12
|
* @returns - A promise that resolves when the folder has been uploaded.
|
|
13
13
|
*/
|
|
14
|
-
uploadFolder({
|
|
14
|
+
uploadFolder({ id, path, globMatches }: RemoteCacheClientUploadOperationOptions): Promise<"success" | "not-found">;
|
|
15
15
|
/**
|
|
16
16
|
* Downloads the folder from the remote cache.
|
|
17
|
-
* @param
|
|
17
|
+
* @param id - The unique identifier of the asset to download.
|
|
18
18
|
* @param path - The path to download the folder to.
|
|
19
19
|
* @returns - A promise that resolves when the folder has been downloaded.
|
|
20
20
|
*/
|
|
21
|
-
downloadFolder({
|
|
21
|
+
downloadFolder({ id, path }: RemoteCacheClientOperationOptions): Promise<"success" | "not-found" | "already-exist">;
|
|
22
22
|
}
|
|
23
23
|
//# sourceMappingURL=AzureRemoteCacheClient.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RemoteCacheClient,
|
|
1
|
+
import type { RemoteCacheClient, RemoteCacheClientUploadOperationOptions, RemoteCacheClientOperationOptions, RemoteCacheClientOperationResult } from '../types/RemoteCacheClient.js';
|
|
2
2
|
/**
|
|
3
3
|
* A decorator for a RemoteCacheClient that keeps a list of remote resources locally.
|
|
4
4
|
*/
|
|
@@ -9,7 +9,7 @@ export declare class InMemoryDecorator implements RemoteCacheClient {
|
|
|
9
9
|
cacheClient: RemoteCacheClient;
|
|
10
10
|
getList: () => Promise<Set<string>>;
|
|
11
11
|
});
|
|
12
|
-
uploadFolder(options:
|
|
12
|
+
uploadFolder(options: RemoteCacheClientUploadOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
13
13
|
downloadFolder(options: RemoteCacheClientOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
14
14
|
}
|
|
15
15
|
//# sourceMappingURL=InMemoryDecorator.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type TaskReporter } from '@ms-cloudpack/task-reporter';
|
|
2
|
-
import type { RemoteCacheClient,
|
|
2
|
+
import type { RemoteCacheClient, RemoteCacheClientUploadOperationOptions, RemoteCacheClientOperationOptions, RemoteCacheClientOperationResult } from '../types/RemoteCacheClient.js';
|
|
3
3
|
import type { TelemetryClient } from '@ms-cloudpack/telemetry';
|
|
4
4
|
export declare class ReporterDecorator implements RemoteCacheClient {
|
|
5
5
|
private readonly client;
|
|
@@ -9,7 +9,7 @@ export declare class ReporterDecorator implements RemoteCacheClient {
|
|
|
9
9
|
telemetryClient: TelemetryClient;
|
|
10
10
|
});
|
|
11
11
|
private buildFailureMessage;
|
|
12
|
-
uploadFolder(options:
|
|
12
|
+
uploadFolder(options: RemoteCacheClientUploadOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
13
13
|
downloadFolder(options: RemoteCacheClientOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
14
14
|
}
|
|
15
15
|
//# sourceMappingURL=ReporterDecorator.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RemoteCacheClient,
|
|
1
|
+
import type { RemoteCacheClient, RemoteCacheClientUploadOperationOptions, RemoteCacheClientOperationOptions, RemoteCacheClientOperationResult } from '../types/RemoteCacheClient.js';
|
|
2
2
|
import type { RetryManager } from '@ms-cloudpack/retry';
|
|
3
3
|
/**
|
|
4
4
|
* A decorator that retries the upload/download operation if it fails.
|
|
@@ -11,7 +11,7 @@ export declare class RetryDecorator implements RemoteCacheClient {
|
|
|
11
11
|
retryManager: RetryManager;
|
|
12
12
|
});
|
|
13
13
|
private printRetryContext;
|
|
14
|
-
uploadFolder(options:
|
|
14
|
+
uploadFolder(options: RemoteCacheClientUploadOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
15
15
|
downloadFolder(options: RemoteCacheClientOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=RetryDecorator.d.ts.map
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createRemoteCacheClient, type CreateRemoteCacheClientParams } from './createRemoteCacheClient.js';
|
|
2
|
-
export type { RemoteCacheClient, RemoteCacheClientDownloadOperationOptions, RemoteCacheClientOperationOptions, RemoteCacheClientOperationResult, } from './types/RemoteCacheClient.js';
|
|
2
|
+
export type { RemoteCacheClient, RemoteCacheClientUploadOperationOptions as RemoteCacheClientDownloadOperationOptions, RemoteCacheClientOperationOptions, RemoteCacheClientOperationResult, } from './types/RemoteCacheClient.js';
|
|
3
3
|
export type { LoginMethod } from './types/LoginMethod.js';
|
|
4
4
|
export type { RemoteCacheClientOptions } from './types/RemoteCacheClientOptions.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
export type RemoteCacheClientOperationResult = 'success' | 'not-found' | 'already-exist';
|
|
2
2
|
export interface RemoteCacheClientOperationOptions {
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The unique identifier of the asset
|
|
5
|
+
*/
|
|
6
|
+
id: string;
|
|
7
|
+
/**
|
|
8
|
+
* Local path to the asset
|
|
9
|
+
*/
|
|
4
10
|
path: string;
|
|
11
|
+
/**
|
|
12
|
+
* The friendly name of the asset to be used in logs
|
|
13
|
+
*/
|
|
5
14
|
friendlyName: string;
|
|
6
15
|
}
|
|
7
|
-
export interface
|
|
16
|
+
export interface RemoteCacheClientUploadOperationOptions extends RemoteCacheClientOperationOptions {
|
|
8
17
|
globMatches: string[];
|
|
9
18
|
}
|
|
10
19
|
export interface RemoteCacheClient {
|
|
11
|
-
uploadFolder(options:
|
|
20
|
+
uploadFolder(options: RemoteCacheClientUploadOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
12
21
|
downloadFolder(options: RemoteCacheClientOperationOptions): Promise<RemoteCacheClientOperationResult>;
|
|
13
22
|
}
|
|
14
23
|
//# sourceMappingURL=RemoteCacheClient.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ms-cloudpack/remote-cache",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1-beta.0",
|
|
4
4
|
"description": "Manages syncing the local Cloudpack cached assets to/from a remote storage service.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,34 +10,34 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"source": "./src/index.ts",
|
|
12
12
|
"types": "./lib/index.d.ts",
|
|
13
|
-
"import": "./
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
-
"devDependencies": {
|
|
17
|
-
"@ms-cloudpack/eslint-plugin-internal": "*",
|
|
18
|
-
"@ms-cloudpack/scripts": "*",
|
|
19
|
-
"uuid": "^9.0.0"
|
|
20
|
-
},
|
|
21
16
|
"scripts": {
|
|
22
17
|
"api": "cloudpack-scripts api",
|
|
23
18
|
"build:watch": "cloudpack-scripts build-watch",
|
|
24
|
-
"build": "cloudpack-scripts build",
|
|
19
|
+
"build": "cloudpack-scripts build && cloudpack-scripts bundle",
|
|
25
20
|
"lint:update": "cloudpack-scripts lint-update",
|
|
26
21
|
"lint": "cloudpack-scripts lint",
|
|
27
22
|
"test:watch": "cloudpack-scripts test-watch",
|
|
28
23
|
"test": "cloudpack-scripts test"
|
|
29
24
|
},
|
|
30
25
|
"files": [
|
|
31
|
-
"
|
|
26
|
+
"dist",
|
|
27
|
+
"lib/**/*.d.ts"
|
|
32
28
|
],
|
|
33
29
|
"dependencies": {
|
|
34
|
-
"@azure/msal-node": "^2.6.0",
|
|
35
30
|
"@azure/msal-node-extensions": "^1.0.10",
|
|
36
31
|
"@ms-cloudpack/task-reporter": "^0.11.1",
|
|
37
|
-
"@ms-cloudpack/telemetry": "^0.4.
|
|
38
|
-
"@ms-cloudpack/retry": "^0.1.1"
|
|
39
|
-
|
|
32
|
+
"@ms-cloudpack/telemetry": "^0.4.7-beta.0",
|
|
33
|
+
"@ms-cloudpack/retry": "^0.1.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@azure/identity": "^3.3.0",
|
|
40
37
|
"@azure/storage-blob": "^12.17.0",
|
|
38
|
+
"@azure/msal-node": "^2.6.0",
|
|
39
|
+
"@ms-cloudpack/eslint-plugin-internal": "*",
|
|
40
|
+
"@ms-cloudpack/scripts": "*",
|
|
41
41
|
"backfill": "^6.2.1",
|
|
42
42
|
"backfill-config": "^6.4.1"
|
|
43
43
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AzureRemoteCacheClient.d.ts","sourceRoot":"","sources":["../src/AzureRemoteCacheClient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAGpF,OAAO,KAAK,EACV,iBAAiB,EACjB,iCAAiC,EACjC,yCAAyC,EAC1C,MAAM,8BAA8B,CAAC;AAGtC,qBAAa,sBAAuB,YAAW,iBAAiB;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsD;IAC7E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAIrB;gBAEU,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,EAAE,wBAAwB;IAe/E;;;;;;OAMG;IACG,YAAY,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,yCAAyC;IAS/F;;;;;OAKG;IACG,cAAc,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,iCAAiC;CAY7E"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { makeLogger, put, fetch } from 'backfill/lib/api.js';
|
|
2
|
-
import { existsSync } from 'fs';
|
|
3
|
-
import { createBlobStorageUrl } from './createBlobStorageUrl.js';
|
|
4
|
-
export class AzureRemoteCacheClient {
|
|
5
|
-
constructor({ container, storageAccount, credential }) {
|
|
6
|
-
this.logger = makeLogger('mute', process.stdout, process.stderr);
|
|
7
|
-
this.config = {
|
|
8
|
-
incrementalCaching: true,
|
|
9
|
-
internalCacheFolder: '', // not used by azure-blob
|
|
10
|
-
cacheStorageConfig: {
|
|
11
|
-
provider: 'azure-blob',
|
|
12
|
-
options: {
|
|
13
|
-
connectionString: createBlobStorageUrl(storageAccount),
|
|
14
|
-
credential,
|
|
15
|
-
container,
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Uploads the folder to the remote cache.
|
|
22
|
-
* @param folderName - The name of the folder to upload.
|
|
23
|
-
* @param path - The path to the folder to upload.
|
|
24
|
-
* @param globMatches - The glob pattern to use when uploading the folder.
|
|
25
|
-
* @returns - A promise that resolves when the folder has been uploaded.
|
|
26
|
-
*/
|
|
27
|
-
async uploadFolder({ folderName, path, globMatches }) {
|
|
28
|
-
if (!existsSync(path)) {
|
|
29
|
-
return 'not-found';
|
|
30
|
-
}
|
|
31
|
-
await put(path, folderName, this.logger, { ...this.config, outputGlob: globMatches });
|
|
32
|
-
return 'success';
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Downloads the folder from the remote cache.
|
|
36
|
-
* @param folderName - The name of the folder to download.
|
|
37
|
-
* @param path - The path to download the folder to.
|
|
38
|
-
* @returns - A promise that resolves when the folder has been downloaded.
|
|
39
|
-
*/
|
|
40
|
-
async downloadFolder({ folderName, path }) {
|
|
41
|
-
if (existsSync(path)) {
|
|
42
|
-
return 'already-exist';
|
|
43
|
-
}
|
|
44
|
-
const result = await fetch(path, folderName, this.logger, this.config);
|
|
45
|
-
if (!result) {
|
|
46
|
-
return 'not-found';
|
|
47
|
-
}
|
|
48
|
-
return 'success';
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=AzureRemoteCacheClient.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AzureRemoteCacheClient.js","sourceRoot":"","sources":["../src/AzureRemoteCacheClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG7D,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAMhC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,OAAO,sBAAsB;IAQjC,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAA4B;QAP9D,WAAM,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAQ3E,IAAI,CAAC,MAAM,GAAG;YACZ,kBAAkB,EAAE,IAAI;YACxB,mBAAmB,EAAE,EAAE,EAAE,yBAAyB;YAClD,kBAAkB,EAAE;gBAClB,QAAQ,EAAE,YAAY;gBACtB,OAAO,EAAE;oBACP,gBAAgB,EAAE,oBAAoB,CAAC,cAAc,CAAC;oBACtD,UAAU;oBACV,SAAS;iBACV;aACF;SACF,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAA6C;QAC7F,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC;QACtF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,IAAI,EAAqC;QAC1E,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,eAAe,CAAC;QACzB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,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';\nimport { existsSync } from 'fs';\nimport type {\n RemoteCacheClient,\n RemoteCacheClientOperationOptions,\n RemoteCacheClientDownloadOperationOptions,\n} from './types/RemoteCacheClient.js';\nimport { createBlobStorageUrl } from './createBlobStorageUrl.js';\n\nexport class AzureRemoteCacheClient implements 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 };\n\n constructor({ container, storageAccount, credential }: RemoteCacheClientOptions) {\n this.config = {\n incrementalCaching: true,\n internalCacheFolder: '', // not used by azure-blob\n cacheStorageConfig: {\n provider: 'azure-blob',\n options: {\n connectionString: createBlobStorageUrl(storageAccount),\n credential,\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 * @param globMatches - The glob pattern to use when uploading the folder.\n * @returns - A promise that resolves when the folder has been uploaded.\n */\n async uploadFolder({ folderName, path, globMatches }: RemoteCacheClientDownloadOperationOptions) {\n if (!existsSync(path)) {\n return 'not-found';\n }\n\n await put(path, folderName, this.logger, { ...this.config, outputGlob: globMatches });\n return 'success';\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 async downloadFolder({ folderName, path }: RemoteCacheClientOperationOptions) {\n if (existsSync(path)) {\n return 'already-exist';\n }\n\n const result = await fetch(path, folderName, this.logger, this.config);\n if (!result) {\n return 'not-found';\n }\n\n return 'success';\n }\n}\n"]}
|
package/lib/Task.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Task.d.ts","sourceRoot":"","sources":["../src/Task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAChD"}
|
package/lib/Task.js
DELETED
package/lib/Task.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Task.js","sourceRoot":"","sources":["../src/Task.ts"],"names":[],"mappings":"","sourcesContent":["import type { TaskReporterTaskResult } from '@ms-cloudpack/task-reporter';\n\nexport interface Task {\n name: string;\n execute: () => Promise<TaskReporterTaskResult>;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getAuthenticationRecord.d.ts","sourceRoot":"","sources":["../../src/authentication/getAuthenticationRecord.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,8DAQxD"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { deserializeAuthenticationRecord } from '@azure/identity';
|
|
2
|
-
import { existsSync, readFileSync } from 'fs';
|
|
3
|
-
import { getAuthenticationRecordPath } from './getAuthenticationRecordPath.js';
|
|
4
|
-
/**
|
|
5
|
-
* Retrieves the authentication record from Cloudpack's global cache folder.
|
|
6
|
-
* @param cachePath - The path to Cloudpack's cache folder.
|
|
7
|
-
* @returns - The authentication record if it exists; otherwise, returns `undefined`.
|
|
8
|
-
*/
|
|
9
|
-
export function getAuthenticationRecord(cachePath) {
|
|
10
|
-
const fullPath = getAuthenticationRecordPath(cachePath);
|
|
11
|
-
if (!existsSync(fullPath)) {
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
const content = readFileSync(fullPath, 'utf-8');
|
|
15
|
-
return deserializeAuthenticationRecord(content);
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=getAuthenticationRecord.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getAuthenticationRecord.js","sourceRoot":"","sources":["../../src/authentication/getAuthenticationRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,MAAM,QAAQ,GAAG,2BAA2B,CAAC,SAAS,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,OAAO,+BAA+B,CAAC,OAAO,CAAC,CAAC;AAClD,CAAC","sourcesContent":["import { deserializeAuthenticationRecord } from '@azure/identity';\nimport { existsSync, readFileSync } from 'fs';\nimport { getAuthenticationRecordPath } from './getAuthenticationRecordPath.js';\n\n/**\n * Retrieves the authentication record from Cloudpack's global cache folder.\n * @param cachePath - The path to Cloudpack's cache folder.\n * @returns - The authentication record if it exists; otherwise, returns `undefined`.\n */\nexport function getAuthenticationRecord(cachePath: string) {\n const fullPath = getAuthenticationRecordPath(cachePath);\n if (!existsSync(fullPath)) {\n return undefined;\n }\n\n const content = readFileSync(fullPath, 'utf-8');\n return deserializeAuthenticationRecord(content);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getAuthenticationRecordPath.d.ts","sourceRoot":"","sources":["../../src/authentication/getAuthenticationRecordPath.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,UAE5D"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
/**
|
|
3
|
-
* Constructs and returns the full path to the authentication record file within the specified cache folder.
|
|
4
|
-
* @param cachePath - The path to Cloudpack's cache folder.
|
|
5
|
-
* @returns - The full path to the authentication record file.
|
|
6
|
-
*/
|
|
7
|
-
export function getAuthenticationRecordPath(cachePath) {
|
|
8
|
-
return path.join(cachePath, 'tokencache.bin');
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=getAuthenticationRecordPath.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getAuthenticationRecordPath.js","sourceRoot":"","sources":["../../src/authentication/getAuthenticationRecordPath.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,SAAiB;IAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;AAChD,CAAC","sourcesContent":["import path from 'path';\n\n/**\n * Constructs and returns the full path to the authentication record file within the specified cache folder.\n * @param cachePath - The path to Cloudpack's cache folder.\n * @returns - The full path to the authentication record file.\n */\nexport function getAuthenticationRecordPath(cachePath: string) {\n return path.join(cachePath, 'tokencache.bin');\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getCredential.d.ts","sourceRoot":"","sources":["../../src/authentication/getCredential.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA4B3D;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,4BAwC9E"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { AzureCliCredential, DeviceCodeCredential, InteractiveBrowserCredential, useIdentityPlugin, } from '@azure/identity';
|
|
2
|
-
import { cachePersistencePlugin } from '../cache-persistance/cachePersistencePlugin.js';
|
|
3
|
-
import { getAuthenticationRecord } from './getAuthenticationRecord.js';
|
|
4
|
-
import { saveAuthenticationRecord } from './saveAuthenticationRecord.js';
|
|
5
|
-
const tokenCachePersistenceOptions = {
|
|
6
|
-
enabled: true,
|
|
7
|
-
name: 'cloudpack',
|
|
8
|
-
};
|
|
9
|
-
function getCredentialInternal(loginMethod, authenticationRecord) {
|
|
10
|
-
switch (loginMethod) {
|
|
11
|
-
case 'interactive':
|
|
12
|
-
return new InteractiveBrowserCredential({
|
|
13
|
-
redirectUri: 'http://localhost:1337',
|
|
14
|
-
authenticationRecord,
|
|
15
|
-
tokenCachePersistenceOptions,
|
|
16
|
-
});
|
|
17
|
-
case 'device-code':
|
|
18
|
-
return new DeviceCodeCredential({
|
|
19
|
-
authenticationRecord,
|
|
20
|
-
tokenCachePersistenceOptions,
|
|
21
|
-
});
|
|
22
|
-
default:
|
|
23
|
-
throw new Error(`Invalid login method: ${loginMethod}`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Gets a credential for the given login method.
|
|
28
|
-
* If the login method is 'azure-cli', it will return an AzureCliCredential.
|
|
29
|
-
* Otherwise, it will return an InteractiveBrowserCredential or a DeviceCodeCredential with persistent token settings.
|
|
30
|
-
* If an authentication record has never been saved before, it will authenticate the credential and save the authentication record.
|
|
31
|
-
*/
|
|
32
|
-
export async function getCredential(loginMethod, cachePath) {
|
|
33
|
-
if (loginMethod == 'azure-cli') {
|
|
34
|
-
return new AzureCliCredential();
|
|
35
|
-
}
|
|
36
|
-
useIdentityPlugin(cachePersistencePlugin);
|
|
37
|
-
let authenticationRecord = getAuthenticationRecord(cachePath);
|
|
38
|
-
const credential = getCredentialInternal(loginMethod, authenticationRecord);
|
|
39
|
-
if (!authenticationRecord) {
|
|
40
|
-
console.warn('Cloudpack requires authentication to access Azure resources.');
|
|
41
|
-
if (loginMethod == 'interactive') {
|
|
42
|
-
console.warn("Prepare to sign in – we're launching a browser page for you. Simply follow the instructions on the login page to seamlessly complete the authentication process.");
|
|
43
|
-
}
|
|
44
|
-
const storageScope = 'https://storage.azure.com/.default';
|
|
45
|
-
authenticationRecord = await credential.authenticate(storageScope);
|
|
46
|
-
const token = await credential.getToken(storageScope);
|
|
47
|
-
// Creating a custom credential with the token from the authentication record.
|
|
48
|
-
// This ensures that we can use the token without having to authenticate again. Otherwise, we may have to authenticate again to get the token which can create concurrency issues.
|
|
49
|
-
const storageCustomCredential = {
|
|
50
|
-
getToken: async () => {
|
|
51
|
-
return Promise.resolve(token);
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
if (authenticationRecord) {
|
|
55
|
-
saveAuthenticationRecord(cachePath, authenticationRecord);
|
|
56
|
-
}
|
|
57
|
-
return storageCustomCredential;
|
|
58
|
-
}
|
|
59
|
-
return credential;
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=getCredential.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getCredential.js","sourceRoot":"","sources":["../../src/authentication/getCredential.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,iBAAiB,GAIlB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,MAAM,4BAA4B,GAAiC;IACjE,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,WAAW;CAClB,CAAC;AAEF,SAAS,qBAAqB,CAAC,WAAwB,EAAE,oBAA2C;IAClG,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,aAAa;YAChB,OAAO,IAAI,4BAA4B,CAAC;gBACtC,WAAW,EAAE,uBAAuB;gBACpC,oBAAoB;gBACpB,4BAA4B;aAC7B,CAAC,CAAC;QACL,KAAK,aAAa;YAChB,OAAO,IAAI,oBAAoB,CAAC;gBAC9B,oBAAoB;gBACpB,4BAA4B;aAC7B,CAAC,CAAC;QACL;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAwB,EAAE,SAAiB;IAC7E,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;QAC/B,OAAO,IAAI,kBAAkB,EAAE,CAAC;IAClC,CAAC;IAED,iBAAiB,CAAC,sBAAsB,CAAC,CAAC;IAE1C,IAAI,oBAAoB,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAE9D,MAAM,UAAU,GAAG,qBAAqB,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAE5E,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;QAE7E,IAAI,WAAW,IAAI,aAAa,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CACV,kKAAkK,CACnK,CAAC;QACJ,CAAC;QAED,MAAM,YAAY,GAAG,oCAAoC,CAAC;QAC1D,oBAAoB,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAEtD,8EAA8E;QAC9E,kLAAkL;QAClL,MAAM,uBAAuB,GAAoB;YAC/C,QAAQ,EAAE,KAAK,IAAI,EAAE;gBACnB,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;SACF,CAAC;QAEF,IAAI,oBAAoB,EAAE,CAAC;YACzB,wBAAwB,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,uBAAuB,CAAC;IACjC,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import {\n AzureCliCredential,\n DeviceCodeCredential,\n InteractiveBrowserCredential,\n useIdentityPlugin,\n type AuthenticationRecord,\n type TokenCachePersistenceOptions,\n type TokenCredential,\n} from '@azure/identity';\nimport type { LoginMethod } from '../types/LoginMethod.js';\nimport { cachePersistencePlugin } from '../cache-persistance/cachePersistencePlugin.js';\nimport { getAuthenticationRecord } from './getAuthenticationRecord.js';\nimport { saveAuthenticationRecord } from './saveAuthenticationRecord.js';\n\nconst tokenCachePersistenceOptions: TokenCachePersistenceOptions = {\n enabled: true,\n name: 'cloudpack',\n};\n\nfunction getCredentialInternal(loginMethod: LoginMethod, authenticationRecord?: AuthenticationRecord) {\n switch (loginMethod) {\n case 'interactive':\n return new InteractiveBrowserCredential({\n redirectUri: 'http://localhost:1337',\n authenticationRecord,\n tokenCachePersistenceOptions,\n });\n case 'device-code':\n return new DeviceCodeCredential({\n authenticationRecord,\n tokenCachePersistenceOptions,\n });\n default:\n throw new Error(`Invalid login method: ${loginMethod}`);\n }\n}\n\n/**\n * Gets a credential for the given login method.\n * If the login method is 'azure-cli', it will return an AzureCliCredential.\n * Otherwise, it will return an InteractiveBrowserCredential or a DeviceCodeCredential with persistent token settings.\n * If an authentication record has never been saved before, it will authenticate the credential and save the authentication record.\n */\nexport async function getCredential(loginMethod: LoginMethod, cachePath: string) {\n if (loginMethod == 'azure-cli') {\n return new AzureCliCredential();\n }\n\n useIdentityPlugin(cachePersistencePlugin);\n\n let authenticationRecord = getAuthenticationRecord(cachePath);\n\n const credential = getCredentialInternal(loginMethod, authenticationRecord);\n\n if (!authenticationRecord) {\n console.warn('Cloudpack requires authentication to access Azure resources.');\n\n if (loginMethod == 'interactive') {\n console.warn(\n \"Prepare to sign in – we're launching a browser page for you. Simply follow the instructions on the login page to seamlessly complete the authentication process.\",\n );\n }\n\n const storageScope = 'https://storage.azure.com/.default';\n authenticationRecord = await credential.authenticate(storageScope);\n const token = await credential.getToken(storageScope);\n\n // Creating a custom credential with the token from the authentication record.\n // This ensures that we can use the token without having to authenticate again. Otherwise, we may have to authenticate again to get the token which can create concurrency issues.\n const storageCustomCredential: TokenCredential = {\n getToken: async () => {\n return Promise.resolve(token);\n },\n };\n\n if (authenticationRecord) {\n saveAuthenticationRecord(cachePath, authenticationRecord);\n }\n\n return storageCustomCredential;\n }\n\n return credential;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"saveAuthenticationRecord.d.ts","sourceRoot":"","sources":["../../src/authentication/saveAuthenticationRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAI3F;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,QAQ3F"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { serializeAuthenticationRecord } from '@azure/identity';
|
|
2
|
-
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
3
|
-
import { getAuthenticationRecordPath } from './getAuthenticationRecordPath.js';
|
|
4
|
-
/**
|
|
5
|
-
* Saves the provided authentication record to Cloudpack's global cache folder.
|
|
6
|
-
* Creates the cache folder if it doesn't exist.
|
|
7
|
-
* @param cachePath - The path to Cloudpack's cache folder.
|
|
8
|
-
* @param authRecord - The authentication record to save.
|
|
9
|
-
*/
|
|
10
|
-
export function saveAuthenticationRecord(cachePath, authRecord) {
|
|
11
|
-
const content = serializeAuthenticationRecord(authRecord);
|
|
12
|
-
if (!existsSync(cachePath)) {
|
|
13
|
-
mkdirSync(cachePath, { recursive: true });
|
|
14
|
-
}
|
|
15
|
-
writeFileSync(getAuthenticationRecordPath(cachePath), content);
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=saveAuthenticationRecord.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"saveAuthenticationRecord.js","sourceRoot":"","sources":["../../src/authentication/saveAuthenticationRecord.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAA6B,MAAM,iBAAiB,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,SAAiB,EAAE,UAAgC;IAC1F,MAAM,OAAO,GAAG,6BAA6B,CAAC,UAAU,CAAC,CAAC;IAE1D,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,aAAa,CAAC,2BAA2B,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC","sourcesContent":["import { serializeAuthenticationRecord, type AuthenticationRecord } from '@azure/identity';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { getAuthenticationRecordPath } from './getAuthenticationRecordPath.js';\n\n/**\n * Saves the provided authentication record to Cloudpack's global cache folder.\n * Creates the cache folder if it doesn't exist.\n * @param cachePath - The path to Cloudpack's cache folder.\n * @param authRecord - The authentication record to save.\n */\nexport function saveAuthenticationRecord(cachePath: string, authRecord: AuthenticationRecord) {\n const content = serializeAuthenticationRecord(authRecord);\n\n if (!existsSync(cachePath)) {\n mkdirSync(cachePath, { recursive: true });\n }\n\n writeFileSync(getAuthenticationRecordPath(cachePath), content);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cachePersistencePlugin.d.ts","sourceRoot":"","sources":["../../src/cache-persistance/cachePersistencePlugin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,eAAO,MAAM,sBAAsB,EAAE,cAGpC,CAAC"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is a fork of https://github.com/altinokdarici/azure-sdk-for-js/tree/main/sdk/identity/identity-cache-persistence
|
|
3
|
-
*/
|
|
4
|
-
import { createPersistenceCachePlugin } from './provider.js';
|
|
5
|
-
/**
|
|
6
|
-
* A plugin that provides persistent token caching for `@azure/identity`
|
|
7
|
-
* credentials. The plugin API is compatible with `@azure/identity` versions
|
|
8
|
-
* 2.0.0 and later. Load this plugin using the `useIdentityPlugin`
|
|
9
|
-
* function, imported from `@azure/identity`.
|
|
10
|
-
*
|
|
11
|
-
* In order to enable this functionality, you must also pass
|
|
12
|
-
* `tokenCachePersistenceOptions` to your credential constructors with an
|
|
13
|
-
* `enabled` property set to true.
|
|
14
|
-
*
|
|
15
|
-
* Example:
|
|
16
|
-
*
|
|
17
|
-
* ```javascript
|
|
18
|
-
* import { useIdentityPlugin, DeviceCodeCredential } from "@azure/identity";
|
|
19
|
-
* import { cachePersistencePlugin } from "@azure/identity-cache-persistence";
|
|
20
|
-
*
|
|
21
|
-
* // Load the plugin
|
|
22
|
-
* useIdentityPlugin(cachePersistencePlugin);
|
|
23
|
-
*
|
|
24
|
-
* const credential = new DeviceCodeCredential({
|
|
25
|
-
* tokenCachePersistenceOptions: {
|
|
26
|
-
* enabled: true
|
|
27
|
-
* }
|
|
28
|
-
* });
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export const cachePersistencePlugin = (context) => {
|
|
32
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
33
|
-
context.cachePluginControl.setPersistence(createPersistenceCachePlugin);
|
|
34
|
-
};
|
|
35
|
-
//# sourceMappingURL=cachePersistencePlugin.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cachePersistencePlugin.js","sourceRoot":"","sources":["../../src/cache-persistance/cachePersistencePlugin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAmB,CAAC,OAAO,EAAE,EAAE;IAChE,6IAA6I;IAC5I,OAAe,CAAC,kBAAkB,CAAC,cAAc,CAAC,4BAA4B,CAAC,CAAC;AACnF,CAAC,CAAC","sourcesContent":["/**\n * This file is a fork of https://github.com/altinokdarici/azure-sdk-for-js/tree/main/sdk/identity/identity-cache-persistence\n */\n\n// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n// import { AzurePluginContext } from '../../identity/src/plugins/provider';\nimport type { IdentityPlugin } from '@azure/identity';\nimport { createPersistenceCachePlugin } from './provider.js';\n\n/**\n * A plugin that provides persistent token caching for `@azure/identity`\n * credentials. The plugin API is compatible with `@azure/identity` versions\n * 2.0.0 and later. Load this plugin using the `useIdentityPlugin`\n * function, imported from `@azure/identity`.\n *\n * In order to enable this functionality, you must also pass\n * `tokenCachePersistenceOptions` to your credential constructors with an\n * `enabled` property set to true.\n *\n * Example:\n *\n * ```javascript\n * import { useIdentityPlugin, DeviceCodeCredential } from \"@azure/identity\";\n * import { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\n *\n * // Load the plugin\n * useIdentityPlugin(cachePersistencePlugin);\n *\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true\n * }\n * });\n * ```\n */\n\nexport const cachePersistencePlugin: IdentityPlugin = (context) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n (context as any).cachePluginControl.setPersistence(createPersistenceCachePlugin);\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"platforms.d.ts","sourceRoot":"","sources":["../../src/cache-persistance/platforms.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAKH,OAAO,EAML,KAAK,YAAY,IAAI,WAAW,EACjC,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAapE;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;CAwB7B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,4BAA4B,EAAE,SAAS,CAAC,CAAC;AAEnF;;;GAGG;AACH,KAAK,sBAAsB,GAAG,CAAC,OAAO,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAazF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CA2C7F,CAAC"}
|