@capraconsulting/cals-cli 3.5.2 → 3.7.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.
@@ -1,74 +1,32 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';
2
+ import semver from 'semver';
3
+ import yargs from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
5
+ import fs from 'fs';
6
+ import yaml from 'js-yaml';
7
+ import { uniq, keyBy, sortBy, groupBy, sumBy, repeat } from 'lodash-es';
8
+ import pMap from 'p-map';
9
+ import AJV from 'ajv';
10
+ import { Octokit } from '@octokit/rest';
11
+ import fetch from 'node-fetch';
12
+ import pLimit from 'p-limit';
13
+ import keytar from 'keytar';
14
+ import * as process$2 from 'process';
15
+ import { performance } from 'perf_hooks';
16
+ import { deprecate } from 'util';
17
+ import path from 'path';
18
+ import rimraf from 'rimraf';
19
+ import cachedir from 'cachedir';
20
+ import https from 'https';
21
+ import os from 'os';
22
+ import chalk from 'chalk';
23
+ import readline from 'readline';
24
+ import { sprintf } from 'sprintf-js';
25
+ import read from 'read';
26
+ import findUp from 'find-up';
27
+ import execa from 'execa';
3
28
 
4
- var semver = require('semver');
5
- var yargs = require('yargs');
6
- var fs = require('fs');
7
- var yaml = require('js-yaml');
8
- var lodash = require('lodash');
9
- var pMap = require('p-map');
10
- var AJV = require('ajv');
11
- var rest = require('@octokit/rest');
12
- var fetch = require('node-fetch');
13
- var pLimit = require('p-limit');
14
- var keytar = require('keytar');
15
- var process$2 = require('process');
16
- var perf_hooks = require('perf_hooks');
17
- var util = require('util');
18
- var path = require('path');
19
- var rimraf = require('rimraf');
20
- var cachedir = require('cachedir');
21
- var https = require('https');
22
- var os = require('os');
23
- var chalk = require('chalk');
24
- var readline = require('readline');
25
- var sprintfJs = require('sprintf-js');
26
- var read = require('read');
27
- var findUp = require('find-up');
28
- var execa = require('execa');
29
-
30
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
31
-
32
- function _interopNamespace(e) {
33
- if (e && e.__esModule) return e;
34
- var n = Object.create(null);
35
- if (e) {
36
- Object.keys(e).forEach(function (k) {
37
- if (k !== 'default') {
38
- var d = Object.getOwnPropertyDescriptor(e, k);
39
- Object.defineProperty(n, k, d.get ? d : {
40
- enumerable: true,
41
- get: function () { return e[k]; }
42
- });
43
- }
44
- });
45
- }
46
- n["default"] = e;
47
- return Object.freeze(n);
48
- }
49
-
50
- var semver__default = /*#__PURE__*/_interopDefaultLegacy(semver);
51
- var yargs__default = /*#__PURE__*/_interopDefaultLegacy(yargs);
52
- var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
53
- var yaml__default = /*#__PURE__*/_interopDefaultLegacy(yaml);
54
- var pMap__default = /*#__PURE__*/_interopDefaultLegacy(pMap);
55
- var AJV__default = /*#__PURE__*/_interopDefaultLegacy(AJV);
56
- var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
57
- var pLimit__default = /*#__PURE__*/_interopDefaultLegacy(pLimit);
58
- var keytar__default = /*#__PURE__*/_interopDefaultLegacy(keytar);
59
- var process__namespace = /*#__PURE__*/_interopNamespace(process$2);
60
- var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
61
- var rimraf__default = /*#__PURE__*/_interopDefaultLegacy(rimraf);
62
- var cachedir__default = /*#__PURE__*/_interopDefaultLegacy(cachedir);
63
- var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
64
- var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
65
- var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
66
- var readline__default = /*#__PURE__*/_interopDefaultLegacy(readline);
67
- var read__default = /*#__PURE__*/_interopDefaultLegacy(read);
68
- var findUp__default = /*#__PURE__*/_interopDefaultLegacy(findUp);
69
- var execa__default = /*#__PURE__*/_interopDefaultLegacy(execa);
70
-
71
- var version = "3.5.2";
29
+ var version = "3.7.0";
72
30
  var engines = {
73
31
  node: ">=12.0.0"
74
32
  };
@@ -374,12 +332,11 @@ function getRepoId(orgName, repoName) {
374
332
  return `${orgName}/${repoName}`;
375
333
  }
376
334
  function checkAgainstSchema(value) {
377
- var _a;
378
- const ajv = new AJV__default["default"]({ allErrors: true });
335
+ const ajv = new AJV({ allErrors: true });
379
336
  const valid = ajv.validate(schema, value);
380
337
  return valid
381
338
  ? { definition: value }
382
- : { error: (_a = ajv.errorsText()) !== null && _a !== void 0 ? _a : "Unknown error" };
339
+ : { error: ajv.errorsText() ?? "Unknown error" };
383
340
  }
384
341
  function requireValidDefinition(definition) {
385
342
  // Verify no duplicates in users and extract known logins.
@@ -424,7 +381,8 @@ function requireValidDefinition(definition) {
424
381
  if (!teamIdList.includes(id)) {
425
382
  throw new Error(`Project team ${id} in project ${project.name} is not registered in team list`);
426
383
  }
427
- });
384
+ }) // Verify repo teams exists as teams.
385
+ ;
428
386
  (org.repos || []).forEach((repo) => {
429
387
  (repo.teams || []).forEach((team) => {
430
388
  const id = getTeamId(org.organization, team.name);
@@ -448,11 +406,12 @@ function requireValidDefinition(definition) {
448
406
  }, []);
449
407
  }
450
408
  class DefinitionFile {
409
+ path;
451
410
  constructor(path) {
452
411
  this.path = path;
453
412
  }
454
413
  async getContents() {
455
- return new Promise((resolve, reject) => fs__default["default"].readFile(this.path, "utf-8", (err, data) => {
414
+ return new Promise((resolve, reject) => fs.readFile(this.path, "utf-8", (err, data) => {
456
415
  if (err)
457
416
  reject(err);
458
417
  else
@@ -464,7 +423,7 @@ class DefinitionFile {
464
423
  }
465
424
  }
466
425
  function parseDefinition(value) {
467
- const result = checkAgainstSchema(yaml__default["default"].load(value));
426
+ const result = checkAgainstSchema(yaml.load(value));
468
427
  if ("error" in result) {
469
428
  throw new Error("Definition content invalid: " + result.error);
470
429
  }
@@ -482,19 +441,17 @@ function getRepos(definition) {
482
441
  .flat());
483
442
  }
484
443
  function getGitHubOrgs(definition) {
485
- return lodash.uniq(definition.projects.flatMap((project) => project.github.map((it) => it.organization)));
444
+ return uniq(definition.projects.flatMap((project) => project.github.map((it) => it.organization)));
486
445
  }
487
446
 
488
447
  class GitHubTokenCliProvider {
489
- constructor() {
490
- this.keyringService = "cals";
491
- this.keyringAccount = "github-token";
492
- }
448
+ keyringService = "cals";
449
+ keyringAccount = "github-token";
493
450
  async getToken() {
494
451
  if (process.env.CALS_GITHUB_TOKEN) {
495
452
  return process.env.CALS_GITHUB_TOKEN;
496
453
  }
497
- const result = await keytar__default["default"].getPassword(this.keyringService, this.keyringAccount);
454
+ const result = await keytar.getPassword(this.keyringService, this.keyringAccount);
498
455
  if (result == null) {
499
456
  process.stderr.write("No token found. Register using `cals github set-token`\n");
500
457
  return undefined;
@@ -502,10 +459,10 @@ class GitHubTokenCliProvider {
502
459
  return result;
503
460
  }
504
461
  async markInvalid() {
505
- await keytar__default["default"].deletePassword(this.keyringService, this.keyringAccount);
462
+ await keytar.deletePassword(this.keyringService, this.keyringAccount);
506
463
  }
507
464
  async setToken(value) {
508
- await keytar__default["default"].setPassword(this.keyringService, this.keyringAccount, value);
465
+ await keytar.setPassword(this.keyringService, this.keyringAccount, value);
509
466
  }
510
467
  }
511
468
 
@@ -570,20 +527,23 @@ async function undefinedForNotFound(value) {
570
527
  }
571
528
 
572
529
  class GitHubService {
530
+ config;
531
+ octokit;
532
+ cache;
533
+ tokenProvider;
534
+ semaphore;
573
535
  constructor(props) {
574
- this._requestCount = 0;
575
536
  this.config = props.config;
576
537
  this.octokit = props.octokit;
577
538
  this.cache = props.cache;
578
539
  this.tokenProvider = props.tokenProvider;
579
540
  // Control concurrency to GitHub API at service level so we
580
541
  // can maximize concurrency all other places.
581
- this.semaphore = pLimit__default["default"](6);
542
+ this.semaphore = pLimit(6);
582
543
  this.octokit.hook.wrap("request", async (request, options) => {
583
544
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
584
545
  this._requestCount++;
585
546
  if (options.method !== "GET") {
586
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
587
547
  return this.semaphore(() => request(options));
588
548
  }
589
549
  // Try to cache ETag for GET requests to save on rate limiting.
@@ -607,7 +567,6 @@ class GitHubService {
607
567
  }
608
568
  const getResponse = async (allowRetry = true) => {
609
569
  try {
610
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
611
570
  return await request(options);
612
571
  }
613
572
  catch (e) {
@@ -646,6 +605,7 @@ class GitHubService {
646
605
  /* eslint-enable @typescript-eslint/no-unsafe-member-access */
647
606
  });
648
607
  }
608
+ _requestCount = 0;
649
609
  get requestCount() {
650
610
  return this._requestCount;
651
611
  }
@@ -660,18 +620,18 @@ class GitHubService {
660
620
  };
661
621
  let requestDuration = -1;
662
622
  const response = await this.semaphore(() => {
663
- const requestStart = perf_hooks.performance.now();
664
- const result = fetch__default["default"](url, {
623
+ const requestStart = performance.now();
624
+ const result = fetch(url, {
665
625
  method: "POST",
666
626
  headers,
667
627
  body: JSON.stringify({ query }),
668
628
  agent: this.config.agent,
669
629
  });
670
- requestDuration = perf_hooks.performance.now() - requestStart;
630
+ requestDuration = performance.now() - requestStart;
671
631
  return result;
672
632
  });
673
633
  if (response.status === 401) {
674
- process__namespace.stderr.write("Unauthorized\n");
634
+ process$2.stderr.write("Unauthorized\n");
675
635
  await this.tokenProvider.markInvalid();
676
636
  }
677
637
  // If you get 502 after 10s, it is a timeout.
@@ -736,7 +696,6 @@ class GitHubService {
736
696
  if (res.organization.repositories.nodes == null) {
737
697
  throw new Error("Missing organization nodes");
738
698
  }
739
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
740
699
  repos.push(...res.organization.repositories.nodes);
741
700
  if (!res.organization.repositories.pageInfo.hasNextPage) {
742
701
  break;
@@ -765,15 +724,12 @@ class GitHubService {
765
724
  login: it.login,
766
725
  data: it,
767
726
  })),
768
- ...(await this.getOrgMembersInvitedList(org)).map((it) => {
769
- var _a;
770
- return ({
771
- type: "invited",
772
- // TODO: Fix ?? case properly
773
- login: (_a = it.login) !== null && _a !== void 0 ? _a : "invalid",
774
- data: it,
775
- });
776
- }),
727
+ ...(await this.getOrgMembersInvitedList(org)).map((it) => ({
728
+ type: "invited",
729
+ // TODO: Fix ?? case properly
730
+ login: it.login ?? "invalid",
731
+ data: it,
732
+ })),
777
733
  ];
778
734
  }
779
735
  async getRepository(owner, repo) {
@@ -842,15 +798,12 @@ class GitHubService {
842
798
  login: it.login,
843
799
  data: it,
844
800
  })),
845
- ...(await this.getTeamMemberInvitedList(org, team)).map((it) => {
846
- var _a;
847
- return ({
848
- type: "invited",
849
- // TODO: Fix ?? case properly
850
- login: (_a = it.login) !== null && _a !== void 0 ? _a : "invalid",
851
- data: it,
852
- });
853
- }),
801
+ ...(await this.getTeamMemberInvitedList(org, team)).map((it) => ({
802
+ type: "invited",
803
+ // TODO: Fix ?? case properly
804
+ login: it.login ?? "invalid",
805
+ data: it,
806
+ })),
854
807
  ];
855
808
  }
856
809
  async getSearchedPullRequestList(owner) {
@@ -975,17 +928,16 @@ class GitHubService {
975
928
  }
976
929
  }`;
977
930
  return this.cache.json(`vulnerability-alerts-${owner}-${repo}`, async () => {
978
- var _a, _b, _c, _d, _e;
979
931
  const result = [];
980
932
  let after = null;
981
933
  while (true) {
982
934
  const query = getQuery(after);
983
935
  const res = await this.runGraphqlQuery(query);
984
- result.push(...((_c = (_b = (_a = res.repository) === null || _a === void 0 ? void 0 : _a.vulnerabilityAlerts.edges) === null || _b === void 0 ? void 0 : _b.map((it) => it.node)) !== null && _c !== void 0 ? _c : []));
985
- if (!((_d = res.repository) === null || _d === void 0 ? void 0 : _d.vulnerabilityAlerts.pageInfo.hasNextPage)) {
936
+ result.push(...(res.repository?.vulnerabilityAlerts.edges?.map((it) => it.node) ?? []));
937
+ if (!res.repository?.vulnerabilityAlerts.pageInfo.hasNextPage) {
986
938
  break;
987
939
  }
988
- after = (_e = res.repository) === null || _e === void 0 ? void 0 : _e.vulnerabilityAlerts.pageInfo.endCursor;
940
+ after = res.repository?.vulnerabilityAlerts.pageInfo.endCursor;
989
941
  }
990
942
  return result;
991
943
  });
@@ -1027,27 +979,23 @@ class GitHubService {
1027
979
  }
1028
980
  }`;
1029
981
  const issues = await this.cache.json(`renovate-bot-issues-${owner}-${repo}`, async () => {
1030
- var _a, _b, _c, _d, _e;
1031
982
  const result = [];
1032
983
  let after = null;
1033
984
  while (true) {
1034
985
  const query = getQuery(after);
1035
986
  const res = await this.runGraphqlQuery(query);
1036
- const nodes = (_c = (_b = (_a = res.repository) === null || _a === void 0 ? void 0 : _a.issues.edges) === null || _b === void 0 ? void 0 : _b.map((it) => it.node)) !== null && _c !== void 0 ? _c : [];
987
+ const nodes = res.repository?.issues.edges?.map((it) => it.node) ?? [];
1037
988
  result.push(...nodes
1038
989
  .filter((it) => it.title === "Dependency Dashboard")
1039
- .map((it) => {
1040
- var _a, _b, _c, _d, _e;
1041
- return ({
1042
- number: it.number,
1043
- body: it.body,
1044
- lastUpdatedByRenovate: (_e = (_d = (_c = (_b = (_a = it.userContentEdits) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b.filter((it) => { var _a; return ((_a = it.editor) === null || _a === void 0 ? void 0 : _a.login) === "renovate"; })) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.createdAt) !== null && _e !== void 0 ? _e : null,
1045
- });
1046
- }));
1047
- if (!((_d = res.repository) === null || _d === void 0 ? void 0 : _d.issues.pageInfo.hasNextPage)) {
990
+ .map((it) => ({
991
+ number: it.number,
992
+ body: it.body,
993
+ lastUpdatedByRenovate: it.userContentEdits?.nodes?.filter((it) => it.editor?.login === "renovate")?.[0]?.createdAt ?? null,
994
+ })));
995
+ if (!res.repository?.issues.pageInfo.hasNextPage) {
1048
996
  break;
1049
997
  }
1050
- after = (_e = res.repository) === null || _e === void 0 ? void 0 : _e.issues.pageInfo.endCursor;
998
+ after = res.repository?.issues.pageInfo.endCursor;
1051
999
  }
1052
1000
  return result;
1053
1001
  });
@@ -1058,7 +1006,7 @@ class GitHubService {
1058
1006
  }
1059
1007
  }
1060
1008
  async function createOctokit(config, tokenProvider) {
1061
- return new rest.Octokit({
1009
+ return new Octokit({
1062
1010
  auth: await tokenProvider.getToken(),
1063
1011
  request: {
1064
1012
  agent: config.agent,
@@ -1066,8 +1014,7 @@ async function createOctokit(config, tokenProvider) {
1066
1014
  });
1067
1015
  }
1068
1016
  async function createGitHubService(props) {
1069
- var _a;
1070
- const tokenProvider = (_a = props.tokenProvider) !== null && _a !== void 0 ? _a : new GitHubTokenCliProvider();
1017
+ const tokenProvider = props.tokenProvider ?? new GitHubTokenCliProvider();
1071
1018
  return new GitHubService({
1072
1019
  config: props.config,
1073
1020
  octokit: await createOctokit(props.config, tokenProvider),
@@ -1077,15 +1024,13 @@ async function createGitHubService(props) {
1077
1024
  }
1078
1025
 
1079
1026
  class SnykTokenCliProvider {
1080
- constructor() {
1081
- this.keyringService = "cals";
1082
- this.keyringAccount = "snyk-token";
1083
- }
1027
+ keyringService = "cals";
1028
+ keyringAccount = "snyk-token";
1084
1029
  async getToken() {
1085
1030
  if (process.env.CALS_SNYK_TOKEN) {
1086
1031
  return process.env.CALS_SNYK_TOKEN;
1087
1032
  }
1088
- const result = await keytar__default["default"].getPassword(this.keyringService, this.keyringAccount);
1033
+ const result = await keytar.getPassword(this.keyringService, this.keyringAccount);
1089
1034
  if (result == null) {
1090
1035
  process.stderr.write("No token found. Register using `cals snyk set-token`\n");
1091
1036
  return undefined;
@@ -1093,21 +1038,22 @@ class SnykTokenCliProvider {
1093
1038
  return result;
1094
1039
  }
1095
1040
  async markInvalid() {
1096
- await keytar__default["default"].deletePassword(this.keyringService, this.keyringAccount);
1041
+ await keytar.deletePassword(this.keyringService, this.keyringAccount);
1097
1042
  }
1098
1043
  async setToken(value) {
1099
- await keytar__default["default"].setPassword(this.keyringService, this.keyringAccount, value);
1044
+ await keytar.setPassword(this.keyringService, this.keyringAccount, value);
1100
1045
  }
1101
1046
  }
1102
1047
 
1103
1048
  class SnykService {
1049
+ config;
1050
+ tokenProvider;
1104
1051
  constructor(props) {
1105
1052
  this.config = props.config;
1106
1053
  this.tokenProvider = props.tokenProvider;
1107
1054
  }
1108
1055
  async getProjects(definition) {
1109
- var _a;
1110
- const snykAccountId = (_a = definition.snyk) === null || _a === void 0 ? void 0 : _a.accountId;
1056
+ const snykAccountId = definition.snyk?.accountId;
1111
1057
  if (snykAccountId === undefined) {
1112
1058
  return [];
1113
1059
  }
@@ -1135,7 +1081,7 @@ class SnykService {
1135
1081
  * We continue calling the Snyk API and retrieving more projects until links.next is null
1136
1082
  * */
1137
1083
  while (nextUrl) {
1138
- const response = await fetch__default["default"](`https://api.snyk.io/rest${nextUrl}`, {
1084
+ const response = await fetch(`https://api.snyk.io/rest${nextUrl}`, {
1139
1085
  method: "GET",
1140
1086
  headers: {
1141
1087
  Accept: "application/json",
@@ -1172,7 +1118,7 @@ class SnykService {
1172
1118
  totalDependencies: project.meta.latest_dependency_total.total,
1173
1119
  issueCountsBySeverity: project.meta.latest_issue_counts,
1174
1120
  lastTestedDate: project.meta.latest_dependency_total.updated_at,
1175
- browseUrl: `https://app.snyk.io/org/${snykOrgSlugId !== null && snykOrgSlugId !== void 0 ? snykOrgSlugId : "it"}/project/${project.id}`,
1121
+ browseUrl: `https://app.snyk.io/org/${snykOrgSlugId ?? "it"}/project/${project.id}`,
1176
1122
  };
1177
1123
  }),
1178
1124
  ];
@@ -1184,10 +1130,9 @@ class SnykService {
1184
1130
  }
1185
1131
  }
1186
1132
  function createSnykService(props) {
1187
- var _a;
1188
1133
  return new SnykService({
1189
1134
  config: props.config,
1190
- tokenProvider: (_a = props.tokenProvider) !== null && _a !== void 0 ? _a : new SnykTokenCliProvider(),
1135
+ tokenProvider: props.tokenProvider ?? new SnykTokenCliProvider(),
1191
1136
  });
1192
1137
  }
1193
1138
 
@@ -1225,23 +1170,24 @@ function getGitHubRepoId(repo) {
1225
1170
 
1226
1171
  class CacheProvider {
1227
1172
  constructor(config) {
1228
- this.mustValidate = false;
1229
- this.defaultCacheTime = 1800;
1230
1173
  this.config = config;
1231
1174
  }
1175
+ mustValidate = false;
1176
+ config;
1177
+ defaultCacheTime = 1800;
1232
1178
  /**
1233
1179
  * Retrieve cache if existent, ignoring the time.
1234
1180
  *
1235
1181
  * The caller is responsible for handling proper validation,
1236
1182
  */
1237
1183
  retrieveJson(cachekey) {
1238
- const cachefile = path__default["default"].join(this.config.cacheDir, `${cachekey}.json`);
1239
- if (!fs__default["default"].existsSync(cachefile)) {
1184
+ const cachefile = path.join(this.config.cacheDir, `${cachekey}.json`);
1185
+ if (!fs.existsSync(cachefile)) {
1240
1186
  return undefined;
1241
1187
  }
1242
- const data = fs__default["default"].readFileSync(cachefile, "utf-8");
1188
+ const data = fs.readFileSync(cachefile, "utf-8");
1243
1189
  return {
1244
- cacheTime: fs__default["default"].statSync(cachefile).mtime.getTime(),
1190
+ cacheTime: fs.statSync(cachefile).mtime.getTime(),
1245
1191
  data: (data === "undefined" ? undefined : JSON.parse(data)),
1246
1192
  };
1247
1193
  }
@@ -1249,11 +1195,11 @@ class CacheProvider {
1249
1195
  * Save data to cache.
1250
1196
  */
1251
1197
  storeJson(cachekey, data) {
1252
- const cachefile = path__default["default"].join(this.config.cacheDir, `${cachekey}.json`);
1253
- if (!fs__default["default"].existsSync(this.config.cacheDir)) {
1254
- fs__default["default"].mkdirSync(this.config.cacheDir, { recursive: true });
1198
+ const cachefile = path.join(this.config.cacheDir, `${cachekey}.json`);
1199
+ if (!fs.existsSync(this.config.cacheDir)) {
1200
+ fs.mkdirSync(this.config.cacheDir, { recursive: true });
1255
1201
  }
1256
- fs__default["default"].writeFileSync(cachefile, data === undefined ? "undefined" : JSON.stringify(data));
1202
+ fs.writeFileSync(cachefile, data === undefined ? "undefined" : JSON.stringify(data));
1257
1203
  }
1258
1204
  async json(cachekey, block, cachetime = this.defaultCacheTime) {
1259
1205
  const cacheItem = this.mustValidate
@@ -1271,20 +1217,18 @@ class CacheProvider {
1271
1217
  * Delete all cached data.
1272
1218
  */
1273
1219
  cleanup() {
1274
- rimraf__default["default"].sync(this.config.cacheDir);
1220
+ rimraf.sync(this.config.cacheDir);
1275
1221
  }
1276
1222
  }
1277
1223
 
1278
1224
  class Config {
1279
- constructor() {
1280
- this.cwd = path__default["default"].resolve(process.cwd());
1281
- this.configFile = path__default["default"].join(os__default["default"].homedir(), ".cals-config.json");
1282
- this.cacheDir = cachedir__default["default"]("cals-cli");
1283
- this.agent = new https__default["default"].Agent({
1284
- keepAlive: true,
1285
- });
1286
- this.configCached = undefined;
1287
- }
1225
+ cwd = path.resolve(process.cwd());
1226
+ configFile = path.join(os.homedir(), ".cals-config.json");
1227
+ cacheDir = cachedir("cals-cli");
1228
+ agent = new https.Agent({
1229
+ keepAlive: true,
1230
+ });
1231
+ configCached = undefined;
1288
1232
  get config() {
1289
1233
  const existingConfig = this.configCached;
1290
1234
  if (existingConfig !== undefined) {
@@ -1295,12 +1239,12 @@ class Config {
1295
1239
  return config;
1296
1240
  }
1297
1241
  readConfig() {
1298
- if (!fs__default["default"].existsSync(this.configFile)) {
1242
+ if (!fs.existsSync(this.configFile)) {
1299
1243
  return {};
1300
1244
  }
1301
1245
  try {
1302
1246
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
1303
- return JSON.parse(fs__default["default"].readFileSync(this.configFile, "utf-8"));
1247
+ return JSON.parse(fs.readFileSync(this.configFile, "utf-8"));
1304
1248
  }
1305
1249
  catch (e) {
1306
1250
  console.error("Failed", e);
@@ -1322,27 +1266,29 @@ class Config {
1322
1266
  ...this.readConfig(),
1323
1267
  [key]: value, // undefined will remove
1324
1268
  };
1325
- fs__default["default"].writeFileSync(this.configFile, JSON.stringify(updatedConfig, null, " "));
1269
+ fs.writeFileSync(this.configFile, JSON.stringify(updatedConfig, null, " "));
1326
1270
  this.configCached = updatedConfig;
1327
1271
  }
1328
1272
  }
1329
1273
 
1330
1274
  const CLEAR_WHOLE_LINE = 0;
1331
1275
  function clearLine(stdout) {
1332
- readline__default["default"].clearLine(stdout, CLEAR_WHOLE_LINE);
1333
- readline__default["default"].cursorTo(stdout, 0);
1276
+ readline.clearLine(stdout, CLEAR_WHOLE_LINE);
1277
+ readline.cursorTo(stdout, 0);
1334
1278
  }
1335
1279
  class Reporter {
1336
1280
  constructor(opts = {}) {
1337
- this.stdout = process.stdout;
1338
- this.stderr = process.stderr;
1339
- this.stdin = process.stdin;
1340
- this.isTTY = this.stdout.isTTY;
1341
- this.format = chalk__default["default"];
1342
- this.startTime = Date.now();
1343
1281
  this.nonInteractive = !!opts.nonInteractive;
1344
1282
  this.isVerbose = !!opts.verbose;
1345
1283
  }
1284
+ stdout = process.stdout;
1285
+ stderr = process.stderr;
1286
+ stdin = process.stdin;
1287
+ isTTY = this.stdout.isTTY;
1288
+ nonInteractive;
1289
+ isVerbose;
1290
+ format = chalk;
1291
+ startTime = Date.now();
1346
1292
  error(msg) {
1347
1293
  clearLine(this.stderr);
1348
1294
  this.stderr.write(`${this.format.red("error")} ${msg}\n`);
@@ -1379,7 +1325,7 @@ function createCacheProvider(config, argv) {
1379
1325
  }
1380
1326
  // old option: --no-cache
1381
1327
  if (argv.cache === false) {
1382
- util.deprecate(() => {
1328
+ deprecate(() => {
1383
1329
  cache.mustValidate = true;
1384
1330
  }, "The --no-cache option is deprecated. See new --validate-cache option")();
1385
1331
  }
@@ -1399,7 +1345,7 @@ function getDefinitionFile(argv) {
1399
1345
  throw Error("Missing --definition-file option");
1400
1346
  }
1401
1347
  const definitionFile = argv.definitionFile;
1402
- if (!fs__default["default"].existsSync(definitionFile)) {
1348
+ if (!fs.existsSync(definitionFile)) {
1403
1349
  throw Error(`The file ${definitionFile} does not exist`);
1404
1350
  }
1405
1351
  return new DefinitionFile(definitionFile);
@@ -1456,9 +1402,9 @@ function reorderListToSimilarAsBefore(oldList, updatedList, selector, insertLast
1456
1402
  }
1457
1403
 
1458
1404
  async function getReposFromGitHub(github, orgs) {
1459
- return (await pMap__default["default"](orgs, async (org) => {
1405
+ return (await pMap(orgs, async (org) => {
1460
1406
  const repos = await github.getOrgRepoList({ org: org.login });
1461
- return pMap__default["default"](repos, async (repo) => {
1407
+ return pMap(repos, async (repo) => {
1462
1408
  const detailedRepo = await github.getRepository(repo.owner.login, repo.name);
1463
1409
  if (detailedRepo === undefined) {
1464
1410
  throw Error(`Repo not found: ${repo.owner.login}/${repo.name}`);
@@ -1472,11 +1418,11 @@ async function getReposFromGitHub(github, orgs) {
1472
1418
  })).flat();
1473
1419
  }
1474
1420
  async function getTeams(github, orgs) {
1475
- const intermediate = await pMap__default["default"](orgs, async (org) => {
1421
+ const intermediate = await pMap(orgs, async (org) => {
1476
1422
  const teams = await github.getTeamList(org);
1477
1423
  return {
1478
1424
  org,
1479
- teams: await pMap__default["default"](teams, async (team) => ({
1425
+ teams: await pMap(teams, async (team) => ({
1480
1426
  team,
1481
1427
  users: await github.getTeamMemberListIncludingInvited(org, team),
1482
1428
  })),
@@ -1505,11 +1451,11 @@ function getFormattedTeams(oldTeams, teams) {
1505
1451
  permission: it.permission,
1506
1452
  }));
1507
1453
  return result
1508
- ? reorderListToSimilarAsBefore(oldTeams !== null && oldTeams !== void 0 ? oldTeams : [], result, (it) => it.name)
1454
+ ? reorderListToSimilarAsBefore(oldTeams ?? [], result, (it) => it.name)
1509
1455
  : undefined;
1510
1456
  }
1511
1457
  async function getOrgs(github, orgs) {
1512
- return pMap__default["default"](orgs, (it) => github.getOrg(it));
1458
+ return pMap(orgs, (it) => github.getOrg(it));
1513
1459
  }
1514
1460
  function removeDuplicates(items, selector) {
1515
1461
  const ids = [];
@@ -1524,7 +1470,7 @@ function removeDuplicates(items, selector) {
1524
1470
  return result;
1525
1471
  }
1526
1472
  async function getMembers(github, orgs) {
1527
- return removeDuplicates((await pMap__default["default"](orgs, (org) => github.getOrgMembersListIncludingInvited(org.login)))
1473
+ return removeDuplicates((await pMap(orgs, (org) => github.getOrgMembersListIncludingInvited(org.login)))
1528
1474
  .flat()
1529
1475
  .map((it) => it.login), (it) => it);
1530
1476
  }
@@ -1538,15 +1484,14 @@ async function getProjects(github, orgs, definition, snyk) {
1538
1484
  const snykReposPromise = getSnykRepos(snyk, definition);
1539
1485
  const repos = await getReposFromGitHub(github, orgs);
1540
1486
  const snykRepos = await snykReposPromise;
1541
- const definitionRepos = lodash.keyBy(getRepos(definition), (it) => it.id);
1487
+ const definitionRepos = keyBy(getRepos(definition), (it) => it.id);
1542
1488
  const projectGroups = Object.values(repos.reduce((acc, cur) => {
1543
- var _a, _b, _c, _d;
1544
1489
  const org = cur.repository.owner.login;
1545
1490
  const repoId = getRepoId(org, cur.repository.name);
1546
- const projectName = (_c = (_b = (_a = definitionRepos[repoId]) === null || _a === void 0 ? void 0 : _a.project) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : "Unknown";
1491
+ const projectName = definitionRepos[repoId]?.project?.name ?? "Unknown";
1547
1492
  const project = acc[projectName] || {
1548
1493
  name: projectName,
1549
- definition: (_d = definitionRepos[repoId]) === null || _d === void 0 ? void 0 : _d.project,
1494
+ definition: definitionRepos[repoId]?.project,
1550
1495
  repos: [],
1551
1496
  };
1552
1497
  return {
@@ -1561,39 +1506,36 @@ async function getProjects(github, orgs, definition, snyk) {
1561
1506
  };
1562
1507
  }, {}));
1563
1508
  const projects = projectGroups.map((project) => {
1564
- var _a, _b;
1565
1509
  const github = Object.entries(project.repos).map(([org, list]) => {
1566
- var _a, _b, _c, _d;
1567
1510
  const commonTeams = getCommonTeams(list);
1568
- const oldOrg = (_b = (_a = project.definition) === null || _a === void 0 ? void 0 : _a.github) === null || _b === void 0 ? void 0 : _b.find((it) => it.organization == org);
1511
+ const oldOrg = project.definition?.github?.find((it) => it.organization == org);
1569
1512
  const repos = list.map((repo) => {
1570
- var _a, _b;
1571
1513
  const repoId = getRepoId(repo.basic.owner.login, repo.basic.name);
1572
1514
  const definitionRepo = definitionRepos[repoId];
1573
1515
  const result = {
1574
1516
  name: repo.basic.name,
1575
- previousNames: definitionRepo === null || definitionRepo === void 0 ? void 0 : definitionRepo.repo.previousNames,
1517
+ previousNames: definitionRepo?.repo.previousNames,
1576
1518
  archived: repo.repository.archived ? true : undefined,
1577
1519
  issues: repo.repository.has_issues ? undefined : false,
1578
1520
  wiki: repo.repository.has_wiki ? undefined : false,
1579
- teams: getFormattedTeams((_b = (_a = definitionRepo === null || definitionRepo === void 0 ? void 0 : definitionRepo.repo) === null || _a === void 0 ? void 0 : _a.teams) !== null && _b !== void 0 ? _b : [], getSpecificTeams(repo.teams, commonTeams)),
1521
+ teams: getFormattedTeams(definitionRepo?.repo?.teams ?? [], getSpecificTeams(repo.teams, commonTeams)),
1580
1522
  snyk: snykRepos.includes(repoId) ? true : undefined,
1581
1523
  public: repo.repository.private ? undefined : true,
1582
- responsible: definitionRepo === null || definitionRepo === void 0 ? void 0 : definitionRepo.repo.responsible,
1524
+ responsible: definitionRepo?.repo.responsible,
1583
1525
  };
1584
1526
  // Try to preserve property order.
1585
1527
  return Object.fromEntries(reorderListToSimilarAsBefore(definitionRepo ? Object.entries(definitionRepo.repo) : [], Object.entries(result), (it) => it[0], true));
1586
1528
  });
1587
- const teams = getFormattedTeams((_c = oldOrg === null || oldOrg === void 0 ? void 0 : oldOrg.teams) !== null && _c !== void 0 ? _c : [], commonTeams);
1529
+ const teams = getFormattedTeams(oldOrg?.teams ?? [], commonTeams);
1588
1530
  return {
1589
1531
  organization: org,
1590
1532
  teams: teams,
1591
- repos: reorderListToSimilarAsBefore((_d = oldOrg === null || oldOrg === void 0 ? void 0 : oldOrg.repos) !== null && _d !== void 0 ? _d : [], repos, (it) => it.name),
1533
+ repos: reorderListToSimilarAsBefore(oldOrg?.repos ?? [], repos, (it) => it.name),
1592
1534
  };
1593
1535
  });
1594
1536
  return {
1595
1537
  name: project.name,
1596
- github: reorderListToSimilarAsBefore((_b = (_a = project.definition) === null || _a === void 0 ? void 0 : _a.github) !== null && _b !== void 0 ? _b : [], github, (it) => it.organization),
1538
+ github: reorderListToSimilarAsBefore(project.definition?.github ?? [], github, (it) => it.organization),
1597
1539
  };
1598
1540
  });
1599
1541
  return reorderListToSimilarAsBefore(definition.projects, projects, (it) => it.name);
@@ -1638,7 +1580,7 @@ async function dumpSetup(config, reporter, github, snyk, outfile, definitionFile
1638
1580
  // package. However it often produced invalid yaml, so we have removed
1639
1581
  // it. We might want to revisit it to preserve comments.
1640
1582
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-explicit-any
1641
- const doc = yaml__default["default"].load(await definitionFile.getContents());
1583
+ const doc = yaml.load(await definitionFile.getContents());
1642
1584
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1643
1585
  doc.snyk = generatedDefinition.snyk;
1644
1586
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -1646,7 +1588,7 @@ async function dumpSetup(config, reporter, github, snyk, outfile, definitionFile
1646
1588
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1647
1589
  doc.github = generatedDefinition.github;
1648
1590
  // Convert to/from plain JSON so that undefined elements are removed.
1649
- fs__default["default"].writeFileSync(outfile, yaml__default["default"].dump(JSON.parse(JSON.stringify(doc))));
1591
+ fs.writeFileSync(outfile, yaml.dump(JSON.parse(JSON.stringify(doc))));
1650
1592
  reporter.info(`Saved to ${outfile}`);
1651
1593
  reporter.info(`Number of GitHub requests: ${github.requestCount}`);
1652
1594
  }
@@ -1691,7 +1633,7 @@ const command$f = {
1691
1633
  .demandCommand()
1692
1634
  .usage(`cals definition`),
1693
1635
  handler: () => {
1694
- yargs__default["default"].showHelp();
1636
+ yargs(hideBin(process.argv)).showHelp();
1695
1637
  },
1696
1638
  };
1697
1639
 
@@ -1719,9 +1661,9 @@ const command$d = {
1719
1661
  async function analyzeDirectory(reporter, config, github, org) {
1720
1662
  const repos = await github.getOrgRepoList({ org });
1721
1663
  const reposDict = repos.reduce((acc, cur) => ({ ...acc, [cur.name]: cur }), {});
1722
- const dirs = fs__default["default"]
1664
+ const dirs = fs
1723
1665
  .readdirSync(config.cwd)
1724
- .filter((it) => fs__default["default"].statSync(path__default["default"].join(config.cwd, it)).isDirectory())
1666
+ .filter((it) => fs.statSync(path.join(config.cwd, it)).isDirectory())
1725
1667
  // Skip hidden folders
1726
1668
  .filter((it) => !it.startsWith("."))
1727
1669
  .sort((a, b) => a.localeCompare(b));
@@ -1732,18 +1674,18 @@ async function analyzeDirectory(reporter, config, github, org) {
1732
1674
  };
1733
1675
  dirs.forEach((it) => {
1734
1676
  if (!(it in reposDict)) {
1735
- reporter.warn(sprintfJs.sprintf("%-30s <-- Not found in repository list (maybe changed name?)", it));
1677
+ reporter.warn(sprintf("%-30s <-- Not found in repository list (maybe changed name?)", it));
1736
1678
  stats.unknown++;
1737
1679
  return;
1738
1680
  }
1739
1681
  if (reposDict[it].isArchived) {
1740
- reporter.info(sprintfJs.sprintf("%-30s <-- Archived", it));
1682
+ reporter.info(sprintf("%-30s <-- Archived", it));
1741
1683
  stats.archived++;
1742
1684
  return;
1743
1685
  }
1744
1686
  stats.ok += 1;
1745
1687
  });
1746
- reporter.info(sprintfJs.sprintf("Stats: unknown=%d archived=%d ok=%d", stats.unknown, stats.archived, stats.ok));
1688
+ reporter.info(sprintf("Stats: unknown=%d archived=%d ok=%d", stats.unknown, stats.archived, stats.ok));
1747
1689
  reporter.info("Use `cals github generate-clone-commands` to check for repositories not checked out");
1748
1690
  }
1749
1691
  const command$c = {
@@ -1766,7 +1708,6 @@ const command$c = {
1766
1708
  };
1767
1709
 
1768
1710
  function getChangedRepoAttribs(definitionRepo, actualRepo) {
1769
- var _a, _b;
1770
1711
  const attribs = [];
1771
1712
  const archived = definitionRepo.archived || false;
1772
1713
  if (archived !== actualRepo.archived) {
@@ -1774,13 +1715,13 @@ function getChangedRepoAttribs(definitionRepo, actualRepo) {
1774
1715
  archived,
1775
1716
  });
1776
1717
  }
1777
- const issues = (_a = definitionRepo.issues) !== null && _a !== void 0 ? _a : true;
1718
+ const issues = definitionRepo.issues ?? true;
1778
1719
  if (issues !== actualRepo.has_issues && !actualRepo.archived) {
1779
1720
  attribs.push({
1780
1721
  issues,
1781
1722
  });
1782
1723
  }
1783
- const wiki = (_b = definitionRepo.wiki) !== null && _b !== void 0 ? _b : true;
1724
+ const wiki = definitionRepo.wiki ?? true;
1784
1725
  if (wiki !== actualRepo.has_wiki && !actualRepo.archived) {
1785
1726
  attribs.push({
1786
1727
  wiki,
@@ -1797,7 +1738,7 @@ function getChangedRepoAttribs(definitionRepo, actualRepo) {
1797
1738
  async function getUnknownRepos(github, definition, limitToOrg) {
1798
1739
  const knownRepos = getRepos(definition).map((it) => it.id);
1799
1740
  const orgs = getGitHubOrgs(definition).filter((orgName) => limitToOrg === undefined || limitToOrg === orgName);
1800
- return lodash.sortBy((await pMap__default["default"](orgs, (orgName) => github.getOrgRepoList({ org: orgName })))
1741
+ return sortBy((await pMap(orgs, (orgName) => github.getOrgRepoList({ org: orgName })))
1801
1742
  .flat()
1802
1743
  .filter((it) => !knownRepos.includes(`${it.owner.login}/${it.name}`)), (it) => `${it.owner.login}/${it.name}`);
1803
1744
  }
@@ -1812,9 +1753,8 @@ function getExpectedTeams(projectTeams, repoTeams) {
1812
1753
  ];
1813
1754
  }
1814
1755
  async function getRepoTeamChanges({ github, org, projectRepo, repo, }) {
1815
- var _a, _b;
1816
1756
  const changes = [];
1817
- const expectedTeams = getExpectedTeams((_a = org.teams) !== null && _a !== void 0 ? _a : [], (_b = projectRepo.teams) !== null && _b !== void 0 ? _b : []);
1757
+ const expectedTeams = getExpectedTeams(org.teams ?? [], projectRepo.teams ?? []);
1818
1758
  const existingTeams = await github.getRepositoryTeamsList(repo);
1819
1759
  // Check for teams to be added / modified.
1820
1760
  for (const repoteam of expectedTeams) {
@@ -1892,7 +1832,7 @@ async function createChangeSetItemsForProjects(github, definition, limitToOrg) {
1892
1832
  const orgs = definition.projects
1893
1833
  .flatMap((it) => it.github)
1894
1834
  .filter((org) => limitToOrg === undefined || limitToOrg === org.organization);
1895
- changes.push(...(await pMap__default["default"](orgs, async (org) => pMap__default["default"](org.repos || [], (projectRepo) => getProjectRepoChanges({
1835
+ changes.push(...(await pMap(orgs, async (org) => pMap(org.repos || [], (projectRepo) => getProjectRepoChanges({
1896
1836
  github,
1897
1837
  org,
1898
1838
  projectRepo,
@@ -1990,8 +1930,7 @@ async function createChangeSetItemsForTeams(github, definition, org) {
1990
1930
  }
1991
1931
  });
1992
1932
  const overlappingTeams = actualTeams.filter((it) => wantedTeamNames.includes(it.name));
1993
- await pMap__default["default"](overlappingTeams, async (actualTeam) => {
1994
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1933
+ await pMap(overlappingTeams, async (actualTeam) => {
1995
1934
  const wantedTeam = teams.find((it) => it.name === actualTeam.name);
1996
1935
  const actualMembers = await github.getTeamMemberListIncludingInvited(org, actualTeam);
1997
1936
  actualMembers
@@ -2194,7 +2133,7 @@ function createOrgGetter(github) {
2194
2133
  const semaphores = {};
2195
2134
  function getSemaphore(orgName) {
2196
2135
  if (!(orgName in semaphores)) {
2197
- semaphores[orgName] = pLimit__default["default"](1);
2136
+ semaphores[orgName] = pLimit(1);
2198
2137
  }
2199
2138
  return semaphores[orgName];
2200
2139
  }
@@ -2251,11 +2190,12 @@ async function process$1(reporter, github, definition, getOrg, execute, limitToO
2251
2190
  }
2252
2191
  if (execute && changes.length > 0) {
2253
2192
  const cont = await new Promise((resolve, reject) => {
2254
- read__default["default"]({
2193
+ read({
2255
2194
  prompt: "Confirm you want to execute the changes [y/N]: ",
2256
2195
  timeout: 60000,
2257
2196
  }, (err, answer) => {
2258
2197
  if (err) {
2198
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
2259
2199
  reject(err);
2260
2200
  }
2261
2201
  resolve(answer);
@@ -2301,7 +2241,7 @@ const command$b = {
2301
2241
 
2302
2242
  async function generateCloneCommands({ reporter, config, github, org, ...opt }) {
2303
2243
  if (!opt.listGroups && !opt.all && opt.group === undefined) {
2304
- yargs__default["default"].showHelp();
2244
+ yargs(hideBin(process.argv)).showHelp();
2305
2245
  return;
2306
2246
  }
2307
2247
  const repos = await github.getOrgRepoList({ org });
@@ -2321,11 +2261,11 @@ async function generateCloneCommands({ reporter, config, github, org, ...opt })
2321
2261
  .filter((it) => opt.name === undefined || it.name.includes(opt.name))
2322
2262
  .filter((it) => opt.topic === undefined || includesTopic(it, opt.topic))
2323
2263
  .filter((it) => !opt.excludeExisting ||
2324
- !fs__default["default"].existsSync(path__default["default"].resolve(config.cwd, it.name)))
2264
+ !fs.existsSync(path.resolve(config.cwd, it.name)))
2325
2265
  .forEach((repo) => {
2326
2266
  // The output of this is used to pipe into e.g. bash.
2327
2267
  // We cannot use reporter.log as it adds additional characters.
2328
- process.stdout.write(sprintfJs.sprintf('[ ! -e "%s" ] && git clone %s\n', repo.name, repo.sshUrl));
2268
+ process.stdout.write(sprintf('[ ! -e "%s" ] && git clone %s\n', repo.name, repo.sshUrl));
2329
2269
  });
2330
2270
  });
2331
2271
  }
@@ -2423,10 +2363,10 @@ async function listPullRequestsStats({ reporter, github, }) {
2423
2363
  reporter.log("Pull requests stats:");
2424
2364
  reporter.log("A pull request is considered old after 60 days");
2425
2365
  reporter.log("");
2426
- reporter.log(sprintfJs.sprintf("%-40s %12s %2s %12s %2s", "", "normal", "", "snyk", ""));
2427
- reporter.log(sprintfJs.sprintf("%-40s %7s %7s %7s %7s", "Repo", "old", "recent", "old", "recent"));
2366
+ reporter.log(sprintf("%-40s %12s %2s %12s %2s", "", "normal", "", "snyk", ""));
2367
+ reporter.log(sprintf("%-40s %7s %7s %7s %7s", "Repo", "old", "recent", "old", "recent"));
2428
2368
  categories.forEach((cat) => {
2429
- reporter.log(sprintfJs.sprintf("%-40s %7s %7s %7s %7s", cat.key, cat.old.length === 0 ? "" : cat.old.length, cat.recent.length === 0 ? "" : cat.recent.length, cat.oldSnyk.length === 0 ? "" : cat.oldSnyk.length, cat.recentSnyk.length === 0 ? "" : cat.recentSnyk.length));
2369
+ reporter.log(sprintf("%-40s %7s %7s %7s %7s", cat.key, cat.old.length === 0 ? "" : cat.old.length, cat.recent.length === 0 ? "" : cat.recent.length, cat.oldSnyk.length === 0 ? "" : cat.oldSnyk.length, cat.recentSnyk.length === 0 ? "" : cat.recentSnyk.length));
2430
2370
  });
2431
2371
  }
2432
2372
  }
@@ -2591,15 +2531,15 @@ async function listWebhooks(reporter, cache, github, org) {
2591
2531
  }
2592
2532
  switch (hook.name) {
2593
2533
  case "web":
2594
- reporter.log(sprintfJs.sprintf(" web: %s (%s) (%s)", hook.config.url, hook.last_response.code, hook.events.join(", ")));
2534
+ reporter.log(sprintf(" web: %s (%s) (%s)", hook.config.url, hook.last_response.code, hook.events.join(", ")));
2595
2535
  break;
2596
2536
  case "jenkinsgit":
2597
- reporter.log(sprintfJs.sprintf(" jenkinsgit: %s (%s) (%s)",
2537
+ reporter.log(sprintf(" jenkinsgit: %s (%s) (%s)",
2598
2538
  // This is undocumented.
2599
2539
  hook.config.jenkins_url, hook.last_response.code, hook.events.join(", ")));
2600
2540
  break;
2601
2541
  case "docker":
2602
- reporter.log(sprintfJs.sprintf(" docker (%s) (%s)", hook.last_response.code, hook.events.join(", ")));
2542
+ reporter.log(sprintf(" docker (%s) (%s)", hook.last_response.code, hook.events.join(", ")));
2603
2543
  break;
2604
2544
  default:
2605
2545
  reporter.log(` ${hook.name}: <unknown type>`);
@@ -2628,11 +2568,12 @@ async function setToken$1({ reporter, token, tokenProvider, }) {
2628
2568
  reporter.info("Need API token to talk to GitHub");
2629
2569
  reporter.info("https://github.com/settings/tokens/new?scopes=repo:status,read:repo_hook");
2630
2570
  token = await new Promise((resolve, reject) => {
2631
- read__default["default"]({
2571
+ read({
2632
2572
  prompt: "Enter new GitHub API token: ",
2633
2573
  silent: true,
2634
2574
  }, (err, answer) => {
2635
2575
  if (err) {
2576
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
2636
2577
  reject(err);
2637
2578
  }
2638
2579
  resolve(answer);
@@ -2691,20 +2632,22 @@ var CloneType;
2691
2632
  CloneType[CloneType["SSH"] = 1] = "SSH";
2692
2633
  })(CloneType || (CloneType = {}));
2693
2634
  class GitRepo {
2635
+ path;
2636
+ logCommand;
2694
2637
  constructor(path, logCommand) {
2695
2638
  this.path = path;
2696
2639
  this.logCommand = logCommand;
2697
2640
  }
2698
2641
  async cloneGitHubRepo(org, name, cloneType) {
2699
- const parent = path__default["default"].dirname(this.path);
2700
- if (!fs__default["default"].existsSync(parent)) {
2701
- await fs__default["default"].promises.mkdir(parent, { recursive: true });
2642
+ const parent = path.dirname(this.path);
2643
+ if (!fs.existsSync(parent)) {
2644
+ await fs.promises.mkdir(parent, { recursive: true });
2702
2645
  }
2703
2646
  const cloneUrl = cloneType === CloneType.SSH
2704
2647
  ? `git@github.com:${org}/${name}.git`
2705
2648
  : `https://github.com/${org}/${name}.git`;
2706
2649
  try {
2707
- const result = await execa__default["default"]("git", ["clone", cloneUrl, this.path], {
2650
+ const result = await execa("git", ["clone", cloneUrl, this.path], {
2708
2651
  cwd: parent,
2709
2652
  });
2710
2653
  await this.logCommand(result);
@@ -2717,7 +2660,7 @@ class GitRepo {
2717
2660
  }
2718
2661
  async git(args) {
2719
2662
  try {
2720
- const result = await execa__default["default"]("git", args, {
2663
+ const result = await execa("git", args, {
2721
2664
  cwd: this.path,
2722
2665
  });
2723
2666
  await this.logCommand(result);
@@ -2750,7 +2693,6 @@ class GitRepo {
2750
2693
  return parseShortlogSummary(result.stdout);
2751
2694
  }
2752
2695
  async update() {
2753
- var _a;
2754
2696
  const fetchOnly = async () => {
2755
2697
  await this.git(["fetch"]);
2756
2698
  return {
@@ -2773,7 +2715,7 @@ class GitRepo {
2773
2715
  return {
2774
2716
  dirty: false,
2775
2717
  updated: wasUpdated(result.stdout),
2776
- updatedRange: (_a = getUpdateRange(result.stdout)) !== null && _a !== void 0 ? _a : undefined,
2718
+ updatedRange: getUpdateRange(result.stdout) ?? undefined,
2777
2719
  };
2778
2720
  }
2779
2721
  }
@@ -2785,11 +2727,11 @@ const CALS_LOG = ".cals.log";
2785
2727
  * backward slashes in paths.
2786
2728
  */
2787
2729
  function getRelpath(it) {
2788
- return path__default["default"].join(it.group, it.name);
2730
+ return path.join(it.group, it.name);
2789
2731
  }
2790
2732
  async function appendFile(path, data) {
2791
2733
  return new Promise((resolve, reject) => {
2792
- fs__default["default"].appendFile(path, data, { encoding: "utf-8" }, (err) => {
2734
+ fs.appendFile(path, data, { encoding: "utf-8" }, (err) => {
2793
2735
  if (err !== null) {
2794
2736
  reject(err);
2795
2737
  }
@@ -2798,15 +2740,14 @@ async function appendFile(path, data) {
2798
2740
  });
2799
2741
  }
2800
2742
  function getAliases(repo) {
2801
- var _a;
2802
- return ((_a = repo.previousNames) !== null && _a !== void 0 ? _a : []).map((it) => ({
2743
+ return (repo.previousNames ?? []).map((it) => ({
2803
2744
  group: it.project,
2804
2745
  name: it.name,
2805
2746
  }));
2806
2747
  }
2807
2748
  async function updateReposInParallel(reporter, items) {
2808
2749
  // Perform git operations in parallel, but limit how much.
2809
- const semaphore = pLimit__default["default"](30);
2750
+ const semaphore = pLimit(30);
2810
2751
  const promises = items.map((repo) => semaphore(async () => {
2811
2752
  try {
2812
2753
  return {
@@ -2815,7 +2756,6 @@ async function updateReposInParallel(reporter, items) {
2815
2756
  };
2816
2757
  }
2817
2758
  catch (e) {
2818
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
2819
2759
  reporter.error(`Failed for ${repo.actualRelpath} - skipping. ${e}`);
2820
2760
  return null;
2821
2761
  }
@@ -2851,7 +2791,7 @@ async function updateRepos(reporter, foundRepos) {
2851
2791
  : undefined;
2852
2792
  // We only focus on changes made by humans, which we make
2853
2793
  // green while keeping the other changes gray.
2854
- const repoNameFormat = (authors === null || authors === void 0 ? void 0 : authors.every(({ name }) => isBotAuthor(name)))
2794
+ const repoNameFormat = authors?.every(({ name }) => isBotAuthor(name))
2855
2795
  ? reporter.format.gray
2856
2796
  : reporter.format.greenBright;
2857
2797
  reporter.info(`Updated: ${repoNameFormat(repo.id)}`);
@@ -2868,8 +2808,8 @@ async function updateRepos(reporter, foundRepos) {
2868
2808
  }
2869
2809
  }
2870
2810
  function guessDefinitionRepoName(rootdir, cals) {
2871
- const p = path__default["default"].resolve(rootdir, cals.resourcesDefinition.path);
2872
- const relativePath = path__default["default"].relative(rootdir, p);
2811
+ const p = path.resolve(rootdir, cals.resourcesDefinition.path);
2812
+ const relativePath = path.relative(rootdir, p);
2873
2813
  if (relativePath.slice(0, 1) == ".") {
2874
2814
  return null;
2875
2815
  }
@@ -2882,8 +2822,8 @@ function guessDefinitionRepoName(rootdir, cals) {
2882
2822
  return parts[1];
2883
2823
  }
2884
2824
  async function getDefinition(rootdir, cals) {
2885
- const p = path__default["default"].resolve(rootdir, cals.resourcesDefinition.path);
2886
- if (!fs__default["default"].existsSync(p)) {
2825
+ const p = path.resolve(rootdir, cals.resourcesDefinition.path);
2826
+ if (!fs.existsSync(p)) {
2887
2827
  throw Error(`The file ${p} does not exist`);
2888
2828
  }
2889
2829
  return new DefinitionFile(p).getDefinition();
@@ -2892,9 +2832,9 @@ async function getDefinition(rootdir, cals) {
2892
2832
  * Get directory names within a directory.
2893
2833
  */
2894
2834
  function getDirNames(parent) {
2895
- return (fs__default["default"]
2835
+ return (fs
2896
2836
  .readdirSync(parent)
2897
- .filter((it) => fs__default["default"].statSync(path__default["default"].join(parent, it)).isDirectory())
2837
+ .filter((it) => fs.statSync(path.join(parent, it)).isDirectory())
2898
2838
  // Skip hidden folders
2899
2839
  .filter((it) => !it.startsWith("."))
2900
2840
  .sort((a, b) => a.localeCompare(b)));
@@ -2904,9 +2844,9 @@ async function getReposInOrg(cals, rootdir) {
2904
2844
  return getRepos(definition)
2905
2845
  .filter((it) => it.orgName === cals.githubOrganization)
2906
2846
  .filter((it) => cals.resourcesDefinition.tags === undefined ||
2907
- (it.project.tags || []).some((tag) => { var _a; return (_a = cals.resourcesDefinition.tags) === null || _a === void 0 ? void 0 : _a.includes(tag); }) ||
2847
+ (it.project.tags || []).some((tag) => cals.resourcesDefinition.tags?.includes(tag)) ||
2908
2848
  // Always include if already checked out to avoid stale state.
2909
- fs__default["default"].existsSync(path__default["default"].join(rootdir, it.project.name, it.repo.name)));
2849
+ fs.existsSync(path.join(rootdir, it.project.name, it.repo.name)));
2910
2850
  }
2911
2851
  function getExpectedRepo(item) {
2912
2852
  return {
@@ -2919,8 +2859,8 @@ function getExpectedRepo(item) {
2919
2859
  };
2920
2860
  }
2921
2861
  function getGitRepo(rootdir, relpath) {
2922
- return new GitRepo(path__default["default"].resolve(rootdir, relpath), async (result) => {
2923
- await appendFile(path__default["default"].resolve(rootdir, CALS_LOG), JSON.stringify({
2862
+ return new GitRepo(path.resolve(rootdir, relpath), async (result) => {
2863
+ await appendFile(path.resolve(rootdir, CALS_LOG), JSON.stringify({
2924
2864
  time: new Date().toISOString(),
2925
2865
  context: relpath,
2926
2866
  type: "exec-result",
@@ -2974,11 +2914,12 @@ async function getExpectedRepos(reporter, github, cals, rootdir) {
2974
2914
  }
2975
2915
  async function getInput(prompt) {
2976
2916
  return new Promise((resolve, reject) => {
2977
- read__default["default"]({
2917
+ read({
2978
2918
  prompt,
2979
2919
  timeout: 60000,
2980
2920
  }, (err, answer) => {
2981
2921
  if (err) {
2922
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
2982
2923
  reject(err);
2983
2924
  }
2984
2925
  resolve(answer);
@@ -3011,15 +2952,15 @@ async function sync$1({ reporter, github, cals, rootdir, askClone, askMove, }) {
3011
2952
  const foundRepos = [];
3012
2953
  // Categorize all dirs.
3013
2954
  for (const topdir of getDirNames(rootdir)) {
3014
- const isGitDir = fs__default["default"].existsSync(path__default["default"].join(rootdir, topdir, ".git"));
2955
+ const isGitDir = fs.existsSync(path.join(rootdir, topdir, ".git"));
3015
2956
  if (isGitDir) {
3016
2957
  // Do not traverse deeper inside another Git repo, as that might
3017
2958
  // mean we do not have the proper grouped structure.
3018
2959
  unknownDirs.push(topdir);
3019
2960
  continue;
3020
2961
  }
3021
- for (const subdir of getDirNames(path__default["default"].join(rootdir, topdir))) {
3022
- const p = path__default["default"].join(topdir, subdir);
2962
+ for (const subdir of getDirNames(path.join(rootdir, topdir))) {
2963
+ const p = path.join(topdir, subdir);
3023
2964
  const expectedRepo = expectedRepos.find((it) => getRelpath(it) === p ||
3024
2965
  it.aliases.some((alias) => getRelpath(alias) === p));
3025
2966
  if (expectedRepo === undefined) {
@@ -3047,9 +2988,9 @@ async function sync$1({ reporter, github, cals, rootdir, askClone, askMove, }) {
3047
2988
  for (const it of archivedRepos) {
3048
2989
  reporter.info(` ${it.actualRelpath}`);
3049
2990
  }
3050
- const thisDirName = path__default["default"].basename(process.cwd());
2991
+ const thisDirName = path.basename(process.cwd());
3051
2992
  const archiveDir = `../${thisDirName}-archive`;
3052
- const hasArchiveDir = fs__default["default"].existsSync(archiveDir);
2993
+ const hasArchiveDir = fs.existsSync(archiveDir);
3053
2994
  if (hasArchiveDir) {
3054
2995
  reporter.info("To move these:");
3055
2996
  for (const it of archivedRepos) {
@@ -3072,17 +3013,17 @@ async function sync$1({ reporter, github, cals, rootdir, askClone, askMove, }) {
3072
3013
  const shouldMove = await askMoveConfirm();
3073
3014
  if (shouldMove) {
3074
3015
  for (const it of movedRepos) {
3075
- const src = path__default["default"].join(rootdir, it.actualRelpath);
3076
- const dest = path__default["default"].join(rootdir, getRelpath(it));
3077
- const destParent = path__default["default"].join(rootdir, it.group);
3078
- if (fs__default["default"].existsSync(dest)) {
3016
+ const src = path.join(rootdir, it.actualRelpath);
3017
+ const dest = path.join(rootdir, getRelpath(it));
3018
+ const destParent = path.join(rootdir, it.group);
3019
+ if (fs.existsSync(dest)) {
3079
3020
  throw new Error(`Target directory already exists: ${dest} - cannot move ${it.actualRelpath}`);
3080
3021
  }
3081
3022
  reporter.info(`Moving ${it.actualRelpath} -> ${getRelpath(it)}`);
3082
- if (!fs__default["default"].existsSync(destParent)) {
3083
- await fs__default["default"].promises.mkdir(destParent, { recursive: true });
3023
+ if (!fs.existsSync(destParent)) {
3024
+ await fs.promises.mkdir(destParent, { recursive: true });
3084
3025
  }
3085
- await fs__default["default"].promises.rename(src, dest);
3026
+ await fs.promises.rename(src, dest);
3086
3027
  }
3087
3028
  // We would have to update expectedRepos if we want to continue.
3088
3029
  // Let's try keeping this simple.
@@ -3115,7 +3056,7 @@ async function sync$1({ reporter, github, cals, rootdir, askClone, askMove, }) {
3115
3056
  }
3116
3057
  const reposToUpdate = foundRepos.filter((it) =>
3117
3058
  // Avoid double-processing the defintion repo.
3118
- (definitionRepo === null || definitionRepo === void 0 ? void 0 : definitionRepo.id) !== it.id);
3059
+ definitionRepo?.id !== it.id);
3119
3060
  reporter.info(`${reposToUpdate.length} repos identified to be updated`);
3120
3061
  await updateRepos(reporter, reposToUpdate);
3121
3062
  // Report repos with changes ahead.
@@ -3126,7 +3067,7 @@ async function sync$1({ reporter, github, cals, rootdir, askClone, askMove, }) {
3126
3067
  }
3127
3068
  }
3128
3069
  async function loadCalsManifest(config, reporter) {
3129
- const p = await findUp__default["default"](CALS_YAML, { cwd: config.cwd });
3070
+ const p = await findUp(CALS_YAML, { cwd: config.cwd });
3130
3071
  if (p === undefined) {
3131
3072
  reporter.error(`File ${CALS_YAML} not found. See help`);
3132
3073
  process.exitCode = 1;
@@ -3135,12 +3076,12 @@ async function loadCalsManifest(config, reporter) {
3135
3076
  // TODO: Verify file has expected contents.
3136
3077
  // (Can we easily generate schema for type and verify?)
3137
3078
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-explicit-any
3138
- const cals = yaml__default["default"].load(fs__default["default"].readFileSync(p, "utf-8"));
3079
+ const cals = yaml.load(fs.readFileSync(p, "utf-8"));
3139
3080
  if (cals.version !== 2) {
3140
3081
  throw new Error(`Unexpected version in ${p}`);
3141
3082
  }
3142
3083
  return {
3143
- dir: path__default["default"].dirname(p),
3084
+ dir: path.dirname(p),
3144
3085
  cals,
3145
3086
  };
3146
3087
  }
@@ -3245,23 +3186,21 @@ Notes:
3245
3186
  option to avoid stale cache. The cache can also be cleared with
3246
3187
  the "cals delete-cache" command.`),
3247
3188
  handler: () => {
3248
- yargs__default["default"].showHelp();
3189
+ yargs(hideBin(process.argv)).showHelp();
3249
3190
  },
3250
3191
  };
3251
3192
 
3252
3193
  function totalSeverityCount(project) {
3253
- var _a;
3254
- return (((_a = project.issueCountsBySeverity.critical) !== null && _a !== void 0 ? _a : 0) +
3194
+ return ((project.issueCountsBySeverity.critical ?? 0) +
3255
3195
  project.issueCountsBySeverity.high +
3256
3196
  project.issueCountsBySeverity.medium +
3257
3197
  project.issueCountsBySeverity.low);
3258
3198
  }
3259
3199
  function buildStatsLine(stats) {
3260
- var _a;
3261
3200
  function item(num, str) {
3262
- return num === 0 ? lodash.repeat(" ", str.length + 4) : sprintfJs.sprintf("%3d %s", num, str);
3201
+ return num === 0 ? repeat(" ", str.length + 4) : sprintf("%3d %s", num, str);
3263
3202
  }
3264
- return sprintfJs.sprintf("%s %s %s %s", item((_a = stats.critical) !== null && _a !== void 0 ? _a : 0, "critical"), item(stats.high, "high"), item(stats.medium, "medium"), item(stats.low, "low"));
3203
+ return sprintf("%s %s %s %s", item(stats.critical ?? 0, "critical"), item(stats.high, "high"), item(stats.medium, "medium"), item(stats.low, "low"));
3265
3204
  }
3266
3205
  async function report({ reporter, snyk, definitionFile, }) {
3267
3206
  const definition = await definitionFile.getDefinition();
@@ -3279,30 +3218,30 @@ async function report({ reporter, snyk, definitionFile, }) {
3279
3218
  function getProjectName(project) {
3280
3219
  return project ? project.name : "unknown project";
3281
3220
  }
3282
- const byProjects = lodash.sortBy(Object.values(lodash.groupBy(enhancedRepos, (it) => it.project ? it.project.name : "unknown")), (it) => getProjectName(it[0].project));
3221
+ const byProjects = sortBy(Object.values(groupBy(enhancedRepos, (it) => it.project ? it.project.name : "unknown")), (it) => getProjectName(it[0].project));
3283
3222
  if (byProjects.length === 0) {
3284
3223
  reporter.info("No issues found");
3285
3224
  }
3286
3225
  else {
3287
- reporter.info(sprintfJs.sprintf("%-70s %s", "Total count", buildStatsLine({
3288
- critical: lodash.sumBy(reposWithIssues, (it) => { var _a; return (_a = it.issueCountsBySeverity.critical) !== null && _a !== void 0 ? _a : 0; }),
3289
- high: lodash.sumBy(reposWithIssues, (it) => it.issueCountsBySeverity.high),
3290
- medium: lodash.sumBy(reposWithIssues, (it) => it.issueCountsBySeverity.medium),
3291
- low: lodash.sumBy(reposWithIssues, (it) => it.issueCountsBySeverity.low),
3226
+ reporter.info(sprintf("%-70s %s", "Total count", buildStatsLine({
3227
+ critical: sumBy(reposWithIssues, (it) => it.issueCountsBySeverity.critical ?? 0),
3228
+ high: sumBy(reposWithIssues, (it) => it.issueCountsBySeverity.high),
3229
+ medium: sumBy(reposWithIssues, (it) => it.issueCountsBySeverity.medium),
3230
+ low: sumBy(reposWithIssues, (it) => it.issueCountsBySeverity.low),
3292
3231
  })));
3293
3232
  reporter.info("Issues by project:");
3294
3233
  byProjects.forEach((repos) => {
3295
3234
  const project = repos[0].project;
3296
3235
  const totalCount = {
3297
- critical: lodash.sumBy(repos, (it) => { var _a; return (_a = it.repo.issueCountsBySeverity.critical) !== null && _a !== void 0 ? _a : 0; }),
3298
- high: lodash.sumBy(repos, (it) => it.repo.issueCountsBySeverity.high),
3299
- medium: lodash.sumBy(repos, (it) => it.repo.issueCountsBySeverity.medium),
3300
- low: lodash.sumBy(repos, (it) => it.repo.issueCountsBySeverity.low),
3236
+ critical: sumBy(repos, (it) => it.repo.issueCountsBySeverity.critical ?? 0),
3237
+ high: sumBy(repos, (it) => it.repo.issueCountsBySeverity.high),
3238
+ medium: sumBy(repos, (it) => it.repo.issueCountsBySeverity.medium),
3239
+ low: sumBy(repos, (it) => it.repo.issueCountsBySeverity.low),
3301
3240
  };
3302
3241
  reporter.info("");
3303
- reporter.info(sprintfJs.sprintf("%-70s %s", getProjectName(project), buildStatsLine(totalCount)));
3242
+ reporter.info(sprintf("%-70s %s", getProjectName(project), buildStatsLine(totalCount)));
3304
3243
  for (const { repo } of repos) {
3305
- reporter.info(sprintfJs.sprintf(" %-68s %s", repo.name, buildStatsLine(repo.issueCountsBySeverity)));
3244
+ reporter.info(sprintf(" %-68s %s", repo.name, buildStatsLine(repo.issueCountsBySeverity)));
3306
3245
  }
3307
3246
  });
3308
3247
  }
@@ -3323,11 +3262,12 @@ async function setToken({ reporter, token, tokenProvider, }) {
3323
3262
  reporter.info("Need API token to talk to Snyk");
3324
3263
  reporter.info("See https://app.snyk.io/account");
3325
3264
  token = await new Promise((resolve, reject) => {
3326
- read__default["default"]({
3265
+ read({
3327
3266
  prompt: "Enter new Snyk API token: ",
3328
3267
  silent: true,
3329
3268
  }, (err, answer) => {
3330
3269
  if (err) {
3270
+ // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
3331
3271
  reject(err);
3332
3272
  }
3333
3273
  resolve(answer);
@@ -3394,30 +3334,17 @@ Notes:
3394
3334
  and provide a link to generate one:
3395
3335
  $ cals snyk set-token`),
3396
3336
  handler: () => {
3397
- yargs__default["default"].showHelp();
3337
+ yargs(hideBin(process.argv)).showHelp();
3398
3338
  },
3399
3339
  };
3400
3340
 
3401
3341
  async function main() {
3402
- if (!semver__default["default"].satisfies(process.version, engines.node)) {
3342
+ if (!semver.satisfies(process.version, engines.node)) {
3403
3343
  console.error(`Required node version ${engines.node} not satisfied with current version ${process.version}.`);
3404
3344
  process.exit(1);
3405
3345
  }
3406
- // http://patorjk.com/software/taag/#p=display&f=Slant&t=CALS
3407
- const header = `
3408
- _________ __ _____
3409
- / ____/ | / / / ___/
3410
- / / / /| | / / \\__ \\
3411
- / /___/ ___ |/ /______/ /
3412
- \\____/_/ |_/_____/____/
3413
- cli ${version}
3414
- built ${"2024-11-30T21:41:56+0000"}
3415
-
3416
- https://github.com/capralifecycle/cals-cli/
3417
-
3418
- Usage: cals <command>`;
3419
- await yargs__default["default"]
3420
- .usage(header)
3346
+ await yargs(hideBin(process.argv))
3347
+ .usage(`cals-cli v${version} (build: ${"2024-12-11T13:09:43+0000"})`)
3421
3348
  .scriptName("cals")
3422
3349
  .locale("en")
3423
3350
  .help("help")
@@ -3442,12 +3369,6 @@ Usage: cals <command>`;
3442
3369
  })
3443
3370
  .parse();
3444
3371
  }
3445
- // Definer prosjekt-navn
3446
- // Definer ønskede miljøer
3447
- // Baselines som skal brukse
3448
- // Er bruker logget inn?
3449
- // Lag repo og endre commit
3450
- // Osv. osv. osv.
3451
3372
 
3452
3373
  void main();
3453
- //# sourceMappingURL=cals-cli.js.map
3374
+ //# sourceMappingURL=cals-cli.mjs.map