@mtndev/cli 0.0.0-dev-20260626045346 → 0.0.0-dev-20260914234436
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/CHANGELOG.md +86 -1
- package/cjs/__chunks/2FSYDFUV.cjs +146 -0
- package/cjs/__chunks/3A5ZYU5M.cjs +105 -0
- package/cjs/__chunks/3NOHGUCF.cjs +9 -0
- package/cjs/__chunks/3T2LXW7J.cjs +387 -0
- package/cjs/__chunks/4XT5JEAS.cjs +1 -0
- package/cjs/__chunks/AZEB4H4I.cjs +208 -0
- package/cjs/__chunks/B5ENMOCD.cjs +288 -0
- package/cjs/__chunks/B6XM5KSF.cjs +338 -0
- package/cjs/__chunks/BDU2UCE5.cjs +1 -0
- package/cjs/__chunks/BLMSMR5E.cjs +46 -0
- package/cjs/__chunks/CMUD7LLN.cjs +47 -0
- package/cjs/__chunks/DTQ2LB3I.cjs +49 -0
- package/cjs/__chunks/FM5MVRQF.cjs +23 -0
- package/cjs/__chunks/FRHST54J.cjs +135 -0
- package/cjs/__chunks/FU4VP2LN.cjs +1 -0
- package/cjs/__chunks/G5K4PVIL.cjs +26 -0
- package/cjs/__chunks/{NSRFG4DF.cjs → GU3R54MK.cjs} +45 -18
- package/cjs/__chunks/GUL36IFZ.cjs +61 -0
- package/cjs/__chunks/GZMTNK5N.cjs +1 -0
- package/cjs/__chunks/H74JSDBU.cjs +30 -0
- package/cjs/__chunks/{EMMC33QA.cjs → JB7T7PKQ.cjs} +170 -33
- package/cjs/__chunks/JSL2JDMW.cjs +1 -0
- package/cjs/__chunks/K4QNHRTP.cjs +163 -0
- package/cjs/__chunks/KU76LC42.cjs +192 -0
- package/cjs/__chunks/LFDSHANP.cjs +34 -0
- package/cjs/__chunks/LHE24ECK.cjs +192 -0
- package/cjs/__chunks/LIKQ3SI4.cjs +1 -0
- package/cjs/__chunks/LXDF5QVZ.cjs +313 -0
- package/cjs/__chunks/LXOOJR2R.cjs +74 -0
- package/cjs/__chunks/N5MXFOQZ.cjs +167 -0
- package/cjs/__chunks/N7D56LPP.cjs +25 -0
- package/cjs/__chunks/NFXQNOQH.cjs +393 -0
- package/cjs/__chunks/NLKJIUEX.cjs +126 -0
- package/cjs/__chunks/NT2XXAI6.cjs +89 -0
- package/cjs/__chunks/NWZGFHKH.cjs +121 -0
- package/cjs/__chunks/R3GUC7O7.cjs +110 -0
- package/cjs/__chunks/RPVAXPJ4.cjs +1 -0
- package/cjs/__chunks/S3LVCWPN.cjs +23 -0
- package/cjs/__chunks/SBBNW2BF.cjs +249 -0
- package/cjs/__chunks/T2A7TN4F.cjs +81 -0
- package/cjs/__chunks/TKNNDDIB.cjs +97 -0
- package/cjs/__chunks/TNSRDJPR.cjs +1 -0
- package/cjs/__chunks/UWHPE2GI.cjs +20 -0
- package/cjs/__chunks/W6K7BV74.cjs +1 -0
- package/cjs/__chunks/WBOQ6AUN.cjs +320 -0
- package/cjs/__chunks/WHGN5PZI.cjs +299 -0
- package/cjs/__chunks/WOYF2L6T.cjs +11 -0
- package/cjs/__chunks/X26XY2N6.cjs +18 -0
- package/cjs/__chunks/XMKOKRXZ.cjs +16 -0
- package/cjs/__chunks/XTJPQ3EX.cjs +1 -0
- package/cjs/__chunks/YRHFKTW2.cjs +63 -0
- package/cjs/commands/aws/ec2/allow-ip/handler.cjs +12 -0
- package/cjs/commands/aws/ec2/allow-ip/handler.d.ts +6 -0
- package/cjs/commands/aws/ec2/allow-ip/index.cjs +55 -0
- package/cjs/commands/aws/ec2/allow-ip/index.d.ts +3 -0
- package/cjs/commands/aws/ec2/allow-ip/schema.cjs +13 -0
- package/cjs/commands/aws/ec2/allow-ip/schema.d.ts +33 -0
- package/cjs/commands/aws/ec2/allow-ip/utils.cjs +39 -0
- package/cjs/commands/aws/ec2/allow-ip/utils.d.ts +189 -0
- package/cjs/commands/aws/iam/admin-group.cjs +15 -0
- package/cjs/commands/aws/iam/admin-group.d.ts +55 -0
- package/cjs/commands/aws/iam/break-glass/handler.cjs +12 -0
- package/cjs/commands/aws/iam/break-glass/handler.d.ts +7 -0
- package/cjs/commands/aws/iam/break-glass/index.cjs +19 -0
- package/cjs/commands/aws/iam/break-glass/index.d.ts +2 -0
- package/cjs/commands/aws/iam/break-glass/schema.cjs +12 -0
- package/cjs/commands/aws/iam/break-glass/schema.d.ts +25 -0
- package/cjs/commands/aws/iam/check-admin/handler.cjs +10 -0
- package/cjs/commands/aws/iam/check-admin/handler.d.ts +5 -0
- package/cjs/commands/aws/iam/check-admin/index.cjs +17 -0
- package/cjs/commands/aws/iam/check-admin/index.d.ts +2 -0
- package/cjs/commands/aws/iam/check-admin/schema.cjs +12 -0
- package/cjs/commands/aws/iam/check-admin/schema.d.ts +19 -0
- package/cjs/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.cjs +28 -0
- package/cjs/commands/aws/iam/policies/sts-federation.cjs +19 -0
- package/cjs/commands/aws/iam/policies/user-admins-deny-list.cjs +183 -0
- package/cjs/commands/aws/iam/policies/user-admins-deny-regions-list.cjs +49 -0
- package/cjs/commands/aws/iam/policies/user-admins-self-service-iam.cjs +64 -0
- package/cjs/commands/aws/iam/policies/user-admins-write-list.cjs +125 -0
- package/cjs/commands/aws/iam/remove-admin/handler.cjs +11 -0
- package/cjs/commands/aws/iam/remove-admin/handler.d.ts +6 -0
- package/cjs/commands/aws/iam/remove-admin/index.cjs +18 -0
- package/cjs/commands/aws/iam/remove-admin/index.d.ts +2 -0
- package/cjs/commands/aws/iam/remove-admin/schema.cjs +12 -0
- package/cjs/commands/aws/iam/remove-admin/schema.d.ts +28 -0
- package/cjs/commands/aws/iam/setup-acl/handler.cjs +14 -0
- package/cjs/commands/aws/iam/setup-acl/handler.d.ts +6 -0
- package/cjs/commands/aws/iam/setup-acl/index.cjs +33 -0
- package/cjs/commands/aws/iam/setup-acl/index.d.ts +3 -0
- package/cjs/commands/aws/iam/setup-acl/schema.cjs +7 -0
- package/cjs/commands/aws/iam/setup-acl/schema.d.ts +24 -0
- package/cjs/commands/aws/iam/setup-acl/utils.cjs +20 -0
- package/cjs/commands/aws/iam/setup-acl/utils.d.ts +61 -0
- package/cjs/commands/aws/iam/users/handler.cjs +12 -0
- package/cjs/commands/aws/iam/users/handler.d.ts +5 -0
- package/cjs/commands/aws/iam/users/index.cjs +41 -0
- package/cjs/commands/aws/iam/users/index.d.ts +3 -0
- package/cjs/commands/aws/iam/users/schema.cjs +7 -0
- package/cjs/commands/aws/iam/users/schema.d.ts +18 -0
- package/cjs/commands/aws/iam/users/utils.cjs +30 -0
- package/cjs/commands/aws/iam/users/utils.d.ts +119 -0
- package/cjs/commands/aws/index.cjs +229 -0
- package/cjs/commands/aws/index.d.ts +14 -0
- package/cjs/commands/aws/route53/add-record/handler.cjs +18 -0
- package/cjs/commands/aws/route53/add-record/handler.d.ts +36 -0
- package/cjs/commands/aws/route53/add-record/index.cjs +57 -0
- package/cjs/commands/aws/route53/add-record/index.d.ts +3 -0
- package/cjs/commands/aws/route53/add-record/schema.cjs +11 -0
- package/cjs/commands/aws/route53/add-record/schema.d.ts +45 -0
- package/cjs/commands/aws/route53/add-record/utils.cjs +37 -0
- package/cjs/commands/aws/route53/add-record/utils.d.ts +216 -0
- package/cjs/commands/aws/route53/remove-record/handler.cjs +14 -0
- package/cjs/commands/aws/route53/remove-record/handler.d.ts +6 -0
- package/cjs/commands/aws/route53/remove-record/index.cjs +18 -0
- package/cjs/commands/aws/route53/remove-record/index.d.ts +2 -0
- package/cjs/commands/aws/route53/remove-record/schema.cjs +8 -0
- package/cjs/commands/aws/route53/remove-record/schema.d.ts +30 -0
- package/cjs/commands/aws/schema.cjs +10 -0
- package/cjs/commands/aws/schema.d.ts +13 -0
- package/cjs/commands/aws/ses/send-email/handler.cjs +12 -0
- package/cjs/commands/aws/ses/send-email/handler.d.ts +5 -0
- package/cjs/commands/aws/ses/send-email/index.cjs +23 -0
- package/cjs/commands/aws/ses/send-email/index.d.ts +3 -0
- package/cjs/commands/aws/ses/send-email/schema.cjs +7 -0
- package/cjs/commands/aws/ses/send-email/schema.d.ts +39 -0
- package/cjs/commands/aws/ses/send-email/utils.cjs +11 -0
- package/cjs/commands/aws/ses/send-email/utils.d.ts +47 -0
- package/cjs/commands/aws/ses/smtp-password.cjs +10 -0
- package/cjs/commands/aws/ses/smtp-password.d.ts +21 -0
- package/cjs/commands/aws/utils/exec-aws.cjs +16 -0
- package/cjs/commands/aws/utils/exec-aws.d.ts +79 -0
- package/cjs/commands/aws/utils/resolve-policy-path.cjs +6 -0
- package/cjs/commands/aws/utils/resolve-policy-path.d.ts +8 -0
- package/cjs/commands/aws/utils/resolve-profile.cjs +11 -0
- package/cjs/commands/aws/utils/resolve-profile.d.ts +28 -0
- package/cjs/commands/aws/utils/tty.cjs +10 -0
- package/cjs/commands/aws/utils/tty.d.ts +24 -0
- package/cjs/commands/db/create-readonly-user/handler.cjs +11 -0
- package/cjs/commands/db/create-readonly-user/handler.d.ts +5 -0
- package/cjs/commands/db/create-readonly-user/index.cjs +40 -0
- package/cjs/commands/db/create-readonly-user/index.d.ts +3 -0
- package/cjs/commands/db/create-readonly-user/mysql.cjs +9 -0
- package/cjs/commands/db/create-readonly-user/mysql.d.ts +33 -0
- package/cjs/commands/db/create-readonly-user/postgres.cjs +9 -0
- package/cjs/commands/db/create-readonly-user/postgres.d.ts +31 -0
- package/cjs/commands/db/create-readonly-user/schema.cjs +12 -0
- package/cjs/commands/db/create-readonly-user/schema.d.ts +55 -0
- package/cjs/commands/db/create-readonly-user/utils.cjs +22 -0
- package/cjs/commands/db/create-readonly-user/utils.d.ts +112 -0
- package/cjs/commands/db/index.cjs +44 -0
- package/cjs/commands/db/index.d.ts +6 -0
- package/cjs/commands/doppler/handler.cjs +6 -4
- package/cjs/commands/doppler/index.cjs +32 -5
- package/cjs/commands/doppler/index.d.ts +1 -0
- package/cjs/commands/doppler/schema.cjs +10 -2
- package/cjs/commands/doppler/schema.d.ts +233 -17
- package/cjs/commands/doppler/set-secret.cjs +19 -0
- package/cjs/commands/doppler/set-secret.d.ts +113 -0
- package/cjs/commands/doppler/utils.cjs +6 -2
- package/cjs/commands/doppler/utils.d.ts +32 -8
- package/cjs/commands/icons/schema.d.ts +1 -1
- package/cjs/commands/index.cjs +91 -12
- package/esm/__chunks/2FTTEFEK.js +97 -0
- package/esm/__chunks/33UYMUQD.js +338 -0
- package/esm/__chunks/3BKWTHLJ.js +25 -0
- package/esm/__chunks/3HE4BEJX.js +105 -0
- package/esm/__chunks/3QLI5BDL.js +387 -0
- package/esm/__chunks/5GIUAFXL.js +89 -0
- package/esm/__chunks/73BJG53F.js +11 -0
- package/esm/__chunks/7VF4Q43Q.js +0 -0
- package/esm/__chunks/AEDEAYF5.js +0 -0
- package/esm/__chunks/AZCP3SFJ.js +0 -0
- package/esm/__chunks/B2DVQ2UL.js +61 -0
- package/esm/__chunks/CVQVHLW5.js +0 -0
- package/esm/__chunks/D62SPZXC.js +0 -0
- package/esm/__chunks/DLEJ25GZ.js +121 -0
- package/esm/__chunks/DMYFNF54.js +192 -0
- package/esm/__chunks/DNFTUMGD.js +23 -0
- package/esm/__chunks/DVKD6YSR.js +49 -0
- package/esm/__chunks/EMSH4P76.js +20 -0
- package/esm/__chunks/FFKFVMIE.js +167 -0
- package/esm/__chunks/FNXUONAV.js +110 -0
- package/esm/__chunks/G4NJHFFU.js +320 -0
- package/esm/__chunks/IEOGAQYI.js +46 -0
- package/esm/__chunks/IZFGBYGE.js +34 -0
- package/esm/__chunks/J34UVKLA.js +26 -0
- package/esm/__chunks/JZPBBBIG.js +74 -0
- package/esm/__chunks/KWUJP5MG.js +135 -0
- package/esm/__chunks/M35URMT4.js +313 -0
- package/esm/__chunks/NF3M2L6C.js +81 -0
- package/esm/__chunks/PNPPDYKC.js +299 -0
- package/esm/__chunks/QFXN4EHM.js +393 -0
- package/esm/__chunks/QKDDLIWD.js +146 -0
- package/esm/__chunks/QSE66AKY.js +208 -0
- package/esm/__chunks/QUF7PS4R.js +18 -0
- package/esm/__chunks/S7IJPJ4R.js +126 -0
- package/esm/__chunks/SD3E3EPH.js +163 -0
- package/esm/__chunks/T3TTUHTW.js +30 -0
- package/esm/__chunks/TIOVE6HR.js +0 -0
- package/esm/__chunks/TXKMEIDQ.js +0 -0
- package/esm/__chunks/U7HAE2RF.js +288 -0
- package/esm/__chunks/UXWY7BYE.js +63 -0
- package/esm/__chunks/VKAKISRG.js +192 -0
- package/esm/__chunks/WD2YR6I7.js +0 -0
- package/esm/__chunks/WOZFZKFY.js +0 -0
- package/esm/__chunks/XI7GZDE2.js +0 -0
- package/esm/__chunks/XOUWDB3T.js +249 -0
- package/esm/__chunks/XQN2TA4S.js +23 -0
- package/esm/__chunks/XXK32TIM.js +16 -0
- package/esm/__chunks/{O262GK4B.js → YGWTVPZE.js} +164 -27
- package/esm/__chunks/{6L5RNR7G.js → YRG7PT33.js} +44 -17
- package/esm/__chunks/ZHKVJO2U.js +47 -0
- package/esm/__chunks/ZO55YUSY.js +9 -0
- package/esm/commands/aws/ec2/allow-ip/handler.d.ts +6 -0
- package/esm/commands/aws/ec2/allow-ip/handler.js +12 -0
- package/esm/commands/aws/ec2/allow-ip/index.d.ts +3 -0
- package/esm/commands/aws/ec2/allow-ip/index.js +55 -0
- package/esm/commands/aws/ec2/allow-ip/schema.d.ts +33 -0
- package/esm/commands/aws/ec2/allow-ip/schema.js +13 -0
- package/esm/commands/aws/ec2/allow-ip/utils.d.ts +189 -0
- package/esm/commands/aws/ec2/allow-ip/utils.js +39 -0
- package/esm/commands/aws/iam/admin-group.d.ts +55 -0
- package/esm/commands/aws/iam/admin-group.js +15 -0
- package/esm/commands/aws/iam/break-glass/handler.d.ts +7 -0
- package/esm/commands/aws/iam/break-glass/handler.js +12 -0
- package/esm/commands/aws/iam/break-glass/index.d.ts +2 -0
- package/esm/commands/aws/iam/break-glass/index.js +19 -0
- package/esm/commands/aws/iam/break-glass/schema.d.ts +25 -0
- package/esm/commands/aws/iam/break-glass/schema.js +12 -0
- package/esm/commands/aws/iam/check-admin/handler.d.ts +5 -0
- package/esm/commands/aws/iam/check-admin/handler.js +10 -0
- package/esm/commands/aws/iam/check-admin/index.d.ts +2 -0
- package/esm/commands/aws/iam/check-admin/index.js +17 -0
- package/esm/commands/aws/iam/check-admin/schema.d.ts +19 -0
- package/esm/commands/aws/iam/check-admin/schema.js +12 -0
- package/esm/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.js +28 -0
- package/esm/commands/aws/iam/policies/sts-federation.js +19 -0
- package/esm/commands/aws/iam/policies/user-admins-deny-list.js +183 -0
- package/esm/commands/aws/iam/policies/user-admins-deny-regions-list.js +49 -0
- package/esm/commands/aws/iam/policies/user-admins-self-service-iam.js +64 -0
- package/esm/commands/aws/iam/policies/user-admins-write-list.js +125 -0
- package/esm/commands/aws/iam/remove-admin/handler.d.ts +6 -0
- package/esm/commands/aws/iam/remove-admin/handler.js +11 -0
- package/esm/commands/aws/iam/remove-admin/index.d.ts +2 -0
- package/esm/commands/aws/iam/remove-admin/index.js +18 -0
- package/esm/commands/aws/iam/remove-admin/schema.d.ts +28 -0
- package/esm/commands/aws/iam/remove-admin/schema.js +12 -0
- package/esm/commands/aws/iam/setup-acl/handler.d.ts +6 -0
- package/esm/commands/aws/iam/setup-acl/handler.js +14 -0
- package/esm/commands/aws/iam/setup-acl/index.d.ts +3 -0
- package/esm/commands/aws/iam/setup-acl/index.js +33 -0
- package/esm/commands/aws/iam/setup-acl/schema.d.ts +24 -0
- package/esm/commands/aws/iam/setup-acl/schema.js +7 -0
- package/esm/commands/aws/iam/setup-acl/utils.d.ts +61 -0
- package/esm/commands/aws/iam/setup-acl/utils.js +20 -0
- package/esm/commands/aws/iam/users/handler.d.ts +5 -0
- package/esm/commands/aws/iam/users/handler.js +12 -0
- package/esm/commands/aws/iam/users/index.d.ts +3 -0
- package/esm/commands/aws/iam/users/index.js +41 -0
- package/esm/commands/aws/iam/users/schema.d.ts +18 -0
- package/esm/commands/aws/iam/users/schema.js +7 -0
- package/esm/commands/aws/iam/users/utils.d.ts +119 -0
- package/esm/commands/aws/iam/users/utils.js +30 -0
- package/esm/commands/aws/index.d.ts +14 -0
- package/esm/commands/aws/index.js +229 -0
- package/esm/commands/aws/route53/add-record/handler.d.ts +36 -0
- package/esm/commands/aws/route53/add-record/handler.js +18 -0
- package/esm/commands/aws/route53/add-record/index.d.ts +3 -0
- package/esm/commands/aws/route53/add-record/index.js +57 -0
- package/esm/commands/aws/route53/add-record/schema.d.ts +45 -0
- package/esm/commands/aws/route53/add-record/schema.js +11 -0
- package/esm/commands/aws/route53/add-record/utils.d.ts +216 -0
- package/esm/commands/aws/route53/add-record/utils.js +37 -0
- package/esm/commands/aws/route53/remove-record/handler.d.ts +6 -0
- package/esm/commands/aws/route53/remove-record/handler.js +14 -0
- package/esm/commands/aws/route53/remove-record/index.d.ts +2 -0
- package/esm/commands/aws/route53/remove-record/index.js +18 -0
- package/esm/commands/aws/route53/remove-record/schema.d.ts +30 -0
- package/esm/commands/aws/route53/remove-record/schema.js +8 -0
- package/esm/commands/aws/schema.d.ts +13 -0
- package/esm/commands/aws/schema.js +10 -0
- package/esm/commands/aws/ses/send-email/handler.d.ts +5 -0
- package/esm/commands/aws/ses/send-email/handler.js +12 -0
- package/esm/commands/aws/ses/send-email/index.d.ts +3 -0
- package/esm/commands/aws/ses/send-email/index.js +23 -0
- package/esm/commands/aws/ses/send-email/schema.d.ts +39 -0
- package/esm/commands/aws/ses/send-email/schema.js +7 -0
- package/esm/commands/aws/ses/send-email/utils.d.ts +47 -0
- package/esm/commands/aws/ses/send-email/utils.js +11 -0
- package/esm/commands/aws/ses/smtp-password.d.ts +21 -0
- package/esm/commands/aws/ses/smtp-password.js +10 -0
- package/esm/commands/aws/utils/exec-aws.d.ts +79 -0
- package/esm/commands/aws/utils/exec-aws.js +16 -0
- package/esm/commands/aws/utils/resolve-policy-path.d.ts +8 -0
- package/esm/commands/aws/utils/resolve-policy-path.js +6 -0
- package/esm/commands/aws/utils/resolve-profile.d.ts +28 -0
- package/esm/commands/aws/utils/resolve-profile.js +11 -0
- package/esm/commands/aws/utils/tty.d.ts +24 -0
- package/esm/commands/aws/utils/tty.js +10 -0
- package/esm/commands/db/create-readonly-user/handler.d.ts +5 -0
- package/esm/commands/db/create-readonly-user/handler.js +11 -0
- package/esm/commands/db/create-readonly-user/index.d.ts +3 -0
- package/esm/commands/db/create-readonly-user/index.js +40 -0
- package/esm/commands/db/create-readonly-user/mysql.d.ts +33 -0
- package/esm/commands/db/create-readonly-user/mysql.js +9 -0
- package/esm/commands/db/create-readonly-user/postgres.d.ts +31 -0
- package/esm/commands/db/create-readonly-user/postgres.js +9 -0
- package/esm/commands/db/create-readonly-user/schema.d.ts +55 -0
- package/esm/commands/db/create-readonly-user/schema.js +12 -0
- package/esm/commands/db/create-readonly-user/utils.d.ts +112 -0
- package/esm/commands/db/create-readonly-user/utils.js +22 -0
- package/esm/commands/db/index.d.ts +6 -0
- package/esm/commands/db/index.js +44 -0
- package/esm/commands/doppler/handler.js +5 -3
- package/esm/commands/doppler/index.d.ts +1 -0
- package/esm/commands/doppler/index.js +32 -5
- package/esm/commands/doppler/schema.d.ts +233 -17
- package/esm/commands/doppler/schema.js +11 -3
- package/esm/commands/doppler/set-secret.d.ts +113 -0
- package/esm/commands/doppler/set-secret.js +19 -0
- package/esm/commands/doppler/utils.d.ts +32 -8
- package/esm/commands/doppler/utils.js +5 -1
- package/esm/commands/icons/schema.d.ts +1 -1
- package/esm/commands/index.js +86 -7
- package/package.json +12 -2
- package/vitest.config.ts +11 -0
- package/cjs/__chunks/4GFJUCSP.cjs +0 -52
- package/esm/__chunks/X3R5PSWH.js +0 -52
- /package/cjs/__chunks/{WNJ3ZYLI.cjs → 3BY5Y4W7.cjs} +0 -0
- /package/esm/__chunks/{46HGXFME.js → 5ZBVGSOK.js} +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defaultBody,
|
|
3
|
+
sendViaApi,
|
|
4
|
+
sendViaSmtp
|
|
5
|
+
} from "./UXWY7BYE.js";
|
|
6
|
+
import {
|
|
7
|
+
resolveProfile
|
|
8
|
+
} from "./5GIUAFXL.js";
|
|
9
|
+
import {
|
|
10
|
+
sendEmailOptionsSchema
|
|
11
|
+
} from "./3BKWTHLJ.js";
|
|
12
|
+
|
|
13
|
+
// src/commands/aws/ses/send-email/handler.js
|
|
14
|
+
import chalk from "chalk";
|
|
15
|
+
import { ZodError } from "zod";
|
|
16
|
+
async function sendEmailCommand(options) {
|
|
17
|
+
try {
|
|
18
|
+
const parsed = sendEmailOptionsSchema.parse(options);
|
|
19
|
+
const {
|
|
20
|
+
to,
|
|
21
|
+
from,
|
|
22
|
+
subject,
|
|
23
|
+
transport,
|
|
24
|
+
region,
|
|
25
|
+
profile: profileOption,
|
|
26
|
+
accessKeyId,
|
|
27
|
+
dryRun,
|
|
28
|
+
verbose
|
|
29
|
+
} = parsed;
|
|
30
|
+
const body = parsed.body ?? defaultBody();
|
|
31
|
+
const profile = transport === "api" ? await resolveProfile({ profile: profileOption }) : profileOption;
|
|
32
|
+
console.log(chalk.blue("\n\u{1F4E7} SES send-email"));
|
|
33
|
+
console.log(chalk.gray(` transport: ${transport}`));
|
|
34
|
+
console.log(chalk.gray(` region: ${region}`));
|
|
35
|
+
console.log(chalk.gray(` from: ${from}`));
|
|
36
|
+
console.log(chalk.gray(` to: ${to}`));
|
|
37
|
+
console.log(chalk.gray(` subject: ${subject}`));
|
|
38
|
+
if (verbose) {
|
|
39
|
+
console.log(chalk.gray(` body: ${body}`));
|
|
40
|
+
}
|
|
41
|
+
if (dryRun) {
|
|
42
|
+
console.log(chalk.yellow("\n[dry-run] No email sent."));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const messageId = transport === "api" ? await sendViaApi({ to, from, subject, body, region, profile }) : await sendViaSmtp({ to, from, subject, body, region, accessKeyId });
|
|
46
|
+
console.log(
|
|
47
|
+
chalk.green(
|
|
48
|
+
`
|
|
49
|
+
\u2705 Email sent${messageId ? ` (messageId: ${messageId})` : ""}.`
|
|
50
|
+
)
|
|
51
|
+
);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (error instanceof ZodError) {
|
|
54
|
+
console.error(chalk.red("\n\u274C Invalid command options:"));
|
|
55
|
+
error.errors.forEach((err) => {
|
|
56
|
+
console.error(chalk.red(` ${err.path.join(".")}: ${err.message}`));
|
|
57
|
+
});
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const verbose = (
|
|
61
|
+
/** @type {any} */
|
|
62
|
+
options?.verbose || false
|
|
63
|
+
);
|
|
64
|
+
console.error(chalk.red("\n\u274C send-email failed:"));
|
|
65
|
+
if (error instanceof Error) {
|
|
66
|
+
console.error(chalk.red(` ${error.message}`));
|
|
67
|
+
if (verbose && error.stack) {
|
|
68
|
+
console.error(chalk.gray("\nStack trace:"));
|
|
69
|
+
console.error(chalk.gray(error.stack));
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
console.error(chalk.red(` ${String(error)}`));
|
|
73
|
+
}
|
|
74
|
+
console.error(chalk.yellow("\n\u{1F4A1} Troubleshooting tips:"));
|
|
75
|
+
console.error(
|
|
76
|
+
chalk.yellow(" \u2022 The sender address must be verified in SES")
|
|
77
|
+
);
|
|
78
|
+
console.error(
|
|
79
|
+
chalk.yellow(
|
|
80
|
+
" \u2022 New SES accounts are sandboxed \u2014 recipients must also be verified"
|
|
81
|
+
)
|
|
82
|
+
);
|
|
83
|
+
console.error(
|
|
84
|
+
chalk.yellow(
|
|
85
|
+
" \u2022 For smtp transport, set SES_SMTP_USER and SES_SMTP_PASSWORD"
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
console.error(
|
|
89
|
+
chalk.yellow(" \u2022 Use --verbose for detailed error information\n")
|
|
90
|
+
);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
sendEmailCommand
|
|
97
|
+
};
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_TTL
|
|
3
|
+
} from "./IEOGAQYI.js";
|
|
4
|
+
import {
|
|
5
|
+
runAws
|
|
6
|
+
} from "./FNXUONAV.js";
|
|
7
|
+
|
|
8
|
+
// src/commands/aws/route53/add-record/utils.js
|
|
9
|
+
function bareHostedZoneId(rawId) {
|
|
10
|
+
return rawId.replace(/^\/hostedzone\//, "");
|
|
11
|
+
}
|
|
12
|
+
function withTrailingDot(name) {
|
|
13
|
+
const trimmed = name.trim();
|
|
14
|
+
if (trimmed === "") {
|
|
15
|
+
return trimmed;
|
|
16
|
+
}
|
|
17
|
+
return trimmed.endsWith(".") ? trimmed : `${trimmed}.`;
|
|
18
|
+
}
|
|
19
|
+
function withoutTrailingDot(name) {
|
|
20
|
+
return name.endsWith(".") ? name.slice(0, -1) : name;
|
|
21
|
+
}
|
|
22
|
+
function listHostedZones(params) {
|
|
23
|
+
const { profile, verbose } = params;
|
|
24
|
+
const data = runAws({
|
|
25
|
+
profile,
|
|
26
|
+
args: ["route53", "list-hosted-zones"],
|
|
27
|
+
verbose
|
|
28
|
+
});
|
|
29
|
+
const zones = [];
|
|
30
|
+
for (const zone of data.HostedZones ?? []) {
|
|
31
|
+
const id = bareHostedZoneId(String(zone.Id ?? ""));
|
|
32
|
+
const name = withTrailingDot(String(zone.Name ?? ""));
|
|
33
|
+
if (!id || !name) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
zones.push({
|
|
37
|
+
id,
|
|
38
|
+
name,
|
|
39
|
+
privateZone: Boolean(zone.Config?.PrivateZone),
|
|
40
|
+
recordCount: Number(zone.ResourceRecordSetCount ?? 0)
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return zones.sort((a, b) => a.name.localeCompare(b.name));
|
|
44
|
+
}
|
|
45
|
+
function findHostedZone(params) {
|
|
46
|
+
const { zones, zoneInput } = params;
|
|
47
|
+
const input = zoneInput.trim();
|
|
48
|
+
if (!input) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const bareId = bareHostedZoneId(input);
|
|
52
|
+
const byId = zones.find((zone) => zone.id === bareId);
|
|
53
|
+
if (byId) {
|
|
54
|
+
return byId;
|
|
55
|
+
}
|
|
56
|
+
const normalized = withTrailingDot(input).toLowerCase();
|
|
57
|
+
const matches = zones.filter(
|
|
58
|
+
(zone) => zone.name.toLowerCase() === normalized
|
|
59
|
+
);
|
|
60
|
+
if (matches.length === 1) {
|
|
61
|
+
return matches[0] ?? null;
|
|
62
|
+
}
|
|
63
|
+
if (matches.length > 1) {
|
|
64
|
+
return matches.find((zone) => !zone.privateZone) ?? matches[0] ?? null;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
function hostedZoneLabel(zone) {
|
|
69
|
+
const visibility = zone.privateZone ? "private" : "public";
|
|
70
|
+
return `${withoutTrailingDot(zone.name)} (${zone.id}, ${visibility}, ${zone.recordCount} records)`;
|
|
71
|
+
}
|
|
72
|
+
function resolveRecordName(params) {
|
|
73
|
+
const { nameInput, zoneName } = params;
|
|
74
|
+
const zoneFqdn = withTrailingDot(zoneName);
|
|
75
|
+
const raw = nameInput.trim();
|
|
76
|
+
if (raw === "" || raw === "@") {
|
|
77
|
+
return zoneFqdn;
|
|
78
|
+
}
|
|
79
|
+
const asFqdn = withTrailingDot(raw);
|
|
80
|
+
const zoneLower = zoneFqdn.toLowerCase();
|
|
81
|
+
if (asFqdn.toLowerCase() === zoneLower) {
|
|
82
|
+
return zoneFqdn;
|
|
83
|
+
}
|
|
84
|
+
if (asFqdn.toLowerCase().endsWith(`.${zoneLower}`)) {
|
|
85
|
+
return asFqdn;
|
|
86
|
+
}
|
|
87
|
+
const relative = raw.replace(/\.$/, "");
|
|
88
|
+
return withTrailingDot(`${relative}.${withoutTrailingDot(zoneFqdn)}`);
|
|
89
|
+
}
|
|
90
|
+
function getRecordSetsAtName(params) {
|
|
91
|
+
const { profile, hostedZoneId, name, verbose } = params;
|
|
92
|
+
const targetName = withTrailingDot(name).toLowerCase();
|
|
93
|
+
let startRecordName = withTrailingDot(name);
|
|
94
|
+
let startRecordType;
|
|
95
|
+
let nextRecordIdentifier;
|
|
96
|
+
const collected = [];
|
|
97
|
+
for (let page = 0; page < 20; page += 1) {
|
|
98
|
+
const args = [
|
|
99
|
+
"route53",
|
|
100
|
+
"list-resource-record-sets",
|
|
101
|
+
"--hosted-zone-id",
|
|
102
|
+
hostedZoneId,
|
|
103
|
+
"--max-items",
|
|
104
|
+
"100"
|
|
105
|
+
];
|
|
106
|
+
if (startRecordName) {
|
|
107
|
+
args.push("--start-record-name", startRecordName);
|
|
108
|
+
}
|
|
109
|
+
if (startRecordType) {
|
|
110
|
+
args.push("--start-record-type", startRecordType);
|
|
111
|
+
}
|
|
112
|
+
if (nextRecordIdentifier) {
|
|
113
|
+
args.push("--start-record-identifier", nextRecordIdentifier);
|
|
114
|
+
}
|
|
115
|
+
const data = runAws({ profile, args, verbose });
|
|
116
|
+
const sets = data.ResourceRecordSets ?? [];
|
|
117
|
+
for (const set of sets) {
|
|
118
|
+
const setName = withTrailingDot(String(set.Name ?? "")).toLowerCase();
|
|
119
|
+
if (setName === targetName) {
|
|
120
|
+
collected.push(normalizeRecordSet(set));
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (setName > targetName) {
|
|
124
|
+
return collected;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const truncated = data.IsTruncated === true;
|
|
128
|
+
if (!truncated) {
|
|
129
|
+
return collected;
|
|
130
|
+
}
|
|
131
|
+
startRecordName = data.NextRecordName ? String(data.NextRecordName) : startRecordName;
|
|
132
|
+
startRecordType = data.NextRecordType ? String(data.NextRecordType) : void 0;
|
|
133
|
+
nextRecordIdentifier = data.NextRecordIdentifier ? String(data.NextRecordIdentifier) : void 0;
|
|
134
|
+
}
|
|
135
|
+
return collected;
|
|
136
|
+
}
|
|
137
|
+
function getResourceRecordSet(params) {
|
|
138
|
+
const { type, ...rest } = params;
|
|
139
|
+
const targetType = type.toUpperCase();
|
|
140
|
+
const sets = getRecordSetsAtName(rest);
|
|
141
|
+
return sets.find((set) => set.type === targetType) ?? null;
|
|
142
|
+
}
|
|
143
|
+
function findCnameConflicts(params) {
|
|
144
|
+
const { existingSets, type } = params;
|
|
145
|
+
const upperType = type.toUpperCase();
|
|
146
|
+
return existingSets.filter((set) => {
|
|
147
|
+
if (set.type === upperType) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
return upperType === "CNAME" || set.type === "CNAME";
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function normalizeRecordSet(set) {
|
|
154
|
+
const values = (set.ResourceRecords ?? []).map(
|
|
155
|
+
(record) => String(record.Value ?? "")
|
|
156
|
+
);
|
|
157
|
+
return {
|
|
158
|
+
name: withTrailingDot(String(set.Name ?? "")),
|
|
159
|
+
type: String(set.Type ?? "").toUpperCase(),
|
|
160
|
+
ttl: typeof set.TTL === "number" ? set.TTL : void 0,
|
|
161
|
+
values,
|
|
162
|
+
isAlias: Boolean(set.AliasTarget),
|
|
163
|
+
aliasTarget: set.AliasTarget ?? void 0
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function formatValues(values) {
|
|
167
|
+
if (values.length === 0) {
|
|
168
|
+
return "(none)";
|
|
169
|
+
}
|
|
170
|
+
if (values.length === 1) {
|
|
171
|
+
return values[0] ?? "(none)";
|
|
172
|
+
}
|
|
173
|
+
return values.map((value) => `
|
|
174
|
+
- ${value}`).join("");
|
|
175
|
+
}
|
|
176
|
+
function normalizeRecordValue(params) {
|
|
177
|
+
const { type, value } = params;
|
|
178
|
+
const trimmed = value.trim();
|
|
179
|
+
if (type === "CNAME" || type === "NS" || type === "MX" || type === "SRV") {
|
|
180
|
+
if (type === "MX") {
|
|
181
|
+
const parts = trimmed.split(/\s+/);
|
|
182
|
+
if (parts.length >= 2) {
|
|
183
|
+
const priority = parts[0];
|
|
184
|
+
const exchange = parts.slice(1).join(" ");
|
|
185
|
+
return `${priority} ${withTrailingDot(exchange)}`;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (type === "SRV") {
|
|
189
|
+
const parts = trimmed.split(/\s+/);
|
|
190
|
+
if (parts.length >= 4) {
|
|
191
|
+
const prefix = parts.slice(0, 3).join(" ");
|
|
192
|
+
const target = parts.slice(3).join(" ");
|
|
193
|
+
return `${prefix} ${withTrailingDot(target)}`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return withTrailingDot(trimmed);
|
|
197
|
+
}
|
|
198
|
+
if (type === "TXT") {
|
|
199
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
200
|
+
return trimmed;
|
|
201
|
+
}
|
|
202
|
+
return `"${trimmed}"`;
|
|
203
|
+
}
|
|
204
|
+
return trimmed;
|
|
205
|
+
}
|
|
206
|
+
function planRecordChange(params) {
|
|
207
|
+
const { existing, newValue, mode = "replace" } = params;
|
|
208
|
+
if (!existing) {
|
|
209
|
+
return {
|
|
210
|
+
action: "create",
|
|
211
|
+
finalValues: [newValue],
|
|
212
|
+
summary: "Adding a new record (nothing exists at this name + type)."
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (existing.isAlias) {
|
|
216
|
+
return {
|
|
217
|
+
action: "overwrite",
|
|
218
|
+
finalValues: [newValue],
|
|
219
|
+
summary: "Overwriting an existing ALIAS record with a standard record set."
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const alreadyPresent = existing.values.some(
|
|
223
|
+
(value) => value === newValue || value === `"${newValue}"`
|
|
224
|
+
);
|
|
225
|
+
if (alreadyPresent && mode !== "replace") {
|
|
226
|
+
return {
|
|
227
|
+
action: "noop",
|
|
228
|
+
finalValues: existing.values,
|
|
229
|
+
summary: "Record already has this value. Nothing to do."
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
if (alreadyPresent && mode === "replace" && existing.values.length === 1 && existing.values[0] === newValue) {
|
|
233
|
+
return {
|
|
234
|
+
action: "noop",
|
|
235
|
+
finalValues: existing.values,
|
|
236
|
+
summary: "Record already has exactly this value. Nothing to do."
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if (mode === "append") {
|
|
240
|
+
return {
|
|
241
|
+
action: "append",
|
|
242
|
+
finalValues: [...existing.values, newValue],
|
|
243
|
+
summary: `Adding to the existing ${existing.type} record (${existing.values.length} value(s) \u2192 ${existing.values.length + 1}).`
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
action: "overwrite",
|
|
248
|
+
finalValues: [newValue],
|
|
249
|
+
summary: existing.values.length === 1 ? `Overwriting existing value:
|
|
250
|
+
${existing.values[0]}
|
|
251
|
+
\u2192 ${newValue}` : `Replacing ${existing.values.length} existing values with a single new value.`
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function upsertResourceRecordSet(params) {
|
|
255
|
+
const { profile, hostedZoneId, name, type, ttl, values, verbose } = params;
|
|
256
|
+
const changeBatch = {
|
|
257
|
+
Comment: `mtn aws route53 add-record: ${type} ${name}`,
|
|
258
|
+
Changes: [
|
|
259
|
+
{
|
|
260
|
+
Action: "UPSERT",
|
|
261
|
+
ResourceRecordSet: {
|
|
262
|
+
Name: withTrailingDot(name),
|
|
263
|
+
Type: type,
|
|
264
|
+
TTL: ttl ?? DEFAULT_TTL,
|
|
265
|
+
ResourceRecords: values.map((value) => ({ Value: value }))
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
};
|
|
270
|
+
const data = runAws({
|
|
271
|
+
profile,
|
|
272
|
+
args: [
|
|
273
|
+
"route53",
|
|
274
|
+
"change-resource-record-sets",
|
|
275
|
+
"--hosted-zone-id",
|
|
276
|
+
hostedZoneId,
|
|
277
|
+
"--change-batch",
|
|
278
|
+
JSON.stringify(changeBatch)
|
|
279
|
+
],
|
|
280
|
+
verbose
|
|
281
|
+
});
|
|
282
|
+
return data.ChangeInfo ?? data;
|
|
283
|
+
}
|
|
284
|
+
function deleteResourceRecordSet(params) {
|
|
285
|
+
const { profile, hostedZoneId, record, verbose } = params;
|
|
286
|
+
const resourceRecordSet = {
|
|
287
|
+
Name: withTrailingDot(record.name),
|
|
288
|
+
Type: record.type
|
|
289
|
+
};
|
|
290
|
+
if (record.isAlias && record.aliasTarget) {
|
|
291
|
+
resourceRecordSet.AliasTarget = record.aliasTarget;
|
|
292
|
+
} else {
|
|
293
|
+
resourceRecordSet.TTL = record.ttl ?? DEFAULT_TTL;
|
|
294
|
+
resourceRecordSet.ResourceRecords = record.values.map((value) => ({
|
|
295
|
+
Value: value
|
|
296
|
+
}));
|
|
297
|
+
}
|
|
298
|
+
const changeBatch = {
|
|
299
|
+
Comment: `mtn aws route53 remove-record: ${record.type} ${record.name}`,
|
|
300
|
+
Changes: [
|
|
301
|
+
{
|
|
302
|
+
Action: "DELETE",
|
|
303
|
+
ResourceRecordSet: resourceRecordSet
|
|
304
|
+
}
|
|
305
|
+
]
|
|
306
|
+
};
|
|
307
|
+
const data = runAws({
|
|
308
|
+
profile,
|
|
309
|
+
args: [
|
|
310
|
+
"route53",
|
|
311
|
+
"change-resource-record-sets",
|
|
312
|
+
"--hosted-zone-id",
|
|
313
|
+
hostedZoneId,
|
|
314
|
+
"--change-batch",
|
|
315
|
+
JSON.stringify(changeBatch)
|
|
316
|
+
],
|
|
317
|
+
verbose
|
|
318
|
+
});
|
|
319
|
+
return data.ChangeInfo ?? data;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export {
|
|
323
|
+
bareHostedZoneId,
|
|
324
|
+
withTrailingDot,
|
|
325
|
+
withoutTrailingDot,
|
|
326
|
+
listHostedZones,
|
|
327
|
+
findHostedZone,
|
|
328
|
+
hostedZoneLabel,
|
|
329
|
+
resolveRecordName,
|
|
330
|
+
getRecordSetsAtName,
|
|
331
|
+
getResourceRecordSet,
|
|
332
|
+
findCnameConflicts,
|
|
333
|
+
formatValues,
|
|
334
|
+
normalizeRecordValue,
|
|
335
|
+
planRecordChange,
|
|
336
|
+
upsertResourceRecordSet,
|
|
337
|
+
deleteResourceRecordSet
|
|
338
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
profileField,
|
|
3
|
+
verboseField
|
|
4
|
+
} from "./73BJG53F.js";
|
|
5
|
+
|
|
6
|
+
// src/commands/aws/ses/send-email/schema.js
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
var sendEmailOptionsSchema = z.object({
|
|
9
|
+
to: z.string({ required_error: "--to <address> is required" }).describe("Recipient email address"),
|
|
10
|
+
from: z.string({ required_error: "--from <address> is required" }).describe("Verified SES sender email address"),
|
|
11
|
+
subject: z.string().optional().default("MTN CLI test email").describe("Email subject line"),
|
|
12
|
+
body: z.string().optional().describe("Email body (defaults to a timestamp and random token)"),
|
|
13
|
+
transport: z.enum(["api", "smtp"]).optional().default("api").describe("Send via the SES API (default) or SES SMTP"),
|
|
14
|
+
region: z.string().optional().default("us-east-1").describe("AWS region for the SES endpoint"),
|
|
15
|
+
profile: profileField,
|
|
16
|
+
accessKeyId: z.string().optional().describe(
|
|
17
|
+
"IAM access key ID used as the SMTP username (smtp transport only)"
|
|
18
|
+
),
|
|
19
|
+
dryRun: z.boolean().optional().default(false).describe("Print the email payload without sending"),
|
|
20
|
+
verbose: verboseField
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
sendEmailOptionsSchema
|
|
25
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isSystemDatabase,
|
|
3
|
+
quoteIdent,
|
|
4
|
+
quoteLiteral
|
|
5
|
+
} from "./DLEJ25GZ.js";
|
|
6
|
+
|
|
7
|
+
// src/commands/db/create-readonly-user/mysql.js
|
|
8
|
+
import mysql from "mysql2/promise";
|
|
9
|
+
async function createConnection(config) {
|
|
10
|
+
return mysql.createConnection({
|
|
11
|
+
host: config.host,
|
|
12
|
+
port: config.port,
|
|
13
|
+
user: config.user,
|
|
14
|
+
password: config.password,
|
|
15
|
+
database: config.database || void 0,
|
|
16
|
+
ssl: config.ssl && typeof config.ssl === "object" ? config.ssl : void 0,
|
|
17
|
+
multipleStatements: false
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async function listMysqlDatabases(config) {
|
|
21
|
+
const connection = await createConnection(config);
|
|
22
|
+
try {
|
|
23
|
+
const [rows] = await connection.query("SHOW DATABASES");
|
|
24
|
+
const names = (
|
|
25
|
+
/** @type {Array<{ Database?: string }>} */
|
|
26
|
+
rows.map(
|
|
27
|
+
(row) => row.Database ?? ""
|
|
28
|
+
)
|
|
29
|
+
);
|
|
30
|
+
return names.filter((name) => Boolean(name)).filter((name) => !isSystemDatabase({ engine: "mysql", name })).sort((a, b) => a.localeCompare(b));
|
|
31
|
+
} finally {
|
|
32
|
+
await connection.end();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function applyMysqlReadonly(params) {
|
|
36
|
+
const {
|
|
37
|
+
config,
|
|
38
|
+
username,
|
|
39
|
+
password,
|
|
40
|
+
databases,
|
|
41
|
+
hostPattern,
|
|
42
|
+
dryRun = false,
|
|
43
|
+
verbose = false
|
|
44
|
+
} = params;
|
|
45
|
+
const userLiteral = quoteLiteral(username);
|
|
46
|
+
const hostLiteral = quoteLiteral(hostPattern);
|
|
47
|
+
const passwordLiteral = quoteLiteral(password);
|
|
48
|
+
const account = `${userLiteral}@${hostLiteral}`;
|
|
49
|
+
const statements = [];
|
|
50
|
+
const createSql = `CREATE USER IF NOT EXISTS ${account} IDENTIFIED BY ${passwordLiteral}`;
|
|
51
|
+
const alterSql = `ALTER USER ${account} IDENTIFIED BY ${passwordLiteral}`;
|
|
52
|
+
const grantSqls = [];
|
|
53
|
+
if (databases === "all") {
|
|
54
|
+
grantSqls.push(
|
|
55
|
+
`GRANT SELECT, SHOW VIEW, SHOW DATABASES ON *.* TO ${account}`
|
|
56
|
+
);
|
|
57
|
+
} else {
|
|
58
|
+
for (const database of databases) {
|
|
59
|
+
const dbIdent = quoteIdent({ engine: "mysql", name: database });
|
|
60
|
+
grantSqls.push(`GRANT SELECT, SHOW VIEW ON ${dbIdent}.* TO ${account}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const flushSql = "FLUSH PRIVILEGES";
|
|
64
|
+
statements.push(createSql, alterSql, ...grantSqls, flushSql);
|
|
65
|
+
if (dryRun) {
|
|
66
|
+
return {
|
|
67
|
+
created: true,
|
|
68
|
+
statements: statements.map(
|
|
69
|
+
(sql) => sql.includes("IDENTIFIED BY") ? sql.replace(/IDENTIFIED BY '.*'/, "IDENTIFIED BY ***") : sql
|
|
70
|
+
),
|
|
71
|
+
databases
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const connection = await createConnection(config);
|
|
75
|
+
try {
|
|
76
|
+
if (verbose) {
|
|
77
|
+
console.log(` Connected to MySQL as ${config.user}@${config.host}`);
|
|
78
|
+
}
|
|
79
|
+
const [existingRows] = await connection.query(
|
|
80
|
+
"SELECT 1 AS ok FROM mysql.user WHERE User = ? AND Host = ? LIMIT 1",
|
|
81
|
+
[username, hostPattern]
|
|
82
|
+
);
|
|
83
|
+
const existed = Array.isArray(existingRows) && existingRows.length > 0;
|
|
84
|
+
await connection.query(createSql);
|
|
85
|
+
await connection.query(alterSql);
|
|
86
|
+
for (const grantSql of grantSqls) {
|
|
87
|
+
await connection.query(grantSql);
|
|
88
|
+
}
|
|
89
|
+
await connection.query(flushSql);
|
|
90
|
+
return {
|
|
91
|
+
created: !existed,
|
|
92
|
+
statements: statements.map(
|
|
93
|
+
(sql) => sql.includes("IDENTIFIED BY") ? sql.replace(/IDENTIFIED BY '.*'/, "IDENTIFIED BY ***") : sql
|
|
94
|
+
),
|
|
95
|
+
databases
|
|
96
|
+
};
|
|
97
|
+
} finally {
|
|
98
|
+
await connection.end();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export {
|
|
103
|
+
listMysqlDatabases,
|
|
104
|
+
applyMysqlReadonly
|
|
105
|
+
};
|