@quiltdata/benchling-webhook 0.7.10 → 0.8.0-20251117T215047Z

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 (79) hide show
  1. package/README.md +1 -0
  2. package/dist/bin/cli.js +8 -5
  3. package/dist/bin/cli.js.map +1 -1
  4. package/dist/bin/commands/deploy.d.ts.map +1 -1
  5. package/dist/bin/commands/deploy.js +64 -8
  6. package/dist/bin/commands/deploy.js.map +1 -1
  7. package/dist/bin/commands/health-check.d.ts.map +1 -1
  8. package/dist/bin/commands/health-check.js +2 -35
  9. package/dist/bin/commands/health-check.js.map +1 -1
  10. package/dist/bin/commands/infer-quilt-config.d.ts +6 -0
  11. package/dist/bin/commands/infer-quilt-config.d.ts.map +1 -1
  12. package/dist/bin/commands/infer-quilt-config.js +50 -2
  13. package/dist/bin/commands/infer-quilt-config.js.map +1 -1
  14. package/dist/bin/commands/install.d.ts.map +1 -1
  15. package/dist/bin/commands/install.js +10 -2
  16. package/dist/bin/commands/install.js.map +1 -1
  17. package/dist/bin/commands/manifest.d.ts.map +1 -1
  18. package/dist/bin/commands/manifest.js +2 -3
  19. package/dist/bin/commands/manifest.js.map +1 -1
  20. package/dist/bin/commands/setup-wizard.d.ts +2 -0
  21. package/dist/bin/commands/setup-wizard.d.ts.map +1 -1
  22. package/dist/bin/commands/setup-wizard.js +3 -1
  23. package/dist/bin/commands/setup-wizard.js.map +1 -1
  24. package/dist/bin/commands/status.d.ts +2 -0
  25. package/dist/bin/commands/status.d.ts.map +1 -1
  26. package/dist/bin/commands/status.js +44 -13
  27. package/dist/bin/commands/status.js.map +1 -1
  28. package/dist/bin/commands/sync-secrets.d.ts.map +1 -1
  29. package/dist/bin/commands/sync-secrets.js +2 -35
  30. package/dist/bin/commands/sync-secrets.js.map +1 -1
  31. package/dist/bin/commands/validate.js +1 -1
  32. package/dist/bin/commands/validate.js.map +1 -1
  33. package/dist/bin/xdg-launch.d.ts +74 -0
  34. package/dist/bin/xdg-launch.d.ts.map +1 -0
  35. package/dist/bin/xdg-launch.js +588 -0
  36. package/dist/bin/xdg-launch.js.map +1 -0
  37. package/dist/lib/benchling-webhook-stack.d.ts.map +1 -1
  38. package/dist/lib/benchling-webhook-stack.js +57 -7
  39. package/dist/lib/benchling-webhook-stack.js.map +1 -1
  40. package/dist/lib/fargate-service.d.ts +24 -4
  41. package/dist/lib/fargate-service.d.ts.map +1 -1
  42. package/dist/lib/fargate-service.js +75 -27
  43. package/dist/lib/fargate-service.js.map +1 -1
  44. package/dist/lib/types/config.d.ts +99 -5
  45. package/dist/lib/types/config.d.ts.map +1 -1
  46. package/dist/lib/types/config.js +4 -1
  47. package/dist/lib/types/config.js.map +1 -1
  48. package/dist/lib/utils/service-resolver.d.ts +155 -0
  49. package/dist/lib/utils/service-resolver.d.ts.map +1 -0
  50. package/dist/lib/utils/service-resolver.js +195 -0
  51. package/dist/lib/utils/service-resolver.js.map +1 -0
  52. package/dist/lib/utils/stack-inference.d.ts +58 -0
  53. package/dist/lib/utils/stack-inference.d.ts.map +1 -1
  54. package/dist/lib/utils/stack-inference.js +76 -2
  55. package/dist/lib/utils/stack-inference.js.map +1 -1
  56. package/dist/lib/wizard/phase2-stack-query.d.ts.map +1 -1
  57. package/dist/lib/wizard/phase2-stack-query.js +45 -8
  58. package/dist/lib/wizard/phase2-stack-query.js.map +1 -1
  59. package/dist/lib/wizard/phase4-validation.d.ts.map +1 -1
  60. package/dist/lib/wizard/phase4-validation.js +3 -4
  61. package/dist/lib/wizard/phase4-validation.js.map +1 -1
  62. package/dist/lib/wizard/phase6-integrated-mode.d.ts.map +1 -1
  63. package/dist/lib/wizard/phase6-integrated-mode.js +19 -0
  64. package/dist/lib/wizard/phase6-integrated-mode.js.map +1 -1
  65. package/dist/lib/wizard/phase7-standalone-mode.d.ts.map +1 -1
  66. package/dist/lib/wizard/phase7-standalone-mode.js +24 -10
  67. package/dist/lib/wizard/phase7-standalone-mode.js.map +1 -1
  68. package/dist/lib/wizard/types.d.ts +14 -0
  69. package/dist/lib/wizard/types.d.ts.map +1 -1
  70. package/dist/package.json +16 -7
  71. package/package.json +16 -7
  72. package/dist/lib/utils/config-loader.d.ts +0 -48
  73. package/dist/lib/utils/config-loader.d.ts.map +0 -1
  74. package/dist/lib/utils/config-loader.js +0 -110
  75. package/dist/lib/utils/config-loader.js.map +0 -1
  76. package/dist/lib/utils/config-resolver.d.ts +0 -138
  77. package/dist/lib/utils/config-resolver.d.ts.map +0 -1
  78. package/dist/lib/utils/config-resolver.js +0 -279
  79. package/dist/lib/utils/config-resolver.js.map +0 -1
@@ -1,110 +0,0 @@
1
- "use strict";
2
- /**
3
- * Configuration loading helpers for application startup
4
- *
5
- * Provides simplified configuration loading for both production (from AWS)
6
- * and testing (from environment variables).
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.loadConfig = loadConfig;
10
- exports.loadConfigForTesting = loadConfigForTesting;
11
- exports.formatConfigError = formatConfigError;
12
- const config_resolver_1 = require("./config-resolver");
13
- /**
14
- * Load configuration for production (from AWS CloudFormation and Secrets Manager)
15
- *
16
- * Reads QuiltStackARN and BenchlingSecret from environment variables and
17
- * resolves complete configuration by querying AWS APIs.
18
- *
19
- * @returns Complete resolved configuration
20
- * @throws Error if required environment variables are missing
21
- * @throws ConfigResolverError if AWS resolution fails
22
- *
23
- * @example
24
- * // In production/container
25
- * const config = await loadConfig();
26
- * console.log(`Database: ${config.quiltDatabase}`);
27
- */
28
- async function loadConfig() {
29
- const quiltStackArn = process.env.QuiltStackARN;
30
- const benchlingSecret = process.env.BenchlingSecret;
31
- if (!quiltStackArn || !benchlingSecret) {
32
- const missing = [];
33
- if (!quiltStackArn)
34
- missing.push("QuiltStackARN");
35
- if (!benchlingSecret)
36
- missing.push("BenchlingSecret");
37
- throw new Error(`Missing required environment variables: ${missing.join(", ")}\n\n` +
38
- "The container requires exactly 2 environment variables:\n" +
39
- " QuiltStackARN: ARN of your Quilt CloudFormation stack\n" +
40
- " Example: arn:aws:cloudformation:us-east-1:123456789012:stack/QuiltStack/abc-123\n\n" +
41
- " BenchlingSecret: Name or ARN of AWS Secrets Manager secret\n" +
42
- " Example: my-benchling-creds\n\n" +
43
- "Documentation: https://github.com/quiltdata/benchling-webhook#configuration");
44
- }
45
- const resolver = new config_resolver_1.ConfigResolver();
46
- return await resolver.resolve({
47
- stackArn: quiltStackArn,
48
- benchlingSecret,
49
- });
50
- }
51
- /**
52
- * Load configuration for testing (from environment variables directly)
53
- *
54
- * Only available when NODE_ENV=test. Provides backward compatibility
55
- * with existing test suite by reading configuration from individual
56
- * environment variables instead of AWS services.
57
- *
58
- * @returns Partial configuration from environment variables
59
- * @throws Error if called outside test environment
60
- *
61
- * @example
62
- * // In test files
63
- * process.env.NODE_ENV = 'test';
64
- * process.env.QUILT_CATALOG = 'test.catalog.com';
65
- * const config = loadConfigForTesting();
66
- */
67
- function loadConfigForTesting() {
68
- if (process.env.NODE_ENV !== "test") {
69
- throw new Error("loadConfigForTesting() should only be used in test environment (NODE_ENV=test)");
70
- }
71
- return {
72
- // AWS
73
- awsRegion: process.env.AWS_REGION || process.env.CDK_DEFAULT_REGION || "us-east-1",
74
- awsAccount: process.env.CDK_DEFAULT_ACCOUNT || "123456789012",
75
- // Quilt
76
- quiltCatalog: process.env.QUILT_CATALOG || "test.catalog.com",
77
- quiltDatabase: process.env.QUILT_DATABASE || "test_db",
78
- quiltUserBucket: process.env.QUILT_USER_BUCKET || "test-bucket",
79
- queueUrl: process.env.QUEUE_URL ||
80
- "https://sqs.us-east-1.amazonaws.com/123456789012/test-queue",
81
- // Benchling
82
- benchlingTenant: process.env.BENCHLING_TENANT || "test-tenant",
83
- benchlingClientId: process.env.BENCHLING_CLIENT_ID || "test-client-id",
84
- benchlingClientSecret: process.env.BENCHLING_CLIENT_SECRET || "test-client-secret",
85
- benchlingAppDefinitionId: process.env.BENCHLING_APP_DEFINITION_ID,
86
- benchlingApiUrl: process.env.BENCHLING_API_URL,
87
- // Optional
88
- pkgPrefix: process.env.PKG_PREFIX || "benchling",
89
- pkgKey: process.env.PKG_KEY || "experiment_id",
90
- logLevel: process.env.LOG_LEVEL || "INFO",
91
- webhookAllowList: process.env.WEBHOOK_ALLOW_LIST,
92
- enableWebhookVerification: process.env.ENABLE_WEBHOOK_VERIFICATION !== "false",
93
- };
94
- }
95
- /**
96
- * Format ConfigResolverError for console output
97
- *
98
- * @param error - The error to format
99
- * @returns Formatted error message
100
- */
101
- function formatConfigError(error) {
102
- if (error instanceof config_resolver_1.ConfigResolverError) {
103
- return error.format();
104
- }
105
- if (error instanceof Error) {
106
- return `Error: ${error.message}`;
107
- }
108
- return `Unknown error: ${String(error)}`;
109
- }
110
- //# sourceMappingURL=config-loader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../../lib/utils/config-loader.ts"],"names":[],"mappings":"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"}
@@ -1,138 +0,0 @@
1
- /**
2
- * Configuration Resolver for Secrets-Only Architecture
3
- *
4
- * This module resolves complete application configuration from just two sources:
5
- * 1. QuiltStackARN - CloudFormation stack ARN for Quilt infrastructure
6
- * 2. BenchlingSecret - AWS Secrets Manager secret containing Benchling credentials
7
- *
8
- * All other configuration is derived from these two sources by querying AWS APIs.
9
- */
10
- import { CloudFormationClient } from "@aws-sdk/client-cloudformation";
11
- import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
12
- import { type BenchlingSecretData } from "./secrets";
13
- /**
14
- * Complete resolved configuration for the application
15
- */
16
- export interface ResolvedConfig {
17
- awsRegion: string;
18
- awsAccount: string;
19
- quiltCatalog: string;
20
- quiltDatabase: string;
21
- quiltUserBucket: string;
22
- queueUrl: string;
23
- benchlingTenant: string;
24
- benchlingClientId: string;
25
- benchlingClientSecret: string;
26
- benchlingAppDefinitionId?: string;
27
- benchlingApiUrl?: string;
28
- pkgPrefix?: string;
29
- pkgKey?: string;
30
- logLevel?: string;
31
- webhookAllowList?: string;
32
- enableWebhookVerification?: boolean;
33
- }
34
- /**
35
- * Options for ConfigResolver
36
- */
37
- export interface ConfigResolverOptions {
38
- stackArn: string;
39
- benchlingSecret: string;
40
- mockCloudFormation?: CloudFormationClient;
41
- mockSecretsManager?: SecretsManagerClient;
42
- }
43
- /**
44
- * Parsed CloudFormation stack ARN
45
- */
46
- export interface ParsedStackArn {
47
- region: string;
48
- account: string;
49
- stackName: string;
50
- stackId: string;
51
- }
52
- /**
53
- * Custom error for configuration resolution failures
54
- */
55
- export declare class ConfigResolverError extends Error {
56
- readonly suggestion?: string | undefined;
57
- readonly details?: string | undefined;
58
- constructor(message: string, suggestion?: string | undefined, details?: string | undefined);
59
- /**
60
- * Format error for CLI/logs with suggestions
61
- */
62
- format(): string;
63
- }
64
- /**
65
- * Parse CloudFormation stack ARN into components
66
- *
67
- * @param arn - CloudFormation stack ARN
68
- * @returns Parsed ARN components
69
- * @throws ConfigResolverError if ARN is invalid
70
- *
71
- * @example
72
- * parseStackArn('arn:aws:cloudformation:us-east-1:123456789012:stack/QuiltStack/abc-123')
73
- * // Returns: { region: 'us-east-1', account: '123456789012', stackName: 'QuiltStack', stackId: 'abc-123' }
74
- */
75
- export declare function parseStackArn(arn: string): ParsedStackArn;
76
- /**
77
- * Extract stack outputs from CloudFormation
78
- *
79
- * @param client - CloudFormation client
80
- * @param stackName - Name of the stack
81
- * @returns Map of output keys to values
82
- * @throws ConfigResolverError if stack not found or inaccessible
83
- */
84
- export declare function extractStackOutputs(client: CloudFormationClient, stackName: string): Promise<Record<string, string>>;
85
- /**
86
- * Fetch and validate secret from AWS Secrets Manager
87
- *
88
- * @param client - Secrets Manager client
89
- * @param region - AWS region
90
- * @param secretIdentifier - Secret name or ARN
91
- * @returns Validated secret data
92
- * @throws ConfigResolverError if secret not found or invalid
93
- */
94
- export declare function resolveAndFetchSecret(client: SecretsManagerClient, region: string, secretIdentifier: string): Promise<BenchlingSecretData>;
95
- /**
96
- * Main configuration resolver class
97
- *
98
- * Resolves complete application configuration from CloudFormation and Secrets Manager.
99
- * Implements caching to avoid repeated AWS API calls.
100
- */
101
- export declare class ConfigResolver {
102
- private cache;
103
- /**
104
- * Resolve complete configuration from AWS
105
- *
106
- * @param options - Configuration resolver options
107
- * @returns Complete resolved configuration
108
- * @throws ConfigResolverError if resolution fails
109
- */
110
- resolve(options: ConfigResolverOptions): Promise<ResolvedConfig>;
111
- /**
112
- * Validate that required CloudFormation outputs are present
113
- *
114
- * @param outputs - Stack outputs
115
- * @throws ConfigResolverError if required outputs are missing
116
- */
117
- private validateRequiredOutputs;
118
- /**
119
- * Resolve catalog URL from stack outputs
120
- *
121
- * @param outputs - Stack outputs
122
- * @returns Normalized catalog URL (hostname only)
123
- * @throws ConfigResolverError if catalog URL cannot be determined
124
- */
125
- private resolveCatalogUrl;
126
- /**
127
- * Normalize catalog URL to hostname only (remove protocol and trailing slash)
128
- *
129
- * @param url - Catalog URL
130
- * @returns Normalized hostname
131
- */
132
- private normalizeCatalogUrl;
133
- /**
134
- * Clear cached configuration (for testing only)
135
- */
136
- clearCache(): void;
137
- }
138
- //# sourceMappingURL=config-resolver.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-resolver.d.ts","sourceRoot":"","sources":["../../../lib/utils/config-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACH,oBAAoB,EAEvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACH,oBAAoB,EAEvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEH,KAAK,mBAAmB,EAC3B,MAAM,WAAW,CAAC;AAGnB;;GAEG;AACH,MAAM,WAAW,cAAc;IAE7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IAGnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IAGjB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IAGxB,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IAC1C,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,UAAU,CAAC,EAAE,MAAM;aACnB,OAAO,CAAC,EAAE,MAAM;gBAF5B,OAAO,EAAE,MAAM,EACH,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,OAAO,CAAC,EAAE,MAAM,YAAA;IAUhC;;KAEC;IACD,MAAM,IAAI,MAAM;CAanB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAqBzD;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiCjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACvC,MAAM,EAAE,oBAAoB,EAC5B,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,GACzB,OAAO,CAAC,mBAAmB,CAAC,CAiE9B;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,KAAK,CAA+B;IAE5C;;;;;;KAMC;IACK,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC;IA6EtE;;;;;KAKC;IACD,OAAO,CAAC,uBAAuB;IAoB/B;;;;;;KAMC;IACD,OAAO,CAAC,iBAAiB;IA0BzB;;;;;KAKC;IACD,OAAO,CAAC,mBAAmB;IAI3B;;KAEC;IACD,UAAU,IAAI,IAAI;CAGrB"}
@@ -1,279 +0,0 @@
1
- "use strict";
2
- /**
3
- * Configuration Resolver for Secrets-Only Architecture
4
- *
5
- * This module resolves complete application configuration from just two sources:
6
- * 1. QuiltStackARN - CloudFormation stack ARN for Quilt infrastructure
7
- * 2. BenchlingSecret - AWS Secrets Manager secret containing Benchling credentials
8
- *
9
- * All other configuration is derived from these two sources by querying AWS APIs.
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.ConfigResolver = exports.ConfigResolverError = void 0;
13
- exports.parseStackArn = parseStackArn;
14
- exports.extractStackOutputs = extractStackOutputs;
15
- exports.resolveAndFetchSecret = resolveAndFetchSecret;
16
- const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
17
- const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager");
18
- const secrets_1 = require("./secrets");
19
- const sqs_1 = require("./sqs");
20
- /**
21
- * Custom error for configuration resolution failures
22
- */
23
- class ConfigResolverError extends Error {
24
- constructor(message, suggestion, details) {
25
- super(message);
26
- this.suggestion = suggestion;
27
- this.details = details;
28
- this.name = "ConfigResolverError";
29
- if (Error.captureStackTrace) {
30
- Error.captureStackTrace(this, ConfigResolverError);
31
- }
32
- }
33
- /**
34
- * Format error for CLI/logs with suggestions
35
- */
36
- format() {
37
- let output = `❌ Configuration Error: ${this.message}`;
38
- if (this.suggestion) {
39
- output += `\n 💡 ${this.suggestion}`;
40
- }
41
- if (this.details) {
42
- output += `\n ℹ️ ${this.details}`;
43
- }
44
- return output;
45
- }
46
- }
47
- exports.ConfigResolverError = ConfigResolverError;
48
- /**
49
- * Parse CloudFormation stack ARN into components
50
- *
51
- * @param arn - CloudFormation stack ARN
52
- * @returns Parsed ARN components
53
- * @throws ConfigResolverError if ARN is invalid
54
- *
55
- * @example
56
- * parseStackArn('arn:aws:cloudformation:us-east-1:123456789012:stack/QuiltStack/abc-123')
57
- * // Returns: { region: 'us-east-1', account: '123456789012', stackName: 'QuiltStack', stackId: 'abc-123' }
58
- */
59
- function parseStackArn(arn) {
60
- const pattern = /^arn:aws:cloudformation:([a-z0-9-]+):(\d{12}):stack\/([^/]+)\/(.+)$/;
61
- const match = arn.match(pattern);
62
- if (!match) {
63
- throw new ConfigResolverError("Invalid CloudFormation stack ARN format", "ARN must match: arn:aws:cloudformation:region:account:stack/name/id", `Received: ${arn}`);
64
- }
65
- const [, region, account, stackName, stackId] = match;
66
- return {
67
- region,
68
- account,
69
- stackName,
70
- stackId,
71
- };
72
- }
73
- /**
74
- * Extract stack outputs from CloudFormation
75
- *
76
- * @param client - CloudFormation client
77
- * @param stackName - Name of the stack
78
- * @returns Map of output keys to values
79
- * @throws ConfigResolverError if stack not found or inaccessible
80
- */
81
- async function extractStackOutputs(client, stackName) {
82
- const command = new client_cloudformation_1.DescribeStacksCommand({ StackName: stackName });
83
- try {
84
- const response = await client.send(command);
85
- const stack = response.Stacks?.[0];
86
- if (!stack) {
87
- throw new ConfigResolverError(`Stack not found: ${stackName}`, "Ensure the CloudFormation stack exists and is accessible");
88
- }
89
- const outputs = stack.Outputs || [];
90
- return Object.fromEntries(outputs.map((o) => [o.OutputKey, o.OutputValue]));
91
- }
92
- catch (error) {
93
- if (error instanceof ConfigResolverError) {
94
- throw error;
95
- }
96
- if (error.name === "ValidationError") {
97
- throw new ConfigResolverError(`Invalid stack name: ${stackName}`, "Check that the stack name is correct");
98
- }
99
- throw new ConfigResolverError(`Failed to describe stack: ${error.message}`, "Check AWS credentials and permissions");
100
- }
101
- }
102
- /**
103
- * Fetch and validate secret from AWS Secrets Manager
104
- *
105
- * @param client - Secrets Manager client
106
- * @param region - AWS region
107
- * @param secretIdentifier - Secret name or ARN
108
- * @returns Validated secret data
109
- * @throws ConfigResolverError if secret not found or invalid
110
- */
111
- async function resolveAndFetchSecret(client, region, secretIdentifier) {
112
- try {
113
- const command = new client_secrets_manager_1.GetSecretValueCommand({ SecretId: secretIdentifier });
114
- const response = await client.send(command);
115
- if (!response.SecretString) {
116
- throw new ConfigResolverError("Secret does not contain string data", "Ensure secret is stored as JSON string, not binary");
117
- }
118
- // Parse JSON
119
- let data;
120
- try {
121
- data = JSON.parse(response.SecretString);
122
- }
123
- catch (parseError) {
124
- throw new ConfigResolverError("Secret contains invalid JSON", "Ensure secret value is valid JSON", `Parse error: ${parseError.message}`);
125
- }
126
- // Validate structure
127
- const validation = (0, secrets_1.validateSecretData)(data);
128
- if (!validation.valid) {
129
- const errors = validation.errors
130
- .map((e) => `${e.field}: ${e.message}`)
131
- .join("; ");
132
- throw new ConfigResolverError("Invalid secret structure", errors, "Expected format: {\"client_id\":\"...\",\"client_secret\":\"...\",\"tenant\":\"...\"}");
133
- }
134
- return data;
135
- }
136
- catch (error) {
137
- if (error instanceof ConfigResolverError) {
138
- throw error;
139
- }
140
- if (error.name === "ResourceNotFoundException") {
141
- throw new ConfigResolverError(`Secret not found: ${secretIdentifier}`, "Ensure the secret exists in AWS Secrets Manager and is accessible", `Region: ${region}`);
142
- }
143
- if (error.name === "AccessDeniedException") {
144
- throw new ConfigResolverError(`Access denied to secret: ${secretIdentifier}`, "Ensure the IAM role has secretsmanager:GetSecretValue permission", `Region: ${region}`);
145
- }
146
- throw new ConfigResolverError(`Failed to fetch secret: ${error.message}`, "Check AWS credentials and permissions");
147
- }
148
- }
149
- /**
150
- * Main configuration resolver class
151
- *
152
- * Resolves complete application configuration from CloudFormation and Secrets Manager.
153
- * Implements caching to avoid repeated AWS API calls.
154
- */
155
- class ConfigResolver {
156
- constructor() {
157
- this.cache = null;
158
- }
159
- /**
160
- * Resolve complete configuration from AWS
161
- *
162
- * @param options - Configuration resolver options
163
- * @returns Complete resolved configuration
164
- * @throws ConfigResolverError if resolution fails
165
- */
166
- async resolve(options) {
167
- // Return cached config if available
168
- if (this.cache) {
169
- return this.cache;
170
- }
171
- // Step 1: Parse stack ARN
172
- const parsed = parseStackArn(options.stackArn);
173
- // Step 2: Create AWS clients (or use mocks for testing)
174
- const cfnClient = options.mockCloudFormation ||
175
- new client_cloudformation_1.CloudFormationClient({ region: parsed.region });
176
- const smClient = options.mockSecretsManager ||
177
- new client_secrets_manager_1.SecretsManagerClient({ region: parsed.region });
178
- // Step 3: Fetch stack outputs
179
- const outputs = await extractStackOutputs(cfnClient, parsed.stackName);
180
- // Step 4: Validate required outputs
181
- this.validateRequiredOutputs(outputs);
182
- // Extract queue URL
183
- const queueUrl = outputs.PackagerQueueUrl;
184
- if (!queueUrl || !(0, sqs_1.isQueueUrl)(queueUrl)) {
185
- throw new ConfigResolverError("Missing SQS queue URL in CloudFormation outputs", "Ensure your Quilt stack exports PackagerQueueUrl", `Available outputs: ${Object.keys(outputs).join(", ")}`);
186
- }
187
- // Step 5: Fetch Benchling secret
188
- const secret = await resolveAndFetchSecret(smClient, parsed.region, options.benchlingSecret);
189
- // Step 6: Resolve catalog URL
190
- const catalog = this.resolveCatalogUrl(outputs);
191
- // Step 7: Assemble complete configuration
192
- const config = {
193
- // AWS
194
- awsRegion: parsed.region,
195
- awsAccount: parsed.account,
196
- // Quilt
197
- quiltCatalog: catalog,
198
- quiltDatabase: outputs.UserAthenaDatabaseName,
199
- quiltUserBucket: outputs.UserBucket || outputs.BucketName,
200
- queueUrl,
201
- // Benchling
202
- benchlingTenant: secret.tenant,
203
- benchlingClientId: secret.client_id,
204
- benchlingClientSecret: secret.client_secret,
205
- benchlingAppDefinitionId: secret.app_definition_id,
206
- benchlingApiUrl: secret.api_url,
207
- // Optional defaults
208
- pkgPrefix: "benchling",
209
- pkgKey: "experiment_id",
210
- logLevel: "INFO",
211
- enableWebhookVerification: true,
212
- };
213
- // Cache for container lifetime
214
- this.cache = config;
215
- return config;
216
- }
217
- /**
218
- * Validate that required CloudFormation outputs are present
219
- *
220
- * @param outputs - Stack outputs
221
- * @throws ConfigResolverError if required outputs are missing
222
- */
223
- validateRequiredOutputs(outputs) {
224
- const missing = [];
225
- if (!outputs.UserAthenaDatabaseName) {
226
- missing.push("UserAthenaDatabaseName");
227
- }
228
- if (!outputs.PackagerQueueUrl) {
229
- missing.push("PackagerQueueUrl");
230
- }
231
- if (missing.length > 0) {
232
- throw new ConfigResolverError(`Missing required CloudFormation outputs: ${missing.join(", ")}`, "Ensure your Quilt stack exports these outputs", `Available outputs: ${Object.keys(outputs).join(", ")}`);
233
- }
234
- }
235
- /**
236
- * Resolve catalog URL from stack outputs
237
- *
238
- * @param outputs - Stack outputs
239
- * @returns Normalized catalog URL (hostname only)
240
- * @throws ConfigResolverError if catalog URL cannot be determined
241
- */
242
- resolveCatalogUrl(outputs) {
243
- // Option 1: Direct from Catalog or CatalogDomain output
244
- if (outputs.Catalog) {
245
- return this.normalizeCatalogUrl(outputs.Catalog);
246
- }
247
- if (outputs.CatalogDomain) {
248
- return this.normalizeCatalogUrl(outputs.CatalogDomain);
249
- }
250
- // Option 2: Extract from API Gateway endpoint
251
- if (outputs.ApiGatewayEndpoint) {
252
- try {
253
- const url = new URL(outputs.ApiGatewayEndpoint);
254
- return url.hostname;
255
- }
256
- catch {
257
- // Invalid URL, fall through to error
258
- }
259
- }
260
- throw new ConfigResolverError("Cannot determine catalog URL", "Stack must export \"Catalog\", \"CatalogDomain\", or \"ApiGatewayEndpoint\"");
261
- }
262
- /**
263
- * Normalize catalog URL to hostname only (remove protocol and trailing slash)
264
- *
265
- * @param url - Catalog URL
266
- * @returns Normalized hostname
267
- */
268
- normalizeCatalogUrl(url) {
269
- return url.replace(/^https?:\/\//, "").replace(/\/$/, "");
270
- }
271
- /**
272
- * Clear cached configuration (for testing only)
273
- */
274
- clearCache() {
275
- this.cache = null;
276
- }
277
- }
278
- exports.ConfigResolver = ConfigResolver;
279
- //# sourceMappingURL=config-resolver.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-resolver.js","sourceRoot":"","sources":["../../../lib/utils/config-resolver.ts"],"names":[],"mappings":"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"}