This commit is contained in:
Stefan Pejcic
2024-05-08 19:58:53 +02:00
parent 440d98beff
commit 8595a9f4e5
2479 changed files with 591504 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
import React from "react";
import dedent from "dedent";
import { SWIZZLE_CODES } from "@utils/swizzle/codes";
import chalk from "chalk";
import { markedTerminalRenderer } from "@utils/marked-terminal-renderer";
type Params = {
label: string;
files: [targetPath: string, statusCode: string][];
message?: string;
};
export const printSwizzleMessage = ({
label,
files,
message = "**`Warning:`** You should use the component where you want to use it.",
}: Params) => {
const errors = files.filter(([, statusCode]) =>
Object.values(SWIZZLE_CODES)
.filter((code) => code !== SWIZZLE_CODES.SUCCESS)
.includes(statusCode),
);
let status = "success";
switch (errors.length) {
// no errors
case 0:
status = "success";
break;
// all errors
case files.length:
status = "error";
break;
// some errors
default:
status = "warning";
break;
}
const clearFilePath = (filePath: string) => {
const relative = filePath?.replace(process.cwd(), "");
if (relative?.startsWith("/")) {
return relative.slice(1);
}
if (relative?.startsWith("./")) {
return relative.slice(2);
}
return relative;
};
const printStatusMessage = () => {
switch (status) {
case "success":
console.log(
chalk.blueBright(
`Successfully swizzled ${chalk.bold(label)}`,
),
);
return;
case "warning":
console.log(
chalk.yellowBright(
`Swizzle completed with errors for ${chalk.bold(
label,
)}`,
),
);
return;
case "error":
console.log(
chalk.redBright(`Swizzle failed for ${chalk.bold(label)}`),
);
return;
default:
return;
}
};
const printFiles = () => {
const chalks = [];
chalks.push(chalk.dim(`File${files.length > 1 ? "s" : ""} created:`));
chalks.push(
files
.map(([targetPath, statusCode]) => {
if (statusCode === SWIZZLE_CODES.SUCCESS) {
return chalk.cyanBright.dim(
` - ${clearFilePath(targetPath)}`,
);
}
if (statusCode === SWIZZLE_CODES.TARGET_ALREADY_EXISTS) {
return chalk.cyanBright.dim(
` - ${chalk.yellowBright.bold(
"[FILE_ALREADY_EXISTS] ",
)}${clearFilePath(targetPath)}`,
);
}
if (statusCode === SWIZZLE_CODES.SOURCE_PATH_NOT_A_FILE) {
return chalk.cyanBright.dim(
` - ${chalk.yellowBright.bold(
"[SOURCE NOT FOUND] ",
)}${clearFilePath(targetPath)}`,
);
}
return chalk.cyanBright.dim(
` - ${chalk.yellowBright.bold(
`[${statusCode}]`,
)}${clearFilePath(targetPath)}`,
);
})
.join("\n"),
);
console.log(chalks.join("\n"));
};
const printSwizzleMessage = () => {
if (message && status !== "error") {
console.log(markedTerminalRenderer(dedent("\n" + message)));
}
};
console.log("");
printStatusMessage();
printFiles();
console.log("");
printSwizzleMessage();
};

View File

@@ -0,0 +1 @@
export * from "./table";

View File

@@ -0,0 +1,52 @@
import * as packageUtils from "@utils/package";
import { getInstallCommand } from "./table";
test("Update warning npm command", async () => {
const testCases: {
output: string;
dependencies: string[];
scripts: Record<string, string>;
}[] = [
// have script, have dependency
{
output: "npm run refine update",
dependencies: ["@refinedev/cli"],
scripts: {
refine: "refine",
},
},
// has script, no dependency
{
output: "npm run refine update",
dependencies: ["@pankod/tefine-cli"],
scripts: {
refine: "refine",
},
},
// no script, has dependency
{
output: "npx refine update",
dependencies: ["@refinedev/cli"],
scripts: {
tefine: "refine",
},
},
// no script, no dependency
{
output: "npx @refinedev/cli update",
dependencies: [],
scripts: {},
},
];
for (const testCase of testCases) {
jest.spyOn(packageUtils, "getDependencies").mockReturnValue(
testCase.dependencies,
);
jest.spyOn(packageUtils, "getScripts").mockReturnValue(
testCase.scripts,
);
expect(await getInstallCommand()).toBe(testCase.output);
}
});

View File

@@ -0,0 +1,168 @@
import React from "react";
import { RefinePackageInstalledVersionData } from "@definitions/package";
import Table from "cli-table3";
import chalk from "chalk";
import center from "center-align";
import { getDependencies, getPreferedPM, getScripts } from "@utils/package";
import { removeANSIColors } from "@utils/text";
const columns = {
name: "name",
current: "current",
wanted: "wanted",
latest: "latest",
changelog: "changelog",
} as const;
const orderedColumns: (typeof columns)[keyof typeof columns][] = [
columns.name,
columns.current,
columns.wanted,
columns.latest,
columns.changelog,
];
export interface UpdateWarningTableParams {
data: RefinePackageInstalledVersionData[];
}
export const printUpdateWarningTable = async (
params: UpdateWarningTableParams,
) => {
const data = params?.data;
const tableHead = Object.keys(data?.[0] || {});
if (!data || !tableHead.length) return;
const table = new Table({
head: orderedColumns,
style: {
head: ["blue"],
},
});
data.forEach((row) => {
table.push(
orderedColumns.map((column) => {
const columnValue = row[column];
if (!columnValue) return columnValue;
if (column === "latest" || column === "wanted") {
const installedVersion = parseVersions(row.current);
const latestVersion = parseVersions(columnValue);
const colors = getColorsByVersionDiffrence(
installedVersion,
latestVersion,
);
const textMajor = chalk[colors.major](latestVersion.major);
const textMinor = chalk[colors.minor](latestVersion.minor);
const textPatch = chalk[colors.patch](latestVersion.patch);
return `${textMajor}.${textMinor}.${textPatch}`;
}
if (column === "changelog") {
return chalk.blueBright.underline(columnValue);
}
return columnValue;
}),
);
});
const tableOutput = table.toString();
const tableWidth = removeANSIColors(
tableOutput.split("\n")?.[0] || "",
).length;
console.log();
console.log(center("Update Available", tableWidth));
console.log(tableOutput);
console.log(
center(
`To update ${chalk.bold("`refine`")} packages with wanted version`,
tableWidth,
),
);
console.log(
center(
` Run the following command: ${chalk.yellowBright(
await getInstallCommand(),
)}`,
tableWidth,
),
);
console.log();
};
const parseVersions = (text: string) => {
const versions = text.split(".");
return {
major: versions[0],
minor: versions[1],
patch: versions[2],
};
};
const getColorsByVersionDiffrence = (
installedVersion: ReturnType<typeof parseVersions>,
nextVersion: ReturnType<typeof parseVersions>,
) => {
const isMajorDiffrence =
installedVersion.major.trim() !== nextVersion.major.trim();
if (isMajorDiffrence)
return {
major: "red",
minor: "red",
patch: "red",
} as const;
const isMinorDiffrence =
installedVersion.minor.trim() !== nextVersion.minor.trim();
if (isMinorDiffrence)
return {
major: "white",
minor: "yellow",
patch: "yellow",
} as const;
const isPatchDiffrence =
installedVersion.patch.trim() !== nextVersion.patch.trim();
if (isPatchDiffrence)
return {
major: "white",
minor: "white",
patch: "green",
} as const;
return {
major: "white",
minor: "white",
patch: "white",
} as const;
};
export const getInstallCommand = async () => {
const fallbackCommand = `npx @refinedev/cli update`;
const dependencies = getDependencies();
const scriptKeys = Object.keys(getScripts());
const hasCli = dependencies.includes("@refinedev/cli");
const hasScript = scriptKeys.includes("refine");
if (!hasCli && !hasScript) {
return fallbackCommand;
}
const pm = await getPreferedPM();
if (hasScript) {
return `${pm.name} run refine update`;
}
if (hasCli) {
return `npx refine update`;
}
return fallbackCommand;
};