@rushstack/rush-amazon-s3-build-cache-plugin 5.110.0 → 5.110.2

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 CHANGED
@@ -1,24 +1,24 @@
1
- @rushstack/rush-amazon-s3-build-cache-plugin
2
-
3
- Copyright (c) Microsoft Corporation. All rights reserved.
4
-
5
- MIT License
6
-
7
- Permission is hereby granted, free of charge, to any person obtaining
8
- a copy of this software and associated documentation files (the
9
- "Software"), to deal in the Software without restriction, including
10
- without limitation the rights to use, copy, modify, merge, publish,
11
- distribute, sublicense, and/or sell copies of the Software, and to
12
- permit persons to whom the Software is furnished to do so, subject to
13
- the following conditions:
14
-
15
- The above copyright notice and this permission notice shall be
16
- included in all copies or substantial portions of the Software.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ @rushstack/rush-amazon-s3-build-cache-plugin
2
+
3
+ Copyright (c) Microsoft Corporation. All rights reserved.
4
+
5
+ MIT License
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ "Software"), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # @rushstack/rush-amazon-s3-build-cache-plugin
2
-
3
- This is a Rush plugin for using Amazon S3 as cloud build cache provider during the "build" and "rebuild" command.
4
-
5
- ## Links
6
-
7
- - [CHANGELOG.md](
8
- https://github.com/microsoft/rushstack/blob/main/rush-plugins/rush-amazon-s3-build-cache-plugin/CHANGELOG.md) - Find
9
- out what's new in the latest version
1
+ # @rushstack/rush-amazon-s3-build-cache-plugin
2
+
3
+ This is a Rush plugin for using Amazon S3 as cloud build cache provider during the "build" and "rebuild" command.
4
+
5
+ ## Links
6
+
7
+ - [CHANGELOG.md](
8
+ https://github.com/microsoft/rushstack/blob/main/rush-plugins/rush-amazon-s3-build-cache-plugin/CHANGELOG.md) - Find
9
+ out what's new in the latest version
@@ -1 +1 @@
1
- {"version":3,"file":"AmazonS3BuildCacheProvider.js","sourceRoot":"","sources":["../src/AmazonS3BuildCacheProvider.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport type { ITerminal } from '@rushstack/node-core-library';\r\nimport {\r\n type ICloudBuildCacheProvider,\r\n type ICredentialCacheEntry,\r\n CredentialCache,\r\n type RushSession,\r\n RushConstants,\r\n EnvironmentVariableNames,\r\n EnvironmentConfiguration\r\n} from '@rushstack/rush-sdk';\r\n\r\nimport { AmazonS3Client } from './AmazonS3Client';\r\nimport { WebClient } from './WebClient';\r\nimport { type IAmazonS3Credentials, fromAmazonEnv, fromRushEnv } from './AmazonS3Credentials';\r\n\r\n/**\r\n * @public\r\n */\r\nexport interface IAmazonS3BuildCacheProviderOptionsBase {\r\n s3Region: string;\r\n s3Prefix: string | undefined;\r\n isCacheWriteAllowed: boolean;\r\n}\r\n\r\n/**\r\n * Advanced options where user has the specify the full http endpoint\r\n * @public\r\n */\r\nexport interface IAmazonS3BuildCacheProviderOptionsAdvanced extends IAmazonS3BuildCacheProviderOptionsBase {\r\n s3Endpoint: string;\r\n}\r\n/**\r\n * Simple options where user only provides the bucket and the endpoint is automatically built\r\n * @public\r\n */\r\nexport interface IAmazonS3BuildCacheProviderOptionsSimple extends IAmazonS3BuildCacheProviderOptionsBase {\r\n s3Bucket: string;\r\n}\r\n\r\nconst DEFAULT_S3_REGION: 'us-east-1' = 'us-east-1';\r\nexport class AmazonS3BuildCacheProvider implements ICloudBuildCacheProvider {\r\n private readonly _options:\r\n | IAmazonS3BuildCacheProviderOptionsSimple\r\n | IAmazonS3BuildCacheProviderOptionsAdvanced;\r\n private readonly _s3Prefix: string | undefined;\r\n private readonly _isCacheWriteAllowedByConfiguration: boolean;\r\n private __credentialCacheId: string | undefined;\r\n private _rushSession: RushSession;\r\n\r\n public get isCacheWriteAllowed(): boolean {\r\n return EnvironmentConfiguration.buildCacheWriteAllowed ?? this._isCacheWriteAllowedByConfiguration;\r\n }\r\n\r\n private __s3Client: AmazonS3Client | undefined;\r\n\r\n public constructor(\r\n options: IAmazonS3BuildCacheProviderOptionsSimple | IAmazonS3BuildCacheProviderOptionsAdvanced,\r\n rushSession: RushSession\r\n ) {\r\n this._rushSession = rushSession;\r\n this._options = options;\r\n this._s3Prefix = options.s3Prefix;\r\n this._isCacheWriteAllowedByConfiguration = options.isCacheWriteAllowed;\r\n }\r\n\r\n private get _s3Endpoint(): string {\r\n const options: IAmazonS3BuildCacheProviderOptionsSimple | IAmazonS3BuildCacheProviderOptionsAdvanced =\r\n this._options;\r\n if ('s3Bucket' in options) {\r\n // options: IAmazonS3BuildCacheProviderOptionsSimple\r\n const bucket: string = options.s3Bucket;\r\n if (options.s3Region === DEFAULT_S3_REGION) {\r\n return `https://${bucket}.s3.amazonaws.com`;\r\n } else {\r\n return `https://${bucket}.s3-${options.s3Region}.amazonaws.com`;\r\n }\r\n }\r\n // options: IAmazonS3BuildCacheProviderOptionsAdvanced\r\n return options.s3Endpoint;\r\n }\r\n\r\n private get _credentialCacheId(): string {\r\n if (!this.__credentialCacheId) {\r\n const cacheIdParts: string[] = ['aws-s3', this._options.s3Region, this._s3Endpoint];\r\n\r\n if (this._isCacheWriteAllowedByConfiguration) {\r\n cacheIdParts.push('cacheWriteAllowed');\r\n }\r\n\r\n this.__credentialCacheId = cacheIdParts.join('|');\r\n }\r\n\r\n return this.__credentialCacheId;\r\n }\r\n\r\n private async _getS3ClientAsync(terminal: ITerminal): Promise<AmazonS3Client> {\r\n if (!this.__s3Client) {\r\n let credentials: IAmazonS3Credentials | undefined = fromRushEnv() ?? fromAmazonEnv();\r\n\r\n if (!credentials) {\r\n terminal.writeDebugLine('No credentials found in env. Trying cloud credentials.');\r\n\r\n let cacheEntry: ICredentialCacheEntry | undefined;\r\n await CredentialCache.usingAsync(\r\n {\r\n supportEditing: false\r\n },\r\n (credentialsCache: CredentialCache) => {\r\n cacheEntry = credentialsCache.tryGetCacheEntry(this._credentialCacheId);\r\n }\r\n );\r\n\r\n if (cacheEntry) {\r\n const expirationTime: number | undefined = cacheEntry.expires?.getTime();\r\n if (expirationTime && expirationTime < Date.now()) {\r\n throw new Error(\r\n 'Cached Amazon S3 credentials have expired. ' +\r\n `Update the credentials by running \"rush ${RushConstants.updateCloudCredentialsCommandName}\".`\r\n );\r\n } else {\r\n credentials = fromRushEnv(cacheEntry?.credential);\r\n }\r\n } else if (this._isCacheWriteAllowedByConfiguration) {\r\n throw new Error(\r\n \"An Amazon S3 credential hasn't been provided, or has expired. \" +\r\n `Update the credentials by running \"rush ${RushConstants.updateCloudCredentialsCommandName}\", ` +\r\n `or provide an <AccessKeyId>:<SecretAccessKey> pair in the ` +\r\n `${EnvironmentVariableNames.RUSH_BUILD_CACHE_CREDENTIAL} environment variable`\r\n );\r\n }\r\n }\r\n\r\n this.__s3Client = new AmazonS3Client(\r\n credentials,\r\n {\r\n ...this._options,\r\n // advanced options\r\n s3Endpoint: this._s3Endpoint\r\n },\r\n new WebClient(),\r\n terminal\r\n );\r\n }\r\n\r\n return this.__s3Client;\r\n }\r\n\r\n public async tryGetCacheEntryBufferByIdAsync(\r\n terminal: ITerminal,\r\n cacheId: string\r\n ): Promise<Buffer | undefined> {\r\n try {\r\n const client: AmazonS3Client = await this._getS3ClientAsync(terminal);\r\n return await client.getObjectAsync(this._s3Prefix ? `${this._s3Prefix}/${cacheId}` : cacheId);\r\n } catch (e) {\r\n terminal.writeWarningLine(`Error getting cache entry from S3: ${e}`);\r\n return undefined;\r\n }\r\n }\r\n\r\n public async trySetCacheEntryBufferAsync(\r\n terminal: ITerminal,\r\n cacheId: string,\r\n objectBuffer: Buffer\r\n ): Promise<boolean> {\r\n if (!this.isCacheWriteAllowed) {\r\n terminal.writeErrorLine('Writing to S3 cache is not allowed in the current configuration.');\r\n return false;\r\n }\r\n\r\n terminal.writeDebugLine('Uploading object with cacheId: ', cacheId);\r\n\r\n try {\r\n const client: AmazonS3Client = await this._getS3ClientAsync(terminal);\r\n await client.uploadObjectAsync(this._s3Prefix ? `${this._s3Prefix}/${cacheId}` : cacheId, objectBuffer);\r\n return true;\r\n } catch (e) {\r\n terminal.writeWarningLine(`Error uploading cache entry to S3: ${e}`);\r\n return false;\r\n }\r\n }\r\n\r\n public async updateCachedCredentialAsync(terminal: ITerminal, credential: string): Promise<void> {\r\n await CredentialCache.usingAsync(\r\n {\r\n supportEditing: true\r\n },\r\n async (credentialsCache: CredentialCache) => {\r\n credentialsCache.setCacheEntry(this._credentialCacheId, { credential });\r\n await credentialsCache.saveIfModifiedAsync();\r\n }\r\n );\r\n }\r\n\r\n public async updateCachedCredentialInteractiveAsync(terminal: ITerminal): Promise<void> {\r\n throw new Error(\r\n 'The interactive cloud credentials flow is not supported for Amazon S3.\\n' +\r\n 'Provide your credentials to rush using the --credential flag instead. Credentials must be ' +\r\n 'in the form of <ACCESS KEY ID>:<SECRET ACCESS KEY> or ' +\r\n '<ACCESS KEY ID>:<SECRET ACCESS KEY>:<SESSION TOKEN>.'\r\n );\r\n }\r\n\r\n public async deleteCachedCredentialsAsync(terminal: ITerminal): Promise<void> {\r\n await CredentialCache.usingAsync(\r\n {\r\n supportEditing: true\r\n },\r\n async (credentialsCache: CredentialCache) => {\r\n credentialsCache.deleteCacheEntry(this._credentialCacheId);\r\n await credentialsCache.saveIfModifiedAsync();\r\n }\r\n );\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"AmazonS3BuildCacheProvider.js","sourceRoot":"","sources":["../src/AmazonS3BuildCacheProvider.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { ITerminal } from '@rushstack/node-core-library';\nimport {\n type ICloudBuildCacheProvider,\n type ICredentialCacheEntry,\n CredentialCache,\n type RushSession,\n RushConstants,\n EnvironmentVariableNames,\n EnvironmentConfiguration\n} from '@rushstack/rush-sdk';\n\nimport { AmazonS3Client } from './AmazonS3Client';\nimport { WebClient } from './WebClient';\nimport { type IAmazonS3Credentials, fromAmazonEnv, fromRushEnv } from './AmazonS3Credentials';\n\n/**\n * @public\n */\nexport interface IAmazonS3BuildCacheProviderOptionsBase {\n s3Region: string;\n s3Prefix: string | undefined;\n isCacheWriteAllowed: boolean;\n}\n\n/**\n * Advanced options where user has the specify the full http endpoint\n * @public\n */\nexport interface IAmazonS3BuildCacheProviderOptionsAdvanced extends IAmazonS3BuildCacheProviderOptionsBase {\n s3Endpoint: string;\n}\n/**\n * Simple options where user only provides the bucket and the endpoint is automatically built\n * @public\n */\nexport interface IAmazonS3BuildCacheProviderOptionsSimple extends IAmazonS3BuildCacheProviderOptionsBase {\n s3Bucket: string;\n}\n\nconst DEFAULT_S3_REGION: 'us-east-1' = 'us-east-1';\nexport class AmazonS3BuildCacheProvider implements ICloudBuildCacheProvider {\n private readonly _options:\n | IAmazonS3BuildCacheProviderOptionsSimple\n | IAmazonS3BuildCacheProviderOptionsAdvanced;\n private readonly _s3Prefix: string | undefined;\n private readonly _isCacheWriteAllowedByConfiguration: boolean;\n private __credentialCacheId: string | undefined;\n private _rushSession: RushSession;\n\n public get isCacheWriteAllowed(): boolean {\n return EnvironmentConfiguration.buildCacheWriteAllowed ?? this._isCacheWriteAllowedByConfiguration;\n }\n\n private __s3Client: AmazonS3Client | undefined;\n\n public constructor(\n options: IAmazonS3BuildCacheProviderOptionsSimple | IAmazonS3BuildCacheProviderOptionsAdvanced,\n rushSession: RushSession\n ) {\n this._rushSession = rushSession;\n this._options = options;\n this._s3Prefix = options.s3Prefix;\n this._isCacheWriteAllowedByConfiguration = options.isCacheWriteAllowed;\n }\n\n private get _s3Endpoint(): string {\n const options: IAmazonS3BuildCacheProviderOptionsSimple | IAmazonS3BuildCacheProviderOptionsAdvanced =\n this._options;\n if ('s3Bucket' in options) {\n // options: IAmazonS3BuildCacheProviderOptionsSimple\n const bucket: string = options.s3Bucket;\n if (options.s3Region === DEFAULT_S3_REGION) {\n return `https://${bucket}.s3.amazonaws.com`;\n } else {\n return `https://${bucket}.s3-${options.s3Region}.amazonaws.com`;\n }\n }\n // options: IAmazonS3BuildCacheProviderOptionsAdvanced\n return options.s3Endpoint;\n }\n\n private get _credentialCacheId(): string {\n if (!this.__credentialCacheId) {\n const cacheIdParts: string[] = ['aws-s3', this._options.s3Region, this._s3Endpoint];\n\n if (this._isCacheWriteAllowedByConfiguration) {\n cacheIdParts.push('cacheWriteAllowed');\n }\n\n this.__credentialCacheId = cacheIdParts.join('|');\n }\n\n return this.__credentialCacheId;\n }\n\n private async _getS3ClientAsync(terminal: ITerminal): Promise<AmazonS3Client> {\n if (!this.__s3Client) {\n let credentials: IAmazonS3Credentials | undefined = fromRushEnv() ?? fromAmazonEnv();\n\n if (!credentials) {\n terminal.writeDebugLine('No credentials found in env. Trying cloud credentials.');\n\n let cacheEntry: ICredentialCacheEntry | undefined;\n await CredentialCache.usingAsync(\n {\n supportEditing: false\n },\n (credentialsCache: CredentialCache) => {\n cacheEntry = credentialsCache.tryGetCacheEntry(this._credentialCacheId);\n }\n );\n\n if (cacheEntry) {\n const expirationTime: number | undefined = cacheEntry.expires?.getTime();\n if (expirationTime && expirationTime < Date.now()) {\n throw new Error(\n 'Cached Amazon S3 credentials have expired. ' +\n `Update the credentials by running \"rush ${RushConstants.updateCloudCredentialsCommandName}\".`\n );\n } else {\n credentials = fromRushEnv(cacheEntry?.credential);\n }\n } else if (this._isCacheWriteAllowedByConfiguration) {\n throw new Error(\n \"An Amazon S3 credential hasn't been provided, or has expired. \" +\n `Update the credentials by running \"rush ${RushConstants.updateCloudCredentialsCommandName}\", ` +\n `or provide an <AccessKeyId>:<SecretAccessKey> pair in the ` +\n `${EnvironmentVariableNames.RUSH_BUILD_CACHE_CREDENTIAL} environment variable`\n );\n }\n }\n\n this.__s3Client = new AmazonS3Client(\n credentials,\n {\n ...this._options,\n // advanced options\n s3Endpoint: this._s3Endpoint\n },\n new WebClient(),\n terminal\n );\n }\n\n return this.__s3Client;\n }\n\n public async tryGetCacheEntryBufferByIdAsync(\n terminal: ITerminal,\n cacheId: string\n ): Promise<Buffer | undefined> {\n try {\n const client: AmazonS3Client = await this._getS3ClientAsync(terminal);\n return await client.getObjectAsync(this._s3Prefix ? `${this._s3Prefix}/${cacheId}` : cacheId);\n } catch (e) {\n terminal.writeWarningLine(`Error getting cache entry from S3: ${e}`);\n return undefined;\n }\n }\n\n public async trySetCacheEntryBufferAsync(\n terminal: ITerminal,\n cacheId: string,\n objectBuffer: Buffer\n ): Promise<boolean> {\n if (!this.isCacheWriteAllowed) {\n terminal.writeErrorLine('Writing to S3 cache is not allowed in the current configuration.');\n return false;\n }\n\n terminal.writeDebugLine('Uploading object with cacheId: ', cacheId);\n\n try {\n const client: AmazonS3Client = await this._getS3ClientAsync(terminal);\n await client.uploadObjectAsync(this._s3Prefix ? `${this._s3Prefix}/${cacheId}` : cacheId, objectBuffer);\n return true;\n } catch (e) {\n terminal.writeWarningLine(`Error uploading cache entry to S3: ${e}`);\n return false;\n }\n }\n\n public async updateCachedCredentialAsync(terminal: ITerminal, credential: string): Promise<void> {\n await CredentialCache.usingAsync(\n {\n supportEditing: true\n },\n async (credentialsCache: CredentialCache) => {\n credentialsCache.setCacheEntry(this._credentialCacheId, { credential });\n await credentialsCache.saveIfModifiedAsync();\n }\n );\n }\n\n public async updateCachedCredentialInteractiveAsync(terminal: ITerminal): Promise<void> {\n throw new Error(\n 'The interactive cloud credentials flow is not supported for Amazon S3.\\n' +\n 'Provide your credentials to rush using the --credential flag instead. Credentials must be ' +\n 'in the form of <ACCESS KEY ID>:<SECRET ACCESS KEY> or ' +\n '<ACCESS KEY ID>:<SECRET ACCESS KEY>:<SESSION TOKEN>.'\n );\n }\n\n public async deleteCachedCredentialsAsync(terminal: ITerminal): Promise<void> {\n await CredentialCache.usingAsync(\n {\n supportEditing: true\n },\n async (credentialsCache: CredentialCache) => {\n credentialsCache.deleteCacheEntry(this._credentialCacheId);\n await credentialsCache.saveIfModifiedAsync();\n }\n );\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AmazonS3Client.js","sourceRoot":"","sources":["../src/AmazonS3Client.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,oEAAsG;AACtG,+CAAiC;AACjC,kDAAoC;AAIpC,+DAA+E;AAE/E,MAAM,wBAAwB,GAA2B,sBAAsB,CAAC;AAChF,MAAM,gBAAgB,GAAiB,YAAY,CAAC;AACpD,MAAM,gBAAgB,GAAW,MAAM,CAAC;AACxC,MAAM,0BAA0B,GAA2B,sBAAsB,CAAC;AAiBlF,MAAM,aAAa,GAAW,cAAc,CAAC;AAC7C,MAAM,SAAS,GAAW,aAAa,CAAC;AAExC,+HAA+H;AAC/H,IAAK,sBAGJ;AAHD,WAAK,sBAAsB;IACzB,iFAAe,CAAA;IACf,qEAAS,CAAA;AACX,CAAC,EAHI,sBAAsB,KAAtB,sBAAsB,QAG1B;AAUD,MAAM,mBAAmB,GAAyB;IAChD,iBAAiB,EAAE,GAAG,GAAG,IAAI;IAC7B,QAAQ,EAAE,CAAC;IACX,cAAc,EAAE,CAAC,GAAG,IAAI;IACxB,eAAe,EAAE,sBAAsB,CAAC,WAAW;CACpD,CAAC;AAEF;;;;GAIG;AACH,MAAa,cAAc;IASzB,YACE,WAA6C,EAC7C,OAAmD,EACnD,SAAoB,EACpB,QAAmB;QAEnB,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QAElC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,wHAAwH;IACxH,0CAA0C;IACnC,MAAM,CAAC,SAAS,CAAC,KAAa;QACnC,IAAI,MAAM,GAAW,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YAChD,MAAM,EAAE,GAAW,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE;gBAClC,MAAM,IAAI,EAAE,CAAC;aACd;iBAAM;gBACL,IAAI,EAAE,KAAK,GAAG,EAAE;oBACd,MAAM,IAAI,KAAK,CAAC;iBACjB;qBAAM;oBACL,MAAM,IAAI,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;iBAC7D;aACF;SACF;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,MAAM,CAAC,yBAAyB,CACrC,gBAAoC;QAEpC,OAAO,IAAA,iCAAW,EAAC,gBAAgB,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAkB;QAC5C,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAAC;QAC/C,OAAO,MAAM,IAAI,CAAC,4BAA4B,CAAC,KAAK,IAAI,EAAE;YACxD,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YACjF,IAAI,QAAQ,CAAC,EAAE,EAAE;gBACf,OAAO;oBACL,eAAe,EAAE,KAAK;oBACtB,QAAQ,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE;iBAClC,CAAC;aACH;iBAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;gBAClC,OAAO;oBACL,eAAe,EAAE,KAAK;oBACtB,QAAQ,EAAE,SAAS;iBACpB,CAAC;aACH;iBAAM,IACL,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;gBAC/E,CAAC,IAAI,CAAC,YAAY,EAClB;gBACA,iDAAiD;gBACjD,4EAA4E;gBAC5E,IAAI,CAAC,iBAAiB,CACpB,uCAAuC,QAAQ,CAAC,MAAM,EAAE,EACxD,wCAAwC,EACxC,0CAA0C,EAC1C,6CAA6C,CAC9C,CAAC;gBACF,OAAO;oBACL,eAAe,EAAE,KAAK;oBACtB,QAAQ,EAAE,SAAS;iBACpB,CAAC;aACH;iBAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;gBACxF,MAAM,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;aAC7C;iBAAM;gBACL,MAAM,KAAK,GAAU,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAC3D,OAAO;oBACL,eAAe,EAAE,IAAI;oBACrB,KAAK;iBACN,CAAC;aACH;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAAC,UAAkB,EAAE,YAAoB;QACrE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;SACtE;QAED,MAAM,IAAI,CAAC,4BAA4B,CAAC,KAAK,IAAI,EAAE;YACjD,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;YAC/F,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBAChB,OAAO;oBACL,eAAe,EAAE,IAAI;oBACrB,KAAK,EAAE,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;iBAC7C,CAAC;aACH;YACD,OAAO;gBACL,eAAe,EAAE,KAAK;gBACtB,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,GAAG,YAA6C;QACtE,4EAA4E;QAC5E,IAAI;YACF,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,CAAC;SAChD;QAAC,OAAO,GAAG,EAAE;YACZ,eAAe;SAChB;IACH,CAAC;IAEO,iBAAiB,CAAC,GAAG,YAA6C;QACxE,8EAA8E;QAC9E,IAAI;YACF,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,YAAY,CAAC,CAAC;SAClD;QAAC,OAAO,GAAG,EAAE;YACZ,eAAe;SAChB;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,IAAmB,EACnB,UAAkB,EAClB,IAAa;QAEb,MAAM,aAAa,GAAmB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/D,MAAM,QAAQ,GAAW,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAkB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC;QAEhD,mEAAmE;QACnE,MAAM,IAAI,GAAW,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,YAAY,GAAW,cAAc,CAAC,SAAS,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,CAAC,CAAC;QAEnE,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,sHAAsH;YACtH,MAAM,gBAAgB,GAAa;gBACjC,GAAG,gBAAgB,IAAI,IAAI,EAAE;gBAC7B,GAAG,wBAAwB,IAAI,QAAQ,EAAE;gBACzC,GAAG,gBAAgB,IAAI,aAAa,CAAC,QAAQ,EAAE;aAChD,CAAC;YAEF,kEAAkE;YAClE,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE;gBAClC,gBAAgB,CAAC,IAAI,CAAC,GAAG,0BAA0B,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;aAC1F;YAED,sDAAsD;YACtD,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;gBACzC,MAAM,WAAW,GAAW,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,MAAM,WAAW,GAAW,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,IAAI,WAAW,GAAG,WAAW,EAAE;oBAC7B,OAAO,CAAC,CAAC,CAAC;iBACX;gBACD,IAAI,WAAW,GAAG,WAAW,EAAE;oBAC7B,OAAO,CAAC,CAAC;iBACV;gBACD,OAAO,CAAC,CAAC;YACX,CAAC,CAAC,CAAC;YAEH,gEAAgE;YAChE,MAAM,uBAAuB,GAAW,gBAAgB;iBACrD,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACd,MAAM,UAAU,GAAW,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChD,OAAO,UAAU,CAAC;YACpB,CAAC,CAAC;iBACD,IAAI,CAAC,GAAG,CAAC,CAAC;YAEb,yCAAyC;YACzC,OAAO;YACP,YAAY;YACZ,EAAE;YACF,sCAAsC;YACtC,kBAAkB;YAClB,wFAAwF;YACxF,8BAA8B;YAC9B,EAAE;YACF,6CAA6C;YAC7C,mEAAmE;YACnE,MAAM,gBAAgB,GAAW;gBAC/B,IAAI;gBACJ,YAAY;gBACZ,EAAE;gBACF,GAAG,gBAAgB;gBACnB,EAAE;gBACF,uBAAuB;gBACvB,QAAQ;aACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,MAAM,oBAAoB,GAAW,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YAEvE,MAAM,KAAK,GAAW,GAAG,aAAa,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,kBAAkB,CAAC;YAChF,sCAAsC;YACtC,mBAAmB;YACnB,mBAAmB;YACnB,qCAAqC;YACrC,mEAAmE;YACnE,MAAM,YAAY,GAAW;gBAC3B,kBAAkB;gBAClB,aAAa,CAAC,QAAQ;gBACtB,KAAK;gBACL,oBAAoB;aACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,OAAO,GAAW,IAAI,CAAC,cAAc,CACzC,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,EAC1C,aAAa,CAAC,IAAI,CACnB,CAAC;YACF,MAAM,aAAa,GAAW,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3E,MAAM,oBAAoB,GAAW,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAC9E,MAAM,UAAU,GAAW,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;YACrF,MAAM,SAAS,GAAW,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;YAE/E,MAAM,mBAAmB,GAAW,+BAA+B,IAAI,CAAC,YAAY,CAAC,WAAW,IAAI,KAAK,kBAAkB,uBAAuB,cAAc,SAAS,EAAE,CAAC;YAE5K,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;YAClD,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE;gBAClC,kEAAkE;gBAClE,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;aACrE;SACF;QAED,MAAM,eAAe,GAAwC;YAC3D,IAAI;YACJ,OAAO;SACR,CAAC;QACF,IAAI,IAAI,KAAK,KAAK,EAAE;YACjB,eAAoC,CAAC,IAAI,GAAG,IAAI,CAAC;SACnD;QAED,MAAM,GAAG,GAAW,GAAG,IAAI,CAAC,WAAW,GAAG,YAAY,EAAE,CAAC;QAEzD,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,0BAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC9B,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAExF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAIM,cAAc,CAAC,GAAoB,EAAE,IAAY,EAAE,QAAgB;QACxE,MAAM,IAAI,GAAgB,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,QAAQ,EAAE;YACZ,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;SAC9B;aAAM;YACL,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;SACtB;IACH,CAAC;IAEO,UAAU,CAAC,IAAsB;QACvC,IAAI,IAAI,EAAE;YACR,MAAM,IAAI,GAAgB,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SAC3B;aAAM;YACL,+BAA+B;YAC/B,OAAO,kEAAkE,CAAC;SAC3E;IACH,CAAC;IAEO,iBAAiB,CAAC,OAAa,IAAI,IAAI,EAAE;QAC/C,IAAI,UAAU,GAAW,IAAI,CAAC,WAAW,EAAE,CAAC;QAC5C,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,8BAA8B;QAC5E,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB;QAE9D,+DAA+D;QAC/D,gDAAgD;QAChD,OAAO;YACL,QAAQ,EAAE,GAAG,UAAU,GAAG;YAC1B,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;SACjC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,QAAwB;QAC1D,IAAI;YACF,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;SAC9B;QAAC,OAAO,GAAG,EAAE;YACZ,mBAAmB;SACpB;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAwB;QACrD,MAAM,IAAI,GAAuB,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAC5E,OAAO,IAAI,KAAK,CACd,wCAAwC,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,IAC7E,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EACvB,EAAE,CACH,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,iBAAiB,CAAC,UAAkB;QAC1C,IAAI,IAAI,GAAW,UAAU,CAAC;QAE9B,IAAI,CAAC,UAAU,EAAE;YACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;SACnD;QAED,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;YACpC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;SACxE;QAED,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAEvC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YACpB,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;SACjG;QAED,MAAM,SAAS,GAA4B,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvE,IAAI,SAAS,EAAE;YACb,MAAM,IAAI,GAAW,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE;gBACtC,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,4BAA4B,CAAC,CAAC;aAC5D;YACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;SACpC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACtB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;SACvC;QAED,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE;YACrB,MAAM,IAAI,KAAK,CACb,qGAAqG,CACtG,CAAC;SACH;QAED,MAAM,UAAU,GAAa,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE7C,MAAM,cAAc,GAAW,iBAAiB,CAAC;QACjD,MAAM,OAAO,GAAY,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE;YACtD,OAAO,CACL,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC9B,SAAS,CAAC,MAAM,GAAG,EAAE;gBACrB,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;gBAC1B,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CACzB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CACb,2FAA2F,CAC5F,CAAC;SACH;IACH,CAAC;IAEO,KAAK,CAAC,4BAA4B,CACxC,WAAuD;QAEvD,MAAM,QAAQ,GAAgC,MAAM,WAAW,EAAE,CAAC;QAElE,MAAM,GAAG,GAA+D,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAExG,IAAI,QAAQ,CAAC,eAAe,EAAE;YAC5B,IAAI,mBAAmB,IAAI,mBAAmB,CAAC,QAAQ,GAAG,CAAC,EAAE;gBAC3D,GAAG,CAAC,gFAAgF,CAAC,CAAC;gBACtF,KAAK,UAAU,KAAK,CAAC,YAAoB;oBACvC,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,mBAAmB,CAAC;oBAC7F,IAAI,KAAK,GAAW,cAAc,CAAC;oBACnC,IAAI,eAAe,KAAK,sBAAsB,CAAC,WAAW,EAAE;wBAC1D,KAAK,GAAG,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;qBACxD;oBACD,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;oBAE3C,GAAG,CAAC,yBAAyB,KAAK,MAAM,CAAC,CAAC;oBAC1C,MAAM,yBAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBACzB,MAAM,aAAa,GAAgC,MAAM,WAAW,EAAE,CAAC;oBAEvE,IAAI,aAAa,CAAC,eAAe,EAAE;wBACjC,IAAI,YAAY,GAAG,QAAQ,GAAG,CAAC,EAAE;4BAC/B,GAAG,CAAC,4CAA4C,CAAC,CAAC;4BAClD,OAAO,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;yBAChC;6BAAM;4BACL,GAAG,CAAC,+DAA+D,CAAC,CAAC;4BACrE,MAAM,aAAa,CAAC,KAAK,CAAC;yBAC3B;qBACF;oBAED,OAAO,aAAa,CAAC,QAAQ,CAAC;gBAChC,CAAC;gBACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;aACjB;iBAAM;gBACL,GAAG,CAAC,iEAAiE,CAAC,CAAC;gBACvE,MAAM,QAAQ,CAAC,KAAK,CAAC;aACtB;SACF;QAED,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAC3B,CAAC;CACF;AA5ZD,wCA4ZC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { Async, Colors, type IColorableSequence, type ITerminal } from '@rushstack/node-core-library';\r\nimport * as crypto from 'crypto';\r\nimport * as fetch from 'node-fetch';\r\n\r\nimport type { IAmazonS3BuildCacheProviderOptionsAdvanced } from './AmazonS3BuildCacheProvider';\r\nimport type { IGetFetchOptions, IPutFetchOptions, WebClient } from './WebClient';\r\nimport { type IAmazonS3Credentials, fromRushEnv } from './AmazonS3Credentials';\r\n\r\nconst CONTENT_HASH_HEADER_NAME: 'x-amz-content-sha256' = 'x-amz-content-sha256';\r\nconst DATE_HEADER_NAME: 'x-amz-date' = 'x-amz-date';\r\nconst HOST_HEADER_NAME: 'host' = 'host';\r\nconst SECURITY_TOKEN_HEADER_NAME: 'x-amz-security-token' = 'x-amz-security-token';\r\n\r\ninterface IIsoDateString {\r\n date: string;\r\n dateTime: string;\r\n}\r\n\r\ntype RetryableRequestResponse<T> =\r\n | {\r\n hasNetworkError: true;\r\n error: Error;\r\n }\r\n | {\r\n hasNetworkError: false;\r\n response: T;\r\n };\r\n\r\nconst protocolRegex: RegExp = /^https?:\\/\\//;\r\nconst portRegex: RegExp = /:(\\d{1,5})$/;\r\n\r\n// Similar to https://docs.microsoft.com/en-us/javascript/api/@azure/storage-blob/storageretrypolicytype?view=azure-node-latest\r\nenum StorageRetryPolicyType {\r\n EXPONENTIAL = 0,\r\n FIXED = 1\r\n}\r\n\r\n// Similar to https://docs.microsoft.com/en-us/javascript/api/@azure/storage-blob/storageretryoptions?view=azure-node-latest\r\ninterface IStorageRetryOptions {\r\n maxRetryDelayInMs: number;\r\n maxTries: number;\r\n retryDelayInMs: number;\r\n retryPolicyType: StorageRetryPolicyType;\r\n}\r\n\r\nconst storageRetryOptions: IStorageRetryOptions = {\r\n maxRetryDelayInMs: 120 * 1000,\r\n maxTries: 4,\r\n retryDelayInMs: 4 * 1000,\r\n retryPolicyType: StorageRetryPolicyType.EXPONENTIAL\r\n};\r\n\r\n/**\r\n * A helper for reading and updating objects on Amazon S3\r\n *\r\n * @public\r\n */\r\nexport class AmazonS3Client {\r\n private readonly _credentials: IAmazonS3Credentials | undefined;\r\n private readonly _s3Endpoint: string;\r\n private readonly _s3Region: string;\r\n\r\n private readonly _webClient: WebClient;\r\n\r\n private readonly _terminal: ITerminal;\r\n\r\n public constructor(\r\n credentials: IAmazonS3Credentials | undefined,\r\n options: IAmazonS3BuildCacheProviderOptionsAdvanced,\r\n webClient: WebClient,\r\n terminal: ITerminal\r\n ) {\r\n this._credentials = credentials;\r\n this._terminal = terminal;\r\n\r\n this._validateEndpoint(options.s3Endpoint);\r\n\r\n this._s3Endpoint = options.s3Endpoint;\r\n this._s3Region = options.s3Region;\r\n\r\n this._webClient = webClient;\r\n }\r\n\r\n // https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html#create-signature-presign-entire-payload\r\n // We want to keep all slashes non encoded\r\n public static UriEncode(input: string): string {\r\n let output: string = '';\r\n for (let i: number = 0; i < input.length; i += 1) {\r\n const ch: string = input[i];\r\n if (ch.match(/[A-Za-z0-9~._-]|\\//)) {\r\n output += ch;\r\n } else {\r\n if (ch === ' ') {\r\n output += '%20';\r\n } else {\r\n output += `%${ch.charCodeAt(0).toString(16).toUpperCase()}`;\r\n }\r\n }\r\n }\r\n return output;\r\n }\r\n\r\n public static tryDeserializeCredentials(\r\n credentialString: string | undefined\r\n ): IAmazonS3Credentials | undefined {\r\n return fromRushEnv(credentialString);\r\n }\r\n\r\n public async getObjectAsync(objectName: string): Promise<Buffer | undefined> {\r\n this._writeDebugLine('Reading object from S3');\r\n return await this._sendCacheRequestWithRetries(async () => {\r\n const response: fetch.Response = await this._makeRequestAsync('GET', objectName);\r\n if (response.ok) {\r\n return {\r\n hasNetworkError: false,\r\n response: await response.buffer()\r\n };\r\n } else if (response.status === 404) {\r\n return {\r\n hasNetworkError: false,\r\n response: undefined\r\n };\r\n } else if (\r\n (response.status === 400 || response.status === 401 || response.status === 403) &&\r\n !this._credentials\r\n ) {\r\n // unauthorized due to not providing credentials,\r\n // silence error for better DX when e.g. running locally without credentials\r\n this._writeWarningLine(\r\n `No credentials found and received a ${response.status}`,\r\n ' response code from the cloud storage.',\r\n ' Maybe run rush update-cloud-credentials',\r\n ' or set the RUSH_BUILD_CACHE_CREDENTIAL env'\r\n );\r\n return {\r\n hasNetworkError: false,\r\n response: undefined\r\n };\r\n } else if (response.status === 400 || response.status === 401 || response.status === 403) {\r\n throw await this._getS3ErrorAsync(response);\r\n } else {\r\n const error: Error = await this._getS3ErrorAsync(response);\r\n return {\r\n hasNetworkError: true,\r\n error\r\n };\r\n }\r\n });\r\n }\r\n\r\n public async uploadObjectAsync(objectName: string, objectBuffer: Buffer): Promise<void> {\r\n if (!this._credentials) {\r\n throw new Error('Credentials are required to upload objects to S3.');\r\n }\r\n\r\n await this._sendCacheRequestWithRetries(async () => {\r\n const response: fetch.Response = await this._makeRequestAsync('PUT', objectName, objectBuffer);\r\n if (!response.ok) {\r\n return {\r\n hasNetworkError: true,\r\n error: await this._getS3ErrorAsync(response)\r\n };\r\n }\r\n return {\r\n hasNetworkError: false,\r\n response: undefined\r\n };\r\n });\r\n }\r\n\r\n private _writeDebugLine(...messageParts: (string | IColorableSequence)[]): void {\r\n // if the terminal has been closed then don't bother sending a debug message\r\n try {\r\n this._terminal.writeDebugLine(...messageParts);\r\n } catch (err) {\r\n // ignore error\r\n }\r\n }\r\n\r\n private _writeWarningLine(...messageParts: (string | IColorableSequence)[]): void {\r\n // if the terminal has been closed then don't bother sending a warning message\r\n try {\r\n this._terminal.writeWarningLine(...messageParts);\r\n } catch (err) {\r\n // ignore error\r\n }\r\n }\r\n\r\n private async _makeRequestAsync(\r\n verb: 'GET' | 'PUT',\r\n objectName: string,\r\n body?: Buffer\r\n ): Promise<fetch.Response> {\r\n const isoDateString: IIsoDateString = this._getIsoDateString();\r\n const bodyHash: string = this._getSha256(body);\r\n const headers: fetch.Headers = new fetch.Headers();\r\n headers.set(DATE_HEADER_NAME, isoDateString.dateTime);\r\n headers.set(CONTENT_HASH_HEADER_NAME, bodyHash);\r\n\r\n // the host can be e.g. https://s3.aws.com or http://localhost:9000\r\n const host: string = this._s3Endpoint.replace(protocolRegex, '');\r\n const canonicalUri: string = AmazonS3Client.UriEncode(`/${objectName}`);\r\n this._writeDebugLine(Colors.bold('Canonical URI: '), canonicalUri);\r\n\r\n if (this._credentials) {\r\n // Compute the authorization header. See https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\r\n const canonicalHeaders: string[] = [\r\n `${HOST_HEADER_NAME}:${host}`,\r\n `${CONTENT_HASH_HEADER_NAME}:${bodyHash}`,\r\n `${DATE_HEADER_NAME}:${isoDateString.dateTime}`\r\n ];\r\n\r\n // Handle signing with temporary credentials (via sts:assume-role)\r\n if (this._credentials.sessionToken) {\r\n canonicalHeaders.push(`${SECURITY_TOKEN_HEADER_NAME}:${this._credentials.sessionToken}`);\r\n }\r\n\r\n // the canonical headers must be sorted by header name\r\n canonicalHeaders.sort((aHeader, bHeader) => {\r\n const aHeaderName: string = aHeader.split(':')[0];\r\n const bHeaderName: string = bHeader.split(':')[0];\r\n if (aHeaderName < bHeaderName) {\r\n return -1;\r\n }\r\n if (aHeaderName > bHeaderName) {\r\n return 1;\r\n }\r\n return 0;\r\n });\r\n\r\n // the singed header names are derived from the canonicalHeaders\r\n const signedHeaderNamesString: string = canonicalHeaders\r\n .map((header) => {\r\n const headerName: string = header.split(':')[0];\r\n return headerName;\r\n })\r\n .join(';');\r\n\r\n // The canonical request looks like this:\r\n // GET\r\n // /test.txt\r\n //\r\n // host:examplebucket.s3.amazonaws.com\r\n // range:bytes=0-9\r\n // x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\r\n // x-amz-date:20130524T000000Z\r\n //\r\n // host;range;x-amz-content-sha256;x-amz-date\r\n // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\r\n const canonicalRequest: string = [\r\n verb,\r\n canonicalUri,\r\n '', // we don't use query strings for these requests\r\n ...canonicalHeaders,\r\n '',\r\n signedHeaderNamesString,\r\n bodyHash\r\n ].join('\\n');\r\n const canonicalRequestHash: string = this._getSha256(canonicalRequest);\r\n\r\n const scope: string = `${isoDateString.date}/${this._s3Region}/s3/aws4_request`;\r\n // The string to sign looks like this:\r\n // AWS4-HMAC-SHA256\r\n // 20130524T423589Z\r\n // 20130524/us-east-1/s3/aws4_request\r\n // 7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972\r\n const stringToSign: string = [\r\n 'AWS4-HMAC-SHA256',\r\n isoDateString.dateTime,\r\n scope,\r\n canonicalRequestHash\r\n ].join('\\n');\r\n\r\n const dateKey: Buffer = this._getSha256Hmac(\r\n `AWS4${this._credentials.secretAccessKey}`,\r\n isoDateString.date\r\n );\r\n const dateRegionKey: Buffer = this._getSha256Hmac(dateKey, this._s3Region);\r\n const dateRegionServiceKey: Buffer = this._getSha256Hmac(dateRegionKey, 's3');\r\n const signingKey: Buffer = this._getSha256Hmac(dateRegionServiceKey, 'aws4_request');\r\n const signature: string = this._getSha256Hmac(signingKey, stringToSign, 'hex');\r\n\r\n const authorizationHeader: string = `AWS4-HMAC-SHA256 Credential=${this._credentials.accessKeyId}/${scope},SignedHeaders=${signedHeaderNamesString},Signature=${signature}`;\r\n\r\n headers.set('Authorization', authorizationHeader);\r\n if (this._credentials.sessionToken) {\r\n // Handle signing with temporary credentials (via sts:assume-role)\r\n headers.set('X-Amz-Security-Token', this._credentials.sessionToken);\r\n }\r\n }\r\n\r\n const webFetchOptions: IGetFetchOptions | IPutFetchOptions = {\r\n verb,\r\n headers\r\n };\r\n if (verb === 'PUT') {\r\n (webFetchOptions as IPutFetchOptions).body = body;\r\n }\r\n\r\n const url: string = `${this._s3Endpoint}${canonicalUri}`;\r\n\r\n this._writeDebugLine(Colors.bold(Colors.underline('Sending request to S3')));\r\n this._writeDebugLine(Colors.bold('HOST: '), url);\r\n this._writeDebugLine(Colors.bold('Headers: '));\r\n headers.forEach((value, name) => {\r\n this._writeDebugLine(Colors.cyan(`\\t${name}: ${value}`));\r\n });\r\n\r\n const response: fetch.Response = await this._webClient.fetchAsync(url, webFetchOptions);\r\n\r\n return response;\r\n }\r\n\r\n public _getSha256Hmac(key: string | Buffer, data: string): Buffer;\r\n public _getSha256Hmac(key: string | Buffer, data: string, encoding: 'hex'): string;\r\n public _getSha256Hmac(key: string | Buffer, data: string, encoding?: 'hex'): Buffer | string {\r\n const hash: crypto.Hmac = crypto.createHmac('sha256', key);\r\n hash.update(data);\r\n if (encoding) {\r\n return hash.digest(encoding);\r\n } else {\r\n return hash.digest();\r\n }\r\n }\r\n\r\n private _getSha256(data?: string | Buffer): string {\r\n if (data) {\r\n const hash: crypto.Hash = crypto.createHash('sha256');\r\n hash.update(data);\r\n return hash.digest('hex');\r\n } else {\r\n // This is the null SHA256 hash\r\n return 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';\r\n }\r\n }\r\n\r\n private _getIsoDateString(date: Date = new Date()): IIsoDateString {\r\n let dateString: string = date.toISOString();\r\n dateString = dateString.replace(/[-:]/g, ''); // Remove separator characters\r\n dateString = dateString.substring(0, 15); // Drop milliseconds\r\n\r\n // dateTime is an ISO8601 date. It looks like \"20130524T423589\"\r\n // date is an ISO date. It looks like \"20130524\"\r\n return {\r\n dateTime: `${dateString}Z`,\r\n date: dateString.substring(0, 8)\r\n };\r\n }\r\n\r\n private async _safeReadResponseText(response: fetch.Response): Promise<string | undefined> {\r\n try {\r\n return await response.text();\r\n } catch (err) {\r\n // ignore the error\r\n }\r\n return undefined;\r\n }\r\n\r\n private async _getS3ErrorAsync(response: fetch.Response): Promise<Error> {\r\n const text: string | undefined = await this._safeReadResponseText(response);\r\n return new Error(\r\n `Amazon S3 responded with status code ${response.status} (${response.statusText})${\r\n text ? `\\n${text}` : ''\r\n }`\r\n );\r\n }\r\n\r\n /**\r\n * Validates a S3 endpoint which is http(s):// + hostname + port. Hostname validated according to RFC 1123\r\n * {@link https://docs.aws.amazon.com/general/latest/gr/s3.html}\r\n */\r\n private _validateEndpoint(s3Endpoint: string): void {\r\n let host: string = s3Endpoint;\r\n\r\n if (!s3Endpoint) {\r\n throw new Error('A S3 endpoint must be provided');\r\n }\r\n\r\n if (!s3Endpoint.match(protocolRegex)) {\r\n throw new Error('The S3 endpoint must start with https:// or http://');\r\n }\r\n\r\n host = host.replace(protocolRegex, '');\r\n\r\n if (host.match(/\\//)) {\r\n throw new Error('The path should be omitted from the endpoint. Use s3Prefix to specify a path');\r\n }\r\n\r\n const portMatch: RegExpMatchArray | null = s3Endpoint.match(portRegex);\r\n if (portMatch) {\r\n const port: number = Number(portMatch[1]);\r\n if (Number.isNaN(port) || port > 65535) {\r\n throw new Error(`Port: ${port} is an invalid port number`);\r\n }\r\n host = host.replace(portRegex, '');\r\n }\r\n\r\n if (host.endsWith('.')) {\r\n host = host.slice(0, host.length - 1);\r\n }\r\n\r\n if (host.length > 253) {\r\n throw new Error(\r\n 'The S3 endpoint is too long. RFC 1123 specifies a hostname should be no longer than 253 characters.'\r\n );\r\n }\r\n\r\n const subDomains: string[] = host.split('.');\r\n\r\n const subDomainRegex: RegExp = /^[a-zA-Z0-9-]+$/;\r\n const isValid: boolean = subDomains.every((subDomain) => {\r\n return (\r\n subDomainRegex.test(subDomain) &&\r\n subDomain.length < 64 &&\r\n !subDomain.startsWith('-') &&\r\n !subDomain.endsWith('-')\r\n );\r\n });\r\n\r\n if (!isValid) {\r\n throw new Error(\r\n 'Invalid S3 endpoint. Some part of the hostname contains invalid characters or is too long'\r\n );\r\n }\r\n }\r\n\r\n private async _sendCacheRequestWithRetries<T>(\r\n sendRequest: () => Promise<RetryableRequestResponse<T>>\r\n ): Promise<T> {\r\n const response: RetryableRequestResponse<T> = await sendRequest();\r\n\r\n const log: (...messageParts: (string | IColorableSequence)[]) => void = this._writeDebugLine.bind(this);\r\n\r\n if (response.hasNetworkError) {\r\n if (storageRetryOptions && storageRetryOptions.maxTries > 1) {\r\n log('Network request failed. Will retry request as specified in storageRetryOptions');\r\n async function retry(retryAttempt: number): Promise<T> {\r\n const { retryDelayInMs, retryPolicyType, maxTries, maxRetryDelayInMs } = storageRetryOptions;\r\n let delay: number = retryDelayInMs;\r\n if (retryPolicyType === StorageRetryPolicyType.EXPONENTIAL) {\r\n delay = retryDelayInMs * Math.pow(2, retryAttempt - 1);\r\n }\r\n delay = Math.min(maxRetryDelayInMs, delay);\r\n\r\n log(`Will retry request in ${delay}s...`);\r\n await Async.sleep(delay);\r\n const retryResponse: RetryableRequestResponse<T> = await sendRequest();\r\n\r\n if (retryResponse.hasNetworkError) {\r\n if (retryAttempt < maxTries - 1) {\r\n log('The retried request failed, will try again');\r\n return retry(retryAttempt + 1);\r\n } else {\r\n log('The retried request failed and has reached the maxTries limit');\r\n throw retryResponse.error;\r\n }\r\n }\r\n\r\n return retryResponse.response;\r\n }\r\n return retry(1);\r\n } else {\r\n log('Network request failed and storageRetryOptions is not specified');\r\n throw response.error;\r\n }\r\n }\r\n\r\n return response.response;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"AmazonS3Client.js","sourceRoot":"","sources":["../src/AmazonS3Client.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,oEAAsG;AACtG,+CAAiC;AACjC,kDAAoC;AAIpC,+DAA+E;AAE/E,MAAM,wBAAwB,GAA2B,sBAAsB,CAAC;AAChF,MAAM,gBAAgB,GAAiB,YAAY,CAAC;AACpD,MAAM,gBAAgB,GAAW,MAAM,CAAC;AACxC,MAAM,0BAA0B,GAA2B,sBAAsB,CAAC;AAiBlF,MAAM,aAAa,GAAW,cAAc,CAAC;AAC7C,MAAM,SAAS,GAAW,aAAa,CAAC;AAExC,+HAA+H;AAC/H,IAAK,sBAGJ;AAHD,WAAK,sBAAsB;IACzB,iFAAe,CAAA;IACf,qEAAS,CAAA;AACX,CAAC,EAHI,sBAAsB,KAAtB,sBAAsB,QAG1B;AAUD,MAAM,mBAAmB,GAAyB;IAChD,iBAAiB,EAAE,GAAG,GAAG,IAAI;IAC7B,QAAQ,EAAE,CAAC;IACX,cAAc,EAAE,CAAC,GAAG,IAAI;IACxB,eAAe,EAAE,sBAAsB,CAAC,WAAW;CACpD,CAAC;AAEF;;;;GAIG;AACH,MAAa,cAAc;IASzB,YACE,WAA6C,EAC7C,OAAmD,EACnD,SAAoB,EACpB,QAAmB;QAEnB,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QAElC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,wHAAwH;IACxH,0CAA0C;IACnC,MAAM,CAAC,SAAS,CAAC,KAAa;QACnC,IAAI,MAAM,GAAW,EAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;YAChD,MAAM,EAAE,GAAW,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE;gBAClC,MAAM,IAAI,EAAE,CAAC;aACd;iBAAM;gBACL,IAAI,EAAE,KAAK,GAAG,EAAE;oBACd,MAAM,IAAI,KAAK,CAAC;iBACjB;qBAAM;oBACL,MAAM,IAAI,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;iBAC7D;aACF;SACF;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,MAAM,CAAC,yBAAyB,CACrC,gBAAoC;QAEpC,OAAO,IAAA,iCAAW,EAAC,gBAAgB,CAAC,CAAC;IACvC,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAkB;QAC5C,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAAC;QAC/C,OAAO,MAAM,IAAI,CAAC,4BAA4B,CAAC,KAAK,IAAI,EAAE;YACxD,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YACjF,IAAI,QAAQ,CAAC,EAAE,EAAE;gBACf,OAAO;oBACL,eAAe,EAAE,KAAK;oBACtB,QAAQ,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE;iBAClC,CAAC;aACH;iBAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;gBAClC,OAAO;oBACL,eAAe,EAAE,KAAK;oBACtB,QAAQ,EAAE,SAAS;iBACpB,CAAC;aACH;iBAAM,IACL,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;gBAC/E,CAAC,IAAI,CAAC,YAAY,EAClB;gBACA,iDAAiD;gBACjD,4EAA4E;gBAC5E,IAAI,CAAC,iBAAiB,CACpB,uCAAuC,QAAQ,CAAC,MAAM,EAAE,EACxD,wCAAwC,EACxC,0CAA0C,EAC1C,6CAA6C,CAC9C,CAAC;gBACF,OAAO;oBACL,eAAe,EAAE,KAAK;oBACtB,QAAQ,EAAE,SAAS;iBACpB,CAAC;aACH;iBAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;gBACxF,MAAM,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;aAC7C;iBAAM;gBACL,MAAM,KAAK,GAAU,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAC3D,OAAO;oBACL,eAAe,EAAE,IAAI;oBACrB,KAAK;iBACN,CAAC;aACH;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAAC,UAAkB,EAAE,YAAoB;QACrE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;SACtE;QAED,MAAM,IAAI,CAAC,4BAA4B,CAAC,KAAK,IAAI,EAAE;YACjD,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;YAC/F,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBAChB,OAAO;oBACL,eAAe,EAAE,IAAI;oBACrB,KAAK,EAAE,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;iBAC7C,CAAC;aACH;YACD,OAAO;gBACL,eAAe,EAAE,KAAK;gBACtB,QAAQ,EAAE,SAAS;aACpB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,GAAG,YAA6C;QACtE,4EAA4E;QAC5E,IAAI;YACF,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,CAAC;SAChD;QAAC,OAAO,GAAG,EAAE;YACZ,eAAe;SAChB;IACH,CAAC;IAEO,iBAAiB,CAAC,GAAG,YAA6C;QACxE,8EAA8E;QAC9E,IAAI;YACF,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,YAAY,CAAC,CAAC;SAClD;QAAC,OAAO,GAAG,EAAE;YACZ,eAAe;SAChB;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,IAAmB,EACnB,UAAkB,EAClB,IAAa;QAEb,MAAM,aAAa,GAAmB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/D,MAAM,QAAQ,GAAW,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAkB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC;QAEhD,mEAAmE;QACnE,MAAM,IAAI,GAAW,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,YAAY,GAAW,cAAc,CAAC,SAAS,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,CAAC,CAAC;QAEnE,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,sHAAsH;YACtH,MAAM,gBAAgB,GAAa;gBACjC,GAAG,gBAAgB,IAAI,IAAI,EAAE;gBAC7B,GAAG,wBAAwB,IAAI,QAAQ,EAAE;gBACzC,GAAG,gBAAgB,IAAI,aAAa,CAAC,QAAQ,EAAE;aAChD,CAAC;YAEF,kEAAkE;YAClE,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE;gBAClC,gBAAgB,CAAC,IAAI,CAAC,GAAG,0BAA0B,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;aAC1F;YAED,sDAAsD;YACtD,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;gBACzC,MAAM,WAAW,GAAW,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,MAAM,WAAW,GAAW,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,IAAI,WAAW,GAAG,WAAW,EAAE;oBAC7B,OAAO,CAAC,CAAC,CAAC;iBACX;gBACD,IAAI,WAAW,GAAG,WAAW,EAAE;oBAC7B,OAAO,CAAC,CAAC;iBACV;gBACD,OAAO,CAAC,CAAC;YACX,CAAC,CAAC,CAAC;YAEH,gEAAgE;YAChE,MAAM,uBAAuB,GAAW,gBAAgB;iBACrD,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;gBACd,MAAM,UAAU,GAAW,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChD,OAAO,UAAU,CAAC;YACpB,CAAC,CAAC;iBACD,IAAI,CAAC,GAAG,CAAC,CAAC;YAEb,yCAAyC;YACzC,OAAO;YACP,YAAY;YACZ,EAAE;YACF,sCAAsC;YACtC,kBAAkB;YAClB,wFAAwF;YACxF,8BAA8B;YAC9B,EAAE;YACF,6CAA6C;YAC7C,mEAAmE;YACnE,MAAM,gBAAgB,GAAW;gBAC/B,IAAI;gBACJ,YAAY;gBACZ,EAAE;gBACF,GAAG,gBAAgB;gBACnB,EAAE;gBACF,uBAAuB;gBACvB,QAAQ;aACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,MAAM,oBAAoB,GAAW,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YAEvE,MAAM,KAAK,GAAW,GAAG,aAAa,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,kBAAkB,CAAC;YAChF,sCAAsC;YACtC,mBAAmB;YACnB,mBAAmB;YACnB,qCAAqC;YACrC,mEAAmE;YACnE,MAAM,YAAY,GAAW;gBAC3B,kBAAkB;gBAClB,aAAa,CAAC,QAAQ;gBACtB,KAAK;gBACL,oBAAoB;aACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,OAAO,GAAW,IAAI,CAAC,cAAc,CACzC,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,EAC1C,aAAa,CAAC,IAAI,CACnB,CAAC;YACF,MAAM,aAAa,GAAW,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3E,MAAM,oBAAoB,GAAW,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;YAC9E,MAAM,UAAU,GAAW,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;YACrF,MAAM,SAAS,GAAW,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;YAE/E,MAAM,mBAAmB,GAAW,+BAA+B,IAAI,CAAC,YAAY,CAAC,WAAW,IAAI,KAAK,kBAAkB,uBAAuB,cAAc,SAAS,EAAE,CAAC;YAE5K,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;YAClD,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE;gBAClC,kEAAkE;gBAClE,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;aACrE;SACF;QAED,MAAM,eAAe,GAAwC;YAC3D,IAAI;YACJ,OAAO;SACR,CAAC;QACF,IAAI,IAAI,KAAK,KAAK,EAAE;YACjB,eAAoC,CAAC,IAAI,GAAG,IAAI,CAAC;SACnD;QAED,MAAM,GAAG,GAAW,GAAG,IAAI,CAAC,WAAW,GAAG,YAAY,EAAE,CAAC;QAEzD,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,0BAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC9B,IAAI,CAAC,eAAe,CAAC,0BAAM,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAExF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAIM,cAAc,CAAC,GAAoB,EAAE,IAAY,EAAE,QAAgB;QACxE,MAAM,IAAI,GAAgB,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,QAAQ,EAAE;YACZ,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;SAC9B;aAAM;YACL,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;SACtB;IACH,CAAC;IAEO,UAAU,CAAC,IAAsB;QACvC,IAAI,IAAI,EAAE;YACR,MAAM,IAAI,GAAgB,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SAC3B;aAAM;YACL,+BAA+B;YAC/B,OAAO,kEAAkE,CAAC;SAC3E;IACH,CAAC;IAEO,iBAAiB,CAAC,OAAa,IAAI,IAAI,EAAE;QAC/C,IAAI,UAAU,GAAW,IAAI,CAAC,WAAW,EAAE,CAAC;QAC5C,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,8BAA8B;QAC5E,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB;QAE9D,+DAA+D;QAC/D,gDAAgD;QAChD,OAAO;YACL,QAAQ,EAAE,GAAG,UAAU,GAAG;YAC1B,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;SACjC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAAC,QAAwB;QAC1D,IAAI;YACF,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;SAC9B;QAAC,OAAO,GAAG,EAAE;YACZ,mBAAmB;SACpB;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,QAAwB;QACrD,MAAM,IAAI,GAAuB,MAAM,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAC5E,OAAO,IAAI,KAAK,CACd,wCAAwC,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,IAC7E,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EACvB,EAAE,CACH,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,iBAAiB,CAAC,UAAkB;QAC1C,IAAI,IAAI,GAAW,UAAU,CAAC;QAE9B,IAAI,CAAC,UAAU,EAAE;YACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;SACnD;QAED,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;YACpC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;SACxE;QAED,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAEvC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YACpB,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;SACjG;QAED,MAAM,SAAS,GAA4B,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvE,IAAI,SAAS,EAAE;YACb,MAAM,IAAI,GAAW,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE;gBACtC,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,4BAA4B,CAAC,CAAC;aAC5D;YACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;SACpC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YACtB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;SACvC;QAED,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE;YACrB,MAAM,IAAI,KAAK,CACb,qGAAqG,CACtG,CAAC;SACH;QAED,MAAM,UAAU,GAAa,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE7C,MAAM,cAAc,GAAW,iBAAiB,CAAC;QACjD,MAAM,OAAO,GAAY,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,EAAE;YACtD,OAAO,CACL,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC9B,SAAS,CAAC,MAAM,GAAG,EAAE;gBACrB,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;gBAC1B,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CACzB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CACb,2FAA2F,CAC5F,CAAC;SACH;IACH,CAAC;IAEO,KAAK,CAAC,4BAA4B,CACxC,WAAuD;QAEvD,MAAM,QAAQ,GAAgC,MAAM,WAAW,EAAE,CAAC;QAElE,MAAM,GAAG,GAA+D,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAExG,IAAI,QAAQ,CAAC,eAAe,EAAE;YAC5B,IAAI,mBAAmB,IAAI,mBAAmB,CAAC,QAAQ,GAAG,CAAC,EAAE;gBAC3D,GAAG,CAAC,gFAAgF,CAAC,CAAC;gBACtF,KAAK,UAAU,KAAK,CAAC,YAAoB;oBACvC,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,mBAAmB,CAAC;oBAC7F,IAAI,KAAK,GAAW,cAAc,CAAC;oBACnC,IAAI,eAAe,KAAK,sBAAsB,CAAC,WAAW,EAAE;wBAC1D,KAAK,GAAG,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;qBACxD;oBACD,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;oBAE3C,GAAG,CAAC,yBAAyB,KAAK,MAAM,CAAC,CAAC;oBAC1C,MAAM,yBAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBACzB,MAAM,aAAa,GAAgC,MAAM,WAAW,EAAE,CAAC;oBAEvE,IAAI,aAAa,CAAC,eAAe,EAAE;wBACjC,IAAI,YAAY,GAAG,QAAQ,GAAG,CAAC,EAAE;4BAC/B,GAAG,CAAC,4CAA4C,CAAC,CAAC;4BAClD,OAAO,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;yBAChC;6BAAM;4BACL,GAAG,CAAC,+DAA+D,CAAC,CAAC;4BACrE,MAAM,aAAa,CAAC,KAAK,CAAC;yBAC3B;qBACF;oBAED,OAAO,aAAa,CAAC,QAAQ,CAAC;gBAChC,CAAC;gBACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;aACjB;iBAAM;gBACL,GAAG,CAAC,iEAAiE,CAAC,CAAC;gBACvE,MAAM,QAAQ,CAAC,KAAK,CAAC;aACtB;SACF;QAED,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAC3B,CAAC;CACF;AA5ZD,wCA4ZC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Async, Colors, type IColorableSequence, type ITerminal } from '@rushstack/node-core-library';\nimport * as crypto from 'crypto';\nimport * as fetch from 'node-fetch';\n\nimport type { IAmazonS3BuildCacheProviderOptionsAdvanced } from './AmazonS3BuildCacheProvider';\nimport type { IGetFetchOptions, IPutFetchOptions, WebClient } from './WebClient';\nimport { type IAmazonS3Credentials, fromRushEnv } from './AmazonS3Credentials';\n\nconst CONTENT_HASH_HEADER_NAME: 'x-amz-content-sha256' = 'x-amz-content-sha256';\nconst DATE_HEADER_NAME: 'x-amz-date' = 'x-amz-date';\nconst HOST_HEADER_NAME: 'host' = 'host';\nconst SECURITY_TOKEN_HEADER_NAME: 'x-amz-security-token' = 'x-amz-security-token';\n\ninterface IIsoDateString {\n date: string;\n dateTime: string;\n}\n\ntype RetryableRequestResponse<T> =\n | {\n hasNetworkError: true;\n error: Error;\n }\n | {\n hasNetworkError: false;\n response: T;\n };\n\nconst protocolRegex: RegExp = /^https?:\\/\\//;\nconst portRegex: RegExp = /:(\\d{1,5})$/;\n\n// Similar to https://docs.microsoft.com/en-us/javascript/api/@azure/storage-blob/storageretrypolicytype?view=azure-node-latest\nenum StorageRetryPolicyType {\n EXPONENTIAL = 0,\n FIXED = 1\n}\n\n// Similar to https://docs.microsoft.com/en-us/javascript/api/@azure/storage-blob/storageretryoptions?view=azure-node-latest\ninterface IStorageRetryOptions {\n maxRetryDelayInMs: number;\n maxTries: number;\n retryDelayInMs: number;\n retryPolicyType: StorageRetryPolicyType;\n}\n\nconst storageRetryOptions: IStorageRetryOptions = {\n maxRetryDelayInMs: 120 * 1000,\n maxTries: 4,\n retryDelayInMs: 4 * 1000,\n retryPolicyType: StorageRetryPolicyType.EXPONENTIAL\n};\n\n/**\n * A helper for reading and updating objects on Amazon S3\n *\n * @public\n */\nexport class AmazonS3Client {\n private readonly _credentials: IAmazonS3Credentials | undefined;\n private readonly _s3Endpoint: string;\n private readonly _s3Region: string;\n\n private readonly _webClient: WebClient;\n\n private readonly _terminal: ITerminal;\n\n public constructor(\n credentials: IAmazonS3Credentials | undefined,\n options: IAmazonS3BuildCacheProviderOptionsAdvanced,\n webClient: WebClient,\n terminal: ITerminal\n ) {\n this._credentials = credentials;\n this._terminal = terminal;\n\n this._validateEndpoint(options.s3Endpoint);\n\n this._s3Endpoint = options.s3Endpoint;\n this._s3Region = options.s3Region;\n\n this._webClient = webClient;\n }\n\n // https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html#create-signature-presign-entire-payload\n // We want to keep all slashes non encoded\n public static UriEncode(input: string): string {\n let output: string = '';\n for (let i: number = 0; i < input.length; i += 1) {\n const ch: string = input[i];\n if (ch.match(/[A-Za-z0-9~._-]|\\//)) {\n output += ch;\n } else {\n if (ch === ' ') {\n output += '%20';\n } else {\n output += `%${ch.charCodeAt(0).toString(16).toUpperCase()}`;\n }\n }\n }\n return output;\n }\n\n public static tryDeserializeCredentials(\n credentialString: string | undefined\n ): IAmazonS3Credentials | undefined {\n return fromRushEnv(credentialString);\n }\n\n public async getObjectAsync(objectName: string): Promise<Buffer | undefined> {\n this._writeDebugLine('Reading object from S3');\n return await this._sendCacheRequestWithRetries(async () => {\n const response: fetch.Response = await this._makeRequestAsync('GET', objectName);\n if (response.ok) {\n return {\n hasNetworkError: false,\n response: await response.buffer()\n };\n } else if (response.status === 404) {\n return {\n hasNetworkError: false,\n response: undefined\n };\n } else if (\n (response.status === 400 || response.status === 401 || response.status === 403) &&\n !this._credentials\n ) {\n // unauthorized due to not providing credentials,\n // silence error for better DX when e.g. running locally without credentials\n this._writeWarningLine(\n `No credentials found and received a ${response.status}`,\n ' response code from the cloud storage.',\n ' Maybe run rush update-cloud-credentials',\n ' or set the RUSH_BUILD_CACHE_CREDENTIAL env'\n );\n return {\n hasNetworkError: false,\n response: undefined\n };\n } else if (response.status === 400 || response.status === 401 || response.status === 403) {\n throw await this._getS3ErrorAsync(response);\n } else {\n const error: Error = await this._getS3ErrorAsync(response);\n return {\n hasNetworkError: true,\n error\n };\n }\n });\n }\n\n public async uploadObjectAsync(objectName: string, objectBuffer: Buffer): Promise<void> {\n if (!this._credentials) {\n throw new Error('Credentials are required to upload objects to S3.');\n }\n\n await this._sendCacheRequestWithRetries(async () => {\n const response: fetch.Response = await this._makeRequestAsync('PUT', objectName, objectBuffer);\n if (!response.ok) {\n return {\n hasNetworkError: true,\n error: await this._getS3ErrorAsync(response)\n };\n }\n return {\n hasNetworkError: false,\n response: undefined\n };\n });\n }\n\n private _writeDebugLine(...messageParts: (string | IColorableSequence)[]): void {\n // if the terminal has been closed then don't bother sending a debug message\n try {\n this._terminal.writeDebugLine(...messageParts);\n } catch (err) {\n // ignore error\n }\n }\n\n private _writeWarningLine(...messageParts: (string | IColorableSequence)[]): void {\n // if the terminal has been closed then don't bother sending a warning message\n try {\n this._terminal.writeWarningLine(...messageParts);\n } catch (err) {\n // ignore error\n }\n }\n\n private async _makeRequestAsync(\n verb: 'GET' | 'PUT',\n objectName: string,\n body?: Buffer\n ): Promise<fetch.Response> {\n const isoDateString: IIsoDateString = this._getIsoDateString();\n const bodyHash: string = this._getSha256(body);\n const headers: fetch.Headers = new fetch.Headers();\n headers.set(DATE_HEADER_NAME, isoDateString.dateTime);\n headers.set(CONTENT_HASH_HEADER_NAME, bodyHash);\n\n // the host can be e.g. https://s3.aws.com or http://localhost:9000\n const host: string = this._s3Endpoint.replace(protocolRegex, '');\n const canonicalUri: string = AmazonS3Client.UriEncode(`/${objectName}`);\n this._writeDebugLine(Colors.bold('Canonical URI: '), canonicalUri);\n\n if (this._credentials) {\n // Compute the authorization header. See https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n const canonicalHeaders: string[] = [\n `${HOST_HEADER_NAME}:${host}`,\n `${CONTENT_HASH_HEADER_NAME}:${bodyHash}`,\n `${DATE_HEADER_NAME}:${isoDateString.dateTime}`\n ];\n\n // Handle signing with temporary credentials (via sts:assume-role)\n if (this._credentials.sessionToken) {\n canonicalHeaders.push(`${SECURITY_TOKEN_HEADER_NAME}:${this._credentials.sessionToken}`);\n }\n\n // the canonical headers must be sorted by header name\n canonicalHeaders.sort((aHeader, bHeader) => {\n const aHeaderName: string = aHeader.split(':')[0];\n const bHeaderName: string = bHeader.split(':')[0];\n if (aHeaderName < bHeaderName) {\n return -1;\n }\n if (aHeaderName > bHeaderName) {\n return 1;\n }\n return 0;\n });\n\n // the singed header names are derived from the canonicalHeaders\n const signedHeaderNamesString: string = canonicalHeaders\n .map((header) => {\n const headerName: string = header.split(':')[0];\n return headerName;\n })\n .join(';');\n\n // The canonical request looks like this:\n // GET\n // /test.txt\n //\n // host:examplebucket.s3.amazonaws.com\n // range:bytes=0-9\n // x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n // x-amz-date:20130524T000000Z\n //\n // host;range;x-amz-content-sha256;x-amz-date\n // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n const canonicalRequest: string = [\n verb,\n canonicalUri,\n '', // we don't use query strings for these requests\n ...canonicalHeaders,\n '',\n signedHeaderNamesString,\n bodyHash\n ].join('\\n');\n const canonicalRequestHash: string = this._getSha256(canonicalRequest);\n\n const scope: string = `${isoDateString.date}/${this._s3Region}/s3/aws4_request`;\n // The string to sign looks like this:\n // AWS4-HMAC-SHA256\n // 20130524T423589Z\n // 20130524/us-east-1/s3/aws4_request\n // 7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972\n const stringToSign: string = [\n 'AWS4-HMAC-SHA256',\n isoDateString.dateTime,\n scope,\n canonicalRequestHash\n ].join('\\n');\n\n const dateKey: Buffer = this._getSha256Hmac(\n `AWS4${this._credentials.secretAccessKey}`,\n isoDateString.date\n );\n const dateRegionKey: Buffer = this._getSha256Hmac(dateKey, this._s3Region);\n const dateRegionServiceKey: Buffer = this._getSha256Hmac(dateRegionKey, 's3');\n const signingKey: Buffer = this._getSha256Hmac(dateRegionServiceKey, 'aws4_request');\n const signature: string = this._getSha256Hmac(signingKey, stringToSign, 'hex');\n\n const authorizationHeader: string = `AWS4-HMAC-SHA256 Credential=${this._credentials.accessKeyId}/${scope},SignedHeaders=${signedHeaderNamesString},Signature=${signature}`;\n\n headers.set('Authorization', authorizationHeader);\n if (this._credentials.sessionToken) {\n // Handle signing with temporary credentials (via sts:assume-role)\n headers.set('X-Amz-Security-Token', this._credentials.sessionToken);\n }\n }\n\n const webFetchOptions: IGetFetchOptions | IPutFetchOptions = {\n verb,\n headers\n };\n if (verb === 'PUT') {\n (webFetchOptions as IPutFetchOptions).body = body;\n }\n\n const url: string = `${this._s3Endpoint}${canonicalUri}`;\n\n this._writeDebugLine(Colors.bold(Colors.underline('Sending request to S3')));\n this._writeDebugLine(Colors.bold('HOST: '), url);\n this._writeDebugLine(Colors.bold('Headers: '));\n headers.forEach((value, name) => {\n this._writeDebugLine(Colors.cyan(`\\t${name}: ${value}`));\n });\n\n const response: fetch.Response = await this._webClient.fetchAsync(url, webFetchOptions);\n\n return response;\n }\n\n public _getSha256Hmac(key: string | Buffer, data: string): Buffer;\n public _getSha256Hmac(key: string | Buffer, data: string, encoding: 'hex'): string;\n public _getSha256Hmac(key: string | Buffer, data: string, encoding?: 'hex'): Buffer | string {\n const hash: crypto.Hmac = crypto.createHmac('sha256', key);\n hash.update(data);\n if (encoding) {\n return hash.digest(encoding);\n } else {\n return hash.digest();\n }\n }\n\n private _getSha256(data?: string | Buffer): string {\n if (data) {\n const hash: crypto.Hash = crypto.createHash('sha256');\n hash.update(data);\n return hash.digest('hex');\n } else {\n // This is the null SHA256 hash\n return 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';\n }\n }\n\n private _getIsoDateString(date: Date = new Date()): IIsoDateString {\n let dateString: string = date.toISOString();\n dateString = dateString.replace(/[-:]/g, ''); // Remove separator characters\n dateString = dateString.substring(0, 15); // Drop milliseconds\n\n // dateTime is an ISO8601 date. It looks like \"20130524T423589\"\n // date is an ISO date. It looks like \"20130524\"\n return {\n dateTime: `${dateString}Z`,\n date: dateString.substring(0, 8)\n };\n }\n\n private async _safeReadResponseText(response: fetch.Response): Promise<string | undefined> {\n try {\n return await response.text();\n } catch (err) {\n // ignore the error\n }\n return undefined;\n }\n\n private async _getS3ErrorAsync(response: fetch.Response): Promise<Error> {\n const text: string | undefined = await this._safeReadResponseText(response);\n return new Error(\n `Amazon S3 responded with status code ${response.status} (${response.statusText})${\n text ? `\\n${text}` : ''\n }`\n );\n }\n\n /**\n * Validates a S3 endpoint which is http(s):// + hostname + port. Hostname validated according to RFC 1123\n * {@link https://docs.aws.amazon.com/general/latest/gr/s3.html}\n */\n private _validateEndpoint(s3Endpoint: string): void {\n let host: string = s3Endpoint;\n\n if (!s3Endpoint) {\n throw new Error('A S3 endpoint must be provided');\n }\n\n if (!s3Endpoint.match(protocolRegex)) {\n throw new Error('The S3 endpoint must start with https:// or http://');\n }\n\n host = host.replace(protocolRegex, '');\n\n if (host.match(/\\//)) {\n throw new Error('The path should be omitted from the endpoint. Use s3Prefix to specify a path');\n }\n\n const portMatch: RegExpMatchArray | null = s3Endpoint.match(portRegex);\n if (portMatch) {\n const port: number = Number(portMatch[1]);\n if (Number.isNaN(port) || port > 65535) {\n throw new Error(`Port: ${port} is an invalid port number`);\n }\n host = host.replace(portRegex, '');\n }\n\n if (host.endsWith('.')) {\n host = host.slice(0, host.length - 1);\n }\n\n if (host.length > 253) {\n throw new Error(\n 'The S3 endpoint is too long. RFC 1123 specifies a hostname should be no longer than 253 characters.'\n );\n }\n\n const subDomains: string[] = host.split('.');\n\n const subDomainRegex: RegExp = /^[a-zA-Z0-9-]+$/;\n const isValid: boolean = subDomains.every((subDomain) => {\n return (\n subDomainRegex.test(subDomain) &&\n subDomain.length < 64 &&\n !subDomain.startsWith('-') &&\n !subDomain.endsWith('-')\n );\n });\n\n if (!isValid) {\n throw new Error(\n 'Invalid S3 endpoint. Some part of the hostname contains invalid characters or is too long'\n );\n }\n }\n\n private async _sendCacheRequestWithRetries<T>(\n sendRequest: () => Promise<RetryableRequestResponse<T>>\n ): Promise<T> {\n const response: RetryableRequestResponse<T> = await sendRequest();\n\n const log: (...messageParts: (string | IColorableSequence)[]) => void = this._writeDebugLine.bind(this);\n\n if (response.hasNetworkError) {\n if (storageRetryOptions && storageRetryOptions.maxTries > 1) {\n log('Network request failed. Will retry request as specified in storageRetryOptions');\n async function retry(retryAttempt: number): Promise<T> {\n const { retryDelayInMs, retryPolicyType, maxTries, maxRetryDelayInMs } = storageRetryOptions;\n let delay: number = retryDelayInMs;\n if (retryPolicyType === StorageRetryPolicyType.EXPONENTIAL) {\n delay = retryDelayInMs * Math.pow(2, retryAttempt - 1);\n }\n delay = Math.min(maxRetryDelayInMs, delay);\n\n log(`Will retry request in ${delay}s...`);\n await Async.sleep(delay);\n const retryResponse: RetryableRequestResponse<T> = await sendRequest();\n\n if (retryResponse.hasNetworkError) {\n if (retryAttempt < maxTries - 1) {\n log('The retried request failed, will try again');\n return retry(retryAttempt + 1);\n } else {\n log('The retried request failed and has reached the maxTries limit');\n throw retryResponse.error;\n }\n }\n\n return retryResponse.response;\n }\n return retry(1);\n } else {\n log('Network request failed and storageRetryOptions is not specified');\n throw response.error;\n }\n }\n\n return response.response;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AmazonS3Credentials.js","sourceRoot":"","sources":["../src/AmazonS3Credentials.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,kDAA+D;AAElD,QAAA,iBAAiB,GAAwB,mBAAmB,CAAC;AAC7D,QAAA,qBAAqB,GAA4B,uBAAuB,CAAC;AACzE,QAAA,iBAAiB,GAAwB,mBAAmB,CAAC;AAa1E;;GAEG;AACI,MAAM,aAAa,GAAG,GAAqC,EAAE;IAClE,MAAM,WAAW,GAAuB,OAAO,CAAC,GAAG,CAAC,yBAAiB,CAAC,CAAC;IACvE,MAAM,eAAe,GAAuB,OAAO,CAAC,GAAG,CAAC,6BAAqB,CAAC,CAAC;IAC/E,MAAM,YAAY,GAAuB,OAAO,CAAC,GAAG,CAAC,yBAAiB,CAAC,CAAC;IAExE,IAAI,WAAW,IAAI,eAAe,EAAE;QAClC,OAAO;YACL,WAAW;YACX,eAAe;YACf,YAAY;SACb,CAAC;KACH;SAAM,IAAI,WAAW,EAAE;QACtB,MAAM,IAAI,KAAK,CACb,QAAQ,yBAAiB,mCAAmC,6BAAqB,IAAI;YACnF,4DAA4D,CAC/D,CAAC;KACH;SAAM,IAAI,eAAe,EAAE;QAC1B,MAAM,IAAI,KAAK,CACb,QAAQ,6BAAqB,mCAAmC,yBAAiB,IAAI;YACnF,4DAA4D,CAC/D,CAAC;KACH;SAAM;QACL,OAAO,SAAS,CAAC;KAClB;AACH,CAAC,CAAC;AAxBW,QAAA,aAAa,iBAwBxB;AAEF;;GAEG;AACI,MAAM,WAAW,GAAG,CACzB,UAAU,GAAG,mCAAwB,CAAC,oBAAoB,EACxB,EAAE;IACpC,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,MAAM,GAAa,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;QAC1C,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;KAC5E;IAED,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;KACxB,CAAC;AACJ,CAAC,CAAC;AAjBW,QAAA,WAAW,eAiBtB","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { EnvironmentConfiguration } from '@rushstack/rush-sdk';\r\n\r\nexport const AWS_ACCESS_KEY_ID: 'AWS_ACCESS_KEY_ID' = 'AWS_ACCESS_KEY_ID';\r\nexport const AWS_SECRET_ACCESS_KEY: 'AWS_SECRET_ACCESS_KEY' = 'AWS_SECRET_ACCESS_KEY';\r\nexport const AWS_SESSION_TOKEN: 'AWS_SESSION_TOKEN' = 'AWS_SESSION_TOKEN';\r\n\r\n/**\r\n * Credentials for authorizing and signing requests to an Amazon S3 endpoint.\r\n *\r\n * @public\r\n */\r\nexport interface IAmazonS3Credentials {\r\n accessKeyId: string;\r\n secretAccessKey: string;\r\n sessionToken: string | undefined;\r\n}\r\n\r\n/**\r\n * Attempt to read credentials from the commonly used AWS_* env vars.\r\n */\r\nexport const fromAmazonEnv = (): IAmazonS3Credentials | undefined => {\r\n const accessKeyId: string | undefined = process.env[AWS_ACCESS_KEY_ID];\r\n const secretAccessKey: string | undefined = process.env[AWS_SECRET_ACCESS_KEY];\r\n const sessionToken: string | undefined = process.env[AWS_SESSION_TOKEN];\r\n\r\n if (accessKeyId && secretAccessKey) {\r\n return {\r\n accessKeyId,\r\n secretAccessKey,\r\n sessionToken\r\n };\r\n } else if (accessKeyId) {\r\n throw new Error(\r\n `The \"${AWS_ACCESS_KEY_ID}\" env variable is set, but the \"${AWS_SECRET_ACCESS_KEY}\" ` +\r\n `env variable is not set. Both or neither must be provided.`\r\n );\r\n } else if (secretAccessKey) {\r\n throw new Error(\r\n `The \"${AWS_SECRET_ACCESS_KEY}\" env variable is set, but the \"${AWS_ACCESS_KEY_ID}\" ` +\r\n `env variable is not set. Both or neither must be provided.`\r\n );\r\n } else {\r\n return undefined;\r\n }\r\n};\r\n\r\n/**\r\n * Attempt to parse credentials set from the RUSH_BUILD_CACHE_CREDENTIAL env var.\r\n */\r\nexport const fromRushEnv = (\r\n credential = EnvironmentConfiguration.buildCacheCredential\r\n): IAmazonS3Credentials | undefined => {\r\n if (!credential) {\r\n return undefined;\r\n }\r\n\r\n const fields: string[] = credential.split(':');\r\n if (fields.length < 2 || fields.length > 3) {\r\n throw new Error(`Rush build cache credential is in an unexpected format.`);\r\n }\r\n\r\n return {\r\n accessKeyId: fields[0],\r\n secretAccessKey: fields[1],\r\n sessionToken: fields[2]\r\n };\r\n};\r\n"]}
1
+ {"version":3,"file":"AmazonS3Credentials.js","sourceRoot":"","sources":["../src/AmazonS3Credentials.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,kDAA+D;AAElD,QAAA,iBAAiB,GAAwB,mBAAmB,CAAC;AAC7D,QAAA,qBAAqB,GAA4B,uBAAuB,CAAC;AACzE,QAAA,iBAAiB,GAAwB,mBAAmB,CAAC;AAa1E;;GAEG;AACI,MAAM,aAAa,GAAG,GAAqC,EAAE;IAClE,MAAM,WAAW,GAAuB,OAAO,CAAC,GAAG,CAAC,yBAAiB,CAAC,CAAC;IACvE,MAAM,eAAe,GAAuB,OAAO,CAAC,GAAG,CAAC,6BAAqB,CAAC,CAAC;IAC/E,MAAM,YAAY,GAAuB,OAAO,CAAC,GAAG,CAAC,yBAAiB,CAAC,CAAC;IAExE,IAAI,WAAW,IAAI,eAAe,EAAE;QAClC,OAAO;YACL,WAAW;YACX,eAAe;YACf,YAAY;SACb,CAAC;KACH;SAAM,IAAI,WAAW,EAAE;QACtB,MAAM,IAAI,KAAK,CACb,QAAQ,yBAAiB,mCAAmC,6BAAqB,IAAI;YACnF,4DAA4D,CAC/D,CAAC;KACH;SAAM,IAAI,eAAe,EAAE;QAC1B,MAAM,IAAI,KAAK,CACb,QAAQ,6BAAqB,mCAAmC,yBAAiB,IAAI;YACnF,4DAA4D,CAC/D,CAAC;KACH;SAAM;QACL,OAAO,SAAS,CAAC;KAClB;AACH,CAAC,CAAC;AAxBW,QAAA,aAAa,iBAwBxB;AAEF;;GAEG;AACI,MAAM,WAAW,GAAG,CACzB,UAAU,GAAG,mCAAwB,CAAC,oBAAoB,EACxB,EAAE;IACpC,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,MAAM,GAAa,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;QAC1C,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;KAC5E;IAED,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;KACxB,CAAC;AACJ,CAAC,CAAC;AAjBW,QAAA,WAAW,eAiBtB","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { EnvironmentConfiguration } from '@rushstack/rush-sdk';\n\nexport const AWS_ACCESS_KEY_ID: 'AWS_ACCESS_KEY_ID' = 'AWS_ACCESS_KEY_ID';\nexport const AWS_SECRET_ACCESS_KEY: 'AWS_SECRET_ACCESS_KEY' = 'AWS_SECRET_ACCESS_KEY';\nexport const AWS_SESSION_TOKEN: 'AWS_SESSION_TOKEN' = 'AWS_SESSION_TOKEN';\n\n/**\n * Credentials for authorizing and signing requests to an Amazon S3 endpoint.\n *\n * @public\n */\nexport interface IAmazonS3Credentials {\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken: string | undefined;\n}\n\n/**\n * Attempt to read credentials from the commonly used AWS_* env vars.\n */\nexport const fromAmazonEnv = (): IAmazonS3Credentials | undefined => {\n const accessKeyId: string | undefined = process.env[AWS_ACCESS_KEY_ID];\n const secretAccessKey: string | undefined = process.env[AWS_SECRET_ACCESS_KEY];\n const sessionToken: string | undefined = process.env[AWS_SESSION_TOKEN];\n\n if (accessKeyId && secretAccessKey) {\n return {\n accessKeyId,\n secretAccessKey,\n sessionToken\n };\n } else if (accessKeyId) {\n throw new Error(\n `The \"${AWS_ACCESS_KEY_ID}\" env variable is set, but the \"${AWS_SECRET_ACCESS_KEY}\" ` +\n `env variable is not set. Both or neither must be provided.`\n );\n } else if (secretAccessKey) {\n throw new Error(\n `The \"${AWS_SECRET_ACCESS_KEY}\" env variable is set, but the \"${AWS_ACCESS_KEY_ID}\" ` +\n `env variable is not set. Both or neither must be provided.`\n );\n } else {\n return undefined;\n }\n};\n\n/**\n * Attempt to parse credentials set from the RUSH_BUILD_CACHE_CREDENTIAL env var.\n */\nexport const fromRushEnv = (\n credential = EnvironmentConfiguration.buildCacheCredential\n): IAmazonS3Credentials | undefined => {\n if (!credential) {\n return undefined;\n }\n\n const fields: string[] = credential.split(':');\n if (fields.length < 2 || fields.length > 3) {\n throw new Error(`Rush build cache credential is in an unexpected format.`);\n }\n\n return {\n accessKeyId: fields[0],\n secretAccessKey: fields[1],\n sessionToken: fields[2]\n };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"RushAmazonS3BuildCachePlugin.js","sourceRoot":"","sources":["../src/RushAmazonS3BuildCachePlugin.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;AAQ3D,MAAM,WAAW,GAAW,0BAA0B,CAAC;AAgCvD;;GAEG;AACH,MAAa,4BAA4B;IAAzC;QACS,eAAU,GAAW,WAAW,CAAC;IAqD1C,CAAC;IAnDQ,KAAK,CAAC,WAAwB,EAAE,UAA6B;QAClE,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE;YACjD,WAAW,CAAC,sCAAsC,CAAC,WAAW,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE;gBAIzF,MAAM,EAAE,qBAAqB,EAAE,GAAG,gBAA+B,CAAC;gBAClE,IAAI,OAGS,CAAC;gBACd,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,qBAAqB,CAAC;gBACjE,MAAM,QAAQ,GAAuB,qBAAqB,CAAC,QAAQ,IAAI,SAAS,CAAC;gBACjF,MAAM,mBAAmB,GAAY,CAAC,CAAC,qBAAqB,CAAC,mBAAmB,CAAC;gBAEjF,IAAI,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBACnC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;iBACzD;gBAED,qBAAqB;gBACrB,IAAI,QAAQ,IAAI,UAAU,EAAE;oBAC1B,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;iBAC7E;gBAED,IAAI,UAAU,EAAE;oBACd,OAAO,GAAG;wBACR,6CAA6C;wBAC7C,QAAQ;wBACR,UAAU;wBACV,QAAQ;wBACR,mBAAmB;qBACpB,CAAC;iBACH;gBACD,IAAI,QAAQ,EAAE;oBACZ,OAAO,GAAG;wBACR,2CAA2C;wBAC3C,QAAQ;wBACR,QAAQ;wBACR,QAAQ;wBACR,mBAAmB;qBACpB,CAAC;iBACH;gBACD,IAAI,CAAC,OAAO,EAAE;oBACZ,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;iBACtE;gBAED,MAAM,EAAE,0BAA0B,EAAE,GAAG,wDAAa,8BAA8B,GAAC,CAAC;gBACpF,OAAO,IAAI,0BAA0B,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAtDD,oEAsDC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';\r\nimport type {\r\n IAmazonS3BuildCacheProviderOptionsAdvanced,\r\n IAmazonS3BuildCacheProviderOptionsSimple\r\n} from './AmazonS3BuildCacheProvider';\r\n\r\nconst PLUGIN_NAME: string = 'AmazonS3BuildCachePlugin';\r\n\r\n/**\r\n * @public\r\n */\r\nexport interface IAmazonS3ConfigurationJson {\r\n /**\r\n * (Required unless s3Endpoint is specified) The name of the bucket to use for build cache (e.g. \"my-bucket\").\r\n */\r\n s3Bucket?: string;\r\n\r\n /**\r\n * (Required unless s3Bucket is specified) The Amazon S3 endpoint of the bucket to use for build cache (e.g. \"my-bucket.s3.us-east-2.amazonaws.com\" or \"http://localhost:9000\").\r\n */\r\n s3Endpoint?: string;\r\n\r\n /**\r\n * The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\").\r\n */\r\n s3Region: string;\r\n\r\n /**\r\n * An optional prefix (\"folder\") for cache items.\r\n */\r\n s3Prefix?: string;\r\n\r\n /**\r\n * If set to true, allow writing to the cache. Defaults to false.\r\n */\r\n isCacheWriteAllowed?: boolean;\r\n}\r\n\r\n/**\r\n * @public\r\n */\r\nexport class RushAmazonS3BuildCachePlugin implements IRushPlugin {\r\n public pluginName: string = PLUGIN_NAME;\r\n\r\n public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {\r\n rushSession.hooks.initialize.tap(PLUGIN_NAME, () => {\r\n rushSession.registerCloudBuildCacheProviderFactory('amazon-s3', async (buildCacheConfig) => {\r\n type IBuildCache = typeof buildCacheConfig & {\r\n amazonS3Configuration: IAmazonS3ConfigurationJson;\r\n };\r\n const { amazonS3Configuration } = buildCacheConfig as IBuildCache;\r\n let options:\r\n | IAmazonS3BuildCacheProviderOptionsAdvanced\r\n | IAmazonS3BuildCacheProviderOptionsSimple\r\n | undefined;\r\n const { s3Endpoint, s3Bucket, s3Region } = amazonS3Configuration;\r\n const s3Prefix: undefined | string = amazonS3Configuration.s3Prefix || undefined;\r\n const isCacheWriteAllowed: boolean = !!amazonS3Configuration.isCacheWriteAllowed;\r\n\r\n if (s3Prefix && s3Prefix[0] === '/') {\r\n throw new Error('s3Prefix should not have a leading /');\r\n }\r\n\r\n // mutually exclusive\r\n if (s3Bucket && s3Endpoint) {\r\n throw new Error('Only one of \"s3Bucket\" or \"s3Endpoint\" must be provided.');\r\n }\r\n\r\n if (s3Endpoint) {\r\n options = {\r\n // IAmazonS3BuildCacheProviderOptionsAdvanced\r\n s3Region,\r\n s3Endpoint,\r\n s3Prefix,\r\n isCacheWriteAllowed\r\n };\r\n }\r\n if (s3Bucket) {\r\n options = {\r\n // IAmazonS3BuildCacheProviderOptionsSimple\r\n s3Region,\r\n s3Bucket,\r\n s3Prefix,\r\n isCacheWriteAllowed\r\n };\r\n }\r\n if (!options) {\r\n throw new Error('You must provide either an s3Endpoint or s3Bucket');\r\n }\r\n\r\n const { AmazonS3BuildCacheProvider } = await import('./AmazonS3BuildCacheProvider');\r\n return new AmazonS3BuildCacheProvider(options, rushSession);\r\n });\r\n });\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"RushAmazonS3BuildCachePlugin.js","sourceRoot":"","sources":["../src/RushAmazonS3BuildCachePlugin.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;AAQ3D,MAAM,WAAW,GAAW,0BAA0B,CAAC;AAgCvD;;GAEG;AACH,MAAa,4BAA4B;IAAzC;QACS,eAAU,GAAW,WAAW,CAAC;IAqD1C,CAAC;IAnDQ,KAAK,CAAC,WAAwB,EAAE,UAA6B;QAClE,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE;YACjD,WAAW,CAAC,sCAAsC,CAAC,WAAW,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE;gBAIzF,MAAM,EAAE,qBAAqB,EAAE,GAAG,gBAA+B,CAAC;gBAClE,IAAI,OAGS,CAAC;gBACd,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,qBAAqB,CAAC;gBACjE,MAAM,QAAQ,GAAuB,qBAAqB,CAAC,QAAQ,IAAI,SAAS,CAAC;gBACjF,MAAM,mBAAmB,GAAY,CAAC,CAAC,qBAAqB,CAAC,mBAAmB,CAAC;gBAEjF,IAAI,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBACnC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;iBACzD;gBAED,qBAAqB;gBACrB,IAAI,QAAQ,IAAI,UAAU,EAAE;oBAC1B,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;iBAC7E;gBAED,IAAI,UAAU,EAAE;oBACd,OAAO,GAAG;wBACR,6CAA6C;wBAC7C,QAAQ;wBACR,UAAU;wBACV,QAAQ;wBACR,mBAAmB;qBACpB,CAAC;iBACH;gBACD,IAAI,QAAQ,EAAE;oBACZ,OAAO,GAAG;wBACR,2CAA2C;wBAC3C,QAAQ;wBACR,QAAQ;wBACR,QAAQ;wBACR,mBAAmB;qBACpB,CAAC;iBACH;gBACD,IAAI,CAAC,OAAO,EAAE;oBACZ,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;iBACtE;gBAED,MAAM,EAAE,0BAA0B,EAAE,GAAG,wDAAa,8BAA8B,GAAC,CAAC;gBACpF,OAAO,IAAI,0BAA0B,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAtDD,oEAsDC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';\nimport type {\n IAmazonS3BuildCacheProviderOptionsAdvanced,\n IAmazonS3BuildCacheProviderOptionsSimple\n} from './AmazonS3BuildCacheProvider';\n\nconst PLUGIN_NAME: string = 'AmazonS3BuildCachePlugin';\n\n/**\n * @public\n */\nexport interface IAmazonS3ConfigurationJson {\n /**\n * (Required unless s3Endpoint is specified) The name of the bucket to use for build cache (e.g. \"my-bucket\").\n */\n s3Bucket?: string;\n\n /**\n * (Required unless s3Bucket is specified) The Amazon S3 endpoint of the bucket to use for build cache (e.g. \"my-bucket.s3.us-east-2.amazonaws.com\" or \"http://localhost:9000\").\n */\n s3Endpoint?: string;\n\n /**\n * The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\").\n */\n s3Region: string;\n\n /**\n * An optional prefix (\"folder\") for cache items.\n */\n s3Prefix?: string;\n\n /**\n * If set to true, allow writing to the cache. Defaults to false.\n */\n isCacheWriteAllowed?: boolean;\n}\n\n/**\n * @public\n */\nexport class RushAmazonS3BuildCachePlugin implements IRushPlugin {\n public pluginName: string = PLUGIN_NAME;\n\n public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {\n rushSession.hooks.initialize.tap(PLUGIN_NAME, () => {\n rushSession.registerCloudBuildCacheProviderFactory('amazon-s3', async (buildCacheConfig) => {\n type IBuildCache = typeof buildCacheConfig & {\n amazonS3Configuration: IAmazonS3ConfigurationJson;\n };\n const { amazonS3Configuration } = buildCacheConfig as IBuildCache;\n let options:\n | IAmazonS3BuildCacheProviderOptionsAdvanced\n | IAmazonS3BuildCacheProviderOptionsSimple\n | undefined;\n const { s3Endpoint, s3Bucket, s3Region } = amazonS3Configuration;\n const s3Prefix: undefined | string = amazonS3Configuration.s3Prefix || undefined;\n const isCacheWriteAllowed: boolean = !!amazonS3Configuration.isCacheWriteAllowed;\n\n if (s3Prefix && s3Prefix[0] === '/') {\n throw new Error('s3Prefix should not have a leading /');\n }\n\n // mutually exclusive\n if (s3Bucket && s3Endpoint) {\n throw new Error('Only one of \"s3Bucket\" or \"s3Endpoint\" must be provided.');\n }\n\n if (s3Endpoint) {\n options = {\n // IAmazonS3BuildCacheProviderOptionsAdvanced\n s3Region,\n s3Endpoint,\n s3Prefix,\n isCacheWriteAllowed\n };\n }\n if (s3Bucket) {\n options = {\n // IAmazonS3BuildCacheProviderOptionsSimple\n s3Region,\n s3Bucket,\n s3Prefix,\n isCacheWriteAllowed\n };\n }\n if (!options) {\n throw new Error('You must provide either an s3Endpoint or s3Bucket');\n }\n\n const { AmazonS3BuildCacheProvider } = await import('./AmazonS3BuildCacheProvider');\n return new AmazonS3BuildCacheProvider(options, rushSession);\n });\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"WebClient.js","sourceRoot":"","sources":["../src/WebClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\n// ===================================================================================================================\r\n// AS A TEMPORARY WORKAROUND, THIS FILE WAS COPY+PASTED FROM THE \"rush-lib\" PROJECT.\r\n//\r\n// Eventually we plan to convert it into a more generic API for \"node-core-library\" or\r\n// else replace it with a third party solution such as Axios. See the discussion here:\r\n// https://github.com/microsoft/rushstack/pull/3036#discussion_r758010126\r\n// ===================================================================================================================\r\n\r\nimport * as os from 'os';\r\nimport * as process from 'process';\r\nimport * as fetch from 'node-fetch';\r\nimport type * as http from 'http';\r\nimport { Import } from '@rushstack/node-core-library';\r\n\r\nconst createHttpsProxyAgent: typeof import('https-proxy-agent') = Import.lazy('https-proxy-agent', require);\r\n\r\n/**\r\n * For use with {@link WebClient}.\r\n *\r\n * @public\r\n */\r\nexport type WebClientResponse = fetch.Response;\r\n\r\n/**\r\n * For use with {@link WebClient}.\r\n *\r\n * @public\r\n */\r\nexport interface IWebFetchOptionsBase {\r\n timeoutMs?: number;\r\n verb?: 'GET' | 'PUT';\r\n headers?: fetch.Headers;\r\n}\r\n\r\n/**\r\n * For use with {@link WebClient}.\r\n *\r\n * @public\r\n */\r\nexport interface IGetFetchOptions extends IWebFetchOptionsBase {\r\n verb: 'GET' | never;\r\n}\r\n\r\n/**\r\n * For use with {@link WebClient}.\r\n *\r\n * @public\r\n */\r\nexport interface IPutFetchOptions extends IWebFetchOptionsBase {\r\n verb: 'PUT';\r\n body?: Buffer;\r\n}\r\n\r\n/**\r\n * For use with {@link WebClient}.\r\n * @public\r\n */\r\nexport enum WebClientProxy {\r\n None,\r\n Detect,\r\n Fiddler\r\n}\r\n\r\n/**\r\n * A helper for issuing HTTP requests.\r\n *\r\n * @public\r\n */\r\nexport class WebClient {\r\n public readonly standardHeaders: fetch.Headers = new fetch.Headers();\r\n\r\n public accept: string | undefined = '*/*';\r\n public userAgent: string | undefined = `rush node/${process.version} ${os.platform()} ${os.arch()}`;\r\n\r\n public proxy: WebClientProxy = WebClientProxy.Detect;\r\n\r\n public constructor() {}\r\n\r\n public static mergeHeaders(target: fetch.Headers, source: fetch.Headers): void {\r\n source.forEach((value, name) => {\r\n target.set(name, value);\r\n });\r\n }\r\n\r\n public addBasicAuthHeader(userName: string, password: string): void {\r\n this.standardHeaders.set(\r\n 'Authorization',\r\n 'Basic ' + Buffer.from(userName + ':' + password).toString('base64')\r\n );\r\n }\r\n\r\n public async fetchAsync(\r\n url: string,\r\n options?: IGetFetchOptions | IPutFetchOptions\r\n ): Promise<WebClientResponse> {\r\n const headers: fetch.Headers = new fetch.Headers();\r\n\r\n WebClient.mergeHeaders(headers, this.standardHeaders);\r\n\r\n if (options?.headers) {\r\n WebClient.mergeHeaders(headers, options.headers);\r\n }\r\n\r\n if (this.userAgent) {\r\n headers.set('user-agent', this.userAgent);\r\n }\r\n if (this.accept) {\r\n headers.set('accept', this.accept);\r\n }\r\n\r\n let proxyUrl: string = '';\r\n\r\n switch (this.proxy) {\r\n case WebClientProxy.Detect:\r\n if (process.env.HTTPS_PROXY) {\r\n proxyUrl = process.env.HTTPS_PROXY;\r\n } else if (process.env.HTTP_PROXY) {\r\n proxyUrl = process.env.HTTP_PROXY;\r\n }\r\n break;\r\n\r\n case WebClientProxy.Fiddler:\r\n // For debugging, disable cert validation\r\n // eslint-disable-next-line\r\n process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';\r\n proxyUrl = 'http://localhost:8888/';\r\n break;\r\n }\r\n\r\n let agent: http.Agent | undefined = undefined;\r\n if (proxyUrl) {\r\n agent = createHttpsProxyAgent(proxyUrl);\r\n }\r\n\r\n const timeoutMs: number = options?.timeoutMs !== undefined ? options.timeoutMs : 15 * 1000; // 15 seconds\r\n const requestInit: fetch.RequestInit = {\r\n method: options?.verb,\r\n headers: headers,\r\n agent: agent,\r\n timeout: timeoutMs\r\n };\r\n const putOptions: IPutFetchOptions | undefined = options as IPutFetchOptions | undefined;\r\n if (putOptions?.body) {\r\n requestInit.body = putOptions.body;\r\n }\r\n\r\n return await fetch.default(url, requestInit);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"WebClient.js","sourceRoot":"","sources":["../src/WebClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n// ===================================================================================================================\n// AS A TEMPORARY WORKAROUND, THIS FILE WAS COPY+PASTED FROM THE \"rush-lib\" PROJECT.\n//\n// Eventually we plan to convert it into a more generic API for \"node-core-library\" or\n// else replace it with a third party solution such as Axios. See the discussion here:\n// https://github.com/microsoft/rushstack/pull/3036#discussion_r758010126\n// ===================================================================================================================\n\nimport * as os from 'os';\nimport * as process from 'process';\nimport * as fetch from 'node-fetch';\nimport type * as http from 'http';\nimport { Import } from '@rushstack/node-core-library';\n\nconst createHttpsProxyAgent: typeof import('https-proxy-agent') = Import.lazy('https-proxy-agent', require);\n\n/**\n * For use with {@link WebClient}.\n *\n * @public\n */\nexport type WebClientResponse = fetch.Response;\n\n/**\n * For use with {@link WebClient}.\n *\n * @public\n */\nexport interface IWebFetchOptionsBase {\n timeoutMs?: number;\n verb?: 'GET' | 'PUT';\n headers?: fetch.Headers;\n}\n\n/**\n * For use with {@link WebClient}.\n *\n * @public\n */\nexport interface IGetFetchOptions extends IWebFetchOptionsBase {\n verb: 'GET' | never;\n}\n\n/**\n * For use with {@link WebClient}.\n *\n * @public\n */\nexport interface IPutFetchOptions extends IWebFetchOptionsBase {\n verb: 'PUT';\n body?: Buffer;\n}\n\n/**\n * For use with {@link WebClient}.\n * @public\n */\nexport enum WebClientProxy {\n None,\n Detect,\n Fiddler\n}\n\n/**\n * A helper for issuing HTTP requests.\n *\n * @public\n */\nexport class WebClient {\n public readonly standardHeaders: fetch.Headers = new fetch.Headers();\n\n public accept: string | undefined = '*/*';\n public userAgent: string | undefined = `rush node/${process.version} ${os.platform()} ${os.arch()}`;\n\n public proxy: WebClientProxy = WebClientProxy.Detect;\n\n public constructor() {}\n\n public static mergeHeaders(target: fetch.Headers, source: fetch.Headers): void {\n source.forEach((value, name) => {\n target.set(name, value);\n });\n }\n\n public addBasicAuthHeader(userName: string, password: string): void {\n this.standardHeaders.set(\n 'Authorization',\n 'Basic ' + Buffer.from(userName + ':' + password).toString('base64')\n );\n }\n\n public async fetchAsync(\n url: string,\n options?: IGetFetchOptions | IPutFetchOptions\n ): Promise<WebClientResponse> {\n const headers: fetch.Headers = new fetch.Headers();\n\n WebClient.mergeHeaders(headers, this.standardHeaders);\n\n if (options?.headers) {\n WebClient.mergeHeaders(headers, options.headers);\n }\n\n if (this.userAgent) {\n headers.set('user-agent', this.userAgent);\n }\n if (this.accept) {\n headers.set('accept', this.accept);\n }\n\n let proxyUrl: string = '';\n\n switch (this.proxy) {\n case WebClientProxy.Detect:\n if (process.env.HTTPS_PROXY) {\n proxyUrl = process.env.HTTPS_PROXY;\n } else if (process.env.HTTP_PROXY) {\n proxyUrl = process.env.HTTP_PROXY;\n }\n break;\n\n case WebClientProxy.Fiddler:\n // For debugging, disable cert validation\n // eslint-disable-next-line\n process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';\n proxyUrl = 'http://localhost:8888/';\n break;\n }\n\n let agent: http.Agent | undefined = undefined;\n if (proxyUrl) {\n agent = createHttpsProxyAgent(proxyUrl);\n }\n\n const timeoutMs: number = options?.timeoutMs !== undefined ? options.timeoutMs : 15 * 1000; // 15 seconds\n const requestInit: fetch.RequestInit = {\n method: options?.verb,\n headers: headers,\n agent: agent,\n timeout: timeoutMs\n };\n const putOptions: IPutFetchOptions | undefined = options as IPutFetchOptions | undefined;\n if (putOptions?.body) {\n requestInit.body = putOptions.body;\n }\n\n return await fetch.default(url, requestInit);\n }\n}\n"]}
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,iFAA8E;AAG9E,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,yCAA+F;AAAtF,sGAAA,SAAS,OAAA;AAClB,kBAAe,2DAA4B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { RushAmazonS3BuildCachePlugin } from './RushAmazonS3BuildCachePlugin';\r\n\r\nexport { type IAmazonS3Credentials } from './AmazonS3Credentials';\r\nexport { AmazonS3Client } from './AmazonS3Client';\r\nexport { WebClient, IGetFetchOptions, IPutFetchOptions, WebClientResponse } from './WebClient';\r\nexport default RushAmazonS3BuildCachePlugin;\r\nexport {\r\n IAmazonS3BuildCacheProviderOptionsBase,\r\n IAmazonS3BuildCacheProviderOptionsAdvanced,\r\n IAmazonS3BuildCacheProviderOptionsSimple\r\n} from './AmazonS3BuildCacheProvider';\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,iFAA8E;AAG9E,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,yCAA+F;AAAtF,sGAAA,SAAS,OAAA;AAClB,kBAAe,2DAA4B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { RushAmazonS3BuildCachePlugin } from './RushAmazonS3BuildCachePlugin';\n\nexport { type IAmazonS3Credentials } from './AmazonS3Credentials';\nexport { AmazonS3Client } from './AmazonS3Client';\nexport { WebClient, IGetFetchOptions, IPutFetchOptions, WebClientResponse } from './WebClient';\nexport default RushAmazonS3BuildCachePlugin;\nexport {\n IAmazonS3BuildCacheProviderOptionsBase,\n IAmazonS3BuildCacheProviderOptionsAdvanced,\n IAmazonS3BuildCacheProviderOptionsSimple\n} from './AmazonS3BuildCacheProvider';\n"]}
@@ -1,51 +1,51 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-04/schema#",
3
- "title": "Configuration for build cache with Amazon S3 configuration",
4
- "type": "object",
5
- "oneOf": [
6
- {
7
- "type": "object",
8
- "required": ["s3Endpoint", "s3Region"],
9
- "properties": {
10
- "s3Endpoint": {
11
- "type": "string",
12
- "description": "(Required) The Amazon S3 endpoint of the bucket to use for build cache (e.g. \"s3.us-east-2.amazonaws.com\")."
13
- },
14
- "s3Region": {
15
- "type": "string",
16
- "description": "(Required) The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\")."
17
- },
18
- "s3Prefix": {
19
- "type": "string",
20
- "description": "An optional prefix (\"folder\") for cache items."
21
- },
22
- "isCacheWriteAllowed": {
23
- "type": "boolean",
24
- "description": "If set to true, allow writing to the cache. Defaults to false."
25
- }
26
- }
27
- },
28
- {
29
- "type": "object",
30
- "required": ["s3Bucket", "s3Region"],
31
- "properties": {
32
- "s3Bucket": {
33
- "type": "string",
34
- "description": "(Required unless s3Endpoint is specified) The name of the bucket to use for build cache (e.g. \"my-bucket\")."
35
- },
36
- "s3Region": {
37
- "type": "string",
38
- "description": "(Required) The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\")."
39
- },
40
- "s3Prefix": {
41
- "type": "string",
42
- "description": "An optional prefix (\"folder\") for cache items."
43
- },
44
- "isCacheWriteAllowed": {
45
- "type": "boolean",
46
- "description": "If set to true, allow writing to the cache. Defaults to false."
47
- }
48
- }
49
- }
50
- ]
51
- }
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Configuration for build cache with Amazon S3 configuration",
4
+ "type": "object",
5
+ "oneOf": [
6
+ {
7
+ "type": "object",
8
+ "required": ["s3Endpoint", "s3Region"],
9
+ "properties": {
10
+ "s3Endpoint": {
11
+ "type": "string",
12
+ "description": "(Required) The Amazon S3 endpoint of the bucket to use for build cache (e.g. \"s3.us-east-2.amazonaws.com\")."
13
+ },
14
+ "s3Region": {
15
+ "type": "string",
16
+ "description": "(Required) The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\")."
17
+ },
18
+ "s3Prefix": {
19
+ "type": "string",
20
+ "description": "An optional prefix (\"folder\") for cache items."
21
+ },
22
+ "isCacheWriteAllowed": {
23
+ "type": "boolean",
24
+ "description": "If set to true, allow writing to the cache. Defaults to false."
25
+ }
26
+ }
27
+ },
28
+ {
29
+ "type": "object",
30
+ "required": ["s3Bucket", "s3Region"],
31
+ "properties": {
32
+ "s3Bucket": {
33
+ "type": "string",
34
+ "description": "(Required unless s3Endpoint is specified) The name of the bucket to use for build cache (e.g. \"my-bucket\")."
35
+ },
36
+ "s3Region": {
37
+ "type": "string",
38
+ "description": "(Required) The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\")."
39
+ },
40
+ "s3Prefix": {
41
+ "type": "string",
42
+ "description": "An optional prefix (\"folder\") for cache items."
43
+ },
44
+ "isCacheWriteAllowed": {
45
+ "type": "boolean",
46
+ "description": "If set to true, allow writing to the cache. Defaults to false."
47
+ }
48
+ }
49
+ }
50
+ ]
51
+ }
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.38.0"
8
+ "packageVersion": "7.38.3"
9
9
  }
10
10
  ]
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/rush-amazon-s3-build-cache-plugin",
3
- "version": "5.110.0",
3
+ "version": "5.110.2",
4
4
  "description": "Rush plugin for Amazon S3 cloud build cache",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,13 +15,13 @@
15
15
  "https-proxy-agent": "~5.0.0",
16
16
  "node-fetch": "2.6.7",
17
17
  "@rushstack/node-core-library": "3.61.0",
18
- "@rushstack/rush-sdk": "5.110.0"
18
+ "@rushstack/rush-sdk": "5.110.2"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/node-fetch": "2.6.2",
22
- "@microsoft/rush-lib": "5.110.0",
23
- "@rushstack/heft": "0.63.0",
24
- "local-node-rig": "1.0.0"
22
+ "@rushstack/heft": "0.63.2",
23
+ "local-node-rig": "1.0.0",
24
+ "@microsoft/rush-lib": "5.110.2"
25
25
  },
26
26
  "scripts": {
27
27
  "build": "heft build --clean",
@@ -1,11 +1,11 @@
1
- {
2
- "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
3
- "plugins": [
4
- {
5
- "pluginName": "rush-amazon-s3-build-cache-plugin",
6
- "description": "Rush plugin for Amazon S3 cloud build cache",
7
- "entryPoint": "lib/index.js",
8
- "optionsSchema": "lib/schemas/amazon-s3-config.schema.json"
9
- }
10
- ]
11
- }
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugin-manifest.schema.json",
3
+ "plugins": [
4
+ {
5
+ "pluginName": "rush-amazon-s3-build-cache-plugin",
6
+ "description": "Rush plugin for Amazon S3 cloud build cache",
7
+ "entryPoint": "lib/index.js",
8
+ "optionsSchema": "lib/schemas/amazon-s3-config.schema.json"
9
+ }
10
+ ]
11
+ }