@aws/nx-plugin 1.0.0-rc.33 → 1.0.0-rc.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +28 -41
- package/generators.json +27 -0
- package/package.json +6 -6
- package/src/connection/generator.js +12 -1
- package/src/connection/generator.js.map +1 -1
- package/src/connection/supported-connections.d.ts +10 -1
- package/src/connection/supported-connections.js +13 -0
- package/src/connection/supported-connections.js.map +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/open-api/ts-client/__snapshots__/generator.complex-types.spec.ts.snap +12 -12
- package/src/open-api/ts-client/__snapshots__/generator.composite-types.spec.ts.snap +74 -10
- package/src/open-api/ts-client/__snapshots__/generator.content-type.spec.ts.snap +22 -4
- package/src/open-api/ts-client/__snapshots__/generator.duplicate-types.spec.ts.snap +53 -8
- package/src/open-api/ts-client/__snapshots__/generator.edge-cases.spec.ts.snap +32 -4
- package/src/open-api/ts-client/__snapshots__/generator.fast-api-gaps.spec.ts.snap +736 -0
- package/src/open-api/ts-client/__snapshots__/generator.fast-api.spec.ts.snap +86 -11
- package/src/open-api/ts-client/__snapshots__/generator.multipart.spec.ts.snap +21 -3
- package/src/open-api/ts-client/__snapshots__/generator.primitive-types.spec.ts.snap +2 -2
- package/src/open-api/ts-client/__snapshots__/generator.request.spec.ts.snap +6 -6
- package/src/open-api/ts-client/__snapshots__/generator.reserved-keywords.spec.ts.snap +2 -2
- package/src/open-api/ts-client/__snapshots__/generator.spec-compliance.spec.ts.snap +1883 -0
- package/src/open-api/ts-client/__snapshots__/generator.tags.spec.ts.snap +4 -4
- package/src/open-api/ts-client/files/client.gen.ts.template +195 -12
- package/src/open-api/ts-client/files/types.gen.ts.template +2 -0
- package/src/open-api/ts-client/generator.js +22 -1
- package/src/open-api/ts-client/generator.js.map +1 -1
- package/src/open-api/utils/codegen-data/languages.js +6 -0
- package/src/open-api/utils/codegen-data/languages.js.map +1 -1
- package/src/open-api/utils/codegen-data/types.d.ts +16 -1
- package/src/open-api/utils/codegen-data/types.js.map +1 -1
- package/src/open-api/utils/codegen-data.js +71 -0
- package/src/open-api/utils/codegen-data.js.map +1 -1
- package/src/open-api/utils/normalise.js +53 -8
- package/src/open-api/utils/normalise.js.map +1 -1
- package/src/open-api/utils/parser.js +48 -15
- package/src/open-api/utils/parser.js.map +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +4 -2
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +1 -1
- package/src/py/fast-api/__snapshots__/generator.terraform.spec.ts.snap +186 -18
- package/src/py/rdb/__snapshots__/generator.spec.ts.snap +2038 -0
- package/src/py/rdb/agent-connection/__snapshots__/generator.spec.ts.snap +104 -0
- package/src/py/rdb/agent-connection/generator.d.ts +10 -0
- package/src/py/rdb/agent-connection/generator.js +46 -0
- package/src/py/rdb/agent-connection/generator.js.map +1 -0
- package/src/py/rdb/agent-connection/schema.d.js +8 -0
- package/src/py/rdb/agent-connection/schema.d.js.map +1 -0
- package/src/py/rdb/agent-connection/schema.d.ts +15 -0
- package/src/py/rdb/agent-connection/schema.json +27 -0
- package/src/py/rdb/fast-api-connection/__snapshots__/generator.spec.ts.snap +44 -0
- package/src/py/rdb/fast-api-connection/files/__apiModuleName__/dependencies/__rdbNameSnake__.py.template +14 -0
- package/src/py/rdb/fast-api-connection/generator.d.ts +10 -0
- package/src/py/rdb/fast-api-connection/generator.js +54 -0
- package/src/py/rdb/fast-api-connection/generator.js.map +1 -0
- package/src/py/rdb/fast-api-connection/schema.d.js +8 -0
- package/src/py/rdb/fast-api-connection/schema.d.js.map +1 -0
- package/src/py/rdb/fast-api-connection/schema.d.ts +13 -0
- package/src/py/rdb/fast-api-connection/schema.json +23 -0
- package/src/py/rdb/files/Dockerfile.create-db-user.template +10 -0
- package/src/py/rdb/files/Dockerfile.migration.template +10 -0
- package/src/py/rdb/files/__name__/__init__.py.template +3 -0
- package/src/py/rdb/files/__name__/connection.py.template +55 -0
- package/src/py/rdb/files/__name__/create_db_user_handler.py.template +97 -0
- package/src/py/rdb/files/__name__/migration_handler.py.template +36 -0
- package/src/py/rdb/files/__name__/models/__init__.py.template +3 -0
- package/src/py/rdb/files/__name__/models/example.py.template +8 -0
- package/src/py/rdb/files/__name__/utils.py.template +104 -0
- package/src/py/rdb/files/alembic.ini.template +38 -0
- package/src/py/rdb/files/config.json.template +14 -0
- package/src/py/rdb/files/migrations/env.py.template +80 -0
- package/src/py/rdb/files/migrations/script.py.mako.template +28 -0
- package/src/py/rdb/generator.d.ts +6 -0
- package/src/py/rdb/generator.js +263 -0
- package/src/py/rdb/generator.js.map +1 -0
- package/src/py/rdb/mcp-server-connection/__snapshots__/generator.spec.ts.snap +101 -0
- package/src/py/rdb/mcp-server-connection/generator.d.ts +10 -0
- package/src/py/rdb/mcp-server-connection/generator.js +46 -0
- package/src/py/rdb/mcp-server-connection/generator.js.map +1 -0
- package/src/py/rdb/mcp-server-connection/schema.d.js +8 -0
- package/src/py/rdb/mcp-server-connection/schema.d.js.map +1 -0
- package/src/py/rdb/mcp-server-connection/schema.d.ts +15 -0
- package/src/py/rdb/mcp-server-connection/schema.json +27 -0
- package/src/py/rdb/schema.d.js +6 -0
- package/src/py/rdb/schema.d.js.map +1 -0
- package/src/py/rdb/schema.d.ts +16 -0
- package/src/py/rdb/schema.json +77 -0
- package/src/py/rdb/utils.d.ts +6 -0
- package/src/py/rdb/utils.js +16 -0
- package/src/py/rdb/utils.js.map +1 -0
- package/src/sdk/py.d.ts +2 -0
- package/src/sdk/py.js +1 -0
- package/src/sdk/py.js.map +1 -1
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +124 -12
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +186 -18
- package/src/ts/rdb/__snapshots__/generator.spec.ts.snap +145 -173
- package/src/ts/rdb/generator.js +4 -3
- package/src/ts/rdb/generator.js.map +1 -1
- package/src/ts/rdb/schema.json +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +16 -16
- package/src/utils/api-constructs/files/terraform/app/apis/http/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +31 -3
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +31 -3
- package/src/utils/rdb-constructs/files/cdk/app/dbs/__nameKebabCase__.ts.template +58 -14
- package/src/utils/rdb-constructs/files/cdk/core/rdb/aurora.ts.template +68 -78
- package/src/utils/rdb-constructs/files/terraform/app/dbs/__nameKebabCase__/__nameKebabCase__.tf.template +88 -8
- package/src/utils/rdb-constructs/files/terraform/core/rdb/aurora/aurora.tf.template +5 -32
- package/src/utils/rdb-constructs/rdb-constructs.d.ts +11 -1
- package/src/utils/rdb-constructs/rdb-constructs.js.map +1 -1
- package/src/utils/shared-constructs.js +9 -21
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/shared-rdb-scripts.js +5 -1
- package/src/utils/shared-rdb-scripts.js.map +1 -1
- package/src/utils/versions.d.ts +34 -30
- package/src/utils/versions.js +34 -30
- package/src/utils/versions.js.map +1 -1
- package/src/utils/files/terraform/scripts/reset-runtime-config.ts.template +0 -25
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from sqlalchemy import Column, String
|
|
2
|
+
from sqlmodel import Field, SQLModel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ExampleModel(SQLModel, table=True):
|
|
6
|
+
id: int | None = Field(default=None, primary_key=True)
|
|
7
|
+
name: str = Field(sa_column=Column(String(255), nullable=False))
|
|
8
|
+
description: str | None = Field(default=None, sa_column=Column(String(255), nullable=True))
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import boto3
|
|
8
|
+
from aws_lambda_powertools.utilities.parameters import AppConfigProvider
|
|
9
|
+
from sqlalchemy import URL
|
|
10
|
+
|
|
11
|
+
DatabaseConfig = dict[str, Any]
|
|
12
|
+
DatabaseSecret = dict[str, Any]
|
|
13
|
+
|
|
14
|
+
def build_database_url(
|
|
15
|
+
username: str,
|
|
16
|
+
host: str,
|
|
17
|
+
port: int,
|
|
18
|
+
database: str,
|
|
19
|
+
password: str | None = None,
|
|
20
|
+
) -> URL:
|
|
21
|
+
return URL.create(
|
|
22
|
+
drivername='<%= engine === "mysql" ? "mysql+aiomysql" : "postgresql+asyncpg" %>',
|
|
23
|
+
username=username,
|
|
24
|
+
password=password,
|
|
25
|
+
host=host,
|
|
26
|
+
port=port,
|
|
27
|
+
database=database,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def is_local_dev() -> bool:
|
|
32
|
+
return os.environ.get('LOCAL_DEV') == 'true'
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_local_dev_config() -> dict:
|
|
36
|
+
config_path = os.path.join(os.path.dirname(__file__), '..', 'config.json')
|
|
37
|
+
with open(config_path) as f:
|
|
38
|
+
return json.load(f)['localDev']
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_database_secret() -> DatabaseSecret:
|
|
42
|
+
secret_arn = os.environ.get('DATABASE_SECRET_ARN')
|
|
43
|
+
if not secret_arn:
|
|
44
|
+
raise ValueError('Missing required environment variable DATABASE_SECRET_ARN.')
|
|
45
|
+
client = boto3.client('secretsmanager')
|
|
46
|
+
response = client.get_secret_value(SecretId=secret_arn)
|
|
47
|
+
return json.loads(response['SecretString'])
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
_database_config: dict[str, DatabaseConfig] = {}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_database_config(runtime_config_key: str) -> DatabaseConfig:
|
|
54
|
+
if runtime_config_key not in _database_config:
|
|
55
|
+
app_id = os.environ.get('RUNTIME_CONFIG_APP_ID')
|
|
56
|
+
if not app_id:
|
|
57
|
+
raise ValueError('Missing required environment variable RUNTIME_CONFIG_APP_ID.')
|
|
58
|
+
provider = AppConfigProvider(application=app_id, environment='default')
|
|
59
|
+
config = provider.get('database', transform='json')
|
|
60
|
+
if not isinstance(config, dict):
|
|
61
|
+
raise ValueError('Unexpected RuntimeConfig format: expected JSON object.')
|
|
62
|
+
db_config = config.get(runtime_config_key)
|
|
63
|
+
if not db_config:
|
|
64
|
+
raise ValueError(f'RuntimeConfig is missing database.{runtime_config_key}.')
|
|
65
|
+
_database_config[runtime_config_key] = db_config
|
|
66
|
+
return _database_config[runtime_config_key]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
_TRANSIENT_ERROR_PATTERNS = [
|
|
70
|
+
'timeout',
|
|
71
|
+
'connection refused',
|
|
72
|
+
'could not connect',
|
|
73
|
+
'connection reset',
|
|
74
|
+
'connection timed out',
|
|
75
|
+
'operationalerror',
|
|
76
|
+
'password authentication failed',
|
|
77
|
+
'access denied',
|
|
78
|
+
'temporary failure',
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def is_transient_connection_error(error: Exception) -> bool:
|
|
83
|
+
error_str = str(error).lower()
|
|
84
|
+
return any(p in error_str for p in _TRANSIENT_ERROR_PATTERNS)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def with_connection_retry[T](
|
|
88
|
+
fn: Callable[[], T],
|
|
89
|
+
max_attempts: int = 6,
|
|
90
|
+
delay_seconds: float = 10.0,
|
|
91
|
+
) -> T:
|
|
92
|
+
for attempt in range(1, max_attempts + 1):
|
|
93
|
+
try:
|
|
94
|
+
return fn()
|
|
95
|
+
except Exception as e:
|
|
96
|
+
if attempt == max_attempts or not is_transient_connection_error(e):
|
|
97
|
+
raise
|
|
98
|
+
wait = delay_seconds * attempt
|
|
99
|
+
print(
|
|
100
|
+
f'Transient connection error (attempt {attempt}/{max_attempts}), '
|
|
101
|
+
f'retrying in {wait:.0f}s: {e}'
|
|
102
|
+
)
|
|
103
|
+
time.sleep(wait)
|
|
104
|
+
raise RuntimeError('unreachable')
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[alembic]
|
|
2
|
+
script_location = migrations
|
|
3
|
+
file_template = %%(year)d%%(month).2d%%(day).2d_%%(hour).2d%%(minute).2d_%%(rev)s_%%(slug)s
|
|
4
|
+
prepend_sys_path = .
|
|
5
|
+
|
|
6
|
+
[loggers]
|
|
7
|
+
keys = root,sqlalchemy,alembic
|
|
8
|
+
|
|
9
|
+
[handlers]
|
|
10
|
+
keys = console
|
|
11
|
+
|
|
12
|
+
[formatters]
|
|
13
|
+
keys = generic
|
|
14
|
+
|
|
15
|
+
[logger_root]
|
|
16
|
+
level = WARN
|
|
17
|
+
handlers = console
|
|
18
|
+
qualname =
|
|
19
|
+
|
|
20
|
+
[logger_sqlalchemy]
|
|
21
|
+
level = WARN
|
|
22
|
+
handlers =
|
|
23
|
+
qualname = sqlalchemy.engine
|
|
24
|
+
|
|
25
|
+
[logger_alembic]
|
|
26
|
+
level = INFO
|
|
27
|
+
handlers =
|
|
28
|
+
qualname = alembic
|
|
29
|
+
|
|
30
|
+
[handler_console]
|
|
31
|
+
class = StreamHandler
|
|
32
|
+
args = (sys.stderr,)
|
|
33
|
+
level = NOTSET
|
|
34
|
+
formatter = generic
|
|
35
|
+
|
|
36
|
+
[formatter_generic]
|
|
37
|
+
format = %(levelname)-5.5s [%(name)s] %(message)s
|
|
38
|
+
datefmt = %H:%M:%S
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"runtimeConfigKey": "<%= runtimeConfigKey %>",
|
|
3
|
+
"localDev": {
|
|
4
|
+
"containerEngine": "<%= containerEngine %>",
|
|
5
|
+
"containerName": "<%= containerName %>",
|
|
6
|
+
"image": "<%= dockerImage %>",
|
|
7
|
+
"port": <%= localDbPort %>,
|
|
8
|
+
"host": "<%= localDbHost %>",
|
|
9
|
+
"dbName": "<%= localDbName %>",
|
|
10
|
+
"dbUser": "<%= localDbUser %>",
|
|
11
|
+
"dbPassword": "<%= localDbPassword %>",
|
|
12
|
+
"dbEngine": "<%= engine %>"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
from logging.config import fileConfig
|
|
5
|
+
|
|
6
|
+
from alembic import context
|
|
7
|
+
from sqlalchemy import URL
|
|
8
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
9
|
+
from sqlmodel import SQLModel
|
|
10
|
+
|
|
11
|
+
# Import all models to register them in SQLModel.metadata
|
|
12
|
+
from <%= name %>.models import * # noqa: F401, F403
|
|
13
|
+
|
|
14
|
+
config = context.config
|
|
15
|
+
|
|
16
|
+
if config.config_file_name is not None:
|
|
17
|
+
fileConfig(config.config_file_name)
|
|
18
|
+
|
|
19
|
+
target_metadata = SQLModel.metadata
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _get_local_url():
|
|
23
|
+
if os.environ.get('LOCAL_DEV') == 'true':
|
|
24
|
+
config_path = os.path.join(os.path.dirname(__file__), '..', 'config.json')
|
|
25
|
+
with open(config_path) as f:
|
|
26
|
+
cfg = json.load(f)['localDev']
|
|
27
|
+
engine = cfg['dbEngine']
|
|
28
|
+
driver = 'mysql+aiomysql' if engine == 'mysql' else 'postgresql+asyncpg'
|
|
29
|
+
return URL.create(
|
|
30
|
+
driver,
|
|
31
|
+
username=cfg['dbUser'],
|
|
32
|
+
password=cfg['dbPassword'],
|
|
33
|
+
host=cfg['host'],
|
|
34
|
+
port=cfg['port'],
|
|
35
|
+
database=cfg['dbName'],
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
raise RuntimeError('Run alembic via nx run <project>:alembic')
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# Generates SQL script without a live DB connection (alembic upgrade head --sql)
|
|
42
|
+
def run_migrations_offline() -> None:
|
|
43
|
+
context.configure(
|
|
44
|
+
url=_get_local_url(),
|
|
45
|
+
target_metadata=target_metadata,
|
|
46
|
+
literal_binds=True,
|
|
47
|
+
dialect_opts={'paramstyle': 'named'},
|
|
48
|
+
)
|
|
49
|
+
with context.begin_transaction():
|
|
50
|
+
context.run_migrations()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _run_migrations_sync(sync_conn) -> None:
|
|
54
|
+
context.configure(connection=sync_conn, target_metadata=target_metadata)
|
|
55
|
+
with context.begin_transaction():
|
|
56
|
+
context.run_migrations()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Runs migrations against a live DB connection
|
|
60
|
+
def run_migrations_online() -> None:
|
|
61
|
+
supplied_connection = config.attributes.get('connection')
|
|
62
|
+
# Connection injected by migration_handler.py (Lambda)
|
|
63
|
+
if supplied_connection is not None:
|
|
64
|
+
_run_migrations_sync(supplied_connection)
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
# Local alembic commands run via nx run <project>:alembic
|
|
68
|
+
async def _run_async() -> None:
|
|
69
|
+
engine = create_async_engine(_get_local_url())
|
|
70
|
+
async with engine.begin() as conn:
|
|
71
|
+
await conn.run_sync(_run_migrations_sync)
|
|
72
|
+
await engine.dispose()
|
|
73
|
+
|
|
74
|
+
asyncio.run(_run_async())
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if context.is_offline_mode():
|
|
78
|
+
run_migrations_offline()
|
|
79
|
+
else:
|
|
80
|
+
run_migrations_online()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""${message}
|
|
2
|
+
|
|
3
|
+
Revision ID: ${up_revision}
|
|
4
|
+
Revises: ${down_revision | comma,n}
|
|
5
|
+
Create Date: ${create_date}
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
from typing import Sequence, Union
|
|
9
|
+
|
|
10
|
+
from alembic import op
|
|
11
|
+
import sqlalchemy as sa
|
|
12
|
+
${imports if imports else ""}
|
|
13
|
+
|
|
14
|
+
# revision identifiers, used by Alembic.
|
|
15
|
+
revision: str = ${repr(up_revision)}
|
|
16
|
+
down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)}
|
|
17
|
+
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
|
18
|
+
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def upgrade() -> None:
|
|
22
|
+
"""Upgrade schema."""
|
|
23
|
+
${upgrades if upgrades else "pass"}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def downgrade() -> None:
|
|
27
|
+
"""Downgrade schema."""
|
|
28
|
+
${downgrades if downgrades else "pass"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
2
|
+
import { type NxGeneratorInfo } from '../../utils/nx';
|
|
3
|
+
import type { PyRdbGeneratorSchema } from './schema';
|
|
4
|
+
export declare const PY_RDB_GENERATOR_INFO: NxGeneratorInfo;
|
|
5
|
+
export declare const pyRdbGenerator: (tree: Tree, options: PyRdbGeneratorSchema) => Promise<GeneratorCallback>;
|
|
6
|
+
export default pyRdbGenerator;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/ import { relative } from "node:path";
|
|
5
|
+
import { addDependenciesToPackageJson, generateFiles, joinPathFragments, readProjectConfiguration, updateProjectConfiguration } from "@nx/devkit";
|
|
6
|
+
import { addPythonBundleTarget } from "../../utils/bundle/bundle.js";
|
|
7
|
+
import { resolveContainers } from "../../utils/containers.js";
|
|
8
|
+
import { formatFilesInSubtree } from "../../utils/format.js";
|
|
9
|
+
import { FsCommands } from "../../utils/fs.js";
|
|
10
|
+
import { resolveIac } from "../../utils/iac.js";
|
|
11
|
+
import { installDependencies } from "../../utils/install.js";
|
|
12
|
+
import { addGeneratorMetricsIfApplicable } from "../../utils/metrics.js";
|
|
13
|
+
import { kebabCase, snakeCase, toClassName } from "../../utils/names.js";
|
|
14
|
+
import { getNpmScope } from "../../utils/npm-scope.js";
|
|
15
|
+
import { addDependencyToTargetIfNotPresent, addGeneratorMetadata, getGeneratorInfo, projectExists } from "../../utils/nx.js";
|
|
16
|
+
import { assignPort } from "../../utils/port.js";
|
|
17
|
+
import { addDependenciesToPyProjectToml } from "../../utils/py.js";
|
|
18
|
+
import { addRdbInfra } from "../../utils/rdb-constructs/rdb-constructs.js";
|
|
19
|
+
import { sharedConstructsGenerator } from "../../utils/shared-constructs.js";
|
|
20
|
+
import { PACKAGES_DIR, SHARED_SCRIPTS_DIR } from "../../utils/shared-constructs-constants.js";
|
|
21
|
+
import { sharedRdbScriptsGenerator } from "../../utils/shared-rdb-scripts.js";
|
|
22
|
+
import { PY_VERSIONS, withVersions } from "../../utils/versions.js";
|
|
23
|
+
import pyProjectGenerator, { getPyProjectDetails } from "../project/generator.js";
|
|
24
|
+
export const PY_RDB_GENERATOR_INFO = getGeneratorInfo(import.meta.filename);
|
|
25
|
+
export const pyRdbGenerator = async (tree, options)=>{
|
|
26
|
+
const nameClassName = toClassName(options.name);
|
|
27
|
+
const databaseUser = options.databaseUser ?? 'dbadmin';
|
|
28
|
+
const databaseName = snakeCase(options.databaseName ?? options.name);
|
|
29
|
+
const containerEngine = await resolveContainers(tree, 'inherit');
|
|
30
|
+
const { fullyQualifiedName, dir, normalizedModuleName } = getPyProjectDetails(tree, {
|
|
31
|
+
name: options.name,
|
|
32
|
+
directory: options.directory,
|
|
33
|
+
subDirectory: options.subDirectory
|
|
34
|
+
});
|
|
35
|
+
if (!projectExists(tree, fullyQualifiedName)) {
|
|
36
|
+
await pyProjectGenerator(tree, {
|
|
37
|
+
name: options.name,
|
|
38
|
+
directory: options.directory,
|
|
39
|
+
subDirectory: options.subDirectory,
|
|
40
|
+
type: 'library'
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const projectConfig = readProjectConfiguration(tree, fullyQualifiedName);
|
|
44
|
+
const { engine } = options;
|
|
45
|
+
const localDbPort = assignPort(tree, projectConfig, engine === 'mysql' ? 3306 : 5432);
|
|
46
|
+
const localDbHost = 'localhost';
|
|
47
|
+
const localDbUser = engine === 'mysql' ? 'root' : 'dbadmin';
|
|
48
|
+
const localDbPassword = 'password';
|
|
49
|
+
const containerName = `${getNpmScope(tree)}-${databaseName}`;
|
|
50
|
+
const dockerImage = engine === 'mysql' ? 'public.ecr.aws/docker/library/mysql:8.0.44' : 'public.ecr.aws/docker/library/postgres:17.7';
|
|
51
|
+
const templateOptions = {
|
|
52
|
+
name: normalizedModuleName,
|
|
53
|
+
runtimeConfigKey: nameClassName,
|
|
54
|
+
engine,
|
|
55
|
+
localDbPort,
|
|
56
|
+
localDbHost,
|
|
57
|
+
localDbName: databaseName,
|
|
58
|
+
localDbUser,
|
|
59
|
+
localDbPassword,
|
|
60
|
+
containerEngine,
|
|
61
|
+
containerName,
|
|
62
|
+
dockerImage,
|
|
63
|
+
sqlmodelVersion: PY_VERSIONS.sqlmodel,
|
|
64
|
+
alembicVersion: PY_VERSIONS.alembic,
|
|
65
|
+
aiomysqlVersion: PY_VERSIONS.aiomysql,
|
|
66
|
+
asyncpgVersion: PY_VERSIONS.asyncpg,
|
|
67
|
+
boto3Version: PY_VERSIONS.boto3,
|
|
68
|
+
awsLambdaPowertoolsVersion: PY_VERSIONS['aws-lambda-powertools']
|
|
69
|
+
};
|
|
70
|
+
generateFiles(tree, joinPathFragments(import.meta.dirname, 'files'), dir, templateOptions);
|
|
71
|
+
await sharedRdbScriptsGenerator(tree, engine);
|
|
72
|
+
// Used by local dev script wait-for-*-db.ts
|
|
73
|
+
addDependenciesToPackageJson(tree, withVersions([
|
|
74
|
+
engine === 'mysql' ? 'mariadb' : 'pg'
|
|
75
|
+
]), engine === 'mysql' ? {} : withVersions([
|
|
76
|
+
'@types/pg'
|
|
77
|
+
]));
|
|
78
|
+
const scriptsDir = relative(dir, joinPathFragments(PACKAGES_DIR, SHARED_SCRIPTS_DIR, 'src', 'rdb'));
|
|
79
|
+
const fs = new FsCommands(tree);
|
|
80
|
+
const migrationBundleDir = joinPathFragments('dist', projectConfig.root, 'docker', 'migration');
|
|
81
|
+
const createDbUserBundleDir = joinPathFragments('dist', projectConfig.root, 'docker', 'create-db-user');
|
|
82
|
+
const migrationDockerImageTag = `${getNpmScope(tree)}-${kebabCase(options.name)}-migration:latest`;
|
|
83
|
+
const createDbUserDockerImageTag = `${getNpmScope(tree)}-${kebabCase(options.name)}-create-db-user:latest`;
|
|
84
|
+
if (options.infra !== 'none') {
|
|
85
|
+
const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(projectConfig, {
|
|
86
|
+
pythonPlatform: 'aarch64-manylinux_2_28'
|
|
87
|
+
});
|
|
88
|
+
projectConfig.targets['bundle-migration'] = {
|
|
89
|
+
cache: true,
|
|
90
|
+
outputs: [
|
|
91
|
+
'{workspaceRoot}/dist/{projectRoot}/docker/migration'
|
|
92
|
+
],
|
|
93
|
+
executor: 'nx:run-commands',
|
|
94
|
+
options: {
|
|
95
|
+
commands: [
|
|
96
|
+
fs.rm(migrationBundleDir),
|
|
97
|
+
fs.mkdir(migrationBundleDir),
|
|
98
|
+
fs.cp(bundleOutputDir, migrationBundleDir),
|
|
99
|
+
fs.cp(joinPathFragments(dir, 'migrations'), joinPathFragments(migrationBundleDir, 'migrations')),
|
|
100
|
+
fs.cp(joinPathFragments(dir, 'alembic.ini'), joinPathFragments(migrationBundleDir, 'alembic.ini')),
|
|
101
|
+
fs.cp(joinPathFragments(dir, 'Dockerfile.migration'), joinPathFragments(migrationBundleDir, 'Dockerfile'))
|
|
102
|
+
],
|
|
103
|
+
parallel: false
|
|
104
|
+
},
|
|
105
|
+
dependsOn: [
|
|
106
|
+
bundleTargetName
|
|
107
|
+
]
|
|
108
|
+
};
|
|
109
|
+
projectConfig.targets['bundle-create-db-user'] = {
|
|
110
|
+
cache: true,
|
|
111
|
+
outputs: [
|
|
112
|
+
'{workspaceRoot}/dist/{projectRoot}/docker/create-db-user'
|
|
113
|
+
],
|
|
114
|
+
executor: 'nx:run-commands',
|
|
115
|
+
options: {
|
|
116
|
+
commands: [
|
|
117
|
+
fs.rm(createDbUserBundleDir),
|
|
118
|
+
fs.mkdir(createDbUserBundleDir),
|
|
119
|
+
fs.cp(bundleOutputDir, createDbUserBundleDir),
|
|
120
|
+
fs.cp(joinPathFragments(dir, 'Dockerfile.create-db-user'), joinPathFragments(createDbUserBundleDir, 'Dockerfile'))
|
|
121
|
+
],
|
|
122
|
+
parallel: false
|
|
123
|
+
},
|
|
124
|
+
dependsOn: [
|
|
125
|
+
bundleTargetName
|
|
126
|
+
]
|
|
127
|
+
};
|
|
128
|
+
addDependencyToTargetIfNotPresent(projectConfig, 'bundle', 'bundle-migration');
|
|
129
|
+
addDependencyToTargetIfNotPresent(projectConfig, 'bundle', 'bundle-create-db-user');
|
|
130
|
+
}
|
|
131
|
+
projectConfig.targets['pull-image'] = {
|
|
132
|
+
executor: 'nx:run-commands',
|
|
133
|
+
options: {
|
|
134
|
+
command: `tsx ${scriptsDir}/pull-image.ts`,
|
|
135
|
+
cwd: '{projectRoot}'
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
projectConfig.targets['dev'] = {
|
|
139
|
+
executor: 'nx:run-commands',
|
|
140
|
+
continuous: true,
|
|
141
|
+
options: {
|
|
142
|
+
command: `tsx ${scriptsDir}/start-container.ts`,
|
|
143
|
+
cwd: '{projectRoot}'
|
|
144
|
+
},
|
|
145
|
+
dependsOn: [
|
|
146
|
+
'pull-image'
|
|
147
|
+
]
|
|
148
|
+
};
|
|
149
|
+
projectConfig.targets['wait-for-db'] = {
|
|
150
|
+
executor: 'nx:run-commands',
|
|
151
|
+
dependsOn: [
|
|
152
|
+
'dev'
|
|
153
|
+
],
|
|
154
|
+
options: {
|
|
155
|
+
command: `tsx ${scriptsDir}/wait-for-${engine}-db.ts`,
|
|
156
|
+
cwd: '{projectRoot}'
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
projectConfig.targets.migrate = {
|
|
160
|
+
executor: 'nx:run-commands',
|
|
161
|
+
dependsOn: [
|
|
162
|
+
'dev',
|
|
163
|
+
'wait-for-db'
|
|
164
|
+
],
|
|
165
|
+
options: {
|
|
166
|
+
command: 'uv run alembic upgrade head',
|
|
167
|
+
cwd: '{projectRoot}',
|
|
168
|
+
env: {
|
|
169
|
+
LOCAL_DEV: 'true'
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
projectConfig.targets.alembic = {
|
|
174
|
+
executor: 'nx:run-commands',
|
|
175
|
+
dependsOn: [
|
|
176
|
+
'dev',
|
|
177
|
+
'wait-for-db'
|
|
178
|
+
],
|
|
179
|
+
options: {
|
|
180
|
+
command: 'uv run alembic',
|
|
181
|
+
cwd: '{projectRoot}',
|
|
182
|
+
env: {
|
|
183
|
+
LOCAL_DEV: 'true'
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
if (options.infra !== 'none') {
|
|
188
|
+
const iac = await resolveIac(tree, options.iac);
|
|
189
|
+
if (iac === 'terraform') {
|
|
190
|
+
projectConfig.targets.docker = {
|
|
191
|
+
cache: true,
|
|
192
|
+
executor: 'nx:run-commands',
|
|
193
|
+
options: {
|
|
194
|
+
commands: [
|
|
195
|
+
`${containerEngine} build --platform linux/arm64 --provenance=false -t ${migrationDockerImageTag} ${migrationBundleDir}`,
|
|
196
|
+
`${containerEngine} build --platform linux/arm64 --provenance=false -t ${createDbUserDockerImageTag} ${createDbUserBundleDir}`
|
|
197
|
+
],
|
|
198
|
+
parallel: false
|
|
199
|
+
},
|
|
200
|
+
dependsOn: [
|
|
201
|
+
'bundle-migration',
|
|
202
|
+
'bundle-create-db-user'
|
|
203
|
+
]
|
|
204
|
+
};
|
|
205
|
+
addDependencyToTargetIfNotPresent(projectConfig, 'build', 'docker');
|
|
206
|
+
}
|
|
207
|
+
addDependencyToTargetIfNotPresent(projectConfig, 'build', 'bundle-migration');
|
|
208
|
+
addDependencyToTargetIfNotPresent(projectConfig, 'build', 'bundle-create-db-user');
|
|
209
|
+
}
|
|
210
|
+
updateProjectConfiguration(tree, fullyQualifiedName, projectConfig);
|
|
211
|
+
addGeneratorMetadata(tree, fullyQualifiedName, PY_RDB_GENERATOR_INFO, {
|
|
212
|
+
engine
|
|
213
|
+
});
|
|
214
|
+
if (options.infra !== 'none') {
|
|
215
|
+
const iac = await resolveIac(tree, options.iac);
|
|
216
|
+
await sharedConstructsGenerator(tree, {
|
|
217
|
+
iac
|
|
218
|
+
});
|
|
219
|
+
await addRdbInfra(tree, {
|
|
220
|
+
iac,
|
|
221
|
+
projectName: fullyQualifiedName,
|
|
222
|
+
projectRoot: dir,
|
|
223
|
+
nameClassName,
|
|
224
|
+
nameKebabCase: kebabCase(options.name),
|
|
225
|
+
databasePackageAlias: normalizedModuleName,
|
|
226
|
+
databaseName,
|
|
227
|
+
adminUser: databaseUser,
|
|
228
|
+
engine,
|
|
229
|
+
migrationBundleDir,
|
|
230
|
+
createDbUserBundleDir,
|
|
231
|
+
framework: 'sqlmodel',
|
|
232
|
+
createDbUserDockerImageTag,
|
|
233
|
+
migrationDockerImageTag,
|
|
234
|
+
containerEngine
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
addDependenciesToPyProjectToml(tree, dir, [
|
|
238
|
+
'sqlmodel',
|
|
239
|
+
'alembic',
|
|
240
|
+
...engine === 'mysql' ? [
|
|
241
|
+
'aiomysql',
|
|
242
|
+
'boto3',
|
|
243
|
+
'aws-lambda-powertools'
|
|
244
|
+
] : [
|
|
245
|
+
'asyncpg',
|
|
246
|
+
'boto3',
|
|
247
|
+
'aws-lambda-powertools'
|
|
248
|
+
]
|
|
249
|
+
]);
|
|
250
|
+
await addGeneratorMetricsIfApplicable(tree, [
|
|
251
|
+
PY_RDB_GENERATOR_INFO
|
|
252
|
+
]);
|
|
253
|
+
await formatFilesInSubtree(tree);
|
|
254
|
+
return ()=>installDependencies(tree, options.preferInstallDependencies, {
|
|
255
|
+
languages: [
|
|
256
|
+
'typescript',
|
|
257
|
+
'python'
|
|
258
|
+
]
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
export default pyRdbGenerator;
|
|
262
|
+
|
|
263
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../packages/nx-plugin/src/py/rdb/generator.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { relative } from 'node:path';\nimport {\n addDependenciesToPackageJson,\n type GeneratorCallback,\n generateFiles,\n joinPathFragments,\n readProjectConfiguration,\n type Tree,\n updateProjectConfiguration,\n} from '@nx/devkit';\nimport { addPythonBundleTarget } from '../../utils/bundle/bundle';\nimport { resolveContainers } from '../../utils/containers';\nimport { formatFilesInSubtree } from '../../utils/format';\nimport { FsCommands } from '../../utils/fs';\nimport { resolveIac } from '../../utils/iac';\nimport { installDependencies } from '../../utils/install';\nimport { addGeneratorMetricsIfApplicable } from '../../utils/metrics';\nimport { kebabCase, snakeCase, toClassName } from '../../utils/names';\nimport { getNpmScope } from '../../utils/npm-scope';\nimport {\n addDependencyToTargetIfNotPresent,\n addGeneratorMetadata,\n getGeneratorInfo,\n type NxGeneratorInfo,\n projectExists,\n} from '../../utils/nx';\nimport { assignPort } from '../../utils/port';\nimport { addDependenciesToPyProjectToml } from '../../utils/py';\nimport { addRdbInfra } from '../../utils/rdb-constructs/rdb-constructs';\nimport { sharedConstructsGenerator } from '../../utils/shared-constructs';\nimport {\n PACKAGES_DIR,\n SHARED_SCRIPTS_DIR,\n} from '../../utils/shared-constructs-constants';\nimport { sharedRdbScriptsGenerator } from '../../utils/shared-rdb-scripts';\nimport { PY_VERSIONS, withVersions } from '../../utils/versions';\nimport pyProjectGenerator, { getPyProjectDetails } from '../project/generator';\nimport type { PyRdbGeneratorSchema } from './schema';\n\nexport const PY_RDB_GENERATOR_INFO: NxGeneratorInfo = getGeneratorInfo(\n import.meta.filename,\n);\n\nexport const pyRdbGenerator = async (\n tree: Tree,\n options: PyRdbGeneratorSchema,\n): Promise<GeneratorCallback> => {\n const nameClassName = toClassName(options.name);\n const databaseUser = options.databaseUser ?? 'dbadmin';\n const databaseName = snakeCase(options.databaseName ?? options.name);\n const containerEngine = await resolveContainers(tree, 'inherit');\n\n const { fullyQualifiedName, dir, normalizedModuleName } = getPyProjectDetails(\n tree,\n {\n name: options.name,\n directory: options.directory,\n subDirectory: options.subDirectory,\n },\n );\n\n if (!projectExists(tree, fullyQualifiedName)) {\n await pyProjectGenerator(tree, {\n name: options.name,\n directory: options.directory,\n subDirectory: options.subDirectory,\n type: 'library',\n });\n }\n\n const projectConfig = readProjectConfiguration(tree, fullyQualifiedName);\n\n const { engine } = options;\n const localDbPort = assignPort(\n tree,\n projectConfig,\n engine === 'mysql' ? 3306 : 5432,\n );\n const localDbHost = 'localhost';\n const localDbUser = engine === 'mysql' ? 'root' : 'dbadmin';\n const localDbPassword = 'password';\n const containerName = `${getNpmScope(tree)}-${databaseName}`;\n const dockerImage =\n engine === 'mysql'\n ? 'public.ecr.aws/docker/library/mysql:8.0.44'\n : 'public.ecr.aws/docker/library/postgres:17.7';\n\n const templateOptions = {\n name: normalizedModuleName,\n runtimeConfigKey: nameClassName,\n engine,\n localDbPort,\n localDbHost,\n localDbName: databaseName,\n localDbUser,\n localDbPassword,\n containerEngine,\n containerName,\n dockerImage,\n sqlmodelVersion: PY_VERSIONS.sqlmodel,\n alembicVersion: PY_VERSIONS.alembic,\n aiomysqlVersion: PY_VERSIONS.aiomysql,\n asyncpgVersion: PY_VERSIONS.asyncpg,\n boto3Version: PY_VERSIONS.boto3,\n awsLambdaPowertoolsVersion: PY_VERSIONS['aws-lambda-powertools'],\n };\n\n generateFiles(\n tree,\n joinPathFragments(import.meta.dirname, 'files'),\n dir,\n templateOptions,\n );\n\n await sharedRdbScriptsGenerator(tree, engine);\n // Used by local dev script wait-for-*-db.ts\n addDependenciesToPackageJson(\n tree,\n withVersions([engine === 'mysql' ? 'mariadb' : 'pg']),\n engine === 'mysql' ? {} : withVersions(['@types/pg']),\n );\n const scriptsDir = relative(\n dir,\n joinPathFragments(PACKAGES_DIR, SHARED_SCRIPTS_DIR, 'src', 'rdb'),\n );\n const fs = new FsCommands(tree);\n\n const migrationBundleDir = joinPathFragments(\n 'dist',\n projectConfig.root,\n 'docker',\n 'migration',\n );\n const createDbUserBundleDir = joinPathFragments(\n 'dist',\n projectConfig.root,\n 'docker',\n 'create-db-user',\n );\n const migrationDockerImageTag = `${getNpmScope(tree)}-${kebabCase(options.name)}-migration:latest`;\n const createDbUserDockerImageTag = `${getNpmScope(tree)}-${kebabCase(\n options.name,\n )}-create-db-user:latest`;\n\n if (options.infra !== 'none') {\n const { bundleTargetName, bundleOutputDir } = addPythonBundleTarget(\n projectConfig,\n { pythonPlatform: 'aarch64-manylinux_2_28' },\n );\n\n projectConfig.targets['bundle-migration'] = {\n cache: true,\n outputs: ['{workspaceRoot}/dist/{projectRoot}/docker/migration'],\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(migrationBundleDir),\n fs.mkdir(migrationBundleDir),\n fs.cp(bundleOutputDir, migrationBundleDir),\n fs.cp(\n joinPathFragments(dir, 'migrations'),\n joinPathFragments(migrationBundleDir, 'migrations'),\n ),\n fs.cp(\n joinPathFragments(dir, 'alembic.ini'),\n joinPathFragments(migrationBundleDir, 'alembic.ini'),\n ),\n fs.cp(\n joinPathFragments(dir, 'Dockerfile.migration'),\n joinPathFragments(migrationBundleDir, 'Dockerfile'),\n ),\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n projectConfig.targets['bundle-create-db-user'] = {\n cache: true,\n outputs: ['{workspaceRoot}/dist/{projectRoot}/docker/create-db-user'],\n executor: 'nx:run-commands',\n options: {\n commands: [\n fs.rm(createDbUserBundleDir),\n fs.mkdir(createDbUserBundleDir),\n fs.cp(bundleOutputDir, createDbUserBundleDir),\n fs.cp(\n joinPathFragments(dir, 'Dockerfile.create-db-user'),\n joinPathFragments(createDbUserBundleDir, 'Dockerfile'),\n ),\n ],\n parallel: false,\n },\n dependsOn: [bundleTargetName],\n };\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'bundle',\n 'bundle-migration',\n );\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'bundle',\n 'bundle-create-db-user',\n );\n }\n\n projectConfig.targets['pull-image'] = {\n executor: 'nx:run-commands',\n options: {\n command: `tsx ${scriptsDir}/pull-image.ts`,\n cwd: '{projectRoot}',\n },\n };\n projectConfig.targets['dev'] = {\n executor: 'nx:run-commands',\n continuous: true,\n options: {\n command: `tsx ${scriptsDir}/start-container.ts`,\n cwd: '{projectRoot}',\n },\n dependsOn: ['pull-image'],\n };\n projectConfig.targets['wait-for-db'] = {\n executor: 'nx:run-commands',\n dependsOn: ['dev'],\n options: {\n command: `tsx ${scriptsDir}/wait-for-${engine}-db.ts`,\n cwd: '{projectRoot}',\n },\n };\n projectConfig.targets.migrate = {\n executor: 'nx:run-commands',\n dependsOn: ['dev', 'wait-for-db'],\n options: {\n command: 'uv run alembic upgrade head',\n cwd: '{projectRoot}',\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n projectConfig.targets.alembic = {\n executor: 'nx:run-commands',\n dependsOn: ['dev', 'wait-for-db'],\n options: {\n command: 'uv run alembic',\n cwd: '{projectRoot}',\n env: {\n LOCAL_DEV: 'true',\n },\n },\n };\n\n if (options.infra !== 'none') {\n const iac = await resolveIac(tree, options.iac);\n if (iac === 'terraform') {\n projectConfig.targets.docker = {\n cache: true,\n executor: 'nx:run-commands',\n options: {\n commands: [\n `${containerEngine} build --platform linux/arm64 --provenance=false -t ${migrationDockerImageTag} ${migrationBundleDir}`,\n `${containerEngine} build --platform linux/arm64 --provenance=false -t ${createDbUserDockerImageTag} ${createDbUserBundleDir}`,\n ],\n parallel: false,\n },\n dependsOn: ['bundle-migration', 'bundle-create-db-user'],\n };\n addDependencyToTargetIfNotPresent(projectConfig, 'build', 'docker');\n }\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'build',\n 'bundle-migration',\n );\n addDependencyToTargetIfNotPresent(\n projectConfig,\n 'build',\n 'bundle-create-db-user',\n );\n }\n\n updateProjectConfiguration(tree, fullyQualifiedName, projectConfig);\n addGeneratorMetadata(tree, fullyQualifiedName, PY_RDB_GENERATOR_INFO, {\n engine,\n });\n\n if (options.infra !== 'none') {\n const iac = await resolveIac(tree, options.iac);\n await sharedConstructsGenerator(tree, { iac });\n await addRdbInfra(tree, {\n iac,\n projectName: fullyQualifiedName,\n projectRoot: dir,\n nameClassName,\n nameKebabCase: kebabCase(options.name),\n databasePackageAlias: normalizedModuleName,\n databaseName,\n adminUser: databaseUser,\n engine,\n migrationBundleDir,\n createDbUserBundleDir,\n framework: 'sqlmodel',\n createDbUserDockerImageTag,\n migrationDockerImageTag,\n containerEngine,\n });\n }\n\n addDependenciesToPyProjectToml(tree, dir, [\n 'sqlmodel',\n 'alembic',\n ...(engine === 'mysql'\n ? (['aiomysql', 'boto3', 'aws-lambda-powertools'] as const)\n : (['asyncpg', 'boto3', 'aws-lambda-powertools'] as const)),\n ]);\n\n await addGeneratorMetricsIfApplicable(tree, [PY_RDB_GENERATOR_INFO]);\n\n await formatFilesInSubtree(tree);\n return () =>\n installDependencies(tree, options.preferInstallDependencies, {\n languages: ['typescript', 'python'],\n });\n};\n\nexport default pyRdbGenerator;\n"],"names":["relative","addDependenciesToPackageJson","generateFiles","joinPathFragments","readProjectConfiguration","updateProjectConfiguration","addPythonBundleTarget","resolveContainers","formatFilesInSubtree","FsCommands","resolveIac","installDependencies","addGeneratorMetricsIfApplicable","kebabCase","snakeCase","toClassName","getNpmScope","addDependencyToTargetIfNotPresent","addGeneratorMetadata","getGeneratorInfo","projectExists","assignPort","addDependenciesToPyProjectToml","addRdbInfra","sharedConstructsGenerator","PACKAGES_DIR","SHARED_SCRIPTS_DIR","sharedRdbScriptsGenerator","PY_VERSIONS","withVersions","pyProjectGenerator","getPyProjectDetails","PY_RDB_GENERATOR_INFO","filename","pyRdbGenerator","tree","options","nameClassName","name","databaseUser","databaseName","containerEngine","fullyQualifiedName","dir","normalizedModuleName","directory","subDirectory","type","projectConfig","engine","localDbPort","localDbHost","localDbUser","localDbPassword","containerName","dockerImage","templateOptions","runtimeConfigKey","localDbName","sqlmodelVersion","sqlmodel","alembicVersion","alembic","aiomysqlVersion","aiomysql","asyncpgVersion","asyncpg","boto3Version","boto3","awsLambdaPowertoolsVersion","dirname","scriptsDir","fs","migrationBundleDir","root","createDbUserBundleDir","migrationDockerImageTag","createDbUserDockerImageTag","infra","bundleTargetName","bundleOutputDir","pythonPlatform","targets","cache","outputs","executor","commands","rm","mkdir","cp","parallel","dependsOn","command","cwd","continuous","migrate","env","LOCAL_DEV","iac","docker","projectName","projectRoot","nameKebabCase","databasePackageAlias","adminUser","framework","preferInstallDependencies","languages"],"mappings":"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"}
|