Skip to content

Commit

Permalink
feat: add installed packages to the context
Browse files Browse the repository at this point in the history
  • Loading branch information
velut committed Dec 22, 2023
1 parent 1591ab3 commit c1bee7f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
4 changes: 3 additions & 1 deletion src/extract-api-from-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ export const extractApiFromPackage = (
})),
)
.andThen((ctx) =>
installPackage(ctx.pkg).map(() => ({
installPackage(ctx.pkg).map((installedPackages) => ({
...ctx,
nodeModulesDir: join(ctx.rootDir, "node_modules"),
pkgDir: join(ctx.rootDir, "node_modules", ctx.pkgName),
installedPackages,
})),
)
.andThen((ctx) =>
Expand Down Expand Up @@ -87,6 +88,7 @@ export const extractApiFromPackage = (
console.log(
JSON.stringify(
{
installedPackages: ctx.installedPackages,
indexFile: indexFile.getFilePath().replace(ctx.nodeModulesDir, ""),
sourceFiles,
referencedFiles,
Expand Down
48 changes: 48 additions & 0 deletions src/install-package.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ok } from "neverthrow";
import { temporaryDirectoryTask } from "tempy";
import { expect, test } from "vitest";
import { InstallPackageError } from "./errors";
import { installPackage } from "./install-package";

test("invalid package", async () => {
await temporaryDirectoryTask(async (dir) => {
process.chdir(dir);
const res = await installPackage("");
expect(res.isErr()).toBe(true);
expect(res._unsafeUnwrapErr() instanceof InstallPackageError).toBe(true);
});
});

test("package with no production dependencies", async () => {
await temporaryDirectoryTask(async (dir) => {
process.chdir(dir);
const installedPackages = await installPackage("verify-hcaptcha@1.0.0");
expect(installedPackages).toStrictEqual(ok(["verify-hcaptcha@1.0.0"]));
});
});

test("package with some production dependencies", async () => {
await temporaryDirectoryTask(async (dir) => {
process.chdir(dir);
const installedPackages = await installPackage("query-registry@2.6.0");
expect(installedPackages).toStrictEqual(
ok([
"builtins@5.0.1",
"isomorphic-unfetch@3.1.0",
"lru-cache@6.0.0",
"make-error@1.3.6",
"node-fetch@2.7.0",
"query-registry@2.6.0",
"semver@7.5.4",
"tiny-lru@8.0.2",
"tr46@0.0.3",
"unfetch@4.2.0",
"url-join@4.0.1",
"validate-npm-package-name@4.0.0",
"webidl-conversions@3.0.1",
"whatwg-url@5.0.0",
"yallist@4.0.0",
]),
);
});
});
22 changes: 18 additions & 4 deletions src/install-package.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import { $ } from "execa";
import { execa } from "execa";
import { ResultAsync } from "neverthrow";
import { InstallPackageError } from "./errors";

export const installPackage = (pkg: string) =>
export const installPackage = (
pkg: string,
): ResultAsync<string[], InstallPackageError> =>
ResultAsync.fromPromise(
$`bun add ${pkg}`,
execa("bun", ["add", pkg, "--verbose"]),
(e) => new InstallPackageError("failed to install package", { cause: e }),
);
).map(({ stdout }) => {
// With verbose output on, bun prints one line per installed package
// (for example, "foo@1.0.0"), including all installed dependencies.
// These lines are between the two delimiting lines found here:
// https://github.com/oven-sh/bun/blob/main/src/install/lockfile.zig#L5354-L5355.
const lines = stdout.split("\n");
const beginHash = lines.findIndex((line) =>
line.startsWith("-- BEGIN SHA512/256"),
);
const endHash = lines.findIndex((line) => line.startsWith("-- END HASH"));
const installedPackages = lines.slice(beginHash + 1, endHash);
return installedPackages;
});

0 comments on commit c1bee7f

Please sign in to comment.