|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +import base64 |
3 | 4 | import importlib |
4 | 5 | import json |
5 | 6 | import re |
|
28 | 29 | SQLMESH_JINJA_PACKAGE = "sqlmesh.utils.jinja" |
29 | 30 |
|
30 | 31 |
|
| 32 | +def b64decode(value: t.Union[str, bytes]) -> str: |
| 33 | + """Decode a base64-encoded value and return it as UTF-8 text. |
| 34 | +
|
| 35 | + Intended for base64-encoded string/JSON secrets (for example a service-account |
| 36 | + key stored in an environment variable), not arbitrary binary payloads. |
| 37 | + """ |
| 38 | + decoded = value.encode("utf-8") if isinstance(value, str) else value |
| 39 | + return base64.b64decode(decoded).decode("utf-8") |
| 40 | + |
| 41 | + |
| 42 | +def b64encode(value: t.Union[str, bytes]) -> str: |
| 43 | + """Base64-encode a value and return the encoding as UTF-8 text. |
| 44 | +
|
| 45 | + The input is treated as UTF-8 text, mirroring ``b64decode``; it is intended for |
| 46 | + string/JSON secrets rather than arbitrary binary payloads. |
| 47 | + """ |
| 48 | + encoded = value.encode("utf-8") if isinstance(value, str) else value |
| 49 | + return base64.b64encode(encoded).decode("utf-8") |
| 50 | + |
| 51 | + |
| 52 | +def create_builtin_filters() -> t.Dict[str, t.Callable]: |
| 53 | + return { |
| 54 | + "b64decode": b64decode, |
| 55 | + "b64encode": b64encode, |
| 56 | + } |
| 57 | + |
| 58 | + |
31 | 59 | def environment(**kwargs: t.Any) -> Environment: |
32 | 60 | extensions = kwargs.pop("extensions", []) |
33 | 61 | extensions.append("jinja2.ext.do") |
34 | 62 | extensions.append("jinja2.ext.loopcontrols") |
35 | | - return Environment(extensions=extensions, **kwargs) |
| 63 | + env = Environment(extensions=extensions, **kwargs) |
| 64 | + env.filters.update(create_builtin_filters()) |
| 65 | + return env |
36 | 66 |
|
37 | 67 |
|
38 | 68 | ENVIRONMENT = environment() |
|
0 commit comments