@mtndev/cli 2.0.0 → 2.0.1

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.
Files changed (264) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/cjs/__chunks/VH7oDXx4.cjs +28 -0
  3. package/cjs/commands/aws/ec2/allow-ip/handler.cjs +261 -12
  4. package/cjs/commands/aws/ec2/allow-ip/index.cjs +25 -55
  5. package/cjs/commands/aws/ec2/allow-ip/schema.cjs +33 -13
  6. package/cjs/commands/aws/ec2/allow-ip/utils.cjs +379 -39
  7. package/cjs/commands/aws/iam/admin-group.cjs +111 -15
  8. package/cjs/commands/aws/iam/break-glass/handler.cjs +127 -12
  9. package/cjs/commands/aws/iam/break-glass/index.cjs +7 -19
  10. package/cjs/commands/aws/iam/break-glass/schema.cjs +21 -12
  11. package/cjs/commands/aws/iam/check-admin/handler.cjs +89 -10
  12. package/cjs/commands/aws/iam/check-admin/index.cjs +7 -17
  13. package/cjs/commands/aws/iam/check-admin/schema.cjs +19 -12
  14. package/cjs/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.json +20 -0
  15. package/cjs/commands/aws/iam/policies/sts-federation.json +11 -0
  16. package/cjs/commands/aws/iam/policies/user-admins-deny-list.json +175 -0
  17. package/cjs/commands/aws/iam/policies/user-admins-deny-regions-list.json +41 -0
  18. package/cjs/commands/aws/iam/policies/user-admins-self-service-iam.json +56 -0
  19. package/cjs/commands/aws/iam/policies/user-admins-write-list.json +117 -0
  20. package/cjs/commands/aws/iam/remove-admin/handler.cjs +120 -11
  21. package/cjs/commands/aws/iam/remove-admin/index.cjs +7 -18
  22. package/cjs/commands/aws/iam/remove-admin/schema.cjs +22 -12
  23. package/cjs/commands/aws/iam/setup-acl/handler.cjs +227 -14
  24. package/cjs/commands/aws/iam/setup-acl/index.cjs +13 -33
  25. package/cjs/commands/aws/iam/setup-acl/schema.cjs +19 -7
  26. package/cjs/commands/aws/iam/setup-acl/utils.cjs +305 -20
  27. package/cjs/commands/aws/iam/users/handler.cjs +59 -12
  28. package/cjs/commands/aws/iam/users/index.cjs +18 -41
  29. package/cjs/commands/aws/iam/users/schema.cjs +17 -7
  30. package/cjs/commands/aws/iam/users/utils.cjs +454 -30
  31. package/cjs/commands/aws/index.cjs +223 -229
  32. package/cjs/commands/aws/route53/add-record/handler.cjs +264 -18
  33. package/cjs/commands/aws/route53/add-record/index.cjs +26 -57
  34. package/cjs/commands/aws/route53/add-record/schema.cjs +43 -11
  35. package/cjs/commands/aws/route53/add-record/utils.cjs +404 -37
  36. package/cjs/commands/aws/route53/remove-record/handler.cjs +114 -14
  37. package/cjs/commands/aws/route53/remove-record/index.cjs +5 -18
  38. package/cjs/commands/aws/route53/remove-record/schema.cjs +22 -8
  39. package/cjs/commands/aws/schema.cjs +19 -10
  40. package/cjs/commands/aws/ses/send-email/handler.cjs +73 -12
  41. package/cjs/commands/aws/ses/send-email/index.cjs +9 -23
  42. package/cjs/commands/aws/ses/send-email/schema.cjs +24 -7
  43. package/cjs/commands/aws/ses/send-email/utils.cjs +87 -11
  44. package/cjs/commands/aws/ses/smtp-password.cjs +72 -10
  45. package/cjs/commands/aws/utils/exec-aws.cjs +145 -16
  46. package/cjs/commands/aws/utils/resolve-policy-path.cjs +15 -6
  47. package/cjs/commands/aws/utils/resolve-profile.cjs +93 -11
  48. package/cjs/commands/aws/utils/tty.cjs +54 -10
  49. package/cjs/commands/db/create-readonly-user/handler.cjs +254 -11
  50. package/cjs/commands/db/create-readonly-user/index.cjs +18 -40
  51. package/cjs/commands/db/create-readonly-user/mysql.cjs +102 -9
  52. package/cjs/commands/db/create-readonly-user/postgres.cjs +209 -9
  53. package/cjs/commands/db/create-readonly-user/schema.cjs +39 -12
  54. package/cjs/commands/db/create-readonly-user/utils.cjs +160 -22
  55. package/cjs/commands/db/index.cjs +46 -44
  56. package/cjs/commands/doppler/handler.cjs +95 -11
  57. package/cjs/commands/doppler/index.cjs +33 -68
  58. package/cjs/commands/doppler/schema.cjs +130 -14
  59. package/cjs/commands/doppler/set-secret.cjs +378 -19
  60. package/cjs/commands/doppler/utils/exec.cjs +106 -12
  61. package/cjs/commands/doppler/utils.cjs +412 -34
  62. package/cjs/commands/icons/handler.cjs +82 -8
  63. package/cjs/commands/icons/index.cjs +15 -31
  64. package/cjs/commands/icons/schema.cjs +101 -13
  65. package/cjs/commands/icons/utils.cjs +131 -13
  66. package/cjs/commands/index.cjs +54 -161
  67. package/cjs/commands/schema.cjs +25 -8
  68. package/cjs/index.cjs +3 -4
  69. package/esm/commands/aws/ec2/allow-ip/handler.js +258 -12
  70. package/esm/commands/aws/ec2/allow-ip/index.js +4 -55
  71. package/esm/commands/aws/ec2/allow-ip/schema.js +29 -13
  72. package/esm/commands/aws/ec2/allow-ip/utils.js +363 -39
  73. package/esm/commands/aws/iam/admin-group.js +104 -15
  74. package/esm/commands/aws/iam/break-glass/handler.js +124 -12
  75. package/esm/commands/aws/iam/break-glass/index.js +4 -19
  76. package/esm/commands/aws/iam/break-glass/schema.js +19 -12
  77. package/esm/commands/aws/iam/check-admin/handler.js +86 -10
  78. package/esm/commands/aws/iam/check-admin/index.js +4 -17
  79. package/esm/commands/aws/iam/check-admin/schema.js +17 -12
  80. package/esm/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.json +20 -0
  81. package/esm/commands/aws/iam/policies/sts-federation.json +11 -0
  82. package/esm/commands/aws/iam/policies/user-admins-deny-list.json +175 -0
  83. package/esm/commands/aws/iam/policies/user-admins-deny-regions-list.json +41 -0
  84. package/esm/commands/aws/iam/policies/user-admins-self-service-iam.json +56 -0
  85. package/esm/commands/aws/iam/policies/user-admins-write-list.json +117 -0
  86. package/esm/commands/aws/iam/remove-admin/handler.js +117 -11
  87. package/esm/commands/aws/iam/remove-admin/index.js +4 -18
  88. package/esm/commands/aws/iam/remove-admin/schema.js +20 -12
  89. package/esm/commands/aws/iam/setup-acl/handler.js +224 -14
  90. package/esm/commands/aws/iam/setup-acl/index.js +4 -33
  91. package/esm/commands/aws/iam/setup-acl/schema.js +18 -7
  92. package/esm/commands/aws/iam/setup-acl/utils.js +298 -20
  93. package/esm/commands/aws/iam/users/handler.js +56 -12
  94. package/esm/commands/aws/iam/users/index.js +4 -41
  95. package/esm/commands/aws/iam/users/schema.js +16 -7
  96. package/esm/commands/aws/iam/users/utils.js +440 -30
  97. package/esm/commands/aws/index.js +142 -229
  98. package/esm/commands/aws/route53/add-record/handler.js +258 -18
  99. package/esm/commands/aws/route53/add-record/index.js +4 -57
  100. package/esm/commands/aws/route53/add-record/schema.js +40 -11
  101. package/esm/commands/aws/route53/add-record/utils.js +389 -37
  102. package/esm/commands/aws/route53/remove-record/handler.js +111 -14
  103. package/esm/commands/aws/route53/remove-record/index.js +3 -18
  104. package/esm/commands/aws/route53/remove-record/schema.js +21 -8
  105. package/esm/commands/aws/schema.js +16 -10
  106. package/esm/commands/aws/ses/send-email/handler.js +70 -12
  107. package/esm/commands/aws/ses/send-email/index.js +4 -23
  108. package/esm/commands/aws/ses/send-email/schema.js +23 -7
  109. package/esm/commands/aws/ses/send-email/utils.js +84 -11
  110. package/esm/commands/aws/ses/smtp-password.js +69 -10
  111. package/esm/commands/aws/utils/exec-aws.js +136 -15
  112. package/esm/commands/aws/utils/resolve-policy-path.js +14 -6
  113. package/esm/commands/aws/utils/resolve-profile.js +88 -11
  114. package/esm/commands/aws/utils/tty.js +51 -10
  115. package/esm/commands/db/create-readonly-user/handler.js +251 -11
  116. package/esm/commands/db/create-readonly-user/index.js +4 -40
  117. package/esm/commands/db/create-readonly-user/mysql.js +98 -9
  118. package/esm/commands/db/create-readonly-user/postgres.js +205 -9
  119. package/esm/commands/db/create-readonly-user/schema.js +35 -12
  120. package/esm/commands/db/create-readonly-user/utils.js +151 -22
  121. package/esm/commands/db/index.js +31 -44
  122. package/esm/commands/doppler/handler.js +92 -11
  123. package/esm/commands/doppler/index.js +6 -68
  124. package/esm/commands/doppler/schema.js +125 -15
  125. package/esm/commands/doppler/set-secret.js +370 -19
  126. package/esm/commands/doppler/utils/exec.js +100 -12
  127. package/esm/commands/doppler/utils.js +396 -34
  128. package/esm/commands/icons/handler.js +79 -8
  129. package/esm/commands/icons/index.js +4 -31
  130. package/esm/commands/icons/schema.js +97 -15
  131. package/esm/commands/icons/utils.js +125 -13
  132. package/esm/commands/index.js +47 -155
  133. package/esm/commands/schema.js +22 -7
  134. package/esm/index.js +3 -4
  135. package/package.json +5 -2
  136. package/vitest.config.ts +11 -0
  137. package/cjs/__chunks/2FSYDFUV.cjs +0 -146
  138. package/cjs/__chunks/3A5ZYU5M.cjs +0 -105
  139. package/cjs/__chunks/3BY5Y4W7.cjs +0 -1
  140. package/cjs/__chunks/3NOHGUCF.cjs +0 -9
  141. package/cjs/__chunks/3T2LXW7J.cjs +0 -387
  142. package/cjs/__chunks/4SFWHCB3.cjs +0 -133
  143. package/cjs/__chunks/4XT5JEAS.cjs +0 -1
  144. package/cjs/__chunks/AZEB4H4I.cjs +0 -208
  145. package/cjs/__chunks/B2KFW7T7.cjs +0 -1
  146. package/cjs/__chunks/B5ENMOCD.cjs +0 -288
  147. package/cjs/__chunks/B6XM5KSF.cjs +0 -338
  148. package/cjs/__chunks/BDU2UCE5.cjs +0 -1
  149. package/cjs/__chunks/BLMSMR5E.cjs +0 -46
  150. package/cjs/__chunks/CMUD7LLN.cjs +0 -47
  151. package/cjs/__chunks/DTQ2LB3I.cjs +0 -49
  152. package/cjs/__chunks/FM5MVRQF.cjs +0 -23
  153. package/cjs/__chunks/FRHST54J.cjs +0 -135
  154. package/cjs/__chunks/FU4VP2LN.cjs +0 -1
  155. package/cjs/__chunks/G5K4PVIL.cjs +0 -26
  156. package/cjs/__chunks/GU3R54MK.cjs +0 -127
  157. package/cjs/__chunks/GUL36IFZ.cjs +0 -61
  158. package/cjs/__chunks/GZMTNK5N.cjs +0 -1
  159. package/cjs/__chunks/H74JSDBU.cjs +0 -30
  160. package/cjs/__chunks/INFOPAHN.cjs +0 -117
  161. package/cjs/__chunks/J36P6UNE.cjs +0 -75
  162. package/cjs/__chunks/JB7T7PKQ.cjs +0 -538
  163. package/cjs/__chunks/JSL2JDMW.cjs +0 -1
  164. package/cjs/__chunks/K4QNHRTP.cjs +0 -163
  165. package/cjs/__chunks/KU76LC42.cjs +0 -192
  166. package/cjs/__chunks/LFDSHANP.cjs +0 -34
  167. package/cjs/__chunks/LHE24ECK.cjs +0 -192
  168. package/cjs/__chunks/LIKQ3SI4.cjs +0 -1
  169. package/cjs/__chunks/LXDF5QVZ.cjs +0 -313
  170. package/cjs/__chunks/LXOOJR2R.cjs +0 -74
  171. package/cjs/__chunks/N5MXFOQZ.cjs +0 -167
  172. package/cjs/__chunks/N7D56LPP.cjs +0 -25
  173. package/cjs/__chunks/NFXQNOQH.cjs +0 -393
  174. package/cjs/__chunks/NIMXXHJQ.cjs +0 -92
  175. package/cjs/__chunks/NLKJIUEX.cjs +0 -126
  176. package/cjs/__chunks/NT2XXAI6.cjs +0 -89
  177. package/cjs/__chunks/NWZGFHKH.cjs +0 -121
  178. package/cjs/__chunks/R3GUC7O7.cjs +0 -110
  179. package/cjs/__chunks/RPVAXPJ4.cjs +0 -1
  180. package/cjs/__chunks/S3LVCWPN.cjs +0 -23
  181. package/cjs/__chunks/SBBNW2BF.cjs +0 -249
  182. package/cjs/__chunks/T2A7TN4F.cjs +0 -81
  183. package/cjs/__chunks/TKNNDDIB.cjs +0 -97
  184. package/cjs/__chunks/TNSRDJPR.cjs +0 -1
  185. package/cjs/__chunks/UWHPE2GI.cjs +0 -20
  186. package/cjs/__chunks/W6K7BV74.cjs +0 -1
  187. package/cjs/__chunks/WBOQ6AUN.cjs +0 -320
  188. package/cjs/__chunks/WHGN5PZI.cjs +0 -299
  189. package/cjs/__chunks/WOYF2L6T.cjs +0 -11
  190. package/cjs/__chunks/X26XY2N6.cjs +0 -18
  191. package/cjs/__chunks/XMKOKRXZ.cjs +0 -16
  192. package/cjs/__chunks/XTJPQ3EX.cjs +0 -1
  193. package/cjs/__chunks/YRHFKTW2.cjs +0 -63
  194. package/cjs/__chunks/ZMDIOZPT.cjs +0 -22
  195. package/cjs/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.cjs +0 -28
  196. package/cjs/commands/aws/iam/policies/sts-federation.cjs +0 -19
  197. package/cjs/commands/aws/iam/policies/user-admins-deny-list.cjs +0 -183
  198. package/cjs/commands/aws/iam/policies/user-admins-deny-regions-list.cjs +0 -49
  199. package/cjs/commands/aws/iam/policies/user-admins-self-service-iam.cjs +0 -64
  200. package/cjs/commands/aws/iam/policies/user-admins-write-list.cjs +0 -125
  201. package/esm/__chunks/2FTTEFEK.js +0 -97
  202. package/esm/__chunks/33UYMUQD.js +0 -338
  203. package/esm/__chunks/3BKWTHLJ.js +0 -25
  204. package/esm/__chunks/3HE4BEJX.js +0 -105
  205. package/esm/__chunks/3QLI5BDL.js +0 -387
  206. package/esm/__chunks/5GIUAFXL.js +0 -89
  207. package/esm/__chunks/5ZBVGSOK.js +0 -0
  208. package/esm/__chunks/6G4PXXKF.js +0 -75
  209. package/esm/__chunks/73BJG53F.js +0 -11
  210. package/esm/__chunks/7VF4Q43Q.js +0 -0
  211. package/esm/__chunks/AEDEAYF5.js +0 -0
  212. package/esm/__chunks/AZCP3SFJ.js +0 -0
  213. package/esm/__chunks/B2DVQ2UL.js +0 -61
  214. package/esm/__chunks/CVQVHLW5.js +0 -0
  215. package/esm/__chunks/D62SPZXC.js +0 -0
  216. package/esm/__chunks/DLEJ25GZ.js +0 -121
  217. package/esm/__chunks/DMYFNF54.js +0 -192
  218. package/esm/__chunks/DNFTUMGD.js +0 -23
  219. package/esm/__chunks/DVKD6YSR.js +0 -49
  220. package/esm/__chunks/EMSH4P76.js +0 -20
  221. package/esm/__chunks/FFKFVMIE.js +0 -167
  222. package/esm/__chunks/FL7AILGH.js +0 -133
  223. package/esm/__chunks/FNXUONAV.js +0 -110
  224. package/esm/__chunks/G4NJHFFU.js +0 -320
  225. package/esm/__chunks/HJSXC6HP.js +0 -117
  226. package/esm/__chunks/IEOGAQYI.js +0 -46
  227. package/esm/__chunks/IZFGBYGE.js +0 -34
  228. package/esm/__chunks/J34UVKLA.js +0 -26
  229. package/esm/__chunks/JZPBBBIG.js +0 -74
  230. package/esm/__chunks/KWUJP5MG.js +0 -135
  231. package/esm/__chunks/M35URMT4.js +0 -313
  232. package/esm/__chunks/NF3M2L6C.js +0 -81
  233. package/esm/__chunks/O3CCA76Q.js +0 -22
  234. package/esm/__chunks/PNPPDYKC.js +0 -299
  235. package/esm/__chunks/QFXN4EHM.js +0 -393
  236. package/esm/__chunks/QKDDLIWD.js +0 -146
  237. package/esm/__chunks/QSE66AKY.js +0 -208
  238. package/esm/__chunks/QUF7PS4R.js +0 -18
  239. package/esm/__chunks/S7IJPJ4R.js +0 -126
  240. package/esm/__chunks/SD3E3EPH.js +0 -163
  241. package/esm/__chunks/SJXQJ7RS.js +0 -92
  242. package/esm/__chunks/SNCKIAOR.js +0 -0
  243. package/esm/__chunks/T3TTUHTW.js +0 -30
  244. package/esm/__chunks/TIOVE6HR.js +0 -0
  245. package/esm/__chunks/TXKMEIDQ.js +0 -0
  246. package/esm/__chunks/U7HAE2RF.js +0 -288
  247. package/esm/__chunks/UXWY7BYE.js +0 -63
  248. package/esm/__chunks/VKAKISRG.js +0 -192
  249. package/esm/__chunks/WD2YR6I7.js +0 -0
  250. package/esm/__chunks/WOZFZKFY.js +0 -0
  251. package/esm/__chunks/XI7GZDE2.js +0 -0
  252. package/esm/__chunks/XOUWDB3T.js +0 -249
  253. package/esm/__chunks/XQN2TA4S.js +0 -23
  254. package/esm/__chunks/XXK32TIM.js +0 -16
  255. package/esm/__chunks/YGWTVPZE.js +0 -538
  256. package/esm/__chunks/YRG7PT33.js +0 -127
  257. package/esm/__chunks/ZHKVJO2U.js +0 -47
  258. package/esm/__chunks/ZO55YUSY.js +0 -9
  259. package/esm/commands/aws/iam/policies/s3-restrictions-deny-non-s3-services.js +0 -28
  260. package/esm/commands/aws/iam/policies/sts-federation.js +0 -19
  261. package/esm/commands/aws/iam/policies/user-admins-deny-list.js +0 -183
  262. package/esm/commands/aws/iam/policies/user-admins-deny-regions-list.js +0 -49
  263. package/esm/commands/aws/iam/policies/user-admins-self-service-iam.js +0 -64
  264. package/esm/commands/aws/iam/policies/user-admins-write-list.js +0 -125
@@ -1,9 +1,209 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
-
4
- var _K4QNHRTPcjs = require('../../../__chunks/K4QNHRTP.cjs');
5
- require('../../../__chunks/NWZGFHKH.cjs');
6
-
7
-
8
-
9
- exports.applyPostgresReadonly = _K4QNHRTPcjs.applyPostgresReadonly; exports.listPostgresDatabases = _K4QNHRTPcjs.listPostgresDatabases;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_rolldown_runtime = require("../../../__chunks/VH7oDXx4.cjs");
3
+ const require_commands_db_create_readonly_user_utils = require("./utils.cjs");
4
+ let pg = require("pg");
5
+ pg = require_rolldown_runtime.__toESM(pg, 1);
6
+ //#region src/commands/db/create-readonly-user/postgres.js
7
+ const { Client } = pg.default;
8
+ /**
9
+ * @typedef {import("./utils.js").ConnectionConfig} ConnectionConfig
10
+ */
11
+ /**
12
+ * @param {ConnectionConfig} config
13
+ * @param {string} [database]
14
+ * @returns {import("pg").Client}
15
+ */
16
+ function createClient(config, database) {
17
+ return new Client({
18
+ host: config.host,
19
+ port: config.port,
20
+ user: config.user,
21
+ password: config.password,
22
+ database: database ?? (config.database || "postgres"),
23
+ ssl: config.ssl
24
+ });
25
+ }
26
+ /**
27
+ * @param {import("pg").Client} client
28
+ * @param {string} sql
29
+ * @param {unknown[]} [params]
30
+ */
31
+ async function query(client, sql, params) {
32
+ return client.query(sql, params);
33
+ }
34
+ /**
35
+ * List non-template databases visible to the admin user.
36
+ * @param {ConnectionConfig} config
37
+ * @returns {Promise<string[]>}
38
+ */
39
+ async function listPostgresDatabases(config) {
40
+ const client = createClient(config, config.database || "postgres");
41
+ await client.connect();
42
+ try {
43
+ return (await query(client, `SELECT datname
44
+ FROM pg_database
45
+ WHERE datistemplate = false
46
+ ORDER BY datname`)).rows.map((row) => row.datname).filter((name) => !require_commands_db_create_readonly_user_utils.isSystemDatabase({
47
+ engine: "postgres",
48
+ name
49
+ }));
50
+ } finally {
51
+ await client.end();
52
+ }
53
+ }
54
+ /**
55
+ * Ensure a login role exists (create or update password).
56
+ * @param {import("pg").Client} client
57
+ * @param {{ username: string; password: string }} params
58
+ * @returns {Promise<{ created: boolean; statements: string[] }>}
59
+ */
60
+ async function ensureRole(client, params) {
61
+ const { username, password } = params;
62
+ const ident = require_commands_db_create_readonly_user_utils.quoteIdent({
63
+ engine: "postgres",
64
+ name: username
65
+ });
66
+ const passwordLiteral = require_commands_db_create_readonly_user_utils.quoteLiteral(password);
67
+ const existing = await query(client, "SELECT 1 FROM pg_roles WHERE rolname = $1", [username]);
68
+ /** @type {string[]} */
69
+ const statements = [];
70
+ if (existing.rowCount && existing.rowCount > 0) {
71
+ const sql = `ALTER ROLE ${ident} WITH LOGIN PASSWORD ${passwordLiteral}`;
72
+ statements.push(sql);
73
+ await query(client, sql);
74
+ return {
75
+ created: false,
76
+ statements
77
+ };
78
+ }
79
+ const sql = `CREATE ROLE ${ident} WITH LOGIN PASSWORD ${passwordLiteral}`;
80
+ statements.push(sql);
81
+ await query(client, sql);
82
+ return {
83
+ created: true,
84
+ statements
85
+ };
86
+ }
87
+ /**
88
+ * Grant read-only privileges inside one database (schemas, tables, sequences, defaults).
89
+ * @param {import("pg").Client} client
90
+ * @param {{ username: string }} params
91
+ * @returns {Promise<string[]>}
92
+ */
93
+ async function grantReadonlyInDatabase(client, params) {
94
+ const { username } = params;
95
+ const ident = require_commands_db_create_readonly_user_utils.quoteIdent({
96
+ engine: "postgres",
97
+ name: username
98
+ });
99
+ /** @type {string[]} */
100
+ const statements = [];
101
+ const schemas = (await query(client, `SELECT nspname
102
+ FROM pg_namespace
103
+ WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
104
+ AND nspname NOT LIKE 'pg_temp_%'
105
+ AND nspname NOT LIKE 'pg_toast_temp_%'
106
+ ORDER BY nspname`)).rows.map((row) => row.nspname);
107
+ if (schemas.length === 0) schemas.push("public");
108
+ for (const schema of schemas) {
109
+ const schemaIdent = require_commands_db_create_readonly_user_utils.quoteIdent({
110
+ engine: "postgres",
111
+ name: schema
112
+ });
113
+ const grants = [
114
+ `GRANT USAGE ON SCHEMA ${schemaIdent} TO ${ident}`,
115
+ `GRANT SELECT ON ALL TABLES IN SCHEMA ${schemaIdent} TO ${ident}`,
116
+ `GRANT SELECT ON ALL SEQUENCES IN SCHEMA ${schemaIdent} TO ${ident}`,
117
+ `ALTER DEFAULT PRIVILEGES IN SCHEMA ${schemaIdent} GRANT SELECT ON TABLES TO ${ident}`,
118
+ `ALTER DEFAULT PRIVILEGES IN SCHEMA ${schemaIdent} GRANT SELECT ON SEQUENCES TO ${ident}`
119
+ ];
120
+ for (const sql of grants) {
121
+ statements.push(sql);
122
+ await query(client, sql);
123
+ }
124
+ }
125
+ return statements;
126
+ }
127
+ /**
128
+ * Create/update a Postgres role and grant read-only on one or all databases.
129
+ * @param {{
130
+ * config: ConnectionConfig;
131
+ * username: string;
132
+ * password: string;
133
+ * databases: string[];
134
+ * dryRun?: boolean;
135
+ * verbose?: boolean;
136
+ * }} params
137
+ * @returns {Promise<{ created: boolean; statements: string[]; databases: string[] }>}
138
+ */
139
+ async function applyPostgresReadonly(params) {
140
+ const { config, username, password, databases, dryRun = false, verbose = false } = params;
141
+ /** @type {string[]} */
142
+ const statements = [];
143
+ let created = false;
144
+ if (dryRun) {
145
+ const ident = require_commands_db_create_readonly_user_utils.quoteIdent({
146
+ engine: "postgres",
147
+ name: username
148
+ });
149
+ statements.push(`-- Would CREATE/ALTER ROLE ${ident} WITH LOGIN PASSWORD ***`);
150
+ for (const database of databases) {
151
+ const dbIdent = require_commands_db_create_readonly_user_utils.quoteIdent({
152
+ engine: "postgres",
153
+ name: database
154
+ });
155
+ statements.push(`GRANT CONNECT ON DATABASE ${dbIdent} TO ${ident}`);
156
+ statements.push(`-- In database ${database}: GRANT USAGE/SELECT on all user schemas + ALTER DEFAULT PRIVILEGES`);
157
+ }
158
+ return {
159
+ created: true,
160
+ statements,
161
+ databases
162
+ };
163
+ }
164
+ const adminDb = config.database || "postgres";
165
+ const adminClient = createClient(config, adminDb);
166
+ await adminClient.connect();
167
+ try {
168
+ if (verbose) console.log(` Connected to Postgres as ${config.user}@${config.host}/${adminDb}`);
169
+ const roleResult = await ensureRole(adminClient, {
170
+ username,
171
+ password
172
+ });
173
+ created = roleResult.created;
174
+ statements.push(...roleResult.statements);
175
+ const ident = require_commands_db_create_readonly_user_utils.quoteIdent({
176
+ engine: "postgres",
177
+ name: username
178
+ });
179
+ for (const database of databases) {
180
+ const connectSql = `GRANT CONNECT ON DATABASE ${require_commands_db_create_readonly_user_utils.quoteIdent({
181
+ engine: "postgres",
182
+ name: database
183
+ })} TO ${ident}`;
184
+ statements.push(connectSql);
185
+ await query(adminClient, connectSql);
186
+ }
187
+ } finally {
188
+ await adminClient.end();
189
+ }
190
+ for (const database of databases) {
191
+ const dbClient = createClient(config, database);
192
+ await dbClient.connect();
193
+ try {
194
+ if (verbose) console.log(` Granting read-only in database ${database}`);
195
+ const dbStatements = await grantReadonlyInDatabase(dbClient, { username });
196
+ statements.push(...dbStatements);
197
+ } finally {
198
+ await dbClient.end();
199
+ }
200
+ }
201
+ return {
202
+ created,
203
+ statements,
204
+ databases
205
+ };
206
+ }
207
+ //#endregion
208
+ exports.applyPostgresReadonly = applyPostgresReadonly;
209
+ exports.listPostgresDatabases = listPostgresDatabases;
@@ -1,12 +1,39 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
-
4
-
5
-
6
- var _H74JSDBUcjs = require('../../../__chunks/H74JSDBU.cjs');
7
-
8
-
9
-
10
-
11
-
12
- exports.DEFAULT_MYSQL_HOST_PATTERN = _H74JSDBUcjs.DEFAULT_MYSQL_HOST_PATTERN; exports.DEFAULT_READONLY_USERNAME = _H74JSDBUcjs.DEFAULT_READONLY_USERNAME; exports.ENGINES = _H74JSDBUcjs.ENGINES; exports.createReadonlyUserOptionsSchema = _H74JSDBUcjs.createReadonlyUserOptionsSchema;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let zod = require("zod");
3
+ //#region src/commands/db/create-readonly-user/schema.js
4
+ /**
5
+ * Supported database engines.
6
+ * @type {readonly ["postgres", "mysql"]}
7
+ */
8
+ const ENGINES = ["postgres", "mysql"];
9
+ /**
10
+ * Zod schema for `db create-readonly-user` options.
11
+ */
12
+ const createReadonlyUserOptionsSchema = zod.z.object({
13
+ engine: zod.z.enum(["postgres", "mysql"]).optional().describe("Database engine (postgres or mysql); inferred from --url when omitted"),
14
+ url: zod.z.string().optional().describe("Admin connection URL (postgres://… or mysql://…). Defaults to DATABASE_URL / MYSQL_URL / POSTGRES_URL."),
15
+ database: zod.z.string().optional().describe("Target database name, or \"all\" for every non-system database"),
16
+ username: zod.z.string().optional().describe("Read-only username to create (default: readonly)"),
17
+ password: zod.z.string().optional().describe("Password for the new user (generated when omitted)"),
18
+ hostPattern: zod.z.string().optional().describe("MySQL user host pattern (default: %)"),
19
+ ssl: zod.z.boolean().optional().describe("Force SSL on/off. Default: off for localhost, on (loose) for remote hosts."),
20
+ yes: zod.z.boolean().optional().default(false).describe("Skip the confirmation prompt"),
21
+ dryRun: zod.z.boolean().optional().default(false).describe("Print the SQL plan without applying it"),
22
+ verbose: zod.z.boolean().optional().default(false).describe("Enable verbose logging")
23
+ });
24
+ /**
25
+ * @typedef {z.infer<typeof createReadonlyUserOptionsSchema>} CreateReadonlyUserOptions
26
+ */
27
+ /**
28
+ * Default username when none is provided.
29
+ */
30
+ const DEFAULT_READONLY_USERNAME = "readonly";
31
+ /**
32
+ * Default MySQL host pattern (any client host).
33
+ */
34
+ const DEFAULT_MYSQL_HOST_PATTERN = "%";
35
+ //#endregion
36
+ exports.DEFAULT_MYSQL_HOST_PATTERN = DEFAULT_MYSQL_HOST_PATTERN;
37
+ exports.DEFAULT_READONLY_USERNAME = DEFAULT_READONLY_USERNAME;
38
+ exports.ENGINES = ENGINES;
39
+ exports.createReadonlyUserOptionsSchema = createReadonlyUserOptionsSchema;
@@ -1,22 +1,160 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
- var _NWZGFHKHcjs = require('../../../__chunks/NWZGFHKH.cjs');
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
- exports.buildReadonlyUrl = _NWZGFHKHcjs.buildReadonlyUrl; exports.detectEngineFromUrl = _NWZGFHKHcjs.detectEngineFromUrl; exports.generatePassword = _NWZGFHKHcjs.generatePassword; exports.isSystemDatabase = _NWZGFHKHcjs.isSystemDatabase; exports.parseConnectionUrl = _NWZGFHKHcjs.parseConnectionUrl; exports.quoteIdent = _NWZGFHKHcjs.quoteIdent; exports.quoteLiteral = _NWZGFHKHcjs.quoteLiteral; exports.resolveAdminUrl = _NWZGFHKHcjs.resolveAdminUrl; exports.resolveSsl = _NWZGFHKHcjs.resolveSsl;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let crypto = require("crypto");
3
+ //#region src/commands/db/create-readonly-user/utils.js
4
+ /**
5
+ * @typedef {"postgres" | "mysql"} Engine
6
+ */
7
+ /**
8
+ * @typedef {Object} ConnectionConfig
9
+ * @property {Engine} engine
10
+ * @property {string} host
11
+ * @property {number} port
12
+ * @property {string} user
13
+ * @property {string} password
14
+ * @property {string} database
15
+ * @property {boolean | object} ssl
16
+ * @property {string} [url]
17
+ */
18
+ /**
19
+ * Generate a URL-safe random password.
20
+ * @param {{ length?: number }} [params]
21
+ * @returns {string}
22
+ */
23
+ function generatePassword(params = {}) {
24
+ const { length = 24 } = params;
25
+ const alphabet = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*";
26
+ const bytes = (0, crypto.randomBytes)(length);
27
+ let result = "";
28
+ for (let i = 0; i < length; i += 1) {
29
+ const byte = bytes[i] ?? 0;
30
+ result += alphabet[byte % 65];
31
+ }
32
+ return result;
33
+ }
34
+ /**
35
+ * Detect engine from a connection URL scheme.
36
+ * @param {string} url
37
+ * @returns {Engine | null}
38
+ */
39
+ function detectEngineFromUrl(url) {
40
+ const trimmed = url.trim().toLowerCase();
41
+ if (trimmed.startsWith("postgres://") || trimmed.startsWith("postgresql://")) return "postgres";
42
+ if (trimmed.startsWith("mysql://") || trimmed.startsWith("mysql2://")) return "mysql";
43
+ return null;
44
+ }
45
+ /**
46
+ * Resolve an admin URL from flags / common env vars.
47
+ * @param {{ url?: string; engine?: Engine }} params
48
+ * @returns {string | null}
49
+ */
50
+ function resolveAdminUrl(params) {
51
+ const { url, engine } = params;
52
+ if (url) return url;
53
+ if (engine === "mysql") return process.env.MYSQL_URL ?? process.env.DATABASE_URL ?? process.env.MYSQL_DATABASE_URL ?? null;
54
+ if (engine === "postgres") return process.env.DATABASE_URL ?? process.env.POSTGRES_URL ?? process.env.POSTGRESQL_URL ?? null;
55
+ return process.env.DATABASE_URL ?? process.env.POSTGRES_URL ?? process.env.POSTGRESQL_URL ?? process.env.MYSQL_URL ?? process.env.MYSQL_DATABASE_URL ?? null;
56
+ }
57
+ /**
58
+ * Decide SSL settings: remote hosts get loose SSL by default (RDS-friendly).
59
+ * @param {{ host: string; sslOption?: boolean }} params
60
+ * @returns {boolean | object}
61
+ */
62
+ function resolveSsl(params) {
63
+ const { host, sslOption } = params;
64
+ if (sslOption === true) return { rejectUnauthorized: false };
65
+ if (sslOption === false) return false;
66
+ if (host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "0.0.0.0") return false;
67
+ return { rejectUnauthorized: false };
68
+ }
69
+ /**
70
+ * Parse a postgres/mysql connection URL into a config object.
71
+ * @param {{ url: string; engine?: Engine; sslOption?: boolean }} params
72
+ * @returns {ConnectionConfig}
73
+ */
74
+ function parseConnectionUrl(params) {
75
+ const { url, engine: engineOption, sslOption } = params;
76
+ const engine = engineOption ?? detectEngineFromUrl(url);
77
+ if (!engine) throw new Error(`Could not detect engine from URL. Pass --engine postgres|mysql. URL starts with: ${url.slice(0, 24)}…`);
78
+ let parsed;
79
+ try {
80
+ parsed = new URL(url);
81
+ } catch {
82
+ throw new Error(`Invalid connection URL: ${url}`);
83
+ }
84
+ const defaultPort = engine === "postgres" ? 5432 : 3306;
85
+ const port = parsed.port ? Number.parseInt(parsed.port, 10) : defaultPort;
86
+ const database = decodeURIComponent(parsed.pathname.replace(/^\//, "")) || (engine === "postgres" ? "postgres" : "");
87
+ const host = parsed.hostname || "localhost";
88
+ const user = decodeURIComponent(parsed.username || "");
89
+ const password = decodeURIComponent(parsed.password || "");
90
+ if (!user) throw new Error("Connection URL is missing a username");
91
+ return {
92
+ engine,
93
+ host,
94
+ port: Number.isFinite(port) ? port : defaultPort,
95
+ user,
96
+ password,
97
+ database,
98
+ ssl: resolveSsl({
99
+ host,
100
+ sslOption
101
+ }),
102
+ url
103
+ };
104
+ }
105
+ /**
106
+ * Build a client connection URL for the new read-only user.
107
+ * @param {{
108
+ * engine: Engine;
109
+ * host: string;
110
+ * port: number;
111
+ * username: string;
112
+ * password: string;
113
+ * database: string;
114
+ * }} params
115
+ * @returns {string}
116
+ */
117
+ function buildReadonlyUrl(params) {
118
+ const { engine, host, port, username, password, database } = params;
119
+ return `${engine === "postgres" ? "postgresql" : "mysql"}://${`${encodeURIComponent(username)}:${encodeURIComponent(password)}`}@${host}:${port}${database ? `/${encodeURIComponent(database)}` : "/"}`;
120
+ }
121
+ /**
122
+ * Quote an identifier for the given engine (not for string literals).
123
+ * @param {{ engine: Engine; name: string }} params
124
+ * @returns {string}
125
+ */
126
+ function quoteIdent(params) {
127
+ const { engine, name } = params;
128
+ if (engine === "postgres") return `"${name.replace(/"/g, "\"\"")}"`;
129
+ return `\`${name.replace(/`/g, "``")}\``;
130
+ }
131
+ /**
132
+ * Escape a string literal for SQL (single-quote doubling).
133
+ * Prefer parameterized queries when the driver supports them for DDL.
134
+ * @param {string} value
135
+ * @returns {string}
136
+ */
137
+ function quoteLiteral(value) {
138
+ return `'${value.replace(/'/g, "''")}'`;
139
+ }
140
+ /**
141
+ * System / template databases to skip when granting "all".
142
+ * @param {{ engine: Engine; name: string }} params
143
+ * @returns {boolean}
144
+ */
145
+ function isSystemDatabase(params) {
146
+ const { engine, name } = params;
147
+ const lower = name.toLowerCase();
148
+ if (engine === "postgres") return lower === "template0" || lower === "template1" || lower === "rdsadmin" || lower === "cloudsqladmin";
149
+ return lower === "information_schema" || lower === "performance_schema" || lower === "mysql" || lower === "sys" || lower === "innodb" || lower === "#mysql50#lost+found";
150
+ }
151
+ //#endregion
152
+ exports.buildReadonlyUrl = buildReadonlyUrl;
153
+ exports.detectEngineFromUrl = detectEngineFromUrl;
154
+ exports.generatePassword = generatePassword;
155
+ exports.isSystemDatabase = isSystemDatabase;
156
+ exports.parseConnectionUrl = parseConnectionUrl;
157
+ exports.quoteIdent = quoteIdent;
158
+ exports.quoteLiteral = quoteLiteral;
159
+ exports.resolveAdminUrl = resolveAdminUrl;
160
+ exports.resolveSsl = resolveSsl;
@@ -1,44 +1,46 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
- var _DTQ2LB3Icjs = require('../../__chunks/DTQ2LB3I.cjs');
4
- require('../../__chunks/W6K7BV74.cjs');
5
-
6
-
7
- var _LXDF5QVZcjs = require('../../__chunks/LXDF5QVZ.cjs');
8
- require('../../__chunks/3A5ZYU5M.cjs');
9
- require('../../__chunks/K4QNHRTP.cjs');
10
-
11
-
12
-
13
-
14
-
15
- var _H74JSDBUcjs = require('../../__chunks/H74JSDBU.cjs');
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
- var _NWZGFHKHcjs = require('../../__chunks/NWZGFHKH.cjs');
27
- require('../../__chunks/CMUD7LLN.cjs');
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
- exports.DEFAULT_MYSQL_HOST_PATTERN = _H74JSDBUcjs.DEFAULT_MYSQL_HOST_PATTERN; exports.DEFAULT_READONLY_USERNAME = _H74JSDBUcjs.DEFAULT_READONLY_USERNAME; exports.ENGINES = _H74JSDBUcjs.ENGINES; exports.buildReadonlyUrl = _NWZGFHKHcjs.buildReadonlyUrl; exports.createReadonlyUserCommand = _LXDF5QVZcjs.createReadonlyUserCommand; exports.createReadonlyUserOptionsSchema = _H74JSDBUcjs.createReadonlyUserOptionsSchema; exports.detectEngineFromUrl = _NWZGFHKHcjs.detectEngineFromUrl; exports.generatePassword = _NWZGFHKHcjs.generatePassword; exports.isSystemDatabase = _NWZGFHKHcjs.isSystemDatabase; exports.parseConnectionUrl = _NWZGFHKHcjs.parseConnectionUrl; exports.quoteIdent = _NWZGFHKHcjs.quoteIdent; exports.quoteLiteral = _NWZGFHKHcjs.quoteLiteral; exports.registerDbCommands = _DTQ2LB3Icjs.registerDbCommands; exports.resolveAdminUrl = _NWZGFHKHcjs.resolveAdminUrl; exports.resolveSsl = _NWZGFHKHcjs.resolveSsl;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_commands_db_create_readonly_user_utils = require("./create-readonly-user/utils.cjs");
3
+ const require_commands_db_create_readonly_user_schema = require("./create-readonly-user/schema.cjs");
4
+ const require_commands_db_create_readonly_user_handler = require("./create-readonly-user/handler.cjs");
5
+ require("./create-readonly-user/index.cjs");
6
+ //#region src/commands/db/index.js
7
+ /**
8
+ * Register the `db` command group and its subcommands on the root program.
9
+ * @param {import('commander').Command} program
10
+ */
11
+ function registerDbCommands(program) {
12
+ program.command("db").summary("Database operational commands").description("Database operational helpers (MySQL and Postgres)").command("create-readonly-user").summary("Create a read-only database user").description("Create (or update) a read-only database user on MySQL or Postgres. Interactively pick a single database or all databases, then print a connection URL.").option("-e, --engine <engine>", "Database engine: postgres or mysql (inferred from --url when omitted)").option("-u, --url <url>", "Admin connection URL (defaults to DATABASE_URL / MYSQL_URL / POSTGRES_URL)").option("-d, --database <name>", "Target database name, or \"all\" for every non-system database").option("--username <name>", "Read-only username to create (default: readonly)").option("--password <password>", "Password for the new user (generated when omitted)").option("--host-pattern <pattern>", "MySQL user host pattern (default: %)").option("--ssl", "Force SSL on (loose verify — useful for RDS)").option("--no-ssl", "Force SSL off").option("-y, --yes", "Skip the confirmation prompt").option("--dry-run", "Print the SQL plan without applying it").option("-v, --verbose", "Enable verbose logging").action(async (options) => {
13
+ /** @type {boolean | undefined} */
14
+ let ssl;
15
+ if (options.ssl === true) ssl = true;
16
+ else if (options.noSsl === true) ssl = false;
17
+ await require_commands_db_create_readonly_user_handler.createReadonlyUserCommand({
18
+ engine: options.engine,
19
+ url: options.url,
20
+ database: options.database,
21
+ username: options.username,
22
+ password: options.password,
23
+ hostPattern: options.hostPattern,
24
+ ssl,
25
+ yes: options.yes ?? false,
26
+ dryRun: options.dryRun ?? false,
27
+ verbose: options.verbose ?? false
28
+ });
29
+ });
30
+ }
31
+ //#endregion
32
+ exports.DEFAULT_MYSQL_HOST_PATTERN = require_commands_db_create_readonly_user_schema.DEFAULT_MYSQL_HOST_PATTERN;
33
+ exports.DEFAULT_READONLY_USERNAME = require_commands_db_create_readonly_user_schema.DEFAULT_READONLY_USERNAME;
34
+ exports.ENGINES = require_commands_db_create_readonly_user_schema.ENGINES;
35
+ exports.buildReadonlyUrl = require_commands_db_create_readonly_user_utils.buildReadonlyUrl;
36
+ exports.createReadonlyUserCommand = require_commands_db_create_readonly_user_handler.createReadonlyUserCommand;
37
+ exports.createReadonlyUserOptionsSchema = require_commands_db_create_readonly_user_schema.createReadonlyUserOptionsSchema;
38
+ exports.detectEngineFromUrl = require_commands_db_create_readonly_user_utils.detectEngineFromUrl;
39
+ exports.generatePassword = require_commands_db_create_readonly_user_utils.generatePassword;
40
+ exports.isSystemDatabase = require_commands_db_create_readonly_user_utils.isSystemDatabase;
41
+ exports.parseConnectionUrl = require_commands_db_create_readonly_user_utils.parseConnectionUrl;
42
+ exports.quoteIdent = require_commands_db_create_readonly_user_utils.quoteIdent;
43
+ exports.quoteLiteral = require_commands_db_create_readonly_user_utils.quoteLiteral;
44
+ exports.registerDbCommands = registerDbCommands;
45
+ exports.resolveAdminUrl = require_commands_db_create_readonly_user_utils.resolveAdminUrl;
46
+ exports.resolveSsl = require_commands_db_create_readonly_user_utils.resolveSsl;
@@ -1,11 +1,95 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
- var _GU3R54MKcjs = require('../../__chunks/GU3R54MK.cjs');
4
- require('../../__chunks/NFXQNOQH.cjs');
5
- require('../../__chunks/JB7T7PKQ.cjs');
6
- require('../../__chunks/CMUD7LLN.cjs');
7
- require('../../__chunks/NIMXXHJQ.cjs');
8
- require('../../__chunks/FRHST54J.cjs');
9
-
10
-
11
- exports.dopplerCommand = _GU3R54MKcjs.dopplerCommand;
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_rolldown_runtime = require("../../__chunks/VH7oDXx4.cjs");
3
+ const require_commands_doppler_schema = require("./schema.cjs");
4
+ const require_commands_doppler_utils = require("./utils.cjs");
5
+ const require_commands_doppler_set_secret = require("./set-secret.cjs");
6
+ let chalk = require("chalk");
7
+ chalk = require_rolldown_runtime.__toESM(chalk, 1);
8
+ let zod = require("zod");
9
+ //#region src/commands/doppler/handler.js
10
+ /**
11
+ * Main doppler command handler
12
+ * @param {unknown} options - Command options (will be validated)
13
+ */
14
+ async function dopplerCommand(options) {
15
+ try {
16
+ const rawOptions = options ?? {};
17
+ if (rawOptions.help || !rawOptions.action) {
18
+ console.log(chalk.default.bold(`\nUsage: @mtndev/cli doppler [options] <action>`));
19
+ console.log(require_commands_doppler_schema.dopplerCommandMetadata.description);
20
+ console.log(chalk.default.bold("\nOptions:"));
21
+ Object.entries(require_commands_doppler_schema.dopplerCommandMetadata.options).forEach(([key, optionMeta]) => {
22
+ const meta = optionMeta;
23
+ const alias = meta?.alias ? chalk.default.cyan(`, -${meta.alias}`) : "";
24
+ const defaultValue = meta?.default ?? false;
25
+ console.log(chalk.default.cyan(` --${key}`) + alias + ` ${meta.description} (default: ${defaultValue})`);
26
+ });
27
+ console.log("");
28
+ return;
29
+ }
30
+ const validatedOptions = require_commands_doppler_schema.dopplerCommandOptionsSchema.parse(options);
31
+ const { action, verbose } = validatedOptions;
32
+ if (action === "set") require_commands_doppler_utils.checkDopplerAuth(verbose);
33
+ else require_commands_doppler_utils.checkDependencies(verbose);
34
+ if (action === "download") {
35
+ const { environments } = validatedOptions;
36
+ await require_commands_doppler_utils.downloadConfigs({
37
+ environments,
38
+ verbose
39
+ });
40
+ } else if (action === "upload") {
41
+ const { environments } = validatedOptions;
42
+ await require_commands_doppler_utils.uploadConfigs({
43
+ environments,
44
+ verbose
45
+ });
46
+ } else if (action === "clone") {
47
+ const { from, to, force, environments } = validatedOptions;
48
+ await require_commands_doppler_utils.cloneProject({
49
+ from,
50
+ to,
51
+ environments,
52
+ force,
53
+ verbose
54
+ });
55
+ } else if (action === "set") {
56
+ const { project, environment, config, name, value, yes } = validatedOptions;
57
+ await require_commands_doppler_set_secret.setSecretInteractive({
58
+ project,
59
+ environment,
60
+ config,
61
+ name,
62
+ value,
63
+ yes,
64
+ verbose
65
+ });
66
+ }
67
+ console.log(chalk.default.green(`\n✅ Doppler ${action} completed successfully!`));
68
+ } catch (error) {
69
+ if (error instanceof zod.ZodError) {
70
+ console.error(chalk.default.red(`\n❌ Invalid command options:`));
71
+ error.errors.forEach((err) => {
72
+ console.error(chalk.default.red(` ${err.path.join(".")}: ${err.message}`));
73
+ });
74
+ process.exit(1);
75
+ }
76
+ const action = options?.action || "operation";
77
+ const verbose = options?.verbose || false;
78
+ console.error(chalk.default.red(`\n❌ Doppler ${action} failed:`));
79
+ if (error instanceof Error) {
80
+ console.error(chalk.default.red(` ${error.message}`));
81
+ if (verbose && error.stack) {
82
+ console.error(chalk.default.gray("\nStack trace:"));
83
+ console.error(chalk.default.gray(error.stack));
84
+ }
85
+ } else console.error(chalk.default.red(` ${String(error)}`));
86
+ console.error(chalk.default.yellow("\n💡 Troubleshooting tips:"));
87
+ console.error(chalk.default.yellow(" • Ensure Doppler CLI is installed (brew install dopplerhq/cli/doppler)"));
88
+ console.error(chalk.default.yellow(" • Make sure you're logged in (doppler login)"));
89
+ console.error(chalk.default.yellow(" • Verify project is configured (doppler setup)"));
90
+ console.error(chalk.default.yellow(" • Use --verbose for detailed error information\n"));
91
+ process.exit(1);
92
+ }
93
+ }
94
+ //#endregion
95
+ exports.dopplerCommand = dopplerCommand;