@paklo/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/dist/browser/defineProperty-ie4tC-F5.js +43 -0
  3. package/dist/browser/environment-DinhzwQn.js +139 -0
  4. package/dist/browser/environment-DinhzwQn.js.map +1 -0
  5. package/dist/browser/environment.d.ts +33 -0
  6. package/dist/browser/environment.js +3 -0
  7. package/dist/browser/github.d.ts +151 -0
  8. package/dist/browser/github.js +199 -0
  9. package/dist/browser/github.js.map +1 -0
  10. package/dist/browser/http.d.ts +121 -0
  11. package/dist/browser/http.js +248 -0
  12. package/dist/browser/http.js.map +1 -0
  13. package/dist/browser/logger-B7HLv660.js +31 -0
  14. package/dist/browser/logger-B7HLv660.js.map +1 -0
  15. package/dist/browser/logger.d.ts +23 -0
  16. package/dist/browser/logger.js +4 -0
  17. package/dist/browser/shared-data.d.ts +22 -0
  18. package/dist/browser/shared-data.js +23 -0
  19. package/dist/browser/shared-data.js.map +1 -0
  20. package/dist/browser/usage.d.ts +99 -0
  21. package/dist/browser/usage.js +383 -0
  22. package/dist/browser/usage.js.map +1 -0
  23. package/dist/node/azure.d.ts +338 -0
  24. package/dist/node/azure.js +735 -0
  25. package/dist/node/azure.js.map +1 -0
  26. package/dist/node/dependabot-BteoKZVy.js +547 -0
  27. package/dist/node/dependabot-BteoKZVy.js.map +1 -0
  28. package/dist/node/dependabot.d.ts +3 -0
  29. package/dist/node/dependabot.js +6 -0
  30. package/dist/node/environment-DX5CD-dD.js +138 -0
  31. package/dist/node/environment-DX5CD-dD.js.map +1 -0
  32. package/dist/node/environment.d.ts +33 -0
  33. package/dist/node/environment.js +3 -0
  34. package/dist/node/github.d.ts +2 -0
  35. package/dist/node/github.js +198 -0
  36. package/dist/node/github.js.map +1 -0
  37. package/dist/node/http-BG_-s47I.js +245 -0
  38. package/dist/node/http-BG_-s47I.js.map +1 -0
  39. package/dist/node/http.d.ts +121 -0
  40. package/dist/node/http.js +4 -0
  41. package/dist/node/index-3wZw74Ah.d.ts +151 -0
  42. package/dist/node/index-DP9JfUPG.d.ts +1761 -0
  43. package/dist/node/job-Crr4kh3e.js +451 -0
  44. package/dist/node/job-Crr4kh3e.js.map +1 -0
  45. package/dist/node/logger-bWnHxtAf.js +31 -0
  46. package/dist/node/logger-bWnHxtAf.js.map +1 -0
  47. package/dist/node/logger.d.ts +23 -0
  48. package/dist/node/logger.js +4 -0
  49. package/dist/node/shared-data.d.ts +22 -0
  50. package/dist/node/shared-data.js +23 -0
  51. package/dist/node/shared-data.js.map +1 -0
  52. package/dist/node/usage.d.ts +99 -0
  53. package/dist/node/usage.js +48 -0
  54. package/dist/node/usage.js.map +1 -0
  55. package/package.json +93 -0
@@ -0,0 +1,547 @@
1
+ import { n as logger } from "./logger-bWnHxtAf.js";
2
+ import { s as DependabotDependencySchema } from "./job-Crr4kh3e.js";
3
+ import { z } from "zod/v4";
4
+ import * as crypto$1 from "node:crypto";
5
+ import { zValidator } from "@hono/zod-validator";
6
+ import { Hono } from "hono";
7
+
8
+ //#region src/dependabot/author.ts
9
+ const DEPENDABOT_DEFAULT_AUTHOR_EMAIL = "noreply@github.com";
10
+ const DEPENDABOT_DEFAULT_AUTHOR_NAME = "dependabot[bot]";
11
+
12
+ //#endregion
13
+ //#region src/dependabot/branch-name.ts
14
+ function getBranchNameForUpdate(packageEcosystem, targetBranchName, directory, dependencyGroupName, dependencies, separator = "/") {
15
+ let branchName;
16
+ if (dependencyGroupName || dependencies.length > 1) {
17
+ const dependencyDigest = crypto$1.createHash("md5").update(dependencies.map((d) => `${d["dependency-name"]}-${d["dependency-version"]}`).join(",")).digest("hex").substring(0, 10);
18
+ branchName = `${dependencyGroupName || "multi"}-${dependencyDigest}`;
19
+ } else branchName = `${dependencies.map((d) => d["dependency-name"]).join("-and-").replace(/[:[]]/g, "-").replace(/@/g, "")}-${dependencies[0]?.removed ? "removed" : dependencies[0]?.["dependency-version"]}`;
20
+ return sanitizeRef([
21
+ "dependabot",
22
+ packageEcosystem,
23
+ targetBranchName,
24
+ directory?.replace(/^\/+|\/+$/g, "").replace(/\//g, separator),
25
+ branchName
26
+ ], separator);
27
+ }
28
+ function sanitizeRef(refParts, separator) {
29
+ return refParts.filter((p) => p && p.trim().length > 0).join(separator).replace(/[^A-Za-z0-9/\-_.(){}]/g, "").replace(/\/\./g, "/dot-").replace(/\.+/g, ".").replace(/\/+/g, "/").replace(/\.$/, "");
30
+ }
31
+
32
+ //#endregion
33
+ //#region src/dependabot/experiments.ts
34
+ const DEFAULT_EXPERIMENTS = {
35
+ "record-ecosystem-versions": true,
36
+ "record-update-job-unknown-error": true,
37
+ "proxy-cached": true,
38
+ "move-job-token": true,
39
+ "dependency-change-validation": true,
40
+ "enable-file-parser-python-local": true,
41
+ "npm-fallback-version-above-v6": true,
42
+ "lead-security-dependency": true,
43
+ "enable-record-ecosystem-meta": true,
44
+ "enable-corepack-for-npm-and-yarn": true,
45
+ "enable-shared-helpers-command-timeout": true,
46
+ "enable-dependabot-setting-up-cronjob": true,
47
+ "enable-engine-version-detection": true,
48
+ "avoid-duplicate-updates-package-json": true,
49
+ "allow-refresh-for-existing-pr-dependencies": true,
50
+ "allow-refresh-group-with-all-dependencies": true,
51
+ "exclude-local-composer-packages": true,
52
+ "enable-enhanced-error-details-for-updater": true,
53
+ "gradle-lockfile-updater": true,
54
+ "enable-exclude-paths-subdirectory-manifest-files": true,
55
+ "group-membership-enforcement": true
56
+ };
57
+ /**
58
+ * Parses a comma-separated list of key=value pairs representing experiments.
59
+ * @param raw A comma-separated list of key=value pairs representing experiments.
60
+ * @returns A map of experiment names to their values.
61
+ */
62
+ function parseExperiments(raw) {
63
+ return raw?.split(",").filter((entry) => entry.trim() !== "").reduce((acc, cur) => {
64
+ const [key, value] = cur.split("=", 2);
65
+ acc[key] = value || true;
66
+ return acc;
67
+ }, {});
68
+ }
69
+
70
+ //#endregion
71
+ //#region src/dependabot/job-builder.ts
72
+ /**
73
+ * Class for building dependabot job objects
74
+ */
75
+ var DependabotJobBuilder = class {
76
+ config;
77
+ update;
78
+ experiments;
79
+ debug;
80
+ packageManager;
81
+ source;
82
+ credentials;
83
+ constructor({ source, config, update, systemAccessUser, systemAccessToken, githubToken, experiments, debug }) {
84
+ this.config = config;
85
+ this.update = update;
86
+ this.experiments = experiments;
87
+ this.debug = debug;
88
+ this.packageManager = mapPackageEcosystemToPackageManager(update["package-ecosystem"]);
89
+ this.source = mapSourceFromDependabotConfigToJobConfig(source, update);
90
+ this.credentials = mapCredentials({
91
+ sourceHostname: source.hostname,
92
+ systemAccessUser,
93
+ systemAccessToken,
94
+ githubToken,
95
+ registries: config.registries
96
+ });
97
+ }
98
+ /**
99
+ * Create a dependabot update job that updates nothing, but will discover the dependency list for a package ecosystem
100
+ */
101
+ forDependenciesList({ id, command }) {
102
+ id ??= makeRandomJobId();
103
+ return {
104
+ jobId: id,
105
+ job: {
106
+ id,
107
+ command,
108
+ "package-manager": this.packageManager,
109
+ "updating-a-pull-request": false,
110
+ dependencies: null,
111
+ "allowed-updates": [{
112
+ "dependency-type": "direct",
113
+ "update-type": "all"
114
+ }],
115
+ "ignore-conditions": [{ "dependency-name": "*" }],
116
+ "security-updates-only": false,
117
+ "security-advisories": [],
118
+ source: this.source,
119
+ "update-subdependencies": false,
120
+ "existing-pull-requests": [],
121
+ "existing-group-pull-requests": [],
122
+ experiments: this.experiments,
123
+ "requirements-update-strategy": null,
124
+ "lockfile-only": false,
125
+ "commit-message-options": {
126
+ prefix: null,
127
+ "prefix-development": null,
128
+ "include-scope": null
129
+ },
130
+ "vendor-dependencies": false,
131
+ "repo-private": true,
132
+ debug: this.debug
133
+ },
134
+ credentials: this.credentials
135
+ };
136
+ }
137
+ /**
138
+ * Create a dependabot update job that updates all dependencies for a package ecosystem
139
+ */
140
+ forUpdate({ id, command, dependencyNamesToUpdate, existingPullRequests, pullRequestToUpdate, securityVulnerabilities }) {
141
+ id ??= makeRandomJobId();
142
+ const securityOnlyUpdate = this.update["open-pull-requests-limit"] === 0;
143
+ let updatingPullRequest;
144
+ let updateDependencyGroupName = null;
145
+ let updateDependencyNames;
146
+ let vulnerabilities;
147
+ if (pullRequestToUpdate) {
148
+ updatingPullRequest = true;
149
+ updateDependencyGroupName = Array.isArray(pullRequestToUpdate) ? null : pullRequestToUpdate["dependency-group-name"];
150
+ updateDependencyNames = (Array.isArray(pullRequestToUpdate) ? pullRequestToUpdate : pullRequestToUpdate.dependencies)?.map((d) => d["dependency-name"]);
151
+ vulnerabilities = securityVulnerabilities?.filter((v) => updateDependencyNames?.includes(v.package.name));
152
+ } else {
153
+ updatingPullRequest = false;
154
+ const names = dependencyNamesToUpdate?.length ? dependencyNamesToUpdate : null;
155
+ updateDependencyNames = securityOnlyUpdate && names ? names?.filter((d) => securityVulnerabilities?.find((v) => v.package.name === d)) : names;
156
+ vulnerabilities = securityVulnerabilities;
157
+ }
158
+ return {
159
+ jobId: id,
160
+ job: {
161
+ id,
162
+ command,
163
+ "package-manager": this.packageManager,
164
+ "updating-a-pull-request": updatingPullRequest || false,
165
+ "dependency-group-to-refresh": updateDependencyGroupName,
166
+ "dependency-groups": mapGroupsFromDependabotConfigToJobConfig(this.update.groups),
167
+ dependencies: updateDependencyNames,
168
+ "allowed-updates": mapAllowedUpdatesFromDependabotConfigToJobConfig(this.update.allow, securityOnlyUpdate),
169
+ "ignore-conditions": mapIgnoreConditionsFromDependabotConfigToJobConfig(this.update.ignore),
170
+ "security-updates-only": securityOnlyUpdate,
171
+ "security-advisories": mapSecurityAdvisories(vulnerabilities),
172
+ source: this.source,
173
+ "update-subdependencies": false,
174
+ "existing-pull-requests": existingPullRequests.filter((pr) => Array.isArray(pr)),
175
+ "existing-group-pull-requests": existingPullRequests.filter((pr) => !Array.isArray(pr)),
176
+ "commit-message-options": {
177
+ prefix: this.update["commit-message"]?.prefix ?? null,
178
+ "prefix-development": this.update["commit-message"]?.["prefix-development"] ?? null,
179
+ "include-scope": this.update["commit-message"]?.include?.toLocaleLowerCase()?.trim() === "scope" ? true : null
180
+ },
181
+ cooldown: this.update.cooldown,
182
+ experiments: mapExperiments(this.experiments),
183
+ "reject-external-code": this.update["insecure-external-code-execution"]?.toLocaleLowerCase()?.trim() === "allow",
184
+ "requirements-update-strategy": mapVersionStrategyToRequirementsUpdateStrategy(this.update["versioning-strategy"]),
185
+ "lockfile-only": this.update["versioning-strategy"] === "lockfile-only",
186
+ "vendor-dependencies": this.update.vendor ?? false,
187
+ "repo-private": true,
188
+ debug: this.debug,
189
+ "proxy-log-response-body-on-auth-failure": true,
190
+ "max-updater-run-time": 2700,
191
+ "enable-beta-ecosystems": this.config["enable-beta-ecosystems"] || false,
192
+ "multi-ecosystem-update": false
193
+ },
194
+ credentials: this.credentials
195
+ };
196
+ }
197
+ };
198
+ function mapPackageEcosystemToPackageManager(ecosystem) {
199
+ switch (ecosystem) {
200
+ case "docker-compose": return "docker_compose";
201
+ case "dotnet-sdk": return "dotnet_sdk";
202
+ case "github-actions": return "github_actions";
203
+ case "gitsubmodule": return "submodules";
204
+ case "gomod": return "go_modules";
205
+ case "mix": return "hex";
206
+ case "npm": return "npm_and_yarn";
207
+ case "pipenv": return "pip";
208
+ case "pip-compile": return "pip";
209
+ case "poetry": return "pip";
210
+ case "pnpm": return "npm_and_yarn";
211
+ case "yarn": return "npm_and_yarn";
212
+ default: return ecosystem;
213
+ }
214
+ }
215
+ function mapSourceFromDependabotConfigToJobConfig(source, update) {
216
+ return {
217
+ provider: source.provider,
218
+ "api-endpoint": source["api-endpoint"],
219
+ hostname: source.hostname,
220
+ repo: source["repository-slug"],
221
+ branch: update["target-branch"],
222
+ commit: null,
223
+ directory: update.directory,
224
+ directories: update.directories
225
+ };
226
+ }
227
+ function mapVersionStrategyToRequirementsUpdateStrategy(strategy) {
228
+ if (!strategy) return null;
229
+ switch (strategy) {
230
+ case "auto": return null;
231
+ case "increase": return "bump_versions";
232
+ case "increase-if-necessary": return "bump_versions_if_necessary";
233
+ case "lockfile-only": return "lockfile_only";
234
+ case "widen": return "widen_ranges";
235
+ default: throw new Error(`Invalid dependabot.yaml versioning strategy option '${strategy}'`);
236
+ }
237
+ }
238
+ function mapGroupsFromDependabotConfigToJobConfig(dependencyGroups) {
239
+ if (!dependencyGroups || !Object.keys(dependencyGroups).length) return [];
240
+ return Object.keys(dependencyGroups).filter((name) => dependencyGroups[name]).map((name) => {
241
+ const group = dependencyGroups[name];
242
+ return {
243
+ name,
244
+ "applies-to": group["applies-to"],
245
+ rules: {
246
+ patterns: group.patterns?.length ? group.patterns : ["*"],
247
+ "exclude-patterns": group["exclude-patterns"],
248
+ "dependency-type": group["dependency-type"],
249
+ "update-types": group["update-types"]
250
+ }
251
+ };
252
+ });
253
+ }
254
+ function mapAllowedUpdatesFromDependabotConfigToJobConfig(allowedUpdates, securityOnlyUpdate) {
255
+ if (!allowedUpdates) return [{
256
+ "dependency-type": "direct",
257
+ "update-type": securityOnlyUpdate ? "security" : "all"
258
+ }];
259
+ return allowedUpdates.map((allow) => {
260
+ return {
261
+ "dependency-name": allow["dependency-name"],
262
+ "dependency-type": allow["dependency-type"],
263
+ "update-type": allow["update-type"]
264
+ };
265
+ });
266
+ }
267
+ function mapIgnoreConditionsFromDependabotConfigToJobConfig(ignoreConditions) {
268
+ if (!ignoreConditions) return [];
269
+ return ignoreConditions.map((ignore) => {
270
+ return {
271
+ source: ignore.source,
272
+ "updated-at": ignore["updated-at"],
273
+ "dependency-name": ignore["dependency-name"] ?? "*",
274
+ "update-types": ignore["update-types"],
275
+ "version-requirement": Array.isArray(ignore.versions) ? ignore.versions?.join(", ") : ignore.versions
276
+ };
277
+ });
278
+ }
279
+ function mapExperiments(experiments) {
280
+ experiments ??= {};
281
+ return Object.keys(experiments).reduce((acc, key) => {
282
+ const value = experiments[key];
283
+ if (typeof value === "string" && value?.toLocaleLowerCase() === "true") acc[key] = true;
284
+ else if (typeof value === "string" && value?.toLocaleLowerCase() === "false") acc[key] = false;
285
+ else if (typeof value === "string" || typeof value === "boolean") acc[key] = value;
286
+ return acc;
287
+ }, {});
288
+ }
289
+ function mapSecurityAdvisories(securityVulnerabilities) {
290
+ if (!securityVulnerabilities) return [];
291
+ const vulnerabilitiesGroupedByPackageNameAndAdvisoryId = /* @__PURE__ */ new Map();
292
+ for (const vuln of securityVulnerabilities) {
293
+ const key = `${vuln.package.name}/${vuln.advisory.identifiers.map((i) => `${i.type}:${i.value}`).join("/")}`;
294
+ if (!vulnerabilitiesGroupedByPackageNameAndAdvisoryId.has(key)) vulnerabilitiesGroupedByPackageNameAndAdvisoryId.set(key, []);
295
+ vulnerabilitiesGroupedByPackageNameAndAdvisoryId.get(key).push(vuln);
296
+ }
297
+ return Array.from(vulnerabilitiesGroupedByPackageNameAndAdvisoryId.values()).map((vulns) => {
298
+ return {
299
+ "dependency-name": vulns[0].package.name,
300
+ "affected-versions": vulns.map((v) => v.vulnerableVersionRange).filter((v) => v && v.length > 0),
301
+ "patched-versions": vulns.map((v) => v.firstPatchedVersion?.identifier).filter((v) => v && v.length > 0).map((v) => v),
302
+ "unaffected-versions": []
303
+ };
304
+ });
305
+ }
306
+ function mapCredentials({ sourceHostname, systemAccessUser, systemAccessToken, githubToken, registries }) {
307
+ const credentials = [];
308
+ if (systemAccessToken) credentials.push({
309
+ type: "git_source",
310
+ host: sourceHostname,
311
+ username: (systemAccessUser ?? "").trim()?.length > 0 ? systemAccessUser : "x-access-token",
312
+ password: systemAccessToken
313
+ });
314
+ if (githubToken) credentials.push({
315
+ type: "git_source",
316
+ host: "github.com",
317
+ username: "x-access-token",
318
+ password: githubToken
319
+ });
320
+ if (registries) credentials.push(...Object.values(registries));
321
+ return credentials;
322
+ }
323
+ function makeRandomJobId() {
324
+ const array = new Uint32Array(1);
325
+ crypto.getRandomValues(array);
326
+ return array[0] % 1e10;
327
+ }
328
+ function makeRandomJobToken() {
329
+ const array = new Uint8Array(30);
330
+ crypto.getRandomValues(array);
331
+ return Array.from(array, (byte) => (byte % 36).toString(36)).join("");
332
+ }
333
+
334
+ //#endregion
335
+ //#region src/dependabot/update.ts
336
+ const DependabotDependencyFileSchema = z.object({
337
+ content: z.string(),
338
+ content_encoding: z.string().nullish(),
339
+ deleted: z.boolean().nullish(),
340
+ directory: z.string(),
341
+ name: z.string(),
342
+ operation: z.string(),
343
+ support_file: z.boolean().nullish(),
344
+ symlink_target: z.string().nullish(),
345
+ type: z.string().nullish(),
346
+ mode: z.string().nullish()
347
+ });
348
+ const DependabotUpdateDependencyListSchema = z.object({
349
+ dependencies: DependabotDependencySchema.array(),
350
+ dependency_files: z.string().array().nullish()
351
+ });
352
+ const DependabotCreatePullRequestSchema = z.object({
353
+ "base-commit-sha": z.string(),
354
+ dependencies: DependabotDependencySchema.array(),
355
+ "updated-dependency-files": DependabotDependencyFileSchema.array(),
356
+ "pr-title": z.string(),
357
+ "pr-body": z.string().nullish(),
358
+ "commit-message": z.string(),
359
+ "dependency-group": z.record(z.string(), z.any()).nullish()
360
+ });
361
+ const DependabotUpdatePullRequestSchema = z.object({
362
+ "base-commit-sha": z.string(),
363
+ "dependency-names": z.string().array(),
364
+ "updated-dependency-files": DependabotDependencyFileSchema.array(),
365
+ "pr-title": z.string().nullish(),
366
+ "pr-body": z.string().nullish(),
367
+ "commit-message": z.string().nullish(),
368
+ "dependency-group": z.record(z.string(), z.any()).nullish()
369
+ });
370
+ const DependabotClosePullRequestSchema = z.object({
371
+ "dependency-names": z.string().array(),
372
+ reason: z.string().nullish()
373
+ });
374
+ const DependabotMarkAsProcessedSchema = z.object({ "base-commit-sha": z.string().nullish() });
375
+ const DependabotRecordUpdateJobErrorSchema = z.object({
376
+ "error-type": z.string(),
377
+ "error-details": z.record(z.string(), z.any()).nullish()
378
+ });
379
+ const DependabotRecordUpdateJobUnknownErrorSchema = z.object({
380
+ "error-type": z.string(),
381
+ "error-details": z.record(z.string(), z.any()).nullish()
382
+ });
383
+ const DependabotRecordEcosystemVersionsSchema = z.object({ ecosystem_versions: z.record(z.string(), z.any()).nullish() });
384
+ const DependabotEcosystemVersionManagerSchema = z.object({
385
+ name: z.string(),
386
+ version: z.string(),
387
+ raw_version: z.string(),
388
+ requirement: z.record(z.string(), z.any()).nullish()
389
+ });
390
+ const DependabotEcosystemMetaSchema = z.object({
391
+ name: z.string(),
392
+ package_manager: DependabotEcosystemVersionManagerSchema.nullish(),
393
+ version: DependabotEcosystemVersionManagerSchema.nullish()
394
+ });
395
+ const DependabotRecordEcosystemMetaSchema = z.object({ ecosystem: DependabotEcosystemMetaSchema });
396
+ const DependabotIncrementMetricSchema = z.object({
397
+ metric: z.string(),
398
+ tags: z.record(z.string(), z.any()).nullish()
399
+ });
400
+ const DependabotMetricSchema = z.object({
401
+ metric: z.string(),
402
+ type: z.enum([
403
+ "increment",
404
+ "gauge",
405
+ "distribution",
406
+ "histogram"
407
+ ]),
408
+ value: z.number().nullish(),
409
+ values: z.number().array().nullish(),
410
+ tags: z.record(z.string(), z.string()).nullish()
411
+ });
412
+
413
+ //#endregion
414
+ //#region src/dependabot/server.ts
415
+ const DependabotRequestTypeSchema = z.enum([
416
+ "create_pull_request",
417
+ "update_pull_request",
418
+ "close_pull_request",
419
+ "record_update_job_error",
420
+ "record_update_job_unknown_error",
421
+ "mark_as_processed",
422
+ "update_dependency_list",
423
+ "record_ecosystem_versions",
424
+ "record_ecosystem_meta",
425
+ "increment_metric",
426
+ "record_metrics"
427
+ ]);
428
+ const DependabotRequestSchema = z.discriminatedUnion("type", [
429
+ z.object({
430
+ type: z.literal("create_pull_request"),
431
+ data: DependabotCreatePullRequestSchema
432
+ }),
433
+ z.object({
434
+ type: z.literal("update_pull_request"),
435
+ data: DependabotUpdatePullRequestSchema
436
+ }),
437
+ z.object({
438
+ type: z.literal("close_pull_request"),
439
+ data: DependabotClosePullRequestSchema
440
+ }),
441
+ z.object({
442
+ type: z.literal("record_update_job_error"),
443
+ data: DependabotRecordUpdateJobErrorSchema
444
+ }),
445
+ z.object({
446
+ type: z.literal("record_update_job_unknown_error"),
447
+ data: DependabotRecordUpdateJobUnknownErrorSchema
448
+ }),
449
+ z.object({
450
+ type: z.literal("mark_as_processed"),
451
+ data: DependabotMarkAsProcessedSchema
452
+ }),
453
+ z.object({
454
+ type: z.literal("update_dependency_list"),
455
+ data: DependabotUpdateDependencyListSchema
456
+ }),
457
+ z.object({
458
+ type: z.literal("record_ecosystem_versions"),
459
+ data: DependabotRecordEcosystemVersionsSchema
460
+ }),
461
+ z.object({
462
+ type: z.literal("record_ecosystem_meta"),
463
+ data: DependabotRecordEcosystemMetaSchema.array()
464
+ }),
465
+ z.object({
466
+ type: z.literal("increment_metric"),
467
+ data: DependabotIncrementMetricSchema
468
+ }),
469
+ z.object({
470
+ type: z.literal("record_metrics"),
471
+ data: DependabotMetricSchema.array()
472
+ })
473
+ ]);
474
+ /**
475
+ * Creates an API server application for handling dependabot update jobs.
476
+ * The endpoints in the server application have paths in the format: `/api/update_jobs/:id/{operation}`,
477
+ * where `:id` is the job ID and `{operation}` is one of the defined operations e.g. `create_pull_request`.
478
+ *
479
+ * You should set the job endpoint URL in the job container to
480
+ * `http://<host>:<port>/api/update_jobs/:id` where `<host>` and `<port>` are the host and port
481
+ *
482
+ * These endpoints are protected using the provided API key.
483
+ * @param params - The parameters for creating the API server application.
484
+ * @returns The created API server application.
485
+ */
486
+ function createApiServerApp({ basePath = `/api/update_jobs`, authenticate, getJob, getCredentials, handle }) {
487
+ const app = new Hono().basePath(basePath);
488
+ function operation(type, schema, method) {
489
+ app.on(method || "post", `/:id/${type}`, zValidator("param", z.object({ id: z.coerce.number() })), async (context, next) => {
490
+ if (new URL(context.req.url).protocol === "https:") {
491
+ const { id } = context.req.valid("param");
492
+ const value = context.req.header("Authorization");
493
+ if (!value) return context.body(null, 401);
494
+ if (!await authenticate("job", id, value)) return context.body(null, 403);
495
+ } else logger.trace(`Skipping authentication because it is not secure ${context.req.url}`);
496
+ await next();
497
+ }, zValidator("json", z.object({ data: schema })), async (context) => {
498
+ const { id } = context.req.valid("param");
499
+ const { data } = context.req.valid("json");
500
+ const success = await handle(id, {
501
+ type,
502
+ data
503
+ });
504
+ return context.body(null, success ? 204 : 400);
505
+ });
506
+ }
507
+ operation("create_pull_request", DependabotCreatePullRequestSchema);
508
+ operation("update_pull_request", DependabotUpdatePullRequestSchema);
509
+ operation("close_pull_request", DependabotClosePullRequestSchema);
510
+ operation("record_update_job_error", DependabotRecordUpdateJobErrorSchema);
511
+ operation("record_update_job_unknown_error", DependabotRecordUpdateJobUnknownErrorSchema);
512
+ operation("mark_as_processed", DependabotMarkAsProcessedSchema, "patch");
513
+ operation("update_dependency_list", DependabotUpdateDependencyListSchema);
514
+ operation("record_ecosystem_versions", DependabotRecordEcosystemVersionsSchema);
515
+ operation("record_ecosystem_meta", DependabotRecordEcosystemMetaSchema.array());
516
+ operation("increment_metric", DependabotIncrementMetricSchema);
517
+ operation("record_metrics", DependabotMetricSchema.array());
518
+ app.on("get", "/:id/details", zValidator("param", z.object({ id: z.coerce.number() })), async (context, next) => {
519
+ const { id } = context.req.valid("param");
520
+ const value = context.req.header("Authorization");
521
+ if (!value) return context.body(null, 401);
522
+ if (!await authenticate("job", id, value)) return context.body(null, 403);
523
+ await next();
524
+ }, async (context) => {
525
+ const { id } = context.req.valid("param");
526
+ const job = await getJob(id);
527
+ if (!job) return context.body(null, 204);
528
+ return context.json(job);
529
+ });
530
+ app.on("get", "/:id/credentials", zValidator("param", z.object({ id: z.coerce.number() })), async (context, next) => {
531
+ const { id } = context.req.valid("param");
532
+ const value = context.req.header("Authorization");
533
+ if (!value) return context.body(null, 401);
534
+ if (!await authenticate("credentials", id, value)) return context.body(null, 403);
535
+ await next();
536
+ }, async (context) => {
537
+ const { id } = context.req.valid("param");
538
+ const credentials = await getCredentials(id);
539
+ if (!credentials) return context.body(null, 204);
540
+ return context.json(credentials);
541
+ });
542
+ return app;
543
+ }
544
+
545
+ //#endregion
546
+ export { DEFAULT_EXPERIMENTS as A, mapExperiments as C, mapSecurityAdvisories as D, mapPackageEcosystemToPackageManager as E, DEPENDABOT_DEFAULT_AUTHOR_NAME as F, getBranchNameForUpdate as M, sanitizeRef as N, mapSourceFromDependabotConfigToJobConfig as O, DEPENDABOT_DEFAULT_AUTHOR_EMAIL as P, mapCredentials as S, mapIgnoreConditionsFromDependabotConfigToJobConfig as T, DependabotUpdatePullRequestSchema as _, DependabotCreatePullRequestSchema as a, makeRandomJobToken as b, DependabotEcosystemVersionManagerSchema as c, DependabotMetricSchema as d, DependabotRecordEcosystemMetaSchema as f, DependabotUpdateDependencyListSchema as g, DependabotRecordUpdateJobUnknownErrorSchema as h, DependabotClosePullRequestSchema as i, parseExperiments as j, mapVersionStrategyToRequirementsUpdateStrategy as k, DependabotIncrementMetricSchema as l, DependabotRecordUpdateJobErrorSchema as m, DependabotRequestTypeSchema as n, DependabotDependencyFileSchema as o, DependabotRecordEcosystemVersionsSchema as p, createApiServerApp as r, DependabotEcosystemMetaSchema as s, DependabotRequestSchema as t, DependabotMarkAsProcessedSchema as u, DependabotJobBuilder as v, mapGroupsFromDependabotConfigToJobConfig as w, mapAllowedUpdatesFromDependabotConfigToJobConfig as x, makeRandomJobId as y };
547
+ //# sourceMappingURL=dependabot-BteoKZVy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependabot-BteoKZVy.js","names":["branchName: string","crypto","DEFAULT_EXPERIMENTS: DependabotExperiments","updatingPullRequest: boolean","updateDependencyGroupName: string | null","updateDependencyNames: string[] | null","vulnerabilities: SecurityVulnerability[] | undefined","success: boolean"],"sources":["../../src/dependabot/author.ts","../../src/dependabot/branch-name.ts","../../src/dependabot/experiments.ts","../../src/dependabot/job-builder.ts","../../src/dependabot/update.ts","../../src/dependabot/server.ts"],"sourcesContent":["export type GitAuthor = {\n name: string;\n email: string;\n};\n\nexport const DEPENDABOT_DEFAULT_AUTHOR_EMAIL = 'noreply@github.com';\nexport const DEPENDABOT_DEFAULT_AUTHOR_NAME = 'dependabot[bot]';\n","import * as crypto from 'node:crypto';\nimport type { PackageEcosystem } from './config';\nimport type { DependabotExistingPR } from './job';\n\n// TODO: figure out how to handle IDENTIFIER field (in a group) in branch naming\n// Docs: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#groups--\n// -> An identifier for a group is used in branch names and pull request titles.\n\nexport function getBranchNameForUpdate(\n packageEcosystem: PackageEcosystem,\n targetBranchName: string | undefined,\n directory: string | undefined,\n dependencyGroupName: string | undefined,\n dependencies: DependabotExistingPR[],\n separator: string = '/',\n): string {\n // Based on dependabot-core implementation:\n // https://github.com/dependabot/dependabot-core/blob/main/common/lib/dependabot/pull_request_creator/branch_namer/solo_strategy.rb\n // https://github.com/dependabot/dependabot-core/blob/main/common/lib/dependabot/pull_request_creator/branch_namer/dependency_group_strategy.rb\n let branchName: string;\n const branchNameMightBeTooLong = dependencyGroupName || dependencies.length > 1;\n if (branchNameMightBeTooLong) {\n // Group/multi dependency update\n // e.g. dependabot/nuget/main/microsoft-3b49c54d9e\n const dependencyDigest = crypto\n .createHash('md5')\n .update(dependencies.map((d) => `${d['dependency-name']}-${d['dependency-version']}`).join(','))\n .digest('hex')\n .substring(0, 10);\n branchName = `${dependencyGroupName || 'multi'}-${dependencyDigest}`;\n } else {\n // Single dependency update\n // e.g. dependabot/nuget/main/Microsoft.Extensions.Logging-1.0.0\n const dependencyNames = dependencies\n .map((d) => d['dependency-name'])\n .join('-and-')\n .replace(/[:[]]/g, '-') // Replace `:` and `[]` with `-`\n .replace(/@/g, ''); // Remove `@`\n const versionSuffix = dependencies[0]?.removed ? 'removed' : dependencies[0]?.['dependency-version'];\n branchName = `${dependencyNames}-${versionSuffix}`;\n }\n\n return sanitizeRef(\n [\n 'dependabot',\n packageEcosystem,\n targetBranchName,\n // normalize directory to remove leading/trailing slashes and replace remaining ones with the separator\n directory\n ?.replace(/^\\/+|\\/+$/g, '')\n .replace(/\\//g, separator),\n branchName,\n ],\n separator,\n );\n}\n\nexport function sanitizeRef(refParts: (string | undefined)[], separator: string): string {\n // Based on dependabot-core implementation:\n // https://github.com/dependabot/dependabot-core/blob/fc31ae64f492dc977cfe6773ab13fb6373aabec4/common/lib/dependabot/pull_request_creator/branch_namer/base.rb#L99\n\n // This isn't a complete implementation of git's ref validation, but it\n // covers most cases that crop up. Its list of allowed characters is a\n // bit stricter than git's, but that's for cosmetic reasons.\n return (\n refParts\n // Join the parts with the separator, ignore empty parts\n .filter((p) => p && p.trim().length > 0)\n .join(separator)\n // Remove forbidden characters (those not already replaced elsewhere)\n .replace(/[^A-Za-z0-9/\\-_.(){}]/g, '')\n // Slashes can't be followed by periods\n .replace(/\\/\\./g, '/dot-')\n // Squeeze out consecutive periods and slashes\n .replace(/\\.+/g, '.')\n .replace(/\\/+/g, '/')\n // Trailing periods are forbidden\n .replace(/\\.$/, '')\n );\n}\n","import type { DependabotExperiments } from './job';\n\n// The default experiments known to be used by the GitHub Dependabot service.\n// This changes often, update as needed by extracting them from a Dependabot GitHub Action run.\n// e.g. https://github.com/mburumaxwell/dependabot-azure-devops/actions/workflows/dependabot/dependabot-updates\nexport const DEFAULT_EXPERIMENTS: DependabotExperiments = {\n 'record-ecosystem-versions': true,\n 'record-update-job-unknown-error': true,\n 'proxy-cached': true,\n 'move-job-token': true,\n 'dependency-change-validation': true,\n 'enable-file-parser-python-local': true,\n 'npm-fallback-version-above-v6': true,\n 'lead-security-dependency': true,\n 'enable-record-ecosystem-meta': true,\n 'enable-corepack-for-npm-and-yarn': true,\n 'enable-shared-helpers-command-timeout': true,\n 'enable-dependabot-setting-up-cronjob': true,\n 'enable-engine-version-detection': true,\n 'avoid-duplicate-updates-package-json': true,\n 'allow-refresh-for-existing-pr-dependencies': true,\n 'allow-refresh-group-with-all-dependencies': true,\n 'exclude-local-composer-packages': true,\n 'enable-enhanced-error-details-for-updater': true,\n 'gradle-lockfile-updater': true,\n 'enable-exclude-paths-subdirectory-manifest-files': true,\n 'group-membership-enforcement': true,\n};\n\n/**\n * Parses a comma-separated list of key=value pairs representing experiments.\n * @param raw A comma-separated list of key=value pairs representing experiments.\n * @returns A map of experiment names to their values.\n */\nexport function parseExperiments(raw?: string): DependabotExperiments | undefined {\n return raw\n ?.split(',')\n .filter((entry) => entry.trim() !== '') // <-- filter out empty entries\n .reduce((acc, cur) => {\n const [key, value] = cur.split('=', 2);\n acc[key!] = value || true;\n return acc;\n }, {} as DependabotExperiments);\n}\n","import type { SecurityVulnerability } from '@/github';\nimport type {\n DependabotAllowCondition,\n DependabotConfig,\n DependabotGroup,\n DependabotIgnoreCondition,\n DependabotRegistry,\n DependabotUpdate,\n PackageEcosystem,\n VersioningStrategy,\n} from './config';\nimport type {\n DependabotAllowed,\n DependabotCondition,\n DependabotCredential,\n DependabotExistingGroupPR,\n DependabotExistingPR,\n DependabotExperiments,\n DependabotGroupJob,\n DependabotJobConfig,\n DependabotPackageManager,\n DependabotSecurityAdvisory,\n DependabotSource,\n DependabotSourceProvider,\n} from './job';\n\nexport type DependabotSourceInfo = {\n provider: DependabotSourceProvider;\n hostname: string;\n 'api-endpoint': string;\n 'repository-slug': string;\n};\n\nexport type DependabotJobBuilderOutput = {\n jobId: number;\n job: DependabotJobConfig;\n credentials: DependabotCredential[];\n};\n\n/**\n * Class for building dependabot job objects\n */\nexport class DependabotJobBuilder {\n private readonly config: DependabotConfig;\n private readonly update: DependabotUpdate;\n private readonly experiments: DependabotExperiments;\n private readonly debug: boolean;\n\n private readonly packageManager: DependabotPackageManager;\n private readonly source: DependabotSource;\n private readonly credentials: DependabotCredential[];\n\n constructor({\n source,\n config,\n update,\n systemAccessUser,\n systemAccessToken,\n githubToken,\n experiments,\n debug,\n }: {\n source: DependabotSourceInfo;\n config: DependabotConfig;\n update: DependabotUpdate;\n experiments: DependabotExperiments;\n systemAccessUser?: string;\n systemAccessToken?: string;\n githubToken?: string;\n /** Determines if verbose log messages are logged */\n debug: boolean;\n }) {\n this.config = config;\n this.update = update;\n this.experiments = experiments;\n this.debug = debug;\n\n this.packageManager = mapPackageEcosystemToPackageManager(update['package-ecosystem']);\n this.source = mapSourceFromDependabotConfigToJobConfig(source, update);\n this.credentials = mapCredentials({\n sourceHostname: source.hostname,\n systemAccessUser,\n systemAccessToken,\n githubToken,\n registries: config.registries,\n });\n }\n\n /**\n * Create a dependabot update job that updates nothing, but will discover the dependency list for a package ecosystem\n */\n public forDependenciesList({\n id,\n command,\n }: {\n id?: number;\n command: DependabotJobConfig['command'];\n }): DependabotJobBuilderOutput {\n id ??= makeRandomJobId();\n return {\n jobId: id,\n job: {\n id: id,\n command: command,\n 'package-manager': this.packageManager,\n 'updating-a-pull-request': false,\n dependencies: null,\n 'allowed-updates': [{ 'dependency-type': 'direct', 'update-type': 'all' }],\n 'ignore-conditions': [{ 'dependency-name': '*' }],\n 'security-updates-only': false,\n 'security-advisories': [],\n source: this.source,\n 'update-subdependencies': false,\n 'existing-pull-requests': [],\n 'existing-group-pull-requests': [],\n experiments: this.experiments,\n 'requirements-update-strategy': null,\n 'lockfile-only': false,\n 'commit-message-options': {\n prefix: null,\n 'prefix-development': null,\n 'include-scope': null,\n },\n 'vendor-dependencies': false,\n 'repo-private': true,\n debug: this.debug,\n },\n credentials: this.credentials,\n };\n }\n\n /**\n * Create a dependabot update job that updates all dependencies for a package ecosystem\n */\n public forUpdate({\n id,\n command,\n dependencyNamesToUpdate,\n existingPullRequests,\n pullRequestToUpdate,\n securityVulnerabilities,\n }: {\n id?: number;\n command: DependabotJobConfig['command'];\n dependencyNamesToUpdate?: string[];\n existingPullRequests: (DependabotExistingPR[] | DependabotExistingGroupPR)[];\n pullRequestToUpdate?: DependabotExistingPR[] | DependabotExistingGroupPR;\n securityVulnerabilities?: SecurityVulnerability[];\n }): DependabotJobBuilderOutput {\n id ??= makeRandomJobId();\n const securityOnlyUpdate = this.update['open-pull-requests-limit'] === 0;\n\n let updatingPullRequest: boolean;\n let updateDependencyGroupName: string | null = null;\n let updateDependencyNames: string[] | null;\n let vulnerabilities: SecurityVulnerability[] | undefined;\n\n if (pullRequestToUpdate) {\n updatingPullRequest = true;\n updateDependencyGroupName = Array.isArray(pullRequestToUpdate)\n ? null\n : pullRequestToUpdate['dependency-group-name'];\n updateDependencyNames = (\n Array.isArray(pullRequestToUpdate) ? pullRequestToUpdate : pullRequestToUpdate.dependencies\n )?.map((d) => d['dependency-name']);\n vulnerabilities = securityVulnerabilities?.filter((v) => updateDependencyNames?.includes(v.package.name));\n } else {\n updatingPullRequest = false;\n const names = dependencyNamesToUpdate?.length ? dependencyNamesToUpdate : null;\n updateDependencyNames =\n securityOnlyUpdate && names\n ? names?.filter((d) => securityVulnerabilities?.find((v) => v.package.name === d))\n : names;\n vulnerabilities = securityVulnerabilities;\n }\n\n return {\n jobId: id,\n job: {\n id: id,\n command: command,\n 'package-manager': this.packageManager,\n 'updating-a-pull-request': updatingPullRequest || false,\n 'dependency-group-to-refresh': updateDependencyGroupName,\n 'dependency-groups': mapGroupsFromDependabotConfigToJobConfig(this.update.groups),\n dependencies: updateDependencyNames,\n 'allowed-updates': mapAllowedUpdatesFromDependabotConfigToJobConfig(this.update.allow, securityOnlyUpdate),\n 'ignore-conditions': mapIgnoreConditionsFromDependabotConfigToJobConfig(this.update.ignore),\n 'security-updates-only': securityOnlyUpdate,\n 'security-advisories': mapSecurityAdvisories(vulnerabilities),\n source: this.source,\n 'update-subdependencies': false,\n 'existing-pull-requests': existingPullRequests.filter((pr) => Array.isArray(pr)),\n 'existing-group-pull-requests': existingPullRequests.filter(\n (pr): pr is DependabotExistingGroupPR => !Array.isArray(pr),\n ),\n 'commit-message-options': {\n prefix: this.update['commit-message']?.prefix ?? null,\n 'prefix-development': this.update['commit-message']?.['prefix-development'] ?? null,\n 'include-scope':\n this.update['commit-message']?.include?.toLocaleLowerCase()?.trim() === 'scope' ? true : null,\n },\n cooldown: this.update.cooldown,\n experiments: mapExperiments(this.experiments),\n 'reject-external-code':\n this.update['insecure-external-code-execution']?.toLocaleLowerCase()?.trim() === 'allow',\n 'requirements-update-strategy': mapVersionStrategyToRequirementsUpdateStrategy(\n this.update['versioning-strategy'],\n ),\n 'lockfile-only': this.update['versioning-strategy'] === 'lockfile-only',\n 'vendor-dependencies': this.update.vendor ?? false,\n 'repo-private': true,\n debug: this.debug,\n 'proxy-log-response-body-on-auth-failure': true,\n 'max-updater-run-time': 2700,\n 'enable-beta-ecosystems': this.config['enable-beta-ecosystems'] || false,\n // Updates across ecosystems is still in development\n // See https://github.com/dependabot/dependabot-core/issues/8126\n // https://github.com/dependabot/dependabot-core/pull/12339\n // It needs to merged in the core repo first before we support it\n // However, to match current job configs and to prevent surprises, we disable it\n 'multi-ecosystem-update': false,\n },\n credentials: this.credentials,\n };\n }\n}\n\nexport function mapPackageEcosystemToPackageManager(ecosystem: PackageEcosystem): DependabotPackageManager {\n // Map the dependabot config \"package ecosystem\" to the equivalent dependabot-core/cli \"package manager\".\n // Config values: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#package-ecosystem-\n // Core/CLI values: https://github.com/dependabot/dependabot-core/blob/main/common/lib/dependabot/config/file.rb#L60-L81\n switch (ecosystem) {\n case 'docker-compose':\n return 'docker_compose';\n case 'dotnet-sdk':\n return 'dotnet_sdk';\n case 'github-actions':\n return 'github_actions';\n case 'gitsubmodule':\n return 'submodules';\n case 'gomod':\n return 'go_modules';\n case 'mix':\n return 'hex';\n case 'npm':\n return 'npm_and_yarn';\n // Additional aliases, sometimes used for convenience\n case 'pipenv':\n return 'pip';\n case 'pip-compile':\n return 'pip';\n case 'poetry':\n return 'pip';\n case 'pnpm':\n return 'npm_and_yarn';\n case 'yarn':\n return 'npm_and_yarn';\n default:\n return ecosystem;\n }\n}\n\nexport function mapSourceFromDependabotConfigToJobConfig(\n source: DependabotSourceInfo,\n update: DependabotUpdate,\n): DependabotSource {\n return {\n provider: source.provider,\n 'api-endpoint': source['api-endpoint'],\n hostname: source.hostname,\n repo: source['repository-slug'],\n branch: update['target-branch'],\n commit: null, // use latest commit of target branch\n directory: update.directory,\n directories: update.directories,\n };\n}\n\nexport function mapVersionStrategyToRequirementsUpdateStrategy(strategy?: VersioningStrategy): string | null {\n if (!strategy) return null;\n switch (strategy) {\n case 'auto':\n return null;\n case 'increase':\n return 'bump_versions';\n case 'increase-if-necessary':\n return 'bump_versions_if_necessary';\n case 'lockfile-only':\n return 'lockfile_only';\n case 'widen':\n return 'widen_ranges';\n default:\n throw new Error(`Invalid dependabot.yaml versioning strategy option '${strategy}'`);\n }\n}\n\nexport function mapGroupsFromDependabotConfigToJobConfig(\n dependencyGroups?: Record<string, DependabotGroup | null>,\n): DependabotGroupJob[] {\n if (!dependencyGroups || !Object.keys(dependencyGroups).length) return [];\n return Object.keys(dependencyGroups)\n .filter((name) => dependencyGroups[name])\n .map((name) => {\n const group = dependencyGroups[name]!;\n return {\n name: name,\n 'applies-to': group['applies-to'],\n rules: {\n patterns: group.patterns?.length ? group.patterns : ['*'],\n 'exclude-patterns': group['exclude-patterns'],\n 'dependency-type': group['dependency-type'],\n 'update-types': group['update-types'],\n },\n } satisfies DependabotGroupJob;\n });\n}\n\nexport function mapAllowedUpdatesFromDependabotConfigToJobConfig(\n allowedUpdates?: DependabotAllowCondition[],\n securityOnlyUpdate?: boolean,\n): DependabotAllowed[] {\n // If no allow conditions are specified, update direct dependencies by default; This is what GitHub does.\n // NOTE: 'update-type' appears to be a deprecated config, but still appears in the dependabot-core model and GitHub Dependabot job logs.\n // See: https://github.com/dependabot/dependabot-core/blob/b3a0c1f86c20729494097ebc695067099f5b4ada/updater/lib/dependabot/job.rb#L253C1-L257C78\n if (!allowedUpdates) {\n return [\n {\n 'dependency-type': 'direct',\n 'update-type': securityOnlyUpdate ? 'security' : 'all',\n },\n ];\n }\n return allowedUpdates.map((allow) => {\n return {\n 'dependency-name': allow['dependency-name'],\n 'dependency-type': allow['dependency-type'],\n 'update-type': allow['update-type'],\n };\n });\n}\n\nexport function mapIgnoreConditionsFromDependabotConfigToJobConfig(\n ignoreConditions?: DependabotIgnoreCondition[],\n): DependabotCondition[] {\n if (!ignoreConditions) return [];\n return ignoreConditions.map((ignore) => {\n return {\n source: ignore.source,\n 'updated-at': ignore['updated-at'],\n 'dependency-name': ignore['dependency-name'] ?? '*',\n 'update-types': ignore['update-types'],\n\n // The dependabot.yml config docs are not very clear about acceptable values; after scanning dependabot-core and dependabot-cli,\n // this could either be a single version string (e.g. '>1.0.0'), or multiple version strings separated by commas (e.g. '>1.0.0, <2.0.0')\n 'version-requirement': Array.isArray(ignore.versions) ? (<string[]>ignore.versions)?.join(', ') : ignore.versions,\n } satisfies DependabotCondition;\n });\n}\n\nexport function mapExperiments(experiments?: DependabotExperiments): DependabotExperiments {\n experiments ??= {};\n return Object.keys(experiments).reduce((acc, key) => {\n // Experiment values are known to be either 'true', 'false', or a string value.\n // If the value is 'true' or 'false', convert it to a boolean type so that dependabot-core handles it correctly.\n const value = experiments[key];\n if (typeof value === 'string' && value?.toLocaleLowerCase() === 'true') {\n acc[key] = true;\n } else if (typeof value === 'string' && value?.toLocaleLowerCase() === 'false') {\n acc[key] = false;\n } else {\n if (typeof value === 'string' || typeof value === 'boolean') acc[key] = value;\n }\n return acc;\n }, {} as DependabotExperiments);\n}\n\nexport function mapSecurityAdvisories(securityVulnerabilities?: SecurityVulnerability[]): DependabotSecurityAdvisory[] {\n if (!securityVulnerabilities) return [];\n\n // A single security advisory can cause a vulnerability in multiple versions of a package.\n // We need to map each unique security advisory to a list of affected-versions and patched-versions.\n const vulnerabilitiesGroupedByPackageNameAndAdvisoryId = new Map<string, SecurityVulnerability[]>();\n for (const vuln of securityVulnerabilities) {\n const key = `${vuln.package.name}/${vuln.advisory.identifiers.map((i) => `${i.type}:${i.value}`).join('/')}`;\n if (!vulnerabilitiesGroupedByPackageNameAndAdvisoryId.has(key)) {\n vulnerabilitiesGroupedByPackageNameAndAdvisoryId.set(key, []);\n }\n vulnerabilitiesGroupedByPackageNameAndAdvisoryId.get(key)!.push(vuln);\n }\n return Array.from(vulnerabilitiesGroupedByPackageNameAndAdvisoryId.values()).map((vulns) => {\n return {\n 'dependency-name': vulns[0]!.package.name,\n 'affected-versions': vulns.map((v) => v.vulnerableVersionRange).filter((v) => v && v.length > 0),\n 'patched-versions': vulns\n .map((v) => v.firstPatchedVersion?.identifier)\n .filter((v) => v && v.length > 0)\n .map((v) => v!),\n 'unaffected-versions': [],\n } satisfies DependabotSecurityAdvisory;\n });\n}\n\nexport function mapCredentials({\n sourceHostname,\n systemAccessUser,\n systemAccessToken,\n githubToken,\n registries,\n}: {\n sourceHostname: string;\n systemAccessUser?: string;\n systemAccessToken?: string;\n githubToken?: string;\n registries?: Record<string, DependabotRegistry>;\n}): DependabotCredential[] {\n const credentials = [];\n\n // Required to authenticate with the git repository when cloning the source code\n if (systemAccessToken) {\n credentials.push({\n type: 'git_source',\n host: sourceHostname,\n username: (systemAccessUser ?? '').trim()?.length > 0 ? systemAccessUser : 'x-access-token',\n password: systemAccessToken,\n });\n }\n\n // Required to avoid rate-limiting errors when generating pull request descriptions (e.g. fetching release notes, commit messages, etc)\n if (githubToken) {\n credentials.push({\n type: 'git_source',\n host: 'github.com',\n username: 'x-access-token',\n password: githubToken,\n });\n }\n if (registries) {\n // TODO: only registries for the current update should be set\n // Required to authenticate with private package feeds when finding the latest version of dependencies.\n // The registries have already been worked on (see parseRegistries) so there is no need to do anything else.\n credentials.push(...Object.values(registries));\n }\n\n return credentials;\n}\n\nexport function makeRandomJobId(): number {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n return array[0]! % 10000000000; // Limit to 10 digits to match GitHub's job IDs\n}\n\nexport function makeRandomJobToken() {\n const array = new Uint8Array(30);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => (byte % 36).toString(36)).join('');\n}\n","import { z } from 'zod/v4';\nimport { DependabotDependencySchema } from './job';\n\n// we use nullish() because it does optional() and allows the value to be set to null\n\nexport const DependabotDependencyFileSchema = z.object({\n content: z.string(),\n content_encoding: z.string().nullish(),\n deleted: z.boolean().nullish(),\n directory: z.string(),\n name: z.string(),\n operation: z.string(), // TODO: convert to enum?\n support_file: z.boolean().nullish(),\n symlink_target: z.string().nullish(),\n type: z.string().nullish(), // TODO: convert to enum?\n mode: z.string().nullish(),\n});\nexport type DependabotDependencyFile = z.infer<typeof DependabotDependencyFileSchema>;\n\nexport const DependabotUpdateDependencyListSchema = z.object({\n dependencies: DependabotDependencySchema.array(),\n dependency_files: z.string().array().nullish(),\n});\nexport type DependabotUpdateDependencyList = z.infer<typeof DependabotUpdateDependencyListSchema>;\n\nexport const DependabotCreatePullRequestSchema = z.object({\n 'base-commit-sha': z.string(),\n dependencies: DependabotDependencySchema.array(),\n 'updated-dependency-files': DependabotDependencyFileSchema.array(),\n 'pr-title': z.string(),\n 'pr-body': z.string().nullish(),\n 'commit-message': z.string(),\n 'dependency-group': z.record(z.string(), z.any()).nullish(),\n});\nexport type DependabotCreatePullRequest = z.infer<typeof DependabotCreatePullRequestSchema>;\n\nexport const DependabotUpdatePullRequestSchema = z.object({\n 'base-commit-sha': z.string(),\n 'dependency-names': z.string().array(),\n 'updated-dependency-files': DependabotDependencyFileSchema.array(),\n 'pr-title': z.string().nullish(), // this is usually excluded when working with dependabot-cli and an empty string if the API\n 'pr-body': z.string().nullish(), // this is usually excluded when working with dependabot-cli and an empty string if the API\n 'commit-message': z.string().nullish(), // this is usually excluded when working with dependabot-cli and an empty string if the API\n 'dependency-group': z.record(z.string(), z.any()).nullish(),\n});\nexport type DependabotUpdatePullRequest = z.infer<typeof DependabotUpdatePullRequestSchema>;\n\nexport const DependabotClosePullRequestSchema = z.object({\n 'dependency-names': z.string().array(),\n reason: z.string().nullish(), // TODO: convert to enum?\n});\nexport type DependabotClosePullRequest = z.infer<typeof DependabotClosePullRequestSchema>;\n\nexport const DependabotMarkAsProcessedSchema = z.object({\n 'base-commit-sha': z.string().nullish(),\n});\nexport type DependabotMarkAsProcessed = z.infer<typeof DependabotMarkAsProcessedSchema>;\n\nexport const DependabotRecordUpdateJobErrorSchema = z.object({\n 'error-type': z.string(),\n 'error-details': z.record(z.string(), z.any()).nullish(),\n});\nexport type DependabotRecordUpdateJobError = z.infer<typeof DependabotRecordUpdateJobErrorSchema>;\n\nexport const DependabotRecordUpdateJobUnknownErrorSchema = z.object({\n 'error-type': z.string(),\n 'error-details': z.record(z.string(), z.any()).nullish(),\n});\nexport type DependabotRecordUpdateJobUnknownError = z.infer<typeof DependabotRecordUpdateJobUnknownErrorSchema>;\n\nexport const DependabotRecordEcosystemVersionsSchema = z.object({\n ecosystem_versions: z.record(z.string(), z.any()).nullish(),\n});\nexport type DependabotRecordEcosystemVersions = z.infer<typeof DependabotRecordEcosystemVersionsSchema>;\n\nexport const DependabotEcosystemVersionManagerSchema = z.object({\n name: z.string(),\n version: z.string(),\n raw_version: z.string(),\n requirement: z.record(z.string(), z.any()).nullish(),\n});\nexport type DependabotEcosystemVersionManager = z.infer<typeof DependabotEcosystemVersionManagerSchema>;\n\nexport const DependabotEcosystemMetaSchema = z.object({\n name: z.string(),\n package_manager: DependabotEcosystemVersionManagerSchema.nullish(),\n version: DependabotEcosystemVersionManagerSchema.nullish(),\n});\nexport type DependabotEcosystemMeta = z.infer<typeof DependabotEcosystemMetaSchema>;\n\nexport const DependabotRecordEcosystemMetaSchema = z.object({\n ecosystem: DependabotEcosystemMetaSchema,\n});\nexport type DependabotRecordEcosystemMeta = z.infer<typeof DependabotRecordEcosystemMetaSchema>;\n\nexport const DependabotIncrementMetricSchema = z.object({\n metric: z.string(),\n tags: z.record(z.string(), z.any()).nullish(),\n});\nexport type DependabotIncrementMetric = z.infer<typeof DependabotIncrementMetricSchema>;\n\nexport const DependabotMetricSchema = z.object({\n metric: z.string(),\n type: z.enum(['increment', 'gauge', 'distribution', 'histogram']),\n value: z.number().nullish(),\n values: z.number().array().nullish(),\n tags: z.record(z.string(), z.string()).nullish(),\n});\nexport type DependabotMetric = z.infer<typeof DependabotMetricSchema>;\n","import { zValidator } from '@hono/zod-validator';\nimport { Hono } from 'hono';\nimport { type ZodType, z } from 'zod/v4';\nimport { logger } from '@/logger';\nimport type { DependabotCredential, DependabotJobConfig } from './job';\nimport {\n DependabotClosePullRequestSchema,\n DependabotCreatePullRequestSchema,\n DependabotIncrementMetricSchema,\n DependabotMarkAsProcessedSchema,\n DependabotMetricSchema,\n DependabotRecordEcosystemMetaSchema,\n DependabotRecordEcosystemVersionsSchema,\n DependabotRecordUpdateJobErrorSchema,\n DependabotRecordUpdateJobUnknownErrorSchema,\n DependabotUpdateDependencyListSchema,\n DependabotUpdatePullRequestSchema,\n} from './update';\n\nexport const DependabotRequestTypeSchema = z.enum([\n 'create_pull_request',\n 'update_pull_request',\n 'close_pull_request',\n 'record_update_job_error',\n 'record_update_job_unknown_error',\n 'mark_as_processed',\n 'update_dependency_list',\n 'record_ecosystem_versions',\n 'record_ecosystem_meta',\n 'increment_metric',\n 'record_metrics',\n]);\nexport type DependabotRequestType = z.infer<typeof DependabotRequestTypeSchema>;\n\nexport const DependabotRequestSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('create_pull_request'), data: DependabotCreatePullRequestSchema }),\n z.object({ type: z.literal('update_pull_request'), data: DependabotUpdatePullRequestSchema }),\n z.object({ type: z.literal('close_pull_request'), data: DependabotClosePullRequestSchema }),\n z.object({ type: z.literal('record_update_job_error'), data: DependabotRecordUpdateJobErrorSchema }),\n z.object({ type: z.literal('record_update_job_unknown_error'), data: DependabotRecordUpdateJobUnknownErrorSchema }),\n z.object({ type: z.literal('mark_as_processed'), data: DependabotMarkAsProcessedSchema }),\n z.object({ type: z.literal('update_dependency_list'), data: DependabotUpdateDependencyListSchema }),\n z.object({ type: z.literal('record_ecosystem_versions'), data: DependabotRecordEcosystemVersionsSchema }),\n z.object({ type: z.literal('record_ecosystem_meta'), data: DependabotRecordEcosystemMetaSchema.array() }),\n z.object({ type: z.literal('increment_metric'), data: DependabotIncrementMetricSchema }),\n z.object({ type: z.literal('record_metrics'), data: DependabotMetricSchema.array() }),\n]);\nexport type DependabotRequest = z.infer<typeof DependabotRequestSchema>;\n\nexport type DependabotTokenType = 'job' | 'credentials';\n\n/**\n * Function type for authenticating requests.\n * @param type - The type of authentication ('job' or 'credentials').\n * @param id - The ID of the dependabot job.\n * @param value - The authentication value (e.g., API key).\n * @returns A promise that resolves to a boolean indicating whether the authentication was successful.\n */\ntype AuthenticatorFunc = (type: DependabotTokenType, id: number, value: string) => Promise<boolean>;\n\n/**\n * Handler function for processing dependabot requests.\n * @param id - The ID of the dependabot job.\n * @param request - The dependabot request to handle.\n * @returns A promise that resolves to the result of handling the request.\n */\ntype HandlerFunc = (id: number, request: DependabotRequest) => Promise<boolean>;\n\nexport type CreateApiServerAppOptions = {\n /**\n * Base path for the endpoints.\n * @default `/api/update_jobs`\n */\n basePath?: string;\n\n /** Handler function for authenticating requests. */\n authenticate: AuthenticatorFunc;\n\n /** Function for getting a dependabot job by ID. */\n getJob: (id: number) => Promise<DependabotJobConfig | undefined>;\n\n /** Function for getting dependabot credentials by job ID. */\n getCredentials: (id: number) => Promise<DependabotCredential[] | undefined>;\n\n /** Handler function for processing the operations. */\n handle: HandlerFunc;\n};\n\n/**\n * Creates an API server application for handling dependabot update jobs.\n * The endpoints in the server application have paths in the format: `/api/update_jobs/:id/{operation}`,\n * where `:id` is the job ID and `{operation}` is one of the defined operations e.g. `create_pull_request`.\n *\n * You should set the job endpoint URL in the job container to\n * `http://<host>:<port>/api/update_jobs/:id` where `<host>` and `<port>` are the host and port\n *\n * These endpoints are protected using the provided API key.\n * @param params - The parameters for creating the API server application.\n * @returns The created API server application.\n */\nexport function createApiServerApp({\n basePath = `/api/update_jobs`,\n authenticate,\n getJob,\n getCredentials,\n handle,\n}: CreateApiServerAppOptions): Hono {\n // Setup app with base path and middleware\n const app = new Hono().basePath(basePath);\n\n // Handle endpoints:\n // - POST request to /create_pull_request\n // - POST request to /update_pull_request\n // - POST request to /close_pull_request\n // - POST request to /record_update_job_error\n // - POST request to /record_update_job_unknown_error\n // - PATCH request to /mark_as_processed\n // - POST request to /update_dependency_list\n // - POST request to /record_ecosystem_versions\n // - POST request to /record_ecosystem_meta\n // - POST request to /increment_metric\n\n function operation<T extends ZodType>(type: DependabotRequestType, schema: T, method?: string) {\n app.on(\n method || 'post',\n `/:id/${type}`,\n zValidator('param', z.object({ id: z.coerce.number() })),\n async (context, next) => {\n /**\n * Do not authenticate in scenarios where the server is not using HTTPS because the\n * dependabot proxy will not send the job token over HTTP, yet trying to get HTTPS to work\n * with localhost (self-signed certs) against docker (host.docker.internal) is complicated.\n */\n const url = new URL(context.req.url);\n const isHTTPS = url.protocol === 'https:';\n if (isHTTPS) {\n const { id } = context.req.valid('param');\n const value = context.req.header('Authorization');\n if (!value) return context.body(null, 401);\n const valid = await authenticate('job', id, value);\n if (!valid) return context.body(null, 403);\n } else {\n logger.trace(`Skipping authentication because it is not secure ${context.req.url}`);\n }\n await next();\n },\n zValidator('json', z.object({ data: schema })),\n async (context) => {\n const { id } = context.req.valid('param');\n const { data } = context.req.valid('json') as { data: z.infer<typeof schema> };\n // biome-ignore lint/suspicious/noExplicitAny: generic\n const success: boolean = await handle(id, { type, data: data as any });\n return context.body(null, success ? 204 : 400);\n },\n );\n }\n\n operation('create_pull_request', DependabotCreatePullRequestSchema);\n operation('update_pull_request', DependabotUpdatePullRequestSchema);\n operation('close_pull_request', DependabotClosePullRequestSchema);\n operation('record_update_job_error', DependabotRecordUpdateJobErrorSchema);\n operation('record_update_job_unknown_error', DependabotRecordUpdateJobUnknownErrorSchema);\n operation('mark_as_processed', DependabotMarkAsProcessedSchema, 'patch');\n operation('update_dependency_list', DependabotUpdateDependencyListSchema);\n operation('record_ecosystem_versions', DependabotRecordEcosystemVersionsSchema);\n operation('record_ecosystem_meta', DependabotRecordEcosystemMetaSchema.array());\n operation('increment_metric', DependabotIncrementMetricSchema);\n operation('record_metrics', DependabotMetricSchema.array());\n\n // Handle endpoints:\n // - GET request to /details\n // - GET request to /credentials\n app.on(\n 'get',\n '/:id/details',\n zValidator('param', z.object({ id: z.coerce.number() })),\n async (context, next) => {\n const { id } = context.req.valid('param');\n const value = context.req.header('Authorization');\n if (!value) return context.body(null, 401);\n const valid = await authenticate('job', id, value);\n if (!valid) return context.body(null, 403);\n await next();\n },\n async (context) => {\n const { id } = context.req.valid('param');\n const job = await getJob(id);\n if (!job) return context.body(null, 204);\n return context.json(job);\n },\n );\n app.on(\n 'get',\n '/:id/credentials',\n zValidator('param', z.object({ id: z.coerce.number() })),\n async (context, next) => {\n const { id } = context.req.valid('param');\n const value = context.req.header('Authorization');\n if (!value) return context.body(null, 401);\n const valid = await authenticate('credentials', id, value);\n if (!valid) return context.body(null, 403);\n await next();\n },\n async (context) => {\n const { id } = context.req.valid('param');\n const credentials = await getCredentials(id);\n if (!credentials) return context.body(null, 204);\n return context.json(credentials);\n },\n );\n\n return app;\n}\n"],"mappings":"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"}