@rushstack/rush-amazon-s3-build-cache-plugin 5.59.0-rc.1 → 5.59.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/CHANGELOG.json CHANGED
@@ -1,11 +1,11 @@
1
- {
2
- "name": "@rushstack/rush-amazon-s3-build-cache-plugin",
3
- "entries": [
4
- {
5
- "version": "0.0.1",
6
- "tag": "@rushstack/rush-amazon-s3-build-cache-plugin_v0.0.1",
7
- "date": "Thu, 11 Nov 2021 16:07:47 GMT",
8
- "comments": {}
9
- }
10
- ]
11
- }
1
+ {
2
+ "name": "@rushstack/rush-amazon-s3-build-cache-plugin",
3
+ "entries": [
4
+ {
5
+ "version": "0.0.1",
6
+ "tag": "@rushstack/rush-amazon-s3-build-cache-plugin_v0.0.1",
7
+ "date": "Thu, 11 Nov 2021 16:07:47 GMT",
8
+ "comments": {}
9
+ }
10
+ ]
11
+ }
package/CHANGELOG.md CHANGED
@@ -1,9 +1,9 @@
1
- # Change Log - @rushstack/rush-amazon-s3-build-cache-plugin
2
-
3
- This log was last generated on Thu, 11 Nov 2021 16:07:47 GMT and should not be manually modified.
4
-
5
- ## 0.0.1
6
- Thu, 11 Nov 2021 16:07:47 GMT
7
-
8
- _Initial release_
9
-
1
+ # Change Log - @rushstack/rush-amazon-s3-build-cache-plugin
2
+
3
+ This log was last generated on Thu, 11 Nov 2021 16:07:47 GMT and should not be manually modified.
4
+
5
+ ## 0.0.1
6
+ Thu, 11 Nov 2021 16:07:47 GMT
7
+
8
+ _Initial release_
9
+
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/master/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/master/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 { ITerminal } from '@rushstack/node-core-library';\r\nimport {\r\n ICloudBuildCacheProvider,\r\n ICredentialCacheEntry,\r\n CredentialCache,\r\n RushSession,\r\n RushConstants,\r\n EnvironmentVariableNames,\r\n EnvironmentConfiguration\r\n} from '@rushstack/rush-sdk';\r\n\r\nimport { AmazonS3Client, IAmazonS3Credentials } from './AmazonS3Client';\r\nimport { WebClient } from './WebClient';\r\n\r\nexport interface IAmazonS3BuildCacheProviderOptions {\r\n s3Bucket: string;\r\n s3Region: string;\r\n s3Prefix?: string;\r\n isCacheWriteAllowed: boolean;\r\n}\r\n\r\nexport class AmazonS3BuildCacheProvider implements ICloudBuildCacheProvider {\r\n private readonly _options: IAmazonS3BuildCacheProviderOptions;\r\n private readonly _s3Prefix: string | undefined;\r\n private readonly _environmentCredential: 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(options: IAmazonS3BuildCacheProviderOptions, rushSession: RushSession) {\r\n this._rushSession = rushSession;\r\n this._options = options;\r\n this._s3Prefix = options.s3Prefix;\r\n this._environmentCredential = EnvironmentConfiguration.buildCacheCredential;\r\n this._isCacheWriteAllowedByConfiguration = options.isCacheWriteAllowed;\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._options.s3Bucket];\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(): Promise<AmazonS3Client> {\r\n if (!this.__s3Client) {\r\n let credentials: IAmazonS3Credentials | undefined = AmazonS3Client.tryDeserializeCredentials(\r\n this._environmentCredential\r\n );\r\n\r\n if (!credentials) {\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 = AmazonS3Client.tryDeserializeCredentials(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(credentials, this._options, new WebClient());\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();\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 try {\r\n const client: AmazonS3Client = await this._getS3ClientAsync();\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 { ITerminal } from '@rushstack/node-core-library';\nimport {\n ICloudBuildCacheProvider,\n ICredentialCacheEntry,\n CredentialCache,\n RushSession,\n RushConstants,\n EnvironmentVariableNames,\n EnvironmentConfiguration\n} from '@rushstack/rush-sdk';\n\nimport { AmazonS3Client, IAmazonS3Credentials } from './AmazonS3Client';\nimport { WebClient } from './WebClient';\n\nexport interface IAmazonS3BuildCacheProviderOptions {\n s3Bucket: string;\n s3Region: string;\n s3Prefix?: string;\n isCacheWriteAllowed: boolean;\n}\n\nexport class AmazonS3BuildCacheProvider implements ICloudBuildCacheProvider {\n private readonly _options: IAmazonS3BuildCacheProviderOptions;\n private readonly _s3Prefix: string | undefined;\n private readonly _environmentCredential: 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(options: IAmazonS3BuildCacheProviderOptions, rushSession: RushSession) {\n this._rushSession = rushSession;\n this._options = options;\n this._s3Prefix = options.s3Prefix;\n this._environmentCredential = EnvironmentConfiguration.buildCacheCredential;\n this._isCacheWriteAllowedByConfiguration = options.isCacheWriteAllowed;\n }\n\n private get _credentialCacheId(): string {\n if (!this.__credentialCacheId) {\n const cacheIdParts: string[] = ['aws-s3', this._options.s3Region, this._options.s3Bucket];\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(): Promise<AmazonS3Client> {\n if (!this.__s3Client) {\n let credentials: IAmazonS3Credentials | undefined = AmazonS3Client.tryDeserializeCredentials(\n this._environmentCredential\n );\n\n if (!credentials) {\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 = AmazonS3Client.tryDeserializeCredentials(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(credentials, this._options, new WebClient());\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();\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 try {\n const client: AmazonS3Client = await this._getS3ClientAsync();\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":"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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 * as crypto from 'crypto';\r\nimport * as fetch from 'node-fetch';\r\n\r\nimport { IAmazonS3BuildCacheProviderOptions } from './AmazonS3BuildCacheProvider';\r\nimport { IGetFetchOptions, IPutFetchOptions, WebClient } from './WebClient';\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\nconst DEFAULT_S3_REGION: 'us-east-1' = 'us-east-1';\r\n\r\nexport interface IAmazonS3Credentials {\r\n accessKeyId: string;\r\n secretAccessKey: string;\r\n sessionToken: string | undefined;\r\n}\r\n\r\ninterface IIsoDateString {\r\n date: string;\r\n dateTime: string;\r\n}\r\n\r\nexport class AmazonS3Client {\r\n private readonly _credentials: IAmazonS3Credentials | undefined;\r\n private readonly _s3Bucket: string;\r\n private readonly _s3Region: string;\r\n\r\n private readonly _webClient: WebClient;\r\n\r\n public constructor(\r\n credentials: IAmazonS3Credentials | undefined,\r\n options: IAmazonS3BuildCacheProviderOptions,\r\n webClient: WebClient\r\n ) {\r\n this._credentials = credentials;\r\n\r\n this._validateBucketName(options.s3Bucket);\r\n\r\n this._s3Bucket = options.s3Bucket;\r\n this._s3Region = options.s3Region;\r\n\r\n this._webClient = webClient;\r\n }\r\n\r\n public static tryDeserializeCredentials(\r\n credentialString: string | undefined\r\n ): IAmazonS3Credentials | undefined {\r\n if (!credentialString) {\r\n return undefined;\r\n }\r\n\r\n const fields: string[] = credentialString.split(':');\r\n if (fields.length < 2 || fields.length > 3) {\r\n throw new Error('Amazon S3 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\r\n public async getObjectAsync(objectName: string): Promise<Buffer | undefined> {\r\n const response: fetch.Response = await this._makeRequestAsync('GET', objectName);\r\n if (response.ok) {\r\n return await response.buffer();\r\n } else if (response.status === 404) {\r\n return undefined;\r\n } else if (response.status === 403 && !this._credentials) {\r\n return undefined;\r\n } else {\r\n this._throwS3Error(response);\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 const response: fetch.Response = await this._makeRequestAsync('PUT', objectName, objectBuffer);\r\n if (!response.ok) {\r\n this._throwS3Error(response);\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 host: string = this._getHost();\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 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 signedHeaderNames: string[] = [HOST_HEADER_NAME, CONTENT_HASH_HEADER_NAME, DATE_HEADER_NAME];\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 signedHeaderNames.push(SECURITY_TOKEN_HEADER_NAME);\r\n canonicalHeaders.push(`${SECURITY_TOKEN_HEADER_NAME}:${this._credentials.sessionToken}`);\r\n }\r\n\r\n const signedHeaderNamesString: string = signedHeaderNames.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 `/${objectName}`,\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 response: fetch.Response = await this._webClient.fetchAsync(\r\n `https://${host}/${objectName}`,\r\n webFetchOptions\r\n );\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.Hash = 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 _throwS3Error(response: fetch.Response): never {\r\n throw new Error(`Amazon S3 responded with status code ${response.status} (${response.statusText})`);\r\n }\r\n\r\n private _getHost(): string {\r\n if (this._s3Region === DEFAULT_S3_REGION) {\r\n return `${this._s3Bucket}.s3.amazonaws.com`;\r\n } else {\r\n return `${this._s3Bucket}.s3-${this._s3Region}.amazonaws.com`;\r\n }\r\n }\r\n\r\n /**\r\n * Validates a S3 bucket name.\r\n * {@link https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-s3-bucket-naming-requirements.html}\r\n */\r\n private _validateBucketName(s3BucketName: string): void {\r\n if (!s3BucketName) {\r\n throw new Error('A S3 bucket name must be provided');\r\n }\r\n\r\n if (!s3BucketName.match(/^[a-z\\d-.]{3,63}$/)) {\r\n throw new Error(\r\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must only contain lowercase ` +\r\n 'alphanumerical characters, dashes, and periods and must be between 3 and 63 characters long.'\r\n );\r\n }\r\n\r\n if (!s3BucketName.match(/^[a-z\\d]/)) {\r\n throw new Error(\r\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must start with a lowercase ` +\r\n 'alphanumerical character.'\r\n );\r\n }\r\n\r\n if (s3BucketName.match(/-$/)) {\r\n throw new Error(\r\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must not end in a dash.`\r\n );\r\n }\r\n\r\n if (s3BucketName.match(/(\\.\\.)|(\\.-)|(-\\.)/)) {\r\n throw new Error(\r\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must not have consecutive periods or ` +\r\n 'dashes adjacent to periods.'\r\n );\r\n }\r\n\r\n if (s3BucketName.match(/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/)) {\r\n throw new Error(\r\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must not be formatted as an IP address.`\r\n );\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"AmazonS3Client.js","sourceRoot":"","sources":["../src/AmazonS3Client.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;AAE3D,+CAAiC;AACjC,kDAAoC;AAKpC,MAAM,wBAAwB,GAA2B,sBAAsB,CAAC;AAChF,MAAM,gBAAgB,GAAiB,YAAY,CAAC;AACpD,MAAM,gBAAgB,GAAW,MAAM,CAAC;AACxC,MAAM,0BAA0B,GAA2B,sBAAsB,CAAC;AAElF,MAAM,iBAAiB,GAAgB,WAAW,CAAC;AAanD,MAAa,cAAc;IAOzB,YACE,WAA6C,EAC7C,OAA2C,EAC3C,SAAoB;QAEpB,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAEhC,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAE3C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;QAElC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;IAEM,MAAM,CAAC,yBAAyB,CACrC,gBAAoC;QAEpC,IAAI,CAAC,gBAAgB,EAAE;YACrB,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,MAAM,GAAa,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YAC1C,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,OAAO;YACL,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;YACtB,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;YAC1B,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;SACxB,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,UAAkB;QAC5C,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACjF,IAAI,QAAQ,CAAC,EAAE,EAAE;YACf,OAAO,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;SAChC;aAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;YAClC,OAAO,SAAS,CAAC;SAClB;aAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACxD,OAAO,SAAS,CAAC;SAClB;aAAM;YACL,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;SAC9B;IACH,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,QAAQ,GAAmB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAC/F,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;YAChB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;SAC9B;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,IAAI,GAAW,IAAI,CAAC,QAAQ,EAAE,CAAC;QACrC,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,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,sHAAsH;YACtH,MAAM,iBAAiB,GAAa,CAAC,gBAAgB,EAAE,wBAAwB,EAAE,gBAAgB,CAAC,CAAC;YACnG,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,iBAAiB,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;gBACnD,gBAAgB,CAAC,IAAI,CAAC,GAAG,0BAA0B,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;aAC1F;YAED,MAAM,uBAAuB,GAAW,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEpE,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,IAAI,UAAU,EAAE;gBAChB,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,QAAQ,GAAmB,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAC/D,WAAW,IAAI,IAAI,UAAU,EAAE,EAC/B,eAAe,CAChB,CAAC;QAEF,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,aAAa,CAAC,QAAwB;QAC5C,MAAM,IAAI,KAAK,CAAC,wCAAwC,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC;IACtG,CAAC;IAEO,QAAQ;QACd,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB,EAAE;YACxC,OAAO,GAAG,IAAI,CAAC,SAAS,mBAAmB,CAAC;SAC7C;aAAM;YACL,OAAO,GAAG,IAAI,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS,gBAAgB,CAAC;SAC/D;IACH,CAAC;IAED;;;OAGG;IACK,mBAAmB,CAAC,YAAoB;QAC9C,IAAI,CAAC,YAAY,EAAE;YACjB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;SACtD;QAED,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE;YAC5C,MAAM,IAAI,KAAK,CACb,oBAAoB,YAAY,6DAA6D;gBAC3F,8FAA8F,CACjG,CAAC;SACH;QAED,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;YACnC,MAAM,IAAI,KAAK,CACb,oBAAoB,YAAY,6DAA6D;gBAC3F,2BAA2B,CAC9B,CAAC;SACH;QAED,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YAC5B,MAAM,IAAI,KAAK,CACb,oBAAoB,YAAY,wDAAwD,CACzF,CAAC;SACH;QAED,IAAI,YAAY,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE;YAC5C,MAAM,IAAI,KAAK,CACb,oBAAoB,YAAY,sEAAsE;gBACpG,6BAA6B,CAChC,CAAC;SACH;QAED,IAAI,YAAY,CAAC,KAAK,CAAC,sCAAsC,CAAC,EAAE;YAC9D,MAAM,IAAI,KAAK,CACb,oBAAoB,YAAY,wEAAwE,CACzG,CAAC;SACH;IACH,CAAC;CACF;AA7PD,wCA6PC","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 * as crypto from 'crypto';\nimport * as fetch from 'node-fetch';\n\nimport { IAmazonS3BuildCacheProviderOptions } from './AmazonS3BuildCacheProvider';\nimport { IGetFetchOptions, IPutFetchOptions, WebClient } from './WebClient';\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\nconst DEFAULT_S3_REGION: 'us-east-1' = 'us-east-1';\n\nexport interface IAmazonS3Credentials {\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken: string | undefined;\n}\n\ninterface IIsoDateString {\n date: string;\n dateTime: string;\n}\n\nexport class AmazonS3Client {\n private readonly _credentials: IAmazonS3Credentials | undefined;\n private readonly _s3Bucket: string;\n private readonly _s3Region: string;\n\n private readonly _webClient: WebClient;\n\n public constructor(\n credentials: IAmazonS3Credentials | undefined,\n options: IAmazonS3BuildCacheProviderOptions,\n webClient: WebClient\n ) {\n this._credentials = credentials;\n\n this._validateBucketName(options.s3Bucket);\n\n this._s3Bucket = options.s3Bucket;\n this._s3Region = options.s3Region;\n\n this._webClient = webClient;\n }\n\n public static tryDeserializeCredentials(\n credentialString: string | undefined\n ): IAmazonS3Credentials | undefined {\n if (!credentialString) {\n return undefined;\n }\n\n const fields: string[] = credentialString.split(':');\n if (fields.length < 2 || fields.length > 3) {\n throw new Error('Amazon S3 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\n public async getObjectAsync(objectName: string): Promise<Buffer | undefined> {\n const response: fetch.Response = await this._makeRequestAsync('GET', objectName);\n if (response.ok) {\n return await response.buffer();\n } else if (response.status === 404) {\n return undefined;\n } else if (response.status === 403 && !this._credentials) {\n return undefined;\n } else {\n this._throwS3Error(response);\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 const response: fetch.Response = await this._makeRequestAsync('PUT', objectName, objectBuffer);\n if (!response.ok) {\n this._throwS3Error(response);\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 host: string = this._getHost();\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 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 signedHeaderNames: string[] = [HOST_HEADER_NAME, CONTENT_HASH_HEADER_NAME, DATE_HEADER_NAME];\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 signedHeaderNames.push(SECURITY_TOKEN_HEADER_NAME);\n canonicalHeaders.push(`${SECURITY_TOKEN_HEADER_NAME}:${this._credentials.sessionToken}`);\n }\n\n const signedHeaderNamesString: string = signedHeaderNames.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 `/${objectName}`,\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 response: fetch.Response = await this._webClient.fetchAsync(\n `https://${host}/${objectName}`,\n webFetchOptions\n );\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.Hash = 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 _throwS3Error(response: fetch.Response): never {\n throw new Error(`Amazon S3 responded with status code ${response.status} (${response.statusText})`);\n }\n\n private _getHost(): string {\n if (this._s3Region === DEFAULT_S3_REGION) {\n return `${this._s3Bucket}.s3.amazonaws.com`;\n } else {\n return `${this._s3Bucket}.s3-${this._s3Region}.amazonaws.com`;\n }\n }\n\n /**\n * Validates a S3 bucket name.\n * {@link https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-s3-bucket-naming-requirements.html}\n */\n private _validateBucketName(s3BucketName: string): void {\n if (!s3BucketName) {\n throw new Error('A S3 bucket name must be provided');\n }\n\n if (!s3BucketName.match(/^[a-z\\d-.]{3,63}$/)) {\n throw new Error(\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must only contain lowercase ` +\n 'alphanumerical characters, dashes, and periods and must be between 3 and 63 characters long.'\n );\n }\n\n if (!s3BucketName.match(/^[a-z\\d]/)) {\n throw new Error(\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must start with a lowercase ` +\n 'alphanumerical character.'\n );\n }\n\n if (s3BucketName.match(/-$/)) {\n throw new Error(\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must not end in a dash.`\n );\n }\n\n if (s3BucketName.match(/(\\.\\.)|(\\.-)|(-\\.)/)) {\n throw new Error(\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must not have consecutive periods or ` +\n 'dashes adjacent to periods.'\n );\n }\n\n if (s3BucketName.match(/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/)) {\n throw new Error(\n `The bucket name \"${s3BucketName}\" is invalid. A S3 bucket name must not be formatted as an IP address.`\n );\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"RushAmazonS3BuildCachePlugin.js","sourceRoot":"","sources":["../src/RushAmazonS3BuildCachePlugin.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,oEAAsD;AAItD,MAAM,gCAAgC,GAAkD,0BAAM,CAAC,IAAI,CACjG,8BAA8B,EAC9B,OAAO,CACR,CAAC;AAEF,MAAM,WAAW,GAAW,0BAA0B,CAAC;AA2BvD;;GAEG;AACH,MAAa,4BAA4B;IAAzC;QACS,eAAU,GAAW,WAAW,CAAC;IAwB1C,CAAC;IAtBQ,KAAK,CAAC,WAAwB,EAAE,UAA6B;QAClE,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE;YACjD,WAAW,CAAC,sCAAsC,CAChD,WAAW,EACX,CAAC,gBAAgB,EAA8B,EAAE;gBAI/C,MAAM,EAAE,qBAAqB,EAAE,GAAG,gBAA+B,CAAC;gBAClE,OAAO,IAAI,gCAAgC,CAAC,0BAA0B,CACpE;oBACE,QAAQ,EAAE,qBAAqB,CAAC,QAAQ;oBACxC,QAAQ,EAAE,qBAAqB,CAAC,QAAQ;oBACxC,QAAQ,EAAE,qBAAqB,CAAC,QAAQ;oBACxC,mBAAmB,EAAE,CAAC,CAAC,qBAAqB,CAAC,mBAAmB;iBACjE,EACD,WAAW,CACZ,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAzBD,oEAyBC","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 { Import } from '@rushstack/node-core-library';\r\nimport type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';\r\nimport type { AmazonS3BuildCacheProvider } from './AmazonS3BuildCacheProvider';\r\n\r\nconst AmazonS3BuildCacheProviderModule: typeof import('./AmazonS3BuildCacheProvider') = Import.lazy(\r\n './AmazonS3BuildCacheProvider',\r\n require\r\n);\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 * 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 * The name of the bucket in Amazon S3 to use for build cache.\r\n */\r\n s3Bucket: 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(\r\n 'amazon-s3',\r\n (buildCacheConfig): AmazonS3BuildCacheProvider => {\r\n type IBuildCache = typeof buildCacheConfig & {\r\n amazonS3Configuration: IAmazonS3ConfigurationJson;\r\n };\r\n const { amazonS3Configuration } = buildCacheConfig as IBuildCache;\r\n return new AmazonS3BuildCacheProviderModule.AmazonS3BuildCacheProvider(\r\n {\r\n s3Region: amazonS3Configuration.s3Region,\r\n s3Bucket: amazonS3Configuration.s3Bucket,\r\n s3Prefix: amazonS3Configuration.s3Prefix,\r\n isCacheWriteAllowed: !!amazonS3Configuration.isCacheWriteAllowed\r\n },\r\n rushSession\r\n );\r\n }\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;;;AAE3D,oEAAsD;AAItD,MAAM,gCAAgC,GAAkD,0BAAM,CAAC,IAAI,CACjG,8BAA8B,EAC9B,OAAO,CACR,CAAC;AAEF,MAAM,WAAW,GAAW,0BAA0B,CAAC;AA2BvD;;GAEG;AACH,MAAa,4BAA4B;IAAzC;QACS,eAAU,GAAW,WAAW,CAAC;IAwB1C,CAAC;IAtBQ,KAAK,CAAC,WAAwB,EAAE,UAA6B;QAClE,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,EAAE;YACjD,WAAW,CAAC,sCAAsC,CAChD,WAAW,EACX,CAAC,gBAAgB,EAA8B,EAAE;gBAI/C,MAAM,EAAE,qBAAqB,EAAE,GAAG,gBAA+B,CAAC;gBAClE,OAAO,IAAI,gCAAgC,CAAC,0BAA0B,CACpE;oBACE,QAAQ,EAAE,qBAAqB,CAAC,QAAQ;oBACxC,QAAQ,EAAE,qBAAqB,CAAC,QAAQ;oBACxC,QAAQ,EAAE,qBAAqB,CAAC,QAAQ;oBACxC,mBAAmB,EAAE,CAAC,CAAC,qBAAqB,CAAC,mBAAmB;iBACjE,EACD,WAAW,CACZ,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAzBD,oEAyBC","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 { Import } from '@rushstack/node-core-library';\nimport type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';\nimport type { AmazonS3BuildCacheProvider } from './AmazonS3BuildCacheProvider';\n\nconst AmazonS3BuildCacheProviderModule: typeof import('./AmazonS3BuildCacheProvider') = Import.lazy(\n './AmazonS3BuildCacheProvider',\n require\n);\n\nconst PLUGIN_NAME: string = 'AmazonS3BuildCachePlugin';\n\n/**\n * @public\n */\nexport interface IAmazonS3ConfigurationJson {\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 * The name of the bucket in Amazon S3 to use for build cache.\n */\n s3Bucket: 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(\n 'amazon-s3',\n (buildCacheConfig): AmazonS3BuildCacheProvider => {\n type IBuildCache = typeof buildCacheConfig & {\n amazonS3Configuration: IAmazonS3ConfigurationJson;\n };\n const { amazonS3Configuration } = buildCacheConfig as IBuildCache;\n return new AmazonS3BuildCacheProviderModule.AmazonS3BuildCacheProvider(\n {\n s3Region: amazonS3Configuration.s3Region,\n s3Bucket: amazonS3Configuration.s3Bucket,\n s3Prefix: amazonS3Configuration.s3Prefix,\n isCacheWriteAllowed: !!amazonS3Configuration.isCacheWriteAllowed\n },\n rushSession\n );\n }\n );\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"WebClient.js","sourceRoot":"","sources":["../src/WebClient.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;AAE3D,sHAAsH;AACtH,oFAAoF;AACpF,EAAE;AACF,sFAAsF;AACtF,uFAAuF;AACvF,yEAAyE;AACzE,sHAAsH;AAEtH,uCAAyB;AACzB,iDAAmC;AACnC,kDAAoC;AAEpC,oEAAsD;AAEtD,MAAM,qBAAqB,GAAuC,0BAAM,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;AA+B5G;;GAEG;AACH,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,mDAAI,CAAA;IACJ,uDAAM,CAAA;IACN,yDAAO,CAAA;AACT,CAAC,EAJW,cAAc,GAAd,sBAAc,KAAd,sBAAc,QAIzB;AAED;;GAEG;AACH,MAAa,SAAS;IAQpB;QAPgB,oBAAe,GAAkB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAE9D,WAAM,GAAuB,KAAK,CAAC;QACnC,cAAS,GAAuB,aAAa,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QAE7F,UAAK,GAAmB,cAAc,CAAC,MAAM,CAAC;IAE/B,CAAC;IAEhB,MAAM,CAAC,YAAY,CAAC,MAAqB,EAAE,MAAqB;QACrE,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,kBAAkB,CAAC,QAAgB,EAAE,QAAgB;QAC1D,IAAI,CAAC,eAAe,CAAC,GAAG,CACtB,eAAe,EACf,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CACrE,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,UAAU,CACrB,GAAW,EACX,OAA6C;QAE7C,MAAM,OAAO,GAAkB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAEnD,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAEtD,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,EAAE;YACpB,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;SAClD;QAED,IAAI,IAAI,CAAC,SAAS,EAAE;YAClB,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;SAC3C;QACD,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;SACpC;QAED,IAAI,QAAQ,GAAW,EAAE,CAAC;QAE1B,QAAQ,IAAI,CAAC,KAAK,EAAE;YAClB,KAAK,cAAc,CAAC,MAAM;gBACxB,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE;oBAC3B,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;iBACpC;qBAAM,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE;oBACjC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;iBACnC;gBACD,MAAM;YAER,KAAK,cAAc,CAAC,OAAO;gBACzB,yCAAyC;gBACzC,2BAA2B;gBAC3B,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,GAAG,GAAG,CAAC;gBAClD,QAAQ,GAAG,wBAAwB,CAAC;gBACpC,MAAM;SACT;QAED,IAAI,KAAK,GAA2B,SAAS,CAAC;QAC9C,IAAI,QAAQ,EAAE;YACZ,KAAK,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;SACzC;QAED,MAAM,SAAS,GAAW,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,MAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;QACzG,MAAM,WAAW,GAAsB;YACrC,MAAM,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI;YACrB,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,SAAS;SACnB,CAAC;QACF,MAAM,UAAU,GAAiC,OAAuC,CAAC;QACzF,IAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,IAAI,EAAE;YACpB,WAAW,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;SACpC;QAED,OAAO,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC;CACF;AAhFD,8BAgFC","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 * 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\nexport type WebClientResponse = fetch.Response;\r\n\r\n/**\r\n * For use with {@link WebClient}.\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\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\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 */\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\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 * 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 */\nexport type WebClientResponse = fetch.Response;\n\n/**\n * For use with {@link WebClient}.\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 */\nexport interface IGetFetchOptions extends IWebFetchOptionsBase {\n verb: 'GET' | never;\n}\n\n/**\n * For use with {@link WebClient}.\n */\nexport interface IPutFetchOptions extends IWebFetchOptionsBase {\n verb: 'PUT';\n body?: Buffer;\n}\n\n/**\n * For use with {@link WebClient}.\n */\nexport enum WebClientProxy {\n None,\n Detect,\n Fiddler\n}\n\n/**\n * A helper for issuing HTTP requests.\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;AAE9E,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 default RushAmazonS3BuildCachePlugin;\r\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;AAE3D,iFAA8E;AAE9E,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 default RushAmazonS3BuildCachePlugin;\n"]}
@@ -1,32 +1,32 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-04/schema#",
3
- "title": "Configuration for build cache with Amazon S3 configuration",
4
-
5
- "type": "object",
6
-
7
- "additionalProperties": false,
8
-
9
- "required": ["s3Region", "s3Bucket"],
10
-
11
- "properties": {
12
- "s3Region": {
13
- "type": "string",
14
- "description": "(Required) The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\")."
15
- },
16
-
17
- "s3Bucket": {
18
- "type": "string",
19
- "description": "(Required) The name of the bucket in Amazon S3 to use for build cache."
20
- },
21
-
22
- "s3Prefix": {
23
- "type": "string",
24
- "description": "An optional prefix (\"folder\") for cache items."
25
- },
26
-
27
- "isCacheWriteAllowed": {
28
- "type": "boolean",
29
- "description": "If set to true, allow writing to the cache. Defaults to false."
30
- }
31
- }
32
- }
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Configuration for build cache with Amazon S3 configuration",
4
+
5
+ "type": "object",
6
+
7
+ "additionalProperties": false,
8
+
9
+ "required": ["s3Region", "s3Bucket"],
10
+
11
+ "properties": {
12
+ "s3Region": {
13
+ "type": "string",
14
+ "description": "(Required) The Amazon S3 region of the bucket to use for build cache (e.g. \"us-east-1\")."
15
+ },
16
+
17
+ "s3Bucket": {
18
+ "type": "string",
19
+ "description": "(Required) The name of the bucket in Amazon S3 to use for build cache."
20
+ },
21
+
22
+ "s3Prefix": {
23
+ "type": "string",
24
+ "description": "An optional prefix (\"folder\") for cache items."
25
+ },
26
+
27
+ "isCacheWriteAllowed": {
28
+ "type": "boolean",
29
+ "description": "If set to true, allow writing to the cache. Defaults to false."
30
+ }
31
+ }
32
+ }
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.19.3"
8
+ "packageVersion": "7.19.4"
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.59.0-rc.1",
3
+ "version": "5.59.2",
4
4
  "description": "Rush plugin for Amazon S3 cloud build cache",
5
5
  "repository": {
6
6
  "type": "git",
@@ -11,16 +11,16 @@
11
11
  "types": "lib/index.d.ts",
12
12
  "license": "MIT",
13
13
  "dependencies": {
14
- "@rushstack/node-core-library": "3.44.3",
15
- "@rushstack/rush-sdk": "5.59.0-rc.1",
14
+ "@rushstack/node-core-library": "3.45.0",
15
+ "@rushstack/rush-sdk": "5.59.2",
16
16
  "https-proxy-agent": "~5.0.0",
17
17
  "node-fetch": "2.6.2"
18
18
  },
19
19
  "devDependencies": {
20
- "@microsoft/rush-lib": "5.59.0-rc.1",
20
+ "@microsoft/rush-lib": "5.59.2",
21
21
  "@rushstack/eslint-config": "2.5.1",
22
- "@rushstack/heft": "0.44.1",
23
- "@rushstack/heft-node-rig": "1.5.1",
22
+ "@rushstack/heft": "0.44.2",
23
+ "@rushstack/heft-node-rig": "1.5.2",
24
24
  "@types/heft-jest": "1.0.1",
25
25
  "@types/node": "12.20.24",
26
26
  "@types/node-fetch": "1.6.9"
@@ -1,12 +1,12 @@
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
- "associatedCommands": ["build", "rebuild", "write-build-cache", "update-cloud-credentials"]
10
- }
11
- ]
12
- }
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
+ "associatedCommands": ["build", "rebuild", "write-build-cache", "update-cloud-credentials"]
10
+ }
11
+ ]
12
+ }