@standards-kit/conform 0.1.0

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 (71) hide show
  1. package/dist/artifactregistry-QQWBMEQN.js +38 -0
  2. package/dist/artifactregistry-QQWBMEQN.js.map +1 -0
  3. package/dist/chunk-J5S6GRGW.js +314 -0
  4. package/dist/chunk-J5S6GRGW.js.map +1 -0
  5. package/dist/chunk-KHO6NIAI.js +1367 -0
  6. package/dist/chunk-KHO6NIAI.js.map +1 -0
  7. package/dist/chunk-M7G73Q6P.js +662 -0
  8. package/dist/chunk-M7G73Q6P.js.map +1 -0
  9. package/dist/chunk-P7TIZJ4C.js +85 -0
  10. package/dist/chunk-P7TIZJ4C.js.map +1 -0
  11. package/dist/chunk-RXA4FO7L.js +279 -0
  12. package/dist/chunk-RXA4FO7L.js.map +1 -0
  13. package/dist/cli.js +7432 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/cloudrun-O36R23SH.js +31 -0
  16. package/dist/cloudrun-O36R23SH.js.map +1 -0
  17. package/dist/cloudwatch-KSZ4A256.js +56 -0
  18. package/dist/cloudwatch-KSZ4A256.js.map +1 -0
  19. package/dist/dynamodb-5KVESCVJ.js +51 -0
  20. package/dist/dynamodb-5KVESCVJ.js.map +1 -0
  21. package/dist/ec2-HKPE6GZV.js +151 -0
  22. package/dist/ec2-HKPE6GZV.js.map +1 -0
  23. package/dist/ecs-OS3NJZTA.js +141 -0
  24. package/dist/ecs-OS3NJZTA.js.map +1 -0
  25. package/dist/elasticache-7TCRHYYM.js +151 -0
  26. package/dist/elasticache-7TCRHYYM.js.map +1 -0
  27. package/dist/elb-PEDLXW5R.js +151 -0
  28. package/dist/elb-PEDLXW5R.js.map +1 -0
  29. package/dist/generate-D4MFMOHP.js +28 -0
  30. package/dist/generate-D4MFMOHP.js.map +1 -0
  31. package/dist/iam-7H5HFWVQ.js +96 -0
  32. package/dist/iam-7H5HFWVQ.js.map +1 -0
  33. package/dist/iam-DJI64AGK.js +39 -0
  34. package/dist/iam-DJI64AGK.js.map +1 -0
  35. package/dist/index.js +7980 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/infra-UXM5XQX3.js +566 -0
  38. package/dist/infra-UXM5XQX3.js.map +1 -0
  39. package/dist/lambda-NFB5UILT.js +60 -0
  40. package/dist/lambda-NFB5UILT.js.map +1 -0
  41. package/dist/manifest-7AIL2FK2.js +23 -0
  42. package/dist/manifest-7AIL2FK2.js.map +1 -0
  43. package/dist/mcp-O5O7XVFG.js +204 -0
  44. package/dist/mcp-O5O7XVFG.js.map +1 -0
  45. package/dist/rds-KLG5O5SI.js +151 -0
  46. package/dist/rds-KLG5O5SI.js.map +1 -0
  47. package/dist/registry-V65CC7IN.js +15 -0
  48. package/dist/registry-V65CC7IN.js.map +1 -0
  49. package/dist/s3-2DH7PRVR.js +49 -0
  50. package/dist/s3-2DH7PRVR.js.map +1 -0
  51. package/dist/scan-EELS42BP.js +593 -0
  52. package/dist/scan-EELS42BP.js.map +1 -0
  53. package/dist/secretmanager-RDL62EFW.js +31 -0
  54. package/dist/secretmanager-RDL62EFW.js.map +1 -0
  55. package/dist/secretsmanager-MOOIHLAO.js +50 -0
  56. package/dist/secretsmanager-MOOIHLAO.js.map +1 -0
  57. package/dist/sns-Y36LVTWA.js +50 -0
  58. package/dist/sns-Y36LVTWA.js.map +1 -0
  59. package/dist/sqs-RRS3GRHK.js +61 -0
  60. package/dist/sqs-RRS3GRHK.js.map +1 -0
  61. package/dist/src-KZRTG3EU.js +45 -0
  62. package/dist/src-KZRTG3EU.js.map +1 -0
  63. package/dist/standards-RXK5G4IG.js +37 -0
  64. package/dist/standards-RXK5G4IG.js.map +1 -0
  65. package/dist/sync-RLYBGYNY.js +877 -0
  66. package/dist/sync-RLYBGYNY.js.map +1 -0
  67. package/dist/validate-AABLVQJS.js +327 -0
  68. package/dist/validate-AABLVQJS.js.map +1 -0
  69. package/dist/validator-6PL5I5EC.js +156 -0
  70. package/dist/validator-6PL5I5EC.js.map +1 -0
  71. package/package.json +91 -0
@@ -0,0 +1,662 @@
1
+ // src/infra/manifest.ts
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+
5
+ // src/infra/arn.ts
6
+ function isValidArn(arn) {
7
+ if (!arn.startsWith("arn:")) {
8
+ return false;
9
+ }
10
+ const parts = arn.split(":");
11
+ return parts.length >= 6;
12
+ }
13
+ function parseArn(arn) {
14
+ if (!isValidArn(arn)) {
15
+ return null;
16
+ }
17
+ const parts = arn.split(":");
18
+ const [, partition, service, region, accountId, ...resourceParts] = parts;
19
+ const resource = resourceParts.join(":");
20
+ const { resourceType, resourceId } = parseResource(service, resource);
21
+ return {
22
+ cloud: "aws",
23
+ partition,
24
+ service,
25
+ region,
26
+ accountId,
27
+ resourceType,
28
+ resourceId,
29
+ raw: arn
30
+ };
31
+ }
32
+ var serviceParsers = {
33
+ s3: parseS3Resource,
34
+ lambda: parseLambdaResource,
35
+ dynamodb: parseDynamoDBResource,
36
+ sqs: (resource) => ({ resourceType: "queue", resourceId: resource }),
37
+ sns: (resource) => ({ resourceType: "topic", resourceId: resource }),
38
+ iam: parseIAMResource,
39
+ secretsmanager: parseSecretsManagerResource,
40
+ logs: parseLogsResource
41
+ };
42
+ function parseS3Resource(resource) {
43
+ if (resource.includes("/")) {
44
+ const [bucket, ...keyParts] = resource.split("/");
45
+ return { resourceType: "object", resourceId: `${bucket}/${keyParts.join("/")}` };
46
+ }
47
+ return { resourceType: "bucket", resourceId: resource };
48
+ }
49
+ function parseLambdaResource(resource) {
50
+ if (resource.startsWith("function:")) {
51
+ const funcName = resource.slice("function:".length);
52
+ const colonIndex = funcName.indexOf(":");
53
+ const resourceId = colonIndex !== -1 ? funcName.slice(0, colonIndex) : funcName;
54
+ return { resourceType: "function", resourceId };
55
+ }
56
+ if (resource.startsWith("layer:")) {
57
+ const rest = resource.slice("layer:".length);
58
+ const colonIndex = rest.indexOf(":");
59
+ const resourceId = colonIndex !== -1 ? rest.slice(0, colonIndex) : rest;
60
+ return { resourceType: "layer", resourceId };
61
+ }
62
+ return { resourceType: "function", resourceId: resource };
63
+ }
64
+ function parseDynamoDBResource(resource) {
65
+ if (resource.startsWith("table/")) {
66
+ const rest = resource.slice("table/".length);
67
+ const indexPos = rest.indexOf("/index/");
68
+ const resourceType = indexPos !== -1 ? "index" : "table";
69
+ return { resourceType, resourceId: rest };
70
+ }
71
+ return { resourceType: "table", resourceId: resource };
72
+ }
73
+ function parseIAMResource(resource) {
74
+ const prefixes = ["role/", "user/", "policy/"];
75
+ for (const prefix of prefixes) {
76
+ if (resource.startsWith(prefix)) {
77
+ return {
78
+ resourceType: prefix.slice(0, -1),
79
+ resourceId: resource.slice(prefix.length)
80
+ };
81
+ }
82
+ }
83
+ const colonIndex = resource.indexOf(":");
84
+ if (colonIndex !== -1) {
85
+ return {
86
+ resourceType: resource.slice(0, colonIndex),
87
+ resourceId: resource.slice(colonIndex + 1)
88
+ };
89
+ }
90
+ return { resourceType: "", resourceId: resource };
91
+ }
92
+ function parseSecretsManagerResource(resource) {
93
+ if (resource.startsWith("secret:")) {
94
+ return { resourceType: "secret", resourceId: resource.slice("secret:".length) };
95
+ }
96
+ return { resourceType: "secret", resourceId: resource };
97
+ }
98
+ function parseLogsResource(resource) {
99
+ if (resource.startsWith("log-group:")) {
100
+ let logGroupName = resource.slice("log-group:".length);
101
+ if (logGroupName.endsWith(":*")) {
102
+ logGroupName = logGroupName.slice(0, -2);
103
+ }
104
+ return { resourceType: "log-group", resourceId: logGroupName };
105
+ }
106
+ return { resourceType: "log-group", resourceId: resource };
107
+ }
108
+ function parseGenericResource(resource) {
109
+ if (resource.includes("/")) {
110
+ const slashIndex = resource.indexOf("/");
111
+ return {
112
+ resourceType: resource.slice(0, slashIndex),
113
+ resourceId: resource.slice(slashIndex + 1)
114
+ };
115
+ }
116
+ if (resource.includes(":")) {
117
+ const colonIndex = resource.indexOf(":");
118
+ return {
119
+ resourceType: resource.slice(0, colonIndex),
120
+ resourceId: resource.slice(colonIndex + 1)
121
+ };
122
+ }
123
+ return { resourceType: "", resourceId: resource };
124
+ }
125
+ function parseResource(service, resource) {
126
+ const parser = serviceParsers[service];
127
+ return parser ? parser(resource) : parseGenericResource(resource);
128
+ }
129
+
130
+ // src/infra/gcp.ts
131
+ function isValidGcpResource(path2) {
132
+ return path2.startsWith("projects/") && path2.split("/").length >= 3;
133
+ }
134
+ function parseGcpResource(path2) {
135
+ if (!isValidGcpResource(path2)) {
136
+ return null;
137
+ }
138
+ const parts = path2.split("/");
139
+ if (parts[0] !== "projects" || parts.length < 3) {
140
+ return null;
141
+ }
142
+ const project = parts[1];
143
+ const result = parseResourcePath(parts.slice(2), path2, project);
144
+ return result;
145
+ }
146
+ function parseResourcePath(parts, raw, project) {
147
+ if (parts[0] === "serviceAccounts" && parts.length >= 2) {
148
+ return gcpResource({
149
+ project,
150
+ service: "iam",
151
+ location: "global",
152
+ resourceType: "serviceAccounts",
153
+ resourceId: parts.slice(1).join("/"),
154
+ raw
155
+ });
156
+ }
157
+ if (parts[0] === "secrets" && parts.length >= 2) {
158
+ return gcpResource({
159
+ project,
160
+ service: "secretmanager",
161
+ location: "global",
162
+ resourceType: "secrets",
163
+ resourceId: parts[1],
164
+ raw
165
+ });
166
+ }
167
+ if (parts[0] === "locations" && parts.length >= 4) {
168
+ const location = parts[1];
169
+ const resourceType = parts[2];
170
+ const resourceId = parts.slice(3).join("/");
171
+ const service = getServiceFromResourceType(resourceType);
172
+ return gcpResource({
173
+ project,
174
+ service,
175
+ location,
176
+ resourceType,
177
+ resourceId,
178
+ raw
179
+ });
180
+ }
181
+ return null;
182
+ }
183
+ function getServiceFromResourceType(resourceType) {
184
+ const serviceMap = {
185
+ services: "run",
186
+ repositories: "artifactregistry",
187
+ functions: "cloudfunctions",
188
+ buckets: "storage",
189
+ instances: "compute",
190
+ clusters: "container"
191
+ };
192
+ return serviceMap[resourceType] ?? resourceType;
193
+ }
194
+ function gcpResource(params) {
195
+ return { cloud: "gcp", ...params };
196
+ }
197
+
198
+ // src/infra/schemas.ts
199
+ import { z } from "zod";
200
+ var CloudProviderSchema = z.enum(["aws", "gcp"]);
201
+ var AccountKeySchema = z.string().regex(
202
+ /^(aws|gcp):.+$/,
203
+ "Invalid account key format. Expected: provider:accountId (e.g., aws:123456789012, gcp:my-project)"
204
+ );
205
+ var ArnSchema = z.string().regex(
206
+ /^arn:(aws|aws-cn|aws-us-gov):[a-z0-9-]+:[a-z0-9-]*:[0-9]*:.+$/,
207
+ "Invalid ARN format. Expected: arn:partition:service:region:account-id:resource"
208
+ );
209
+ var ParsedArnSchema = z.object({
210
+ /** Cloud provider (always "aws" for ARNs) */
211
+ cloud: z.literal("aws"),
212
+ /** AWS partition (aws, aws-cn, aws-us-gov) */
213
+ partition: z.string(),
214
+ /** AWS service (s3, lambda, rds, etc.) */
215
+ service: z.string(),
216
+ /** AWS region (empty for global services like S3, IAM) */
217
+ region: z.string(),
218
+ /** AWS account ID (empty for S3 buckets) */
219
+ accountId: z.string(),
220
+ /** Resource type (e.g., function, table, bucket) */
221
+ resourceType: z.string(),
222
+ /** Resource name/identifier */
223
+ resourceId: z.string(),
224
+ /** Original ARN string */
225
+ raw: z.string()
226
+ });
227
+ var GcpResourcePathSchema = z.string().regex(
228
+ /^projects\/[^/]+\/.+$/,
229
+ "Invalid GCP resource path format. Expected: projects/{project-id}/..."
230
+ );
231
+ var ParsedGcpResourceSchema = z.object({
232
+ /** Cloud provider (always "gcp" for GCP resources) */
233
+ cloud: z.literal("gcp"),
234
+ /** GCP project ID */
235
+ project: z.string(),
236
+ /** GCP service (run, iam, secretmanager, artifactregistry, etc.) */
237
+ service: z.string(),
238
+ /** Location/region (us-central1, global, etc.) */
239
+ location: z.string(),
240
+ /** Resource type (services, serviceAccounts, secrets, repositories, etc.) */
241
+ resourceType: z.string(),
242
+ /** Resource name/ID */
243
+ resourceId: z.string(),
244
+ /** Original resource path */
245
+ raw: z.string()
246
+ });
247
+ var ResourceIdentifierSchema = z.union([ArnSchema, GcpResourcePathSchema]);
248
+ var AccountIdSchema = z.object({
249
+ /** Cloud provider */
250
+ cloud: CloudProviderSchema,
251
+ /** AWS account ID or GCP project ID */
252
+ id: z.string()
253
+ });
254
+ var ManifestAccountSchema = z.object({
255
+ /** Optional human-readable alias for this account */
256
+ alias: z.string().optional(),
257
+ /** List of resource identifiers (ARNs or GCP resource paths) */
258
+ resources: z.array(z.string())
259
+ });
260
+ var MultiAccountManifestSchema = z.object({
261
+ /** Manifest version - must be 2 for multi-account format */
262
+ version: z.literal(2),
263
+ /** Optional project name */
264
+ project: z.string().optional(),
265
+ /** Resources grouped by account key (e.g., "aws:123456789012", "gcp:my-project") */
266
+ accounts: z.record(z.string(), ManifestAccountSchema)
267
+ });
268
+ var LegacyManifestSchema = z.object({
269
+ /** Optional manifest version (1 or undefined for legacy) */
270
+ version: z.literal(1).optional(),
271
+ /** Optional project name */
272
+ project: z.string().optional(),
273
+ /** Flat list of resource identifiers */
274
+ resources: z.array(z.string())
275
+ });
276
+ var ManifestSchema = z.union([MultiAccountManifestSchema, LegacyManifestSchema]);
277
+ var ResourceCheckResultSchema = z.object({
278
+ /** The resource ARN or GCP path */
279
+ arn: z.string(),
280
+ /** Whether the resource exists */
281
+ exists: z.boolean(),
282
+ /** Error message if check failed */
283
+ error: z.string().optional(),
284
+ /** Service name (e.g., s3, lambda, run) */
285
+ service: z.string(),
286
+ /** Resource type (e.g., bucket, function) */
287
+ resourceType: z.string(),
288
+ /** Resource identifier */
289
+ resourceId: z.string()
290
+ });
291
+ var InfraScanSummarySchema = z.object({
292
+ /** Total resources checked */
293
+ total: z.number().int().nonnegative(),
294
+ /** Resources that exist */
295
+ found: z.number().int().nonnegative(),
296
+ /** Resources that don't exist */
297
+ missing: z.number().int().nonnegative(),
298
+ /** Resources that couldn't be checked (errors) */
299
+ errors: z.number().int().nonnegative()
300
+ });
301
+ var AccountScanResultSchema = z.object({
302
+ /** Account alias if provided */
303
+ alias: z.string().optional(),
304
+ /** Individual resource check results */
305
+ results: z.array(ResourceCheckResultSchema),
306
+ /** Summary statistics for this account */
307
+ summary: InfraScanSummarySchema
308
+ });
309
+ var InfraScanResultSchema = z.object({
310
+ /** Path to the manifest file */
311
+ manifest: z.string(),
312
+ /** Project name */
313
+ project: z.string().optional(),
314
+ /** Individual resource check results */
315
+ results: z.array(ResourceCheckResultSchema),
316
+ /** Summary statistics */
317
+ summary: InfraScanSummarySchema,
318
+ /** Per-account results (only present for multi-account manifests) */
319
+ accountResults: z.record(z.string(), AccountScanResultSchema).optional()
320
+ });
321
+ var PulumiResourceSchema = z.object({
322
+ urn: z.string().optional(),
323
+ type: z.string().optional(),
324
+ inputs: z.record(z.string(), z.unknown()).optional(),
325
+ outputs: z.record(z.string(), z.unknown()).optional()
326
+ });
327
+ var PulumiStackExportSchema = z.object({
328
+ version: z.number().optional(),
329
+ deployment: z.object({
330
+ manifest: z.object({
331
+ time: z.string().optional(),
332
+ magic: z.string().optional(),
333
+ version: z.string().optional()
334
+ }).optional(),
335
+ resources: z.array(PulumiResourceSchema).optional()
336
+ }).optional()
337
+ });
338
+ function validateArn(arn) {
339
+ return ArnSchema.parse(arn);
340
+ }
341
+ function isValidArnFormat(arn) {
342
+ return ArnSchema.safeParse(arn).success;
343
+ }
344
+ function validateGcpResourcePath(path2) {
345
+ return GcpResourcePathSchema.parse(path2);
346
+ }
347
+ function isValidGcpResourcePath(path2) {
348
+ return GcpResourcePathSchema.safeParse(path2).success;
349
+ }
350
+ function validateAccountKey(key) {
351
+ return AccountKeySchema.parse(key);
352
+ }
353
+ function isValidAccountKey(key) {
354
+ return AccountKeySchema.safeParse(key).success;
355
+ }
356
+ function validateLegacyManifest(data) {
357
+ return LegacyManifestSchema.parse(data);
358
+ }
359
+ function validateMultiAccountManifest(data) {
360
+ return MultiAccountManifestSchema.parse(data);
361
+ }
362
+ function validateManifest(data) {
363
+ return ManifestSchema.parse(data);
364
+ }
365
+ function isMultiAccountManifestSchema(data) {
366
+ return MultiAccountManifestSchema.safeParse(data).success;
367
+ }
368
+ function isLegacyManifestSchema(data) {
369
+ return LegacyManifestSchema.safeParse(data).success;
370
+ }
371
+ function validateStackExport(data) {
372
+ return PulumiStackExportSchema.parse(data);
373
+ }
374
+
375
+ // src/infra/manifest.ts
376
+ function isValidResource(resource) {
377
+ return isValidArn(resource) || isValidGcpResource(resource);
378
+ }
379
+ var ManifestError = class extends Error {
380
+ constructor(message) {
381
+ super(message);
382
+ this.name = "ManifestError";
383
+ }
384
+ };
385
+ function isMultiAccountManifest(manifest) {
386
+ return "accounts" in manifest && typeof manifest.accounts === "object";
387
+ }
388
+ function isLegacyManifest(manifest) {
389
+ return "resources" in manifest && Array.isArray(manifest.resources);
390
+ }
391
+ function parseAccountKey(key) {
392
+ if (!isValidAccountKey(key)) {
393
+ return null;
394
+ }
395
+ const colonIndex = key.indexOf(":");
396
+ return {
397
+ cloud: key.substring(0, colonIndex),
398
+ id: key.substring(colonIndex + 1)
399
+ };
400
+ }
401
+ function formatAccountKey(cloud, id) {
402
+ return `${cloud}:${id}`;
403
+ }
404
+ function normalizeManifest(manifest) {
405
+ if (isMultiAccountManifest(manifest)) {
406
+ return manifest;
407
+ }
408
+ const accounts = {};
409
+ for (const resource of manifest.resources) {
410
+ const accountKey = detectAccountFromResource(resource);
411
+ if (accountKey in accounts) {
412
+ accounts[accountKey].resources.push(resource);
413
+ } else {
414
+ accounts[accountKey] = { resources: [resource] };
415
+ }
416
+ }
417
+ return {
418
+ version: 2,
419
+ project: manifest.project,
420
+ accounts
421
+ };
422
+ }
423
+ function detectAccountFromResource(resource) {
424
+ if (resource.startsWith("arn:")) {
425
+ const parts = resource.split(":");
426
+ if (parts.length >= 5) {
427
+ const accountId = parts[4];
428
+ if (accountId) {
429
+ return formatAccountKey("aws", accountId);
430
+ }
431
+ return "aws:unknown";
432
+ }
433
+ }
434
+ const gcpRegex = /^projects\/([^/]+)\//;
435
+ const gcpMatch = gcpRegex.exec(resource);
436
+ if (gcpMatch) {
437
+ return formatAccountKey("gcp", gcpMatch[1]);
438
+ }
439
+ return "unknown:unknown";
440
+ }
441
+ function getAllResources(manifest) {
442
+ if (isMultiAccountManifest(manifest)) {
443
+ return Object.values(manifest.accounts).flatMap((account) => account.resources);
444
+ }
445
+ return manifest.resources;
446
+ }
447
+ function readManifest(manifestPath) {
448
+ if (!fs.existsSync(manifestPath)) {
449
+ throw new ManifestError(`Manifest file not found: ${manifestPath}`);
450
+ }
451
+ const content = fs.readFileSync(manifestPath, "utf-8");
452
+ const ext = path.extname(manifestPath).toLowerCase();
453
+ if (ext === ".json") {
454
+ return parseJsonManifest(content, manifestPath);
455
+ }
456
+ if (ext === ".txt") {
457
+ return parseTxtManifest(content, manifestPath);
458
+ }
459
+ try {
460
+ return parseJsonManifest(content, manifestPath);
461
+ } catch {
462
+ return parseTxtManifest(content, manifestPath);
463
+ }
464
+ }
465
+ function parseJsonManifest(content, manifestPath) {
466
+ const data = parseJsonContent(content, manifestPath);
467
+ if (!data || typeof data !== "object") {
468
+ throw new ManifestError(`Manifest ${manifestPath} must be a JSON object`);
469
+ }
470
+ if (isMultiAccountManifestSchema(data)) {
471
+ return validateMultiAccountManifestWithResources(data, manifestPath);
472
+ }
473
+ if (isLegacyManifestSchema(data)) {
474
+ return validateLegacyManifestWithResources(data, manifestPath);
475
+ }
476
+ return parseFallbackManifest(data, manifestPath);
477
+ }
478
+ function parseFallbackManifest(obj, manifestPath) {
479
+ if ("accounts" in obj) {
480
+ return parseMultiAccountManifestFallback(obj, manifestPath);
481
+ }
482
+ validateJsonStructure(obj, manifestPath);
483
+ const resources = extractAndValidateResources(obj.resources, manifestPath);
484
+ const project = typeof obj.project === "string" ? obj.project : void 0;
485
+ return { project, resources };
486
+ }
487
+ function validateMultiAccountManifestWithResources(data, manifestPath) {
488
+ try {
489
+ const manifest = validateMultiAccountManifest(data);
490
+ for (const [accountKey, account] of Object.entries(manifest.accounts)) {
491
+ if (!isValidAccountKey(accountKey)) {
492
+ throw new ManifestError(
493
+ `Manifest ${manifestPath} has invalid account key: "${accountKey}". Expected format: "aws:<account-id>" or "gcp:<project-id>"`
494
+ );
495
+ }
496
+ const invalidResources = account.resources.filter((r) => !isValidResource(r));
497
+ if (invalidResources.length > 0) {
498
+ throw new ManifestError(
499
+ `Manifest ${manifestPath} account "${accountKey}" contains invalid resources: ${invalidResources.join(", ")}`
500
+ );
501
+ }
502
+ }
503
+ return manifest;
504
+ } catch (error) {
505
+ if (error instanceof ManifestError) {
506
+ throw error;
507
+ }
508
+ const message = error instanceof Error ? error.message : "Unknown error";
509
+ throw new ManifestError(`Invalid manifest ${manifestPath}: ${message}`);
510
+ }
511
+ }
512
+ function validateLegacyManifestWithResources(data, manifestPath) {
513
+ try {
514
+ const manifest = validateLegacyManifest(data);
515
+ const invalidResources = manifest.resources.filter((r) => !isValidResource(r));
516
+ if (invalidResources.length > 0) {
517
+ throw new ManifestError(
518
+ `Manifest ${manifestPath} contains invalid resources: ${invalidResources.join(", ")}`
519
+ );
520
+ }
521
+ return manifest;
522
+ } catch (error) {
523
+ if (error instanceof ManifestError) {
524
+ throw error;
525
+ }
526
+ const message = error instanceof Error ? error.message : "Unknown error";
527
+ throw new ManifestError(`Invalid manifest ${manifestPath}: ${message}`);
528
+ }
529
+ }
530
+ function parseMultiAccountManifestFallback(obj, manifestPath) {
531
+ const accountsRaw = obj.accounts;
532
+ const accounts = {};
533
+ for (const [key, value] of Object.entries(accountsRaw)) {
534
+ accounts[key] = parseAccountEntry(key, value, manifestPath);
535
+ }
536
+ const project = typeof obj.project === "string" ? obj.project : void 0;
537
+ return { version: 2, project, accounts };
538
+ }
539
+ function parseAccountEntry(key, value, manifestPath) {
540
+ const parsedKey = parseAccountKey(key);
541
+ if (!parsedKey) {
542
+ throw new ManifestError(
543
+ `Manifest ${manifestPath} has invalid account key: "${key}". Expected format: "aws:<account-id>" or "gcp:<project-id>"`
544
+ );
545
+ }
546
+ if (!value || typeof value !== "object") {
547
+ throw new ManifestError(`Manifest ${manifestPath} account "${key}" must be an object`);
548
+ }
549
+ const accountObj = value;
550
+ if (!Array.isArray(accountObj.resources)) {
551
+ throw new ManifestError(`Manifest ${manifestPath} account "${key}" must have a "resources" array`);
552
+ }
553
+ const resources = extractAndValidateResources(accountObj.resources, manifestPath);
554
+ const alias = typeof accountObj.alias === "string" ? accountObj.alias : void 0;
555
+ return { alias, resources };
556
+ }
557
+ function parseJsonContent(content, manifestPath) {
558
+ try {
559
+ return JSON.parse(content);
560
+ } catch (error) {
561
+ const message = error instanceof Error ? error.message : "Unknown error";
562
+ throw new ManifestError(`Invalid JSON in manifest ${manifestPath}: ${message}`);
563
+ }
564
+ }
565
+ function validateJsonStructure(data, manifestPath) {
566
+ if (!data || typeof data !== "object") {
567
+ throw new ManifestError(`Manifest ${manifestPath} must be a JSON object`);
568
+ }
569
+ const obj = data;
570
+ if (!Array.isArray(obj.resources)) {
571
+ throw new ManifestError(`Manifest ${manifestPath} must have a "resources" array`);
572
+ }
573
+ }
574
+ function extractAndValidateResources(items, manifestPath) {
575
+ const resources = [];
576
+ const invalidResources = [];
577
+ for (const item of items) {
578
+ if (typeof item !== "string") {
579
+ throw new ManifestError(
580
+ `Manifest ${manifestPath} contains non-string resource: ${JSON.stringify(item)}`
581
+ );
582
+ }
583
+ if (!isValidResource(item)) {
584
+ invalidResources.push(item);
585
+ } else {
586
+ resources.push(item);
587
+ }
588
+ }
589
+ if (invalidResources.length > 0) {
590
+ throw new ManifestError(
591
+ `Manifest ${manifestPath} contains invalid resources: ${invalidResources.join(", ")}`
592
+ );
593
+ }
594
+ return resources;
595
+ }
596
+ function parseTxtManifest(content, manifestPath) {
597
+ const lines = content.split("\n");
598
+ const resources = [];
599
+ const invalidResources = [];
600
+ for (let i = 0; i < lines.length; i++) {
601
+ const line = lines[i].trim();
602
+ if (!line || line.startsWith("#")) {
603
+ continue;
604
+ }
605
+ if (!isValidResource(line)) {
606
+ invalidResources.push({ line: i + 1, value: line });
607
+ } else {
608
+ resources.push(line);
609
+ }
610
+ }
611
+ if (invalidResources.length > 0) {
612
+ const details = invalidResources.map((a) => `line ${a.line}: "${a.value}"`).join(", ");
613
+ throw new ManifestError(`Manifest ${manifestPath} contains invalid resources: ${details}`);
614
+ }
615
+ return { resources };
616
+ }
617
+
618
+ export {
619
+ isValidArn,
620
+ parseArn,
621
+ isValidGcpResource,
622
+ parseGcpResource,
623
+ CloudProviderSchema,
624
+ AccountKeySchema,
625
+ ArnSchema,
626
+ ParsedArnSchema,
627
+ GcpResourcePathSchema,
628
+ ParsedGcpResourceSchema,
629
+ ResourceIdentifierSchema,
630
+ AccountIdSchema,
631
+ ManifestAccountSchema,
632
+ MultiAccountManifestSchema,
633
+ LegacyManifestSchema,
634
+ ManifestSchema,
635
+ ResourceCheckResultSchema,
636
+ InfraScanSummarySchema,
637
+ InfraScanResultSchema,
638
+ PulumiResourceSchema,
639
+ PulumiStackExportSchema,
640
+ validateArn,
641
+ isValidArnFormat,
642
+ validateGcpResourcePath,
643
+ isValidGcpResourcePath,
644
+ validateAccountKey,
645
+ isValidAccountKey,
646
+ validateLegacyManifest,
647
+ validateMultiAccountManifest,
648
+ validateManifest,
649
+ isMultiAccountManifestSchema,
650
+ isLegacyManifestSchema,
651
+ validateStackExport,
652
+ ManifestError,
653
+ isMultiAccountManifest,
654
+ isLegacyManifest,
655
+ parseAccountKey,
656
+ formatAccountKey,
657
+ normalizeManifest,
658
+ detectAccountFromResource,
659
+ getAllResources,
660
+ readManifest
661
+ };
662
+ //# sourceMappingURL=chunk-M7G73Q6P.js.map