From 81b84ee223cae9bc89f96514589c37510faed248 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Tue, 25 Jul 2023 14:39:50 +0200 Subject: [PATCH 01/16] fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa --- aws_lambda_powertools/utilities/parameters/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/parameters/base.py b/aws_lambda_powertools/utilities/parameters/base.py index 2317ebc82d9..4ee6caa6c2f 100644 --- a/aws_lambda_powertools/utilities/parameters/base.py +++ b/aws_lambda_powertools/utilities/parameters/base.py @@ -28,7 +28,7 @@ from aws_lambda_powertools.shared import constants, user_agent from aws_lambda_powertools.shared.functions import resolve_max_age -from aws_lambda_powertools.utilities.parameters.types import TransformOptions +from aws_lambda_powertools.utilities.parameters.types import RecursiveOptions, TransformOptions from .exceptions import GetParameterError, TransformParameterError From 822ef012db5803e311003e09974f9704033b378f Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Tue, 25 Jul 2023 15:16:51 +0200 Subject: [PATCH 02/16] chore: cleanup, add test for single and nested Signed-off-by: heitorlessa --- aws_lambda_powertools/utilities/parameters/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/parameters/base.py b/aws_lambda_powertools/utilities/parameters/base.py index 4ee6caa6c2f..2317ebc82d9 100644 --- a/aws_lambda_powertools/utilities/parameters/base.py +++ b/aws_lambda_powertools/utilities/parameters/base.py @@ -28,7 +28,7 @@ from aws_lambda_powertools.shared import constants, user_agent from aws_lambda_powertools.shared.functions import resolve_max_age -from aws_lambda_powertools.utilities.parameters.types import RecursiveOptions, TransformOptions +from aws_lambda_powertools.utilities.parameters.types import TransformOptions from .exceptions import GetParameterError, TransformParameterError From e6aad730017798ceb4fa16a48612130ddacc6171 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 5 Apr 2024 17:46:07 +0200 Subject: [PATCH 03/16] chore(ci): add first centralized reusable workflow --- bla.py | 78 +++++++++++ playground/.prettierrc | 4 + playground/app.mjs | 311 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 393 insertions(+) create mode 100644 bla.py create mode 100644 playground/.prettierrc create mode 100644 playground/app.mjs diff --git a/bla.py b/bla.py new file mode 100644 index 00000000000..bb447e66675 --- /dev/null +++ b/bla.py @@ -0,0 +1,78 @@ +# KMS_KEYS = ["arn:aws:kms:eu-west-1:231436140809:key/1053c7d7-97d7-49ca-9763-5214f28999cc"] + +# from aws_lambda_powertools.utilities.data_masking import DataMasking +# from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( +# AWSEncryptionSDKProvider, +# ) + + +# # from aws_lambda_powertools import Logger + +# # from aws_lambda_powertools.logging.utils import copy_config_to_registered_loggers + +# # logger = Logger() + +# # copy_config_to_registered_loggers(source_logger=logger, log_level="DEBUG") + +# # def test_encryption_context_kms_api(data: bytes): +# # import boto3 + +# # kms = boto3.client("kms") +# # cipher = kms.encrypt(KeyId=KMS_KEYS[0], Plaintext=data, EncryptionContext={"h": "e"}) + +# # # When encryption context isn't an exact match +# # # botocore.errorfactory.InvalidCiphertextException: An error occurred (InvalidCiphertextException) when calling the Decrypt operation: +# # kms.decrypt(CiphertextBlob=cipher["CiphertextBlob"]) + + +# encryption_provider = AWSEncryptionSDKProvider(keys=KMS_KEYS) +# masker = DataMasking(provider=encryption_provider) + + +# data = { +# "name": "Leandro", +# "operation": "non sensitive", +# "card_number": "1000 4444 333 2222", +# "address": [ +# { +# "postcode": 81847, +# "street": "38986 Joanne Stravenue", +# "country": "United States", +# "timezone": "America/La_Paz", +# }, +# {"postcode": 94400, "street": "623 Kraig Mall", "country": "United States", "timezone": "America/Mazatlan"}, +# ], +# } + + +# fields = ["address[*].postcode"] +# encrypted = masker.encrypt(data, fields, data_classification="10", data_type="customer_data") +# output = f""" +# ========================Encrypted blob======================== + +# {masker.encrypt(data)} + +# ========================Field encrypted======================= + +# {encrypted} + +# ========================Decrypted============================= + + +# {masker.decrypt(encrypted, data_type="customer_data", data_classification="10")} + +# ============================================================== +# """ + +# print(output) + +# # encrypted_data = { +# # "zip": [ +# # { +# # "postcode": "AgV4cx2NbEYAiNulToXGoaFxGB8avUnn0C5yuECrPbTgrmkAXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREFtV0hyRzROQ0h3Z1hSQmFGVDZCemUwT2dzMGVsK2tTL2hUV1FKZnZrTjJ3OUNQYlk2bTg3QmF0MVJ3NmdNUWNIZz09AAEAB2F3cy1rbXMAS2Fybjphd3M6a21zOmV1LXdlc3QtMToyMzE0MzYxNDA4MDk6a2V5LzEwNTNjN2Q3LTk3ZDctNDljYS05NzYzLTUyMTRmMjg5OTljYwC4AQIBAHgWR9amI/KXfzepTHbCvEUXLMN8D5Fzkp9W3nvbLFphtgF1vgCkRBJno+apgeramUnFAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM1s93BzUOeCTYIFJ/AgEQgDvhPDdfMN6dPAdQN16djAUhoYjkdIbKx+g9VBp2HZ8RF2gBvsla3chPkTR+ElfanPiEqt49rL2c46RvVwIAABAAV8XWwONI8SlcSYaGblM516qB6gh93eEb2DlWbt8uo13BpgdjZhYEIzRU7C+Nmoq6/////wAAAAEAAAAAAAAAAAAAAAEAAAAHfIP2Crb6uIIkj0KnT2y34JUyKL/L3TAAZzBlAjAqPfOXUJBmB3BpUL4VT4xaHVSv74wfrqtHbTVKrzvTKpb7AdwMJTEXLHXcZwQXncwCMQCX82+7r6wZ7aE1d7c/thDLB/w3HcFAvEadnBsBbkGrMpSZrI6TiRuqSE4EIZZLNWc=" +# # } +# # ], +# # "name": "Lessa", +# # "operation": "non sensitive", +# # "card_number": "1000 4444 333 2222", +# # } diff --git a/playground/.prettierrc b/playground/.prettierrc new file mode 100644 index 00000000000..222861c3415 --- /dev/null +++ b/playground/.prettierrc @@ -0,0 +1,4 @@ +{ + "tabWidth": 2, + "useTabs": false +} diff --git a/playground/app.mjs b/playground/app.mjs new file mode 100644 index 00000000000..5d1915c0518 --- /dev/null +++ b/playground/app.mjs @@ -0,0 +1,311 @@ +const DEFAULT_EMPTY_RESPONSE = [{}]; +const MONTH = new Date().toLocaleString("default", { month: "long" }); +const BLOCKED_LABELS = [ + "do-not-merge", + "need-issue", + "need-rfc", + "need-customer-feedback", +]; + +/** + * Calculate the difference in days between the current date and a given datetime. + * + * @param {string} datetime - The datetime string to calculate the difference from. + * @returns {number} - The difference in days between the current date and the given datetime. + */ +const diffInDays = (datetime) => { + const diff_in_ms = new Date() - new Date(datetime); + + // ms(1000)->seconds(60)->minutes(60)->hours(24)->days + return Math.floor(diff_in_ms / (1000 * 60 * 60 * 24)); +}; + +/** + * Formats a datetime string into a localized human date string e.g., April 5, 2024. + * + * @param {string} datetime - The datetime string to format. + * @returns {string} The formatted date string. + * + * @example + * const datetime = "2022-01-01T12:00:00Z"; + * console.log(formatDate(datetime)); // April 5, 2024 + */ +const formatDate = (datetime) => { + const date = new Date(datetime); + return new Intl.DateTimeFormat("en-US", { dateStyle: "long" }).format(date); +}; + +/** + * Generates a markdown table from an array of key:value object. + * + * This function takes an array of objects as input and generates a markdown table with the keys as column headings and the values as rows. + * + * @param {Array} data - The data to generate the table from. + * @returns {Object} An object containing the formatted table components. + * - heading: The formatted column headings of the table. + * - dashes: The formatted dashed line separating the headings from the rows. + * - rows: The formatted rows of the table. + * + * @example + * const data = [ + * { name: 'John', age: 30, city: 'New York' }, + * { name: 'Jane', age: 25, city: 'London' }, + * { name: 'Bob', age: 35, city: 'Paris' } + * ]; + * + * const table = buildMarkdownTable(data); + * console.log(table.heading); // '| name | age | city |' + * console.log(table.dashes); // '| ---- | --- | ---- |' + * console.log(table.rows); // '| John | 30 | New York |' + */ +const buildMarkdownTable = (data) => { + const keys = Object.keys(data[0]); + + if (keys.length === 0) { + return "Not available"; + } + + const formatted_headings = `${keys.join(" | ")}`; + const keyLength = keys[0]?.length || 0; + const dashes = keys.map(() => `${"-".repeat(keyLength)} |`).join(" "); + + const values = data.map((issues) => Object.values(issues)); + const rows = values.map((row) => `${row.join(" | ")} |`).join("\n"); + + return `${formatted_headings} +${dashes} +${rows}`; +}; + +/** + * Retrieves a list of PRs from a repository sorted by `reactions-+1` keyword. + * + * @param {import('@types/github-script').AsyncFunctionArguments} AsyncFunctionArguments + * @typedef {Object} Response + * @property {string} title - The title of the issue, with a link to the issue. + * @property {string} created_at - The creation date of the issue, formatted as April 5, 2024. + * @property {number} reaction_count - The total number of reactions on the issue. + * @property {string} labels - The labels of the issue, enclosed in backticks. + * @returns {Promise>} A promise resolving with an array of issue objects. + * + */ +async function getTopFeatureRequests({ github, context, core }) { + core.info("Fetching feature requests sorted by +1 reactions"); + + const { data: issues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + labels: "feature-request", + sort: "reactions-+1", + direction: "desc", + per_page: 3, + }); + + core.info("Successfully fetched issues"); + core.debug(issues); + + return issues.map((issue) => ({ + title: `[${issue.title}](${issue.html_url})`, + created_at: formatDate(issue.created_at), + reaction_count: issue.reactions.total_count, + labels: `${issue.labels.map((label) => `\`${label.name}\``).join(",")}`, // enclose each label with `