@infrascan/cli 0.4.0 → 0.5.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.
@@ -0,0 +1,64 @@
1
+ // src/commands/graph.ts
2
+ import { readFileSync, writeFileSync } from "fs";
3
+ import { join, resolve } from "path";
4
+ import {
5
+ CommandLineAction
6
+ } from "@rushstack/ts-command-line";
7
+ import buildFsConnector from "@infrascan/fs-connector";
8
+ import {
9
+ serializeGraph
10
+ } from "@infrascan/cytoscape-serializer";
11
+ function readScanMetadata(outputPath) {
12
+ const scanMetadata = readFileSync(
13
+ join(resolve(outputPath), "metadata.json"),
14
+ "utf8"
15
+ );
16
+ return JSON.parse(scanMetadata);
17
+ }
18
+ function writeGraphOutput(outputPath, graphState) {
19
+ writeFileSync(
20
+ join(resolve(outputPath), "graph.json"),
21
+ JSON.stringify(graphState)
22
+ );
23
+ }
24
+ var GraphCmd = class extends CommandLineAction {
25
+ constructor(infrascanClient) {
26
+ super({
27
+ actionName: "graph",
28
+ summary: "Graphs a set of AWS accounts which have been scanned",
29
+ documentation: "Reads in the output of an account scan, and generates an infrastructure diagram from the output. The graph is saved to the local filesystem."
30
+ });
31
+ this.infrascanClient = infrascanClient;
32
+ }
33
+ onDefineParameters() {
34
+ this._outputDirectory = this.defineStringParameter({
35
+ parameterLongName: "--input",
36
+ parameterShortName: "-i",
37
+ argumentName: "PATH_TO_STATE",
38
+ description: "Location to read scan state from. This should be the same as the directory given to the scan command.",
39
+ defaultValue: "./state"
40
+ });
41
+ }
42
+ async onExecute() {
43
+ const scanMetadata = readScanMetadata(
44
+ this._outputDirectory.value
45
+ );
46
+ const connector = buildFsConnector(this._outputDirectory.value);
47
+ let nServicesScanned = 0;
48
+ this.infrascanClient.registerPlugin({
49
+ event: "onServiceComplete",
50
+ id: "countServicesScanner",
51
+ handler: () => {
52
+ nServicesScanned += 1;
53
+ }
54
+ });
55
+ const graphData = await this.infrascanClient.generateGraph(scanMetadata, connector, serializeGraph);
56
+ console.log(
57
+ `Graph Complete. Found resources in ${nServicesScanned} services.`
58
+ );
59
+ return writeGraphOutput(this._outputDirectory.value, graphData);
60
+ }
61
+ };
62
+ export {
63
+ GraphCmd as default
64
+ };
@@ -0,0 +1,78 @@
1
+ // src/commands/render.ts
2
+ import { readFileSync, mkdtempSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { dirname, resolve, sep } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import {
7
+ CommandLineAction
8
+ } from "@rushstack/ts-command-line";
9
+ import { renderFile } from "ejs";
10
+ import open from "open";
11
+ var RenderCmd = class extends CommandLineAction {
12
+ #graphPath;
13
+ #outputPath;
14
+ #launchBrowser;
15
+ constructor() {
16
+ super({
17
+ actionName: "render",
18
+ summary: "Renders your Infrascan graph in your browser",
19
+ documentation: "Loads in the output of a graph command, and render it in a static webpage.\n\nNote: this will only work with Cytoscape compatible graphs."
20
+ });
21
+ }
22
+ onDefineParameters() {
23
+ this.#graphPath = this.defineStringParameter({
24
+ parameterLongName: "--input",
25
+ parameterShortName: "-i",
26
+ argumentName: "PATH_TO_GRAPH",
27
+ description: "Location to read graph data from. This should be the path to the file output by the graph command.",
28
+ defaultValue: "./state/graph.json"
29
+ });
30
+ this.#outputPath = this.defineStringParameter({
31
+ parameterLongName: "--output",
32
+ parameterShortName: "-o",
33
+ argumentName: "OUTPUT_PATH_FOR_WEBPAGE",
34
+ description: "Location to save the generated graph page to. Defaults to a temp directory."
35
+ });
36
+ this.#launchBrowser = this.defineFlagParameter({
37
+ parameterLongName: "--browser",
38
+ description: "Launches the default browser to view the generated graph view."
39
+ });
40
+ }
41
+ async onExecute() {
42
+ const graphText = this.readGraphData();
43
+ if (graphText == null) {
44
+ process.exit(1);
45
+ }
46
+ const graph = JSON.parse(graphText);
47
+ const populatedGraphView = await renderFile(
48
+ resolve(
49
+ dirname(fileURLToPath(import.meta.url)),
50
+ "templates",
51
+ "index.html.ejs"
52
+ ),
53
+ {
54
+ graphData: JSON.stringify(graph)
55
+ }
56
+ );
57
+ let output = this.#outputPath.value != null ? this.#outputPath.value : mkdtempSync(`${tmpdir()}${sep}infrascan-generated-`);
58
+ if (!output.endsWith(".html")) {
59
+ output = `${output}${sep}index.html`;
60
+ }
61
+ writeFileSync(output, populatedGraphView);
62
+ console.log(`Graph view written to ${output}`);
63
+ if (this.#launchBrowser.value) {
64
+ await open(output, { wait: false });
65
+ }
66
+ }
67
+ readGraphData() {
68
+ try {
69
+ return readFileSync(this.#graphPath.value, "utf8");
70
+ } catch (err) {
71
+ console.error(`Failed to read graph data from: ${this.#graphPath.value}`);
72
+ return null;
73
+ }
74
+ }
75
+ };
76
+ export {
77
+ RenderCmd as default
78
+ };
@@ -0,0 +1,126 @@
1
+ // src/commands/scan.ts
2
+ import { writeFileSync } from "fs";
3
+ import { resolve as resolve2, join } from "path";
4
+ import {
5
+ CommandLineAction
6
+ } from "@rushstack/ts-command-line";
7
+ import buildFsConnector from "@infrascan/fs-connector";
8
+ import {
9
+ fromIni,
10
+ fromNodeProviderChain,
11
+ fromTemporaryCredentials
12
+ } from "@aws-sdk/credential-providers";
13
+ import { loadSharedConfigFiles } from "@smithy/shared-ini-file-loader";
14
+
15
+ // src/config.ts
16
+ import { readFileSync } from "fs";
17
+ import { resolve } from "path";
18
+ import { env } from "process";
19
+ import { DEFAULT_PROFILE } from "@smithy/shared-ini-file-loader";
20
+ function getConfig(path) {
21
+ const resolvedConfigPath = resolve(path);
22
+ return JSON.parse(readFileSync(resolvedConfigPath, "utf8"));
23
+ }
24
+ function getDefaultRegion(parsedAwsConfig, currentProfile) {
25
+ const profile = currentProfile ?? env.AWS_PROFILE ?? DEFAULT_PROFILE;
26
+ return env.AWS_REGION ?? parsedAwsConfig?.[profile]?.region;
27
+ }
28
+
29
+ // src/commands/scan.ts
30
+ function writeScanMetadata(outputDirectory, metadata) {
31
+ writeFileSync(
32
+ join(resolve2(outputDirectory), "metadata.json"),
33
+ JSON.stringify(metadata),
34
+ "utf8"
35
+ );
36
+ }
37
+ function resolveCredentialProvider(profile, roleToAssume) {
38
+ if (profile) {
39
+ return (region) => fromIni({
40
+ profile,
41
+ clientConfig: { region }
42
+ });
43
+ }
44
+ if (roleToAssume) {
45
+ return (region) => fromTemporaryCredentials({
46
+ params: {
47
+ RoleArn: roleToAssume,
48
+ RoleSessionName: "infrascan-cli-scan"
49
+ },
50
+ clientConfig: { region }
51
+ });
52
+ }
53
+ console.log(
54
+ "No profile or role given, falling back to default provider chain."
55
+ );
56
+ return (region) => fromNodeProviderChain({ clientConfig: { region } });
57
+ }
58
+ var ScanCmd = class extends CommandLineAction {
59
+ constructor(infrascanClient) {
60
+ super({
61
+ actionName: "scan",
62
+ summary: "Scans a set of AWS accounts",
63
+ documentation: "Reads in config of accounts, regions and services to scans, and executes a scan against each in turn. The ouput is saved to the local filesystem."
64
+ });
65
+ this.infrascanClient = infrascanClient;
66
+ }
67
+ onDefineParameters() {
68
+ this._config = this.defineStringParameter({
69
+ parameterLongName: "--config",
70
+ parameterShortName: "-c",
71
+ argumentName: "PATH_TO_CONFIG",
72
+ description: "Config to use for the scan."
73
+ });
74
+ this._outputDirectory = this.defineStringParameter({
75
+ parameterLongName: "--output",
76
+ parameterShortName: "-o",
77
+ argumentName: "PATH_TO_STATE_OUTPUT",
78
+ description: "Location to save scan output to.",
79
+ defaultValue: "./state"
80
+ });
81
+ this._regions = this.defineStringListParameter({
82
+ parameterLongName: "--region",
83
+ argumentName: "REGION_TO_SCAN",
84
+ description: "The region to scan. This flag can be provided many times e.g. --region us-east-1 --region eu-west-1"
85
+ });
86
+ }
87
+ async onExecute() {
88
+ const awsConfig = await loadSharedConfigFiles().catch((err) => {
89
+ console.warn(
90
+ `Failed to load AWS config file, falling back to @infrascan/sdk defaults. (${err.message})`
91
+ );
92
+ return void 0;
93
+ });
94
+ const defaultRegionFromEnv = getDefaultRegion(awsConfig?.configFile);
95
+ const runtimeRegionsToScan = this._regions.values.length > 0 ? this._regions.values : void 0;
96
+ const scanConfig = this._config.value ? getConfig(this._config.value) : [
97
+ {
98
+ defaultRegion: defaultRegionFromEnv
99
+ }
100
+ ];
101
+ const connector = buildFsConnector(this._outputDirectory.value, {
102
+ createTargetDirectory: true
103
+ });
104
+ const metadata = [];
105
+ for (const accountConfig of scanConfig) {
106
+ const {
107
+ profile,
108
+ roleToAssume,
109
+ regions,
110
+ defaultRegion: configDefaultRegion
111
+ } = accountConfig;
112
+ const credentials = resolveCredentialProvider(profile, roleToAssume);
113
+ const defaultRegion = configDefaultRegion ?? getDefaultRegion(awsConfig?.configFile, profile);
114
+ const accountMetadata = await this.infrascanClient.performScan(
115
+ credentials,
116
+ connector,
117
+ { regions: runtimeRegionsToScan ?? regions, defaultRegion }
118
+ );
119
+ metadata.push(accountMetadata);
120
+ }
121
+ return writeScanMetadata(this._outputDirectory.value, metadata);
122
+ }
123
+ };
124
+ export {
125
+ ScanCmd as default
126
+ };
@@ -0,0 +1,17 @@
1
+ // src/config.ts
2
+ import { readFileSync } from "fs";
3
+ import { resolve } from "path";
4
+ import { env } from "process";
5
+ import { DEFAULT_PROFILE } from "@smithy/shared-ini-file-loader";
6
+ function getConfig(path) {
7
+ const resolvedConfigPath = resolve(path);
8
+ return JSON.parse(readFileSync(resolvedConfigPath, "utf8"));
9
+ }
10
+ function getDefaultRegion(parsedAwsConfig, currentProfile) {
11
+ const profile = currentProfile ?? env.AWS_PROFILE ?? DEFAULT_PROFILE;
12
+ return env.AWS_REGION ?? parsedAwsConfig?.[profile]?.region;
13
+ }
14
+ export {
15
+ getConfig,
16
+ getDefaultRegion
17
+ };
package/dist/index.mjs CHANGED
@@ -12,7 +12,9 @@ import {
12
12
  CommandLineAction
13
13
  } from "@rushstack/ts-command-line";
14
14
  import buildFsConnector from "@infrascan/fs-connector";
15
- import { serializeGraph } from "@infrascan/cytoscape-serializer";
15
+ import {
16
+ serializeGraph
17
+ } from "@infrascan/cytoscape-serializer";
16
18
  function readScanMetadata(outputPath) {
17
19
  const scanMetadata = readFileSync(
18
20
  join(resolve(outputPath), "metadata.json"),
@@ -57,11 +59,7 @@ var GraphCmd = class extends CommandLineAction {
57
59
  nServicesScanned += 1;
58
60
  }
59
61
  });
60
- const graphData = await this.infrascanClient.generateGraph(
61
- scanMetadata,
62
- connector,
63
- serializeGraph
64
- );
62
+ const graphData = await this.infrascanClient.generateGraph(scanMetadata, connector, serializeGraph);
65
63
  console.log(
66
64
  `Graph Complete. Found resources in ${nServicesScanned} services.`
67
65
  );
@@ -69,30 +67,104 @@ var GraphCmd = class extends CommandLineAction {
69
67
  }
70
68
  };
71
69
 
72
- // src/commands/scan.ts
73
- import { writeFileSync as writeFileSync2 } from "fs";
74
- import { resolve as resolve3, join as join2 } from "path";
70
+ // src/commands/render.ts
71
+ import { readFileSync as readFileSync2, mkdtempSync, writeFileSync as writeFileSync2 } from "node:fs";
72
+ import { tmpdir } from "node:os";
73
+ import { dirname, resolve as resolve2, sep } from "node:path";
74
+ import { fileURLToPath } from "node:url";
75
75
  import {
76
76
  CommandLineAction as CommandLineAction2
77
77
  } from "@rushstack/ts-command-line";
78
+ import { renderFile } from "ejs";
79
+ import open from "open";
80
+ var RenderCmd = class extends CommandLineAction2 {
81
+ #graphPath;
82
+ #outputPath;
83
+ #launchBrowser;
84
+ constructor() {
85
+ super({
86
+ actionName: "render",
87
+ summary: "Renders your Infrascan graph in your browser",
88
+ documentation: "Loads in the output of a graph command, and render it in a static webpage.\n\nNote: this will only work with Cytoscape compatible graphs."
89
+ });
90
+ }
91
+ onDefineParameters() {
92
+ this.#graphPath = this.defineStringParameter({
93
+ parameterLongName: "--input",
94
+ parameterShortName: "-i",
95
+ argumentName: "PATH_TO_GRAPH",
96
+ description: "Location to read graph data from. This should be the path to the file output by the graph command.",
97
+ defaultValue: "./state/graph.json"
98
+ });
99
+ this.#outputPath = this.defineStringParameter({
100
+ parameterLongName: "--output",
101
+ parameterShortName: "-o",
102
+ argumentName: "OUTPUT_PATH_FOR_WEBPAGE",
103
+ description: "Location to save the generated graph page to. Defaults to a temp directory."
104
+ });
105
+ this.#launchBrowser = this.defineFlagParameter({
106
+ parameterLongName: "--browser",
107
+ description: "Launches the default browser to view the generated graph view."
108
+ });
109
+ }
110
+ async onExecute() {
111
+ const graphText = this.readGraphData();
112
+ if (graphText == null) {
113
+ process.exit(1);
114
+ }
115
+ const graph = JSON.parse(graphText);
116
+ const populatedGraphView = await renderFile(
117
+ resolve2(
118
+ dirname(fileURLToPath(import.meta.url)),
119
+ "templates",
120
+ "index.html.ejs"
121
+ ),
122
+ {
123
+ graphData: JSON.stringify(graph)
124
+ }
125
+ );
126
+ let output = this.#outputPath.value != null ? this.#outputPath.value : mkdtempSync(`${tmpdir()}${sep}infrascan-generated-`);
127
+ if (!output.endsWith(".html")) {
128
+ output = `${output}${sep}index.html`;
129
+ }
130
+ writeFileSync2(output, populatedGraphView);
131
+ console.log(`Graph view written to ${output}`);
132
+ if (this.#launchBrowser.value) {
133
+ await open(output, { wait: false });
134
+ }
135
+ }
136
+ readGraphData() {
137
+ try {
138
+ return readFileSync2(this.#graphPath.value, "utf8");
139
+ } catch (err) {
140
+ console.error(`Failed to read graph data from: ${this.#graphPath.value}`);
141
+ return null;
142
+ }
143
+ }
144
+ };
145
+
146
+ // src/commands/scan.ts
147
+ import { writeFileSync as writeFileSync3 } from "fs";
148
+ import { resolve as resolve4, join as join2 } from "path";
149
+ import {
150
+ CommandLineAction as CommandLineAction3
151
+ } from "@rushstack/ts-command-line";
78
152
  import buildFsConnector2 from "@infrascan/fs-connector";
79
153
  import {
80
154
  fromIni,
81
155
  fromNodeProviderChain,
82
156
  fromTemporaryCredentials
83
157
  } from "@aws-sdk/credential-providers";
84
- import {
85
- loadSharedConfigFiles
86
- } from "@smithy/shared-ini-file-loader";
158
+ import { loadSharedConfigFiles } from "@smithy/shared-ini-file-loader";
87
159
 
88
160
  // src/config.ts
89
- import { readFileSync as readFileSync2 } from "fs";
90
- import { resolve as resolve2 } from "path";
161
+ import { readFileSync as readFileSync3 } from "fs";
162
+ import { resolve as resolve3 } from "path";
91
163
  import { env } from "process";
92
164
  import { DEFAULT_PROFILE } from "@smithy/shared-ini-file-loader";
93
165
  function getConfig(path) {
94
- const resolvedConfigPath = resolve2(path);
95
- return JSON.parse(readFileSync2(resolvedConfigPath, "utf8"));
166
+ const resolvedConfigPath = resolve3(path);
167
+ return JSON.parse(readFileSync3(resolvedConfigPath, "utf8"));
96
168
  }
97
169
  function getDefaultRegion(parsedAwsConfig, currentProfile) {
98
170
  const profile = currentProfile ?? env.AWS_PROFILE ?? DEFAULT_PROFILE;
@@ -101,8 +173,8 @@ function getDefaultRegion(parsedAwsConfig, currentProfile) {
101
173
 
102
174
  // src/commands/scan.ts
103
175
  function writeScanMetadata(outputDirectory, metadata) {
104
- writeFileSync2(
105
- join2(resolve3(outputDirectory), "metadata.json"),
176
+ writeFileSync3(
177
+ join2(resolve4(outputDirectory), "metadata.json"),
106
178
  JSON.stringify(metadata),
107
179
  "utf8"
108
180
  );
@@ -128,7 +200,7 @@ function resolveCredentialProvider(profile, roleToAssume) {
128
200
  );
129
201
  return (region) => fromNodeProviderChain({ clientConfig: { region } });
130
202
  }
131
- var ScanCmd = class extends CommandLineAction2 {
203
+ var ScanCmd = class extends CommandLineAction3 {
132
204
  constructor(infrascanClient) {
133
205
  super({
134
206
  actionName: "scan",
@@ -203,8 +275,9 @@ var InfrascanCLI = class extends CommandLineParser {
203
275
  toolDescription: 'The "infrascan" tool helps you stay on top of your cloud infrastructure.'
204
276
  });
205
277
  const infrascanClient = registerAwsScanners(new Infrascan());
206
- this.addAction(new ScanCmd(infrascanClient));
207
278
  this.addAction(new GraphCmd(infrascanClient));
279
+ this.addAction(new RenderCmd());
280
+ this.addAction(new ScanCmd(infrascanClient));
208
281
  }
209
282
  onExecute() {
210
283
  return super.onExecute();
@@ -0,0 +1,143 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Infrascan Graph</title>
7
+ <link rel="icon" type="image/svg+xml" href="https://cdn.infrascan.io/img/logo.svg" />
8
+ <link
9
+ rel="preload"
10
+ as="fetch"
11
+ type="application/json"
12
+ href="https://cdn.infrascan.io/graph-styles/default.json"
13
+ crossorigin
14
+ />
15
+ <script
16
+ src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.30.2/cytoscape.min.js"
17
+ integrity="sha512-EY3U1MWdgKx0P1dqTE4inlKz2cpXtWpsR1YUyD855Hs6RL/A0cyvrKh60EpE8wDZ814cTe1KgRK+sG0Rn792vQ=="
18
+ crossorigin="anonymous"
19
+ ></script>
20
+ <style>
21
+ :root {
22
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
23
+ line-height: 1.5;
24
+ font-weight: 400;
25
+
26
+ color-scheme: light dark;
27
+ color: rgba(255, 255, 255, 0.87);
28
+ background-color: #242424;
29
+
30
+ font-synthesis: none;
31
+ text-rendering: optimizeLegibility;
32
+ -webkit-font-smoothing: antialiased;
33
+ -moz-osx-font-smoothing: grayscale;
34
+ -webkit-text-size-adjust: 100%;
35
+ }
36
+
37
+ a {
38
+ font-weight: 500;
39
+ color: #646cff;
40
+ text-decoration: inherit;
41
+ }
42
+ a:hover {
43
+ color: #535bf2;
44
+ }
45
+
46
+ body {
47
+ margin: 0;
48
+ min-width: 100vw;
49
+ min-height: 100vh;
50
+ }
51
+
52
+ h1 {
53
+ font-size: 3.2em;
54
+ line-height: 1.1;
55
+ }
56
+
57
+ #app {
58
+ position: relative;
59
+ width: 100vw;
60
+ height: 100vh;
61
+ margin: 0 auto;
62
+ }
63
+
64
+ #graph-canvas {
65
+ width: 100vw;
66
+ height: 100vh;
67
+ background-image: radial-gradient(
68
+ circle at 20px 20px,
69
+ rgba(255, 255, 255, 0.3) 1px,
70
+ transparent 0px
71
+ );
72
+ background-size: 40px 40px;
73
+ }
74
+
75
+ #powered-by {
76
+ height: 32px;
77
+ width: 128px;
78
+ border-radius: 32px;
79
+
80
+ display: flex;
81
+ align-items: center;
82
+
83
+ background-color: #fff;
84
+ position: absolute;
85
+ top: calc(100vh - 64px);
86
+ left: calc(100vw - 192px);
87
+
88
+ cursor: pointer;
89
+ }
90
+ #powered-by > img {
91
+ padding-left: 8px;
92
+ }
93
+ #powered-by > div {
94
+ padding-left: 8px;
95
+ }
96
+ #powered-by > * > p {
97
+ font-size: 0.5rem;
98
+ }
99
+ #powered-by > * > p,
100
+ #powered-by > * > h5 {
101
+ margin: 0;
102
+ color: #000;
103
+ }
104
+ </style>
105
+ <script>
106
+ document.addEventListener('DOMContentLoaded', () => {
107
+
108
+ document.getElementById('powered-by')?.addEventListener("click", () => {
109
+ if (window != null) {
110
+ window?.open("https://infrascan.io", "_blank")?.focus();
111
+ }
112
+ });
113
+
114
+ const graphContent = <%- graphData %>;
115
+
116
+ if(window.cytoscape != null) {
117
+ fetch('https://cdn.infrascan.io/graph-styles/default.json')
118
+ .then((res) => res.json())
119
+ .then((graphStyle) => {
120
+ console.log(graphStyle);
121
+ window.graph = window.cytoscape({
122
+ container: document.getElementById("graph-canvas"),
123
+ elements: graphContent,
124
+ style: graphStyle,
125
+ });
126
+ });
127
+ }
128
+ });
129
+ </script>
130
+ </head>
131
+ <body>
132
+ <div id="app">
133
+ <div id="graph-canvas"></div>
134
+ <div id="powered-by">
135
+ <img src="https://cdn.infrascan.io/img/logo.svg" alt="Infrascan.io logo" />
136
+ <div>
137
+ <p>Powered By:</p>
138
+ <h5>Infrascan.io</h5>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </body>
143
+ </html>
package/package.json CHANGED
@@ -1,24 +1,13 @@
1
1
  {
2
2
  "name": "@infrascan/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Thin command line wrapper around the infrascan sdk",
5
5
  "main": "dist/index.mjs",
6
6
  "scripts": {
7
- "build": "rm -rf dist ; tsup",
7
+ "build": "rm -rf dist ; tsup --config internal/tsconfig/app.tsup.json ; cp -r ./src/templates ./dist/templates",
8
8
  "lint": "tsc --noEmit ; eslint .",
9
9
  "clean": "rm -rf dist node_modules"
10
10
  },
11
- "tsup": {
12
- "clean": true,
13
- "splitting": false,
14
- "entry": [
15
- "src/index.ts"
16
- ],
17
- "format": [
18
- "esm"
19
- ],
20
- "target": "node18"
21
- },
22
11
  "bin": {
23
12
  "infrascan": "./dist/index.mjs"
24
13
  },
@@ -36,20 +25,23 @@
36
25
  "author": "Liam Farrelly <liam@l3f7.dev> (https://whoisli.am/)",
37
26
  "license": "MPL-2.0",
38
27
  "dependencies": {
39
- "@aws-sdk/credential-providers": "3.428.0",
28
+ "@aws-sdk/credential-providers": "3.624.0",
40
29
  "@infrascan/aws": "^0.4.1",
41
- "@infrascan/cytoscape-serializer": "^0.2.0",
30
+ "@infrascan/cytoscape-serializer": "^0.2.1",
42
31
  "@infrascan/fs-connector": "^0.2.2",
43
- "@infrascan/sdk": "^0.4.0",
32
+ "@infrascan/sdk": "^0.4.2",
44
33
  "@rushstack/ts-command-line": "^4.15.2",
45
34
  "@smithy/shared-ini-file-loader": "^2.2.2",
46
- "minimatch": "^6.1.6"
35
+ "ejs": "^3.1.9",
36
+ "minimatch": "^6.1.6",
37
+ "open": "^10.1.0"
47
38
  },
48
39
  "devDependencies": {
49
- "@aws-sdk/types": "3.428.0",
50
- "@infrascan/shared-types": "^0.4.0",
40
+ "@aws-sdk/types": "3.609.0",
41
+ "@infrascan/shared-types": "^0.5.1",
51
42
  "@smithy/types": "^2.4.0",
43
+ "@types/ejs": "^3.1.5",
52
44
  "ts-node": "^10.9.1",
53
45
  "typescript": "^5.1.3"
54
46
  }
55
- }
47
+ }