@pitcher/cli-scripts 1.1.0 → 2.0.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.
- package/README.md +27 -11
- package/dist/copyInstanceFiles.d.ts +2 -0
- package/dist/copyInstanceFiles.js +17 -0
- package/dist/index.js +0 -2
- package/dist/package.json +40 -0
- package/dist/publishApp.d.ts +2 -0
- package/dist/publishApp.js +93 -0
- package/dist/src/publishApp.js +158 -2
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -2,30 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
> Pitcher CLI Tools provide a suite of command-line utilities to streamline your workflow. For the best experience, we recommend installing the tools globally using `npm install -g @pitcher/cli-scripts`.
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
## Help
|
|
6
|
+
|
|
7
7
|
```bash
|
|
8
8
|
p --help
|
|
9
9
|
# or for specific command help:
|
|
10
10
|
p command --help
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
## To run the `copy-instance-files` command:
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
p copy-instance-files <fromInstance> <toInstance> --org pitcher --api-key myapikey
|
|
18
|
-
```
|
|
19
|
-
|
|
20
13
|
## To run the `publish-app` command:
|
|
14
|
+
|
|
21
15
|
```bash
|
|
16
|
+
# Basic usage
|
|
22
17
|
p publish-app <folder> --url https://dev.my.pitcher.com --api-key myapikey
|
|
23
|
-
|
|
18
|
+
|
|
19
|
+
# Publish to current folder and dev org
|
|
24
20
|
p publish-app --api-key myapikey
|
|
25
|
-
|
|
21
|
+
|
|
22
|
+
# Dry run with version increment
|
|
26
23
|
p publish-app --api-key myapikey --dry-run --increment-version
|
|
27
24
|
|
|
25
|
+
# Publish and install to specific instances
|
|
26
|
+
p publish-app --api-key myapikey --increment-version --install-to "01HG0C5NS1BTQ2ZPE1XCGKSGDH, 01HG0C5NS1BTQ2ZPE1XCGKSGDA"
|
|
27
|
+
|
|
28
|
+
# Publish and install to all instances with a specific environment name
|
|
29
|
+
p publish-app --api-key myapikey --increment-version --install-to-env-name "Demo"
|
|
30
|
+
|
|
31
|
+
# Combine both: install to specific instances AND all instances in an environment
|
|
32
|
+
p publish-app --api-key myapikey --increment-version --install-to "01HG0C5NS1BTQ2ZPE1XCGKSGDH" --install-to-env-name "Demo"
|
|
33
|
+
|
|
28
34
|
# Alternative: Set API key via environment variable
|
|
29
35
|
export NG_API_KEY=myapikey
|
|
30
|
-
p publish-app --increment-version
|
|
36
|
+
p publish-app --increment-version --install-to-env-name "Production"
|
|
31
37
|
```
|
|
38
|
+
|
|
39
|
+
### Options
|
|
40
|
+
|
|
41
|
+
- `--api-key <apiKey>`: API Key for authentication (can also use `NG_API_KEY` env variable)
|
|
42
|
+
- `--org <organization>`: Organization subdomain (default: "dev")
|
|
43
|
+
- `--increment-version`: Increment version in app.json with timestamp
|
|
44
|
+
- `--dry-run`: Perform a dry run without publishing
|
|
45
|
+
- `--publish-url <url>`: Explicit publish URL
|
|
46
|
+
- `--install-to <instanceIds>`: Comma-separated list of instance IDs to install the app to after publishing
|
|
47
|
+
- `--install-to-env-name <envName>`: Environment name to filter instances and install the app to after publishing
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
export function createCopyInstanceFilesCommand() {
|
|
3
|
+
const program = new Command("copy-instance-files");
|
|
4
|
+
program
|
|
5
|
+
.arguments("<fromInstance> <toInstance>")
|
|
6
|
+
.requiredOption("--api-key <apiKey>", "API Key", process.env.PITCHER_API_KEY)
|
|
7
|
+
.requiredOption("--org <orgName>", "Organization Name", process.env.PITCHER_ORG)
|
|
8
|
+
.description('clone instance files into another one e.g. "p copy-instance-files <fromInstanceId> <toInstanceId> --org mondelez --api-key myapikey"')
|
|
9
|
+
.action((sourceInstanceId, destinationInstanceId, options) => {
|
|
10
|
+
console.log("clone instance files command called", {
|
|
11
|
+
sourceInstanceId,
|
|
12
|
+
destinationInstanceId,
|
|
13
|
+
options,
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
return program;
|
|
17
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import { createCopyInstanceFilesCommand } from "./src/copyInstanceFiles.js";
|
|
4
3
|
import { createPublishAppCommand } from "./src/publishApp.js";
|
|
5
4
|
import { readFileSync } from "fs";
|
|
6
5
|
import { fileURLToPath } from "url";
|
|
@@ -14,6 +13,5 @@ program
|
|
|
14
13
|
.description("The Pitcher CLI for various tasks in its ecosystem.")
|
|
15
14
|
.version(pkg.version);
|
|
16
15
|
// Add subcommands
|
|
17
|
-
program.addCommand(createCopyInstanceFilesCommand());
|
|
18
16
|
program.addCommand(createPublishAppCommand());
|
|
19
17
|
program.parse(process.argv);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pitcher/cli-scripts",
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "The Pitcher CLI for various tasks in its ecosystem.",
|
|
5
|
+
"author": "Pitcher AG",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/PitcherAG/ng-scripts.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"pitcher",
|
|
13
|
+
"cli",
|
|
14
|
+
"ng-scripts"
|
|
15
|
+
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"p": "node --no-warnings ./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/archiver": "^6.0.2",
|
|
31
|
+
"@types/node": "^20.0.0",
|
|
32
|
+
"typescript": "^5.4.5"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"archiver": "^7.0.1",
|
|
36
|
+
"axios": "^1.7.2",
|
|
37
|
+
"commander": "^12.1.0",
|
|
38
|
+
"form-data": "^4.0.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import archiver from "archiver";
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import FormData from "form-data";
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
export function createPublishAppCommand() {
|
|
9
|
+
const program = new Command("publish-app");
|
|
10
|
+
program
|
|
11
|
+
.arguments("[folder]")
|
|
12
|
+
.requiredOption("--api-key <apiKey>", "API Key for authentication")
|
|
13
|
+
.option("--org <organization>", "Organization subdomain", "dev")
|
|
14
|
+
.option("--increment-version", "Increment version in app.json")
|
|
15
|
+
.option("--dry-run", "Perform a dry run without publishing")
|
|
16
|
+
.option("--publish-url <url>", "Explicit publish URL")
|
|
17
|
+
.description('zip the contents of a folder and publish as an app to a pitcher org URL. for current folder: "p publish-app --api-key myapikey"')
|
|
18
|
+
.action(async (folder = ".", options) => {
|
|
19
|
+
try {
|
|
20
|
+
const folderPath = path.resolve(folder);
|
|
21
|
+
if (options.incrementVersion) {
|
|
22
|
+
const appJsonPath = path.join(folderPath, "app.json");
|
|
23
|
+
if (fs.existsSync(appJsonPath)) {
|
|
24
|
+
const appJson = JSON.parse(fs.readFileSync(appJsonPath, "utf-8"));
|
|
25
|
+
const now = new Date();
|
|
26
|
+
const year = now.getFullYear();
|
|
27
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
28
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
29
|
+
const timestamp = now.getTime();
|
|
30
|
+
const version = `${year}.${month}.${day}.${timestamp}`;
|
|
31
|
+
appJson.version = version;
|
|
32
|
+
fs.writeFileSync(appJsonPath, JSON.stringify(appJson, null, 2));
|
|
33
|
+
console.log(`Updated app.json version to ${version}`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error("app.json not found in the specified folder.");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
41
|
+
const zipFilePath = path.join(currentDir, "app.zip");
|
|
42
|
+
const output = fs.createWriteStream(zipFilePath);
|
|
43
|
+
const archive = archiver("zip", {
|
|
44
|
+
zlib: { level: 9 },
|
|
45
|
+
});
|
|
46
|
+
output.on("close", async () => {
|
|
47
|
+
console.log(`Zipped ${archive.pointer()} total bytes`);
|
|
48
|
+
const formData = new FormData();
|
|
49
|
+
formData.append("file", fs.createReadStream(zipFilePath));
|
|
50
|
+
const publishUrl = options.publishUrl || `https://${options.org}.my.pitcher.com/api/v1/apps/publish/`;
|
|
51
|
+
if (options.dryRun) {
|
|
52
|
+
console.log("Dry run mode enabled. The following data would be published:");
|
|
53
|
+
console.log("Publish URL:", publishUrl);
|
|
54
|
+
console.log("Headers:", {
|
|
55
|
+
...formData.getHeaders(),
|
|
56
|
+
"x-api-key": options.apiKey,
|
|
57
|
+
});
|
|
58
|
+
console.log("app.json content:", fs.readFileSync(path.join(folderPath, "app.json"), "utf-8"));
|
|
59
|
+
fs.unlinkSync(zipFilePath);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
try {
|
|
63
|
+
const response = await axios.post(publishUrl, formData, {
|
|
64
|
+
headers: {
|
|
65
|
+
...formData.getHeaders(),
|
|
66
|
+
"x-api-key": options.apiKey,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
console.log("Publish response:", response.data);
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
const error = e;
|
|
73
|
+
const errData = error?.response?.data;
|
|
74
|
+
console.error("Error publishing:", errData?.detail ?? errData);
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
fs.unlinkSync(zipFilePath);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
archive.on("error", (err) => {
|
|
82
|
+
throw err;
|
|
83
|
+
});
|
|
84
|
+
archive.pipe(output);
|
|
85
|
+
archive.directory(folderPath, false);
|
|
86
|
+
await archive.finalize();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error("Error zipping or publishing:", error);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return program;
|
|
93
|
+
}
|
package/dist/src/publishApp.js
CHANGED
|
@@ -4,7 +4,113 @@ import axios from "axios";
|
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import FormData from "form-data";
|
|
7
|
-
import { fileURLToPath } from
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
async function fetchAllInstances(baseUrl, apiKey) {
|
|
9
|
+
const pageSize = 100;
|
|
10
|
+
const maxPages = 1000;
|
|
11
|
+
try {
|
|
12
|
+
console.log("Fetching instances page 1 to determine total count...");
|
|
13
|
+
const firstResponse = await axios.get(`${baseUrl}/api/v1/instances`, {
|
|
14
|
+
headers: {
|
|
15
|
+
accept: "application/json",
|
|
16
|
+
"x-api-key": apiKey,
|
|
17
|
+
},
|
|
18
|
+
params: {
|
|
19
|
+
page_size: pageSize,
|
|
20
|
+
page: 1,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
const firstData = firstResponse.data;
|
|
24
|
+
const firstInstances = firstData.results || [];
|
|
25
|
+
if (firstInstances.length === 0) {
|
|
26
|
+
console.log("No instances found");
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const totalCount = firstData.count || firstInstances.length;
|
|
30
|
+
const totalPages = Math.min(Math.ceil(totalCount / pageSize), maxPages);
|
|
31
|
+
console.log(`Found ${totalCount} instance(s) across ${totalPages} page(s)`);
|
|
32
|
+
if (totalPages === 1) {
|
|
33
|
+
console.log(`✓ Fetched ${firstInstances.length} total instance(s) from API`);
|
|
34
|
+
return firstInstances;
|
|
35
|
+
}
|
|
36
|
+
const remainingPageNumbers = Array.from({ length: totalPages - 1 }, (_, i) => i + 2);
|
|
37
|
+
console.log(`Fetching remaining ${totalPages - 1} pages in parallel...`);
|
|
38
|
+
const remainingPagePromises = remainingPageNumbers.map((page) => axios.get(`${baseUrl}/api/v1/instances`, {
|
|
39
|
+
headers: {
|
|
40
|
+
accept: "application/json",
|
|
41
|
+
"x-api-key": apiKey,
|
|
42
|
+
},
|
|
43
|
+
params: {
|
|
44
|
+
page_size: pageSize,
|
|
45
|
+
page: page,
|
|
46
|
+
},
|
|
47
|
+
}));
|
|
48
|
+
const remainingResponses = await Promise.all(remainingPagePromises);
|
|
49
|
+
const remainingInstances = remainingResponses.flatMap((response) => response.data.results || []);
|
|
50
|
+
const allInstances = [...firstInstances, ...remainingInstances];
|
|
51
|
+
if (totalPages >= maxPages) {
|
|
52
|
+
console.warn(`⚠ Warning: Reached maximum page limit (${maxPages}). There may be more instances.`);
|
|
53
|
+
}
|
|
54
|
+
console.log(`✓ Fetched ${allInstances.length} total instance(s) from API`);
|
|
55
|
+
return allInstances;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const axiosError = error;
|
|
59
|
+
console.error("Error fetching instances:", axiosError?.response?.data?.detail ?? axiosError.message);
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function filterInstancesByEnvName(instances, envName) {
|
|
64
|
+
const filtered = instances.filter((instance) => instance.env_name === envName);
|
|
65
|
+
if (filtered.length === 0) {
|
|
66
|
+
console.warn(`No instances found with environment name "${envName}"`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.log(`Found ${filtered.length} instance(s) with environment name "${envName}"`);
|
|
70
|
+
}
|
|
71
|
+
return filtered;
|
|
72
|
+
}
|
|
73
|
+
function validateInstanceIds(instances, requestedIds) {
|
|
74
|
+
const instanceMap = new Map(instances.map((inst) => [inst.id, inst]));
|
|
75
|
+
const valid = [];
|
|
76
|
+
const invalid = [];
|
|
77
|
+
for (const id of requestedIds) {
|
|
78
|
+
const instance = instanceMap.get(id);
|
|
79
|
+
if (instance) {
|
|
80
|
+
valid.push(instance);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
invalid.push(id);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { valid, invalid };
|
|
87
|
+
}
|
|
88
|
+
async function installAppToInstances(baseUrl, apiKey, appName, instances) {
|
|
89
|
+
if (instances.length === 0) {
|
|
90
|
+
console.log("No instances to install to.");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const instanceIds = instances.map((inst) => inst.id);
|
|
94
|
+
console.log(`\nInstalling app "${appName}" to ${instances.length} instance(s):`);
|
|
95
|
+
instances.forEach((inst) => {
|
|
96
|
+
console.log(` - ${inst.id}${inst.env_name ? ` (${inst.env_name})` : ""}${inst.name ? ` - ${inst.name}` : ""}`);
|
|
97
|
+
});
|
|
98
|
+
try {
|
|
99
|
+
const response = await axios.post(`${baseUrl}/api/v1/apps/${appName}/install/`, { instance_ids: instanceIds }, {
|
|
100
|
+
headers: {
|
|
101
|
+
accept: "application/json",
|
|
102
|
+
"content-type": "application/json",
|
|
103
|
+
"x-api-key": apiKey,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
console.log("\nInstallation response:", response.data);
|
|
107
|
+
console.log(`✓ Successfully installed app to ${instances.length} instance(s)`);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
const axiosError = error;
|
|
111
|
+
console.error("\n✗ Error installing app:", axiosError?.response?.data?.detail ?? axiosError.message);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
8
114
|
export function createPublishAppCommand() {
|
|
9
115
|
const program = new Command("publish-app");
|
|
10
116
|
program
|
|
@@ -14,6 +120,8 @@ export function createPublishAppCommand() {
|
|
|
14
120
|
.option("--increment-version", "Increment version in app.json")
|
|
15
121
|
.option("--dry-run", "Perform a dry run without publishing")
|
|
16
122
|
.option("--publish-url <url>", "Explicit publish URL")
|
|
123
|
+
.option("--install-to <instanceIds>", "Comma-separated list of instance IDs to install the app to after publishing")
|
|
124
|
+
.option("--install-to-env-name <envName>", "Environment name to filter instances and install the app to after publishing")
|
|
17
125
|
.description('zip the contents of a folder and publish as an app to a pitcher org URL. for current folder: "p publish-app --api-key myapikey"')
|
|
18
126
|
.action(async (folder = ".", options) => {
|
|
19
127
|
const apiKey = options.apiKey || process.env.NG_API_KEY;
|
|
@@ -21,6 +129,8 @@ export function createPublishAppCommand() {
|
|
|
21
129
|
console.error("Error: API key is required. Provide it via --api-key or set the NG_API_KEY environment variable.");
|
|
22
130
|
process.exit(1);
|
|
23
131
|
}
|
|
132
|
+
if (!options.publishUrl && !options.org)
|
|
133
|
+
options.org = "dev";
|
|
24
134
|
options.apiKey = apiKey;
|
|
25
135
|
try {
|
|
26
136
|
const folderPath = path.resolve(folder);
|
|
@@ -53,7 +163,8 @@ export function createPublishAppCommand() {
|
|
|
53
163
|
console.log(`Zipped ${archive.pointer()} total bytes`);
|
|
54
164
|
const formData = new FormData();
|
|
55
165
|
formData.append("file", fs.createReadStream(zipFilePath));
|
|
56
|
-
const publishUrl = options.publishUrl ||
|
|
166
|
+
const publishUrl = options.publishUrl ||
|
|
167
|
+
`https://${options.org}.my.pitcher.com/api/v1/apps/publish/`;
|
|
57
168
|
if (options.dryRun) {
|
|
58
169
|
console.log("Dry run mode enabled. The following data would be published:");
|
|
59
170
|
console.log("Publish URL:", publishUrl);
|
|
@@ -73,6 +184,51 @@ export function createPublishAppCommand() {
|
|
|
73
184
|
},
|
|
74
185
|
});
|
|
75
186
|
console.log("Publish response:", response.data);
|
|
187
|
+
const baseUrl = options.publishUrl
|
|
188
|
+
? new URL(options.publishUrl).origin
|
|
189
|
+
: `https://${options.org}.my.pitcher.com`;
|
|
190
|
+
const appName = response.data?.app?.name;
|
|
191
|
+
if (!appName) {
|
|
192
|
+
console.warn("Could not determine app name from publish response");
|
|
193
|
+
}
|
|
194
|
+
else if (options.installTo || options.installToEnvName) {
|
|
195
|
+
console.log("\n--- Starting installation process ---");
|
|
196
|
+
const allInstances = await fetchAllInstances(baseUrl, options.apiKey);
|
|
197
|
+
if (allInstances.length === 0) {
|
|
198
|
+
console.warn("Cannot proceed with installation: no instances available");
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
let targetInstances = [];
|
|
202
|
+
if (options.installTo) {
|
|
203
|
+
const requestedIds = options.installTo
|
|
204
|
+
.split(",")
|
|
205
|
+
.map((id) => id.trim())
|
|
206
|
+
.filter(Boolean);
|
|
207
|
+
console.log(`\nValidating ${requestedIds.length} requested instance ID(s)...`);
|
|
208
|
+
const { valid, invalid } = validateInstanceIds(allInstances, requestedIds);
|
|
209
|
+
if (invalid.length > 0) {
|
|
210
|
+
console.warn(`⚠ Warning: ${invalid.length} invalid instance ID(s) will be skipped:`);
|
|
211
|
+
invalid.forEach((id) => console.warn(` - ${id}`));
|
|
212
|
+
}
|
|
213
|
+
if (valid.length > 0) {
|
|
214
|
+
console.log(`✓ Found ${valid.length} valid instance(s)`);
|
|
215
|
+
targetInstances = [...targetInstances, ...valid];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (options.installToEnvName) {
|
|
219
|
+
console.log(`\nFiltering instances by environment name: "${options.installToEnvName}"`);
|
|
220
|
+
const envInstances = filterInstancesByEnvName(allInstances, options.installToEnvName);
|
|
221
|
+
targetInstances = [...targetInstances, ...envInstances];
|
|
222
|
+
}
|
|
223
|
+
const uniqueInstances = Array.from(new Map(targetInstances.map((inst) => [inst.id, inst])).values());
|
|
224
|
+
if (uniqueInstances.length > 0) {
|
|
225
|
+
await installAppToInstances(baseUrl, options.apiKey, appName, uniqueInstances);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
console.log("\nNo valid instances found to install to.");
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
76
232
|
}
|
|
77
233
|
catch (e) {
|
|
78
234
|
const error = e;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pitcher/cli-scripts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "The Pitcher CLI for various tasks in its ecosystem.",
|
|
5
5
|
"author": "Pitcher AG",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
],
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/archiver": "^6.0.3",
|
|
27
|
-
"@types/node": "^22.
|
|
28
|
-
"typescript": "^5.
|
|
27
|
+
"@types/node": "^22.18.0",
|
|
28
|
+
"typescript": "^5.9.2"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"archiver": "^7.0.1",
|
|
32
|
-
"axios": "^1.
|
|
32
|
+
"axios": "^1.12.0",
|
|
33
33
|
"commander": "^13.1.0",
|
|
34
34
|
"form-data": "^4.0.2"
|
|
35
35
|
}
|