@zeroheight/adoption-cli 2.4.2 → 3.0.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.
- package/CHANGELOG.md +14 -1
- package/README.md +26 -4
- package/dist/ast/analyze.d.ts +11 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +18 -5
- package/dist/commands/analyze.d.ts +5 -3
- package/dist/commands/analyze.js +9 -4
- package/dist/commands/analyze.utils.d.ts +10 -11
- package/dist/commands/analyze.utils.js +87 -0
- package/dist/commands/track-package.d.ts +1 -0
- package/dist/commands/track-package.js +3 -1
- package/dist/commands/track-package.utils.d.ts +12 -1
- package/dist/commands/track-package.utils.js +33 -4
- package/dist/common/api.d.ts +20 -2
- package/dist/common/api.js +27 -1
- package/dist/components/analyze/analyze.d.ts +7 -4
- package/dist/components/analyze/analyze.js +330 -112
- package/dist/components/analyze/non-interactive-analyze.d.ts +9 -3
- package/dist/components/analyze/non-interactive-analyze.js +57 -19
- package/dist/components/auth/no-credentials-onboarding.js +3 -1
- package/dist/components/color-usage-table.d.ts +7 -0
- package/dist/components/color-usage-table.js +38 -0
- package/dist/components/latest-version-info.d.ts +9 -0
- package/dist/components/latest-version-info.js +27 -0
- package/dist/components/track-package/non-interactive-track-package.d.ts +4 -1
- package/dist/components/track-package/non-interactive-track-package.js +3 -3
- package/dist/components/ui/continue-prompt.js +4 -1
- package/package.json +1 -1
|
@@ -2,18 +2,19 @@ import React from "react";
|
|
|
2
2
|
import { Box, Newline, Text } from "ink";
|
|
3
3
|
import Spinner from "ink-spinner";
|
|
4
4
|
import Link from "ink-link";
|
|
5
|
-
import { calculateNumberOfComponents } from "../../commands/analyze.utils.js";
|
|
5
|
+
import { calculateNumberOfColors, calculateNumberOfComponents, } from "../../commands/analyze.utils.js";
|
|
6
6
|
import { readConfig } from "../../common/config.js";
|
|
7
|
-
import {
|
|
7
|
+
import { submitComponentUsageData, submitTokenLiteralUsageData, } from "../../common/api.js";
|
|
8
8
|
import { ApiError } from "../../common/errors.js";
|
|
9
|
-
export default function NonInteractiveAnalyze({ repoName, onAnalyzeFiles, }) {
|
|
9
|
+
export default function NonInteractiveAnalyze({ repoName, onAnalyzeFiles, onAnalyzeColorUsage, shouldAnalyzeComponentUsage, shouldAnalyzeTokenUsage, }) {
|
|
10
10
|
const [isSendingData, setIsSendingData] = React.useState(false);
|
|
11
11
|
const [isAnalyzingFiles, setIsAnalyzingFiles] = React.useState(false);
|
|
12
12
|
const [isFetchingCredentials, setIsFetchingCredentials] = React.useState(false);
|
|
13
13
|
const [errorFileLocation, setErrorFileLocation] = React.useState(null);
|
|
14
14
|
const [errorList, setErrorList] = React.useState([]);
|
|
15
15
|
const [credentials, setCredentials] = React.useState(null);
|
|
16
|
-
const [
|
|
16
|
+
const [componentUsage, setComponentUsage] = React.useState(null);
|
|
17
|
+
const [colorUsage, setColorUsage] = React.useState(null);
|
|
17
18
|
async function loadCredentials() {
|
|
18
19
|
setIsFetchingCredentials(true);
|
|
19
20
|
try {
|
|
@@ -31,13 +32,13 @@ export default function NonInteractiveAnalyze({ repoName, onAnalyzeFiles, }) {
|
|
|
31
32
|
}
|
|
32
33
|
return null;
|
|
33
34
|
}
|
|
34
|
-
async function
|
|
35
|
+
async function sendComponentUsageData(result, repoName, credentials) {
|
|
35
36
|
setIsSendingData(true);
|
|
36
37
|
try {
|
|
37
|
-
await
|
|
38
|
+
await submitComponentUsageData(result, repoName, credentials);
|
|
38
39
|
}
|
|
39
40
|
catch (e) {
|
|
40
|
-
let errorMessage = "Failed to send data to zeroheight";
|
|
41
|
+
let errorMessage = "Failed to send component usage data to zeroheight";
|
|
41
42
|
if (e instanceof ApiError) {
|
|
42
43
|
errorMessage = e.message;
|
|
43
44
|
}
|
|
@@ -47,10 +48,36 @@ export default function NonInteractiveAnalyze({ repoName, onAnalyzeFiles, }) {
|
|
|
47
48
|
setIsSendingData(false);
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
|
-
async function
|
|
51
|
+
async function sendTokenUsageData(result, repoName, credentials) {
|
|
52
|
+
setIsSendingData(true);
|
|
53
|
+
try {
|
|
54
|
+
await submitTokenLiteralUsageData(result, repoName, credentials);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
let errorMessage = "Failed to send color usage data to zeroheight";
|
|
58
|
+
if (e instanceof ApiError) {
|
|
59
|
+
errorMessage = e.message;
|
|
60
|
+
}
|
|
61
|
+
setErrorList((s) => [...s, errorMessage]);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
setIsSendingData(false);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function analyzeComponentUsage() {
|
|
51
68
|
setIsAnalyzingFiles(true);
|
|
52
69
|
const { errorFile, usage } = await onAnalyzeFiles();
|
|
53
|
-
|
|
70
|
+
setComponentUsage(usage);
|
|
71
|
+
if (errorFile) {
|
|
72
|
+
setErrorFileLocation(errorFile);
|
|
73
|
+
}
|
|
74
|
+
setIsAnalyzingFiles(false);
|
|
75
|
+
return usage;
|
|
76
|
+
}
|
|
77
|
+
async function analyzeTokenUsage() {
|
|
78
|
+
setIsAnalyzingFiles(true);
|
|
79
|
+
const { errorFile, usage } = await onAnalyzeColorUsage();
|
|
80
|
+
setColorUsage(usage);
|
|
54
81
|
if (errorFile) {
|
|
55
82
|
setErrorFileLocation(errorFile);
|
|
56
83
|
}
|
|
@@ -62,18 +89,25 @@ export default function NonInteractiveAnalyze({ repoName, onAnalyzeFiles, }) {
|
|
|
62
89
|
const credentials = await loadCredentials();
|
|
63
90
|
if (!credentials)
|
|
64
91
|
return;
|
|
65
|
-
const usage = await anaylzeUsage();
|
|
66
92
|
if (!repoName)
|
|
67
93
|
return;
|
|
68
|
-
|
|
94
|
+
if (shouldAnalyzeComponentUsage) {
|
|
95
|
+
const componentUsageMap = await analyzeComponentUsage();
|
|
96
|
+
await sendComponentUsageData(componentUsageMap, repoName, credentials);
|
|
97
|
+
}
|
|
98
|
+
if (shouldAnalyzeTokenUsage) {
|
|
99
|
+
const colorUsageMap = await analyzeTokenUsage();
|
|
100
|
+
await sendTokenUsageData(colorUsageMap, repoName, credentials);
|
|
101
|
+
}
|
|
69
102
|
})();
|
|
70
103
|
}, []);
|
|
71
104
|
if (isAnalyzingFiles || isFetchingCredentials || isSendingData) {
|
|
72
105
|
return (React.createElement(Text, null,
|
|
73
106
|
React.createElement(Spinner, { type: "dots" }),
|
|
74
|
-
|
|
107
|
+
" ",
|
|
108
|
+
isAnalyzingFiles && React.createElement(Text, null, "Analyzing files"),
|
|
75
109
|
isFetchingCredentials && React.createElement(Text, null, "Loading credentials"),
|
|
76
|
-
isSendingData && React.createElement(Text, null, "Sending data to
|
|
110
|
+
isSendingData && React.createElement(Text, null, "Sending data to zeroheight")));
|
|
77
111
|
}
|
|
78
112
|
if (errorList.length > 0) {
|
|
79
113
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
@@ -115,12 +149,16 @@ export default function NonInteractiveAnalyze({ repoName, onAnalyzeFiles, }) {
|
|
|
115
149
|
" ",
|
|
116
150
|
React.createElement(Text, { italic: true }, "--interactive false")));
|
|
117
151
|
}
|
|
118
|
-
if (!
|
|
152
|
+
if (!componentUsage && !colorUsage) {
|
|
119
153
|
return React.createElement(Text, null, "No usage could be found.");
|
|
120
154
|
}
|
|
121
|
-
return (React.createElement(React.Fragment, null,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
155
|
+
return (React.createElement(React.Fragment, null,
|
|
156
|
+
componentUsage && (React.createElement(Text, { color: "green" },
|
|
157
|
+
calculateNumberOfComponents(componentUsage),
|
|
158
|
+
" components found and sent to ",
|
|
159
|
+
React.createElement(Text, { color: "#f63e7c" }, "zeroheight"))),
|
|
160
|
+
colorUsage && (React.createElement(Text, { color: "green" },
|
|
161
|
+
calculateNumberOfColors(colorUsage),
|
|
162
|
+
" usages of raw colors found and sent to ",
|
|
163
|
+
React.createElement(Text, { color: "#f63e7c" }, "zeroheight")))));
|
|
126
164
|
}
|
|
@@ -22,7 +22,9 @@ export default function NoCredentialsOnboarding({ onCheckCredentials, onSaveCred
|
|
|
22
22
|
React.createElement(Text, null,
|
|
23
23
|
"If you need a new auth token, generate them from the",
|
|
24
24
|
" ",
|
|
25
|
-
React.createElement(Link, { url: "https://zeroheight.com/settings/team/developers" },
|
|
25
|
+
React.createElement(Link, { url: "https://zeroheight.com/settings/team/developers" },
|
|
26
|
+
React.createElement(Text, { underline: true, color: "#f63e7c" }, "Developer Settings"))),
|
|
27
|
+
React.createElement(Newline, null),
|
|
26
28
|
field === "client" && (React.createElement(Box, null,
|
|
27
29
|
React.createElement(Text, null, "Client ID: "),
|
|
28
30
|
React.createElement(TextInput, { onChange: setClient, value: client, onSubmit: (v) => {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
const colorTypeNameMap = {
|
|
4
|
+
hex: "HEX",
|
|
5
|
+
rgb: "RGB",
|
|
6
|
+
hsla: "HSL",
|
|
7
|
+
oklab: "Oklab",
|
|
8
|
+
hwb: "HWB",
|
|
9
|
+
lab: "LAB",
|
|
10
|
+
lch: "LCH",
|
|
11
|
+
colorSpace: "Color space",
|
|
12
|
+
totalCount: "Total usage",
|
|
13
|
+
};
|
|
14
|
+
export default function ColorUsageTable({ usage }) {
|
|
15
|
+
const rows = Array.from(usage.entries());
|
|
16
|
+
return (React.createElement(Box, { flexDirection: "column" }, rows.map(([filepath, rawColorUsage]) => {
|
|
17
|
+
const rowValues = Object.entries(rawColorUsage);
|
|
18
|
+
return (React.createElement(Box, { key: filepath, flexDirection: "column" },
|
|
19
|
+
React.createElement(Text, { color: "green" }, filepath),
|
|
20
|
+
React.createElement(Box, { flexDirection: "column", marginLeft: 2 },
|
|
21
|
+
React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, rowValues.map(([type, values]) => {
|
|
22
|
+
if (type === "totalCount")
|
|
23
|
+
return null;
|
|
24
|
+
const count = values.length;
|
|
25
|
+
if (count === 0)
|
|
26
|
+
return null;
|
|
27
|
+
const name = colorTypeNameMap[type];
|
|
28
|
+
return (React.createElement(Box, { gap: 2, key: `${type}-${count}` },
|
|
29
|
+
React.createElement(Text, { bold: true },
|
|
30
|
+
name,
|
|
31
|
+
": "),
|
|
32
|
+
React.createElement(Text, null, count)));
|
|
33
|
+
})),
|
|
34
|
+
React.createElement(Text, { bold: true },
|
|
35
|
+
"Total usage: ",
|
|
36
|
+
rawColorUsage.totalCount))));
|
|
37
|
+
})));
|
|
38
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
interface LatestVersionInfoProps {
|
|
3
|
+
latestVersion: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Rich help banner with info about the latest version
|
|
7
|
+
*/
|
|
8
|
+
export default function LatestVersionInfo({ latestVersion, }: LatestVersionInfoProps): React.JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import Link from "ink-link";
|
|
4
|
+
import { CURRENT_VERSION } from "../cli.js";
|
|
5
|
+
/**
|
|
6
|
+
* Rich help banner with info about the latest version
|
|
7
|
+
*/
|
|
8
|
+
export default function LatestVersionInfo({ latestVersion, }) {
|
|
9
|
+
const isMajorVersionOut = Number(CURRENT_VERSION.split(".")[0]) < Number(latestVersion.split(".")[0]);
|
|
10
|
+
return (React.createElement(React.Fragment, null,
|
|
11
|
+
React.createElement(Box, { borderStyle: "double", paddingLeft: 1, paddingRight: 1, marginBottom: 1, flexDirection: "column" },
|
|
12
|
+
React.createElement(Box, { justifyContent: "center", marginBottom: 1 },
|
|
13
|
+
React.createElement(Text, null, "\uD83D\uDC4B It seems you're not using the latest version of this package")),
|
|
14
|
+
React.createElement(Box, { flexDirection: "column", alignItems: "center", marginBottom: 1 },
|
|
15
|
+
React.createElement(Box, null,
|
|
16
|
+
React.createElement(Text, { color: isMajorVersionOut ? "redBright" : "blueBright", bold: true }, CURRENT_VERSION),
|
|
17
|
+
React.createElement(Text, { bold: true }, ` -> `),
|
|
18
|
+
React.createElement(Text, { color: "green", bold: true }, latestVersion)),
|
|
19
|
+
React.createElement(Box, null,
|
|
20
|
+
React.createElement(Text, null, "Update using: "),
|
|
21
|
+
React.createElement(Text, { bold: true }, "npm i @zeroheight/adoption-cli"))),
|
|
22
|
+
React.createElement(Box, { flexDirection: "column", alignItems: "center" },
|
|
23
|
+
React.createElement(Text, null,
|
|
24
|
+
"For more information on the latest version, check",
|
|
25
|
+
" ",
|
|
26
|
+
React.createElement(Link, { url: "https://www.npmjs.com/package/@zeroheight/adoption-cli" }, "here"))))));
|
|
27
|
+
}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
export
|
|
2
|
+
export interface NonInteractiveTrackPackageProps {
|
|
3
|
+
allowedPackages?: string[];
|
|
4
|
+
}
|
|
5
|
+
export default function NonInteractiveTrackPackage({ allowedPackages, }: NonInteractiveTrackPackageProps): React.JSX.Element;
|
|
@@ -13,7 +13,7 @@ var Step;
|
|
|
13
13
|
Step[Step["MULTIPLE_PACKAGES_FOUND"] = 3] = "MULTIPLE_PACKAGES_FOUND";
|
|
14
14
|
Step[Step["SINGLE_PACKAGE_FOUND"] = 4] = "SINGLE_PACKAGE_FOUND";
|
|
15
15
|
})(Step || (Step = {}));
|
|
16
|
-
export default function NonInteractiveTrackPackage() {
|
|
16
|
+
export default function NonInteractiveTrackPackage({ allowedPackages, }) {
|
|
17
17
|
const { exit } = useApp();
|
|
18
18
|
const [currentStep, setCurrentStep] = React.useState(Step.FINDING_DETAILS);
|
|
19
19
|
const [errorMessage, setErrorMessage] = React.useState(null);
|
|
@@ -22,7 +22,7 @@ export default function NonInteractiveTrackPackage() {
|
|
|
22
22
|
const [packageVersion, setPackageVersion] = React.useState(null);
|
|
23
23
|
async function runTrackPackage() {
|
|
24
24
|
const config = (await readConfig()) ?? { token: "temp", client: "temp" };
|
|
25
|
-
const { files, error } = await getPackageInfo();
|
|
25
|
+
const { files, error } = await getPackageInfo(allowedPackages);
|
|
26
26
|
try {
|
|
27
27
|
if (files.length === 1) {
|
|
28
28
|
const { name, path, version, exports } = files[0];
|
|
@@ -83,7 +83,7 @@ export default function NonInteractiveTrackPackage() {
|
|
|
83
83
|
" searching for package file...")),
|
|
84
84
|
currentStep === Step.SINGLE_PACKAGE_FOUND && (React.createElement(React.Fragment, null,
|
|
85
85
|
React.createElement(Text, null,
|
|
86
|
-
React.createElement(Text, { color: "green" }, "Details
|
|
86
|
+
React.createElement(Text, { color: "green" }, "Details found:"),
|
|
87
87
|
" ",
|
|
88
88
|
packageName,
|
|
89
89
|
"@",
|
|
@@ -5,7 +5,10 @@ export default function ContinuePrompt({ onContinue }) {
|
|
|
5
5
|
const [shouldContinueText, setShouldContinueText] = React.useState("");
|
|
6
6
|
return (React.createElement(Box, null,
|
|
7
7
|
React.createElement(Text, null,
|
|
8
|
-
"
|
|
8
|
+
"Send this data to ",
|
|
9
|
+
React.createElement(Text, { color: "#f63e7c" }, "zeroheight"),
|
|
10
|
+
"?",
|
|
11
|
+
" ",
|
|
9
12
|
React.createElement(Text, { dimColor: true }, "(Y/n):")),
|
|
10
13
|
React.createElement(ConfirmInput, { isChecked: true, value: shouldContinueText, onChange: setShouldContinueText, onSubmit: (answer) => {
|
|
11
14
|
onContinue(answer);
|