@trayai/tray-sync-cli 1.0.14 → 1.0.15
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,6 +1,42 @@
|
|
|
1
1
|
export async function rollbackProject(client, projectId, versionNumber) {
|
|
2
2
|
await client.request("POST", `/v1/projects/${projectId}/rollbacks/versions/${versionNumber}`);
|
|
3
3
|
}
|
|
4
|
+
export async function getLatestProjectVersion(client, targetProjectId) {
|
|
5
|
+
const result = (await client.request("GET", `/v1/projects/${targetProjectId}/versions?last=1`));
|
|
6
|
+
const latest = result.elements?.[0];
|
|
7
|
+
if (!latest)
|
|
8
|
+
return null;
|
|
9
|
+
const [major, minor] = latest.versionNumber.split(".").map(Number);
|
|
10
|
+
return { major, minor };
|
|
11
|
+
}
|
|
12
|
+
export function computeNextVersionNumber(current, mode) {
|
|
13
|
+
if (!current)
|
|
14
|
+
return "1.0";
|
|
15
|
+
if (mode === "major")
|
|
16
|
+
return `${current.major + 1}.0`;
|
|
17
|
+
return `${current.major}.${current.minor + 1}`;
|
|
18
|
+
}
|
|
19
|
+
export async function createProjectVersion(client, targetProjectId, versionNumber, title, description) {
|
|
20
|
+
const result = (await client.request("POST", `/v1/projects/${targetProjectId}/versions/${versionNumber}`, { title, description }));
|
|
21
|
+
return {
|
|
22
|
+
versionNumber: result.versionNumber,
|
|
23
|
+
title: result.title,
|
|
24
|
+
description: result.description,
|
|
25
|
+
created: result.created,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export async function updateProjectVersion(client, projectId, versionNumber, fields) {
|
|
29
|
+
const result = (await client.request("PUT", `/v1/projects/${projectId}/versions/${versionNumber}`, fields));
|
|
30
|
+
return {
|
|
31
|
+
versionNumber: result.versionNumber,
|
|
32
|
+
title: result.title,
|
|
33
|
+
description: result.description,
|
|
34
|
+
created: result.created,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export async function deleteProjectVersion(client, projectId, versionNumber) {
|
|
38
|
+
await client.request("DELETE", `/v1/projects/${projectId}/versions/${versionNumber}`);
|
|
39
|
+
}
|
|
4
40
|
export async function listProjectVersions(client, projectId, options = {}) {
|
|
5
41
|
const params = new URLSearchParams();
|
|
6
42
|
if (options.last !== undefined)
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import ansis from "ansis";
|
|
1
2
|
import { Command, InvalidArgumentError } from "commander";
|
|
2
|
-
import { listProjectVersions, rollbackProject } from "../../api/resources/project.js";
|
|
3
|
+
import { computeNextVersionNumber, createProjectVersion, deleteProjectVersion, getLatestProjectVersion, listProjectVersions, rollbackProject, updateProjectVersion, } from "../../api/resources/project.js";
|
|
3
4
|
import { isUuid } from "../../lib/uuid.js";
|
|
4
5
|
import { parseVersionNumber } from "../../lib/versionNumber.js";
|
|
5
6
|
import { OutputFormats } from "../../lib/outputFormat.js";
|
|
6
|
-
import { printProjectRollbackResult, printProjectVersionListTable } from "../../views/api/project.v2.js";
|
|
7
|
+
import { printProjectRollbackResult, printProjectVersionDeletedResult, printProjectVersionListTable, printProjectVersionResult, } from "../../views/api/project.v2.js";
|
|
7
8
|
import { printConfirmationJson } from "../../views/api/shared.js";
|
|
9
|
+
import { FAILURE_ICON } from "../../views/icons.js";
|
|
8
10
|
import { addCommonApiOptions, apiClientFor, realDeps, runApiAction, } from "./shared.js";
|
|
11
|
+
const DEFAULT_VERSION_CREATE_TITLE = "Created via tray-sync-cli";
|
|
9
12
|
const DEFAULT_VERSION_LIST_LIMIT = 5;
|
|
10
13
|
function parseLimit(value) {
|
|
11
14
|
const limit = Number(value);
|
|
@@ -48,6 +51,63 @@ export async function runProjectVersionList(deps, options) {
|
|
|
48
51
|
}
|
|
49
52
|
return 0;
|
|
50
53
|
}
|
|
54
|
+
function printMutuallyExclusiveMajorAndVersion(stderr) {
|
|
55
|
+
stderr(`${FAILURE_ICON} ${ansis.bold("--major")} and ${ansis.bold("--version-number")} are mutually exclusive.`);
|
|
56
|
+
}
|
|
57
|
+
export async function runProjectVersionCreate(deps, options) {
|
|
58
|
+
if (options.major && options.versionNumber) {
|
|
59
|
+
printMutuallyExclusiveMajorAndVersion(deps.stderr);
|
|
60
|
+
return 1;
|
|
61
|
+
}
|
|
62
|
+
const client = await apiClientFor(deps, options);
|
|
63
|
+
const mode = options.major ? "major" : "minor";
|
|
64
|
+
const versionNumber = options.versionNumber ?? computeNextVersionNumber(await getLatestProjectVersion(client, options.projectId), mode);
|
|
65
|
+
const title = options.title ?? DEFAULT_VERSION_CREATE_TITLE;
|
|
66
|
+
const description = options.description ?? "";
|
|
67
|
+
const created = await createProjectVersion(client, options.projectId, versionNumber, title, description);
|
|
68
|
+
if (options.format === OutputFormats.JSON) {
|
|
69
|
+
printConfirmationJson(deps.stdout, { projectId: options.projectId, ...created });
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
printProjectVersionResult(deps.stdout, options.projectId, created, "created");
|
|
73
|
+
}
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
export async function runProjectVersionEdit(deps, options) {
|
|
77
|
+
if (options.title === undefined && options.description === undefined) {
|
|
78
|
+
deps.stderr(`${FAILURE_ICON} Nothing to edit — pass --title and/or --description.`);
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
const client = await apiClientFor(deps, options);
|
|
82
|
+
const fields = {};
|
|
83
|
+
if (options.title !== undefined)
|
|
84
|
+
fields.title = options.title;
|
|
85
|
+
if (options.description !== undefined)
|
|
86
|
+
fields.description = options.description;
|
|
87
|
+
const updated = await updateProjectVersion(client, options.projectId, options.versionNumber, fields);
|
|
88
|
+
if (options.format === OutputFormats.JSON) {
|
|
89
|
+
printConfirmationJson(deps.stdout, { projectId: options.projectId, ...updated });
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
printProjectVersionResult(deps.stdout, options.projectId, updated, "updated");
|
|
93
|
+
}
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
export async function runProjectVersionDelete(deps, options) {
|
|
97
|
+
const client = await apiClientFor(deps, options);
|
|
98
|
+
await deleteProjectVersion(client, options.projectId, options.versionNumber);
|
|
99
|
+
if (options.format === OutputFormats.JSON) {
|
|
100
|
+
printConfirmationJson(deps.stdout, {
|
|
101
|
+
projectId: options.projectId,
|
|
102
|
+
versionNumber: options.versionNumber,
|
|
103
|
+
deleted: true,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
printProjectVersionDeletedResult(deps.stdout, options.projectId, options.versionNumber);
|
|
108
|
+
}
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
51
111
|
export const projectCommand = new Command("project").description("Manage projects");
|
|
52
112
|
const versionCommand = new Command("version").description("Manage project versions");
|
|
53
113
|
projectCommand.addCommand(versionCommand);
|
|
@@ -79,4 +139,56 @@ addCommonApiOptions(versionCommand
|
|
|
79
139
|
format: opts.format,
|
|
80
140
|
}));
|
|
81
141
|
});
|
|
142
|
+
addCommonApiOptions(versionCommand
|
|
143
|
+
.command("create")
|
|
144
|
+
.description("Create a new version for a project")
|
|
145
|
+
.argument("<project-id>", "Tray project UUID", parseProjectId)
|
|
146
|
+
.option("--major", "bump the major version instead of minor")
|
|
147
|
+
.option("--version-number <major.minor>", "explicit target version number (overrides --major)", parseVersionNumber)
|
|
148
|
+
.option("--title <title>", `title for the created version (default "${DEFAULT_VERSION_CREATE_TITLE}")`)
|
|
149
|
+
.option("--description <description>", "description for the created version")).action(async (projectId, opts) => {
|
|
150
|
+
const deps = realDeps();
|
|
151
|
+
await runApiAction(deps, () => runProjectVersionCreate(deps, {
|
|
152
|
+
projectId,
|
|
153
|
+
major: opts.major,
|
|
154
|
+
versionNumber: opts.versionNumber,
|
|
155
|
+
title: opts.title,
|
|
156
|
+
description: opts.description,
|
|
157
|
+
region: opts.region,
|
|
158
|
+
token: opts.token,
|
|
159
|
+
format: opts.format,
|
|
160
|
+
}));
|
|
161
|
+
});
|
|
162
|
+
addCommonApiOptions(versionCommand
|
|
163
|
+
.command("edit")
|
|
164
|
+
.description("Edit a version's title and/or description")
|
|
165
|
+
.argument("<project-id>", "Tray project UUID", parseProjectId)
|
|
166
|
+
.requiredOption("--version-number <major.minor>", "target version number", parseVersionNumber)
|
|
167
|
+
.option("--title <title>", "new title")
|
|
168
|
+
.option("--description <description>", "new description")).action(async (projectId, opts) => {
|
|
169
|
+
const deps = realDeps();
|
|
170
|
+
await runApiAction(deps, () => runProjectVersionEdit(deps, {
|
|
171
|
+
projectId,
|
|
172
|
+
versionNumber: opts.versionNumber,
|
|
173
|
+
title: opts.title,
|
|
174
|
+
description: opts.description,
|
|
175
|
+
region: opts.region,
|
|
176
|
+
token: opts.token,
|
|
177
|
+
format: opts.format,
|
|
178
|
+
}));
|
|
179
|
+
});
|
|
180
|
+
addCommonApiOptions(versionCommand
|
|
181
|
+
.command("delete")
|
|
182
|
+
.description("Delete a version")
|
|
183
|
+
.argument("<project-id>", "Tray project UUID", parseProjectId)
|
|
184
|
+
.requiredOption("--version-number <major.minor>", "target version number", parseVersionNumber)).action(async (projectId, opts) => {
|
|
185
|
+
const deps = realDeps();
|
|
186
|
+
await runApiAction(deps, () => runProjectVersionDelete(deps, {
|
|
187
|
+
projectId,
|
|
188
|
+
versionNumber: opts.versionNumber,
|
|
189
|
+
region: opts.region,
|
|
190
|
+
token: opts.token,
|
|
191
|
+
format: opts.format,
|
|
192
|
+
}));
|
|
193
|
+
});
|
|
82
194
|
//# sourceMappingURL=project.js.map
|
package/dist/commands/promote.js
CHANGED
|
@@ -13,7 +13,8 @@ import { resolveContainedSafe } from "../lib/pathContainment.js";
|
|
|
13
13
|
import { entityDisplayName } from "../lib/exportStructure.js";
|
|
14
14
|
import { importProject, previewImport } from "../lib/promoteExecute.js";
|
|
15
15
|
import { summarizeImpactForVersionDescription, toProjectImportImpact, } from "../lib/promoteReport.js";
|
|
16
|
-
import {
|
|
16
|
+
import { isFullyResolved, resolveProjectRequirements, scaffoldUnresolvedAuthentications, } from "../lib/promoteTarget.js";
|
|
17
|
+
import { computeNextVersionNumber, createProjectVersion, getLatestProjectVersion, } from "../api/resources/project.js";
|
|
17
18
|
import { resolveToken } from "../lib/tokenResolution.js";
|
|
18
19
|
import { isUuid } from "../lib/uuid.js";
|
|
19
20
|
import { OutputFormats, parseFormat } from "../lib/outputFormat.js";
|
|
@@ -96,30 +96,6 @@ export function validateAuthenticationMappings(mapping) {
|
|
|
96
96
|
.filter(([, authenticationId]) => !isUuid(authenticationId))
|
|
97
97
|
.map(([authExportId, value]) => ({ authExportId, value }));
|
|
98
98
|
}
|
|
99
|
-
export async function getLatestProjectVersion(client, targetProjectId) {
|
|
100
|
-
const result = (await client.request("GET", `/v1/projects/${targetProjectId}/versions?last=1`));
|
|
101
|
-
const latest = result.elements?.[0];
|
|
102
|
-
if (!latest)
|
|
103
|
-
return null;
|
|
104
|
-
const [major, minor] = latest.versionNumber.split(".").map(Number);
|
|
105
|
-
return { major, minor };
|
|
106
|
-
}
|
|
107
|
-
export function computeNextVersionNumber(current, mode) {
|
|
108
|
-
if (!current)
|
|
109
|
-
return "1.0";
|
|
110
|
-
if (mode === "major")
|
|
111
|
-
return `${current.major + 1}.0`;
|
|
112
|
-
return `${current.major}.${current.minor + 1}`;
|
|
113
|
-
}
|
|
114
|
-
export async function createProjectVersion(client, targetProjectId, versionNumber, title, description) {
|
|
115
|
-
const result = (await client.request("POST", `/v1/projects/${targetProjectId}/versions/${versionNumber}`, { title, description }));
|
|
116
|
-
return {
|
|
117
|
-
versionNumber: result.versionNumber,
|
|
118
|
-
title: result.title,
|
|
119
|
-
description: result.description,
|
|
120
|
-
created: result.created,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
99
|
export async function resolveProjectRequirements(client, deps, options) {
|
|
124
100
|
const targetResolution = await resolveTargetProjectId(client, {
|
|
125
101
|
projectDirPath: options.projectDirPath,
|
|
@@ -21,4 +21,10 @@ export function printProjectVersionListTable(stdout, versions) {
|
|
|
21
21
|
}
|
|
22
22
|
stdout(table.toString());
|
|
23
23
|
}
|
|
24
|
+
export function printProjectVersionResult(stdout, projectId, version, verb) {
|
|
25
|
+
stdout(`${SUCCESS_ICON} Project ${ansis.bold(projectId)} version ${ansis.bold(version.versionNumber)} ${verb}: ${ansis.bold(version.title)}.`);
|
|
26
|
+
}
|
|
27
|
+
export function printProjectVersionDeletedResult(stdout, projectId, versionNumber) {
|
|
28
|
+
stdout(`${SUCCESS_ICON} Project ${ansis.bold(projectId)} version ${ansis.bold(versionNumber)} deleted.`);
|
|
29
|
+
}
|
|
24
30
|
//# sourceMappingURL=project.v2.js.map
|
package/package.json
CHANGED