@zeroheight/adoption-cli 3.0.1 → 3.1.1-rc.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 +10 -0
- package/dist/cli.d.ts +8 -5
- package/dist/cli.js +12924 -36
- package/package.json +11 -6
- package/dist/ast/analyze.d.ts +0 -50
- package/dist/ast/analyze.js +0 -247
- package/dist/ast/parser.d.ts +0 -13
- package/dist/ast/parser.js +0 -14
- package/dist/commands/analyze.d.ts +0 -16
- package/dist/commands/analyze.js +0 -53
- package/dist/commands/analyze.utils.d.ts +0 -27
- package/dist/commands/analyze.utils.js +0 -204
- package/dist/commands/auth.d.ts +0 -9
- package/dist/commands/auth.js +0 -28
- package/dist/commands/monitor-repo.d.ts +0 -10
- package/dist/commands/monitor-repo.js +0 -42
- package/dist/commands/monitor-repo.utils.d.ts +0 -31
- package/dist/commands/monitor-repo.utils.js +0 -81
- package/dist/commands/track-package.d.ts +0 -9
- package/dist/commands/track-package.js +0 -41
- package/dist/commands/track-package.utils.d.ts +0 -25
- package/dist/commands/track-package.utils.js +0 -82
- package/dist/common/api.d.ts +0 -113
- package/dist/common/api.js +0 -169
- package/dist/common/config.d.ts +0 -14
- package/dist/common/config.js +0 -41
- package/dist/common/errors.d.ts +0 -12
- package/dist/common/errors.js +0 -21
- package/dist/common/logging.d.ts +0 -4
- package/dist/common/logging.js +0 -26
- package/dist/common/types/package-file.d.ts +0 -13
- package/dist/common/types/package-file.js +0 -1
- package/dist/components/analyze/analyze.d.ts +0 -14
- package/dist/components/analyze/analyze.js +0 -429
- package/dist/components/analyze/non-interactive-analyze.d.ts +0 -16
- package/dist/components/analyze/non-interactive-analyze.js +0 -164
- package/dist/components/auth/auth.d.ts +0 -7
- package/dist/components/auth/auth.js +0 -119
- package/dist/components/auth/credentials-already-exists.d.ts +0 -13
- package/dist/components/auth/credentials-already-exists.js +0 -16
- package/dist/components/auth/credentials-preview.d.ts +0 -10
- package/dist/components/auth/credentials-preview.js +0 -20
- package/dist/components/auth/no-credentials-onboarding.d.ts +0 -8
- package/dist/components/auth/no-credentials-onboarding.js +0 -57
- package/dist/components/color-usage-table.d.ts +0 -7
- package/dist/components/color-usage-table.js +0 -38
- package/dist/components/help-info.d.ts +0 -5
- package/dist/components/help-info.js +0 -24
- package/dist/components/latest-version-info.d.ts +0 -9
- package/dist/components/latest-version-info.js +0 -27
- package/dist/components/monitor-repo/monitor-repo.d.ts +0 -2
- package/dist/components/monitor-repo/monitor-repo.js +0 -9
- package/dist/components/monitor-repo/non-interactive-monitor-repo.d.ts +0 -7
- package/dist/components/monitor-repo/non-interactive-monitor-repo.js +0 -124
- package/dist/components/repo-name-prompt.d.ts +0 -8
- package/dist/components/repo-name-prompt.js +0 -97
- package/dist/components/track-package/non-interactive-track-package.d.ts +0 -5
- package/dist/components/track-package/non-interactive-track-package.js +0 -117
- package/dist/components/track-package/track-package.d.ts +0 -2
- package/dist/components/track-package/track-package.js +0 -214
- package/dist/components/ui/confirm-input.d.ts +0 -10
- package/dist/components/ui/confirm-input.js +0 -10
- package/dist/components/ui/continue-prompt.d.ts +0 -6
- package/dist/components/ui/continue-prompt.js +0 -16
- package/dist/components/usage-table.d.ts +0 -7
- package/dist/components/usage-table.js +0 -14
- package/dist/lockfile-parsers/lock-parser.d.ts +0 -9
- package/dist/lockfile-parsers/lock-parser.js +0 -5
- package/dist/lockfile-parsers/npm-lock-parser.d.ts +0 -6
- package/dist/lockfile-parsers/npm-lock-parser.js +0 -54
- package/dist/lockfile-parsers/pnpm-lock-parser.d.ts +0 -6
- package/dist/lockfile-parsers/pnpm-lock-parser.js +0 -51
- package/dist/lockfile-parsers/yarn-lock-parser.d.ts +0 -6
- package/dist/lockfile-parsers/yarn-lock-parser.js +0 -70
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { stat, readFile } from "fs/promises";
|
|
2
|
-
import * as fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { Glob } from "glob";
|
|
5
|
-
import ignore from "ignore";
|
|
6
|
-
import { parse } from "../ast/parser.js";
|
|
7
|
-
import { analyze } from "../ast/analyze.js";
|
|
8
|
-
import logger from "../common/logging.js";
|
|
9
|
-
/**
|
|
10
|
-
* Get a list of files matching extensions, skips hidden files and node_modules
|
|
11
|
-
* @param base starting directory
|
|
12
|
-
* @param extensions glob syntax of files to look for, e.g. **\/*.{js,jsx,ts,tsx}
|
|
13
|
-
* @param ignorePattern glob syntax of files to ignore, e.g. **\/*.{test,spec}.*
|
|
14
|
-
* @param gitIgnore contents of .gitignore file
|
|
15
|
-
* @returns list of file paths
|
|
16
|
-
*/
|
|
17
|
-
export async function findFiles(base, extensions, ignorePattern) {
|
|
18
|
-
const gitIgnore = await getGitIgnore(base);
|
|
19
|
-
// typescript complains about the ignore() function having
|
|
20
|
-
// no call signature. Could not find a way to fix this.
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
const ig = ignore()
|
|
23
|
-
// skip hidden files and directories
|
|
24
|
-
.add("/**/.*")
|
|
25
|
-
.add("/**/.*/")
|
|
26
|
-
// skip node_modules
|
|
27
|
-
.add("node_modules/")
|
|
28
|
-
// add gitignore rules
|
|
29
|
-
.add(gitIgnore);
|
|
30
|
-
const matchingFiles = [];
|
|
31
|
-
const g = new Glob(extensions, {
|
|
32
|
-
cwd: base,
|
|
33
|
-
ignore: ignorePattern,
|
|
34
|
-
fs,
|
|
35
|
-
});
|
|
36
|
-
for await (const file of g) {
|
|
37
|
-
const fullFilepath = path.join(base, file);
|
|
38
|
-
const meta = await stat(fullFilepath);
|
|
39
|
-
if (!meta.isDirectory() && !ig.ignores(file)) {
|
|
40
|
-
matchingFiles.push(fullFilepath);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return matchingFiles;
|
|
44
|
-
}
|
|
45
|
-
async function getGitIgnore(base) {
|
|
46
|
-
const gitIgnorePath = path.join(base, ".gitignore");
|
|
47
|
-
try {
|
|
48
|
-
return await readFile(gitIgnorePath, "utf-8");
|
|
49
|
-
}
|
|
50
|
-
catch (e) {
|
|
51
|
-
return "";
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
export async function analyzeFiles(extensions, ignorePattern) {
|
|
55
|
-
const files = await findFiles(process.cwd(), extensions, ignorePattern);
|
|
56
|
-
if (files.length === 0) {
|
|
57
|
-
throw new Error("Can't find any relevant files");
|
|
58
|
-
}
|
|
59
|
-
const parseErrors = [];
|
|
60
|
-
const usageMap = new Map();
|
|
61
|
-
for (const file of files) {
|
|
62
|
-
try {
|
|
63
|
-
const fileContents = await readFile(file, "utf-8");
|
|
64
|
-
const { ast, errors } = parse(fileContents, file);
|
|
65
|
-
if (errors.length > 0) {
|
|
66
|
-
logger.error({ file, errors }, "Error parsing file");
|
|
67
|
-
parseErrors.push(`Can't parse file ${file}`);
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
const usage = analyze(ast);
|
|
71
|
-
if (usage.length > 0) {
|
|
72
|
-
const relativePath = file.slice(process.cwd().length);
|
|
73
|
-
usageMap.set(relativePath, usage);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
catch (e) {
|
|
77
|
-
logger.error({ file, error: e }, "Error parsing file");
|
|
78
|
-
parseErrors.push(`Can't parse file ${file}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const errorFile = `/tmp/zh-adoption-analyze-errors-${Date.now()}`;
|
|
82
|
-
if (parseErrors.length > 0) {
|
|
83
|
-
const file = fs.createWriteStream(errorFile);
|
|
84
|
-
parseErrors.forEach((err) => {
|
|
85
|
-
file.write(err + "\n");
|
|
86
|
-
});
|
|
87
|
-
file.end();
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
errorFile: parseErrors.length > 0 ? errorFile : null,
|
|
91
|
-
usage: usageMap,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
export function calculateNumberOfComponents(usageResult) {
|
|
95
|
-
if (usageResult) {
|
|
96
|
-
const components = Array.from(usageResult.entries()).flatMap((comps) => comps[1]);
|
|
97
|
-
const componentCount = components.reduce((prev, next) => {
|
|
98
|
-
return prev + next.count;
|
|
99
|
-
}, 0);
|
|
100
|
-
return componentCount;
|
|
101
|
-
}
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
export function calculateNumberOfColors(usageResult) {
|
|
105
|
-
if (!usageResult)
|
|
106
|
-
return 0;
|
|
107
|
-
const colors = Array.from(usageResult.entries()).flatMap((cols) => cols[1]);
|
|
108
|
-
const colorCount = colors.reduce((prev, next) => {
|
|
109
|
-
return prev + next.totalCount;
|
|
110
|
-
}, 0);
|
|
111
|
-
return colorCount;
|
|
112
|
-
}
|
|
113
|
-
export function countColorOccurrences(fileContent) {
|
|
114
|
-
// Matches #FFF, #FFFA, #FFFFFF or #FFFFFFA
|
|
115
|
-
const hexColorRegex = /#([a-fA-F0-9]{6}|[a-fA-F0-9]{8})\b|#([a-fA-F0-9]{3})\b/gi;
|
|
116
|
-
const hexMatches = Array.from(fileContent.match(hexColorRegex) ?? []);
|
|
117
|
-
// Matches rgb(255, 255, 255) or rgba(255, 255, 255) (with or without commas)
|
|
118
|
-
const rgbColorRegex = /rgba?\(\s*(\d{1,3})\s*[,\s]\s*(\d{1,3})\s*[,\s]\s*(\d{1,3})(?:\s*[,\s]\s*(\d*\.?\d+))?\s*\)/g;
|
|
119
|
-
const rgbMatches = Array.from(fileContent.match(rgbColorRegex) ?? []);
|
|
120
|
-
// Matches hsl and hsla values
|
|
121
|
-
const hslaColorRegex = /hsl(?:a)?\(\s*(?:(?:none|from\s+[a-zA-Z#0-9()]+)?\s*(?:[a-z\d+\-*/%()\s]+)\s*|(\d+(?:deg|grad|rad|turn)?)\s*(\d+%?)\s*(\d+%?)\s*(?:\/\s*(\d+%?|0?\.\d+))?|(\d+(?:deg|grad|rad|turn)?)\s*,\s*(\d+%)\s*,\s*(\d+%)\s*(?:,\s*(\d+(\.\d+)?%?))?)\)/g;
|
|
122
|
-
const hslaMatches = Array.from(fileContent.match(hslaColorRegex) ?? []);
|
|
123
|
-
// Matches oklab and oklch values (with or without commas and opacity)
|
|
124
|
-
const oklabColorRegex = /okl(?:ab|ch)\(\s*(-?\d*\.?\d+)\s*[,\s]\s*(-?\d*\.?\d+)\s*[,\s]\s*(-?\d*\.?\d+)(?:\s*[,\s]\s*(\d*\.?\d+))?\s*\)/g;
|
|
125
|
-
const oklabMatches = Array.from(fileContent.match(oklabColorRegex) ?? []);
|
|
126
|
-
// Matches hwb values (with or without commas and opacity)
|
|
127
|
-
const hwbColorRegex = /hwb\(\s*(\d*\.?\d+)(?:deg|turn|rad|grad)?\s*[,\s]\s*(\d*\.?\d+%)\s*[,\s]\s*(\d*\.?\d+%)(?:\s*[,\s]\s*(\d*\.?\d+))?\s*\)/g;
|
|
128
|
-
const hwbMatches = Array.from(fileContent.match(hwbColorRegex) ?? []);
|
|
129
|
-
// Matches lab values (with or without commas and opacity)
|
|
130
|
-
const labColorRegex = /(?<!ok)lab\(\s*(-?\d*\.?\d+%)\s*[,\s]\s*(-?\d*\.?\d+)\s*[,\s]\s*(-?\d*\.?\d+)(?:\s*[,\s]\s*(\d*\.?\d+))?\s*\)/g;
|
|
131
|
-
const labMatches = Array.from(fileContent.match(labColorRegex) ?? []);
|
|
132
|
-
// Matches lch values (with or without commas and opacity)
|
|
133
|
-
const lchColorRegex = /(?<!ok)lch\(\s*(-?\d*\.?\d+%)\s*[,\s]\s*(-?\d*\.?\d+)\s*[,\s]\s*(-?\d*\.?\d+)(?:\s*[,\s]\s*(\d*\.?\d+))?\s*\)/g;
|
|
134
|
-
const lchMatches = Array.from(fileContent.match(lchColorRegex) ?? []);
|
|
135
|
-
// Matches color space values
|
|
136
|
-
const colorSpaceColorRegex = /color\(\s*([\w-]+)\s+(?:[-+]?\d*\.?\d+(?:e[-+]?\d+)?%?\s*){3,4}\)/g;
|
|
137
|
-
const colorSpaceMatches = Array.from(fileContent.match(colorSpaceColorRegex) ?? []);
|
|
138
|
-
return {
|
|
139
|
-
hex: hexMatches,
|
|
140
|
-
rgb: rgbMatches,
|
|
141
|
-
hsla: hslaMatches,
|
|
142
|
-
oklab: oklabMatches,
|
|
143
|
-
hwb: hwbMatches,
|
|
144
|
-
lab: labMatches,
|
|
145
|
-
lch: lchMatches,
|
|
146
|
-
colorSpace: colorSpaceMatches,
|
|
147
|
-
totalCount: hexMatches.length +
|
|
148
|
-
rgbMatches.length +
|
|
149
|
-
hslaMatches.length +
|
|
150
|
-
hwbMatches.length +
|
|
151
|
-
labMatches.length +
|
|
152
|
-
lchMatches.length +
|
|
153
|
-
colorSpaceMatches.length +
|
|
154
|
-
oklabMatches.length,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
export async function analyzeRawColorUsage(extensions, ignorePattern) {
|
|
158
|
-
const files = await findFiles(process.cwd(), extensions, ignorePattern);
|
|
159
|
-
if (files.length === 0) {
|
|
160
|
-
throw new Error("Can't find any relevant files");
|
|
161
|
-
}
|
|
162
|
-
const parseErrors = [];
|
|
163
|
-
const usageMap = new Map();
|
|
164
|
-
for (const file of files) {
|
|
165
|
-
try {
|
|
166
|
-
const fileContents = await readFile(file, "utf-8");
|
|
167
|
-
const colorUsage = countColorOccurrences(fileContents);
|
|
168
|
-
if (colorUsage.totalCount > 0) {
|
|
169
|
-
const relativePath = file.slice(process.cwd().length);
|
|
170
|
-
usageMap.set(relativePath, colorUsage);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
catch (e) {
|
|
174
|
-
logger.error({ file, error: e }, "Error parsing file");
|
|
175
|
-
parseErrors.push(`Can't parse file ${file}`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
const errorFile = `/tmp/zh-adoption-analyze-errors-${Date.now()}`;
|
|
179
|
-
if (parseErrors.length > 0) {
|
|
180
|
-
const file = fs.createWriteStream(errorFile);
|
|
181
|
-
parseErrors.forEach((err) => {
|
|
182
|
-
file.write(err + "\n");
|
|
183
|
-
});
|
|
184
|
-
file.end();
|
|
185
|
-
}
|
|
186
|
-
return {
|
|
187
|
-
errorFile: parseErrors.length > 0 ? errorFile : null,
|
|
188
|
-
usage: usageMap,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Parse the ignore array and format correctly
|
|
193
|
-
*/
|
|
194
|
-
export function parseGlobList(value, previous) {
|
|
195
|
-
// Ignore default values if option given instead
|
|
196
|
-
if (previous == this.defaultValue) {
|
|
197
|
-
return [value];
|
|
198
|
-
}
|
|
199
|
-
// Concat to array if array already exists
|
|
200
|
-
if (Array.isArray(previous)) {
|
|
201
|
-
return previous.concat(value);
|
|
202
|
-
}
|
|
203
|
-
return [value];
|
|
204
|
-
}
|
package/dist/commands/auth.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { RenderOptions } from "ink";
|
|
3
|
-
interface AuthOptions {
|
|
4
|
-
client?: string;
|
|
5
|
-
token?: string;
|
|
6
|
-
}
|
|
7
|
-
export declare function authAction(options: AuthOptions, renderOptions?: RenderOptions): Promise<void>;
|
|
8
|
-
export declare function authCommand(): Command;
|
|
9
|
-
export {};
|
package/dist/commands/auth.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { Command } from "commander";
|
|
3
|
-
import { render } from "ink";
|
|
4
|
-
import Auth from "../components/auth/auth.js";
|
|
5
|
-
export async function authAction(options, renderOptions) {
|
|
6
|
-
render(React.createElement(Auth, { token: options.token, client: options.client }), renderOptions);
|
|
7
|
-
}
|
|
8
|
-
export function authCommand() {
|
|
9
|
-
const command = new Command();
|
|
10
|
-
return command
|
|
11
|
-
.command("auth")
|
|
12
|
-
.description("Authenticate with zeroheight")
|
|
13
|
-
.configureHelp({
|
|
14
|
-
showGlobalOptions: true,
|
|
15
|
-
})
|
|
16
|
-
.addHelpText("before", "Set credentials for performing actions with zeroheight. Credentials will default to ZEROHEIGHT_CLIENT_ID and ZEROHEIGHT_ACCESS_TOKEN environment variables if not supplied")
|
|
17
|
-
.option("-c, --client <client_id>", "zeroheight Client ID", process.env["ZEROHEIGHT_CLIENT_ID"])
|
|
18
|
-
.option("-t, --token <access_token>", "zeroheight Access Token", process.env["ZEROHEIGHT_ACCESS_TOKEN"])
|
|
19
|
-
.action(async (options) => {
|
|
20
|
-
try {
|
|
21
|
-
await authAction(options);
|
|
22
|
-
}
|
|
23
|
-
catch (e) {
|
|
24
|
-
console.error(e);
|
|
25
|
-
process.exitCode = 1;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { RenderOptions } from "ink";
|
|
3
|
-
interface MonitorRepoOptions {
|
|
4
|
-
interactive: boolean;
|
|
5
|
-
dir?: string[];
|
|
6
|
-
packageName?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function monitorRepoAction(options: MonitorRepoOptions, _renderOptions?: RenderOptions): Promise<void>;
|
|
9
|
-
export declare function monitorRepoCommand(): Command;
|
|
10
|
-
export {};
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { Command, Option } from "commander";
|
|
3
|
-
import { render } from "ink";
|
|
4
|
-
// import yn from "yn";
|
|
5
|
-
import NonInteractiveMonitorRepo from "../components/monitor-repo/non-interactive-monitor-repo.js";
|
|
6
|
-
import { setStdErrStream } from "../common/logging.js";
|
|
7
|
-
export async function monitorRepoAction(options, _renderOptions) {
|
|
8
|
-
// if (options.interactive) {
|
|
9
|
-
// render(<MonitorRepo />, renderOptions);
|
|
10
|
-
// } else {
|
|
11
|
-
render(React.createElement(NonInteractiveMonitorRepo, { packageDirs: options.dir, packageName: options.packageName }));
|
|
12
|
-
// }
|
|
13
|
-
}
|
|
14
|
-
export function monitorRepoCommand() {
|
|
15
|
-
const command = new Command();
|
|
16
|
-
return (command
|
|
17
|
-
.command("monitor-repo")
|
|
18
|
-
.description("Monitor package usage in a repository")
|
|
19
|
-
.configureHelp({
|
|
20
|
-
showGlobalOptions: true,
|
|
21
|
-
})
|
|
22
|
-
// .addOption(
|
|
23
|
-
// new Option(
|
|
24
|
-
// "-in, --interactive [boolean]",
|
|
25
|
-
// "disable to skip manual input (useful when running in CI)"
|
|
26
|
-
// )
|
|
27
|
-
// .default(true)
|
|
28
|
-
// .argParser((value) => yn(value))
|
|
29
|
-
// )
|
|
30
|
-
.addOption(new Option("-d, --dir <path...>", "use package directory to find package.json and lockfile"))
|
|
31
|
-
.addOption(new Option("-p, --package-name <name>", "specify the name used to identify the package in zeroheight"))
|
|
32
|
-
.action(async (options) => {
|
|
33
|
-
setStdErrStream();
|
|
34
|
-
try {
|
|
35
|
-
await monitorRepoAction(options);
|
|
36
|
-
}
|
|
37
|
-
catch (e) {
|
|
38
|
-
console.error(e);
|
|
39
|
-
process.exitCode = 1;
|
|
40
|
-
}
|
|
41
|
-
}));
|
|
42
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import NPMLockParser from "../lockfile-parsers/npm-lock-parser.js";
|
|
2
|
-
import PNPMLockParser from "../lockfile-parsers/pnpm-lock-parser.js";
|
|
3
|
-
import YarnLockParser from "../lockfile-parsers/yarn-lock-parser.js";
|
|
4
|
-
/**
|
|
5
|
-
* Group a list of paths by the directory
|
|
6
|
-
*/
|
|
7
|
-
export declare function groupByBasename(paths: string[]): Record<string, string[]>;
|
|
8
|
-
/**
|
|
9
|
-
* Retrieve name and version from a package.json filepath
|
|
10
|
-
*/
|
|
11
|
-
export declare function getPackageMeta(packageFile: string): Promise<{
|
|
12
|
-
name: string;
|
|
13
|
-
version: string;
|
|
14
|
-
}>;
|
|
15
|
-
export declare function parseLockfile(lockfilePath: string): Promise<NPMLockParser | PNPMLockParser | YarnLockParser>;
|
|
16
|
-
/**
|
|
17
|
-
* Find the lock file based on known lock file names
|
|
18
|
-
* @param subpath - provide to search inside subpath instead of working directory
|
|
19
|
-
*/
|
|
20
|
-
export declare function findLockfiles(subpath?: string): Promise<string[]>;
|
|
21
|
-
/**
|
|
22
|
-
* Get the lockfile parser so name, version and packages can be extracted from the lockfile
|
|
23
|
-
*
|
|
24
|
-
* @param filename the lockfile name
|
|
25
|
-
* @returns the parser to use or null if unrecognized
|
|
26
|
-
*/
|
|
27
|
-
export declare function getLockParserForFile(filename: string): typeof NPMLockParser | typeof PNPMLockParser | typeof YarnLockParser | null;
|
|
28
|
-
/**
|
|
29
|
-
* Get the type of lockfile given the name
|
|
30
|
-
*/
|
|
31
|
-
export declare function getParserTypeFromFileName(filename: string): "yarn" | "npm" | "pnpm" | null;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { readFile } from "fs/promises";
|
|
2
|
-
import { basename, dirname, join as joinPath } from "path";
|
|
3
|
-
import { findFiles } from "./analyze.utils.js";
|
|
4
|
-
import NPMLockParser from "../lockfile-parsers/npm-lock-parser.js";
|
|
5
|
-
import PNPMLockParser from "../lockfile-parsers/pnpm-lock-parser.js";
|
|
6
|
-
import YarnLockParser from "../lockfile-parsers/yarn-lock-parser.js";
|
|
7
|
-
/**
|
|
8
|
-
* Group a list of paths by the directory
|
|
9
|
-
*/
|
|
10
|
-
export function groupByBasename(paths) {
|
|
11
|
-
return paths
|
|
12
|
-
.map((p) => {
|
|
13
|
-
return { base: dirname(p), filename: basename(p) };
|
|
14
|
-
})
|
|
15
|
-
.reduce((acc, pathObj) => {
|
|
16
|
-
acc[pathObj.base] = [...(acc[pathObj.base] ?? []), pathObj.filename];
|
|
17
|
-
return acc;
|
|
18
|
-
}, {});
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Retrieve name and version from a package.json filepath
|
|
22
|
-
*/
|
|
23
|
-
export async function getPackageMeta(packageFile) {
|
|
24
|
-
const packageContents = await readFile(packageFile, "utf-8");
|
|
25
|
-
const packageData = JSON.parse(packageContents);
|
|
26
|
-
return { name: packageData.name, version: packageData.version };
|
|
27
|
-
}
|
|
28
|
-
export async function parseLockfile(lockfilePath) {
|
|
29
|
-
const lockfileName = basename(lockfilePath);
|
|
30
|
-
const ParserClass = getLockParserForFile(lockfileName);
|
|
31
|
-
if (!ParserClass) {
|
|
32
|
-
throw new Error(`Can\'t find parser for ${lockfileName}`);
|
|
33
|
-
}
|
|
34
|
-
const fileContents = await readFile(lockfilePath, "utf-8");
|
|
35
|
-
return new ParserClass(fileContents);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Find the lock file based on known lock file names
|
|
39
|
-
* @param subpath - provide to search inside subpath instead of working directory
|
|
40
|
-
*/
|
|
41
|
-
export async function findLockfiles(subpath) {
|
|
42
|
-
const workingDir = joinPath(process.cwd(), subpath ?? "");
|
|
43
|
-
return findFiles(workingDir, "**/**/{package-lock.json,shrinkwrap.yaml,pnpm-lock.yaml,yarn.lock}", []);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Get the lockfile parser so name, version and packages can be extracted from the lockfile
|
|
47
|
-
*
|
|
48
|
-
* @param filename the lockfile name
|
|
49
|
-
* @returns the parser to use or null if unrecognized
|
|
50
|
-
*/
|
|
51
|
-
export function getLockParserForFile(filename) {
|
|
52
|
-
switch (filename) {
|
|
53
|
-
case "yarn.lock":
|
|
54
|
-
return YarnLockParser;
|
|
55
|
-
case "package-lock.json":
|
|
56
|
-
return NPMLockParser;
|
|
57
|
-
case "pnpm-lock.yaml":
|
|
58
|
-
return PNPMLockParser;
|
|
59
|
-
case "shrinkwrap.yaml":
|
|
60
|
-
return PNPMLockParser;
|
|
61
|
-
default:
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get the type of lockfile given the name
|
|
67
|
-
*/
|
|
68
|
-
export function getParserTypeFromFileName(filename) {
|
|
69
|
-
switch (filename) {
|
|
70
|
-
case "yarn.lock":
|
|
71
|
-
return "yarn";
|
|
72
|
-
case "package-lock.json":
|
|
73
|
-
return "npm";
|
|
74
|
-
case "pnpm-lock.yaml":
|
|
75
|
-
return "pnpm";
|
|
76
|
-
case "shrinkwrap.yaml":
|
|
77
|
-
return "pnpm";
|
|
78
|
-
default:
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
import { RenderOptions } from "ink";
|
|
3
|
-
interface TrackPackageOptions {
|
|
4
|
-
interactive: boolean;
|
|
5
|
-
packages?: string[];
|
|
6
|
-
}
|
|
7
|
-
export declare function trackPackageAction(options: TrackPackageOptions, renderOptions?: RenderOptions): Promise<void>;
|
|
8
|
-
export declare function trackPackageCommand(): Command;
|
|
9
|
-
export {};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { Command, Option } from "commander";
|
|
3
|
-
import { render } from "ink";
|
|
4
|
-
import yn from "yn";
|
|
5
|
-
import NonInteractiveTrackPackage from "../components/track-package/non-interactive-track-package.js";
|
|
6
|
-
import TrackPackage from "../components/track-package/track-package.js";
|
|
7
|
-
import { setStdErrStream } from "../common/logging.js";
|
|
8
|
-
import { parsePackageList } from "./track-package.utils.js";
|
|
9
|
-
export async function trackPackageAction(options, renderOptions) {
|
|
10
|
-
if (options.interactive) {
|
|
11
|
-
render(React.createElement(TrackPackage, null), renderOptions);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
render(React.createElement(NonInteractiveTrackPackage, { allowedPackages: options.packages }));
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export function trackPackageCommand() {
|
|
18
|
-
const command = new Command();
|
|
19
|
-
return command
|
|
20
|
-
.command("track-package")
|
|
21
|
-
.description("Track the latest version of your package in zeroheight")
|
|
22
|
-
.configureHelp({
|
|
23
|
-
showGlobalOptions: true,
|
|
24
|
-
})
|
|
25
|
-
.addOption(new Option("-in, --interactive [boolean]", "disable to skip manual input (useful when running in CI)")
|
|
26
|
-
.default(true)
|
|
27
|
-
.argParser((value) => yn(value)))
|
|
28
|
-
.addOption(new Option("-p, --packages [packageNames]", "specify the packages to search for, use multiple times to match more than one package").argParser(parsePackageList))
|
|
29
|
-
.action(async (options) => {
|
|
30
|
-
if (!options.interactive) {
|
|
31
|
-
setStdErrStream();
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
await trackPackageAction(options);
|
|
35
|
-
}
|
|
36
|
-
catch (e) {
|
|
37
|
-
console.error(e);
|
|
38
|
-
process.exitCode = 1;
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { PackageFile } from "../common/types/package-file.js";
|
|
2
|
-
/**
|
|
3
|
-
* Find the package.json file
|
|
4
|
-
* @param subpath - provide to search inside subpath instead of working directory
|
|
5
|
-
*/
|
|
6
|
-
export declare function findPackageFiles(subpath?: string): Promise<string[]>;
|
|
7
|
-
/**
|
|
8
|
-
* Get allowed package files from the directory and return
|
|
9
|
-
* their name/package/version/exports
|
|
10
|
-
*
|
|
11
|
-
* @param allowedPackages a list of package names to match on
|
|
12
|
-
* @returns a list of matched packages files and errors
|
|
13
|
-
*/
|
|
14
|
-
export declare function getPackageInfo(allowedPackages?: string[]): Promise<{
|
|
15
|
-
files: PackageFile[];
|
|
16
|
-
error: string | null;
|
|
17
|
-
}>;
|
|
18
|
-
/**
|
|
19
|
-
* Transform exports object into fully qualified aliases
|
|
20
|
-
*/
|
|
21
|
-
export declare function getAliasesFromExports(packageName: string, exports?: PackageFile["exports"]): string[];
|
|
22
|
-
/**
|
|
23
|
-
* Parse package list and format correctly
|
|
24
|
-
*/
|
|
25
|
-
export declare function parsePackageList(value: string, previous?: string[]): string[];
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { readFile } from "fs/promises";
|
|
2
|
-
import { join as joinPath } from "path";
|
|
3
|
-
import { findFiles } from "./analyze.utils.js";
|
|
4
|
-
/**
|
|
5
|
-
* Find the package.json file
|
|
6
|
-
* @param subpath - provide to search inside subpath instead of working directory
|
|
7
|
-
*/
|
|
8
|
-
export async function findPackageFiles(subpath) {
|
|
9
|
-
const workingDir = joinPath(process.cwd(), subpath ?? "");
|
|
10
|
-
return findFiles(workingDir, "**/**/package.json", []);
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Get allowed package files from the directory and return
|
|
14
|
-
* their name/package/version/exports
|
|
15
|
-
*
|
|
16
|
-
* @param allowedPackages a list of package names to match on
|
|
17
|
-
* @returns a list of matched packages files and errors
|
|
18
|
-
*/
|
|
19
|
-
export async function getPackageInfo(allowedPackages) {
|
|
20
|
-
const base = process.cwd();
|
|
21
|
-
const files = await findPackageFiles();
|
|
22
|
-
if (files.length === 0) {
|
|
23
|
-
return {
|
|
24
|
-
files: [],
|
|
25
|
-
error: "Can't find any package files",
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
try {
|
|
29
|
-
let packageFiles = await Promise.all(files.map(async (file) => {
|
|
30
|
-
const fileContents = await readFile(file, "utf-8");
|
|
31
|
-
const parsedPackage = JSON.parse(fileContents);
|
|
32
|
-
return {
|
|
33
|
-
name: parsedPackage.name,
|
|
34
|
-
path: `.${file.split(base).pop()}`,
|
|
35
|
-
// Default to 0.0.0 as we don't have a version so it might be a workspaces project/monorepo
|
|
36
|
-
version: parsedPackage.version ?? "0.0.0",
|
|
37
|
-
exports: parsedPackage.exports,
|
|
38
|
-
};
|
|
39
|
-
}));
|
|
40
|
-
if (allowedPackages?.length) {
|
|
41
|
-
packageFiles = packageFiles.filter((pack) => allowedPackages.includes(pack.name));
|
|
42
|
-
if (!packageFiles.length) {
|
|
43
|
-
return {
|
|
44
|
-
files: [],
|
|
45
|
-
error: "Can't find any matching packages",
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return {
|
|
50
|
-
files: packageFiles,
|
|
51
|
-
error: null,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
return {
|
|
56
|
-
files: [],
|
|
57
|
-
error: `Can't parse file ${files[0]}`,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Transform exports object into fully qualified aliases
|
|
63
|
-
*/
|
|
64
|
-
export function getAliasesFromExports(packageName, exports) {
|
|
65
|
-
if (!exports)
|
|
66
|
-
return [];
|
|
67
|
-
return Object.keys(exports)
|
|
68
|
-
.map((path) => joinPath(packageName, path))
|
|
69
|
-
.filter((name) => name !== packageName);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Parse package list and format correctly
|
|
73
|
-
*/
|
|
74
|
-
export function parsePackageList(value, previous = []) {
|
|
75
|
-
return [
|
|
76
|
-
...previous,
|
|
77
|
-
...value
|
|
78
|
-
.split(",")
|
|
79
|
-
.map((entry) => entry.trim())
|
|
80
|
-
.filter(Boolean),
|
|
81
|
-
];
|
|
82
|
-
}
|
package/dist/common/api.d.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { ComponentProps } from "../ast/analyze.js";
|
|
2
|
-
import { RawColorUsageMap, RawComponentUsageMap } from "../commands/analyze.js";
|
|
3
|
-
import { Credentials } from "./config.js";
|
|
4
|
-
export interface ComponentUsageRecord {
|
|
5
|
-
name: string;
|
|
6
|
-
files: string[];
|
|
7
|
-
count: number;
|
|
8
|
-
package: string;
|
|
9
|
-
props: ComponentProps;
|
|
10
|
-
}
|
|
11
|
-
export interface TokenLiteralUsageRecord {
|
|
12
|
-
value: string;
|
|
13
|
-
files: string[];
|
|
14
|
-
/** Only support color values right now */
|
|
15
|
-
type: "color";
|
|
16
|
-
count: number;
|
|
17
|
-
}
|
|
18
|
-
export declare enum ResponseStatus {
|
|
19
|
-
Success = "success",
|
|
20
|
-
Error = "error",
|
|
21
|
-
Fail = "fail"
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Open API V2 Response format
|
|
25
|
-
*/
|
|
26
|
-
interface BaseResponse<T> {
|
|
27
|
-
status: ResponseStatus;
|
|
28
|
-
message: string;
|
|
29
|
-
data: T;
|
|
30
|
-
}
|
|
31
|
-
interface SuccessResponse<T> extends BaseResponse<T> {
|
|
32
|
-
status: ResponseStatus.Success;
|
|
33
|
-
}
|
|
34
|
-
interface FailResponse<T> extends BaseResponse<T> {
|
|
35
|
-
status: ResponseStatus.Fail;
|
|
36
|
-
}
|
|
37
|
-
interface ErrorResponse<T> extends BaseResponse<T> {
|
|
38
|
-
status: ResponseStatus.Error;
|
|
39
|
-
}
|
|
40
|
-
export type APIResponse<S = {}, F = {}, E = {}> = SuccessResponse<S> | FailResponse<F> | ErrorResponse<E>;
|
|
41
|
-
export declare function getZeroheightURL(): URL;
|
|
42
|
-
interface PackageDetailsSuccessResponse {
|
|
43
|
-
design_system_packages: {
|
|
44
|
-
id: number;
|
|
45
|
-
name: string;
|
|
46
|
-
path: string;
|
|
47
|
-
latest_version: string;
|
|
48
|
-
source: string;
|
|
49
|
-
repository_id: number | null;
|
|
50
|
-
team_id: number | null;
|
|
51
|
-
project_id: number | null;
|
|
52
|
-
created_at: string;
|
|
53
|
-
updated_at: string;
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
export declare function submitPackageDetails(name: string, path: string, version: string, aliases: string[], credentials: Credentials): Promise<APIResponse<PackageDetailsSuccessResponse, {}, {}>>;
|
|
57
|
-
interface MonitoredRepoDetailsSuccess {
|
|
58
|
-
monitored_repository: {
|
|
59
|
-
id: number;
|
|
60
|
-
lock_file_path: string;
|
|
61
|
-
repository_id: number;
|
|
62
|
-
team_id: number | null;
|
|
63
|
-
project_id: number | null;
|
|
64
|
-
created_at: string;
|
|
65
|
-
updated_at: string;
|
|
66
|
-
name: string;
|
|
67
|
-
source: string;
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
export declare function submitMonitoredRepoDetails(name: string, version: string, lockfilePath: string, packages: {
|
|
71
|
-
name: string;
|
|
72
|
-
version: string;
|
|
73
|
-
}[], credentials: Credentials): Promise<APIResponse<MonitoredRepoDetailsSuccess>>;
|
|
74
|
-
interface ComponentUsageDetailsSuccess {
|
|
75
|
-
component_usage: {
|
|
76
|
-
id: number;
|
|
77
|
-
usage: {
|
|
78
|
-
name: string;
|
|
79
|
-
count: number;
|
|
80
|
-
package: string;
|
|
81
|
-
files: string[];
|
|
82
|
-
}[];
|
|
83
|
-
team_id: number | null;
|
|
84
|
-
project_id: number | null;
|
|
85
|
-
created_at: string;
|
|
86
|
-
updated_at: string;
|
|
87
|
-
repo_name: string;
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
export declare function submitComponentUsageData(usage: RawComponentUsageMap, repoName: string, credentials: Credentials): Promise<APIResponse<ComponentUsageDetailsSuccess>>;
|
|
91
|
-
interface TokenLiteralUsageDetailsSuccess {
|
|
92
|
-
token_literal_usage: {};
|
|
93
|
-
}
|
|
94
|
-
export declare function submitTokenLiteralUsageData(usage: RawColorUsageMap, repoName: string, credentials: Credentials): Promise<APIResponse<TokenLiteralUsageDetailsSuccess>>;
|
|
95
|
-
interface RepoNamesSuccess {
|
|
96
|
-
repo_names: string[];
|
|
97
|
-
}
|
|
98
|
-
export declare function getExistingRepoNames(credentials: Credentials): Promise<APIResponse<RepoNamesSuccess>>;
|
|
99
|
-
interface AuthTokensResponse {
|
|
100
|
-
scopes: string[];
|
|
101
|
-
email: string;
|
|
102
|
-
project: {
|
|
103
|
-
id: number;
|
|
104
|
-
name: string;
|
|
105
|
-
} | null;
|
|
106
|
-
team: {
|
|
107
|
-
id: number;
|
|
108
|
-
name: string;
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
export declare function getAuthDetails(credentials: Credentials): Promise<APIResponse<AuthTokensResponse>>;
|
|
112
|
-
export declare function mergeUsageProps(newProps: ComponentProps, currentProps?: ComponentProps): any;
|
|
113
|
-
export {};
|