|
3 | 3 | """
|
4 | 4 | import logging
|
5 | 5 | from pathlib import Path
|
6 |
| -from typing import Any, Dict, List |
| 6 | +from typing import Any, Callable, Dict, List, Union |
7 | 7 |
|
8 | 8 | from aws_lambda_builders.actions import ActionFailedError
|
9 | 9 | from aws_lambda_builders.workflows.nodejs_npm.utils import OSUtils
|
@@ -99,28 +99,7 @@ def run(self, args, cwd=None):
|
99 | 99 | return out.decode("utf8").strip()
|
100 | 100 |
|
101 | 101 |
|
102 |
| -# The esbuild API flags are broken up into three forms (https://esbuild.github.io/api/): |
103 |
| -# Multi-word arguments are expected to be passed down using snake case e.g. entry_points |
104 |
| -# Boolean types (--minify) |
105 |
| -SUPPORTED_ESBUILD_APIS_BOOLEAN = [ |
106 |
| - "minify", |
107 |
| - "sourcemap", |
108 |
| -] |
109 |
| - |
110 |
| -# single value types (--target=es2020) |
111 |
| -SUPPORTED_ESBUILD_APIS_SINGLE_VALUE = [ |
112 |
| - "target", |
113 |
| - "format", |
114 |
| - "main_fields", |
115 |
| - "sources_content", |
116 |
| -] |
117 |
| - |
118 |
| -# Multi-value types (--external:axios --external:aws-sdk) |
119 |
| -SUPPORTED_ESBUILD_APIS_MULTI_VALUE = [ |
120 |
| - "external", |
121 |
| - "loader", |
122 |
| - "out_extension", |
123 |
| -] |
| 102 | +NON_CONFIGURABLE_VALUES = {"bundle", "platform", "outdir"} |
124 | 103 |
|
125 | 104 |
|
126 | 105 | class EsbuildCommandBuilder:
|
@@ -154,15 +133,96 @@ def build_esbuild_args_from_config(self) -> "EsbuildCommandBuilder":
|
154 | 133 | """
|
155 | 134 | args = []
|
156 | 135 |
|
157 |
| - args.extend(self._get_boolean_args()) |
158 |
| - args.extend(self._get_single_value_args()) |
159 |
| - args.extend(self._get_multi_value_args()) |
| 136 | + for config_key, config_value in self._bundler_config.items(): |
| 137 | + if config_key in NON_CONFIGURABLE_VALUES: |
| 138 | + LOG.debug( |
| 139 | + "'%s=%s' was not a used configuration since AWS Lambda Builders " |
| 140 | + "sets these values for the code to be correctly consumed by AWS Lambda", |
| 141 | + config_key, |
| 142 | + config_value, |
| 143 | + ) |
| 144 | + continue |
| 145 | + if config_key == "entry_points": |
| 146 | + # Entry points are a required parameter and are handled by the build_entry_points() method |
| 147 | + continue |
| 148 | + configuration_type_callback = self._get_config_type_callback(config_value) |
| 149 | + LOG.debug("Configuring the parameter '%s=%s'", config_key, config_value) |
| 150 | + args.extend(configuration_type_callback(config_key, config_value)) |
160 | 151 |
|
161 | 152 | LOG.debug("Found the following args in the config: %s", str(args))
|
162 | 153 |
|
163 | 154 | self._command.extend(args)
|
164 | 155 | return self
|
165 | 156 |
|
| 157 | + def _get_config_type_callback( |
| 158 | + self, config_value: Union[bool, str, list] |
| 159 | + ) -> Callable[[str, Union[bool, str, list]], List[str]]: |
| 160 | + """ |
| 161 | + Determines the type of the command and returns the corresponding |
| 162 | + function to build out that command line argument type |
| 163 | +
|
| 164 | + :param config_value: Union[bool, str, list] |
| 165 | + The configuration value configured through the options. The configuration should be one |
| 166 | + of the supported types as defined by the esbuild API (https://esbuild.github.io/api/). |
| 167 | + :return: Callable[[str, Union[bool, str, list]], List[str]] |
| 168 | + Returns a function that the caller can use to turn the relevant |
| 169 | + configuration into the correctly formatted command line argument. |
| 170 | + """ |
| 171 | + if isinstance(config_value, bool): |
| 172 | + return self._create_boolean_config |
| 173 | + elif isinstance(config_value, str): |
| 174 | + return self._create_str_config |
| 175 | + elif isinstance(config_value, list): |
| 176 | + return self._create_list_config |
| 177 | + raise EsbuildCommandError("Failed to determine the type of the configuration: %s", config_value) |
| 178 | + |
| 179 | + def _create_boolean_config(self, config_key: str, config_value: bool) -> List[str]: |
| 180 | + """ |
| 181 | + Given boolean-type configuration, convert it to a string representation suitable for the esbuild API |
| 182 | + Should be created in the form ([--config-key]) |
| 183 | +
|
| 184 | + :param config_key: str |
| 185 | + The configuration key to be used |
| 186 | + :param config_value: bool |
| 187 | + The configuration value to be used |
| 188 | + :return: List[str] |
| 189 | + List of resolved command line arguments to be appended to the builder |
| 190 | + """ |
| 191 | + if config_value is True: |
| 192 | + return [f"--{self._convert_snake_to_kebab_case(config_key)}"] |
| 193 | + return [] |
| 194 | + |
| 195 | + def _create_str_config(self, config_key: str, config_value: str) -> List[str]: |
| 196 | + """ |
| 197 | + Given string-type configuration, convert it to a string representation suitable for the esbuild API |
| 198 | + Should be created in the form ([--config-key=config_value]) |
| 199 | +
|
| 200 | + :param config_key: str |
| 201 | + The configuration key to be used |
| 202 | + :param config_value: List[str] |
| 203 | + The configuration value to be used |
| 204 | + :return: List[str] |
| 205 | + List of resolved command line arguments to be appended to the builder |
| 206 | + """ |
| 207 | + return [f"--{self._convert_snake_to_kebab_case(config_key)}={config_value}"] |
| 208 | + |
| 209 | + def _create_list_config(self, config_key: str, config_value: List[str]) -> List[str]: |
| 210 | + """ |
| 211 | + Given list-type configuration, convert it to a string representation suitable for the esbuild API |
| 212 | + Should be created in the form ([--config-key:config_value_a, --config_key:config_value_b]) |
| 213 | +
|
| 214 | + :param config_key: str |
| 215 | + The configuration key to be used |
| 216 | + :param config_value: List[str] |
| 217 | + The configuration value to be used |
| 218 | + :return: List[str] |
| 219 | + List of resolved command line arguments to be appended to the builder |
| 220 | + """ |
| 221 | + args = [] |
| 222 | + for config_item in config_value: |
| 223 | + args.append(f"--{self._convert_snake_to_kebab_case(config_key)}:{config_item}") |
| 224 | + return args |
| 225 | + |
166 | 226 | def build_entry_points(self) -> "EsbuildCommandBuilder":
|
167 | 227 | """
|
168 | 228 | Build the entry points to the command
|
@@ -227,50 +287,6 @@ def build_with_no_dependencies(self) -> "EsbuildCommandBuilder":
|
227 | 287 | self._command.extend(args)
|
228 | 288 | return self
|
229 | 289 |
|
230 |
| - def _get_boolean_args(self) -> List[str]: |
231 |
| - """ |
232 |
| - Get a list of all the boolean value flag types (e.g. --minify) |
233 |
| -
|
234 |
| - :rtype: List[str] |
235 |
| - :return: Arguments to be appended to the command list |
236 |
| - """ |
237 |
| - args = [] |
238 |
| - for param in SUPPORTED_ESBUILD_APIS_BOOLEAN: |
239 |
| - if param in self._bundler_config and self._bundler_config[param] is True: |
240 |
| - args.append(f"--{self._convert_snake_to_kebab_case(param)}") |
241 |
| - return args |
242 |
| - |
243 |
| - def _get_single_value_args(self) -> List[str]: |
244 |
| - """ |
245 |
| - Get a list of all the single value flag types (e.g. --target=es2020) |
246 |
| -
|
247 |
| - :rtype: List[str] |
248 |
| - :return: Arguments to be appended to the command list |
249 |
| - """ |
250 |
| - args = [] |
251 |
| - for param in SUPPORTED_ESBUILD_APIS_SINGLE_VALUE: |
252 |
| - if param in self._bundler_config: |
253 |
| - value = self._bundler_config.get(param) |
254 |
| - args.append(f"--{self._convert_snake_to_kebab_case(param)}={value}") |
255 |
| - return args |
256 |
| - |
257 |
| - def _get_multi_value_args(self) -> List[str]: |
258 |
| - """ |
259 |
| - Get a list of all the multi-value flag types (e.g. --external:aws-sdk) |
260 |
| -
|
261 |
| - :rtype: List[str] |
262 |
| - :return: Arguments to be appended to the command list |
263 |
| - """ |
264 |
| - args = [] |
265 |
| - for param in SUPPORTED_ESBUILD_APIS_MULTI_VALUE: |
266 |
| - if param in self._bundler_config: |
267 |
| - values = self._bundler_config.get(param) |
268 |
| - if not isinstance(values, list): |
269 |
| - raise EsbuildCommandError(f"Invalid type for property {param}, must be a dict.") |
270 |
| - for param_item in values: |
271 |
| - args.append(f"--{self._convert_snake_to_kebab_case(param)}:{param_item}") |
272 |
| - return args |
273 |
| - |
274 | 290 | def _get_explicit_file_type(self, entry_point, entry_path):
|
275 | 291 | """
|
276 | 292 | Get an entry point with an explicit .ts or .js suffix.
|
|
0 commit comments