@quiltdata/benchling-webhook 0.4.13 → 0.5.0-20251029T180511Z

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 (87) hide show
  1. package/dist/bin/benchling-webhook.d.ts +50 -0
  2. package/dist/bin/benchling-webhook.d.ts.map +1 -0
  3. package/dist/bin/benchling-webhook.js +268 -0
  4. package/dist/bin/benchling-webhook.js.map +1 -0
  5. package/dist/bin/cli.d.ts +3 -0
  6. package/dist/bin/cli.d.ts.map +1 -0
  7. package/dist/bin/cli.js +83 -0
  8. package/dist/bin/cli.js.map +1 -0
  9. package/dist/bin/commands/deploy.d.ts +7 -0
  10. package/dist/bin/commands/deploy.d.ts.map +1 -0
  11. package/dist/bin/commands/deploy.js +154 -0
  12. package/dist/bin/commands/deploy.js.map +1 -0
  13. package/dist/bin/commands/init.d.ts +9 -0
  14. package/dist/bin/commands/init.d.ts.map +1 -0
  15. package/dist/bin/commands/init.js +155 -0
  16. package/dist/bin/commands/init.js.map +1 -0
  17. package/dist/bin/commands/validate.d.ts +5 -0
  18. package/dist/bin/commands/validate.d.ts.map +1 -0
  19. package/dist/bin/commands/validate.js +135 -0
  20. package/dist/bin/commands/validate.js.map +1 -0
  21. package/dist/bin/get-env.js +180 -0
  22. package/dist/bin/publish.js +327 -0
  23. package/{bin → dist/bin}/version.js +73 -37
  24. package/dist/lib/alb-api-gateway.d.ts +17 -0
  25. package/dist/lib/alb-api-gateway.d.ts.map +1 -0
  26. package/dist/lib/alb-api-gateway.js +191 -0
  27. package/dist/lib/alb-api-gateway.js.map +1 -0
  28. package/dist/lib/benchling-webhook-stack.d.ts +25 -0
  29. package/dist/lib/benchling-webhook-stack.d.ts.map +1 -0
  30. package/dist/lib/benchling-webhook-stack.js +165 -0
  31. package/dist/lib/benchling-webhook-stack.js.map +1 -0
  32. package/dist/lib/constants.d.ts +28 -0
  33. package/dist/lib/constants.d.ts.map +1 -0
  34. package/dist/lib/constants.js +31 -0
  35. package/dist/lib/constants.js.map +1 -0
  36. package/dist/lib/ecr-repository.d.ts +16 -0
  37. package/dist/lib/ecr-repository.d.ts.map +1 -0
  38. package/dist/lib/ecr-repository.js +90 -0
  39. package/dist/lib/ecr-repository.js.map +1 -0
  40. package/dist/lib/fargate-service.d.ts +32 -0
  41. package/dist/lib/fargate-service.d.ts.map +1 -0
  42. package/dist/lib/fargate-service.js +294 -0
  43. package/dist/lib/fargate-service.js.map +1 -0
  44. package/{lib/index.ts → dist/lib/index.d.ts} +5 -5
  45. package/dist/lib/index.d.ts.map +1 -0
  46. package/dist/lib/index.js +38 -0
  47. package/dist/lib/index.js.map +1 -0
  48. package/dist/lib/templates/base-template.d.ts +14 -0
  49. package/dist/lib/templates/base-template.d.ts.map +1 -0
  50. package/dist/lib/templates/base-template.js +68 -0
  51. package/dist/lib/templates/base-template.js.map +1 -0
  52. package/dist/lib/templates/readme.d.ts +11 -0
  53. package/dist/lib/templates/readme.d.ts.map +1 -0
  54. package/dist/lib/templates/readme.js +105 -0
  55. package/dist/lib/templates/readme.js.map +1 -0
  56. package/dist/lib/utils/config.d.ts +68 -0
  57. package/dist/lib/utils/config.d.ts.map +1 -0
  58. package/dist/lib/utils/config.js +195 -0
  59. package/dist/lib/utils/config.js.map +1 -0
  60. package/dist/lib/utils/stack-inference.d.ts +73 -0
  61. package/dist/lib/utils/stack-inference.d.ts.map +1 -0
  62. package/dist/lib/utils/stack-inference.js +410 -0
  63. package/dist/lib/utils/stack-inference.js.map +1 -0
  64. package/dist/package.json +90 -0
  65. package/package.json +31 -20
  66. package/AGENTS.md +0 -226
  67. package/CHANGELOG.md +0 -91
  68. package/bin/benchling-webhook.ts +0 -172
  69. package/bin/cli-auth.sh +0 -74
  70. package/bin/get-env.js +0 -564
  71. package/bin/publish-manual.js +0 -211
  72. package/bin/release-notes.sh +0 -82
  73. package/bin/sync-version.js +0 -72
  74. package/cdk.context.json +0 -58
  75. package/cdk.json +0 -85
  76. package/doc/NPM_OIDC_SETUP.md +0 -95
  77. package/doc/PARAMETERS.md +0 -203
  78. package/doc/RELEASE.md +0 -297
  79. package/doc/RELEASE_NOTES.md +0 -64
  80. package/jest.config.js +0 -14
  81. package/lib/README.md +0 -50
  82. package/lib/oauth-tester.json +0 -35
  83. package/tsconfig.json +0 -34
  84. /package/{bin → dist/bin}/check-logs.js +0 -0
  85. /package/{bin → dist/bin}/release.js +0 -0
  86. /package/{bin → dist/bin}/send-event.js +0 -0
  87. /package/{bin → dist/bin}/test-invalid-signature.js +0 -0
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initCommand = initCommand;
7
+ const fs_1 = require("fs");
8
+ const path_1 = require("path");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const ora_1 = __importDefault(require("ora"));
11
+ const boxen_1 = __importDefault(require("boxen"));
12
+ const enquirer_1 = require("enquirer");
13
+ const benchling_webhook_1 = require("../benchling-webhook");
14
+ async function initCommand(options) {
15
+ console.log((0, boxen_1.default)(chalk_1.default.bold("Benchling Webhook Setup"), {
16
+ padding: 1,
17
+ borderColor: "cyan",
18
+ borderStyle: "round",
19
+ }));
20
+ console.log();
21
+ console.log("Let's configure your deployment. You'll need:");
22
+ console.log(" • Access to your Quilt catalog");
23
+ console.log(" • An S3 bucket for storing data");
24
+ console.log(" • Benchling API credentials");
25
+ console.log();
26
+ console.log(chalk_1.default.dim("Press Ctrl+C at any time to cancel."));
27
+ console.log();
28
+ // Check if output file exists
29
+ const outputPath = (0, path_1.resolve)(options.output || ".env");
30
+ if ((0, fs_1.existsSync)(outputPath) && !options.force) {
31
+ console.error(chalk_1.default.yellow(`⚠️ File already exists: ${outputPath}`));
32
+ console.error();
33
+ const response = await (0, enquirer_1.prompt)({
34
+ type: "confirm",
35
+ name: "overwrite",
36
+ message: "Overwrite existing file?",
37
+ initial: false,
38
+ });
39
+ if (!response.overwrite) {
40
+ console.log(chalk_1.default.yellow("Setup cancelled"));
41
+ process.exit(0);
42
+ }
43
+ console.log();
44
+ }
45
+ // Prompt for required values
46
+ const answers = await (0, enquirer_1.prompt)([
47
+ {
48
+ type: "input",
49
+ name: "catalog",
50
+ message: "Quilt catalog URL (domain only):",
51
+ initial: "quilt-catalog.company.com",
52
+ validate: (value) => /^[a-z0-9.-]+\.[a-z]{2,}$/i.test(value) || "Please enter a valid domain name",
53
+ },
54
+ {
55
+ type: "input",
56
+ name: "bucket",
57
+ message: "S3 data bucket name:",
58
+ initial: "my-data-bucket",
59
+ validate: (value) => /^[a-z0-9.-]{3,63}$/.test(value) || "Please enter a valid S3 bucket name",
60
+ },
61
+ {
62
+ type: "input",
63
+ name: "tenant",
64
+ message: "Benchling tenant (XXX if you login to XXX.benchling.com):",
65
+ validate: (value) => value.trim().length > 0 || "Tenant is required",
66
+ },
67
+ {
68
+ type: "input",
69
+ name: "clientId",
70
+ message: "Benchling OAuth client ID:",
71
+ validate: (value) => value.trim().length > 0 || "Client ID is required",
72
+ },
73
+ {
74
+ type: "password",
75
+ name: "clientSecret",
76
+ message: "Benchling OAuth client secret:",
77
+ validate: (value) => value.trim().length > 0 || "Client secret is required",
78
+ },
79
+ {
80
+ type: "input",
81
+ name: "appId",
82
+ message: "Benchling app definition ID:",
83
+ validate: (value) => value.trim().length > 0 || "App definition ID is required",
84
+ },
85
+ ]);
86
+ // Build .env content
87
+ const envLines = [];
88
+ envLines.push("# ==============================================================================");
89
+ envLines.push("# Benchling Webhook Configuration");
90
+ envLines.push("# ==============================================================================");
91
+ envLines.push("# Generated by: npx @quiltdata/benchling-webhook init");
92
+ envLines.push("# Date: " + new Date().toISOString());
93
+ envLines.push("# ==============================================================================");
94
+ envLines.push("");
95
+ envLines.push("# Quilt Configuration");
96
+ envLines.push(`QUILT_CATALOG=${answers.catalog}`);
97
+ envLines.push(`QUILT_USER_BUCKET=${answers.bucket}`);
98
+ envLines.push("");
99
+ envLines.push("# Benchling Configuration");
100
+ envLines.push(`BENCHLING_TENANT=${answers.tenant}`);
101
+ envLines.push(`BENCHLING_CLIENT_ID=${answers.clientId}`);
102
+ envLines.push(`BENCHLING_CLIENT_SECRET=${answers.clientSecret}`);
103
+ envLines.push(`BENCHLING_APP_DEFINITION_ID=${answers.appId}`);
104
+ envLines.push("");
105
+ // Attempt inference if requested
106
+ let inferredVars = {};
107
+ if (options.infer !== false) {
108
+ console.log();
109
+ const spinner = (0, ora_1.default)("Inferring additional configuration from catalog...").start();
110
+ const inferenceResult = await (0, benchling_webhook_1.inferConfiguration)(answers.catalog);
111
+ if (inferenceResult.success) {
112
+ inferredVars = inferenceResult.inferredVars;
113
+ spinner.succeed("Successfully inferred additional configuration");
114
+ if (inferredVars.CDK_DEFAULT_ACCOUNT) {
115
+ envLines.push("# AWS Configuration (inferred)");
116
+ envLines.push(`CDK_DEFAULT_ACCOUNT=${inferredVars.CDK_DEFAULT_ACCOUNT}`);
117
+ envLines.push(`CDK_DEFAULT_REGION=${inferredVars.CDK_DEFAULT_REGION}`);
118
+ envLines.push("");
119
+ }
120
+ if (inferredVars.QUEUE_NAME) {
121
+ envLines.push("# SQS Configuration (inferred)");
122
+ envLines.push(`QUEUE_NAME=${inferredVars.QUEUE_NAME}`);
123
+ envLines.push(`SQS_QUEUE_URL=${inferredVars.SQS_QUEUE_URL}`);
124
+ envLines.push("");
125
+ }
126
+ if (inferredVars.QUILT_DATABASE) {
127
+ envLines.push("# Quilt Database (inferred)");
128
+ envLines.push(`QUILT_DATABASE=${inferredVars.QUILT_DATABASE}`);
129
+ envLines.push("");
130
+ }
131
+ }
132
+ else {
133
+ spinner.warn(`Could not infer additional configuration: ${inferenceResult.error}`);
134
+ }
135
+ }
136
+ // Add optional configuration section
137
+ if (!options.minimal) {
138
+ envLines.push("# Optional Configuration");
139
+ envLines.push("# PKG_PREFIX=benchling");
140
+ envLines.push("# LOG_LEVEL=INFO");
141
+ envLines.push("# ENABLE_WEBHOOK_VERIFICATION=true");
142
+ envLines.push("");
143
+ }
144
+ // Write file
145
+ (0, fs_1.writeFileSync)(outputPath, envLines.join("\n"));
146
+ console.log();
147
+ console.log((0, boxen_1.default)(`${chalk_1.default.green.bold("✓ Configuration saved!")}\n\n` +
148
+ `File: ${chalk_1.default.cyan(outputPath)}\n\n` +
149
+ `${chalk_1.default.bold("Next steps:")}\n` +
150
+ ` 1. Review ${outputPath} and verify all values\n` +
151
+ ` 2. Run: ${chalk_1.default.cyan("npx @quiltdata/benchling-webhook deploy")}\n` +
152
+ " 3. Configure your Benchling app\n\n" +
153
+ `${chalk_1.default.dim("For help: npx @quiltdata/benchling-webhook --help")}`, { padding: 1, borderColor: "green", borderStyle: "round" }));
154
+ }
155
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../bin/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type ConfigOptions } from "../../lib/utils/config";
2
+ export declare function validateCommand(options: ConfigOptions & {
3
+ verbose?: boolean;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../bin/commands/validate.ts"],"names":[],"mappings":"AAIA,OAAO,EAKH,KAAK,aAAa,EACrB,MAAM,wBAAwB,CAAC;AAMhC,wBAAsB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgJnG"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateCommand = validateCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const boxen_1 = __importDefault(require("boxen"));
10
+ const child_process_1 = require("child_process");
11
+ const config_1 = require("../../lib/utils/config");
12
+ const benchling_webhook_1 = require("../benchling-webhook");
13
+ async function validateCommand(options) {
14
+ console.log((0, boxen_1.default)(chalk_1.default.bold("Configuration Validation"), {
15
+ padding: 1,
16
+ borderColor: "yellow",
17
+ borderStyle: "round",
18
+ }));
19
+ console.log();
20
+ // 1. Load configuration
21
+ const spinner = (0, ora_1.default)("Loading configuration...").start();
22
+ let config = (0, config_1.loadConfigSync)(options);
23
+ spinner.succeed(`Configuration loaded from: ${options.envFile || ".env"}`);
24
+ // 2. Attempt inference
25
+ if (config.quiltCatalog) {
26
+ spinner.start("Inferring additional configuration from catalog...");
27
+ const inferenceResult = await (0, benchling_webhook_1.inferConfiguration)(config.quiltCatalog);
28
+ if (inferenceResult.success) {
29
+ config = (0, config_1.mergeInferredConfig)(config, inferenceResult.inferredVars);
30
+ spinner.succeed("Configuration inferred from catalog");
31
+ }
32
+ else {
33
+ spinner.warn(`Could not infer configuration: ${inferenceResult.error}`);
34
+ }
35
+ }
36
+ // 3. Validate
37
+ spinner.start("Validating configuration...");
38
+ const validation = (0, config_1.validateConfig)(config);
39
+ if (validation.valid) {
40
+ spinner.succeed("Configuration is valid");
41
+ }
42
+ else {
43
+ spinner.fail("Configuration validation failed");
44
+ }
45
+ // 4. Display results
46
+ console.log();
47
+ if (options.verbose || !validation.valid) {
48
+ console.log(chalk_1.default.bold("Configuration Summary:"));
49
+ console.log(chalk_1.default.gray("─".repeat(80)));
50
+ console.log();
51
+ // Required user values
52
+ console.log(chalk_1.default.bold("Required user values:"));
53
+ const userFields = [
54
+ "quiltCatalog",
55
+ "quiltUserBucket",
56
+ "benchlingTenant",
57
+ "benchlingClientId",
58
+ "benchlingClientSecret",
59
+ "benchlingAppDefinitionId",
60
+ ];
61
+ for (const field of userFields) {
62
+ const value = config[field];
63
+ const status = value ? chalk_1.default.green("✓") : chalk_1.default.red("✗");
64
+ const display = value || chalk_1.default.gray("(not set)");
65
+ console.log(` ${status} ${field}: ${display}`);
66
+ }
67
+ console.log();
68
+ // Inferred values
69
+ console.log(chalk_1.default.bold("Inferred values:"));
70
+ const inferredFields = [
71
+ "cdkAccount",
72
+ "cdkRegion",
73
+ "queueName",
74
+ "sqsQueueUrl",
75
+ "quiltDatabase",
76
+ ];
77
+ for (const field of inferredFields) {
78
+ const value = config[field];
79
+ const status = value ? chalk_1.default.green("✓") : chalk_1.default.red("✗");
80
+ const display = value || chalk_1.default.gray("(could not infer)");
81
+ console.log(` ${status} ${field}: ${display}`);
82
+ }
83
+ console.log();
84
+ }
85
+ // 5. Check AWS credentials
86
+ spinner.start("Checking AWS credentials...");
87
+ try {
88
+ const accountId = (0, child_process_1.execSync)("aws sts get-caller-identity --query Account --output text", {
89
+ encoding: "utf-8",
90
+ }).trim();
91
+ spinner.succeed(`AWS credentials configured (account: ${accountId})`);
92
+ }
93
+ catch {
94
+ spinner.fail("AWS credentials not configured");
95
+ console.log();
96
+ console.log(chalk_1.default.yellow("To configure AWS credentials, run:"));
97
+ console.log(chalk_1.default.cyan(" aws configure"));
98
+ console.log();
99
+ }
100
+ // 6. Check CDK bootstrap
101
+ if (config.cdkAccount && config.cdkRegion) {
102
+ spinner.start("Checking CDK bootstrap status...");
103
+ const bootstrapStatus = await (0, benchling_webhook_1.checkCdkBootstrap)(config.cdkAccount, config.cdkRegion);
104
+ if (bootstrapStatus.bootstrapped) {
105
+ spinner.succeed(`CDK is bootstrapped (${bootstrapStatus.status})`);
106
+ }
107
+ else {
108
+ spinner.fail("CDK is not bootstrapped");
109
+ console.log();
110
+ console.log(chalk_1.default.yellow("To bootstrap CDK, run:"));
111
+ console.log(chalk_1.default.cyan(` ${bootstrapStatus.command}`));
112
+ console.log();
113
+ }
114
+ }
115
+ // 7. Final result
116
+ console.log();
117
+ console.log(chalk_1.default.gray("─".repeat(80)));
118
+ if (validation.valid) {
119
+ console.log();
120
+ console.log((0, boxen_1.default)(`${chalk_1.default.green.bold("✓ Configuration is valid!")}\n\n` +
121
+ "Ready to deploy.\n\n" +
122
+ `Run: ${chalk_1.default.cyan("npx @quiltdata/benchling-webhook deploy")}`, { padding: 1, borderColor: "green", borderStyle: "round" }));
123
+ }
124
+ else {
125
+ console.log();
126
+ console.error(chalk_1.default.red.bold("❌ Configuration is invalid\n"));
127
+ console.error((0, config_1.formatValidationErrors)(validation));
128
+ console.log(chalk_1.default.yellow("To fix this:"));
129
+ console.log(" 1. Run: " + chalk_1.default.cyan("npx @quiltdata/benchling-webhook init"));
130
+ console.log(" 2. Or edit your .env file to add missing values");
131
+ console.log();
132
+ process.exit(1);
133
+ }
134
+ }
135
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../bin/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Get environment configuration from a Quilt catalog's config.json
4
+ *
5
+ * This script fetches config.json from a Quilt catalog URL and attempts to:
6
+ * 1. Parse the configuration
7
+ * 2. Query AWS CloudFormation to find the stack using resource identifiers
8
+ * 3. Extract stack outputs and parameters
9
+ * 4. Generate environment variables for .env
10
+ *
11
+ * Usage:
12
+ * node bin/get-env.js https://quilt-catalog.yourcompany.com
13
+ * node bin/get-env.js https://quilt-catalog.yourcompany.com --write
14
+ */
15
+
16
+ const fs = require("fs");
17
+ const path = require("path");
18
+
19
+ // Import utility functions from lib/utils
20
+ const { inferStackConfig } = require("../lib/utils/stack-inference");
21
+
22
+ // Parse command line arguments (only when run directly)
23
+ let args, catalogUrl, outputFile, writeFile;
24
+ if (require.main === module) {
25
+ args = process.argv.slice(2);
26
+ catalogUrl = args.find((arg) => !arg.startsWith("--"));
27
+ outputFile = args.find((arg) => arg.startsWith("--output="))?.split("=")[1];
28
+ writeFile = args.includes("--write");
29
+
30
+ if (!catalogUrl || args.includes("--help") || args.includes("-h")) {
31
+ printHelp();
32
+ process.exit(catalogUrl ? 0 : 1);
33
+ }
34
+ }
35
+
36
+ // CLI-specific functions moved to lib/utils/stack-inference.ts
37
+ // Re-export for backward compatibility if needed
38
+
39
+ /**
40
+ * Format environment variables for output
41
+ */
42
+ function formatEnvVars(vars) {
43
+ const lines = [];
44
+
45
+ lines.push("# ==============================================================================");
46
+ lines.push("# INFERRED CONFIGURATION");
47
+ lines.push("# ==============================================================================");
48
+ lines.push("# Generated by: bin/get-env.js");
49
+ lines.push("# Date: " + new Date().toISOString());
50
+ lines.push("#");
51
+ lines.push("# ⚠️ IMPORTANT: Review and verify all values before using!");
52
+ lines.push("# Some values may need manual verification or completion.");
53
+ lines.push("# ==============================================================================");
54
+ lines.push("");
55
+
56
+ for (const [key, value] of Object.entries(vars)) {
57
+ if (key.startsWith("#")) {
58
+ lines.push(`${key}: ${value}`);
59
+ } else {
60
+ lines.push(`${key}=${value}`);
61
+ }
62
+ }
63
+
64
+ lines.push("");
65
+ lines.push("# ==============================================================================");
66
+ lines.push("# REQUIRED VALUES NOT INFERRED - Must be filled manually");
67
+ lines.push("# ==============================================================================");
68
+ lines.push("PREFIX=benchling-webhook");
69
+ lines.push("BENCHLING_TENANT=your-tenant");
70
+ lines.push("BENCHLING_CLIENT_ID=your-client-id");
71
+ lines.push("BENCHLING_CLIENT_SECRET=your-client-secret");
72
+ lines.push("BENCHLING_APP=benchling-webhook");
73
+ lines.push("BENCHLING_API_KEY=your-api-key");
74
+ lines.push("BENCHLING_APP_DEFINITION_ID=appdef_your_id_here");
75
+ lines.push("ENABLE_WEBHOOK_VERIFICATION=true");
76
+ lines.push("BENCHLING_TEST_ENTRY=etr_123456789");
77
+ lines.push("");
78
+
79
+ return lines.join("\n");
80
+ }
81
+
82
+ /**
83
+ * Print help
84
+ */
85
+ function printHelp() {
86
+ console.log("Usage: node bin/get-env.js <catalog-url> [options]");
87
+ console.log("");
88
+ console.log("Arguments:");
89
+ console.log(" catalog-url URL of Quilt catalog (e.g., https://quilt-catalog.yourcompany.com)");
90
+ console.log("");
91
+ console.log("Options:");
92
+ console.log(" --output=FILE Write output to FILE instead of stdout");
93
+ console.log(" --write Write to env.inferred by default (without dot - user-visible)");
94
+ console.log(" --help, -h Show this help message");
95
+ console.log("");
96
+ console.log("Examples:");
97
+ console.log(" node bin/get-env.js https://nightly.quilttest.com");
98
+ console.log(" node bin/get-env.js https://nightly.quilttest.com --write");
99
+ console.log(" node bin/get-env.js https://nightly.quilttest.com --output=env.staging");
100
+ console.log("");
101
+ console.log("Description:");
102
+ console.log(" This script fetches config.json from a Quilt catalog and infers");
103
+ console.log(" environment variables needed for benchling-webhook deployment by:");
104
+ console.log(" 1. Parsing the catalog configuration");
105
+ console.log(" 2. Querying AWS CloudFormation to find the associated stack");
106
+ console.log(" 3. Extracting stack outputs and parameters");
107
+ console.log(" 4. Generating environment variable assignments");
108
+ console.log("");
109
+ console.log("Requirements:");
110
+ console.log(" - AWS CLI installed and configured");
111
+ console.log(" - AWS credentials with CloudFormation read permissions");
112
+ console.log(" - Network access to the catalog URL");
113
+ }
114
+
115
+ /**
116
+ * Main execution
117
+ */
118
+ async function main() {
119
+ try {
120
+ const result = await inferStackConfig(catalogUrl);
121
+
122
+ // Format output
123
+ const output = formatEnvVars(result.inferredVars);
124
+
125
+ // Print summary
126
+ console.log("=".repeat(80));
127
+ console.log("INFERRED CONFIGURATION");
128
+ console.log("=".repeat(80));
129
+ console.log("");
130
+ console.log(output);
131
+ console.log("");
132
+
133
+ // Write to file if requested
134
+ const targetFile = outputFile || (writeFile ? "env.inferred" : null);
135
+ if (targetFile) {
136
+ const fullPath = path.resolve(targetFile);
137
+
138
+ // Check if .env already exists and warn before proceeding
139
+ const envPath = path.resolve(".env");
140
+ if (fs.existsSync(envPath)) {
141
+ console.log("⚠️ NOTICE: A .env file already exists!");
142
+ console.log(` Writing to ${targetFile} instead to avoid overwriting your configuration.`);
143
+ console.log("");
144
+ }
145
+
146
+ fs.writeFileSync(fullPath, output);
147
+ console.log("=".repeat(80));
148
+ console.log(`✓ Configuration written to: ${fullPath}`);
149
+ console.log("=".repeat(80));
150
+ console.log("");
151
+ console.log("Next steps:");
152
+ console.log(" 1. Review the generated file and verify all values");
153
+ console.log(" 2. Fill in the REQUIRED VALUES section with your Benchling credentials");
154
+ if (fs.existsSync(envPath)) {
155
+ console.log(" 3. Carefully merge with your existing .env file (DO NOT overwrite!)");
156
+ console.log(" Compare: diff .env env.inferred");
157
+ } else {
158
+ console.log(" 3. Copy to .env when ready: cp env.inferred .env");
159
+ }
160
+ console.log("");
161
+ } else {
162
+ console.log("=".repeat(80));
163
+ console.log("To save this configuration, run:");
164
+ console.log(` node bin/get-env.js ${catalogUrl} --write`);
165
+ console.log("=".repeat(80));
166
+ console.log("");
167
+ }
168
+
169
+ } catch (error) {
170
+ console.error("Error:", error.message);
171
+ process.exit(1);
172
+ }
173
+ }
174
+
175
+ if (require.main === module) {
176
+ main();
177
+ }
178
+
179
+ // For backward compatibility, re-export from the new location
180
+ module.exports = require("../lib/utils/stack-inference");