@quiltdata/benchling-webhook 0.5.1 → 0.5.4-20251031T221509Z
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 +218 -5
- package/dist/bin/benchling-webhook.d.ts.map +1 -1
- package/dist/bin/benchling-webhook.js +15 -9
- package/dist/bin/benchling-webhook.js.map +1 -1
- package/dist/bin/cdk-dev.js +252 -0
- package/dist/bin/cli.js +23 -4
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/commands/deploy.d.ts.map +1 -1
- package/dist/bin/commands/deploy.js +132 -11
- package/dist/bin/commands/deploy.js.map +1 -1
- package/dist/bin/commands/init.d.ts.map +1 -1
- package/dist/bin/commands/init.js +2 -3
- package/dist/bin/commands/init.js.map +1 -1
- package/dist/bin/commands/manifest.d.ts.map +1 -1
- package/dist/bin/commands/manifest.js +8 -2
- package/dist/bin/commands/manifest.js.map +1 -1
- package/dist/bin/commands/test.js +2 -2
- package/dist/bin/commands/validate.d.ts.map +1 -1
- package/dist/bin/commands/validate.js +0 -1
- package/dist/bin/commands/validate.js.map +1 -1
- package/dist/lib/alb-api-gateway.d.ts.map +1 -1
- package/dist/lib/alb-api-gateway.js +24 -7
- package/dist/lib/alb-api-gateway.js.map +1 -1
- package/dist/lib/benchling-webhook-stack.d.ts +9 -1
- package/dist/lib/benchling-webhook-stack.d.ts.map +1 -1
- package/dist/lib/benchling-webhook-stack.js +85 -9
- package/dist/lib/benchling-webhook-stack.js.map +1 -1
- package/dist/lib/fargate-service.d.ts +10 -1
- package/dist/lib/fargate-service.d.ts.map +1 -1
- package/dist/lib/fargate-service.js +65 -27
- package/dist/lib/fargate-service.js.map +1 -1
- package/dist/lib/utils/config.d.ts +52 -3
- package/dist/lib/utils/config.d.ts.map +1 -1
- package/dist/lib/utils/config.js +96 -21
- package/dist/lib/utils/config.js.map +1 -1
- package/dist/lib/utils/secrets.d.ts +174 -0
- package/dist/lib/utils/secrets.d.ts.map +1 -0
- package/dist/lib/utils/secrets.js +351 -0
- package/dist/lib/utils/secrets.js.map +1 -0
- package/dist/lib/utils/stack-inference.d.ts +2 -14
- package/dist/lib/utils/stack-inference.d.ts.map +1 -1
- package/dist/lib/utils/stack-inference.js +33 -132
- package/dist/lib/utils/stack-inference.js.map +1 -1
- package/dist/package.json +9 -4
- package/env.template +1 -2
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ Connects Benchling lab notebook entries to Quilt data packages via webhooks.
|
|
|
7
7
|
- `npx` from Node.js 18+ ([download](https://nodejs.org))
|
|
8
8
|
- [AWS credentials](https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html) configured
|
|
9
9
|
- Existing [Quilt deployment](https://www.quilt.bio/install)
|
|
10
|
+
- Benchling tenant with OAuth app configured
|
|
10
11
|
|
|
11
12
|
## Setup
|
|
12
13
|
|
|
@@ -18,15 +19,35 @@ npx @quiltdata/benchling-webhook manifest
|
|
|
18
19
|
|
|
19
20
|
Follow the displayed instructions to [upload the manifest](https://docs.benchling.com/docs/getting-started-benchling-apps#creating-an-app-from-a-manifest) to Benchling and get your App Definition ID.
|
|
20
21
|
|
|
21
|
-
### 2.
|
|
22
|
+
### 2. Configure Benchling Secrets
|
|
23
|
+
|
|
24
|
+
Create a JSON file with your Benchling credentials:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cat > benchling-secrets.json << EOF
|
|
28
|
+
{
|
|
29
|
+
"client_id": "your-benchling-client-id",
|
|
30
|
+
"client_secret": "your-benchling-client-secret",
|
|
31
|
+
"tenant": "your-tenant"
|
|
32
|
+
}
|
|
33
|
+
EOF
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
> **Important**: Never commit secrets to version control. Add `benchling-secrets.json` to `.gitignore`.
|
|
37
|
+
|
|
38
|
+
**See [Secrets Configuration Guide](./docs/SECRETS_CONFIGURATION.md) for detailed configuration options**
|
|
39
|
+
|
|
40
|
+
### 3. Deploy to AWS
|
|
22
41
|
|
|
23
42
|
```bash
|
|
24
|
-
npx @quiltdata/benchling-webhook
|
|
43
|
+
npx @quiltdata/benchling-webhook deploy \
|
|
44
|
+
--benchling-secrets @benchling-secrets.json \
|
|
45
|
+
--catalog your-catalog.quiltdata.com
|
|
25
46
|
```
|
|
26
47
|
|
|
27
48
|
The interactive wizard will auto-detect or request configuration information, deploy to AWS, and test the webhook automatically.
|
|
28
49
|
|
|
29
|
-
###
|
|
50
|
+
### 4. Install in Benchling
|
|
30
51
|
|
|
31
52
|
After deployment, you'll receive a webhook URL. Set it in your Benchling app settings and [install the app](https://docs.benchling.com/docs/getting-started-benchling-apps#installing-your-app) in your tenant.
|
|
32
53
|
|
|
@@ -34,12 +55,138 @@ After deployment, you'll receive a webhook URL. Set it in your Benchling app set
|
|
|
34
55
|
|
|
35
56
|
In Benchling: Create entry → Insert Canvas → "Quilt Integration" → Create/Update package
|
|
36
57
|
|
|
58
|
+
## Configuration
|
|
59
|
+
|
|
60
|
+
### Secrets Management (v0.6.0+)
|
|
61
|
+
|
|
62
|
+
The webhook supports multiple ways to configure Benchling credentials:
|
|
63
|
+
|
|
64
|
+
#### Option 1: Inline JSON
|
|
65
|
+
```bash
|
|
66
|
+
npx @quiltdata/benchling-webhook deploy \
|
|
67
|
+
--benchling-secrets '{"client_id":"xxx","client_secret":"yyy","tenant":"company"}'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
#### Option 2: JSON File (Recommended)
|
|
71
|
+
```bash
|
|
72
|
+
npx @quiltdata/benchling-webhook deploy --benchling-secrets @benchling-secrets.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Option 3: AWS Secrets Manager ARN
|
|
76
|
+
```bash
|
|
77
|
+
npx @quiltdata/benchling-webhook deploy \
|
|
78
|
+
--benchling-secrets "arn:aws:secretsmanager:us-east-1:123456789012:secret:benchling-creds"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
#### Option 4: Environment Variable
|
|
82
|
+
```bash
|
|
83
|
+
export BENCHLING_SECRETS='{"client_id":"xxx","client_secret":"yyy","tenant":"company"}'
|
|
84
|
+
npx @quiltdata/benchling-webhook deploy
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**📖 [Complete Secrets Configuration Guide](./docs/SECRETS_CONFIGURATION.md)**
|
|
88
|
+
|
|
89
|
+
### Secret Format
|
|
90
|
+
|
|
91
|
+
**Required fields**:
|
|
92
|
+
- `client_id`: Benchling OAuth client ID
|
|
93
|
+
- `client_secret`: Benchling OAuth client secret
|
|
94
|
+
- `tenant`: Benchling tenant name (e.g., "company" for company.benchling.com)
|
|
95
|
+
|
|
96
|
+
**Optional fields**:
|
|
97
|
+
- `app_definition_id`: Benchling app definition ID
|
|
98
|
+
- `api_url`: Custom Benchling API URL
|
|
99
|
+
|
|
100
|
+
**Example**:
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"client_id": "abc123",
|
|
104
|
+
"client_secret": "secret_key",
|
|
105
|
+
"tenant": "mycompany",
|
|
106
|
+
"app_definition_id": "app_def_123"
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Updating Secrets
|
|
111
|
+
|
|
112
|
+
To update Benchling credentials after deployment:
|
|
113
|
+
|
|
114
|
+
**Method 1: Update in AWS Secrets Manager (Recommended)**
|
|
115
|
+
```bash
|
|
116
|
+
aws secretsmanager update-secret \
|
|
117
|
+
--secret-id benchling-webhook/credentials \
|
|
118
|
+
--secret-string '{"client_id":"new_id","client_secret":"new_secret","tenant":"company"}'
|
|
119
|
+
|
|
120
|
+
# Restart ECS service to pick up changes
|
|
121
|
+
aws ecs update-service \
|
|
122
|
+
--cluster benchling-webhook-cluster \
|
|
123
|
+
--service benchling-webhook-service \
|
|
124
|
+
--force-new-deployment
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Method 2: Redeploy Stack**
|
|
128
|
+
```bash
|
|
129
|
+
npx @quiltdata/benchling-webhook deploy \
|
|
130
|
+
--benchling-secrets @updated-secrets.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## All Available Commands
|
|
134
|
+
|
|
37
135
|
For all available commands, run:
|
|
38
136
|
|
|
39
137
|
```bash
|
|
40
138
|
npx @quiltdata/benchling-webhook --help
|
|
41
139
|
```
|
|
42
140
|
|
|
141
|
+
### Commands
|
|
142
|
+
|
|
143
|
+
- `deploy` - Deploy the CDK stack to AWS (default command)
|
|
144
|
+
- `init` - Initialize configuration interactively
|
|
145
|
+
- `validate` - Validate configuration without deploying
|
|
146
|
+
- `test` - Test the deployed webhook endpoint
|
|
147
|
+
- `manifest` - Generate Benchling app manifest file
|
|
148
|
+
|
|
149
|
+
### Deploy Options
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
npx @quiltdata/benchling-webhook deploy [options]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Secrets Configuration**:
|
|
156
|
+
- `--benchling-secrets <value>` - Benchling secrets (ARN, JSON, or @file)
|
|
157
|
+
|
|
158
|
+
**Quilt Configuration**:
|
|
159
|
+
- `--catalog <url>` - Quilt catalog URL
|
|
160
|
+
- `--bucket <name>` - S3 bucket for data
|
|
161
|
+
|
|
162
|
+
**AWS Configuration**:
|
|
163
|
+
- `--profile <name>` - AWS profile to use
|
|
164
|
+
- `--region <region>` - AWS region to deploy to
|
|
165
|
+
- `--image-tag <tag>` - Docker image tag to deploy (default: latest)
|
|
166
|
+
|
|
167
|
+
**Deployment Options**:
|
|
168
|
+
- `--env-file <path>` - Path to .env file (default: .env)
|
|
169
|
+
- `--yes` - Skip confirmation prompts
|
|
170
|
+
- `--no-bootstrap-check` - Skip CDK bootstrap verification
|
|
171
|
+
- `--require-approval <level>` - CDK approval level (default: never)
|
|
172
|
+
|
|
173
|
+
### Deprecated Parameters (v0.6.0+)
|
|
174
|
+
|
|
175
|
+
> ⚠️ **Warning**: The following parameters are deprecated and will be removed in v1.0.0
|
|
176
|
+
|
|
177
|
+
- `--tenant` - Use `--benchling-secrets` instead
|
|
178
|
+
- `--client-id` - Use `--benchling-secrets` instead
|
|
179
|
+
- `--client-secret` - Use `--benchling-secrets` instead
|
|
180
|
+
- `--app-id` - Use `--benchling-secrets` instead
|
|
181
|
+
|
|
182
|
+
**Migration guide**: See [Secrets Configuration - Migration Guide](./docs/SECRETS_CONFIGURATION.md#migration-guide)
|
|
183
|
+
|
|
184
|
+
## Documentation
|
|
185
|
+
|
|
186
|
+
- 📖 [Secrets Configuration Guide](./docs/SECRETS_CONFIGURATION.md) - Comprehensive secrets management documentation
|
|
187
|
+
- 📖 [Architecture Decision Record: Secrets Management](./docs/ADR-001-SECRETS-MANAGEMENT.md) - Design decisions and rationale
|
|
188
|
+
- 📖 [CHANGELOG.md](./CHANGELOG.md) - Version history and release notes
|
|
189
|
+
|
|
43
190
|
## Development
|
|
44
191
|
|
|
45
192
|
For local development and contributing:
|
|
@@ -53,10 +200,76 @@ npm install
|
|
|
53
200
|
npm run cli -- --help
|
|
54
201
|
npm run cli -- deploy
|
|
55
202
|
|
|
56
|
-
npm test
|
|
57
|
-
npm run build
|
|
203
|
+
npm test # Run tests
|
|
204
|
+
npm run build # Build package
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Running Tests
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Run all tests (TypeScript + Python)
|
|
211
|
+
npm test
|
|
212
|
+
|
|
213
|
+
# Run TypeScript tests only
|
|
214
|
+
npm run test:ts
|
|
215
|
+
|
|
216
|
+
# Run Python tests only
|
|
217
|
+
npm run test:python
|
|
218
|
+
|
|
219
|
+
# Type checking
|
|
220
|
+
npm run typecheck
|
|
221
|
+
|
|
222
|
+
# Linting
|
|
223
|
+
npm run lint
|
|
58
224
|
```
|
|
59
225
|
|
|
226
|
+
## Troubleshooting
|
|
227
|
+
|
|
228
|
+
### Common Issues
|
|
229
|
+
|
|
230
|
+
**Error: "Invalid secret ARN format"**
|
|
231
|
+
- Verify ARN format: `arn:aws:secretsmanager:region:account:secret:name`
|
|
232
|
+
- See [Troubleshooting Guide](./docs/SECRETS_CONFIGURATION.md#troubleshooting)
|
|
233
|
+
|
|
234
|
+
**Error: "Missing required field: client_id"**
|
|
235
|
+
- Check secret JSON includes all required fields: `client_id`, `client_secret`, `tenant`
|
|
236
|
+
- Validate JSON syntax: `echo '{"client_id":"..."}' | jq .`
|
|
237
|
+
|
|
238
|
+
**Deprecation Warning**
|
|
239
|
+
- Migrate to `--benchling-secrets` parameter
|
|
240
|
+
- See [Migration Guide](./docs/SECRETS_CONFIGURATION.md#migration-guide)
|
|
241
|
+
|
|
242
|
+
**For more help**: See [Secrets Configuration - Troubleshooting](./docs/SECRETS_CONFIGURATION.md#troubleshooting)
|
|
243
|
+
|
|
244
|
+
## Security
|
|
245
|
+
|
|
246
|
+
- Secrets are stored in AWS Secrets Manager with encryption at rest
|
|
247
|
+
- Secrets are masked in all CLI output
|
|
248
|
+
- CloudFormation parameters use `noEcho: true`
|
|
249
|
+
- IAM policies grant least-privilege access
|
|
250
|
+
- CloudTrail logs all secret access for audit
|
|
251
|
+
|
|
252
|
+
**Best Practices**:
|
|
253
|
+
- Never commit secrets to version control
|
|
254
|
+
- Use AWS Secrets Manager for production deployments
|
|
255
|
+
- Rotate secrets regularly
|
|
256
|
+
- Review IAM policies periodically
|
|
257
|
+
|
|
258
|
+
**For detailed security guidance**: See [Secrets Configuration - Security](./docs/SECRETS_CONFIGURATION.md#security-best-practices)
|
|
259
|
+
|
|
260
|
+
## Support
|
|
261
|
+
|
|
262
|
+
- 🐛 [Report Issues](https://github.com/quiltdata/benchling-webhook/issues)
|
|
263
|
+
- 📧 Security vulnerabilities: security@quiltdata.com
|
|
264
|
+
- 📖 [Documentation](./docs/)
|
|
265
|
+
- 💬 [Discussions](https://github.com/quiltdata/benchling-webhook/discussions)
|
|
266
|
+
|
|
60
267
|
## License
|
|
61
268
|
|
|
62
269
|
Apache-2.0
|
|
270
|
+
|
|
271
|
+
## Version
|
|
272
|
+
|
|
273
|
+
Current version: 0.5.4 (see [CHANGELOG.md](./CHANGELOG.md))
|
|
274
|
+
|
|
275
|
+
Next version: 0.6.0 (secrets management integration)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"benchling-webhook.d.ts","sourceRoot":"","sources":["../../bin/benchling-webhook.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,QAAA,MAAQ,gBAAgB,KAA4B,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;IACb,KAAK,EAAE,qBAAqB,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CAsC1B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAoBrF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"benchling-webhook.d.ts","sourceRoot":"","sources":["../../bin/benchling-webhook.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC;AACvB,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,QAAA,MAAQ,gBAAgB,KAA4B,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;IACb,KAAK,EAAE,qBAAqB,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CAsC1B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAoBrF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CA8B5D;AAwKD,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -117,7 +117,7 @@ function createStack(config) {
|
|
|
117
117
|
region: config.cdkRegion,
|
|
118
118
|
},
|
|
119
119
|
bucketName: config.quiltUserBucket,
|
|
120
|
-
|
|
120
|
+
queueArn: config.queueArn,
|
|
121
121
|
environment: "production",
|
|
122
122
|
prefix: config.pkgPrefix || "benchling",
|
|
123
123
|
benchlingClientId: config.benchlingClientId,
|
|
@@ -129,6 +129,7 @@ function createStack(config) {
|
|
|
129
129
|
logLevel: config.logLevel || "INFO",
|
|
130
130
|
createEcrRepository: config.createEcrRepository === "true",
|
|
131
131
|
ecrRepositoryName: config.ecrRepositoryName || "quiltdata/benchling",
|
|
132
|
+
imageTag: config.imageTag || "latest",
|
|
132
133
|
});
|
|
133
134
|
return {
|
|
134
135
|
app,
|
|
@@ -182,8 +183,7 @@ async function legacyGetConfig() {
|
|
|
182
183
|
const requiredInferredVars = [
|
|
183
184
|
"CDK_DEFAULT_ACCOUNT",
|
|
184
185
|
"CDK_DEFAULT_REGION",
|
|
185
|
-
"
|
|
186
|
-
"SQS_QUEUE_URL",
|
|
186
|
+
"QUEUE_ARN",
|
|
187
187
|
"QUILT_DATABASE",
|
|
188
188
|
];
|
|
189
189
|
const missingInferredVars = requiredInferredVars.filter((varName) => !config[varName]);
|
|
@@ -200,11 +200,17 @@ async function legacyGetConfig() {
|
|
|
200
200
|
console.error("\nAlternatively, you can manually set these values in your .env file.");
|
|
201
201
|
process.exit(1);
|
|
202
202
|
}
|
|
203
|
-
// Validate
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
203
|
+
// Validate required Benchling fields
|
|
204
|
+
const requiredBenchlingFields = [
|
|
205
|
+
"BENCHLING_TENANT",
|
|
206
|
+
"BENCHLING_CLIENT_ID",
|
|
207
|
+
"BENCHLING_CLIENT_SECRET",
|
|
208
|
+
"BENCHLING_APP_DEFINITION_ID",
|
|
209
|
+
];
|
|
210
|
+
const missingBenchling = requiredBenchlingFields.filter((field) => !config[field]);
|
|
211
|
+
if (missingBenchling.length > 0) {
|
|
212
|
+
console.error("Error: The following required Benchling configuration is missing:");
|
|
213
|
+
missingBenchling.forEach((field) => console.error(` - ${field}`));
|
|
208
214
|
process.exit(1);
|
|
209
215
|
}
|
|
210
216
|
return config;
|
|
@@ -243,7 +249,7 @@ async function legacyMain() {
|
|
|
243
249
|
region: config.CDK_DEFAULT_REGION,
|
|
244
250
|
},
|
|
245
251
|
bucketName: config.QUILT_USER_BUCKET, // User's data bucket
|
|
246
|
-
|
|
252
|
+
queueArn: config.QUEUE_ARN,
|
|
247
253
|
environment: "production",
|
|
248
254
|
prefix: config.PKG_PREFIX || "benchling",
|
|
249
255
|
benchlingClientId: config.BENCHLING_CLIENT_ID,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"benchling-webhook.js","sourceRoot":"","sources":["../../bin/benchling-webhook.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,8CAyCC;AAMD,gDAoBC;AAMD,
|
|
1
|
+
{"version":3,"file":"benchling-webhook.js","sourceRoot":"","sources":["../../bin/benchling-webhook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Development deployment workflow script
|
|
5
|
+
*
|
|
6
|
+
* This script:
|
|
7
|
+
* 1. Creates a dev git tag with timestamp (v{version}-{timestamp})
|
|
8
|
+
* 2. Pushes the tag to GitHub (triggers CI to build Docker image)
|
|
9
|
+
* 3. Waits for CI/CD pipeline to complete (monitors GitHub Actions)
|
|
10
|
+
* 4. Deploys CDK stack using the CI-built image tag
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* npm run cdk:dev # Full workflow
|
|
14
|
+
* npm run cdk:dev -- --continue # Skip tag creation, wait for CI and deploy
|
|
15
|
+
* npm run cdk:dev -- --tag <tag> # Use specific existing tag
|
|
16
|
+
*
|
|
17
|
+
* IMPORTANT: This uses CI-built images (x86_64), NOT local builds.
|
|
18
|
+
* Local ARM builds would fail in AWS which runs on x86_64.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const { execSync } = require('child_process');
|
|
22
|
+
const fs = require('fs');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
|
|
25
|
+
// Read package.json for version
|
|
26
|
+
const packagePath = path.join(__dirname, '..', 'package.json');
|
|
27
|
+
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
28
|
+
|
|
29
|
+
function run(command, options = {}) {
|
|
30
|
+
const silent = options.silent || false;
|
|
31
|
+
if (!silent) {
|
|
32
|
+
console.log(`\n$ ${command}\n`);
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return execSync(command, {
|
|
36
|
+
stdio: silent ? 'pipe' : 'inherit',
|
|
37
|
+
encoding: 'utf-8',
|
|
38
|
+
...options
|
|
39
|
+
});
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (!silent) {
|
|
42
|
+
console.error(`\n❌ Command failed: ${command}`);
|
|
43
|
+
}
|
|
44
|
+
if (options.allowFailure) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function waitForWorkflow(commitSha, timeoutMinutes = 15) {
|
|
52
|
+
console.log('');
|
|
53
|
+
console.log(`Waiting for CI workflow to complete (timeout: ${timeoutMinutes} minutes)...`);
|
|
54
|
+
console.log('');
|
|
55
|
+
|
|
56
|
+
// Check if gh CLI is available
|
|
57
|
+
try {
|
|
58
|
+
execSync('gh --version', { stdio: 'ignore' });
|
|
59
|
+
} catch (e) {
|
|
60
|
+
console.error('❌ GitHub CLI (gh) is not installed or not in PATH');
|
|
61
|
+
console.error(' Install from: https://cli.github.com/');
|
|
62
|
+
console.error('\n Alternatively, monitor the workflow manually and deploy when complete:');
|
|
63
|
+
console.error(' 1. Watch: https://github.com/quiltdata/benchling-webhook/actions');
|
|
64
|
+
console.error(' 2. Deploy: npm run cli -- --image-tag <version> --yes');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const startTime = Date.now();
|
|
69
|
+
const timeoutMs = timeoutMinutes * 60 * 1000;
|
|
70
|
+
let attempt = 0;
|
|
71
|
+
let workflowUrl = null;
|
|
72
|
+
|
|
73
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
74
|
+
attempt++;
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
// Use gh to list recent workflow runs for this commit
|
|
78
|
+
const result = run(`gh run list --commit ${commitSha} --json status,conclusion,url,databaseId --limit 5`, {
|
|
79
|
+
silent: true,
|
|
80
|
+
allowFailure: true
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
if (!result) {
|
|
84
|
+
process.stdout.write(`\r Attempt ${attempt}: Waiting for workflow to start (commit ${commitSha.substring(0, 7)})...`);
|
|
85
|
+
await new Promise(resolve => setTimeout(resolve, 10000));
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const runs = JSON.parse(result);
|
|
90
|
+
|
|
91
|
+
if (runs && runs.length > 0) {
|
|
92
|
+
const workflowRun = runs[0]; // Most recent run for this commit
|
|
93
|
+
const status = workflowRun.status;
|
|
94
|
+
const conclusion = workflowRun.conclusion;
|
|
95
|
+
workflowUrl = workflowRun.url;
|
|
96
|
+
|
|
97
|
+
process.stdout.write(`\r Attempt ${attempt}: Status=${status}, Conclusion=${conclusion || 'pending'}... ${workflowUrl}`);
|
|
98
|
+
|
|
99
|
+
if (status === 'completed') {
|
|
100
|
+
console.log('\n');
|
|
101
|
+
if (conclusion === 'success') {
|
|
102
|
+
console.log(`✅ CI workflow completed successfully!`);
|
|
103
|
+
console.log(` Run: ${workflowUrl}`);
|
|
104
|
+
return true;
|
|
105
|
+
} else {
|
|
106
|
+
console.error(`\n❌ CI workflow failed with conclusion: ${conclusion}`);
|
|
107
|
+
console.error(` Run: ${workflowUrl}`);
|
|
108
|
+
console.error(' Please check the workflow logs and fix any issues.');
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
process.stdout.write(`\r Attempt ${attempt}: Waiting for workflow to start (commit ${commitSha.substring(0, 7)})...`);
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
// Errors are non-fatal, just retry
|
|
117
|
+
if (attempt % 10 === 0) {
|
|
118
|
+
console.log(`\n Warning: ${error.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Wait 10 seconds between checks
|
|
123
|
+
await new Promise(resolve => setTimeout(resolve, 10000));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.error('\n\n❌ Timeout waiting for CI workflow to complete');
|
|
127
|
+
console.error(` Waited ${timeoutMinutes} minutes`);
|
|
128
|
+
if (workflowUrl) {
|
|
129
|
+
console.error(` Check status at: ${workflowUrl}`);
|
|
130
|
+
} else {
|
|
131
|
+
console.error(` Check status at: https://github.com/quiltdata/benchling-webhook/actions`);
|
|
132
|
+
}
|
|
133
|
+
console.error('\n Once the workflow completes, you can deploy manually with:');
|
|
134
|
+
console.error(` npm run cli -- --image-tag <version> --yes`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function main() {
|
|
139
|
+
console.log('🚀 Starting development deployment workflow...');
|
|
140
|
+
console.log('');
|
|
141
|
+
console.log('This workflow uses CI-built Docker images (x86_64 for AWS).');
|
|
142
|
+
console.log('Local ARM builds are NOT used as they would fail in AWS.');
|
|
143
|
+
console.log('');
|
|
144
|
+
|
|
145
|
+
// Parse command line arguments
|
|
146
|
+
const args = process.argv.slice(2);
|
|
147
|
+
const continueMode = args.includes('--continue');
|
|
148
|
+
const tagIndex = args.indexOf('--tag');
|
|
149
|
+
const specificTag = tagIndex !== -1 ? args[tagIndex + 1] : null;
|
|
150
|
+
|
|
151
|
+
let devTag;
|
|
152
|
+
let version;
|
|
153
|
+
|
|
154
|
+
if (specificTag) {
|
|
155
|
+
// Use specific tag provided by user
|
|
156
|
+
devTag = specificTag;
|
|
157
|
+
version = specificTag.replace(/^v/, '').split('-')[0]; // Extract version from tag
|
|
158
|
+
console.log(`Using specified tag: ${devTag}`);
|
|
159
|
+
console.log(`Extracted version: ${version}`);
|
|
160
|
+
} else if (continueMode) {
|
|
161
|
+
// Continue mode - find most recent dev tag
|
|
162
|
+
console.log('Continue mode: Finding most recent dev tag...');
|
|
163
|
+
try {
|
|
164
|
+
const tags = run('git tag --sort=-creatordate', { silent: true }).trim().split('\n');
|
|
165
|
+
const recentDevTag = tags.find(t => t.match(/^v[\d.]+-.+Z$/));
|
|
166
|
+
|
|
167
|
+
if (!recentDevTag) {
|
|
168
|
+
console.error('❌ No dev tags found');
|
|
169
|
+
console.error(' Run without --continue to create a new dev tag first');
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
devTag = recentDevTag;
|
|
174
|
+
version = devTag.replace(/^v/, '').split('-')[0];
|
|
175
|
+
console.log(`✅ Found recent dev tag: ${devTag}`);
|
|
176
|
+
console.log(` Version: ${version}`);
|
|
177
|
+
} catch (e) {
|
|
178
|
+
console.error('❌ Failed to find recent dev tag');
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
// Normal mode - create new tag
|
|
183
|
+
// 1. Check for uncommitted changes
|
|
184
|
+
console.log('Step 1: Checking for uncommitted changes...');
|
|
185
|
+
try {
|
|
186
|
+
execSync('git diff-index --quiet HEAD --', { stdio: 'ignore' });
|
|
187
|
+
} catch (e) {
|
|
188
|
+
console.error('❌ You have uncommitted changes');
|
|
189
|
+
console.error(' Commit or stash your changes before creating a dev deployment');
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
console.log('✅ Working directory is clean');
|
|
193
|
+
|
|
194
|
+
// 2. Generate dev tag name
|
|
195
|
+
version = pkg.version;
|
|
196
|
+
const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+Z$/, 'Z');
|
|
197
|
+
devTag = `v${version}-${timestamp}`;
|
|
198
|
+
|
|
199
|
+
console.log('');
|
|
200
|
+
console.log(`Step 2: Creating dev tag: ${devTag}`);
|
|
201
|
+
|
|
202
|
+
// Check if tag already exists
|
|
203
|
+
try {
|
|
204
|
+
execSync(`git rev-parse ${devTag}`, { stdio: 'ignore' });
|
|
205
|
+
console.error(`❌ Tag ${devTag} already exists`);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
} catch (e) {
|
|
208
|
+
// Tag doesn't exist, continue
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Create tag
|
|
212
|
+
const message = `Development release ${devTag}\n\nThis is a pre-release for testing purposes.`;
|
|
213
|
+
run(`git tag -a ${devTag} -m "${message}"`);
|
|
214
|
+
console.log(`✅ Created git tag ${devTag}`);
|
|
215
|
+
|
|
216
|
+
// 3. Push tag to origin (triggers CI)
|
|
217
|
+
console.log('');
|
|
218
|
+
console.log(`Step 3: Pushing tag to origin (this triggers CI/CD)...`);
|
|
219
|
+
run(`git push origin ${devTag}`);
|
|
220
|
+
console.log(`✅ Pushed tag ${devTag} to origin`);
|
|
221
|
+
console.log(' CI will now build Docker image for x86_64 (AWS-compatible)');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 4. Wait for CI to complete
|
|
225
|
+
console.log('');
|
|
226
|
+
console.log(`Step 4: Waiting for CI to build Docker image...`);
|
|
227
|
+
|
|
228
|
+
// Get the commit SHA for the tag (use ^{commit} to dereference annotated tags)
|
|
229
|
+
const commitSha = run(`git rev-parse ${devTag}^{commit}`, { silent: true }).trim();
|
|
230
|
+
|
|
231
|
+
await waitForWorkflow(commitSha);
|
|
232
|
+
|
|
233
|
+
// 5. Deploy CDK stack with CI-built image tag
|
|
234
|
+
console.log('');
|
|
235
|
+
console.log(`Step 5: Deploying CDK stack with CI-built image...`);
|
|
236
|
+
process.chdir(path.join(__dirname, '..'));
|
|
237
|
+
// Use the full version with timestamp (without 'v' prefix)
|
|
238
|
+
const imageTag = devTag.replace(/^v/, '');
|
|
239
|
+
run(`npm run cli -- --image-tag ${imageTag} --yes`);
|
|
240
|
+
|
|
241
|
+
console.log('');
|
|
242
|
+
console.log('✅ Development deployment complete!');
|
|
243
|
+
console.log('');
|
|
244
|
+
console.log(`Dev tag: ${devTag}`);
|
|
245
|
+
console.log(`Image tag: ${imageTag} (built by CI for x86_64)`);
|
|
246
|
+
console.log('');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
main().catch(error => {
|
|
250
|
+
console.error('\n❌ Error:', error.message);
|
|
251
|
+
process.exit(1);
|
|
252
|
+
});
|
package/dist/bin/cli.js
CHANGED
|
@@ -26,16 +26,35 @@ program
|
|
|
26
26
|
.description("Deploy the CDK stack to AWS")
|
|
27
27
|
.option("--catalog <url>", "Quilt catalog URL")
|
|
28
28
|
.option("--bucket <name>", "S3 bucket for data")
|
|
29
|
-
.option("--
|
|
30
|
-
.option("--
|
|
31
|
-
.option("--client-
|
|
32
|
-
.option("--
|
|
29
|
+
.option("--benchling-secrets <value>", "Benchling secrets configuration (ARN, JSON, or @file)")
|
|
30
|
+
.option("--tenant <name>", "Benchling tenant (deprecated, use --benchling-secrets)")
|
|
31
|
+
.option("--client-id <id>", "Benchling OAuth client ID (deprecated, use --benchling-secrets)")
|
|
32
|
+
.option("--client-secret <secret>", "Benchling OAuth client secret (deprecated, use --benchling-secrets)")
|
|
33
|
+
.option("--app-id <id>", "Benchling app definition ID (deprecated, use --benchling-secrets)")
|
|
33
34
|
.option("--env-file <path>", "Path to .env file", ".env")
|
|
34
35
|
.option("--no-bootstrap-check", "Skip CDK bootstrap verification")
|
|
35
36
|
.option("--require-approval <level>", "CDK approval level", "never")
|
|
36
37
|
.option("--profile <name>", "AWS profile to use")
|
|
37
38
|
.option("--region <region>", "AWS region to deploy to")
|
|
39
|
+
.option("--image-tag <tag>", "Docker image tag to deploy (default: latest)")
|
|
38
40
|
.option("--yes", "Skip confirmation prompts")
|
|
41
|
+
.addHelpText("after", `
|
|
42
|
+
Examples:
|
|
43
|
+
Using AWS Secrets Manager ARN:
|
|
44
|
+
$ npx @quiltdata/benchling-webhook deploy --benchling-secrets "arn:aws:secretsmanager:us-east-1:123456789012:secret:benchling-credentials"
|
|
45
|
+
|
|
46
|
+
Using inline JSON:
|
|
47
|
+
$ npx @quiltdata/benchling-webhook deploy --benchling-secrets '{"client_id":"xxx","client_secret":"yyy","tenant":"company"}'
|
|
48
|
+
|
|
49
|
+
Using JSON file:
|
|
50
|
+
$ npx @quiltdata/benchling-webhook deploy --benchling-secrets @secrets.json
|
|
51
|
+
|
|
52
|
+
Using environment variable:
|
|
53
|
+
$ export BENCHLING_SECRETS='{"client_id":"xxx","client_secret":"yyy","tenant":"company"}'
|
|
54
|
+
$ npx @quiltdata/benchling-webhook deploy
|
|
55
|
+
|
|
56
|
+
For more information: https://github.com/quiltdata/benchling-webhook#secrets-configuration
|
|
57
|
+
`)
|
|
39
58
|
.action(async (options) => {
|
|
40
59
|
try {
|
|
41
60
|
await (0, deploy_1.deployCommand)(options);
|
package/dist/bin/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";;;;;;AACA,yCAAoC;AACpC,kDAA0B;AAC1B,8CAAkD;AAClD,0CAA8C;AAC9C,kDAAsD;AACtD,0CAA8C;AAC9C,kDAAsD;AAEtD,gCAAgC;AAChC,iEAAiE;AACjE,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,mBAAmB,CAAC;KACzB,WAAW,CAAC,kFAAkF,CAAC;KAC/F,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,wBAAwB,CAAC;KAC/D,UAAU,CAAC,YAAY,EAAE,0BAA0B,CAAC,CAAC;AAE1D,2BAA2B;AAC3B,OAAO;KACF,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACtC,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;KAC9C,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;KAC/C,MAAM,CAAC,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":";;;;;;AACA,yCAAoC;AACpC,kDAA0B;AAC1B,8CAAkD;AAClD,0CAA8C;AAC9C,kDAAsD;AACtD,0CAA8C;AAC9C,kDAAsD;AAEtD,gCAAgC;AAChC,iEAAiE;AACjE,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,mBAAmB,CAAC;KACzB,WAAW,CAAC,kFAAkF,CAAC;KAC/F,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,wBAAwB,CAAC;KAC/D,UAAU,CAAC,YAAY,EAAE,0BAA0B,CAAC,CAAC;AAE1D,2BAA2B;AAC3B,OAAO;KACF,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACtC,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,CAAC;KAC9C,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;KAC/C,MAAM,CAAC,6BAA6B,EAAE,uDAAuD,CAAC;KAC9F,MAAM,CAAC,iBAAiB,EAAE,wDAAwD,CAAC;KACnF,MAAM,CAAC,kBAAkB,EAAE,iEAAiE,CAAC;KAC7F,MAAM,CAAC,0BAA0B,EAAE,qEAAqE,CAAC;KACzG,MAAM,CAAC,eAAe,EAAE,mEAAmE,CAAC;KAC5F,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC;KACxD,MAAM,CAAC,sBAAsB,EAAE,iCAAiC,CAAC;KACjE,MAAM,CAAC,4BAA4B,EAAE,oBAAoB,EAAE,OAAO,CAAC;KACnE,MAAM,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;KAChD,MAAM,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;KACtD,MAAM,CAAC,mBAAmB,EAAE,8CAA8C,CAAC;KAC3E,MAAM,CAAC,OAAO,EAAE,2BAA2B,CAAC;KAC5C,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;CAgBzB,CAAC;KACG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACD,MAAM,IAAA,sBAAa,EAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC;AAEP,eAAe;AACf,OAAO;KACF,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,CAAC;KACrD,MAAM,CAAC,SAAS,EAAE,yBAAyB,CAAC;KAC5C,MAAM,CAAC,WAAW,EAAE,iCAAiC,CAAC;KACtD,MAAM,CAAC,SAAS,EAAE,sCAAsC,CAAC;KACzD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACD,MAAM,IAAA,kBAAW,EAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC;AAEP,mBAAmB;AACnB,OAAO;KACF,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC;KACxD,MAAM,CAAC,WAAW,EAAE,sCAAsC,CAAC;KAC3D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACD,MAAM,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC;AAEP,eAAe;AACf,OAAO;KACF,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,aAAa,EAAE,2DAA2D,CAAC;KAClF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACD,MAAM,IAAA,kBAAW,EAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC;AAEP,mBAAmB;AACnB,OAAO;KACF,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,CAAC;KAClE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACD,MAAM,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC;AAEP,qCAAqC;AACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAChC,OAAO,CAAC,UAAU,EAAE,CAAC;AACzB,CAAC;AAED,OAAO,CAAC,KAAK,EAAE,CAAC"}
|