bdy 1.24.8-stage → 1.25.0-dev
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 +7 -2
- package/distTs/src/cliIndex.js +2 -0
- package/distTs/src/command/yaml/actions/detect.js +268 -0
- package/distTs/src/command/yaml/actions/info.js +79 -0
- package/distTs/src/command/yaml/actions/list.js +96 -0
- package/distTs/src/command/yaml/actions/schema.js +104 -0
- package/distTs/src/command/yaml/actions.js +16 -0
- package/distTs/src/command/yaml/cache.js +106 -0
- package/distTs/src/command/yaml/pipeline.js +53 -0
- package/distTs/src/command/yaml/render.js +111 -0
- package/distTs/src/command/yaml/schemaUtils.js +164 -0
- package/distTs/src/command/yaml/validate.js +300 -0
- package/distTs/src/command/yaml.js +20 -0
- package/distTs/src/diskCache.js +200 -0
- package/distTs/src/openapi.js +10 -81
- package/distTs/src/texts.js +66 -1
- package/distTs/src/utils.js +18 -13
- package/package.json +7 -2
|
@@ -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.
|
|
4
|
+
"version": "1.25.0-dev",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://buddy.works/docs/cli",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"lint": "eslint \"*/**\"",
|
|
13
13
|
"lint:types": "tsc --skipLibCheck --noEmit --project tsconfig.json && tsc --skipLibCheck --project test/tsconfig.json && tsc --skipLibCheck --project e2e/tsconfig.json",
|
|
14
14
|
"watch": "tsc --watch --project tsconfig.json & tsc --watch --project src/visualTest/utils/tsconfig.json",
|
|
15
|
-
"buildTs": "(tsc --project tsconfig.json & tsc --project src/visualTest/utils/tsconfig.json & wait) && cp package.json distTs/package.json && curl -fsSL https://raw.githubusercontent.com/buddy/cli/main/README.md -o README.md",
|
|
15
|
+
"buildTs": "(tsc --project tsconfig.json & tsc --project src/visualTest/utils/tsconfig.json & wait) && cp package.json distTs/package.json && cp detect-rules.json distTs/detect-rules.json && curl -fsSL https://raw.githubusercontent.com/buddy/cli/main/README.md -o README.md",
|
|
16
16
|
"e2e": "npm run buildTs && vitest run --config e2e/vitest.config.ts",
|
|
17
17
|
"e2e:version": "vitest run --config e2e/vitest.config.ts e2e/modules/version/",
|
|
18
18
|
"e2e:tunnel-config": "vitest run --config e2e/vitest.config.ts e2e/modules/tunnel-config/",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/",
|
|
30
30
|
"e2e:target": "vitest run --config e2e/vitest.config.ts e2e/modules/target/",
|
|
31
31
|
"e2e:environment": "vitest run --config e2e/vitest.config.ts e2e/modules/environment/",
|
|
32
|
+
"e2e:yaml": "vitest run --config e2e/vitest.config.ts e2e/modules/yaml/",
|
|
32
33
|
"unit": "vitest run --config vitest.config.ts"
|
|
33
34
|
},
|
|
34
35
|
"files": [
|
|
@@ -58,6 +59,8 @@
|
|
|
58
59
|
"@scalar/openapi-parser": "0.28.7",
|
|
59
60
|
"@scalar/openapi-types": "0.9.1",
|
|
60
61
|
"@xhmikosr/decompress": "11.1.3",
|
|
62
|
+
"ajv": "8.20.0",
|
|
63
|
+
"ajv-formats": "3.0.1",
|
|
61
64
|
"basic-auth": "2.0.1",
|
|
62
65
|
"chalk": "5.6.2",
|
|
63
66
|
"commander": "15.0.0",
|
|
@@ -74,6 +77,7 @@
|
|
|
74
77
|
"jsonwebtoken": "9.0.3",
|
|
75
78
|
"mime-db": "1.54.0",
|
|
76
79
|
"mime-types": "3.0.2",
|
|
80
|
+
"minisearch": "7.2.0",
|
|
77
81
|
"netmask": "2.1.1",
|
|
78
82
|
"node-forge": "1.4.0",
|
|
79
83
|
"open": "11.0.0",
|
|
@@ -92,6 +96,7 @@
|
|
|
92
96
|
"uuid": "14.0.0",
|
|
93
97
|
"which": "4.0.0",
|
|
94
98
|
"ws": "8.21.0",
|
|
99
|
+
"yaml": "2.8.3",
|
|
95
100
|
"zod": "3.25.76"
|
|
96
101
|
},
|
|
97
102
|
"devDependencies": {
|
package/distTs/src/cliIndex.js
CHANGED
|
@@ -21,6 +21,7 @@ const workspace_1 = __importDefault(require("./command/workspace"));
|
|
|
21
21
|
const project_1 = __importDefault(require("./command/project"));
|
|
22
22
|
const whoami_1 = __importDefault(require("./command/whoami"));
|
|
23
23
|
const artifact_1 = __importDefault(require("./command/artifact"));
|
|
24
|
+
const yaml_1 = __importDefault(require("./command/yaml"));
|
|
24
25
|
const api_1 = __importDefault(require("./command/api"));
|
|
25
26
|
const domain_1 = __importDefault(require("./command/domain"));
|
|
26
27
|
const distro_1 = __importDefault(require("./command/distro"));
|
|
@@ -57,6 +58,7 @@ function cliIndex() {
|
|
|
57
58
|
program.addCommand(logout_1.default);
|
|
58
59
|
program.addCommand(workspace_1.default);
|
|
59
60
|
program.addCommand(project_1.default);
|
|
61
|
+
program.addCommand(yaml_1.default);
|
|
60
62
|
program.addCommand(api_1.default);
|
|
61
63
|
program.addCommand(mcp_1.default);
|
|
62
64
|
program.action((_, cmd) => {
|
|
@@ -0,0 +1,268 @@
|
|
|
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.detectActions = detectActions;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const picomatch_1 = __importDefault(require("picomatch"));
|
|
10
|
+
const utils_1 = require("../../../utils");
|
|
11
|
+
const cache_1 = require("../cache");
|
|
12
|
+
const DETECT_CACHE_TTL = 10 * 60 * 1000; // 10 minutes
|
|
13
|
+
const DETECT_CACHE_PREFIX = 'detect:';
|
|
14
|
+
let cachedRules = null;
|
|
15
|
+
function loadDetectRules() {
|
|
16
|
+
if (cachedRules)
|
|
17
|
+
return cachedRules;
|
|
18
|
+
const filePath = path_1.default.resolve((0, utils_1.getRootDir)(), 'detect-rules.json');
|
|
19
|
+
cachedRules = JSON.parse((0, fs_1.readFileSync)(filePath, 'utf8'));
|
|
20
|
+
return cachedRules;
|
|
21
|
+
}
|
|
22
|
+
function safeReadDir(dir) {
|
|
23
|
+
try {
|
|
24
|
+
return (0, fs_1.readdirSync)(dir, { withFileTypes: true });
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function readDirIndex(dir) {
|
|
31
|
+
const names = [];
|
|
32
|
+
const lowerNames = new Set();
|
|
33
|
+
const lowerDirs = new Set();
|
|
34
|
+
for (const entry of safeReadDir(dir)) {
|
|
35
|
+
names.push(entry.name);
|
|
36
|
+
lowerNames.add(entry.name.toLowerCase());
|
|
37
|
+
if (entry.isDirectory())
|
|
38
|
+
lowerDirs.add(entry.name.toLowerCase());
|
|
39
|
+
}
|
|
40
|
+
return { names, lowerNames, lowerDirs };
|
|
41
|
+
}
|
|
42
|
+
function existsCaseInsensitive(dir, relPath, mustBeDir) {
|
|
43
|
+
const segments = relPath.split('/').filter(Boolean);
|
|
44
|
+
if (segments.length === 0)
|
|
45
|
+
return false;
|
|
46
|
+
let current = dir;
|
|
47
|
+
for (let i = 0; i < segments.length; i++) {
|
|
48
|
+
const lower = segments[i].toLowerCase();
|
|
49
|
+
const found = safeReadDir(current).find((e) => e.name.toLowerCase() === lower);
|
|
50
|
+
if (!found)
|
|
51
|
+
return false;
|
|
52
|
+
if (i === segments.length - 1 && mustBeDir && !found.isDirectory())
|
|
53
|
+
return false;
|
|
54
|
+
current = path_1.default.join(current, found.name);
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
function fileMatchesAny(patterns, dir, index) {
|
|
59
|
+
for (const pattern of patterns) {
|
|
60
|
+
if (pattern.includes('*')) {
|
|
61
|
+
const isMatch = (0, picomatch_1.default)(pattern, { nocase: true, dot: true });
|
|
62
|
+
if (index.names.some((name) => isMatch(name)))
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
else if (pattern.includes('/')) {
|
|
66
|
+
const mustBeDir = pattern.endsWith('/');
|
|
67
|
+
const rel = mustBeDir ? pattern.slice(0, -1) : pattern;
|
|
68
|
+
if (rel.includes('/')) {
|
|
69
|
+
if (existsCaseInsensitive(dir, rel, mustBeDir))
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
else if (mustBeDir) {
|
|
73
|
+
if (index.lowerDirs.has(rel.toLowerCase()))
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
else if (index.lowerNames.has(rel.toLowerCase())) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (index.lowerNames.has(pattern.toLowerCase())) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
function parsePackageJson(content) {
|
|
87
|
+
const pkg = JSON.parse(content);
|
|
88
|
+
return Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
|
|
89
|
+
}
|
|
90
|
+
function parseRequirementsTxt(content) {
|
|
91
|
+
const names = [];
|
|
92
|
+
for (const line of content.split('\n')) {
|
|
93
|
+
const trimmed = line.trim();
|
|
94
|
+
if (trimmed && !trimmed.startsWith('#') && !trimmed.startsWith('-')) {
|
|
95
|
+
names.push(trimmed.split(/[>=<!~[;]/)[0].trim());
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return names;
|
|
99
|
+
}
|
|
100
|
+
function parseComposerJson(content) {
|
|
101
|
+
const composer = JSON.parse(content);
|
|
102
|
+
return Object.keys({ ...composer.require, ...composer['require-dev'] });
|
|
103
|
+
}
|
|
104
|
+
function parseGoMod(content) {
|
|
105
|
+
const names = [];
|
|
106
|
+
const requireBlocks = content.match(/require\s*\(([\s\S]*?)\)/g);
|
|
107
|
+
if (requireBlocks) {
|
|
108
|
+
for (const block of requireBlocks) {
|
|
109
|
+
for (const line of block.split('\n')) {
|
|
110
|
+
const trimmed = line.trim();
|
|
111
|
+
if (trimmed && !trimmed.startsWith('//') && !trimmed.startsWith('require') && trimmed !== ')') {
|
|
112
|
+
names.push(trimmed.split(/\s/)[0]);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const singleReqs = content.match(/^require\s+(\S+)/gm);
|
|
118
|
+
if (singleReqs) {
|
|
119
|
+
for (const req of singleReqs)
|
|
120
|
+
names.push(req.replace(/^require\s+/, '').trim());
|
|
121
|
+
}
|
|
122
|
+
return names;
|
|
123
|
+
}
|
|
124
|
+
function parseGemfile(content) {
|
|
125
|
+
const names = [];
|
|
126
|
+
for (const line of content.split('\n')) {
|
|
127
|
+
const match = line.match(/^\s*gem\s+['"]([^'"]+)['"]/);
|
|
128
|
+
if (match)
|
|
129
|
+
names.push(match[1]);
|
|
130
|
+
}
|
|
131
|
+
return names;
|
|
132
|
+
}
|
|
133
|
+
function parsePubspec(content) {
|
|
134
|
+
const YAML = require('yaml');
|
|
135
|
+
const pubspec = YAML.parse(content) || {};
|
|
136
|
+
return [
|
|
137
|
+
...Object.keys(pubspec.dependencies || {}),
|
|
138
|
+
...Object.keys(pubspec.dev_dependencies || {}),
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
function parseCargoToml(content) {
|
|
142
|
+
const names = [];
|
|
143
|
+
const depSection = content.match(/\[dependencies]([\s\S]*?)(?=\n\[|$)/);
|
|
144
|
+
if (depSection) {
|
|
145
|
+
for (const line of depSection[1].split('\n')) {
|
|
146
|
+
const match = line.match(/^(\S+)\s*=/);
|
|
147
|
+
if (match)
|
|
148
|
+
names.push(match[1]);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return names;
|
|
152
|
+
}
|
|
153
|
+
function parsePomXml(content) {
|
|
154
|
+
const names = [];
|
|
155
|
+
const artifacts = content.match(/<artifactId>([^<]+)<\/artifactId>/g);
|
|
156
|
+
if (artifacts) {
|
|
157
|
+
for (const a of artifacts)
|
|
158
|
+
names.push(a.replace(/<\/?artifactId>/g, ''));
|
|
159
|
+
}
|
|
160
|
+
return names;
|
|
161
|
+
}
|
|
162
|
+
function parseGradle(content) {
|
|
163
|
+
const names = [];
|
|
164
|
+
const deps = content.match(/(?:implementation|api|compile|testImplementation)\s*[('"]([^'"()]+)['")\s]/g);
|
|
165
|
+
if (deps) {
|
|
166
|
+
for (const d of deps) {
|
|
167
|
+
const match = d.match(/['"]([^'"]+)['"]/);
|
|
168
|
+
if (match)
|
|
169
|
+
names.push(match[1]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return names;
|
|
173
|
+
}
|
|
174
|
+
function parsePyproject(content) {
|
|
175
|
+
const names = [];
|
|
176
|
+
const depMatch = content.match(/dependencies\s*=\s*\[([\s\S]*?)]/);
|
|
177
|
+
if (depMatch) {
|
|
178
|
+
const items = depMatch[1].match(/["']([^"'>=<![;]+)/g);
|
|
179
|
+
if (items) {
|
|
180
|
+
for (const item of items)
|
|
181
|
+
names.push(item.replace(/^["']/, '').trim());
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return names;
|
|
185
|
+
}
|
|
186
|
+
const MANIFEST_PARSERS = [
|
|
187
|
+
{ file: 'package.json', parse: parsePackageJson },
|
|
188
|
+
{ file: 'requirements.txt', parse: parseRequirementsTxt },
|
|
189
|
+
{ file: 'composer.json', parse: parseComposerJson },
|
|
190
|
+
{ file: 'go.mod', parse: parseGoMod },
|
|
191
|
+
{ file: 'Gemfile', parse: parseGemfile },
|
|
192
|
+
{ file: 'pubspec.yaml', parse: parsePubspec },
|
|
193
|
+
{ file: 'Cargo.toml', parse: parseCargoToml },
|
|
194
|
+
{ file: 'pom.xml', parse: parsePomXml },
|
|
195
|
+
{ file: 'build.gradle', parse: parseGradle },
|
|
196
|
+
{ file: 'build.gradle.kts', parse: parseGradle },
|
|
197
|
+
{ file: 'pyproject.toml', parse: parsePyproject },
|
|
198
|
+
];
|
|
199
|
+
const LOCKFILES = ['package-lock.json', 'composer.lock', 'go.sum', 'Gemfile.lock', 'pubspec.lock', 'Cargo.lock'];
|
|
200
|
+
const MANIFEST_FILES = [...new Set(MANIFEST_PARSERS.map((p) => p.file)), ...LOCKFILES];
|
|
201
|
+
function readPackageNames(dir) {
|
|
202
|
+
const packages = new Set();
|
|
203
|
+
for (const { file, parse } of MANIFEST_PARSERS) {
|
|
204
|
+
const filePath = path_1.default.join(dir, file);
|
|
205
|
+
if (!(0, fs_1.existsSync)(filePath))
|
|
206
|
+
continue;
|
|
207
|
+
try {
|
|
208
|
+
for (const name of parse((0, fs_1.readFileSync)(filePath, 'utf8'))) {
|
|
209
|
+
if (name)
|
|
210
|
+
packages.add(name);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// ignore malformed manifests
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return packages;
|
|
218
|
+
}
|
|
219
|
+
function packageMatchesPattern(pkg, pattern) {
|
|
220
|
+
if (pattern.endsWith('/*')) {
|
|
221
|
+
const prefix = pattern.slice(0, -2);
|
|
222
|
+
return pkg.startsWith(prefix + '/');
|
|
223
|
+
}
|
|
224
|
+
return pkg === pattern;
|
|
225
|
+
}
|
|
226
|
+
function scanActions(dir) {
|
|
227
|
+
const rules = loadDetectRules();
|
|
228
|
+
const packages = readPackageNames(dir);
|
|
229
|
+
const detectedTypes = [];
|
|
230
|
+
const index = readDirIndex(dir);
|
|
231
|
+
for (const [type, rule] of Object.entries(rules)) {
|
|
232
|
+
let matched = false;
|
|
233
|
+
if (rule.files) {
|
|
234
|
+
matched = fileMatchesAny(rule.files, dir, index);
|
|
235
|
+
}
|
|
236
|
+
if (!matched && rule.packages) {
|
|
237
|
+
for (const pkgPattern of rule.packages) {
|
|
238
|
+
for (const pkg of packages) {
|
|
239
|
+
if (packageMatchesPattern(pkg, pkgPattern)) {
|
|
240
|
+
matched = true;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (matched)
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (matched) {
|
|
249
|
+
detectedTypes.push(type);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return detectedTypes;
|
|
253
|
+
}
|
|
254
|
+
let pruned = false;
|
|
255
|
+
function detectActions(dir) {
|
|
256
|
+
const cacheKey = DETECT_CACHE_PREFIX + dir;
|
|
257
|
+
const fingerprint = (0, cache_1.fingerprintFiles)(dir, MANIFEST_FILES);
|
|
258
|
+
const cached = (0, cache_1.getCache)(cacheKey, fingerprint);
|
|
259
|
+
if (cached)
|
|
260
|
+
return new Set(cached);
|
|
261
|
+
const detected = scanActions(dir);
|
|
262
|
+
(0, cache_1.setCache)(cacheKey, fingerprint, detected, DETECT_CACHE_TTL);
|
|
263
|
+
if (!pruned) {
|
|
264
|
+
pruned = true;
|
|
265
|
+
(0, cache_1.pruneCache)();
|
|
266
|
+
}
|
|
267
|
+
return new Set(detected);
|
|
268
|
+
}
|