@corejam/base
Version:
A scaffolding for building progressive GraphQL powered jamstack applications
144 lines • 5.01 kB
JavaScript
import * as fs from "fs";
import * as path from "path";
import { PluginLoadError } from "./Errors";
/**
* Check if we are currently a plugin that needs to load server side code.
* If packageName is provided we check that.
*
* Otherwise we default to checking current process.cwd if we are inside a package.
*/
export function isAPlugin(packageName) {
try {
if (!packageName) {
packageName = process.cwd();
}
const packageJson = require(packageName + "/package.json");
if (!Object.prototype.hasOwnProperty.call(packageJson, "corejam"))
return false;
let hasServerDir = false;
if (process.env.NODE_ENV === "test")
hasServerDir = typeof require.resolve(`${packageName}/server/`) === "string";
else {
hasServerDir = typeof require.resolve(`${packageName}/dist/server/`) === "string";
}
return hasServerDir ? true : false;
}
catch (e) {
return false;
}
}
/**
* Collect all corejam plugins that are currently active
* so we can bootstrap them individually.
*
* @param path
*/
export function collectPlugins(path = process.cwd()) {
const packageJson = require(path + "/package.json");
const deps = packageJson.dependencies ? Object.keys(packageJson.dependencies) : [];
const devDeps = packageJson.devDependencies ? Object.keys(packageJson.devDependencies) : [];
const plugins = [];
//Check all the dependencies
[...deps, ...devDeps].forEach((key) => {
if (isAPlugin(key)) {
plugins.push(key);
}
});
return plugins;
}
/**
* Imports a plugin while taking into consideration
* different contexts it could be launched in.
*
* (Production, Inside plugin, testing)
*
* @param plugin
*/
export function importPlugin(plugin) {
try {
if (plugin[0] === "/") {
let pluginPath;
//If we are testing we want to go directly to src/ instead
if (process.env.NODE_ENV === "test") {
pluginPath = path.resolve(plugin, "server/index.ts");
}
else {
pluginPath = path.resolve(plugin, "dist/server/index.js");
}
return require(pluginPath);
}
else {
if (process.env.NODE_ENV === "test") {
plugin = `${plugin}/server/index.ts`;
}
return require(plugin);
}
}
catch (e) {
throw new PluginLoadError(plugin, e);
}
}
/**
* Load the manifest file from cache
*/
export function loadManifest() {
return require(getCacheDir() + "/manifest.json");
}
let schema;
/**
* Collect the schemas from each plugin and write it out to one large schema.
* Doing it this way temporarily due to us loosing caching functionality using
* executableSchema()
*/
export function bootstrapSchema(hoisted = false) {
if (schema)
return schema; //We already have it
/**
* In cases like next.js we cant include extra files into our lambdas.
* We need to hoist the schema into the root of the project for it to be readable.
*/
const hoistedSchema = fs.existsSync(process.cwd() + "/schema.graphql")
? fs.readFileSync(process.cwd() + "/schema.graphql", "utf-8")
: false;
if (hoistedSchema)
return (schema = hoistedSchema);
let cacheDir = getCacheDir();
if (hoisted) {
cacheDir = process.cwd();
}
const schemaCachePath = path.join(cacheDir, "schema.graphql");
if (fs.existsSync(schemaCachePath) && process.env.NODE_ENV === "production") {
return fs.readFileSync(schemaCachePath, "utf-8");
}
const corePath = path.resolve(__dirname, "../utils/core.graphql");
let mergedSchemas = fs.readFileSync(corePath, "utf-8");
//Merge all schemas provided by packages into one
for (const plugin of loadManifest().plugins) {
const isLocalPlugin = isAPlugin();
const currentPlugin = importPlugin(plugin);
currentPlugin.default.schemas.forEach((schema) => {
const schemaRootPath = isLocalPlugin
? plugin
: require.resolve(plugin).replace("/dist/server/index.js", "").replace("/server/index.ts", "");
let schemaPath = schemaRootPath + "/dist/schema/" + schema + ".graphql";
if (process.env.NODE_ENV === "test") {
schemaPath = schemaRootPath + "/server/schema/" + schema + ".graphql";
}
const schemaFile = require.resolve(schemaPath);
mergedSchemas += fs.readFileSync(schemaFile, "utf-8");
});
}
fs.writeFileSync(schemaCachePath, mergedSchemas, "utf8");
return mergedSchemas;
}
/**
* Get the current cache dir, create it if needed
*/
export function getCacheDir() {
const cacheDir = path.join(process.cwd(), ".corejam");
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir);
}
return cacheDir;
}
//# sourceMappingURL=Bootstrap.js.map