@capraconsulting/cals-cli 3.11.4 → 3.12.1

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 (43) hide show
  1. package/lib/cache.d.ts +1 -1
  2. package/lib/cals-cli.mjs +84 -105
  3. package/lib/cals-cli.mjs.map +1 -1
  4. package/lib/cli/commands/definition/dump-setup.d.ts +1 -1
  5. package/lib/cli/commands/definition/validate.d.ts +1 -1
  6. package/lib/cli/commands/definition.d.ts +1 -1
  7. package/lib/cli/commands/delete-cache.d.ts +1 -1
  8. package/lib/cli/commands/getting-started.d.ts +1 -1
  9. package/lib/cli/commands/github/analyze-directory.d.ts +1 -1
  10. package/lib/cli/commands/github/configure.d.ts +1 -1
  11. package/lib/cli/commands/github/generate-clone-commands.d.ts +1 -1
  12. package/lib/cli/commands/github/list-pull-requests-stats.d.ts +1 -1
  13. package/lib/cli/commands/github/list-repos.d.ts +1 -1
  14. package/lib/cli/commands/github/list-webhooks.d.ts +1 -1
  15. package/lib/cli/commands/github/set-token.d.ts +1 -1
  16. package/lib/cli/commands/github/sync.d.ts +2 -2
  17. package/lib/cli/commands/github/util.d.ts +2 -2
  18. package/lib/cli/commands/github.d.ts +1 -1
  19. package/lib/cli/commands/snyk/report.d.ts +1 -1
  20. package/lib/cli/commands/snyk/set-token.d.ts +1 -1
  21. package/lib/cli/commands/snyk/sync.d.ts +1 -1
  22. package/lib/cli/commands/snyk.d.ts +1 -1
  23. package/lib/cli/util.d.ts +1 -1
  24. package/lib/config.d.ts +1 -1
  25. package/lib/definition/definition.d.ts +1 -1
  26. package/lib/definition/types.d.ts +1 -1
  27. package/lib/github/changeset/changeset.d.ts +4 -4
  28. package/lib/github/changeset/execute.d.ts +3 -3
  29. package/lib/github/changeset/types.d.ts +1 -1
  30. package/lib/github/index.d.ts +1 -1
  31. package/lib/github/service.d.ts +4 -4
  32. package/lib/github/types.d.ts +1 -1
  33. package/lib/github/util.d.ts +1 -1
  34. package/lib/index.es.js +32 -51
  35. package/lib/index.es.js.map +1 -1
  36. package/lib/index.js +32 -51
  37. package/lib/index.js.map +1 -1
  38. package/lib/snyk/service.d.ts +4 -4
  39. package/lib/snyk/util.d.ts +1 -1
  40. package/lib/sonarcloud/index.d.ts +1 -1
  41. package/lib/sonarcloud/service.d.ts +2 -2
  42. package/lib/testing/lib.d.ts +1 -1
  43. package/package.json +16 -23
package/lib/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import https from "https";
1
+ import https from "node:https";
2
2
  export declare class Config {
3
3
  cwd: string;
4
4
  configFile: string;
@@ -1,5 +1,5 @@
1
1
  import schema from "../definition-schema.json";
2
- import { Definition, GetReposResponse } from "./types";
2
+ import type { Definition, GetReposResponse } from "./types";
3
3
  export { schema };
4
4
  export declare function getRepoId(orgName: string, repoName: string): string;
5
5
  export declare class DefinitionFile {
@@ -1,4 +1,4 @@
1
- import { Permission } from "../github/types";
1
+ import type { Permission } from "../github/types";
2
2
  export interface Definition {
3
3
  snyk?: {
4
4
  accountId: string;
@@ -1,7 +1,7 @@
1
- import { Definition } from "../../definition/types";
2
- import { GitHubService } from "../service";
3
- import { OrgsGetResponse } from "../types";
4
- import { ChangeSetItem } from "./types";
1
+ import type { Definition } from "../../definition/types";
2
+ import type { GitHubService } from "../service";
3
+ import type { OrgsGetResponse } from "../types";
4
+ import type { ChangeSetItem } from "./types";
5
5
  /**
6
6
  * Generate change set items for projects.
7
7
  */
@@ -1,6 +1,6 @@
1
- import { Reporter } from "../../cli/reporter";
2
- import { GitHubService } from "../service";
3
- import { ChangeSetItem, RepoCreateItem } from "./types";
1
+ import type { Reporter } from "../../cli/reporter";
2
+ import type { GitHubService } from "../service";
3
+ import type { ChangeSetItem, RepoCreateItem } from "./types";
4
4
  type NotImplementedChangeSetItem = RepoCreateItem;
5
5
  export declare function isNotImplementedChangeSetItem(changeItem: ChangeSetItem): changeItem is NotImplementedChangeSetItem;
6
6
  /**
@@ -1,4 +1,4 @@
1
- import { Permission } from "../types";
1
+ import type { Permission } from "../types";
2
2
  export interface RepoCreateItem {
3
3
  type: "repo-create";
4
4
  org: string;
@@ -1,3 +1,3 @@
1
- export { createGitHubService, GitHubService } from "./service";
2
1
  export type { SearchedPullRequestListItem } from "./service";
2
+ export { createGitHubService, GitHubService } from "./service";
3
3
  export type { RenovateDependencyDashboardIssue, VulnerabilityAlert, } from "./types";
@@ -1,8 +1,8 @@
1
1
  import { Octokit } from "@octokit/rest";
2
- import { CacheProvider } from "../cache";
3
- import { Config } from "../config";
4
- import { GitHubTokenProvider } from "./token";
5
- import { OrgMemberOrInvited, OrgsGetResponse, OrgsListMembersResponseItem, OrgsListPendingInvitationsResponseItem, RenovateDependencyDashboardIssue, Repo, ReposGetResponse, ReposListHooksResponseItem, ReposListTeamsResponseItem, TeamMemberOrInvited, TeamsListMembersResponseItem, TeamsListPendingInvitationsResponseItem, TeamsListResponseItem, VulnerabilityAlert } from "./types";
2
+ import type { CacheProvider } from "../cache";
3
+ import type { Config } from "../config";
4
+ import { type GitHubTokenProvider } from "./token";
5
+ import type { OrgMemberOrInvited, OrgsGetResponse, OrgsListMembersResponseItem, OrgsListPendingInvitationsResponseItem, RenovateDependencyDashboardIssue, Repo, ReposGetResponse, ReposListHooksResponseItem, ReposListTeamsResponseItem, TeamMemberOrInvited, TeamsListMembersResponseItem, TeamsListPendingInvitationsResponseItem, TeamsListResponseItem, VulnerabilityAlert } from "./types";
6
6
  interface SearchedPullRequestListQueryResult {
7
7
  search: {
8
8
  pageInfo: {
@@ -1,4 +1,4 @@
1
- import { Endpoints } from "@octokit/types";
1
+ import type { Endpoints } from "@octokit/types";
2
2
  export type OrgsGetResponse = Endpoints["GET /orgs/{org}"]["response"]["data"];
3
3
  export type OrgsListMembersResponseItem = Exclude<Endpoints["GET /orgs/{org}/members"]["response"]["data"][0], null>;
4
4
  export type OrgsListPendingInvitationsResponseItem = Endpoints["GET /orgs/{org}/invitations"]["response"]["data"][0];
@@ -1,4 +1,4 @@
1
- import { Repo } from "./types";
1
+ import type { Repo } from "./types";
2
2
  export declare function getGroup(repo: Repo): string | null;
3
3
  export declare function getGroupedRepos(repos: Repo[]): {
4
4
  name: string;
package/lib/index.es.js CHANGED
@@ -1,27 +1,27 @@
1
1
  import fs from 'node:fs';
2
- import path from 'path';
3
- import chalk from 'chalk';
4
- import readline from 'readline';
2
+ import path from 'node:path';
5
3
  import process$1 from 'node:process';
6
- import 'util';
4
+ import readline from 'node:readline';
5
+ import chalk from 'chalk';
6
+ import 'node:util';
7
+ import https from 'node:https';
8
+ import os from 'node:os';
7
9
  import cachedir from 'cachedir';
8
- import https from 'https';
9
- import os from 'os';
10
10
  import AJV from 'ajv';
11
11
  import yaml from 'js-yaml';
12
+ import { Buffer } from 'node:buffer';
13
+ import { performance } from 'node:perf_hooks';
12
14
  import { Octokit } from '@octokit/rest';
13
15
  import fetch from 'node-fetch';
14
16
  import pLimit from 'p-limit';
15
- import keytar from 'keytar';
16
17
  import * as process from 'process';
17
- import { performance } from 'perf_hooks';
18
- import { Buffer } from 'node:buffer';
19
- import { strict } from 'assert';
18
+ import keytar from 'keytar';
19
+ import { strict } from 'node:assert';
20
+ import { Transform } from 'node:stream';
20
21
  import { execa } from 'execa';
21
22
  import { read } from 'read';
22
- import { Transform } from 'stream';
23
23
 
24
- var version = "3.11.4";
24
+ var version = "3.12.1";
25
25
 
26
26
  class CacheProvider {
27
27
  constructor(config) {
@@ -60,7 +60,7 @@ class CacheProvider {
60
60
  const cacheItem = this.mustValidate
61
61
  ? undefined
62
62
  : this.retrieveJson(cachekey);
63
- const expire = new Date(new Date().getTime() - cachetime * 1000).getTime();
63
+ const expire = new Date(Date.now() - cachetime * 1000).getTime();
64
64
  if (cacheItem !== undefined && cacheItem.cacheTime > expire) {
65
65
  return cacheItem.data;
66
66
  }
@@ -131,7 +131,6 @@ class Config {
131
131
  return {};
132
132
  }
133
133
  try {
134
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
135
134
  return JSON.parse(fs.readFileSync(this.configFile, "utf-8"));
136
135
  }
137
136
  catch (e) {
@@ -159,6 +158,10 @@ class Config {
159
158
  }
160
159
  }
161
160
 
161
+ function uniq(array) {
162
+ return Array.from(new Set(array));
163
+ }
164
+
162
165
  var type = "object";
163
166
  var properties = {
164
167
  snyk: {
@@ -453,10 +456,6 @@ var schema = {
453
456
  $schema: $schema
454
457
  };
455
458
 
456
- function uniq(array) {
457
- return Array.from(new Set(array));
458
- }
459
-
460
459
  function getTeamId(org, teamName) {
461
460
  return `${org}/${teamName}`;
462
461
  }
@@ -490,8 +489,7 @@ function requireValidDefinition(definition) {
490
489
  }, []);
491
490
  // Verify team members exists as users.
492
491
  definition.github.teams
493
- .map((it) => it.teams)
494
- .flat()
492
+ .flatMap((it) => it.teams)
495
493
  .forEach((team) => {
496
494
  team.members.forEach((login) => {
497
495
  if (!loginList.includes(login)) {
@@ -527,9 +525,7 @@ function requireValidDefinition(definition) {
527
525
  });
528
526
  // Verify no duplicates in repos.
529
527
  definition.projects
530
- .flatMap((project) => project.github
531
- .map((org) => (org.repos || []).map((repo) => getRepoId(org.organization, repo.name)))
532
- .flat())
528
+ .flatMap((project) => project.github.flatMap((org) => (org.repos || []).map((repo) => getRepoId(org.organization, repo.name))))
533
529
  .reduce((acc, repoName) => {
534
530
  if (acc.includes(repoName)) {
535
531
  throw new Error(`Duplicate repo: ${repoName}`);
@@ -557,20 +553,18 @@ class DefinitionFile {
557
553
  function parseDefinition(value) {
558
554
  const result = checkAgainstSchema(yaml.load(value));
559
555
  if ("error" in result) {
560
- throw new Error("Definition content invalid: " + result.error);
556
+ throw new Error(`Definition content invalid: ${result.error}`);
561
557
  }
562
558
  requireValidDefinition(result.definition);
563
559
  return result.definition;
564
560
  }
565
561
  function getRepos(definition) {
566
- return definition.projects.flatMap((project) => project.github
567
- .map((org) => (org.repos || []).map((repo) => ({
562
+ return definition.projects.flatMap((project) => project.github.flatMap((org) => (org.repos || []).map((repo) => ({
568
563
  id: getRepoId(org.organization, repo.name),
569
564
  orgName: org.organization,
570
565
  project,
571
566
  repo,
572
- })))
573
- .flat());
567
+ }))));
574
568
  }
575
569
  function getGitHubOrgs(definition) {
576
570
  const githubOrganizations = definition.projects.flatMap((project) => project.github.map((it) => it.organization));
@@ -620,13 +614,10 @@ async function undefinedForNotFound(value) {
620
614
  return await value;
621
615
  }
622
616
  catch (e) {
623
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
624
617
  if (e.name === "HttpError" && e.status === 404) {
625
618
  return undefined;
626
619
  }
627
- else {
628
- throw e;
629
- }
620
+ throw e;
630
621
  }
631
622
  }
632
623
 
@@ -645,17 +636,14 @@ class GitHubService {
645
636
  // can maximize concurrency all other places.
646
637
  this.semaphore = pLimit(6);
647
638
  this.octokit.hook.wrap("request", async (request, options) => {
648
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
649
639
  this._requestCount++;
650
640
  if (options.method !== "GET") {
651
641
  return this.semaphore(() => request(options));
652
642
  }
653
643
  // Try to cache ETag for GET requests to save on rate limiting.
654
644
  // Hits on ETag does not count towards rate limiting.
655
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
656
645
  const rest = {
657
646
  ...options,
658
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
659
647
  };
660
648
  delete rest.method;
661
649
  delete rest.baseUrl;
@@ -706,7 +694,6 @@ class GitHubService {
706
694
  });
707
695
  }
708
696
  return response;
709
- /* eslint-enable @typescript-eslint/no-unsafe-member-access */
710
697
  });
711
698
  }
712
699
  _requestCount = 0;
@@ -746,11 +733,11 @@ class GitHubService {
746
733
  throw new Error(`Response from GitHub not OK (${response.status}): ${await response.text()}`);
747
734
  }
748
735
  const json = (await response.json());
749
- if (!!json.errors) {
736
+ if (json.errors) {
750
737
  throw new Error(`Error from GitHub GraphQL API: ${JSON.stringify(json.errors)}`);
751
738
  }
752
739
  if (json.data == null) {
753
- throw new Error(`No data received from GitHub GraphQL API (unknown reason)`);
740
+ throw new Error("No data received from GitHub GraphQL API (unknown reason)");
754
741
  }
755
742
  return json.data;
756
743
  }
@@ -983,7 +970,6 @@ class GitHubService {
983
970
  return true;
984
971
  }
985
972
  catch (e) {
986
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
987
973
  if (e.status === 404) {
988
974
  return false;
989
975
  }
@@ -1257,8 +1243,7 @@ function getGitHubRepo(snykProject) {
1257
1243
  name: match[2],
1258
1244
  };
1259
1245
  }
1260
- else if (snykProject.origin === "cli" &&
1261
- snykProject.remoteRepoUrl != null) {
1246
+ if (snykProject.origin === "cli" && snykProject.remoteRepoUrl != null) {
1262
1247
  // The remoteRepoUrl can be overridden when using the CLI, so don't
1263
1248
  // fail if we cannot extract the value.
1264
1249
  const match = /github.com\/([^/]+)\/(.+)\.git$/.exec(snykProject.remoteRepoUrl);
@@ -1270,9 +1255,7 @@ function getGitHubRepo(snykProject) {
1270
1255
  name: match[2],
1271
1256
  };
1272
1257
  }
1273
- else {
1274
- return undefined;
1275
- }
1258
+ return undefined;
1276
1259
  }
1277
1260
  function getGitHubRepoId(repo) {
1278
1261
  return repo ? `${repo.owner}/${repo.name}` : undefined;
@@ -1424,12 +1407,11 @@ class TestExecutor {
1424
1407
  await body(this);
1425
1408
  }
1426
1409
  catch (error) {
1427
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1428
1410
  console.error(error.stack || error.message || error);
1429
1411
  process$1.exitCode = 1;
1430
1412
  }
1431
1413
  finally {
1432
- console.log(`Reached finally block`);
1414
+ console.log("Reached finally block");
1433
1415
  this.usingWithCleanupTasks = false;
1434
1416
  if (this.cleanupTask == null) {
1435
1417
  this.cleanupTask = this.runTasks();
@@ -1448,8 +1430,8 @@ function createTestExecutor() {
1448
1430
  * Gives a value formatted as "yyyymmdd-xxxxxx", e.g. "20200523-3f2c87".
1449
1431
  */
1450
1432
  function generateRunId() {
1451
- const low = parseInt("100000", 16);
1452
- const high = parseInt("ffffff", 16);
1433
+ const low = 0x100000;
1434
+ const high = 0xffffff;
1453
1435
  const range = high - low + 1;
1454
1436
  const now = new Date();
1455
1437
  return [
@@ -1610,7 +1592,7 @@ class OutputPrefixTransform extends Transform {
1610
1592
  if (result.endsWith("\n\u001B[0m")) {
1611
1593
  result = result.slice(0, -5) + result.slice(-4);
1612
1594
  }
1613
- result = prefix + result.replace(/\n/g, `\n${prefix}`) + "\n";
1595
+ result = `${prefix + result.replace(/\n/g, `\n${prefix}`)}\n`;
1614
1596
  callback(null, result);
1615
1597
  },
1616
1598
  });
@@ -1739,12 +1721,11 @@ async function startContainer({ executor, network, imageId, alias, env, dockerAr
1739
1721
  executor.registerCleanupTask(async () => {
1740
1722
  console.log(`Stopping container ${containerName}`);
1741
1723
  const r = execa("docker", ["stop", containerName]);
1742
- pipeToConsole(r, (alias ?? containerName) + " (stop)");
1724
+ pipeToConsole(r, `${alias ?? containerName} (stop)`);
1743
1725
  try {
1744
1726
  await r;
1745
1727
  }
1746
1728
  catch (e) {
1747
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
1748
1729
  if (!(e.stderr || "").includes("No such container")) {
1749
1730
  throw e;
1750
1731
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/lib/index.js CHANGED
@@ -1,27 +1,27 @@
1
1
  import fs from 'node:fs';
2
- import path from 'path';
3
- import chalk from 'chalk';
4
- import readline from 'readline';
2
+ import path from 'node:path';
5
3
  import process$1 from 'node:process';
6
- import 'util';
4
+ import readline from 'node:readline';
5
+ import chalk from 'chalk';
6
+ import 'node:util';
7
+ import https from 'node:https';
8
+ import os from 'node:os';
7
9
  import cachedir from 'cachedir';
8
- import https from 'https';
9
- import os from 'os';
10
10
  import AJV from 'ajv';
11
11
  import yaml from 'js-yaml';
12
+ import { Buffer } from 'node:buffer';
13
+ import { performance } from 'node:perf_hooks';
12
14
  import { Octokit } from '@octokit/rest';
13
15
  import fetch from 'node-fetch';
14
16
  import pLimit from 'p-limit';
15
- import keytar from 'keytar';
16
17
  import * as process from 'process';
17
- import { performance } from 'perf_hooks';
18
- import { Buffer } from 'node:buffer';
19
- import { strict } from 'assert';
18
+ import keytar from 'keytar';
19
+ import { strict } from 'node:assert';
20
+ import { Transform } from 'node:stream';
20
21
  import { execa } from 'execa';
21
22
  import { read } from 'read';
22
- import { Transform } from 'stream';
23
23
 
24
- var version = "3.11.4";
24
+ var version = "3.12.1";
25
25
 
26
26
  class CacheProvider {
27
27
  constructor(config) {
@@ -60,7 +60,7 @@ class CacheProvider {
60
60
  const cacheItem = this.mustValidate
61
61
  ? undefined
62
62
  : this.retrieveJson(cachekey);
63
- const expire = new Date(new Date().getTime() - cachetime * 1000).getTime();
63
+ const expire = new Date(Date.now() - cachetime * 1000).getTime();
64
64
  if (cacheItem !== undefined && cacheItem.cacheTime > expire) {
65
65
  return cacheItem.data;
66
66
  }
@@ -131,7 +131,6 @@ class Config {
131
131
  return {};
132
132
  }
133
133
  try {
134
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
135
134
  return JSON.parse(fs.readFileSync(this.configFile, "utf-8"));
136
135
  }
137
136
  catch (e) {
@@ -159,6 +158,10 @@ class Config {
159
158
  }
160
159
  }
161
160
 
161
+ function uniq(array) {
162
+ return Array.from(new Set(array));
163
+ }
164
+
162
165
  var type = "object";
163
166
  var properties = {
164
167
  snyk: {
@@ -453,10 +456,6 @@ var schema = {
453
456
  $schema: $schema
454
457
  };
455
458
 
456
- function uniq(array) {
457
- return Array.from(new Set(array));
458
- }
459
-
460
459
  function getTeamId(org, teamName) {
461
460
  return `${org}/${teamName}`;
462
461
  }
@@ -490,8 +489,7 @@ function requireValidDefinition(definition) {
490
489
  }, []);
491
490
  // Verify team members exists as users.
492
491
  definition.github.teams
493
- .map((it) => it.teams)
494
- .flat()
492
+ .flatMap((it) => it.teams)
495
493
  .forEach((team) => {
496
494
  team.members.forEach((login) => {
497
495
  if (!loginList.includes(login)) {
@@ -527,9 +525,7 @@ function requireValidDefinition(definition) {
527
525
  });
528
526
  // Verify no duplicates in repos.
529
527
  definition.projects
530
- .flatMap((project) => project.github
531
- .map((org) => (org.repos || []).map((repo) => getRepoId(org.organization, repo.name)))
532
- .flat())
528
+ .flatMap((project) => project.github.flatMap((org) => (org.repos || []).map((repo) => getRepoId(org.organization, repo.name))))
533
529
  .reduce((acc, repoName) => {
534
530
  if (acc.includes(repoName)) {
535
531
  throw new Error(`Duplicate repo: ${repoName}`);
@@ -557,20 +553,18 @@ class DefinitionFile {
557
553
  function parseDefinition(value) {
558
554
  const result = checkAgainstSchema(yaml.load(value));
559
555
  if ("error" in result) {
560
- throw new Error("Definition content invalid: " + result.error);
556
+ throw new Error(`Definition content invalid: ${result.error}`);
561
557
  }
562
558
  requireValidDefinition(result.definition);
563
559
  return result.definition;
564
560
  }
565
561
  function getRepos(definition) {
566
- return definition.projects.flatMap((project) => project.github
567
- .map((org) => (org.repos || []).map((repo) => ({
562
+ return definition.projects.flatMap((project) => project.github.flatMap((org) => (org.repos || []).map((repo) => ({
568
563
  id: getRepoId(org.organization, repo.name),
569
564
  orgName: org.organization,
570
565
  project,
571
566
  repo,
572
- })))
573
- .flat());
567
+ }))));
574
568
  }
575
569
  function getGitHubOrgs(definition) {
576
570
  const githubOrganizations = definition.projects.flatMap((project) => project.github.map((it) => it.organization));
@@ -620,13 +614,10 @@ async function undefinedForNotFound(value) {
620
614
  return await value;
621
615
  }
622
616
  catch (e) {
623
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
624
617
  if (e.name === "HttpError" && e.status === 404) {
625
618
  return undefined;
626
619
  }
627
- else {
628
- throw e;
629
- }
620
+ throw e;
630
621
  }
631
622
  }
632
623
 
@@ -645,17 +636,14 @@ class GitHubService {
645
636
  // can maximize concurrency all other places.
646
637
  this.semaphore = pLimit(6);
647
638
  this.octokit.hook.wrap("request", async (request, options) => {
648
- /* eslint-disable @typescript-eslint/no-unsafe-member-access */
649
639
  this._requestCount++;
650
640
  if (options.method !== "GET") {
651
641
  return this.semaphore(() => request(options));
652
642
  }
653
643
  // Try to cache ETag for GET requests to save on rate limiting.
654
644
  // Hits on ETag does not count towards rate limiting.
655
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
656
645
  const rest = {
657
646
  ...options,
658
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
659
647
  };
660
648
  delete rest.method;
661
649
  delete rest.baseUrl;
@@ -706,7 +694,6 @@ class GitHubService {
706
694
  });
707
695
  }
708
696
  return response;
709
- /* eslint-enable @typescript-eslint/no-unsafe-member-access */
710
697
  });
711
698
  }
712
699
  _requestCount = 0;
@@ -746,11 +733,11 @@ class GitHubService {
746
733
  throw new Error(`Response from GitHub not OK (${response.status}): ${await response.text()}`);
747
734
  }
748
735
  const json = (await response.json());
749
- if (!!json.errors) {
736
+ if (json.errors) {
750
737
  throw new Error(`Error from GitHub GraphQL API: ${JSON.stringify(json.errors)}`);
751
738
  }
752
739
  if (json.data == null) {
753
- throw new Error(`No data received from GitHub GraphQL API (unknown reason)`);
740
+ throw new Error("No data received from GitHub GraphQL API (unknown reason)");
754
741
  }
755
742
  return json.data;
756
743
  }
@@ -983,7 +970,6 @@ class GitHubService {
983
970
  return true;
984
971
  }
985
972
  catch (e) {
986
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
987
973
  if (e.status === 404) {
988
974
  return false;
989
975
  }
@@ -1257,8 +1243,7 @@ function getGitHubRepo(snykProject) {
1257
1243
  name: match[2],
1258
1244
  };
1259
1245
  }
1260
- else if (snykProject.origin === "cli" &&
1261
- snykProject.remoteRepoUrl != null) {
1246
+ if (snykProject.origin === "cli" && snykProject.remoteRepoUrl != null) {
1262
1247
  // The remoteRepoUrl can be overridden when using the CLI, so don't
1263
1248
  // fail if we cannot extract the value.
1264
1249
  const match = /github.com\/([^/]+)\/(.+)\.git$/.exec(snykProject.remoteRepoUrl);
@@ -1270,9 +1255,7 @@ function getGitHubRepo(snykProject) {
1270
1255
  name: match[2],
1271
1256
  };
1272
1257
  }
1273
- else {
1274
- return undefined;
1275
- }
1258
+ return undefined;
1276
1259
  }
1277
1260
  function getGitHubRepoId(repo) {
1278
1261
  return repo ? `${repo.owner}/${repo.name}` : undefined;
@@ -1424,12 +1407,11 @@ class TestExecutor {
1424
1407
  await body(this);
1425
1408
  }
1426
1409
  catch (error) {
1427
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1428
1410
  console.error(error.stack || error.message || error);
1429
1411
  process$1.exitCode = 1;
1430
1412
  }
1431
1413
  finally {
1432
- console.log(`Reached finally block`);
1414
+ console.log("Reached finally block");
1433
1415
  this.usingWithCleanupTasks = false;
1434
1416
  if (this.cleanupTask == null) {
1435
1417
  this.cleanupTask = this.runTasks();
@@ -1448,8 +1430,8 @@ function createTestExecutor() {
1448
1430
  * Gives a value formatted as "yyyymmdd-xxxxxx", e.g. "20200523-3f2c87".
1449
1431
  */
1450
1432
  function generateRunId() {
1451
- const low = parseInt("100000", 16);
1452
- const high = parseInt("ffffff", 16);
1433
+ const low = 0x100000;
1434
+ const high = 0xffffff;
1453
1435
  const range = high - low + 1;
1454
1436
  const now = new Date();
1455
1437
  return [
@@ -1610,7 +1592,7 @@ class OutputPrefixTransform extends Transform {
1610
1592
  if (result.endsWith("\n\u001B[0m")) {
1611
1593
  result = result.slice(0, -5) + result.slice(-4);
1612
1594
  }
1613
- result = prefix + result.replace(/\n/g, `\n${prefix}`) + "\n";
1595
+ result = `${prefix + result.replace(/\n/g, `\n${prefix}`)}\n`;
1614
1596
  callback(null, result);
1615
1597
  },
1616
1598
  });
@@ -1739,12 +1721,11 @@ async function startContainer({ executor, network, imageId, alias, env, dockerAr
1739
1721
  executor.registerCleanupTask(async () => {
1740
1722
  console.log(`Stopping container ${containerName}`);
1741
1723
  const r = execa("docker", ["stop", containerName]);
1742
- pipeToConsole(r, (alias ?? containerName) + " (stop)");
1724
+ pipeToConsole(r, `${alias ?? containerName} (stop)`);
1743
1725
  try {
1744
1726
  await r;
1745
1727
  }
1746
1728
  catch (e) {
1747
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
1748
1729
  if (!(e.stderr || "").includes("No such container")) {
1749
1730
  throw e;
1750
1731
  }
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,7 +1,7 @@
1
- import { Config } from "../config";
2
- import { Definition } from "../definition";
3
- import { SnykTokenProvider } from "./token";
4
- import { SnykProject } from "./types";
1
+ import type { Config } from "../config";
2
+ import type { Definition } from "../definition";
3
+ import { type SnykTokenProvider } from "./token";
4
+ import type { SnykProject } from "./types";
5
5
  interface SnykServiceProps {
6
6
  config: Config;
7
7
  tokenProvider: SnykTokenProvider;
@@ -1,3 +1,3 @@
1
- import { SnykGitHubRepo, SnykProject } from "./types";
1
+ import type { SnykGitHubRepo, SnykProject } from "./types";
2
2
  export declare function getGitHubRepo(snykProject: SnykProject): SnykGitHubRepo | undefined;
3
3
  export declare function getGitHubRepoId(repo: SnykGitHubRepo | undefined): string | undefined;
@@ -1,3 +1,3 @@
1
1
  export { createSonarCloudService, SonarCloudService } from "./service";
2
- export { SonarCloudTokenCliProvider } from "./token";
3
2
  export type { SonarCloudTokenProvider } from "./token";
3
+ export { SonarCloudTokenCliProvider } from "./token";
@@ -1,5 +1,5 @@
1
- import { Config } from "../config";
2
- import { SonarCloudTokenProvider } from "./token";
1
+ import type { Config } from "../config";
2
+ import { type SonarCloudTokenProvider } from "./token";
3
3
  interface SonarCloudServiceProps {
4
4
  config: Config;
5
5
  tokenProvider: SonarCloudTokenProvider;
@@ -1,5 +1,5 @@
1
1
  import { type Subprocess } from "execa";
2
- import { TestExecutor } from "./executor";
2
+ import type { TestExecutor } from "./executor";
3
3
  export interface Container {
4
4
  id: string;
5
5
  name: string;