keycloak_theme/src/bin/tools/listInstalledModules.ts

132 lines
4.0 KiB
TypeScript
Raw Normal View History

2024-11-02 22:39:03 +01:00
import { assert, type Equals } from "tsafe/assert";
import { id } from "tsafe/id";
import { z } from "zod";
2024-11-09 14:02:19 +01:00
import { join as pathJoin, dirname as pathDirname } from "path";
2024-11-02 22:39:03 +01:00
import * as fsPr from "fs/promises";
import { is } from "tsafe/is";
import { getInstalledModuleDirPath } from "../tools/getInstalledModuleDirPath";
2024-11-09 14:02:19 +01:00
import { exclude } from "tsafe/exclude";
2024-11-02 22:39:03 +01:00
export async function listInstalledModules(params: {
packageJsonFilePath: string;
projectDirPath: string;
filter: (params: { moduleName: string }) => boolean;
2024-11-03 01:56:41 +01:00
}): Promise<
{
moduleName: string;
version: string;
dirPath: string;
peerDependencies: Record<string, string>;
}[]
> {
2024-11-02 22:39:03 +01:00
const { packageJsonFilePath, projectDirPath, filter } = params;
const parsedPackageJson = await readPackageJsonDependencies({
packageJsonFilePath
});
const uiModuleNames = (
[parsedPackageJson.dependencies, parsedPackageJson.devDependencies] as const
)
2024-11-09 14:02:19 +01:00
.filter(exclude(undefined))
2024-11-02 22:39:03 +01:00
.map(obj => Object.keys(obj))
.flat()
.filter(moduleName => filter({ moduleName }));
2024-11-03 01:56:41 +01:00
2024-11-02 22:39:03 +01:00
const result = await Promise.all(
uiModuleNames.map(async moduleName => {
const dirPath = await getInstalledModuleDirPath({
moduleName,
2024-11-09 14:02:19 +01:00
packageJsonDirPath: pathDirname(packageJsonFilePath),
2024-11-02 22:39:03 +01:00
projectDirPath
});
2024-11-03 01:56:41 +01:00
const { version, peerDependencies } =
await readPackageJsonVersionAndPeerDependencies({
packageJsonFilePath: pathJoin(dirPath, "package.json")
});
2024-11-02 22:39:03 +01:00
2024-11-03 01:56:41 +01:00
return { moduleName, version, peerDependencies, dirPath } as const;
2024-11-02 22:39:03 +01:00
})
);
return result;
}
const { readPackageJsonDependencies } = (() => {
type ParsedPackageJson = {
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
};
const zParsedPackageJson = (() => {
type TargetType = ParsedPackageJson;
const zTargetType = z.object({
dependencies: z.record(z.string()).optional(),
devDependencies: z.record(z.string()).optional()
});
assert<Equals<z.infer<typeof zTargetType>, TargetType>>();
return id<z.ZodType<TargetType>>(zTargetType);
})();
async function readPackageJsonDependencies(params: { packageJsonFilePath: string }) {
const { packageJsonFilePath } = params;
const parsedPackageJson = JSON.parse(
(await fsPr.readFile(packageJsonFilePath)).toString("utf8")
);
zParsedPackageJson.parse(parsedPackageJson);
assert(is<ParsedPackageJson>(parsedPackageJson));
return parsedPackageJson;
}
return { readPackageJsonDependencies };
})();
2024-11-03 01:56:41 +01:00
const { readPackageJsonVersionAndPeerDependencies } = (() => {
2024-11-02 22:39:03 +01:00
type ParsedPackageJson = {
version: string;
2024-11-03 01:56:41 +01:00
peerDependencies?: Record<string, string>;
2024-11-02 22:39:03 +01:00
};
const zParsedPackageJson = (() => {
type TargetType = ParsedPackageJson;
const zTargetType = z.object({
2024-11-03 01:56:41 +01:00
version: z.string(),
peerDependencies: z.record(z.string()).optional()
2024-11-02 22:39:03 +01:00
});
assert<Equals<z.infer<typeof zTargetType>, TargetType>>();
return id<z.ZodType<TargetType>>(zTargetType);
})();
2024-11-03 01:56:41 +01:00
async function readPackageJsonVersionAndPeerDependencies(params: {
packageJsonFilePath: string;
}): Promise<{ version: string; peerDependencies: Record<string, string> }> {
2024-11-02 22:39:03 +01:00
const { packageJsonFilePath } = params;
const parsedPackageJson = JSON.parse(
(await fsPr.readFile(packageJsonFilePath)).toString("utf8")
);
zParsedPackageJson.parse(parsedPackageJson);
assert(is<ParsedPackageJson>(parsedPackageJson));
2024-11-03 01:56:41 +01:00
return {
version: parsedPackageJson.version,
peerDependencies: parsedPackageJson.peerDependencies ?? {}
};
2024-11-02 22:39:03 +01:00
}
2024-11-03 01:56:41 +01:00
return { readPackageJsonVersionAndPeerDependencies };
2024-11-02 22:39:03 +01:00
})();