@stacksjs/ts-cloud-core 0.1.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 (251) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +321 -0
  3. package/package.json +31 -0
  4. package/src/advanced-features.test.ts +465 -0
  5. package/src/aws/cloudformation.ts +421 -0
  6. package/src/aws/cloudfront.ts +158 -0
  7. package/src/aws/credentials.test.ts +132 -0
  8. package/src/aws/credentials.ts +545 -0
  9. package/src/aws/index.ts +87 -0
  10. package/src/aws/s3.test.ts +188 -0
  11. package/src/aws/s3.ts +1088 -0
  12. package/src/aws/signature.test.ts +670 -0
  13. package/src/aws/signature.ts +1155 -0
  14. package/src/backup/disaster-recovery.test.ts +726 -0
  15. package/src/backup/disaster-recovery.ts +500 -0
  16. package/src/backup/index.ts +34 -0
  17. package/src/backup/manager.test.ts +498 -0
  18. package/src/backup/manager.ts +432 -0
  19. package/src/cicd/circleci.ts +430 -0
  20. package/src/cicd/github-actions.ts +424 -0
  21. package/src/cicd/gitlab-ci.ts +255 -0
  22. package/src/cicd/index.ts +8 -0
  23. package/src/cli/history.ts +396 -0
  24. package/src/cli/index.ts +10 -0
  25. package/src/cli/progress.ts +458 -0
  26. package/src/cli/repl.ts +454 -0
  27. package/src/cli/suggestions.ts +327 -0
  28. package/src/cli/table.test.ts +319 -0
  29. package/src/cli/table.ts +332 -0
  30. package/src/cloudformation/builder.test.ts +327 -0
  31. package/src/cloudformation/builder.ts +378 -0
  32. package/src/cloudformation/builders/api-gateway.ts +449 -0
  33. package/src/cloudformation/builders/cache.ts +334 -0
  34. package/src/cloudformation/builders/cdn.ts +278 -0
  35. package/src/cloudformation/builders/compute.ts +485 -0
  36. package/src/cloudformation/builders/database.ts +392 -0
  37. package/src/cloudformation/builders/functions.ts +343 -0
  38. package/src/cloudformation/builders/messaging.ts +140 -0
  39. package/src/cloudformation/builders/monitoring.ts +300 -0
  40. package/src/cloudformation/builders/network.ts +264 -0
  41. package/src/cloudformation/builders/queue.ts +147 -0
  42. package/src/cloudformation/builders/security.ts +399 -0
  43. package/src/cloudformation/builders/storage.ts +285 -0
  44. package/src/cloudformation/index.ts +30 -0
  45. package/src/cloudformation/types.ts +173 -0
  46. package/src/compliance/aws-config.ts +543 -0
  47. package/src/compliance/cloudtrail.ts +376 -0
  48. package/src/compliance/compliance.test.ts +423 -0
  49. package/src/compliance/guardduty.ts +446 -0
  50. package/src/compliance/index.ts +66 -0
  51. package/src/compliance/security-hub.ts +456 -0
  52. package/src/containers/build-optimization.ts +416 -0
  53. package/src/containers/containers.test.ts +508 -0
  54. package/src/containers/image-scanning.ts +360 -0
  55. package/src/containers/index.ts +9 -0
  56. package/src/containers/registry.ts +293 -0
  57. package/src/containers/service-mesh.ts +520 -0
  58. package/src/database/database.test.ts +762 -0
  59. package/src/database/index.ts +9 -0
  60. package/src/database/migrations.ts +444 -0
  61. package/src/database/performance.ts +528 -0
  62. package/src/database/replicas.ts +534 -0
  63. package/src/database/users.ts +494 -0
  64. package/src/dependency-graph.ts +143 -0
  65. package/src/deployment/ab-testing.ts +582 -0
  66. package/src/deployment/blue-green.ts +452 -0
  67. package/src/deployment/canary.ts +500 -0
  68. package/src/deployment/deployment.test.ts +526 -0
  69. package/src/deployment/index.ts +61 -0
  70. package/src/deployment/progressive.ts +62 -0
  71. package/src/dns/dns.test.ts +641 -0
  72. package/src/dns/dnssec.ts +315 -0
  73. package/src/dns/index.ts +8 -0
  74. package/src/dns/resolver.ts +496 -0
  75. package/src/dns/routing.ts +593 -0
  76. package/src/email/advanced/analytics.ts +445 -0
  77. package/src/email/advanced/index.ts +11 -0
  78. package/src/email/advanced/rules.ts +465 -0
  79. package/src/email/advanced/scheduling.ts +352 -0
  80. package/src/email/advanced/search.ts +412 -0
  81. package/src/email/advanced/shared-mailboxes.ts +404 -0
  82. package/src/email/advanced/templates.ts +455 -0
  83. package/src/email/advanced/threading.ts +281 -0
  84. package/src/email/analytics.ts +467 -0
  85. package/src/email/bounce-handling.ts +425 -0
  86. package/src/email/email.test.ts +431 -0
  87. package/src/email/handlers/__tests__/inbound.test.ts +38 -0
  88. package/src/email/handlers/__tests__/outbound.test.ts +37 -0
  89. package/src/email/handlers/converter.ts +227 -0
  90. package/src/email/handlers/feedback.ts +228 -0
  91. package/src/email/handlers/inbound.ts +169 -0
  92. package/src/email/handlers/outbound.ts +178 -0
  93. package/src/email/index.ts +15 -0
  94. package/src/email/reputation.ts +303 -0
  95. package/src/email/templates.ts +352 -0
  96. package/src/errors/index.test.ts +434 -0
  97. package/src/errors/index.ts +416 -0
  98. package/src/health-checks/index.ts +40 -0
  99. package/src/index.ts +360 -0
  100. package/src/intrinsic-functions.ts +118 -0
  101. package/src/lambda/concurrency.ts +330 -0
  102. package/src/lambda/destinations.ts +345 -0
  103. package/src/lambda/dlq.ts +425 -0
  104. package/src/lambda/index.ts +11 -0
  105. package/src/lambda/lambda.test.ts +840 -0
  106. package/src/lambda/layers.ts +263 -0
  107. package/src/lambda/versions.ts +376 -0
  108. package/src/lambda/vpc.ts +399 -0
  109. package/src/local/config.ts +114 -0
  110. package/src/local/index.ts +6 -0
  111. package/src/local/mock-aws.ts +351 -0
  112. package/src/modules/ai.ts +340 -0
  113. package/src/modules/api.ts +478 -0
  114. package/src/modules/auth.ts +805 -0
  115. package/src/modules/cache.ts +417 -0
  116. package/src/modules/cdn.ts +1062 -0
  117. package/src/modules/communication.ts +1094 -0
  118. package/src/modules/compute.ts +3348 -0
  119. package/src/modules/database.ts +554 -0
  120. package/src/modules/deployment.ts +1079 -0
  121. package/src/modules/dns.ts +337 -0
  122. package/src/modules/email.ts +1538 -0
  123. package/src/modules/filesystem.ts +515 -0
  124. package/src/modules/index.ts +32 -0
  125. package/src/modules/messaging.ts +486 -0
  126. package/src/modules/monitoring.ts +2086 -0
  127. package/src/modules/network.ts +664 -0
  128. package/src/modules/parameter-store.ts +325 -0
  129. package/src/modules/permissions.ts +1081 -0
  130. package/src/modules/phone.ts +494 -0
  131. package/src/modules/queue.ts +1260 -0
  132. package/src/modules/redirects.ts +464 -0
  133. package/src/modules/registry.ts +699 -0
  134. package/src/modules/search.ts +401 -0
  135. package/src/modules/secrets.ts +416 -0
  136. package/src/modules/security.ts +731 -0
  137. package/src/modules/sms.ts +389 -0
  138. package/src/modules/storage.ts +1120 -0
  139. package/src/modules/workflow.ts +680 -0
  140. package/src/multi-account/config.ts +521 -0
  141. package/src/multi-account/index.ts +7 -0
  142. package/src/multi-account/manager.ts +427 -0
  143. package/src/multi-region/cross-region.ts +410 -0
  144. package/src/multi-region/index.ts +8 -0
  145. package/src/multi-region/manager.ts +483 -0
  146. package/src/multi-region/regions.ts +435 -0
  147. package/src/network-security/index.ts +48 -0
  148. package/src/observability/index.ts +9 -0
  149. package/src/observability/logs.ts +522 -0
  150. package/src/observability/metrics.ts +460 -0
  151. package/src/observability/observability.test.ts +782 -0
  152. package/src/observability/synthetics.ts +568 -0
  153. package/src/observability/xray.ts +358 -0
  154. package/src/phone/advanced/analytics.ts +349 -0
  155. package/src/phone/advanced/callbacks.ts +428 -0
  156. package/src/phone/advanced/index.ts +8 -0
  157. package/src/phone/advanced/ivr-builder.ts +504 -0
  158. package/src/phone/advanced/recording.ts +310 -0
  159. package/src/phone/handlers/__tests__/incoming-call.test.ts +40 -0
  160. package/src/phone/handlers/incoming-call.ts +117 -0
  161. package/src/phone/handlers/missed-call.ts +116 -0
  162. package/src/phone/handlers/voicemail.ts +179 -0
  163. package/src/phone/index.ts +9 -0
  164. package/src/presets/api-backend.ts +134 -0
  165. package/src/presets/data-pipeline.ts +204 -0
  166. package/src/presets/extend.test.ts +295 -0
  167. package/src/presets/extend.ts +297 -0
  168. package/src/presets/fullstack-app.ts +144 -0
  169. package/src/presets/index.ts +27 -0
  170. package/src/presets/jamstack.ts +135 -0
  171. package/src/presets/microservices.ts +167 -0
  172. package/src/presets/ml-api.ts +208 -0
  173. package/src/presets/nodejs-server.ts +104 -0
  174. package/src/presets/nodejs-serverless.ts +114 -0
  175. package/src/presets/realtime-app.ts +184 -0
  176. package/src/presets/static-site.ts +64 -0
  177. package/src/presets/traditional-web-app.ts +339 -0
  178. package/src/presets/wordpress.ts +138 -0
  179. package/src/preview/github.test.ts +249 -0
  180. package/src/preview/github.ts +297 -0
  181. package/src/preview/index.ts +37 -0
  182. package/src/preview/manager.test.ts +440 -0
  183. package/src/preview/manager.ts +326 -0
  184. package/src/preview/notifications.test.ts +582 -0
  185. package/src/preview/notifications.ts +341 -0
  186. package/src/queue/batch-processing.ts +402 -0
  187. package/src/queue/dlq-monitoring.ts +402 -0
  188. package/src/queue/fifo.ts +342 -0
  189. package/src/queue/index.ts +9 -0
  190. package/src/queue/management.ts +428 -0
  191. package/src/queue/queue.test.ts +429 -0
  192. package/src/resource-mgmt/index.ts +39 -0
  193. package/src/resource-naming.ts +62 -0
  194. package/src/s3/index.ts +523 -0
  195. package/src/schema/cloud-config.schema.json +554 -0
  196. package/src/schema/index.ts +68 -0
  197. package/src/security/certificate-manager.ts +492 -0
  198. package/src/security/index.ts +9 -0
  199. package/src/security/scanning.ts +545 -0
  200. package/src/security/secrets-manager.ts +476 -0
  201. package/src/security/secrets-rotation.ts +456 -0
  202. package/src/security/security.test.ts +738 -0
  203. package/src/sms/advanced/ab-testing.ts +389 -0
  204. package/src/sms/advanced/analytics.ts +336 -0
  205. package/src/sms/advanced/campaigns.ts +523 -0
  206. package/src/sms/advanced/chatbot.ts +224 -0
  207. package/src/sms/advanced/index.ts +10 -0
  208. package/src/sms/advanced/link-tracking.ts +248 -0
  209. package/src/sms/advanced/mms.ts +308 -0
  210. package/src/sms/handlers/__tests__/send.test.ts +40 -0
  211. package/src/sms/handlers/delivery-status.ts +133 -0
  212. package/src/sms/handlers/receive.ts +162 -0
  213. package/src/sms/handlers/send.ts +174 -0
  214. package/src/sms/index.ts +9 -0
  215. package/src/stack-diff.ts +389 -0
  216. package/src/static-site/index.ts +85 -0
  217. package/src/template-builder.ts +110 -0
  218. package/src/template-validator.ts +574 -0
  219. package/src/utils/cache.ts +291 -0
  220. package/src/utils/diff.ts +269 -0
  221. package/src/utils/hash.ts +227 -0
  222. package/src/utils/index.ts +8 -0
  223. package/src/utils/parallel.ts +294 -0
  224. package/src/validators/credentials.test.ts +274 -0
  225. package/src/validators/credentials.ts +233 -0
  226. package/src/validators/quotas.test.ts +434 -0
  227. package/src/validators/quotas.ts +217 -0
  228. package/test/ai.test.ts +327 -0
  229. package/test/api.test.ts +511 -0
  230. package/test/auth.test.ts +632 -0
  231. package/test/cache.test.ts +406 -0
  232. package/test/cdn.test.ts +247 -0
  233. package/test/compute.test.ts +861 -0
  234. package/test/database.test.ts +523 -0
  235. package/test/deployment.test.ts +499 -0
  236. package/test/dns.test.ts +270 -0
  237. package/test/email.test.ts +439 -0
  238. package/test/filesystem.test.ts +382 -0
  239. package/test/integration.test.ts +350 -0
  240. package/test/messaging.test.ts +514 -0
  241. package/test/monitoring.test.ts +634 -0
  242. package/test/network.test.ts +425 -0
  243. package/test/permissions.test.ts +488 -0
  244. package/test/queue.test.ts +484 -0
  245. package/test/registry.test.ts +306 -0
  246. package/test/security.test.ts +462 -0
  247. package/test/storage.test.ts +463 -0
  248. package/test/template-validator.test.ts +559 -0
  249. package/test/workflow.test.ts +592 -0
  250. package/tsconfig.json +16 -0
  251. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,476 @@
1
+ /**
2
+ * Secrets Management
3
+ * Versioning, audit logging, and external secret manager integration
4
+ */
5
+
6
+ export interface SecretVersion {
7
+ id: string
8
+ secretId: string
9
+ versionId: string
10
+ versionStages: string[] // AWSCURRENT, AWSPENDING, AWSPREVIOUS
11
+ value?: string
12
+ createdAt: Date
13
+ deprecatedAt?: Date
14
+ }
15
+
16
+ export interface SecretAudit {
17
+ id: string
18
+ secretId: string
19
+ action: SecretAction
20
+ actor: string
21
+ versionId?: string
22
+ timestamp: Date
23
+ ipAddress?: string
24
+ userAgent?: string
25
+ success: boolean
26
+ error?: string
27
+ }
28
+
29
+ export type SecretAction =
30
+ | 'CREATE'
31
+ | 'READ'
32
+ | 'UPDATE'
33
+ | 'DELETE'
34
+ | 'ROTATE'
35
+ | 'RESTORE'
36
+ | 'REPLICATE'
37
+
38
+ export interface ExternalSecretManager {
39
+ id: string
40
+ type: 'vault' | 'onepassword' | 'azure_keyvault' | 'gcp_secretmanager'
41
+ name: string
42
+ endpoint?: string
43
+ authentication: ExternalAuthConfig
44
+ syncEnabled?: boolean
45
+ syncInterval?: number // minutes
46
+ }
47
+
48
+ export interface ExternalAuthConfig {
49
+ type: 'token' | 'iam' | 'certificate' | 'apikey'
50
+ credentials?: Record<string, string>
51
+ roleArn?: string
52
+ certificateArn?: string
53
+ }
54
+
55
+ export interface SecretReplication {
56
+ id: string
57
+ secretId: string
58
+ sourceRegion: string
59
+ replicaRegions: string[]
60
+ kmsKeyIds?: Record<string, string> // region -> KMS key ID
61
+ status: 'replicating' | 'completed' | 'failed'
62
+ }
63
+
64
+ export interface SecretPolicy {
65
+ id: string
66
+ secretId: string
67
+ policy: PolicyDocument
68
+ }
69
+
70
+ export interface PolicyDocument {
71
+ Version: string
72
+ Statement: PolicyStatement[]
73
+ }
74
+
75
+ export interface PolicyStatement {
76
+ Effect: 'Allow' | 'Deny'
77
+ Principal: {
78
+ AWS?: string | string[]
79
+ Service?: string | string[]
80
+ }
81
+ Action: string | string[]
82
+ Resource?: string | string[]
83
+ Condition?: Record<string, any>
84
+ }
85
+
86
+ /**
87
+ * Secrets manager
88
+ */
89
+ export class SecretsManager {
90
+ private versions: Map<string, SecretVersion> = new Map()
91
+ private audits: Map<string, SecretAudit> = new Map()
92
+ private externalManagers: Map<string, ExternalSecretManager> = new Map()
93
+ private replications: Map<string, SecretReplication> = new Map()
94
+ private policies: Map<string, SecretPolicy> = new Map()
95
+ private versionCounter = 0
96
+ private auditCounter = 0
97
+ private managerCounter = 0
98
+ private replicationCounter = 0
99
+ private policyCounter = 0
100
+
101
+ /**
102
+ * Create secret version
103
+ */
104
+ createVersion(version: Omit<SecretVersion, 'id'>): SecretVersion {
105
+ const id = `version-${Date.now()}-${this.versionCounter++}`
106
+
107
+ const secretVersion: SecretVersion = {
108
+ id,
109
+ ...version,
110
+ }
111
+
112
+ this.versions.set(id, secretVersion)
113
+
114
+ // Audit the action
115
+ this.auditAction({
116
+ secretId: version.secretId,
117
+ action: 'CREATE',
118
+ actor: 'system',
119
+ versionId: version.versionId,
120
+ success: true,
121
+ })
122
+
123
+ return secretVersion
124
+ }
125
+
126
+ /**
127
+ * Get secret version by stage
128
+ */
129
+ getVersionByStage(secretId: string, stage: string): SecretVersion | undefined {
130
+ return Array.from(this.versions.values()).find(
131
+ v => v.secretId === secretId && v.versionStages.includes(stage)
132
+ )
133
+ }
134
+
135
+ /**
136
+ * List versions for secret
137
+ */
138
+ listVersions(secretId: string): SecretVersion[] {
139
+ return Array.from(this.versions.values())
140
+ .filter(v => v.secretId === secretId)
141
+ .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
142
+ }
143
+
144
+ /**
145
+ * Deprecate version
146
+ */
147
+ deprecateVersion(versionId: string): void {
148
+ const version = Array.from(this.versions.values()).find(v => v.versionId === versionId)
149
+
150
+ if (version) {
151
+ version.deprecatedAt = new Date()
152
+ version.versionStages = version.versionStages.filter(s => s !== 'AWSCURRENT')
153
+
154
+ this.auditAction({
155
+ secretId: version.secretId,
156
+ action: 'UPDATE',
157
+ actor: 'system',
158
+ versionId,
159
+ success: true,
160
+ })
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Restore version
166
+ */
167
+ restoreVersion(versionId: string): void {
168
+ const version = Array.from(this.versions.values()).find(v => v.versionId === versionId)
169
+
170
+ if (version) {
171
+ // Remove AWSCURRENT from other versions
172
+ Array.from(this.versions.values())
173
+ .filter(v => v.secretId === version.secretId && v.versionId !== versionId)
174
+ .forEach(v => {
175
+ v.versionStages = v.versionStages.filter(s => s !== 'AWSCURRENT')
176
+ })
177
+
178
+ // Set this version as current
179
+ version.versionStages.push('AWSCURRENT')
180
+ version.deprecatedAt = undefined
181
+
182
+ this.auditAction({
183
+ secretId: version.secretId,
184
+ action: 'RESTORE',
185
+ actor: 'system',
186
+ versionId,
187
+ success: true,
188
+ })
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Audit secret action
194
+ */
195
+ auditAction(audit: Omit<SecretAudit, 'id' | 'timestamp'>): SecretAudit {
196
+ const id = `audit-${Date.now()}-${this.auditCounter++}`
197
+
198
+ const secretAudit: SecretAudit = {
199
+ id,
200
+ timestamp: new Date(),
201
+ ...audit,
202
+ }
203
+
204
+ this.audits.set(id, secretAudit)
205
+
206
+ return secretAudit
207
+ }
208
+
209
+ /**
210
+ * Get audit trail for secret
211
+ */
212
+ getAuditTrail(secretId: string, limit: number = 100): SecretAudit[] {
213
+ return Array.from(this.audits.values())
214
+ .filter(audit => audit.secretId === secretId)
215
+ .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
216
+ .slice(0, limit)
217
+ }
218
+
219
+ /**
220
+ * Get failed access attempts
221
+ */
222
+ getFailedAccesses(secretId: string, hours: number = 24): SecretAudit[] {
223
+ const cutoffTime = Date.now() - hours * 60 * 60 * 1000
224
+
225
+ return Array.from(this.audits.values()).filter(
226
+ audit =>
227
+ audit.secretId === secretId &&
228
+ !audit.success &&
229
+ audit.timestamp.getTime() > cutoffTime
230
+ )
231
+ }
232
+
233
+ /**
234
+ * Register external secret manager
235
+ */
236
+ registerExternalManager(manager: Omit<ExternalSecretManager, 'id'>): ExternalSecretManager {
237
+ const id = `ext-manager-${Date.now()}-${this.managerCounter++}`
238
+
239
+ const externalManager: ExternalSecretManager = {
240
+ id,
241
+ ...manager,
242
+ }
243
+
244
+ this.externalManagers.set(id, externalManager)
245
+
246
+ return externalManager
247
+ }
248
+
249
+ /**
250
+ * Register HashiCorp Vault
251
+ */
252
+ registerVault(options: {
253
+ name: string
254
+ endpoint: string
255
+ token?: string
256
+ roleArn?: string
257
+ syncEnabled?: boolean
258
+ }): ExternalSecretManager {
259
+ return this.registerExternalManager({
260
+ type: 'vault',
261
+ name: options.name,
262
+ endpoint: options.endpoint,
263
+ authentication: {
264
+ type: options.token ? 'token' : 'iam',
265
+ credentials: options.token ? { token: options.token } : undefined,
266
+ roleArn: options.roleArn,
267
+ },
268
+ syncEnabled: options.syncEnabled || false,
269
+ syncInterval: 60,
270
+ })
271
+ }
272
+
273
+ /**
274
+ * Register 1Password
275
+ */
276
+ registerOnePassword(options: {
277
+ name: string
278
+ endpoint?: string
279
+ apiKey: string
280
+ syncEnabled?: boolean
281
+ }): ExternalSecretManager {
282
+ return this.registerExternalManager({
283
+ type: 'onepassword',
284
+ name: options.name,
285
+ endpoint: options.endpoint || 'https://my.1password.com',
286
+ authentication: {
287
+ type: 'apikey',
288
+ credentials: { apiKey: options.apiKey },
289
+ },
290
+ syncEnabled: options.syncEnabled || false,
291
+ syncInterval: 30,
292
+ })
293
+ }
294
+
295
+ /**
296
+ * Enable secret replication
297
+ */
298
+ enableReplication(options: {
299
+ secretId: string
300
+ sourceRegion: string
301
+ replicaRegions: string[]
302
+ kmsKeyIds?: Record<string, string>
303
+ }): SecretReplication {
304
+ const id = `replication-${Date.now()}-${this.replicationCounter++}`
305
+
306
+ const replication: SecretReplication = {
307
+ id,
308
+ secretId: options.secretId,
309
+ sourceRegion: options.sourceRegion,
310
+ replicaRegions: options.replicaRegions,
311
+ kmsKeyIds: options.kmsKeyIds,
312
+ status: 'replicating',
313
+ }
314
+
315
+ this.replications.set(id, replication)
316
+
317
+ this.auditAction({
318
+ secretId: options.secretId,
319
+ action: 'REPLICATE',
320
+ actor: 'system',
321
+ success: true,
322
+ })
323
+
324
+ // Simulate replication
325
+ setTimeout(() => {
326
+ replication.status = 'completed'
327
+ }, 100)
328
+
329
+ return replication
330
+ }
331
+
332
+ /**
333
+ * Create secret policy
334
+ */
335
+ createPolicy(options: {
336
+ secretId: string
337
+ allowedPrincipals: string[]
338
+ allowedActions: string[]
339
+ }): SecretPolicy {
340
+ const id = `policy-${Date.now()}-${this.policyCounter++}`
341
+
342
+ const policy: SecretPolicy = {
343
+ id,
344
+ secretId: options.secretId,
345
+ policy: {
346
+ Version: '2012-10-17',
347
+ Statement: [
348
+ {
349
+ Effect: 'Allow',
350
+ Principal: {
351
+ AWS: options.allowedPrincipals,
352
+ },
353
+ Action: options.allowedActions,
354
+ Resource: '*',
355
+ },
356
+ ],
357
+ },
358
+ }
359
+
360
+ this.policies.set(id, policy)
361
+
362
+ return policy
363
+ }
364
+
365
+ /**
366
+ * Create cross-account access policy
367
+ */
368
+ createCrossAccountPolicy(options: {
369
+ secretId: string
370
+ accountId: string
371
+ roleNames: string[]
372
+ }): SecretPolicy {
373
+ const principals = options.roleNames.map(
374
+ role => `arn:aws:iam::${options.accountId}:role/${role}`
375
+ )
376
+
377
+ return this.createPolicy({
378
+ secretId: options.secretId,
379
+ allowedPrincipals: principals,
380
+ allowedActions: ['secretsmanager:GetSecretValue', 'secretsmanager:DescribeSecret'],
381
+ })
382
+ }
383
+
384
+ /**
385
+ * Get version
386
+ */
387
+ getVersion(id: string): SecretVersion | undefined {
388
+ return this.versions.get(id)
389
+ }
390
+
391
+ /**
392
+ * Get external manager
393
+ */
394
+ getExternalManager(id: string): ExternalSecretManager | undefined {
395
+ return this.externalManagers.get(id)
396
+ }
397
+
398
+ /**
399
+ * List external managers
400
+ */
401
+ listExternalManagers(): ExternalSecretManager[] {
402
+ return Array.from(this.externalManagers.values())
403
+ }
404
+
405
+ /**
406
+ * Get replication
407
+ */
408
+ getReplication(id: string): SecretReplication | undefined {
409
+ return this.replications.get(id)
410
+ }
411
+
412
+ /**
413
+ * List replications
414
+ */
415
+ listReplications(): SecretReplication[] {
416
+ return Array.from(this.replications.values())
417
+ }
418
+
419
+ /**
420
+ * Generate CloudFormation for secret
421
+ */
422
+ generateSecretCF(options: {
423
+ name: string
424
+ description?: string
425
+ kmsKeyId?: string
426
+ replicaRegions?: string[]
427
+ }): any {
428
+ return {
429
+ Type: 'AWS::SecretsManager::Secret',
430
+ Properties: {
431
+ Name: options.name,
432
+ Description: options.description,
433
+ ...(options.kmsKeyId && { KmsKeyId: options.kmsKeyId }),
434
+ ...(options.replicaRegions && {
435
+ ReplicaRegions: options.replicaRegions.map(region => ({
436
+ Region: region,
437
+ })),
438
+ }),
439
+ },
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Generate CloudFormation for secret policy
445
+ */
446
+ generateSecretPolicyCF(policy: SecretPolicy): any {
447
+ return {
448
+ Type: 'AWS::SecretsManager::ResourcePolicy',
449
+ Properties: {
450
+ SecretId: policy.secretId,
451
+ ResourcePolicy: policy.policy,
452
+ },
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Clear all data
458
+ */
459
+ clear(): void {
460
+ this.versions.clear()
461
+ this.audits.clear()
462
+ this.externalManagers.clear()
463
+ this.replications.clear()
464
+ this.policies.clear()
465
+ this.versionCounter = 0
466
+ this.auditCounter = 0
467
+ this.managerCounter = 0
468
+ this.replicationCounter = 0
469
+ this.policyCounter = 0
470
+ }
471
+ }
472
+
473
+ /**
474
+ * Global secrets manager instance
475
+ */
476
+ export const secretsManager: SecretsManager = new SecretsManager()