Skip to content

Commit

Permalink
refactor: remove setupFrameworkPlugin() function
Browse files Browse the repository at this point in the history
  • Loading branch information
fwouts committed Oct 16, 2023
1 parent db06a24 commit 54a66ad
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 138 deletions.
25 changes: 17 additions & 8 deletions core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ import createLogger from "pino";
import prettyLogger from "pino-pretty";
import { crawlFiles } from "./crawl-files";
import { getFreePort } from "./get-free-port";
import type { FrameworkPluginFactory } from "./plugins/framework";
import { setupFrameworkPlugin } from "./plugins/setup-framework-plugin";
import { extractPackageDependencies } from "./plugins/dependencies";
import type {
FrameworkPlugin,
FrameworkPluginFactory,
} from "./plugins/framework";
import type { OnServerStart } from "./preview-env";
import { Previewer } from "./previewer";
import { ApiRouter } from "./router";
Expand Down Expand Up @@ -61,12 +64,18 @@ export async function createWorkspace({
reader?: Reader;
onServerStart?: OnServerStart;
}): Promise<Workspace> {
const frameworkPlugin = await setupFrameworkPlugin({
rootDir,
frameworkPlugins,
reader,
logger,
});
const dependencies = await extractPackageDependencies(logger, rootDir);
let frameworkPlugin!: FrameworkPlugin;
for (const candidate of frameworkPlugins) {
if (await candidate.isCompatible(dependencies)) {
frameworkPlugin = await candidate.create({
rootDir,
reader,
logger,
dependencies,
});
}
}
if (!frameworkPlugin) {
throw new NoCompatiblePluginError(
`No compatible plugin found for workspace with root: ${rootDir}`
Expand Down
103 changes: 103 additions & 0 deletions core/src/plugins/dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import fs from "fs-extra";
import { createRequire } from "module";
import path from "path";
import type { Logger } from "pino";

const require = createRequire(import.meta.url);

export type PackageDependencies = Record<
string,
{
Expand All @@ -7,3 +14,99 @@ export type PackageDependencies = Record<
readInstalledVersion(): Promise<string | null>;
}
>;

export async function extractPackageDependencies(
logger: Logger,
rootDir: string
): Promise<PackageDependencies> {
const packageJsonPath = path.join(rootDir, "package.json");
if (!(await fs.pathExists(packageJsonPath))) {
return {};
}
const { dependencies, devDependencies, peerDependencies } = JSON.parse(
await fs.readFile(packageJsonPath, "utf8")
);
const allDependencies = {
...dependencies,
...devDependencies,
...peerDependencies,
};
return Object.fromEntries(
Object.entries(allDependencies).map(
([name, version]): [string, PackageDependencies[string]] => {
let majorVersion: number;
if (typeof version !== "string") {
majorVersion = 0;
} else if (version.startsWith("^") || version.startsWith("~")) {
majorVersion = parseInt(version.slice(1));
} else {
majorVersion = parseInt(version);
}
const readInstalledVersion = async () => {
try {
const moduleEntryPath = findModuleEntryPath(name, rootDir);
let packagePath = moduleEntryPath;
let packageJsonPath: string | null = null;
while (packagePath !== path.dirname(packagePath)) {
const candidatePackageJsonPath = path.join(
packagePath,
"package.json"
);
if (fs.existsSync(candidatePackageJsonPath)) {
packageJsonPath = candidatePackageJsonPath;
break;
}
packagePath = path.dirname(packagePath);
}
if (!packageJsonPath) {
throw new Error(
`No package.json path found from: ${moduleEntryPath}`
);
}
const packageInfo = JSON.parse(
await fs.readFile(packageJsonPath, "utf8")
);
const version = packageInfo["version"];
if (!version || typeof version !== "string") {
throw new Error(
`Invalid version found for package: ${packageJsonPath}`
);
}
return version;
} catch (e) {
logger.error(
`Unable to read installed version of package: ${name}`,
e
);
return null;
}
};
return [name, { majorVersion, readInstalledVersion }];
}
)
);
}

function findModuleEntryPath(name: string, rootDir: string): string {
try {
return require.resolve(name, {
paths: [rootDir],
});
} catch (e: any) {
if (e.code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
// When this occurs, the error conveniently includes the package path we're precisely trying to extract.
//
// Note: this could break in future Node versions.
//
// Example:
// Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in .../nuxt-app/node_modules/nuxt/package.json
const potentialMatch = (e.message as string).match(
/No "exports" main defined in (.*)(\/|\\)package\.json/
);
if (potentialMatch) {
return potentialMatch[1]!;
}
}
throw e;
}
}
130 changes: 0 additions & 130 deletions core/src/plugins/setup-framework-plugin.ts

This file was deleted.

0 comments on commit 54a66ad

Please sign in to comment.