feat!: Initial v2 commit

* Implemented editorconfig
* Switched to ESM
* Switched to a TypeScript workflow
* Switched to projen for project management
* Major code refactor
* TODO: need tests
This commit is contained in:
Tom Keller
2022-10-14 20:38:03 -07:00
parent 50eedb0bfd
commit 239add3ff1
48 changed files with 17553 additions and 49931 deletions
+67
View File
@@ -0,0 +1,67 @@
import { STSClient } from '@aws-sdk/client-sts';
const MAX_TAG_VALUE_LENGTH = 256;
const SANITIZATION_CHARACTER = '_';
let stsclient: STSClient | undefined;
export function getStsClient(region: string, agent?: string) {
if (!stsclient) {
stsclient = new STSClient({
region,
customUserAgent: agent,
});
}
return stsclient;
}
export function sanitizeGithubActor(actor: string) {
// In some circumstances the actor may contain square brackets. For example, if they're a bot ('[bot]')
// Square brackets are not allowed in AWS session tags
return actor.replace(/\[|\]/g, SANITIZATION_CHARACTER);
}
export function sanitizeGithubWorkflowName(name: string) {
// Workflow names can be almost any valid UTF-8 string, but tags are more restrictive.
// This replaces anything not conforming to the tag restrictions by inverting the regular expression.
// See the AWS documentation for constraint specifics https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html.
const nameWithoutSpecialCharacters = name.replace(/[^\p{L}\p{Z}\p{N}_:/=+.-@-]/gu, SANITIZATION_CHARACTER);
const nameTruncated = nameWithoutSpecialCharacters.slice(0, MAX_TAG_VALUE_LENGTH);
return nameTruncated;
}
export function errorMessage(error: unknown) {
return error instanceof Error ? error.message : String(error);
}
export function isDefined<T>(i: T | undefined | null): i is T {
return i !== undefined && i !== null;
}
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// retryAndBackoff retries with exponential backoff the promise if the error isRetryable upto maxRetries time.
export async function retryAndBackoff<T>(
fn: () => Promise<T>,
isRetryable: boolean,
retries = 0,
maxRetries = 12,
base = 50
): Promise<T> {
try {
return await fn();
} catch (err) {
if (!isRetryable) {
throw err;
}
// It's retryable, so sleep and retry.
await sleep(Math.random() * (Math.pow(2, retries) * base));
retries += 1;
if (retries === maxRetries) {
throw err;
}
return await retryAndBackoff(fn, isRetryable, retries, maxRetries, base);
}
}