bdy 1.23.11-dev → 1.23.13-dev-target-commands
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/distTs/detect-rules.json +351 -0
- package/distTs/package.json +3 -1
- package/distTs/src/api/client.js +222 -12
- package/distTs/src/cliIndex.js +4 -0
- package/distTs/src/command/artifact/list.js +2 -6
- package/distTs/src/command/distro/list.js +1 -0
- package/distTs/src/command/distro/route/update.js +1 -1
- package/distTs/src/command/distro/update.js +9 -9
- package/distTs/src/command/environment/create.js +70 -0
- package/distTs/src/command/environment/delete.js +29 -0
- package/distTs/src/command/environment/get.js +48 -0
- package/distTs/src/command/environment/list.js +45 -0
- package/distTs/src/command/environment/resolve.js +22 -0
- package/distTs/src/command/environment/update.js +59 -0
- package/distTs/src/command/environment.js +20 -0
- package/distTs/src/command/pipeline/run/apply.js +62 -0
- package/distTs/src/command/target/create.js +33 -0
- package/distTs/src/command/target/delete.js +30 -0
- package/distTs/src/command/target/exec/command.js +103 -0
- package/distTs/src/command/target/exec/kill.js +31 -0
- package/distTs/src/command/target/exec/list.js +53 -0
- package/distTs/src/command/target/exec/logs.js +27 -0
- package/distTs/src/command/target/exec/status.js +44 -0
- package/distTs/src/command/target/exec.js +24 -0
- package/distTs/src/command/target/get.js +63 -0
- package/distTs/src/command/target/list.js +49 -0
- package/distTs/src/command/target/scope.js +108 -0
- package/distTs/src/command/target/update.js +31 -0
- package/distTs/src/command/target.js +22 -0
- package/distTs/src/command/yaml/actions/detect.js +268 -0
- package/distTs/src/command/yaml/actions/info.js +56 -0
- package/distTs/src/command/yaml/actions/list.js +70 -0
- package/distTs/src/command/yaml/actions/schema.js +104 -0
- package/distTs/src/command/yaml/actions.js +13 -0
- package/distTs/src/command/yaml/agents.js +88 -0
- package/distTs/src/command/yaml/cache.js +98 -0
- package/distTs/src/command/yaml/init.js +110 -0
- package/distTs/src/command/yaml/pipeline.js +42 -0
- package/distTs/src/command/yaml/render.js +83 -0
- package/distTs/src/command/yaml/schemaUtils.js +139 -0
- package/distTs/src/command/yaml/validate.js +259 -0
- package/distTs/src/command/yaml.js +18 -0
- package/distTs/src/diskCache.js +82 -0
- package/distTs/src/input.js +65 -0
- package/distTs/src/output.js +21 -2
- package/distTs/src/texts.js +252 -27
- package/distTs/src/utils.js +18 -2
- package/package.json +3 -1
- package/distTs/README.md +0 -181
- package/distTs/src/command/project/get.js +0 -18
- package/distTs/src/command/project/set.js +0 -31
- package/distTs/src/command/sandbox/get/yaml.js +0 -30
- package/distTs/src/command/vt/scrape.js +0 -193
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
{
|
|
2
|
+
"BUILD": {
|
|
3
|
+
"files": ["package.json", "requirements.txt", "pyproject.toml", "go.mod", "Gemfile", "pom.xml", "build.gradle", "build.gradle.kts", "Cargo.toml", "composer.json", "pubspec.yaml", "Makefile", "CMakeLists.txt"],
|
|
4
|
+
"packages": ["eslint", "oxlint", "@oxlint/cli", "@biomejs/biome", "prettier", "stylelint", "xo", "standard", "typescript"]
|
|
5
|
+
},
|
|
6
|
+
"DOCKERFILE": {
|
|
7
|
+
"files": ["Dockerfile", "Containerfile", "compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml"]
|
|
8
|
+
},
|
|
9
|
+
"DOCKER_PUSH": {
|
|
10
|
+
"files": ["Dockerfile", "Containerfile"]
|
|
11
|
+
},
|
|
12
|
+
"RUN_DOCKER_CONTAINER": {
|
|
13
|
+
"files": ["Dockerfile", "Containerfile", "compose.yaml", "compose.yml", "docker-compose.yml"]
|
|
14
|
+
},
|
|
15
|
+
"DOCKERFILE_LINTER": {
|
|
16
|
+
"files": ["Dockerfile", "Containerfile"]
|
|
17
|
+
},
|
|
18
|
+
"DOCKER": {
|
|
19
|
+
"files": ["Dockerfile", "Containerfile", "compose.yaml", "compose.yml", "docker-compose.yml"]
|
|
20
|
+
},
|
|
21
|
+
"DOCKER_BUILD_MULTI_ARCH": {
|
|
22
|
+
"files": ["Dockerfile", "Containerfile"]
|
|
23
|
+
},
|
|
24
|
+
"NATIVE_BUILD_DOCKER_CLI": {
|
|
25
|
+
"files": ["Dockerfile", "Containerfile"]
|
|
26
|
+
},
|
|
27
|
+
"PROMOTE_IMAGE": {
|
|
28
|
+
"files": ["Dockerfile", "Containerfile"]
|
|
29
|
+
},
|
|
30
|
+
"KUBERNETES_APPLY": {
|
|
31
|
+
"files": ["k8s/", "kubernetes/", "kustomization.yaml", "kustomization.yml", "Kustomization"],
|
|
32
|
+
"packages": ["@aws-sdk/client-eks", "@google-cloud/container", "@azure/arm-containerservice"]
|
|
33
|
+
},
|
|
34
|
+
"KUBERNETES_SET_IMAGE": {
|
|
35
|
+
"files": ["k8s/", "kubernetes/"]
|
|
36
|
+
},
|
|
37
|
+
"KUBERNETES_RUN_POD": {
|
|
38
|
+
"files": ["k8s/", "kubernetes/"]
|
|
39
|
+
},
|
|
40
|
+
"KUBERNETES_RUN_JOB": {
|
|
41
|
+
"files": ["k8s/", "kubernetes/"]
|
|
42
|
+
},
|
|
43
|
+
"KUBERNETES_CLI": {
|
|
44
|
+
"files": ["k8s/", "kubernetes/", "kustomization.yaml", "kustomization.yml", "Kustomization"],
|
|
45
|
+
"packages": ["@kubernetes/client-node", "@aws-sdk/client-eks", "@google-cloud/container", "@azure/arm-containerservice"]
|
|
46
|
+
},
|
|
47
|
+
"HELM": {
|
|
48
|
+
"files": ["Chart.yaml", "helm/", "charts/"]
|
|
49
|
+
},
|
|
50
|
+
"WAIT_FOR_APPLY": {
|
|
51
|
+
"files": ["k8s/", "kubernetes/"]
|
|
52
|
+
},
|
|
53
|
+
"AMAZON_S3": {
|
|
54
|
+
"packages": ["aws-sdk", "@aws-sdk/client-s3"]
|
|
55
|
+
},
|
|
56
|
+
"AWS_CLI": {
|
|
57
|
+
"files": ["buildspec.yml"],
|
|
58
|
+
"packages": ["aws-sdk", "@aws-sdk/*"]
|
|
59
|
+
},
|
|
60
|
+
"AWS_CLI_2": {
|
|
61
|
+
"files": ["buildspec.yml"],
|
|
62
|
+
"packages": ["aws-sdk", "@aws-sdk/*"]
|
|
63
|
+
},
|
|
64
|
+
"AWS_LAMBDA_DEPLOY": {
|
|
65
|
+
"files": ["serverless.yml", "serverless.yaml", "samconfig.toml", "sam-template.yaml"],
|
|
66
|
+
"packages": ["aws-sdk", "@aws-sdk/client-lambda"]
|
|
67
|
+
},
|
|
68
|
+
"LAMBDA": {
|
|
69
|
+
"files": ["serverless.yml", "samconfig.toml"],
|
|
70
|
+
"packages": ["@aws-sdk/client-lambda"]
|
|
71
|
+
},
|
|
72
|
+
"AWS_ECS": {
|
|
73
|
+
"files": ["ecs-task-definition.json", "task-definition.json"],
|
|
74
|
+
"packages": ["@aws-sdk/client-ecs"]
|
|
75
|
+
},
|
|
76
|
+
"CODE_DEPLOY": {
|
|
77
|
+
"files": ["appspec.yml", "appspec.yaml"]
|
|
78
|
+
},
|
|
79
|
+
"ELASTIC_BEANSTALK": {
|
|
80
|
+
"files": [".elasticbeanstalk/"]
|
|
81
|
+
},
|
|
82
|
+
"MONITOR": {
|
|
83
|
+
"files": [".elasticbeanstalk/"]
|
|
84
|
+
},
|
|
85
|
+
"AWS_CLOUD_FORMATION": {
|
|
86
|
+
"files": ["cloudformation/"]
|
|
87
|
+
},
|
|
88
|
+
"CLOUD_FRONT": {
|
|
89
|
+
"packages": ["aws-sdk", "@aws-sdk/client-cloudfront"]
|
|
90
|
+
},
|
|
91
|
+
"CODE_PIPELINE": {
|
|
92
|
+
"files": ["buildspec.yml"]
|
|
93
|
+
},
|
|
94
|
+
"AWS_APP_RUNNER_DEPLOY": {
|
|
95
|
+
"packages": ["@aws-sdk/client-apprunner"]
|
|
96
|
+
},
|
|
97
|
+
"AWS_APP_RUNNER_MONITOR": {
|
|
98
|
+
"packages": ["@aws-sdk/client-apprunner"]
|
|
99
|
+
},
|
|
100
|
+
"AWS_CDK_CLI": {
|
|
101
|
+
"files": ["cdk.json"],
|
|
102
|
+
"packages": ["aws-cdk-lib", "aws-cdk"]
|
|
103
|
+
},
|
|
104
|
+
"DOWNLOAD_S3": {
|
|
105
|
+
"packages": ["aws-sdk", "@aws-sdk/client-s3"]
|
|
106
|
+
},
|
|
107
|
+
"GOOGLE_CLOUD_STORAGE": {
|
|
108
|
+
"packages": ["@google-cloud/storage"]
|
|
109
|
+
},
|
|
110
|
+
"GOOGLE_CLOUD_CLI": {
|
|
111
|
+
"packages": ["@google-cloud/*"]
|
|
112
|
+
},
|
|
113
|
+
"GOOGLE_APP_DEPLOY": {
|
|
114
|
+
"files": ["app.yaml"]
|
|
115
|
+
},
|
|
116
|
+
"GOOGLE_FUNCTION_DEPLOY": {
|
|
117
|
+
"files": ["firebase.json"],
|
|
118
|
+
"packages": ["@google-cloud/functions-framework"]
|
|
119
|
+
},
|
|
120
|
+
"GOOGLE_FUNCTION_INVOKE": {
|
|
121
|
+
"packages": ["@google-cloud/functions-framework"]
|
|
122
|
+
},
|
|
123
|
+
"GOOGLE_CLOUD_RUN_DEPLOY": {
|
|
124
|
+
"files": ["Dockerfile", "Containerfile"]
|
|
125
|
+
},
|
|
126
|
+
"GOOGLE_CDN_INVALIDATE": {
|
|
127
|
+
"packages": ["@google-cloud/compute"]
|
|
128
|
+
},
|
|
129
|
+
"FIREBASE": {
|
|
130
|
+
"files": ["firebase.json", ".firebaserc"],
|
|
131
|
+
"packages": ["firebase", "firebase-admin"]
|
|
132
|
+
},
|
|
133
|
+
"DOWNLOAD_GCS": {
|
|
134
|
+
"packages": ["@google-cloud/storage"]
|
|
135
|
+
},
|
|
136
|
+
"AZURE": {
|
|
137
|
+
"files": ["azure-pipelines.yml"]
|
|
138
|
+
},
|
|
139
|
+
"AZURE_CLI": {
|
|
140
|
+
"files": ["azure-pipelines.yml"],
|
|
141
|
+
"packages": ["@azure/*"]
|
|
142
|
+
},
|
|
143
|
+
"AZURE_STORAGE": {
|
|
144
|
+
"packages": ["@azure/storage-blob"]
|
|
145
|
+
},
|
|
146
|
+
"HEROKU": {
|
|
147
|
+
"files": ["Procfile"]
|
|
148
|
+
},
|
|
149
|
+
"HEROKU_CLI": {
|
|
150
|
+
"files": ["Procfile"]
|
|
151
|
+
},
|
|
152
|
+
"NETLIFY": {
|
|
153
|
+
"files": ["netlify.toml"]
|
|
154
|
+
},
|
|
155
|
+
"TERRAFORM": {
|
|
156
|
+
"files": ["*.tf", "*.tofu", "terraform/", ".terraform/"]
|
|
157
|
+
},
|
|
158
|
+
"ANDROID_SIGN": {
|
|
159
|
+
"files": ["android/", "app/src/main/AndroidManifest.xml"]
|
|
160
|
+
},
|
|
161
|
+
"ANDROID_SIGN_BUNDLE": {
|
|
162
|
+
"files": ["android/", "app/src/main/AndroidManifest.xml"]
|
|
163
|
+
},
|
|
164
|
+
"ANDROID_PUBLISH_APK": {
|
|
165
|
+
"files": ["android/", "app/src/main/AndroidManifest.xml"]
|
|
166
|
+
},
|
|
167
|
+
"ANDROID_PUBLISH_APP_BUNDLE": {
|
|
168
|
+
"files": ["android/", "app/src/main/AndroidManifest.xml"]
|
|
169
|
+
},
|
|
170
|
+
"FASTLANE_ANDROID": {
|
|
171
|
+
"files": ["fastlane/", "android/"]
|
|
172
|
+
},
|
|
173
|
+
"NATIVE_BUILD_MAC": {
|
|
174
|
+
"files": ["*.xcodeproj", "*.xcworkspace"]
|
|
175
|
+
},
|
|
176
|
+
"NATIVE_BUILD_MAC_VM": {
|
|
177
|
+
"files": ["*.xcodeproj", "*.xcworkspace"]
|
|
178
|
+
},
|
|
179
|
+
"NATIVE_BUILD_MAC_SIGN": {
|
|
180
|
+
"files": ["*.xcodeproj", "*.xcworkspace"]
|
|
181
|
+
},
|
|
182
|
+
"NATIVE_BUILD_MAC_DEPLOY": {
|
|
183
|
+
"files": ["*.xcodeproj", "*.xcworkspace"]
|
|
184
|
+
},
|
|
185
|
+
"NATIVE_BUILD_MAC_REACT": {
|
|
186
|
+
"files": ["ios/"],
|
|
187
|
+
"packages": ["react-native"]
|
|
188
|
+
},
|
|
189
|
+
"NATIVE_BUILD_MAC_CORDOVA": {
|
|
190
|
+
"packages": ["cordova"]
|
|
191
|
+
},
|
|
192
|
+
"NATIVE_BUILD_MAC_FASTLANE": {
|
|
193
|
+
"files": ["fastlane/Fastfile"]
|
|
194
|
+
},
|
|
195
|
+
"NATIVE_BUILD_MAC_FLUTTER": {
|
|
196
|
+
"files": ["pubspec.yaml", "ios/"]
|
|
197
|
+
},
|
|
198
|
+
"PLAYWRIGHT": {
|
|
199
|
+
"files": ["playwright.config.*"],
|
|
200
|
+
"packages": ["@playwright/test", "playwright"]
|
|
201
|
+
},
|
|
202
|
+
"CYPRESS": {
|
|
203
|
+
"files": ["cypress.config.*", "cypress/"],
|
|
204
|
+
"packages": ["cypress"]
|
|
205
|
+
},
|
|
206
|
+
"STORYBOOK": {
|
|
207
|
+
"files": [".storybook/"],
|
|
208
|
+
"packages": ["storybook", "@storybook/react"]
|
|
209
|
+
},
|
|
210
|
+
"LIGHTHOUSE": {
|
|
211
|
+
"packages": ["lighthouse"]
|
|
212
|
+
},
|
|
213
|
+
"JMETER_CLI": {
|
|
214
|
+
"files": ["*.jmx"]
|
|
215
|
+
},
|
|
216
|
+
"SNYK_CLI": {
|
|
217
|
+
"files": [".snyk"],
|
|
218
|
+
"packages": ["snyk"]
|
|
219
|
+
},
|
|
220
|
+
"STACK_HAWK_CLI": {
|
|
221
|
+
"files": ["stackhawk.yml"]
|
|
222
|
+
},
|
|
223
|
+
"BLACKFIRE_PHP": {
|
|
224
|
+
"packages": ["blackfire/php-sdk"]
|
|
225
|
+
},
|
|
226
|
+
"BLACKFIRE_PYTHON": {
|
|
227
|
+
"packages": ["blackfire"]
|
|
228
|
+
},
|
|
229
|
+
"BLACKFIRE_GO": {
|
|
230
|
+
"packages": ["github.com/blackfireio/go-blackfire"]
|
|
231
|
+
},
|
|
232
|
+
"SENTRY": {
|
|
233
|
+
"packages": ["@sentry/node", "@sentry/browser", "@sentry/react"]
|
|
234
|
+
},
|
|
235
|
+
"SENTRY_ENTERPRISE": {
|
|
236
|
+
"packages": ["@sentry/node", "@sentry/browser"]
|
|
237
|
+
},
|
|
238
|
+
"NEW_RELIC": {
|
|
239
|
+
"packages": ["newrelic"]
|
|
240
|
+
},
|
|
241
|
+
"NEW_RELIC_CLI": {
|
|
242
|
+
"packages": ["newrelic"]
|
|
243
|
+
},
|
|
244
|
+
"DATADOG": {
|
|
245
|
+
"packages": ["dd-trace", "datadog-metrics"]
|
|
246
|
+
},
|
|
247
|
+
"DATADOG_STATUS_CHECK": {
|
|
248
|
+
"packages": ["dd-trace"]
|
|
249
|
+
},
|
|
250
|
+
"ROLLBAR": {
|
|
251
|
+
"packages": ["rollbar"]
|
|
252
|
+
},
|
|
253
|
+
"HONEYBADGER": {
|
|
254
|
+
"packages": ["@honeybadger-io/js"]
|
|
255
|
+
},
|
|
256
|
+
"BUGSNAG": {
|
|
257
|
+
"packages": ["@bugsnag/js", "@bugsnag/node"]
|
|
258
|
+
},
|
|
259
|
+
"RAYGUN": {
|
|
260
|
+
"packages": ["raygun"]
|
|
261
|
+
},
|
|
262
|
+
"LOGGLY": {
|
|
263
|
+
"packages": ["node-loggly-bulk", "winston-loggly-bulk"]
|
|
264
|
+
},
|
|
265
|
+
"DO_SPACES": {
|
|
266
|
+
"packages": ["aws-sdk", "@aws-sdk/client-s3"]
|
|
267
|
+
},
|
|
268
|
+
"GIT_HUB_RELEASE": {
|
|
269
|
+
"files": [".github/workflows/"]
|
|
270
|
+
},
|
|
271
|
+
"GIT_HUB_CLI": {
|
|
272
|
+
"files": [".github/workflows/"]
|
|
273
|
+
},
|
|
274
|
+
"GIT_LAB_CLI": {
|
|
275
|
+
"files": [".gitlab-ci.yml"]
|
|
276
|
+
},
|
|
277
|
+
"SHOPIFY": {
|
|
278
|
+
"files": ["shopify.app.toml"],
|
|
279
|
+
"packages": ["@shopify/shopify-api"]
|
|
280
|
+
},
|
|
281
|
+
"SHOPIFY_CLI": {
|
|
282
|
+
"files": ["shopify.app.toml"],
|
|
283
|
+
"packages": ["@shopify/cli"]
|
|
284
|
+
},
|
|
285
|
+
"SHOPIFY_THEMEKIT_CLI": {
|
|
286
|
+
"files": ["shopify.app.toml"]
|
|
287
|
+
},
|
|
288
|
+
"WP_CLI": {
|
|
289
|
+
"files": ["wp-config.php", "wp-content/"]
|
|
290
|
+
},
|
|
291
|
+
"CONTENTFUL_CLI": {
|
|
292
|
+
"packages": ["contentful", "contentful-management"]
|
|
293
|
+
},
|
|
294
|
+
"MYSQL_CLI": {
|
|
295
|
+
"packages": ["mysql", "mysql2", "sequelize", "typeorm", "prisma", "drizzle-orm"]
|
|
296
|
+
},
|
|
297
|
+
"CLOUDFLARE": {
|
|
298
|
+
"files": ["wrangler.toml", "wrangler.json", "wrangler.jsonc"],
|
|
299
|
+
"packages": ["wrangler"]
|
|
300
|
+
},
|
|
301
|
+
"NATIVE_BUILD_WINDOWS": {
|
|
302
|
+
"files": ["*.sln", "*.slnx", "*.csproj"]
|
|
303
|
+
},
|
|
304
|
+
"GIT_CRYPT_UNLOCK": {
|
|
305
|
+
"files": [".git-crypt/"]
|
|
306
|
+
},
|
|
307
|
+
"GIT_CRYPT_LOCK": {
|
|
308
|
+
"files": [".git-crypt/"]
|
|
309
|
+
},
|
|
310
|
+
"JIRA_BUILD": {
|
|
311
|
+
"files": [".jira/"]
|
|
312
|
+
},
|
|
313
|
+
"JIRA_DEPLOYMENT": {
|
|
314
|
+
"files": [".jira/"]
|
|
315
|
+
},
|
|
316
|
+
"NPM_PUBLISH": {
|
|
317
|
+
"files": ["package.json"]
|
|
318
|
+
},
|
|
319
|
+
"DOCTL": {
|
|
320
|
+
"files": [".do/"],
|
|
321
|
+
"packages": ["digitalocean", "do-wrapper"]
|
|
322
|
+
},
|
|
323
|
+
"DIGITAL_OCEAN_CDN": {
|
|
324
|
+
"files": [".do/"],
|
|
325
|
+
"packages": ["digitalocean", "do-wrapper"]
|
|
326
|
+
},
|
|
327
|
+
"SLACK": {
|
|
328
|
+
"packages": ["@slack/web-api", "@slack/bolt", "@slack/webhook"]
|
|
329
|
+
},
|
|
330
|
+
"DISCORD2": {
|
|
331
|
+
"packages": ["discord.js", "discord-webhook-node"]
|
|
332
|
+
},
|
|
333
|
+
"MICROSOFT_TEAMS": {
|
|
334
|
+
"packages": ["botbuilder", "@microsoft/teams-js"]
|
|
335
|
+
},
|
|
336
|
+
"TELEGRAM": {
|
|
337
|
+
"packages": ["telegraf", "node-telegram-bot-api", "grammy"]
|
|
338
|
+
},
|
|
339
|
+
"EMAIL": {
|
|
340
|
+
"packages": ["nodemailer", "@sendgrid/mail", "postmark", "mailgun-js"]
|
|
341
|
+
},
|
|
342
|
+
"POWERSHELL": {
|
|
343
|
+
"files": ["*.ps1", "*.psm1"]
|
|
344
|
+
},
|
|
345
|
+
"GHOST_INSPECTOR_CLI": {
|
|
346
|
+
"packages": ["ghost-inspector"]
|
|
347
|
+
},
|
|
348
|
+
"BACKBLAZE_B2": {
|
|
349
|
+
"packages": ["backblaze-b2"]
|
|
350
|
+
}
|
|
351
|
+
}
|
package/distTs/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bdy",
|
|
3
3
|
"preferGlobal": false,
|
|
4
|
-
"version": "1.23.
|
|
4
|
+
"version": "1.23.13-dev-target-commands",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://buddy.works/docs/cli",
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
"e2e:tunnel": "vitest run --config e2e/vitest.config.ts e2e/modules/tunnel/",
|
|
28
28
|
"e2e:agent": "vitest run --config e2e/vitest.config.ts e2e/modules/agent/",
|
|
29
29
|
"e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/",
|
|
30
|
+
"e2e:target": "vitest run --config e2e/vitest.config.ts e2e/modules/target/",
|
|
31
|
+
"e2e:environment": "vitest run --config e2e/vitest.config.ts e2e/modules/environment/",
|
|
30
32
|
"unit": "vitest run --config vitest.config.ts"
|
|
31
33
|
},
|
|
32
34
|
"files": [
|
package/distTs/src/api/client.js
CHANGED
|
@@ -16,6 +16,25 @@ const cfg_1 = __importDefault(require("../tunnel/cfg"));
|
|
|
16
16
|
* echo back the escaped form - callers comparing a response against the names
|
|
17
17
|
* they passed in must apply the same mapping.
|
|
18
18
|
*/
|
|
19
|
+
const RETRIABLE_NETWORK_ERROR = /ECONNREFUSED|ECONNRESET|ETIMEDOUT/;
|
|
20
|
+
// undici headers can be string | string[]; callers want the first value.
|
|
21
|
+
const headerValue = (h) => Array.isArray(h) ? h[0] : h;
|
|
22
|
+
// How long to wait before retrying a transient status on an idempotent
|
|
23
|
+
// request, or null when a retry makes no sense (non-retriable status, or a
|
|
24
|
+
// rate limit window that resets too far in the future to wait for).
|
|
25
|
+
const retryDelay = (status, attempt, rateLimitReset) => {
|
|
26
|
+
if (status === 429) {
|
|
27
|
+
if (!rateLimitReset)
|
|
28
|
+
return null;
|
|
29
|
+
const ms = parseInt(rateLimitReset, 10) * 1000 - Date.now();
|
|
30
|
+
if (ms <= 0)
|
|
31
|
+
return 1000;
|
|
32
|
+
return ms > 15000 ? null : ms + 500;
|
|
33
|
+
}
|
|
34
|
+
return [502, 503, 504].includes(status) ? attempt * 1000 : null;
|
|
35
|
+
};
|
|
36
|
+
const RATE_LIMIT_WARN_THRESHOLD = 25;
|
|
37
|
+
let rateLimitWarned = false;
|
|
19
38
|
const formDataFileName = (name) => name.replace(/["\r\n]/g, (c) => ({ '"': '%22', '\r': '%0D', '\n': '%0A' })[c]);
|
|
20
39
|
exports.formDataFileName = formDataFileName;
|
|
21
40
|
class ApiClient {
|
|
@@ -112,20 +131,41 @@ class ApiClient {
|
|
|
112
131
|
logger_1.default.debug(headers);
|
|
113
132
|
logger_1.default.debug('BODY');
|
|
114
133
|
logger_1.default.debug(bodyParsed);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
134
|
+
// Transient failures (rate limit with a nearby reset, 5xx, connection
|
|
135
|
+
// resets) are retried with a backoff, but only for idempotent requests -
|
|
136
|
+
// retrying a POST could duplicate the operation.
|
|
137
|
+
const maxAttempts = method === 'GET' ? 3 : 1;
|
|
138
|
+
for (let attempt = 1;; attempt += 1) {
|
|
139
|
+
try {
|
|
140
|
+
response = await this.client.request(opts);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
logger_1.default.debug('API CLIENT RESPONSE ERROR');
|
|
144
|
+
logger_1.default.debug(err);
|
|
145
|
+
const retriable = RETRIABLE_NETWORK_ERROR.test(err.message);
|
|
146
|
+
if (retriable && attempt < maxAttempts) {
|
|
147
|
+
await (0, utils_1.sleep)(attempt * 1000);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
throw new Error(retriable ? texts_1.ERR_REST_API_CONNECT_ERROR : texts_1.ERR_REST_API_GENERAL_ERROR, { cause: err });
|
|
151
|
+
}
|
|
152
|
+
rateLimitReset = headerValue(response.headers['x-rate-limit-reset']);
|
|
118
153
|
status = response.statusCode;
|
|
119
154
|
responseBody = response.body;
|
|
120
155
|
logger_1.default.debug(`API CLIENT RESPONSE STATUS: ${status}`);
|
|
156
|
+
const delay = attempt < maxAttempts
|
|
157
|
+
? retryDelay(status, attempt, rateLimitReset)
|
|
158
|
+
: null;
|
|
159
|
+
if (delay === null)
|
|
160
|
+
break;
|
|
161
|
+
await responseBody.dump();
|
|
162
|
+
logger_1.default.debug(`API CLIENT RETRY IN ${delay}ms`);
|
|
163
|
+
await (0, utils_1.sleep)(delay);
|
|
121
164
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
throw new Error(texts_1.ERR_REST_API_CONNECT_ERROR, { cause: err });
|
|
127
|
-
}
|
|
128
|
-
throw new Error(texts_1.ERR_REST_API_GENERAL_ERROR, { cause: err });
|
|
165
|
+
this.warnRateLimitLow(headerValue(response.headers['x-rate-limit-remaining']), rateLimitReset);
|
|
166
|
+
if (status === 429) {
|
|
167
|
+
await responseBody.dump();
|
|
168
|
+
throw new Error((0, texts_1.ERR_REST_API_RATE_LIMIT)(rateLimitReset));
|
|
129
169
|
}
|
|
130
170
|
if (status === 401) {
|
|
131
171
|
await responseBody.dump();
|
|
@@ -185,7 +225,7 @@ class ApiClient {
|
|
|
185
225
|
if (status === 404)
|
|
186
226
|
throw new Error(texts_1.ERR_REST_API_RESOURCE_NOT_FOUND);
|
|
187
227
|
else
|
|
188
|
-
throw new Error(texts_1.
|
|
228
|
+
throw new Error((0, texts_1.ERR_REST_API_HTTP_ERROR)(status));
|
|
189
229
|
}
|
|
190
230
|
if ([200, 201].includes(status)) {
|
|
191
231
|
if (parseResponseBody) {
|
|
@@ -221,9 +261,23 @@ class ApiClient {
|
|
|
221
261
|
}
|
|
222
262
|
else {
|
|
223
263
|
await responseBody.dump();
|
|
224
|
-
throw new Error(texts_1.
|
|
264
|
+
throw new Error((0, texts_1.ERR_REST_API_HTTP_ERROR)(status));
|
|
225
265
|
}
|
|
226
266
|
}
|
|
267
|
+
// Set by the CLI bootstrap (Input.restApiTokenClient); the transport layer
|
|
268
|
+
// only detects the condition and leaves rendering to the caller, so
|
|
269
|
+
// non-interactive consumers (MCP proxy) stay silent.
|
|
270
|
+
static onRateLimitLow;
|
|
271
|
+
// One-time notification when the rate limit window is nearly exhausted.
|
|
272
|
+
warnRateLimitLow(remaining, reset) {
|
|
273
|
+
if (rateLimitWarned || !remaining || !ApiClient.onRateLimitLow)
|
|
274
|
+
return;
|
|
275
|
+
const left = parseInt(remaining, 10);
|
|
276
|
+
if (Number.isNaN(left) || left > RATE_LIMIT_WARN_THRESHOLD)
|
|
277
|
+
return;
|
|
278
|
+
rateLimitWarned = true;
|
|
279
|
+
ApiClient.onRateLimitLow(remaining, reset);
|
|
280
|
+
}
|
|
227
281
|
async getPipelineRunActionLogs(workspace, project, pipelineId, executionId, actionExecutionId, offset, limit) {
|
|
228
282
|
const query = {
|
|
229
283
|
offset: String(offset),
|
|
@@ -563,6 +617,162 @@ class ApiClient {
|
|
|
563
617
|
q.project = project;
|
|
564
618
|
return await this.getResourceByIdentifier(workspace, q);
|
|
565
619
|
}
|
|
620
|
+
// Target methods
|
|
621
|
+
targetScopeQuery(scope) {
|
|
622
|
+
const query = {};
|
|
623
|
+
if (scope.project)
|
|
624
|
+
query.project_name = scope.project;
|
|
625
|
+
if (scope.pipelineId)
|
|
626
|
+
query.pipeline_id = scope.pipelineId.toString();
|
|
627
|
+
if (scope.environmentId)
|
|
628
|
+
query.environment_id = scope.environmentId;
|
|
629
|
+
return query;
|
|
630
|
+
}
|
|
631
|
+
async getTargets(workspace, filters = {}) {
|
|
632
|
+
return await this.request({
|
|
633
|
+
method: 'GET',
|
|
634
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets`,
|
|
635
|
+
query: this.targetScopeQuery(filters),
|
|
636
|
+
parseResponseBody: true,
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
async getTarget(workspace, targetId) {
|
|
640
|
+
return await this.request({
|
|
641
|
+
method: 'GET',
|
|
642
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}`,
|
|
643
|
+
parseResponseBody: true,
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
async createTargetByYaml(workspace, scope, body) {
|
|
647
|
+
return await this.request({
|
|
648
|
+
method: 'POST',
|
|
649
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/yaml`,
|
|
650
|
+
query: this.targetScopeQuery(scope),
|
|
651
|
+
body,
|
|
652
|
+
parseResponseBody: true,
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
async updateTargetByYaml(workspace, targetId, body) {
|
|
656
|
+
return await this.request({
|
|
657
|
+
method: 'PATCH',
|
|
658
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}/yaml`,
|
|
659
|
+
body,
|
|
660
|
+
parseResponseBody: true,
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
async deleteTarget(workspace, targetId) {
|
|
664
|
+
return await this.request({
|
|
665
|
+
method: 'DELETE',
|
|
666
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}`,
|
|
667
|
+
parseResponseBody: false,
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
async executeTargetCommand(workspace, targetId, body) {
|
|
671
|
+
return await this.request({
|
|
672
|
+
method: 'POST',
|
|
673
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}/execs`,
|
|
674
|
+
body,
|
|
675
|
+
parseResponseBody: true,
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
async getTargetExecs(workspace, targetId, limit) {
|
|
679
|
+
const query = {};
|
|
680
|
+
if (limit)
|
|
681
|
+
query.limit = limit.toString();
|
|
682
|
+
return await this.request({
|
|
683
|
+
method: 'GET',
|
|
684
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/${encodeURIComponent(targetId)}/execs`,
|
|
685
|
+
query,
|
|
686
|
+
parseResponseBody: true,
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
async getTargetExec(workspace, execId, wait) {
|
|
690
|
+
const query = {};
|
|
691
|
+
if (wait)
|
|
692
|
+
query.wait = wait.toString();
|
|
693
|
+
return await this.request({
|
|
694
|
+
method: 'GET',
|
|
695
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/execs/${encodeURIComponent(execId)}`,
|
|
696
|
+
query,
|
|
697
|
+
parseResponseBody: true,
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
async cancelTargetExec(workspace, execId) {
|
|
701
|
+
return await this.request({
|
|
702
|
+
method: 'DELETE',
|
|
703
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/execs/${encodeURIComponent(execId)}`,
|
|
704
|
+
parseResponseBody: false,
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
async getTargetExecLog(workspace, execId, offset, limit) {
|
|
708
|
+
const query = {};
|
|
709
|
+
if (offset)
|
|
710
|
+
query.offset = offset.toString();
|
|
711
|
+
if (limit)
|
|
712
|
+
query.limit = limit.toString();
|
|
713
|
+
return await this.request({
|
|
714
|
+
method: 'GET',
|
|
715
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/targets/execs/${encodeURIComponent(execId)}/log`,
|
|
716
|
+
query,
|
|
717
|
+
parseResponseBody: true,
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
async getTargetByIdentifier(workspace, identifier, line = {}) {
|
|
721
|
+
return await this.getResourceByIdentifier(workspace, {
|
|
722
|
+
target: identifier,
|
|
723
|
+
...line,
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
// Environment methods
|
|
727
|
+
async getEnvironments(workspace, project) {
|
|
728
|
+
const query = {};
|
|
729
|
+
if (project)
|
|
730
|
+
query.project_name = project;
|
|
731
|
+
return await this.request({
|
|
732
|
+
method: 'GET',
|
|
733
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/environments`,
|
|
734
|
+
query,
|
|
735
|
+
parseResponseBody: true,
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
async getEnvironment(workspace, environmentId) {
|
|
739
|
+
return await this.request({
|
|
740
|
+
method: 'GET',
|
|
741
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/environments/${encodeURIComponent(environmentId)}`,
|
|
742
|
+
parseResponseBody: true,
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
async createEnvironment(workspace, body) {
|
|
746
|
+
return await this.request({
|
|
747
|
+
method: 'POST',
|
|
748
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/environments`,
|
|
749
|
+
body,
|
|
750
|
+
parseResponseBody: true,
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
async updateEnvironment(workspace, environmentId, body) {
|
|
754
|
+
return await this.request({
|
|
755
|
+
method: 'PATCH',
|
|
756
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/environments/${encodeURIComponent(environmentId)}`,
|
|
757
|
+
body,
|
|
758
|
+
parseResponseBody: true,
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
async deleteEnvironment(workspace, environmentId) {
|
|
762
|
+
return await this.request({
|
|
763
|
+
method: 'DELETE',
|
|
764
|
+
path: `/workspaces/${encodeURIComponent(workspace)}/environments/${encodeURIComponent(environmentId)}`,
|
|
765
|
+
parseResponseBody: false,
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
async getEnvironmentByIdentifier(workspace, identifier, project) {
|
|
769
|
+
const q = {
|
|
770
|
+
environment: identifier,
|
|
771
|
+
};
|
|
772
|
+
if (project)
|
|
773
|
+
q.project = project;
|
|
774
|
+
return await this.getResourceByIdentifier(workspace, q);
|
|
775
|
+
}
|
|
566
776
|
// Sandbox methods
|
|
567
777
|
async createSandbox(workspace, project, body) {
|
|
568
778
|
return await this.request({
|
package/distTs/src/cliIndex.js
CHANGED
|
@@ -24,6 +24,8 @@ const artifact_1 = __importDefault(require("./command/artifact"));
|
|
|
24
24
|
const api_1 = __importDefault(require("./command/api"));
|
|
25
25
|
const domain_1 = __importDefault(require("./command/domain"));
|
|
26
26
|
const distro_1 = __importDefault(require("./command/distro"));
|
|
27
|
+
const target_1 = __importDefault(require("./command/target"));
|
|
28
|
+
const environment_1 = __importDefault(require("./command/environment"));
|
|
27
29
|
const register_1 = __importDefault(require("./command/register"));
|
|
28
30
|
const mcp_1 = __importDefault(require("./command/mcp"));
|
|
29
31
|
function cliIndex() {
|
|
@@ -47,6 +49,8 @@ function cliIndex() {
|
|
|
47
49
|
program.addCommand(sandbox_1.default);
|
|
48
50
|
program.addCommand(domain_1.default);
|
|
49
51
|
program.addCommand(distro_1.default);
|
|
52
|
+
program.addCommand(target_1.default);
|
|
53
|
+
program.addCommand(environment_1.default);
|
|
50
54
|
program.addCommand(login_1.default);
|
|
51
55
|
program.addCommand(register_1.default);
|
|
52
56
|
program.addCommand(whoami_1.default);
|
|
@@ -18,14 +18,12 @@ commandArtifactList.action(async (options) => {
|
|
|
18
18
|
const workspace = input_1.default.restApiWorkspace(options.workspace);
|
|
19
19
|
const project = input_1.default.restApiProject(options.project, true);
|
|
20
20
|
const scope = input_1.default.scope(project, options.scope);
|
|
21
|
+
input_1.default.projectScopeNote(options, project, scope, 'artifacts');
|
|
21
22
|
const client = input_1.default.restApiTokenClient();
|
|
22
23
|
const response = await client.getArtifacts(workspace, scope === distro_1.SCOPE.PROJECT ? project : null);
|
|
23
24
|
const artifacts = response.artifacts || [];
|
|
24
25
|
if (options.format === 'json') {
|
|
25
|
-
|
|
26
|
-
? artifacts.filter((a) => a.scope !== distro_1.SCOPE.WORKSPACE)
|
|
27
|
-
: artifacts;
|
|
28
|
-
output_1.default.json(filtered);
|
|
26
|
+
output_1.default.json(artifacts);
|
|
29
27
|
}
|
|
30
28
|
else {
|
|
31
29
|
if (artifacts.length === 0) {
|
|
@@ -33,8 +31,6 @@ commandArtifactList.action(async (options) => {
|
|
|
33
31
|
}
|
|
34
32
|
const data = [['NAME', 'IDENTIFIER', 'TYPE', 'URL']];
|
|
35
33
|
for (const artifact of artifacts) {
|
|
36
|
-
if (scope === distro_1.SCOPE.PROJECT && artifact.scope === distro_1.SCOPE.WORKSPACE)
|
|
37
|
-
continue;
|
|
38
34
|
data.push([
|
|
39
35
|
artifact.name,
|
|
40
36
|
artifact.identifier,
|