@zeroheight/adoption-cli 2.1.0 → 2.2.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/CHANGELOG.md +8 -0
- package/dist/cli.js +1 -1
- package/dist/commands/track-package.utils.d.ts +4 -0
- package/dist/commands/track-package.utils.js +14 -2
- package/dist/common/api.d.ts +1 -1
- package/dist/common/api.js +29 -13
- package/dist/common/types/package-file.d.ts +5 -0
- package/dist/components/track-package/non-interactive-track-package.js +6 -4
- package/dist/components/track-package/track-package.js +11 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Release notes
|
|
2
2
|
|
|
3
|
+
## [2.2.1](https://www.npmjs.com/package/@zeroheight/adoption-cli/v/2.2.1) - 13th November 2024
|
|
4
|
+
|
|
5
|
+
- Handle API throttling
|
|
6
|
+
|
|
7
|
+
## [2.2.0](https://www.npmjs.com/package/@zeroheight/adoption-cli/v/2.2.0) - 8th November 2024
|
|
8
|
+
|
|
9
|
+
- Include export names in package file as part of component analyzing
|
|
10
|
+
|
|
3
11
|
## [2.1.0](https://www.npmjs.com/package/@zeroheight/adoption-cli/v/2.1.0) - 8th November 2024
|
|
4
12
|
|
|
5
13
|
- Start collecting component property usage data as part of component analyzing
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ const { output, cleanup } = render(React.createElement(HelpInfo, null));
|
|
|
12
12
|
program
|
|
13
13
|
.name("zh-adoption")
|
|
14
14
|
.description("CLI for measuring design system usage usage in your products")
|
|
15
|
-
.version("2.1
|
|
15
|
+
.version("2.2.1")
|
|
16
16
|
.addHelpText("before", output)
|
|
17
17
|
.addCommand(analyzeCommand())
|
|
18
18
|
.addCommand(authCommand())
|
|
@@ -8,3 +8,7 @@ export declare function getPackageInfo(): Promise<{
|
|
|
8
8
|
files: PackageFile[];
|
|
9
9
|
error: string | null;
|
|
10
10
|
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Transform exports object into fully qualified aliases
|
|
13
|
+
*/
|
|
14
|
+
export declare function getAliasesFromExports(packageName: string, exports?: PackageFile["exports"]): string[];
|
|
@@ -21,10 +21,12 @@ export async function getPackageInfo() {
|
|
|
21
21
|
try {
|
|
22
22
|
const packageFiles = await Promise.all(files.map(async (file) => {
|
|
23
23
|
const fileContents = await readFile(file, "utf-8");
|
|
24
|
+
const parsedPackage = JSON.parse(fileContents);
|
|
24
25
|
return {
|
|
25
|
-
name:
|
|
26
|
+
name: parsedPackage.name,
|
|
26
27
|
path: `.${files[0]?.split(base).pop()}`,
|
|
27
|
-
version:
|
|
28
|
+
version: parsedPackage.version,
|
|
29
|
+
exports: parsedPackage.exports,
|
|
28
30
|
};
|
|
29
31
|
}));
|
|
30
32
|
return {
|
|
@@ -39,3 +41,13 @@ export async function getPackageInfo() {
|
|
|
39
41
|
};
|
|
40
42
|
}
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Transform exports object into fully qualified aliases
|
|
46
|
+
*/
|
|
47
|
+
export function getAliasesFromExports(packageName, exports) {
|
|
48
|
+
if (!exports)
|
|
49
|
+
return [];
|
|
50
|
+
return Object.keys(exports)
|
|
51
|
+
.map((path) => joinPath(packageName, path))
|
|
52
|
+
.filter((name) => name !== packageName);
|
|
53
|
+
}
|
package/dist/common/api.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ interface PackageDetailsSuccessResponse {
|
|
|
39
39
|
updated_at: string;
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
export declare function submitPackageDetails(name: string, path: string, version: string, credentials: Credentials): Promise<APIResponse<PackageDetailsSuccessResponse, {}, {}>>;
|
|
42
|
+
export declare function submitPackageDetails(name: string, path: string, version: string, aliases: string[], credentials: Credentials): Promise<APIResponse<PackageDetailsSuccessResponse, {}, {}>>;
|
|
43
43
|
interface MonitoredRepoDetailsSuccess {
|
|
44
44
|
monitored_repository: {
|
|
45
45
|
id: number;
|
package/dist/common/api.js
CHANGED
|
@@ -13,11 +13,12 @@ export function getZeroheightURL() {
|
|
|
13
13
|
return new URL("https://zeroheight.com");
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
export async function submitPackageDetails(name, path, version, credentials) {
|
|
16
|
+
export async function submitPackageDetails(name, path, version, aliases, credentials) {
|
|
17
17
|
return post("/design_system_packages", {
|
|
18
18
|
name,
|
|
19
19
|
path,
|
|
20
20
|
latest_version: version,
|
|
21
|
+
aliases,
|
|
21
22
|
}, credentials);
|
|
22
23
|
}
|
|
23
24
|
export async function submitMonitoredRepoDetails(name, version, lockfilePath, packages, credentials) {
|
|
@@ -51,25 +52,40 @@ async function post(path, body, credentials) {
|
|
|
51
52
|
body: JSON.stringify(body),
|
|
52
53
|
});
|
|
53
54
|
}
|
|
55
|
+
async function sleep(ms) {
|
|
56
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
57
|
+
}
|
|
54
58
|
async function request(path, credentials, init) {
|
|
55
59
|
const url = getZeroheightURL();
|
|
56
60
|
url.pathname = API_PATH + path;
|
|
57
61
|
if (process.env["NODE_ENV"] === "dev") {
|
|
58
62
|
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
|
|
59
63
|
}
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
const maxRetries = 3;
|
|
65
|
+
let retries = 0;
|
|
66
|
+
while (retries < maxRetries) {
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
...init,
|
|
69
|
+
headers: {
|
|
70
|
+
"X-API-CLIENT-NAME": "cli",
|
|
71
|
+
"X-API-CLIENT": credentials.client,
|
|
72
|
+
"X-API-KEY": credentials.token,
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
if (response.status === 401) {
|
|
77
|
+
throw new Error("Unauthorized");
|
|
78
|
+
}
|
|
79
|
+
else if (response.status === 429) {
|
|
80
|
+
retries++;
|
|
81
|
+
const responseData = await response.json();
|
|
82
|
+
const waitTime = responseData.data.reset_time * 1000 - Date.now();
|
|
83
|
+
await sleep(waitTime);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
return await response.json();
|
|
71
87
|
}
|
|
72
|
-
|
|
88
|
+
throw new Error(`Request failed after ${maxRetries} retries`);
|
|
73
89
|
}
|
|
74
90
|
export function mergeUsageProps(newProps, currentProps) {
|
|
75
91
|
if (!currentProps)
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { Newline, Text, useApp } from "ink";
|
|
3
3
|
import Spinner from "ink-spinner";
|
|
4
4
|
import { readConfig } from "../../common/config.js";
|
|
5
|
-
import { getPackageInfo } from "../../commands/track-package.utils.js";
|
|
5
|
+
import { getAliasesFromExports, getPackageInfo, } from "../../commands/track-package.utils.js";
|
|
6
6
|
import { ResponseStatus, submitPackageDetails } from "../../common/api.js";
|
|
7
7
|
var Step;
|
|
8
8
|
(function (Step) {
|
|
@@ -24,11 +24,12 @@ export default function NonInteractiveTrackPackage() {
|
|
|
24
24
|
const { files, error } = await getPackageInfo();
|
|
25
25
|
try {
|
|
26
26
|
if (files.length === 1) {
|
|
27
|
-
const { name, path, version } = files[0];
|
|
27
|
+
const { name, path, version, exports } = files[0];
|
|
28
28
|
setPackageName(name);
|
|
29
29
|
setPackageVersion(version);
|
|
30
30
|
setCurrentStep(Step.SINGLE_PACKAGE_FOUND);
|
|
31
|
-
const
|
|
31
|
+
const aliases = getAliasesFromExports(name, exports);
|
|
32
|
+
const response = await submitPackageDetails(name, path, version, aliases, {
|
|
32
33
|
token: config.token,
|
|
33
34
|
client: config.client,
|
|
34
35
|
});
|
|
@@ -46,7 +47,8 @@ export default function NonInteractiveTrackPackage() {
|
|
|
46
47
|
setPackageFiles(files);
|
|
47
48
|
setCurrentStep(Step.MULTIPLE_PACKAGES_FOUND);
|
|
48
49
|
await Promise.all(files.map(async (pack) => {
|
|
49
|
-
|
|
50
|
+
const aliases = getAliasesFromExports(pack.name, pack.exports);
|
|
51
|
+
await submitPackageDetails(pack.name, pack.path, pack.version, aliases, {
|
|
50
52
|
token: config.token,
|
|
51
53
|
client: config.client,
|
|
52
54
|
});
|
|
@@ -5,7 +5,7 @@ import SelectInput from "ink-select-input";
|
|
|
5
5
|
import Spinner from "ink-spinner";
|
|
6
6
|
import ConfirmInput from "../ui/confirm-input.js";
|
|
7
7
|
import { readConfig } from "../../common/config.js";
|
|
8
|
-
import { getPackageInfo } from "../../commands/track-package.utils.js";
|
|
8
|
+
import { getAliasesFromExports, getPackageInfo, } from "../../commands/track-package.utils.js";
|
|
9
9
|
import { submitPackageDetails } from "../../common/api.js";
|
|
10
10
|
var Step;
|
|
11
11
|
(function (Step) {
|
|
@@ -28,12 +28,13 @@ export default function TrackPackage() {
|
|
|
28
28
|
const [packageName, setPackageName] = React.useState(null);
|
|
29
29
|
const [packagePath, setPackagePath] = React.useState(null);
|
|
30
30
|
const [packageVersion, setPackageVersion] = React.useState(null);
|
|
31
|
+
const [packageAliases, setPackageAliases] = React.useState([]);
|
|
31
32
|
const [shouldSend, setShouldSend] = React.useState("");
|
|
32
33
|
const [shouldMultiSelect, setShouldMultiSelect] = React.useState("");
|
|
33
34
|
const [packageSelection, setPackageSelection] = React.useState([]);
|
|
34
35
|
const [selectedFileLabels, setSelectedFileLabels] = React.useState([]);
|
|
35
|
-
async function submitPackage(name, path, version) {
|
|
36
|
-
await submitPackageDetails(name, path, version, credentials);
|
|
36
|
+
async function submitPackage(name, path, version, aliases) {
|
|
37
|
+
await submitPackageDetails(name, path, version, aliases, credentials);
|
|
37
38
|
}
|
|
38
39
|
async function sendData() {
|
|
39
40
|
setCurrentStep(Step.SENDING_DETAILS);
|
|
@@ -42,18 +43,20 @@ export default function TrackPackage() {
|
|
|
42
43
|
const packagesToSend = packageFiles.filter((p) => selectedFileLabels.includes(`${p.name}@${p.version}`));
|
|
43
44
|
if (packagesToSend.length > 0) {
|
|
44
45
|
await Promise.all(packagesToSend.map(async (pack) => {
|
|
45
|
-
|
|
46
|
+
const aliases = getAliasesFromExports(pack.name, pack.exports);
|
|
47
|
+
submitPackage(pack.name, pack.path, pack.version, aliases);
|
|
46
48
|
}));
|
|
47
49
|
}
|
|
48
50
|
else {
|
|
49
51
|
await Promise.all(packageFiles.map(async (pack) => {
|
|
50
|
-
|
|
52
|
+
const aliases = getAliasesFromExports(pack.name, pack.exports);
|
|
53
|
+
submitPackage(pack.name, pack.path, pack.version, aliases);
|
|
51
54
|
}));
|
|
52
55
|
}
|
|
53
56
|
setCurrentStep(Step.COMPLETE);
|
|
54
57
|
}
|
|
55
58
|
else {
|
|
56
|
-
await submitPackage(packageName, packagePath, packageVersion);
|
|
59
|
+
await submitPackage(packageName, packagePath, packageVersion, packageAliases);
|
|
57
60
|
setCurrentStep(Step.COMPLETE);
|
|
58
61
|
}
|
|
59
62
|
}
|
|
@@ -101,10 +104,11 @@ export default function TrackPackage() {
|
|
|
101
104
|
}
|
|
102
105
|
const { files, error } = await getPackageInfo();
|
|
103
106
|
if (files.length === 1) {
|
|
104
|
-
const { name, path, version } = files[0];
|
|
107
|
+
const { name, path, version, exports } = files[0];
|
|
105
108
|
setPackageName(name);
|
|
106
109
|
setPackagePath(path);
|
|
107
110
|
setPackageVersion(version);
|
|
111
|
+
setPackageAliases(getAliasesFromExports(name, exports));
|
|
108
112
|
setCurrentStep(Step.SINGLE_PACKAGE_FOUND);
|
|
109
113
|
}
|
|
110
114
|
else if (files.length > 1) {
|