@quiltdata/benchling-webhook 0.5.4-20251102T020826Z → 0.5.4-20251103T180342Z

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 (91) hide show
  1. package/README.md +26 -17
  2. package/dist/bin/benchling-webhook.d.ts +1 -1
  3. package/dist/bin/benchling-webhook.d.ts.map +1 -1
  4. package/dist/bin/benchling-webhook.js +8 -23
  5. package/dist/bin/benchling-webhook.js.map +1 -1
  6. package/dist/bin/cdk-dev.js +51 -0
  7. package/dist/bin/cli.js +8 -22
  8. package/dist/bin/cli.js.map +1 -1
  9. package/dist/bin/commands/deploy.d.ts +4 -2
  10. package/dist/bin/commands/deploy.d.ts.map +1 -1
  11. package/dist/bin/commands/deploy.js +88 -300
  12. package/dist/bin/commands/deploy.js.map +1 -1
  13. package/dist/bin/config-profiles.d.ts +59 -0
  14. package/dist/bin/config-profiles.d.ts.map +1 -0
  15. package/dist/bin/config-profiles.js +272 -0
  16. package/dist/bin/config-profiles.js.map +1 -0
  17. package/dist/bin/create-secret.d.ts +3 -0
  18. package/dist/bin/create-secret.d.ts.map +1 -1
  19. package/dist/bin/create-secret.js +51 -48
  20. package/dist/bin/create-secret.js.map +1 -1
  21. package/dist/lib/benchling-auth-validator.d.ts +65 -0
  22. package/dist/lib/benchling-auth-validator.d.ts.map +1 -0
  23. package/dist/lib/benchling-auth-validator.js +213 -0
  24. package/dist/lib/benchling-auth-validator.js.map +1 -0
  25. package/dist/lib/benchling-webhook-stack.d.ts +5 -23
  26. package/dist/lib/benchling-webhook-stack.d.ts.map +1 -1
  27. package/dist/lib/benchling-webhook-stack.js +25 -145
  28. package/dist/lib/benchling-webhook-stack.js.map +1 -1
  29. package/dist/lib/config-logger.d.ts +191 -0
  30. package/dist/lib/config-logger.d.ts.map +1 -0
  31. package/dist/lib/config-logger.js +372 -0
  32. package/dist/lib/config-logger.js.map +1 -0
  33. package/dist/lib/configuration-saver.d.ts +75 -0
  34. package/dist/lib/configuration-saver.d.ts.map +1 -0
  35. package/dist/lib/configuration-saver.js +145 -0
  36. package/dist/lib/configuration-saver.js.map +1 -0
  37. package/dist/lib/configuration-validator.d.ts +63 -0
  38. package/dist/lib/configuration-validator.d.ts.map +1 -0
  39. package/dist/lib/configuration-validator.js +136 -0
  40. package/dist/lib/configuration-validator.js.map +1 -0
  41. package/dist/lib/configuration-wizard.d.ts +52 -0
  42. package/dist/lib/configuration-wizard.d.ts.map +1 -0
  43. package/dist/lib/configuration-wizard.js +193 -0
  44. package/dist/lib/configuration-wizard.js.map +1 -0
  45. package/dist/lib/quilt-config-resolver.d.ts +53 -0
  46. package/dist/lib/quilt-config-resolver.d.ts.map +1 -0
  47. package/dist/lib/quilt-config-resolver.js +100 -0
  48. package/dist/lib/quilt-config-resolver.js.map +1 -0
  49. package/dist/lib/s3-bucket-validator.d.ts +76 -0
  50. package/dist/lib/s3-bucket-validator.d.ts.map +1 -0
  51. package/dist/lib/s3-bucket-validator.js +237 -0
  52. package/dist/lib/s3-bucket-validator.js.map +1 -0
  53. package/dist/lib/types/config.d.ts +398 -0
  54. package/dist/lib/types/config.d.ts.map +1 -0
  55. package/dist/lib/types/config.js +11 -0
  56. package/dist/lib/types/config.js.map +1 -0
  57. package/dist/lib/utils/config-loader.js.map +1 -1
  58. package/dist/lib/utils/config-resolver.d.ts +26 -26
  59. package/dist/lib/utils/config-resolver.d.ts.map +1 -1
  60. package/dist/lib/utils/config-resolver.js +29 -29
  61. package/dist/lib/utils/config-resolver.js.map +1 -1
  62. package/dist/lib/utils/config.d.ts +2 -0
  63. package/dist/lib/utils/config.d.ts.map +1 -1
  64. package/dist/lib/utils/config.js.map +1 -1
  65. package/dist/lib/xdg-cli-wrapper.d.ts +113 -0
  66. package/dist/lib/xdg-cli-wrapper.d.ts.map +1 -0
  67. package/dist/lib/xdg-cli-wrapper.js +288 -0
  68. package/dist/lib/xdg-cli-wrapper.js.map +1 -0
  69. package/dist/lib/xdg-config.d.ts +187 -0
  70. package/dist/lib/xdg-config.d.ts.map +1 -0
  71. package/dist/lib/xdg-config.js +562 -0
  72. package/dist/lib/xdg-config.js.map +1 -0
  73. package/dist/package.json +38 -26
  74. package/dist/scripts/config-health-check.d.ts +78 -0
  75. package/dist/scripts/config-health-check.d.ts.map +1 -0
  76. package/dist/scripts/config-health-check.js +559 -0
  77. package/dist/scripts/config-health-check.js.map +1 -0
  78. package/dist/scripts/infer-quilt-config.d.ts +50 -0
  79. package/dist/scripts/infer-quilt-config.d.ts.map +1 -0
  80. package/dist/scripts/infer-quilt-config.js +353 -0
  81. package/dist/scripts/infer-quilt-config.js.map +1 -0
  82. package/dist/scripts/install-wizard.d.ts +34 -0
  83. package/dist/scripts/install-wizard.d.ts.map +1 -0
  84. package/dist/scripts/install-wizard.js +719 -0
  85. package/dist/scripts/install-wizard.js.map +1 -0
  86. package/dist/scripts/sync-secrets.d.ts +63 -0
  87. package/dist/scripts/sync-secrets.d.ts.map +1 -0
  88. package/dist/scripts/sync-secrets.js +424 -0
  89. package/dist/scripts/sync-secrets.js.map +1 -0
  90. package/env.template +60 -47
  91. package/package.json +38 -26
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quilt-config-resolver.d.ts","sourceRoot":"","sources":["../../lib/quilt-config-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,mBAAmB;IAC5B;;;;;OAKG;WACiB,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBtF;;;;;OAKG;IACU,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC;IAItD;;;;;;OAMG;IACU,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAatE;;;;;OAKG;IACI,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;CAuBxD"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * Quilt Configuration Resolver
4
+ *
5
+ * Automatically infers Quilt configuration from the quilt3 CLI.
6
+ * Extracts catalog URL, S3 bucket, and region information.
7
+ *
8
+ * @module quilt-config-resolver
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.QuiltConfigResolver = void 0;
12
+ const child_process_1 = require("child_process");
13
+ /**
14
+ * Quilt Configuration Resolver
15
+ *
16
+ * Resolves Quilt configuration from the quilt3 CLI or user overrides.
17
+ */
18
+ class QuiltConfigResolver {
19
+ /**
20
+ * Resolves Quilt configuration with optional manual overrides
21
+ *
22
+ * @param manualConfig - Optional manual configuration overrides
23
+ * @returns Resolved Quilt configuration
24
+ */
25
+ static async resolve(manualConfig) {
26
+ const resolver = new QuiltConfigResolver();
27
+ // If manual config is provided, return it
28
+ if (manualConfig) {
29
+ return {
30
+ catalogUrl: manualConfig.catalogUrl,
31
+ userBucket: manualConfig.userBucket,
32
+ defaultRegion: manualConfig.defaultRegion,
33
+ };
34
+ }
35
+ // Try to infer from quilt3 CLI
36
+ try {
37
+ return await resolver.resolveFromQuilt3();
38
+ }
39
+ catch (error) {
40
+ throw new Error(`Quilt configuration not found: ${error.message}`);
41
+ }
42
+ }
43
+ /**
44
+ * Resolves configuration from quilt3 CLI
45
+ *
46
+ * @returns Resolved Quilt configuration
47
+ * @throws {Error} If quilt3 is not installed or configured
48
+ */
49
+ async resolveFromQuilt3() {
50
+ return this.resolveWithCommand("quilt3 config");
51
+ }
52
+ /**
53
+ * Resolves configuration using a custom command
54
+ *
55
+ * @param command - Command to execute
56
+ * @returns Resolved Quilt configuration
57
+ * @throws {Error} If command fails
58
+ */
59
+ async resolveWithCommand(command) {
60
+ try {
61
+ const output = (0, child_process_1.execSync)(command, {
62
+ encoding: "utf-8",
63
+ stdio: ["pipe", "pipe", "pipe"],
64
+ }).trim();
65
+ return this.parseQuilt3Config(output);
66
+ }
67
+ catch (error) {
68
+ throw new Error(`Failed to execute command: ${command}. ${error.message}`);
69
+ }
70
+ }
71
+ /**
72
+ * Parses quilt3 config output
73
+ *
74
+ * @param output - Raw output from quilt3 config command
75
+ * @returns Parsed Quilt configuration
76
+ */
77
+ parseQuilt3Config(output) {
78
+ if (!output) {
79
+ throw new Error("Empty quilt3 config output");
80
+ }
81
+ // quilt3 config returns the full URL (e.g., https://nightly.quilttest.com)
82
+ // We want just the domain
83
+ let catalogUrl = output.trim();
84
+ // Remove protocol if present
85
+ if (catalogUrl.startsWith("http://") || catalogUrl.startsWith("https://")) {
86
+ try {
87
+ const url = new URL(catalogUrl);
88
+ catalogUrl = url.hostname;
89
+ }
90
+ catch {
91
+ // If URL parsing fails, use as-is
92
+ }
93
+ }
94
+ return {
95
+ catalogUrl,
96
+ };
97
+ }
98
+ }
99
+ exports.QuiltConfigResolver = QuiltConfigResolver;
100
+ //# sourceMappingURL=quilt-config-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quilt-config-resolver.js","sourceRoot":"","sources":["../../lib/quilt-config-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,iDAAyC;AAWzC;;;;GAIG;AACH,MAAa,mBAAmB;IAC5B;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,YAAmC;QAC3D,MAAM,QAAQ,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAE3C,0CAA0C;QAC1C,IAAI,YAAY,EAAE,CAAC;YACf,OAAO;gBACH,UAAU,EAAE,YAAY,CAAC,UAAU;gBACnC,UAAU,EAAE,YAAY,CAAC,UAAU;gBACnC,aAAa,EAAE,YAAY,CAAC,aAAa;aAC5C,CAAC;QACN,CAAC;QAED,+BAA+B;QAC/B,IAAI,CAAC;YACD,OAAO,MAAM,QAAQ,CAAC,iBAAiB,EAAE,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,kCAAmC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAClF,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,iBAAiB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,kBAAkB,CAAC,OAAe;QAC3C,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,OAAO,EAAE;gBAC7B,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC,IAAI,EAAE,CAAC;YAEV,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACI,iBAAiB,CAAC,MAAc;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAClD,CAAC;QAED,2EAA2E;QAC3E,0BAA0B;QAC1B,IAAI,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAE/B,6BAA6B;QAC7B,IAAI,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC;gBACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;gBAChC,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACL,kCAAkC;YACtC,CAAC;QACL,CAAC;QAED,OAAO;YACH,UAAU;SACb,CAAC;IACN,CAAC;CACJ;AAtFD,kDAsFC"}
@@ -0,0 +1,76 @@
1
+ import { S3Client } from "@aws-sdk/client-s3";
2
+ /**
3
+ * S3 bucket configuration
4
+ */
5
+ export interface S3BucketConfig {
6
+ bucketName: string;
7
+ region: string;
8
+ }
9
+ /**
10
+ * S3 bucket validation result
11
+ */
12
+ export interface S3ValidationResult {
13
+ hasAccess: boolean;
14
+ isConfigured: boolean;
15
+ hasWritePermission?: boolean;
16
+ hasReadPermission?: boolean;
17
+ errors: string[];
18
+ }
19
+ /**
20
+ * S3 bucket access validator
21
+ *
22
+ * Validates S3 bucket access and permissions required for the webhook integration.
23
+ */
24
+ export declare class S3BucketValidator {
25
+ /**
26
+ * Valid AWS region patterns
27
+ */
28
+ private static readonly VALID_REGIONS;
29
+ /**
30
+ * Validate S3 bucket access and permissions
31
+ *
32
+ * @param config - S3 bucket configuration
33
+ * @returns Validation result with access status and errors
34
+ */
35
+ static validate(config: S3BucketConfig): Promise<S3ValidationResult>;
36
+ /**
37
+ * Validate S3 bucket name format
38
+ *
39
+ * @param bucketName - Bucket name to validate
40
+ * @returns True if bucket name is valid
41
+ */
42
+ static validateBucketName(bucketName: string): boolean;
43
+ /**
44
+ * Validate AWS region format
45
+ *
46
+ * @param region - AWS region to validate
47
+ * @returns True if region format is valid
48
+ */
49
+ static validateRegion(region: string): boolean;
50
+ /**
51
+ * Check if S3 bucket exists
52
+ *
53
+ * @param bucketName - Name of the bucket
54
+ * @param region - AWS region
55
+ * @param s3Client - Optional S3 client instance
56
+ * @returns True if bucket exists
57
+ */
58
+ static checkBucketExists(bucketName: string, region: string, s3Client?: S3Client): Promise<boolean>;
59
+ /**
60
+ * Test write permissions on S3 bucket
61
+ *
62
+ * @param bucketName - Name of the bucket
63
+ * @param s3Client - S3 client instance
64
+ * @returns True if write permission is granted
65
+ */
66
+ private static testWritePermission;
67
+ /**
68
+ * Test read permissions on S3 bucket
69
+ *
70
+ * @param bucketName - Name of the bucket
71
+ * @param s3Client - S3 client instance
72
+ * @returns True if read permission is granted
73
+ */
74
+ private static testReadPermission;
75
+ }
76
+ //# sourceMappingURL=s3-bucket-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-bucket-validator.d.ts","sourceRoot":"","sources":["../../lib/s3-bucket-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA8E,MAAM,oBAAoB,CAAC;AAE1H;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;IAC1B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAoH;IAEzJ;;;;;OAKG;WACiB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA6FjF;;;;;OAKG;WACW,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAmB7D;;;;;OAKG;WACW,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAQrD;;;;;;;OAOG;WACiB,iBAAiB,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,QAAQ,GACpB,OAAO,CAAC,OAAO,CAAC;IAiBnB;;;;;;OAMG;mBACkB,mBAAmB;IAgCxC;;;;;;OAMG;mBACkB,kBAAkB;CAgD1C"}
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.S3BucketValidator = void 0;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ /**
6
+ * S3 bucket access validator
7
+ *
8
+ * Validates S3 bucket access and permissions required for the webhook integration.
9
+ */
10
+ class S3BucketValidator {
11
+ /**
12
+ * Validate S3 bucket access and permissions
13
+ *
14
+ * @param config - S3 bucket configuration
15
+ * @returns Validation result with access status and errors
16
+ */
17
+ static async validate(config) {
18
+ const errors = [];
19
+ // Validate bucket name format
20
+ if (!S3BucketValidator.validateBucketName(config.bucketName)) {
21
+ errors.push("Invalid bucket name format");
22
+ return {
23
+ hasAccess: false,
24
+ isConfigured: false,
25
+ errors,
26
+ };
27
+ }
28
+ // Validate region format
29
+ if (!S3BucketValidator.validateRegion(config.region)) {
30
+ errors.push("Invalid AWS region");
31
+ return {
32
+ hasAccess: false,
33
+ isConfigured: false,
34
+ errors,
35
+ };
36
+ }
37
+ // Create S3 client
38
+ const s3Client = new client_s3_1.S3Client({ region: config.region });
39
+ try {
40
+ // Check if bucket exists
41
+ const bucketExists = await S3BucketValidator.checkBucketExists(config.bucketName, config.region, s3Client);
42
+ if (!bucketExists) {
43
+ errors.push("Bucket does not exist");
44
+ return {
45
+ hasAccess: false,
46
+ isConfigured: false,
47
+ errors,
48
+ };
49
+ }
50
+ // Test write permissions
51
+ const hasWritePermission = await S3BucketValidator.testWritePermission(config.bucketName, s3Client);
52
+ if (!hasWritePermission) {
53
+ errors.push("Insufficient write permissions");
54
+ return {
55
+ hasAccess: false,
56
+ isConfigured: false,
57
+ hasWritePermission: false,
58
+ errors,
59
+ };
60
+ }
61
+ // Test read permissions
62
+ const hasReadPermission = await S3BucketValidator.testReadPermission(config.bucketName, s3Client);
63
+ return {
64
+ hasAccess: true,
65
+ isConfigured: true,
66
+ hasWritePermission,
67
+ hasReadPermission,
68
+ errors: [],
69
+ };
70
+ }
71
+ catch (error) {
72
+ if (error instanceof Error) {
73
+ const errorName = error.name || "";
74
+ if (errorName === "NoSuchBucket") {
75
+ errors.push("Bucket does not exist");
76
+ }
77
+ else if (errorName === "AccessDenied" || errorName === "Forbidden") {
78
+ errors.push("Insufficient write permissions");
79
+ }
80
+ else {
81
+ errors.push(`Validation error: ${error.message}`);
82
+ }
83
+ }
84
+ return {
85
+ hasAccess: false,
86
+ isConfigured: false,
87
+ errors,
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * Validate S3 bucket name format
93
+ *
94
+ * @param bucketName - Bucket name to validate
95
+ * @returns True if bucket name is valid
96
+ */
97
+ static validateBucketName(bucketName) {
98
+ if (!bucketName || bucketName.trim() === "") {
99
+ return false;
100
+ }
101
+ // S3 bucket naming rules:
102
+ // - 3-63 characters
103
+ // - lowercase letters, numbers, hyphens, dots
104
+ // - must start and end with letter or number
105
+ const bucketRegex = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;
106
+ // Reject names with uppercase (invalid for S3)
107
+ if (bucketName !== bucketName.toLowerCase()) {
108
+ return false;
109
+ }
110
+ return bucketRegex.test(bucketName);
111
+ }
112
+ /**
113
+ * Validate AWS region format
114
+ *
115
+ * @param region - AWS region to validate
116
+ * @returns True if region format is valid
117
+ */
118
+ static validateRegion(region) {
119
+ if (!region || region.trim() === "") {
120
+ return false;
121
+ }
122
+ return S3BucketValidator.VALID_REGIONS.test(region);
123
+ }
124
+ /**
125
+ * Check if S3 bucket exists
126
+ *
127
+ * @param bucketName - Name of the bucket
128
+ * @param region - AWS region
129
+ * @param s3Client - Optional S3 client instance
130
+ * @returns True if bucket exists
131
+ */
132
+ static async checkBucketExists(bucketName, region, s3Client) {
133
+ const client = s3Client || new client_s3_1.S3Client({ region });
134
+ try {
135
+ const command = new client_s3_1.HeadBucketCommand({ Bucket: bucketName });
136
+ await client.send(command);
137
+ return true;
138
+ }
139
+ catch (error) {
140
+ const errorName = error.name || "";
141
+ if (errorName === "NoSuchBucket" || errorName === "NotFound") {
142
+ return false;
143
+ }
144
+ // For other errors (like AccessDenied), bucket exists but we can't access it
145
+ throw error;
146
+ }
147
+ }
148
+ /**
149
+ * Test write permissions on S3 bucket
150
+ *
151
+ * @param bucketName - Name of the bucket
152
+ * @param s3Client - S3 client instance
153
+ * @returns True if write permission is granted
154
+ */
155
+ static async testWritePermission(bucketName, s3Client) {
156
+ const testKey = `.benchling-webhook-test-${Date.now()}`;
157
+ try {
158
+ // Attempt to write a test object
159
+ const putCommand = new client_s3_1.PutObjectCommand({
160
+ Bucket: bucketName,
161
+ Key: testKey,
162
+ Body: "test",
163
+ });
164
+ await s3Client.send(putCommand);
165
+ // Clean up test object
166
+ const deleteCommand = new client_s3_1.DeleteObjectCommand({
167
+ Bucket: bucketName,
168
+ Key: testKey,
169
+ });
170
+ await s3Client.send(deleteCommand);
171
+ return true;
172
+ }
173
+ catch (error) {
174
+ const errorName = error.name || "";
175
+ if (errorName === "AccessDenied" || errorName === "Forbidden") {
176
+ return false;
177
+ }
178
+ throw error;
179
+ }
180
+ }
181
+ /**
182
+ * Test read permissions on S3 bucket
183
+ *
184
+ * @param bucketName - Name of the bucket
185
+ * @param s3Client - S3 client instance
186
+ * @returns True if read permission is granted
187
+ */
188
+ static async testReadPermission(bucketName, s3Client) {
189
+ const testKey = `.benchling-webhook-test-${Date.now()}`;
190
+ try {
191
+ // First, write a test object
192
+ const putCommand = new client_s3_1.PutObjectCommand({
193
+ Bucket: bucketName,
194
+ Key: testKey,
195
+ Body: "test",
196
+ });
197
+ await s3Client.send(putCommand);
198
+ // Attempt to read the test object
199
+ const getCommand = new client_s3_1.GetObjectCommand({
200
+ Bucket: bucketName,
201
+ Key: testKey,
202
+ });
203
+ await s3Client.send(getCommand);
204
+ // Clean up test object
205
+ const deleteCommand = new client_s3_1.DeleteObjectCommand({
206
+ Bucket: bucketName,
207
+ Key: testKey,
208
+ });
209
+ await s3Client.send(deleteCommand);
210
+ return true;
211
+ }
212
+ catch (error) {
213
+ const errorName = error.name || "";
214
+ if (errorName === "AccessDenied" || errorName === "Forbidden") {
215
+ return false;
216
+ }
217
+ // If we can't read, still try to clean up
218
+ try {
219
+ const deleteCommand = new client_s3_1.DeleteObjectCommand({
220
+ Bucket: bucketName,
221
+ Key: testKey,
222
+ });
223
+ await s3Client.send(deleteCommand);
224
+ }
225
+ catch {
226
+ // Ignore cleanup errors
227
+ }
228
+ throw error;
229
+ }
230
+ }
231
+ }
232
+ exports.S3BucketValidator = S3BucketValidator;
233
+ /**
234
+ * Valid AWS region patterns
235
+ */
236
+ S3BucketValidator.VALID_REGIONS = /^(us|eu|ap|sa|ca|me|af|cn|us-gov)-(north|south|east|west|central|northeast|southeast|southwest|northwest)-\d+$/;
237
+ //# sourceMappingURL=s3-bucket-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-bucket-validator.js","sourceRoot":"","sources":["../../lib/s3-bucket-validator.ts"],"names":[],"mappings":"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"}