-
Notifications
You must be signed in to change notification settings - Fork 587
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(packages): re-export from @smithy/property-provider (#4925)
- Loading branch information
Showing
8 changed files
with
7 additions
and
227 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1 @@ | ||
import { ProviderError } from "./ProviderError"; | ||
|
||
/** | ||
* @internal | ||
* | ||
* An error representing a failure of an individual credential provider. | ||
* | ||
* This error class has special meaning to the {@link chain} method. If a | ||
* provider in the chain is rejected with an error, the chain will only proceed | ||
* to the next provider if the value of the `tryNextLink` property on the error | ||
* is truthy. This allows individual providers to halt the chain and also | ||
* ensures the chain will stop if an entirely unexpected error is encountered. | ||
*/ | ||
export class CredentialsProviderError extends ProviderError { | ||
name = "CredentialsProviderError"; | ||
constructor(message: string, public readonly tryNextLink: boolean = true) { | ||
super(message, tryNextLink); | ||
// Remove once we stop targetting ES5. | ||
Object.setPrototypeOf(this, CredentialsProviderError.prototype); | ||
} | ||
} | ||
export { CredentialsProviderError } from "@smithy/property-provider"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1 @@ | ||
/** | ||
* @internal | ||
* | ||
* An error representing a failure of an individual provider. | ||
* | ||
* This error class has special meaning to the {@link chain} method. If a | ||
* provider in the chain is rejected with an error, the chain will only proceed | ||
* to the next provider if the value of the `tryNextLink` property on the error | ||
* is truthy. This allows individual providers to halt the chain and also | ||
* ensures the chain will stop if an entirely unexpected error is encountered. | ||
*/ | ||
export class ProviderError extends Error { | ||
name = "ProviderError"; | ||
constructor(message: string, public readonly tryNextLink: boolean = true) { | ||
super(message); | ||
// Remove once we stop targetting ES5. | ||
Object.setPrototypeOf(this, ProviderError.prototype); | ||
} | ||
static from(error: Error, tryNextLink = true): ProviderError { | ||
return Object.assign(new this(error.message, tryNextLink), error); | ||
} | ||
} | ||
export { ProviderError } from "@smithy/property-provider"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1 @@ | ||
import { ProviderError } from "./ProviderError"; | ||
|
||
/** | ||
* @internal | ||
* | ||
* An error representing a failure of an individual token provider. | ||
* | ||
* This error class has special meaning to the {@link chain} method. If a | ||
* provider in the chain is rejected with an error, the chain will only proceed | ||
* to the next provider if the value of the `tryNextLink` property on the error | ||
* is truthy. This allows individual providers to halt the chain and also | ||
* ensures the chain will stop if an entirely unexpected error is encountered. | ||
*/ | ||
export class TokenProviderError extends ProviderError { | ||
name = "TokenProviderError"; | ||
constructor(message: string, public readonly tryNextLink: boolean = true) { | ||
super(message, tryNextLink); | ||
// Remove once we stop targetting ES5. | ||
Object.setPrototypeOf(this, TokenProviderError.prototype); | ||
} | ||
} | ||
export { TokenProviderError } from "@smithy/property-provider"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1 @@ | ||
import { Provider } from "@aws-sdk/types"; | ||
|
||
import { ProviderError } from "./ProviderError"; | ||
|
||
/** | ||
* @internal | ||
* | ||
* Compose a single credential provider function from multiple credential | ||
* providers. The first provider in the argument list will always be invoked; | ||
* subsequent providers in the list will be invoked in the order in which the | ||
* were received if the preceding provider did not successfully resolve. | ||
* | ||
* If no providers were received or no provider resolves successfully, the | ||
* returned promise will be rejected. | ||
*/ | ||
export const chain = | ||
<T>(...providers: Array<Provider<T>>): Provider<T> => | ||
async () => { | ||
if (providers.length === 0) { | ||
throw new ProviderError("No providers in chain"); | ||
} | ||
|
||
let lastProviderError: Error | undefined; | ||
for (const provider of providers) { | ||
try { | ||
const credentials = await provider(); | ||
return credentials; | ||
} catch (err) { | ||
lastProviderError = err; | ||
if (err?.tryNextLink) { | ||
continue; | ||
} | ||
throw err; | ||
} | ||
} | ||
throw lastProviderError; | ||
}; | ||
export { chain } from "@smithy/property-provider"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1 @@ | ||
import { Provider } from "@aws-sdk/types"; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
export const fromStatic = | ||
<T>(staticValue: T): Provider<T> => | ||
() => | ||
Promise.resolve(staticValue); | ||
export { fromStatic } from "@smithy/property-provider"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,6 @@ | ||
/** | ||
* @internal | ||
*/ | ||
export * from "./CredentialsProviderError"; | ||
/** | ||
* @internal | ||
*/ | ||
export * from "./ProviderError"; | ||
/** | ||
* @internal | ||
*/ | ||
export * from "./TokenProviderError"; | ||
/** | ||
* @internal | ||
*/ | ||
export * from "./chain"; | ||
/** | ||
* @internal | ||
*/ | ||
export * from "./fromStatic"; | ||
/** | ||
* @internal | ||
*/ | ||
export * from "./memoize"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1 @@ | ||
import { MemoizedProvider, Provider } from "@aws-sdk/types"; | ||
|
||
interface MemoizeOverload { | ||
/** | ||
* | ||
* Decorates a provider function with either static memoization. | ||
* | ||
* To create a statically memoized provider, supply a provider as the only | ||
* argument to this function. The provider will be invoked once, and all | ||
* invocations of the provider returned by `memoize` will return the same | ||
* promise object. | ||
* | ||
* @param provider The provider whose result should be cached indefinitely. | ||
*/ | ||
<T>(provider: Provider<T>): MemoizedProvider<T>; | ||
|
||
/** | ||
* Decorates a provider function with refreshing memoization. | ||
* | ||
* @param provider The provider whose result should be cached. | ||
* @param isExpired A function that will evaluate the resolved value and | ||
* determine if it is expired. For example, when | ||
* memoizing AWS credential providers, this function | ||
* should return `true` when the credential's | ||
* expiration is in the past (or very near future) and | ||
* `false` otherwise. | ||
* @param requiresRefresh A function that will evaluate the resolved value and | ||
* determine if it represents static value or one that | ||
* will eventually need to be refreshed. For example, | ||
* AWS credentials that have no defined expiration will | ||
* never need to be refreshed, so this function would | ||
* return `true` if the credentials resolved by the | ||
* underlying provider had an expiration and `false` | ||
* otherwise. | ||
*/ | ||
<T>( | ||
provider: Provider<T>, | ||
isExpired: (resolved: T) => boolean, | ||
requiresRefresh?: (resolved: T) => boolean | ||
): MemoizedProvider<T>; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
export const memoize: MemoizeOverload = <T>( | ||
provider: Provider<T>, | ||
isExpired?: (resolved: T) => boolean, | ||
requiresRefresh?: (resolved: T) => boolean | ||
): MemoizedProvider<T> => { | ||
let resolved: T; | ||
let pending: Promise<T> | undefined; | ||
let hasResult: boolean; | ||
let isConstant = false; | ||
// Wrapper over supplied provider with side effect to handle concurrent invocation. | ||
const coalesceProvider: Provider<T> = async () => { | ||
if (!pending) { | ||
pending = provider(); | ||
} | ||
try { | ||
resolved = await pending; | ||
hasResult = true; | ||
isConstant = false; | ||
} finally { | ||
pending = undefined; | ||
} | ||
return resolved; | ||
}; | ||
|
||
if (isExpired === undefined) { | ||
// This is a static memoization; no need to incorporate refreshing unless using forceRefresh; | ||
return async (options) => { | ||
if (!hasResult || options?.forceRefresh) { | ||
resolved = await coalesceProvider(); | ||
} | ||
return resolved; | ||
}; | ||
} | ||
|
||
return async (options) => { | ||
if (!hasResult || options?.forceRefresh) { | ||
resolved = await coalesceProvider(); | ||
} | ||
if (isConstant) { | ||
return resolved; | ||
} | ||
|
||
if (requiresRefresh && !requiresRefresh(resolved)) { | ||
isConstant = true; | ||
return resolved; | ||
} | ||
if (isExpired(resolved)) { | ||
await coalesceProvider(); | ||
return resolved; | ||
} | ||
return resolved; | ||
}; | ||
}; | ||
export { memoize } from "@smithy/property-provider"; |