@tobiastengler/create-relay-app
Advanced tools
Comparing version 0.0.0-experimental-c4ec8b793 to 0.0.0-experimental-dfc800e6e
203
dist/bin.js
#!/usr/bin/env node | ||
import path from "path"; | ||
import path, { dirname } from "path"; | ||
import { TaskRunner } from "./TaskRunner.js"; | ||
import { AddGraphQlSchemaFileTask } from "./tasks/AddGraphQlSchemaFileTask.js"; | ||
import { GenerateGraphQlSchemaFileTask } from "./tasks/GenerateGraphQlSchemaFileTask.js"; | ||
import chalk from "chalk"; | ||
import { AddRelayConfigurationTask } from "./tasks/AddRelayConfigurationTask.js"; | ||
import inquirer from "inquirer"; | ||
import { ToolChainOptions, LanguageOptions, PackageManagerOptions, } from "./types.js"; | ||
import { InstallNpmPackagesTask } from "./tasks/InstallNpmPackagesTask.js"; | ||
import { AddRelayPluginConfigurationTask } from "./tasks/AddRelayPluginConfigurationTask.js"; | ||
import { AddRelayEnvironmentTask } from "./tasks/AddRelayEnvironmentTask.js"; | ||
import { traverseUpToFindFile, getPackageManagerToUse } from "./helpers.js"; | ||
import { ConfigureRelayGraphqlTransformTask } from "./tasks/ConfigureRelayGraphqlTransformTask.js"; | ||
import { AddRelayEnvironmentProviderTask } from "./tasks/AddRelayEnvironmentProviderTask.js"; | ||
import { traverseUpToFindFile, printError, getRelayDevDependencies, getRelayCompilerLanguage, highlight, printInvalidArg, getToolchainSettings, prettifyRelativePath, } from "./helpers.js"; | ||
import { exit } from "process"; | ||
import { ARTIFACT_DIR_ARG, BABEL_RELAY_PACKAGE, PACKAGE_FILE, REACT_RELAY_PACKAGE, SCHEMA_FILE_ARG, SRC_DIR_ARG, } from "./consts.js"; | ||
import { fileURLToPath } from "url"; | ||
import { getCliArguments, promptForMissingCliArguments } from "./cli.js"; | ||
import { hasUnsavedGitChanges, isValidArtifactDirectory, isValidSchemaPath, isValidSrcDirectory, } from "./validation.js"; | ||
import { GenerateRelayEnvironmentTask } from "./tasks/GenerateRelayEnvironmentTask.js"; | ||
import { GenerateArtifactDirectoryTask } from "./tasks/GenerateArtifactDirectoryTask.js"; | ||
import { getProjectRelayEnvFilepath } from "./defaults.js"; | ||
// INIT ENVIRONMENT | ||
const distDirectory = dirname(fileURLToPath(import.meta.url)); | ||
const ownPackageDirectory = path.join(distDirectory, ".."); | ||
const workingDirectory = process.cwd(); | ||
// FIND package.json FILE | ||
const packageJsonFile = await traverseUpToFindFile(workingDirectory, "package.json"); | ||
const packageJsonFile = await traverseUpToFindFile(workingDirectory, PACKAGE_FILE); | ||
if (!packageJsonFile) { | ||
// package.json file is missing. | ||
throw new Error("package.json file is missing"); | ||
printError(`Could not find a ${highlight(PACKAGE_FILE)} in the ${highlight(workingDirectory)} directory.`); | ||
exit(1); | ||
} | ||
const projectRootDirectory = path.dirname(packageJsonFile); | ||
// CHECK REPO FOR UNSAVED CHANGES | ||
// const hasUnsavedChanges = await hasUnsavedGitChanges(projectDir); | ||
// if (hasUnsavedChanges) { | ||
// throw new Error("Project has unsaved changes"); | ||
// } | ||
const settings = await readProjectSettings(); | ||
console.log(); | ||
const dependencies = ["react-relay"]; | ||
const devDependencies = getRelayDevDependencies(settings.toolchain, settings.language); | ||
const envArguments = { | ||
workingDirectory, | ||
ownPackageDirectory, | ||
packageJsonFile, | ||
projectRootDirectory, | ||
}; | ||
// GET ARGUMENTS | ||
let cliArgs; | ||
try { | ||
const partialCliArguments = await getCliArguments(envArguments); | ||
if (!partialCliArguments.ignoreGitChanges) { | ||
const hasUnsavedChanges = await hasUnsavedGitChanges(envArguments.projectRootDirectory); | ||
if (hasUnsavedChanges) { | ||
printError(`Please commit or discard all changes in the ${highlight(envArguments.projectRootDirectory)} directory before continuing.`); | ||
exit(1); | ||
} | ||
} | ||
cliArgs = await promptForMissingCliArguments(partialCliArguments, envArguments); | ||
} | ||
catch (error) { | ||
if (error instanceof Error) { | ||
printError(error.message); | ||
} | ||
else { | ||
printError("Unexpected error while parsing CLI arguments"); | ||
} | ||
exit(1); | ||
} | ||
// VALIDATE ARGUMENTS | ||
const schemaPathValid = isValidSchemaPath(cliArgs.schemaFile, envArguments.projectRootDirectory); | ||
if (schemaPathValid !== true) { | ||
printInvalidArg(SCHEMA_FILE_ARG, schemaPathValid, cliArgs.schemaFile); | ||
exit(1); | ||
} | ||
const srcDirValid = isValidSrcDirectory(cliArgs.src, envArguments.projectRootDirectory); | ||
if (srcDirValid !== true) { | ||
printInvalidArg(SRC_DIR_ARG, srcDirValid, cliArgs.src); | ||
exit(1); | ||
} | ||
const artifactDirValid = isValidArtifactDirectory(cliArgs.artifactDirectory, cliArgs.toolchain, envArguments.projectRootDirectory); | ||
if (artifactDirValid !== true) { | ||
printInvalidArg(ARTIFACT_DIR_ARG, artifactDirValid, cliArgs.artifactDirectory); | ||
exit(1); | ||
} | ||
const toolchainSettings = await getToolchainSettings(envArguments, cliArgs); | ||
const settings = Object.assign(Object.assign(Object.assign(Object.assign({}, envArguments), cliArgs), { compilerLanguage: getRelayCompilerLanguage(cliArgs.typescript), relayEnvFilepath: getProjectRelayEnvFilepath(envArguments, cliArgs) }), toolchainSettings); | ||
// EXECUTE TASKS | ||
const dependencies = [REACT_RELAY_PACKAGE]; | ||
const devDependencies = getRelayDevDependencies(settings.toolchain, settings.typescript); | ||
const relRelayEnvPath = prettifyRelativePath(settings.projectRootDirectory, settings.relayEnvFilepath); | ||
const relMainPath = prettifyRelativePath(settings.projectRootDirectory, settings.mainFilepath); | ||
const relConfigPath = prettifyRelativePath(settings.projectRootDirectory, settings.configFilepath); | ||
const relSchemaPath = prettifyRelativePath(settings.projectRootDirectory, settings.schemaFile); | ||
const runner = new TaskRunner([ | ||
{ | ||
title: `Add Relay dependencies: ${dependencies | ||
.map((d) => chalk.cyan.bold(d)) | ||
.map((d) => highlight(d)) | ||
.join(" ")}`, | ||
task: new InstallNpmPackagesTask(dependencies, settings.packageManager, projectRootDirectory), | ||
task: new InstallNpmPackagesTask(dependencies, false, settings), | ||
}, | ||
{ | ||
title: `Add Relay devDependencies: ${devDependencies | ||
.map((d) => chalk.cyan.bold(d)) | ||
.map((d) => highlight(d)) | ||
.join(" ")}`, | ||
task: new InstallNpmPackagesTask(devDependencies, settings.packageManager, projectRootDirectory, true), | ||
task: new InstallNpmPackagesTask(devDependencies, true, settings), | ||
}, | ||
{ | ||
title: "Add Relay configuration to package.json", | ||
task: new AddRelayConfigurationTask(packageJsonFile, settings.schemaFilePath, settings.language), | ||
title: `Add Relay configuration to ${highlight(PACKAGE_FILE)}`, | ||
task: new AddRelayConfigurationTask(settings), | ||
}, | ||
{ | ||
title: "Add Relay plugin configuration", | ||
task: new AddRelayPluginConfigurationTask(projectRootDirectory, settings.toolchain, settings.language), | ||
title: `Configure Relay transform in ${highlight(relConfigPath)}`, | ||
task: new ConfigureRelayGraphqlTransformTask(settings), | ||
when: !!settings.configFilepath, // todo: remove once cra is fully supported | ||
}, | ||
{ | ||
title: "Add Relay environment", | ||
task: new AddRelayEnvironmentTask(), | ||
title: `Generate Relay environment ${highlight(relRelayEnvPath)}`, | ||
task: new GenerateRelayEnvironmentTask(settings), | ||
}, | ||
{ | ||
title: `Generate GraphQL schema file (${chalk.cyan.bold(settings.schemaFilePath)})`, | ||
task: new AddGraphQlSchemaFileTask(settings.schemaFilePath), | ||
title: `Add RelayEnvironmentProvider to ${highlight(relMainPath)}`, | ||
task: new AddRelayEnvironmentProviderTask(settings), | ||
when: !!settings.configFilepath, // todo: remove once cra is fully supported | ||
}, | ||
{ | ||
title: `Generate GraphQL schema file ${highlight(relSchemaPath)}`, | ||
task: new GenerateGraphQlSchemaFileTask(settings), | ||
}, | ||
{ | ||
title: `Generate artifact directory ${highlight(settings.artifactDirectory)}`, | ||
task: new GenerateArtifactDirectoryTask(settings), | ||
when: !!settings.artifactDirectory, | ||
}, | ||
]); | ||
await runner.run(); | ||
try { | ||
await runner.run(); | ||
} | ||
catch (_a) { | ||
console.log(); | ||
printError("Some of the tasks failed unexpectedly."); | ||
exit(1); | ||
// todo: if tasks fail, display ways to resovle the tasks manually | ||
} | ||
// DISPLAY RESULT | ||
console.log(); | ||
console.log(chalk.italic.bold("### NEXT STEPS ###")); | ||
console.log(`1. Replace ${chalk.cyan.bold(settings.schemaFilePath)} with your own GraphQL schema file.`); | ||
console.log(`2. Replace the HOST variable in the RelayEnvironment.ts file.`); | ||
console.log(); | ||
// todo: add integration tests | ||
async function readProjectSettings() { | ||
const defaultPackageManager = getPackageManagerToUse(); | ||
// todo: handle artifact directory | ||
// todo: handle error | ||
return await inquirer.prompt([ | ||
{ | ||
name: "toolchain", | ||
message: "Select the toolchain your project is using", | ||
type: "list", | ||
default: 0, | ||
choices: ToolChainOptions, | ||
}, | ||
{ | ||
name: "language", | ||
message: "Select the language of your project", | ||
type: "list", | ||
default: 0, | ||
choices: LanguageOptions, | ||
}, | ||
{ | ||
// todo: validate that it's inside project dir and ends in .graphql | ||
name: "schemaFilePath", | ||
message: "Select the path to your GraphQL schema file", | ||
type: "input", | ||
default: "./src/schema.graphql", | ||
validate: (input) => { | ||
if (!input.endsWith(".graphql")) { | ||
return `File needs to end in ${chalk.green(".graphql")}`; | ||
} | ||
return true; | ||
}, | ||
}, | ||
{ | ||
name: "packageManager", | ||
message: "Select the package manager you wish to use to install packages", | ||
type: "list", | ||
default: defaultPackageManager, | ||
choices: PackageManagerOptions, | ||
}, | ||
]); | ||
console.log(chalk.cyan.bold.underline("Next steps")); | ||
console.log(); | ||
console.log(`1. Replace ${highlight(relSchemaPath)} with your own GraphQL schema file.`); | ||
console.log(`2. Replace the value of the ${highlight("HOST")} variable in the ${highlight(relRelayEnvPath)} file.`); | ||
// todo: remove once cra is fully supported | ||
if (settings.toolchain === "cra") { | ||
console.log(`3. Setup ${highlight(BABEL_RELAY_PACKAGE)} to conform to your project. ${chalk.dim("(This will soon be automated!)")}`); | ||
} | ||
export function getRelayDevDependencies(toolChain, language) { | ||
let relayDevDep = ["relay-compiler"]; | ||
if (toolChain === "Create-React-App") { | ||
relayDevDep = relayDevDep.concat(["babel-plugin-relay", "graphql"]); | ||
} | ||
else if (toolChain === "Vite") { | ||
relayDevDep.push("vite-plugin-relay"); | ||
} | ||
if (language === "Typescript") { | ||
relayDevDep = relayDevDep.concat(["@types/react-relay"]); | ||
} | ||
return relayDevDep; | ||
} | ||
console.log(); |
@@ -1,44 +0,15 @@ | ||
import { exec, execSync } from "child_process"; | ||
import path from "path"; | ||
import { promises as fs } from "fs"; | ||
export async function hasUnsavedGitChanges(dir) { | ||
const isPartOfGitRepo = await new Promise((resolve) => { | ||
exec("git rev-parse --is-inside-work-tree", { cwd: dir }, (error) => { | ||
resolve(!error); | ||
}); | ||
}); | ||
if (!isPartOfGitRepo) { | ||
return false; | ||
} | ||
const hasUnsavedChanges = await new Promise((resolve) => { | ||
exec("git status --porcelain", { cwd: dir }, (error, stdout) => { | ||
resolve(!!error || !!stdout); | ||
}); | ||
}); | ||
return hasUnsavedChanges; | ||
import fs from "fs/promises"; | ||
import { BABEL_RELAY_PACKAGE, PACKAGE_FILE, VITE_RELAY_PACKAGE, } from "./consts.js"; | ||
import glob from "glob"; | ||
import chalk from "chalk"; | ||
export function printInvalidArg(arg, validationMsg, value) { | ||
printError(`Invalid ${arg} specified: ${value} ${chalk.dim(validationMsg)}`); | ||
} | ||
export function getPackageManagerToUse() { | ||
try { | ||
const userAgent = process.env.npm_config_user_agent; | ||
if (userAgent) { | ||
if (userAgent.startsWith("yarn")) { | ||
return "yarn"; | ||
} | ||
else if (userAgent.startsWith("pnpm")) { | ||
return "pnpm"; | ||
} | ||
} | ||
try { | ||
execSync("yarn --version", { stdio: "ignore" }); | ||
return "yarn"; | ||
} | ||
catch (_a) { | ||
execSync("pnpm --version", { stdio: "ignore" }); | ||
return "pnpm"; | ||
} | ||
} | ||
catch (_b) { | ||
return "npm"; | ||
} | ||
export function printError(message) { | ||
console.log(chalk.red("✖") + " " + message); | ||
} | ||
export function highlight(message) { | ||
return chalk.cyan.bold(message); | ||
} | ||
export async function traverseUpToFindFile(directory, filename) { | ||
@@ -75,1 +46,138 @@ let currentDirectory = directory; | ||
} | ||
export async function searchFilesInDirectory(directory, pattern) { | ||
return new Promise((resolve) => { | ||
try { | ||
glob(pattern, { cwd: directory }, (error, matches) => { | ||
if (error || !matches || !matches.some((m) => !!m)) { | ||
resolve([]); | ||
} | ||
else { | ||
resolve(matches); | ||
} | ||
}); | ||
} | ||
catch (_a) { | ||
resolve([]); | ||
} | ||
}); | ||
} | ||
export async function getPackageDetails(env) { | ||
const ownPackageJsonFile = path.join(env.ownPackageDirectory, PACKAGE_FILE); | ||
const packageJsonContent = await fs.readFile(ownPackageJsonFile, "utf8"); | ||
const packageJson = JSON.parse(packageJsonContent); | ||
const name = packageJson === null || packageJson === void 0 ? void 0 : packageJson.name; | ||
if (!name) { | ||
throw new Error(`Could not determine name in ${ownPackageJsonFile}`); | ||
} | ||
const version = packageJson === null || packageJson === void 0 ? void 0 : packageJson.version; | ||
if (!version) { | ||
throw new Error(`Could not determine version in ${ownPackageJsonFile}`); | ||
} | ||
const description = packageJson === null || packageJson === void 0 ? void 0 : packageJson.description; | ||
if (!description) { | ||
throw new Error(`Could not determine description in ${ownPackageJsonFile}`); | ||
} | ||
return { name, version, description }; | ||
} | ||
export function getRelayDevDependencies(toolchain, useTypescript) { | ||
const relayDevDep = ["relay-compiler"]; | ||
if (useTypescript) { | ||
relayDevDep.push("@types/react-relay"); | ||
relayDevDep.push("@types/relay-runtime"); | ||
} | ||
if (toolchain === "cra" || toolchain === "vite") { | ||
relayDevDep.push(BABEL_RELAY_PACKAGE); | ||
} | ||
if (toolchain === "vite") { | ||
relayDevDep.push(VITE_RELAY_PACKAGE); | ||
} | ||
return relayDevDep; | ||
} | ||
export function getSpecifiedProperties(obj) { | ||
const keys = Object.keys(obj); | ||
const newObj = {}; | ||
for (const key of keys) { | ||
if (obj[key] === null) { | ||
continue; | ||
} | ||
newObj[key] = obj[key]; | ||
} | ||
return newObj; | ||
} | ||
export function isSubDirectory(parent, dir) { | ||
const relative = path.relative(parent, dir); | ||
return !relative.startsWith("..") && !path.isAbsolute(relative); | ||
} | ||
export function prettifyRelativePath(parentPath, childPath) { | ||
const relativePath = path.relative(parentPath, childPath); | ||
return prettifyPath(relativePath); | ||
} | ||
export function prettifyPath(input) { | ||
let normalizedPath = normalizePath(input); | ||
if (!normalizedPath.startsWith("..") && !normalizedPath.startsWith("./")) { | ||
normalizedPath = "./" + normalizedPath; | ||
} | ||
return normalizedPath; | ||
} | ||
export function normalizePath(input) { | ||
return input.split(path.sep).join("/"); | ||
} | ||
export function removeExtension(filename) { | ||
return filename.substring(0, filename.lastIndexOf(".")) || filename; | ||
} | ||
export function getRelayCompilerLanguage(useTypescript) { | ||
if (useTypescript) { | ||
return "typescript"; | ||
} | ||
else { | ||
return "javascript"; | ||
} | ||
} | ||
export async function getToolchainSettings(env, args) { | ||
if (args.toolchain === "vite") { | ||
const configFilename = "vite.config" + (args.typescript ? ".ts" : ".js"); | ||
const configFilepath = await findFileInDirectory(env.projectRootDirectory, configFilename); | ||
if (!configFilepath) { | ||
throw new Error(`${configFilename} not found`); | ||
} | ||
const mainFilename = "main" + (args.typescript ? ".tsx" : ".jsx"); | ||
const searchDirectory = path.join(env.projectRootDirectory, "src"); | ||
const mainFilepath = await findFileInDirectory(searchDirectory, mainFilename); | ||
if (!mainFilepath) { | ||
throw new Error(`${mainFilename} not found`); | ||
} | ||
return { | ||
configFilepath, | ||
mainFilepath, | ||
}; | ||
} | ||
else if (args.toolchain === "next") { | ||
const configFilename = "next.config.js"; | ||
const configFilepath = await findFileInDirectory(env.projectRootDirectory, configFilename); | ||
if (!configFilepath) { | ||
throw new Error(`${configFilename} not found`); | ||
} | ||
const mainFilename = "_app" + (args.typescript ? ".tsx" : ".jsx"); | ||
const searchDirectory = path.join(env.projectRootDirectory, "pages"); | ||
const mainFilepath = await findFileInDirectory(searchDirectory, mainFilename); | ||
if (!mainFilepath) { | ||
throw new Error(`${mainFilename} not found`); | ||
} | ||
return { | ||
configFilepath, | ||
mainFilepath, | ||
}; | ||
} | ||
else { | ||
const mainFilename = "index" + (args.typescript ? ".tsx" : ".jsx"); | ||
const searchDirectory = path.join(env.projectRootDirectory, "src"); | ||
const mainFilepath = await findFileInDirectory(searchDirectory, mainFilename); | ||
if (!mainFilepath) { | ||
throw new Error(`${mainFilename} not found`); | ||
} | ||
return { | ||
configFilepath: "", | ||
mainFilepath, | ||
}; | ||
} | ||
} |
import chalk from "chalk"; | ||
export class TaskBase { | ||
setSpinner(spinner) { | ||
init(spinner) { | ||
this.spinner = spinner; | ||
@@ -8,3 +8,4 @@ } | ||
var _a; | ||
(_a = this.spinner) === null || _a === void 0 ? void 0 : _a.warn(this.spinner.text + " " + chalk.dim("[Skipped: " + message + "]")); | ||
const reason = message ? ": " + message : undefined; | ||
(_a = this.spinner) === null || _a === void 0 ? void 0 : _a.warn(this.spinner.text + " " + chalk.dim(`[Skipped${reason}]`)); | ||
throw new TaskSkippedError(); | ||
@@ -11,0 +12,0 @@ } |
@@ -8,5 +8,8 @@ import ora from "ora"; | ||
async run() { | ||
for (const { title, task } of this.taskDefs) { | ||
for (const { title, task, when } of this.taskDefs) { | ||
if (when === false) { | ||
continue; | ||
} | ||
const spinner = ora(title); | ||
task.setSpinner(spinner); | ||
task.init(spinner); | ||
try { | ||
@@ -22,9 +25,12 @@ spinner.start(); | ||
let errorMsg; | ||
if (!!error && typeof error === "string") { | ||
errorMsg = error; | ||
if (!!error) { | ||
if (typeof error === "string") { | ||
errorMsg = error; | ||
} | ||
else if (error instanceof Error) { | ||
errorMsg = error.message; | ||
} | ||
} | ||
errorMsg !== null && errorMsg !== void 0 ? errorMsg : (errorMsg = "Unexpected error"); | ||
task.error(errorMsg); | ||
// throw error; | ||
break; | ||
} | ||
@@ -31,0 +37,0 @@ } |
import { TaskBase } from "../TaskBase.js"; | ||
import { promises as fs } from "fs"; | ||
import fs from "fs/promises"; | ||
export class AddRelayConfigurationTask extends TaskBase { | ||
constructor(packageJsonFile, schemaFilePath, language) { | ||
constructor(settings) { | ||
super(); | ||
this.packageJsonFile = packageJsonFile; | ||
this.schemaFilePath = schemaFilePath; | ||
this.language = language; | ||
this.settings = settings; | ||
} | ||
async run() { | ||
var _a; | ||
const compilerLanguage = getCompilerLanguage(this.language); | ||
// todo: handle error | ||
const packageJsonContent = await fs.readFile(this.packageJsonFile, { | ||
const packageJsonContent = await fs.readFile(this.settings.packageJsonFile, { | ||
encoding: "utf-8", | ||
@@ -26,7 +23,6 @@ }); | ||
// Add "relay" configuration section | ||
packageJson["relay"] = { | ||
// todo: this should probably be different for the Next.js project | ||
src: "./src", | ||
language: compilerLanguage, | ||
schema: this.schemaFilePath, | ||
const relayConfig = { | ||
src: this.settings.src, | ||
language: this.settings.compilerLanguage, | ||
schema: this.settings.schemaFile, | ||
exclude: [ | ||
@@ -38,17 +34,11 @@ "**/node_modules/**", | ||
}; | ||
if (this.settings.artifactDirectory) { | ||
relayConfig.artifactDirectory = this.settings.artifactDirectory; | ||
} | ||
packageJson["relay"] = relayConfig; | ||
} | ||
const serializedPackageJson = JSON.stringify(packageJson, null, 2); | ||
// todo: handle error | ||
await fs.writeFile(this.packageJsonFile, serializedPackageJson, "utf-8"); | ||
await fs.writeFile(this.settings.packageJsonFile, serializedPackageJson, "utf-8"); | ||
} | ||
} | ||
function getCompilerLanguage(language) { | ||
switch (language) { | ||
case "Typescript": | ||
return "typescript"; | ||
case "Flow": | ||
return "flow"; | ||
default: | ||
return "javascript"; | ||
} | ||
} |
@@ -0,16 +1,16 @@ | ||
import { spawn } from "child_process"; | ||
import { TaskBase } from "../TaskBase.js"; | ||
export class InstallNpmPackagesTask extends TaskBase { | ||
constructor(packages, manager, workingDirectory, isDevDependency = false) { | ||
constructor(packages, isDevDependency, settings) { | ||
super(); | ||
this.packages = packages; | ||
this.manager = manager; | ||
this.workingDirectory = workingDirectory; | ||
this.isDevDependency = isDevDependency; | ||
this.settings = settings; | ||
} | ||
async run() { | ||
const command = this.manager; | ||
const useYarn = this.manager === "yarn"; | ||
const command = this.settings.packageManager; | ||
const useYarn = command === "yarn"; | ||
let args = []; | ||
if (useYarn) { | ||
args = ["add", "--exact", "--cwd", this.workingDirectory]; | ||
args = ["add", "--exact", "--cwd", this.settings.projectRootDirectory]; | ||
if (this.isDevDependency) { | ||
@@ -29,19 +29,18 @@ args.push("--dev"); | ||
} | ||
return Promise.resolve(); | ||
// return new Promise((resolve, reject) => { | ||
// const child = spawn(command, args, { | ||
// // stdio: "inherit", | ||
// cwd: this.workingDirectory, | ||
// env: process.env, | ||
// shell: true, | ||
// }); | ||
// child.on("close", (code) => { | ||
// if (code !== 0) { | ||
// reject({ command: `${command} ${args.join(" ")}` }); | ||
// return; | ||
// } | ||
// resolve(); | ||
// }); | ||
// }); | ||
return new Promise((resolve, reject) => { | ||
const child = spawn(command, args, { | ||
// stdio: "inherit", | ||
cwd: this.settings.projectRootDirectory, | ||
env: process.env, | ||
shell: true, | ||
}); | ||
child.on("close", (code) => { | ||
if (code !== 0) { | ||
reject({ command: `${command} ${args.join(" ")}` }); | ||
return; | ||
} | ||
resolve(); | ||
}); | ||
}); | ||
} | ||
} |
@@ -1,7 +0,2 @@ | ||
export const ToolChainOptions = [ | ||
"Create-React-App", | ||
"Next.js", | ||
"Vite", | ||
]; | ||
export const LanguageOptions = ["Typescript", "JavaScript", "Flow"]; | ||
export const ToolchainOptions = ["cra", "next", "vite"]; | ||
export const PackageManagerOptions = ["npm", "yarn", "pnpm"]; |
{ | ||
"name": "@tobiastengler/create-relay-app", | ||
"version": "0.0.0-experimental-c4ec8b793", | ||
"version": "0.0.0-experimental-dfc800e6e", | ||
"description": "Easy configuration of Relay for existing projects", | ||
"homepage": "https://github.com/tobias-tengler/create-relay-app#readme", | ||
"license": "MIT", | ||
"author": "tobias-tengler", | ||
"author": { | ||
"name": "Tobias Tengler", | ||
"url": "https://github.com/tobias-tengler", | ||
"email": "contact.tobiastengler@gmail.com" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/tobias-tengler/create-relay-app.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/tobias-tengler/create-relay-app/issues" | ||
}, | ||
"keywords": [], | ||
"files": [ | ||
"dist" | ||
"./dist", | ||
"./assets" | ||
], | ||
@@ -17,5 +32,10 @@ "bin": "./dist/bin.js", | ||
"devDependencies": { | ||
"@types/babel__generator": "^7.6.4", | ||
"@types/babel__traverse": "^7.18.0", | ||
"@types/fs-extra": "^9.0.13", | ||
"@types/glob": "^7.2.0", | ||
"@types/inquirer": "^9.0.0", | ||
"@types/node": "^18.6.5", | ||
"@types/ora": "^3.2.0", | ||
"@types/prettier": "^2.7.0", | ||
"tslib": "^2.4.0", | ||
@@ -25,6 +45,13 @@ "typescript": "^4.7.4" | ||
"dependencies": { | ||
"@babel/generator": "^7.18.12", | ||
"@babel/parser": "^7.18.11", | ||
"@babel/traverse": "^7.18.11", | ||
"chalk": "^5.0.1", | ||
"commander": "^9.4.0", | ||
"fs-extra": "^10.1.0", | ||
"glob": "^8.0.3", | ||
"inquirer": "^9.1.0", | ||
"ora": "^6.1.2" | ||
"ora": "^6.1.2", | ||
"prettier": "^2.7.1" | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
56220
22
1159
0
1
1
181
10
10
11
4
+ Added@babel/generator@^7.18.12
+ Added@babel/parser@^7.18.11
+ Added@babel/traverse@^7.18.11
+ Addedcommander@^9.4.0
+ Addedfs-extra@^10.1.0
+ Addedglob@^8.0.3
+ Addedprettier@^2.7.1
+ Added@babel/code-frame@7.26.2(transitive)
+ Added@babel/generator@7.26.9(transitive)
+ Added@babel/helper-string-parser@7.25.9(transitive)
+ Added@babel/helper-validator-identifier@7.25.9(transitive)
+ Added@babel/parser@7.26.9(transitive)
+ Added@babel/template@7.26.9(transitive)
+ Added@babel/traverse@7.26.9(transitive)
+ Added@babel/types@7.26.9(transitive)
+ Added@jridgewell/gen-mapping@0.3.8(transitive)
+ Added@jridgewell/resolve-uri@3.1.2(transitive)
+ Added@jridgewell/set-array@1.2.1(transitive)
+ Added@jridgewell/sourcemap-codec@1.5.0(transitive)
+ Added@jridgewell/trace-mapping@0.3.25(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@2.0.1(transitive)
+ Addedcommander@9.5.0(transitive)
+ Addeddebug@4.4.0(transitive)
+ Addedfs-extra@10.1.0(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@8.1.0(transitive)
+ Addedglobals@11.12.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedjs-tokens@4.0.0(transitive)
+ Addedjsesc@3.1.0(transitive)
+ Addedjsonfile@6.1.0(transitive)
+ Addedminimatch@5.1.6(transitive)
+ Addedms@2.1.3(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpicocolors@1.1.1(transitive)
+ Addedprettier@2.8.8(transitive)
+ Addeduniversalify@2.0.1(transitive)
+ Addedwrappy@1.0.2(transitive)