@quiltdata/benchling-webhook 0.7.9 → 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.
- package/README.md +1 -0
- package/dist/bin/benchling-webhook.js +4 -2
- package/dist/bin/benchling-webhook.js.map +1 -1
- package/dist/bin/cli.js +15 -7
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/commands/deploy.d.ts.map +1 -1
- package/dist/bin/commands/deploy.js +64 -8
- package/dist/bin/commands/deploy.js.map +1 -1
- package/dist/bin/commands/health-check.d.ts.map +1 -1
- package/dist/bin/commands/health-check.js +2 -35
- package/dist/bin/commands/health-check.js.map +1 -1
- package/dist/bin/commands/infer-quilt-config.d.ts +6 -0
- package/dist/bin/commands/infer-quilt-config.d.ts.map +1 -1
- package/dist/bin/commands/infer-quilt-config.js +127 -49
- package/dist/bin/commands/infer-quilt-config.js.map +1 -1
- package/dist/bin/commands/install.d.ts.map +1 -1
- package/dist/bin/commands/install.js +13 -17
- package/dist/bin/commands/install.js.map +1 -1
- package/dist/bin/commands/logs.d.ts.map +1 -1
- package/dist/bin/commands/logs.js +4 -128
- package/dist/bin/commands/logs.js.map +1 -1
- package/dist/bin/commands/manifest.d.ts.map +1 -1
- package/dist/bin/commands/manifest.js +2 -3
- package/dist/bin/commands/manifest.js.map +1 -1
- package/dist/bin/commands/setup-wizard.d.ts +2 -0
- package/dist/bin/commands/setup-wizard.d.ts.map +1 -1
- package/dist/bin/commands/setup-wizard.js +5 -5
- package/dist/bin/commands/setup-wizard.js.map +1 -1
- package/dist/bin/commands/status.d.ts +49 -0
- package/dist/bin/commands/status.d.ts.map +1 -1
- package/dist/bin/commands/status.js +666 -41
- package/dist/bin/commands/status.js.map +1 -1
- package/dist/bin/commands/sync-secrets.d.ts.map +1 -1
- package/dist/bin/commands/sync-secrets.js +3 -36
- package/dist/bin/commands/sync-secrets.js.map +1 -1
- package/dist/bin/commands/validate.js +1 -1
- package/dist/bin/commands/validate.js.map +1 -1
- package/dist/bin/xdg-launch.d.ts +74 -0
- package/dist/bin/xdg-launch.d.ts.map +1 -0
- package/dist/bin/xdg-launch.js +588 -0
- package/dist/bin/xdg-launch.js.map +1 -0
- package/dist/lib/benchling-webhook-stack.d.ts.map +1 -1
- package/dist/lib/benchling-webhook-stack.js +59 -7
- package/dist/lib/benchling-webhook-stack.js.map +1 -1
- package/dist/lib/fargate-service.d.ts +24 -4
- package/dist/lib/fargate-service.d.ts.map +1 -1
- package/dist/lib/fargate-service.js +75 -27
- package/dist/lib/fargate-service.js.map +1 -1
- package/dist/lib/types/config.d.ts +99 -5
- package/dist/lib/types/config.d.ts.map +1 -1
- package/dist/lib/types/config.js +4 -1
- package/dist/lib/types/config.js.map +1 -1
- package/dist/lib/utils/service-resolver.d.ts +155 -0
- package/dist/lib/utils/service-resolver.d.ts.map +1 -0
- package/dist/lib/utils/service-resolver.js +195 -0
- package/dist/lib/utils/service-resolver.js.map +1 -0
- package/dist/lib/utils/stack-inference.d.ts +58 -0
- package/dist/lib/utils/stack-inference.d.ts.map +1 -1
- package/dist/lib/utils/stack-inference.js +76 -2
- package/dist/lib/utils/stack-inference.js.map +1 -1
- package/dist/lib/utils/stack-parameter-update.js +2 -2
- package/dist/lib/utils/stack-parameter-update.js.map +1 -1
- package/dist/lib/wizard/phase2-stack-query.d.ts.map +1 -1
- package/dist/lib/wizard/phase2-stack-query.js +46 -9
- package/dist/lib/wizard/phase2-stack-query.js.map +1 -1
- package/dist/lib/wizard/phase3-parameter-collection.js +5 -5
- package/dist/lib/wizard/phase3-parameter-collection.js.map +1 -1
- package/dist/lib/wizard/phase4-validation.d.ts.map +1 -1
- package/dist/lib/wizard/phase4-validation.js +4 -5
- package/dist/lib/wizard/phase4-validation.js.map +1 -1
- package/dist/lib/wizard/phase5-mode-decision.js +1 -1
- package/dist/lib/wizard/phase5-mode-decision.js.map +1 -1
- package/dist/lib/wizard/phase6-integrated-mode.d.ts.map +1 -1
- package/dist/lib/wizard/phase6-integrated-mode.js +19 -0
- package/dist/lib/wizard/phase6-integrated-mode.js.map +1 -1
- package/dist/lib/wizard/phase7-standalone-mode.d.ts.map +1 -1
- package/dist/lib/wizard/phase7-standalone-mode.js +24 -10
- package/dist/lib/wizard/phase7-standalone-mode.js.map +1 -1
- package/dist/lib/wizard/types.d.ts +14 -0
- package/dist/lib/wizard/types.d.ts.map +1 -1
- package/dist/package.json +20 -9
- package/package.json +20 -9
- package/dist/lib/utils/config-loader.d.ts +0 -48
- package/dist/lib/utils/config-loader.d.ts.map +0 -1
- package/dist/lib/utils/config-loader.js +0 -110
- package/dist/lib/utils/config-loader.js.map +0 -1
- package/dist/lib/utils/config-resolver.d.ts +0 -138
- package/dist/lib/utils/config-resolver.d.ts.map +0 -1
- package/dist/lib/utils/config-resolver.js +0 -279
- package/dist/lib/utils/config-resolver.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quiltdata/benchling-webhook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-20251117T215047Z",
|
|
4
4
|
"description": "AWS CDK deployment for Benchling webhook processing using Fargate - Deploy directly with npx",
|
|
5
5
|
"main": "dist/lib/index.js",
|
|
6
6
|
"types": "dist/lib/index.d.ts",
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
"deploy:dev": "ts-node bin/cli.ts deploy --stage dev --profile dev",
|
|
22
22
|
"deploy:prod": "ts-node bin/cli.ts deploy --stage prod",
|
|
23
23
|
"deploy:notes": "bash scripts/release-notes.sh",
|
|
24
|
+
"launch": "ts-node bin/xdg-launch.ts",
|
|
25
|
+
"dev": "npm run launch -- --mode native --profile dev --verbose",
|
|
26
|
+
"dev:docker": "npm run launch -- --mode docker-dev --profile dev --verbose",
|
|
27
|
+
"dev:prod": "npm run launch -- --mode docker --profile dev",
|
|
24
28
|
"logs": "ts-node scripts/check-logs.ts",
|
|
25
29
|
"logs:watch": "ts-node scripts/check-logs.ts --type=ecs --follow",
|
|
26
30
|
"lint": "eslint . --ext .ts --fix && make -C docker lint",
|
|
@@ -34,17 +38,22 @@
|
|
|
34
38
|
"setup:infer": "ts-node bin/commands/infer-quilt-config.ts",
|
|
35
39
|
"setup:profile": "ts-node bin/cli.ts setup-profile",
|
|
36
40
|
"setup:sync-secrets": "ts-node bin/commands/sync-secrets.ts",
|
|
37
|
-
"test": "npm run build:typecheck && npm run test:ts && npm run test:python",
|
|
38
|
-
"test:ci": "npm run build:typecheck && npm run test:
|
|
41
|
+
"test": "npm run lint && npm run build:typecheck && npm run test:ts && npm run test:python",
|
|
42
|
+
"test:ci": "npm run lint && npm run build:typecheck && npm run test:unit",
|
|
43
|
+
"test:unit": "cross-env NODE_ENV=test jest --testPathIgnorePatterns='/test/integration/' --maxWorkers=50%",
|
|
44
|
+
"test:local": "npm run launch -- --mode docker-dev --profile dev --test",
|
|
45
|
+
"test:local:prod": "npm run launch -- --mode docker --profile dev --test",
|
|
46
|
+
"test:native": "npm run launch -- --mode native --profile dev --test",
|
|
39
47
|
"test:dev": "make -C docker test-deployed-dev PROFILE=dev",
|
|
40
|
-
"test:
|
|
41
|
-
"test:prod": "make -C docker test-deployed-prod",
|
|
48
|
+
"test:prod": "make -C docker test-deployed-prod PROFILE=default",
|
|
42
49
|
"test:python": "make -C docker test-unit",
|
|
43
|
-
"test:ts": "cross-env NODE_ENV=test jest --maxWorkers=50%",
|
|
50
|
+
"test:ts": "cross-env NODE_ENV=test NODE_OPTIONS='--experimental-vm-modules' jest --maxWorkers=50%",
|
|
44
51
|
"version": "ts-node scripts/version.ts",
|
|
45
52
|
"version:dev": "ts-node scripts/get-dev-version.ts",
|
|
46
|
-
"version:tag": "npm
|
|
47
|
-
"version:tag:dev": "npm
|
|
53
|
+
"version:tag": "npm test && ts-node scripts/version.ts tag",
|
|
54
|
+
"version:tag:dev": "npm test && ts-node scripts/version.ts tag dev",
|
|
55
|
+
"test:integration": "cross-env NODE_ENV=test NODE_OPTIONS='--experimental-vm-modules' jest --testMatch='**/test/integration/**/*.test.ts' --runInBand",
|
|
56
|
+
"test:integration:verbose": "npm run test:integration -- --verbose"
|
|
48
57
|
},
|
|
49
58
|
"keywords": [
|
|
50
59
|
"benchling",
|
|
@@ -85,8 +94,10 @@
|
|
|
85
94
|
},
|
|
86
95
|
"dependencies": {
|
|
87
96
|
"@aws-sdk/client-cloudformation": "^3.920.0",
|
|
97
|
+
"@aws-sdk/client-ecs": "^3.932.0",
|
|
98
|
+
"@aws-sdk/client-elastic-load-balancing-v2": "^3.932.0",
|
|
88
99
|
"@aws-sdk/client-s3": "^3.758.0",
|
|
89
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
|
100
|
+
"@aws-sdk/client-secrets-manager": "^3.932.0",
|
|
90
101
|
"@aws-sdk/client-sts": "^3.922.0",
|
|
91
102
|
"@aws-sdk/credential-providers": "^3.922.0",
|
|
92
103
|
"@types/inquirer": "^9.0.9",
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Configuration loading helpers for application startup
|
|
3
|
-
*
|
|
4
|
-
* Provides simplified configuration loading for both production (from AWS)
|
|
5
|
-
* and testing (from environment variables).
|
|
6
|
-
*/
|
|
7
|
-
import { type ResolvedConfig } from "./config-resolver";
|
|
8
|
-
/**
|
|
9
|
-
* Load configuration for production (from AWS CloudFormation and Secrets Manager)
|
|
10
|
-
*
|
|
11
|
-
* Reads QuiltStackARN and BenchlingSecret from environment variables and
|
|
12
|
-
* resolves complete configuration by querying AWS APIs.
|
|
13
|
-
*
|
|
14
|
-
* @returns Complete resolved configuration
|
|
15
|
-
* @throws Error if required environment variables are missing
|
|
16
|
-
* @throws ConfigResolverError if AWS resolution fails
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* // In production/container
|
|
20
|
-
* const config = await loadConfig();
|
|
21
|
-
* console.log(`Database: ${config.quiltDatabase}`);
|
|
22
|
-
*/
|
|
23
|
-
export declare function loadConfig(): Promise<ResolvedConfig>;
|
|
24
|
-
/**
|
|
25
|
-
* Load configuration for testing (from environment variables directly)
|
|
26
|
-
*
|
|
27
|
-
* Only available when NODE_ENV=test. Provides backward compatibility
|
|
28
|
-
* with existing test suite by reading configuration from individual
|
|
29
|
-
* environment variables instead of AWS services.
|
|
30
|
-
*
|
|
31
|
-
* @returns Partial configuration from environment variables
|
|
32
|
-
* @throws Error if called outside test environment
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* // In test files
|
|
36
|
-
* process.env.NODE_ENV = 'test';
|
|
37
|
-
* process.env.QUILT_CATALOG = 'test.catalog.com';
|
|
38
|
-
* const config = loadConfigForTesting();
|
|
39
|
-
*/
|
|
40
|
-
export declare function loadConfigForTesting(): Partial<ResolvedConfig>;
|
|
41
|
-
/**
|
|
42
|
-
* Format ConfigResolverError for console output
|
|
43
|
-
*
|
|
44
|
-
* @param error - The error to format
|
|
45
|
-
* @returns Formatted error message
|
|
46
|
-
*/
|
|
47
|
-
export declare function formatConfigError(error: unknown): string;
|
|
48
|
-
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../lib/utils/config-loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAkB,KAAK,cAAc,EAAuB,MAAM,mBAAmB,CAAC;AAE7F;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAyB1D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAAC,cAAc,CAAC,CAiC9D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUxD"}
|
|
@@ -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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"}
|