@celo/celo-composer
Advanced tools
Comparing version 1.0.2 to 1.0.3
@@ -11,289 +11,323 @@ const inquirer = require("inquirer"); | ||
const createAsync = async (command) => { | ||
let availablePackages = { | ||
"react-app": "React", | ||
"react-native-app": "React Native (With Expo)", | ||
"react-native-app-without-expo": "React Native (without Expo)", | ||
"flutter-app": "Flutter", | ||
"angular-app": "Angular", | ||
hardhat: "Hardhat", | ||
truffle: "Truffle", | ||
subgraphs: "TheGraph", | ||
}; | ||
let availablePackages = { | ||
"react-app": "React", | ||
"react-native-app": "React Native (With Expo)", | ||
"react-native-app-without-expo": "React Native (without Expo)", | ||
"flutter-app": "Flutter", | ||
"angular-app": "Angular", | ||
hardhat: "Hardhat", | ||
truffle: "Truffle", | ||
subgraphs: "TheGraph", | ||
}; | ||
let packageNameMap = { | ||
"react-app": "react-app", | ||
"react-native-app": "react-native-app", | ||
"react-native-app-without-expo": "react-native-app", | ||
"flutter-app": "flutter-app", | ||
"angular-app": "angular-app", | ||
hardhat: "hardhat", | ||
truffle: "truffle", | ||
subgraphs: "subgraphs", | ||
}; | ||
let packageNameMap = { | ||
"react-app": "react-app", | ||
"react-native-app": "react-native-app", | ||
"react-native-app-without-expo": "react-native-app", | ||
"flutter-app": "flutter-app", | ||
"angular-app": "angular-app", | ||
hardhat: "hardhat", | ||
truffle: "truffle", | ||
subgraphs: "subgraphs", | ||
}; | ||
let fELibraries = { | ||
"rc": "React-celo", | ||
"rk": "Rainbowkit-celo" | ||
} | ||
let fELibraries = { | ||
rc: "React-celo", | ||
rk: "Rainbowkit-celo", | ||
}; | ||
let selectedPackages = []; | ||
let selectedFELibrary = ""; | ||
let selectedPackages = []; | ||
let selectedFELibrary = ""; | ||
let { fEFramework } = await inquirer.prompt({ | ||
type: "list", | ||
name: "fEFramework", | ||
message: "Choose front-end framework:", | ||
default: Object.values(availablePackages)[0], | ||
choices: [ | ||
availablePackages["react-app"], | ||
availablePackages["react-native-app"], | ||
availablePackages["react-native-app-without-expo"], | ||
availablePackages["flutter-app"], | ||
availablePackages["angular-app"], | ||
], | ||
}); | ||
let { fEFramework } = await inquirer.prompt({ | ||
type: "list", | ||
name: "fEFramework", | ||
message: "Choose front-end framework:", | ||
default: Object.values(availablePackages)[0], | ||
choices: [ | ||
availablePackages["react-app"], | ||
availablePackages["react-native-app"], | ||
availablePackages["react-native-app-without-expo"], | ||
availablePackages["flutter-app"], | ||
availablePackages["angular-app"], | ||
], | ||
}); | ||
/** | ||
* Based on what fEFramework value is, | ||
* get its index in the object values array, | ||
* at the same index get its key and push it to selectedPackages. | ||
*/ | ||
/** | ||
* Based on what fEFramework value is, | ||
* get its index in the object values array, | ||
* at the same index get its key and push it to selectedPackages. | ||
*/ | ||
selectedPackages.push( | ||
Object.keys(availablePackages)[ | ||
Object.values(availablePackages).indexOf(fEFramework) | ||
] | ||
); | ||
selectedPackages.push( | ||
Object.keys(availablePackages)[ | ||
Object.values(availablePackages).indexOf(fEFramework) | ||
] | ||
); | ||
if (fEFramework == availablePackages["react-app"]) { | ||
let { fELibrary } = await inquirer.prompt({ | ||
type: "list", | ||
name: "fELibrary", | ||
message: "Choose web3 library for react app:", | ||
default: fELibraries["rk"], | ||
choices: [ | ||
fELibraries["rc"], | ||
fELibraries["rk"] | ||
], | ||
if (fEFramework == availablePackages["react-app"]) { | ||
let { fELibrary } = await inquirer.prompt({ | ||
type: "list", | ||
name: "fELibrary", | ||
message: "Choose web3 library for react app:", | ||
default: fELibraries["rk"], | ||
choices: [fELibraries["rc"], fELibraries["rk"]], | ||
}); | ||
selectedFELibrary = fELibrary; | ||
} | ||
let { scFramework } = await inquirer.prompt({ | ||
type: "list", | ||
name: "scFramework", | ||
message: "Choose smart-contract framework:", | ||
default: availablePackages["hardhat"], | ||
choices: [ | ||
availablePackages["hardhat"], | ||
availablePackages["truffle"], | ||
"None", | ||
], | ||
}); | ||
selectedFELibrary = fELibrary; | ||
} | ||
let { scFramework } = await inquirer.prompt({ | ||
type: "list", | ||
name: "scFramework", | ||
message: "Choose smart-contract framework:", | ||
default: availablePackages["hardhat"], | ||
choices: [ | ||
availablePackages["hardhat"], | ||
availablePackages["truffle"], | ||
"None", | ||
], | ||
}); | ||
if (scFramework !== "None") { | ||
selectedPackages.push( | ||
Object.keys(availablePackages)[ | ||
Object.values(availablePackages).indexOf(scFramework) | ||
] | ||
); | ||
} | ||
if (scFramework !== "None") { | ||
selectedPackages.push( | ||
Object.keys(availablePackages)[ | ||
Object.values(availablePackages).indexOf(scFramework) | ||
] | ||
); | ||
} | ||
let { indexingProtocol } = await inquirer.prompt({ | ||
type: "list", | ||
name: "indexingProtocol", | ||
message: "Create a subgraph:", | ||
default: "No", | ||
choices: ["Yes", "No"], | ||
}); | ||
let { indexingProtocol } = await inquirer.prompt({ | ||
type: "list", | ||
name: "indexingProtocol", | ||
message: "Create a subgraph:", | ||
default: "No", | ||
choices: ["Yes", "No"], | ||
}); | ||
if (indexingProtocol === "Yes") { | ||
selectedPackages.push("subgraphs"); | ||
} | ||
if (indexingProtocol === "Yes") { | ||
selectedPackages.push("subgraphs"); | ||
} | ||
let { projectName } = await inquirer.prompt({ | ||
type: "input", | ||
name: "projectName", | ||
message: "Project name: ", | ||
}); | ||
let { projectName } = await inquirer.prompt({ | ||
type: "input", | ||
name: "projectName", | ||
message: "Project name: ", | ||
}); | ||
if (selectedPackages.length > 0) { | ||
const pwd = process.cwd(); | ||
const outputDir = `${pwd}/${projectName}`; | ||
if (selectedPackages.length > 0) { | ||
const pwd = process.cwd(); | ||
const outputDir = `${pwd}/${projectName}`; | ||
// Ensure the output directory exists | ||
await ensureDir(outputDir); | ||
await isOutputDirectoryEmpty(outputDir); | ||
// Ensure the output directory exists | ||
await ensureDir(outputDir); | ||
await isOutputDirectoryEmpty(outputDir); | ||
// Showing the loader | ||
const spinner = loading( | ||
`Generating custom Celo Composer project with the following packages: ${selectedPackages.join( | ||
", " | ||
)}...\n` | ||
); | ||
// Showing the loader | ||
const spinner = loading( | ||
`Generating custom Celo Composer project with the following packages: ${selectedPackages.join( | ||
", " | ||
)}...\n` | ||
); | ||
// Shell commands to clone and trim the required directories | ||
shell.cd(pwd); | ||
shell.exec( | ||
`git clone --depth 2 --filter=blob:none --sparse ${BASE_URL} ${projectName}` | ||
); | ||
shell.cd(projectName); | ||
// Shell commands to clone and trim the required directories | ||
shell.cd(pwd); | ||
shell.exec( | ||
`git clone --depth 2 --filter=blob:none --sparse ${BASE_URL} ${projectName}` | ||
); | ||
shell.cd(projectName); | ||
let packageJson = { | ||
name: `${projectName}`, | ||
version: "1.0.0", | ||
description: "Custom Celo Composer project.", | ||
private: true, | ||
author: "Celo", | ||
license: "MIT", | ||
scripts: {}, | ||
repository: { | ||
type: "git", | ||
url: "git+https://github.com/celo-org/celo-composer.git", | ||
}, | ||
bugs: { | ||
url: "https://github.com/celo-org/celo-composer/issues", | ||
}, | ||
homepage: | ||
"https://github.com/celo-org/celo-composer/blob/main/README.md", | ||
workspaces: ["packages/*"], | ||
keywords: ["celo-composer", "celo"], | ||
}; | ||
let packageJson = { | ||
name: `${projectName}`, | ||
version: "1.0.0", | ||
description: "Custom Celo Composer project.", | ||
private: true, | ||
author: "Celo", | ||
license: "MIT", | ||
scripts: {}, | ||
repository: { | ||
type: "git", | ||
url: "git+https://github.com/celo-org/celo-composer.git", | ||
}, | ||
bugs: { | ||
url: "https://github.com/celo-org/celo-composer/issues", | ||
}, | ||
homepage: "https://github.com/celo-org/celo-composer/blob/main/README.md", | ||
workspaces: ["packages/*"], | ||
keywords: ["celo-composer", "celo"], | ||
}; | ||
for (let x = 0; x < selectedPackages.length; x++) { | ||
// clone to local only the projects user wants | ||
shell.exec( | ||
`git sparse-checkout add packages/${selectedPackages[x]}`, | ||
{ silent: true } | ||
); | ||
for (let x = 0; x < selectedPackages.length; x++) { | ||
// clone to local only the projects user wants | ||
const { stdout, stderr, code } = shell.exec( | ||
`git sparse-checkout add packages/${selectedPackages[x]}`, | ||
{ silent: true } | ||
); | ||
// if project isn't web no need to netlify.toml | ||
if ( | ||
selectedPackages[x] == availablePackages["react-native-app"] || | ||
selectedPackages[x] == | ||
availablePackages["react-native-app-without-expo"] || | ||
selectedPackages[x] == availablePackages["flutter-app"] | ||
) { | ||
shell.rm("netlify.toml"); | ||
} | ||
} | ||
/** | ||
* Getting all packages selected by the user | ||
* First list them via echo packages/\*\/ | ||
* Some string manipulation so that packages looks like | ||
* eg:- ["react-app", "hardhat"] etc... | ||
*/ | ||
// if project isn't web no need to netlify.toml | ||
if ( | ||
selectedPackages[x] == availablePackages["react-native-app"] || | ||
selectedPackages[x] == | ||
availablePackages["react-native-app-without-expo"] || | ||
selectedPackages[x] == availablePackages["flutter-app"] | ||
) { | ||
shell.rm("netlify.toml"); | ||
} | ||
let { stdout: packagesStdOut } = shell.exec("echo packages/*/", { | ||
silent: true, | ||
}); | ||
/** | ||
* Getting all packages selected by the user | ||
* First list them via echo packages/\*\/ | ||
* Some string manipulation so that packages looks like | ||
* eg:- ["react-app", "hardhat"] etc... | ||
*/ | ||
/** | ||
* Node 14 and below doens't support replaceAll | ||
*/ | ||
let packages = packagesStdOut | ||
.replace(/packages\//g, "") | ||
.replace(/\//g, "") | ||
.replace(/\n/g, "") | ||
.split(" "); | ||
let packages = shell | ||
.exec("echo packages/*/", { silent: true }) | ||
.replaceAll("packages/", "") | ||
.replaceAll("/", "") | ||
.replaceAll("\n", "") | ||
.split(" "); | ||
/** | ||
* For every package selected by user, | ||
* we read package.json of every package, | ||
* extract all the scripts inside it | ||
* and write respective scripts in the main package.json file. | ||
* | ||
* If react-app has start, dev, build etc... scripts | ||
* all of them will be add as react-app:start, react-app:dev, react-app:build etc... | ||
*/ | ||
/** | ||
* For every package selected by user, | ||
* we read package.json of every package, | ||
* extract all the scripts inside it | ||
* and write respective scripts in the main package.json file. | ||
* | ||
* If react-app has start, dev, build etc... scripts | ||
* all of them will be add as react-app:start, react-app:dev, react-app:build etc... | ||
*/ | ||
packages.forEach((package) => { | ||
// flutter project doesn't have package.json | ||
if (package != availablePackages["flutter-app"]) { | ||
let localPackageJson = shell.cat( | ||
`packages/${package}/package.json` | ||
); | ||
let projectPackage = JSON.parse(localPackageJson); | ||
packages.forEach((package) => { | ||
// Change the name of the project in package.json for the generated packages. | ||
projectPackage["name"] = `@${projectName}/${package}`; | ||
// flutter project doesn't have package.json | ||
if (package != availablePackages["flutter-app"]) { | ||
let localPackageJson = shell.cat(`packages/${package}/package.json`); | ||
let projectPackage = JSON.parse(localPackageJson); | ||
// update front-end web3 library | ||
if ( | ||
package == packageNameMap["react-app"] && | ||
selectedFELibrary != "" | ||
) { | ||
switch (selectedFELibrary) { | ||
// rainbowkit-celo | ||
case fELibraries["rk"]: | ||
// remove react-celo libraries in packages.json file | ||
delete projectPackage.dependencies[ | ||
"@celo/react-celo" | ||
]; | ||
delete projectPackage.dependencies[ | ||
"@celo/contractkit" | ||
]; | ||
// Change the name of the project in package.json for the generated packages. | ||
projectPackage["name"] = `@${projectName}/${package}`; | ||
// remove react-celo header component | ||
shell.rm( | ||
"packages/react-app/components/HeaderRC.tsx" | ||
); | ||
shell.rm("packages/react-app/pages/_appRC.tsx"); | ||
shell.mv( | ||
"packages/react-app/components/HeaderRK.tsx", | ||
"packages/react-app/components/Header.tsx" | ||
); | ||
shell.sed( | ||
"-i", | ||
'import Header from "./HeaderRK";', | ||
'import Header from "./Header";', | ||
"packages/react-app/components/Layout.tsx" | ||
); | ||
break; | ||
// update front-end web3 library | ||
if (package == packageNameMap["react-app"] && selectedFELibrary != "") { | ||
switch (selectedFELibrary) { | ||
// react-celo | ||
case fELibraries["rc"]: | ||
// remove rainbowkit-celo libraries in packages.json file | ||
delete projectPackage["dependencies"][ | ||
"@celo/rainbowkit-celo" | ||
]; | ||
delete projectPackage["dependencies"][ | ||
"@rainbow-me/rainbowkit" | ||
]; | ||
// rainbowkit-celo | ||
case fELibraries["rk"]: | ||
// remove rainbowkit-celo header component | ||
shell.rm( | ||
"packages/react-app/components/HeaderRK.tsx" | ||
); | ||
shell.rm("packages/react-app/pages/_app.tsx"); | ||
shell.mv( | ||
"packages/react-app/pages/_appRC.tsx", | ||
"packages/react-app/pages/_app.tsx" | ||
); | ||
shell.mv( | ||
"packages/react-app/components/HeaderRC.tsx", | ||
"packages/react-app/components/Header.tsx" | ||
); | ||
shell.sed( | ||
"-i", | ||
'import Header from "./HeaderRK";', | ||
'import Header from "./Header";', | ||
"packages/react-app/components/Layout.tsx" | ||
); | ||
break; | ||
// remove react-celo libraries in packages.json file | ||
delete projectPackage.dependencies['@celo/react-celo']; | ||
delete projectPackage.dependencies['@celo/contractkit']; | ||
// remove react-celo header component | ||
shell.rm("/packages/react-app/components/HeaderRC.tsx"); | ||
shell.rm("/packages/react-app/pages/_appRC.tsx"); | ||
shell.mv("/packages/react-app/components/HeaderRK.tsx", "/packages/react-app/components/Header.tsx"); | ||
shell.sed('-i', 'import Header from "./HeaderRK";', 'import Header from "./Header";', '/packages/react-app/components/Layout.tsx'); | ||
break; | ||
// react-celo | ||
case fELibraries["rc"]: | ||
default: | ||
break; | ||
} | ||
} | ||
// remove rainbowkit-celo libraries in packages.json file | ||
delete projectPackage["dependencies"]['@celo/rainbowkit-celo']; | ||
delete projectPackage["dependencies"]['@rainbow-me/rainbowkit']; | ||
// remove rainbowkit-celo header component | ||
shell.rm("/packages/react-app/components/HeaderRK.tsx"); | ||
shell.rm("/packages/react-app/pages/_app.tsx"); | ||
shell.mv("/packages/react-app/pages/_appRC.tsx", "/packages/react-app/pages/_app.tsx"); | ||
shell.mv("/packages/react-app/components/HeaderRC.tsx", "/packages/react-app/components/Header.tsx"); | ||
shell.sed('-i', 'import Header from "./HeaderRC";', 'import Header from "./Header";', '/packages/react-app/components/Layout.tsx'); | ||
break; | ||
default: | ||
break; | ||
// write back the changes to the package.json | ||
shell | ||
.echo(JSON.stringify(projectPackage, "", 4)) | ||
.to(`packages/${package}/package.json`); | ||
Object.keys(projectPackage.scripts).forEach((key) => { | ||
packageJson.scripts[ | ||
`${packageNameMap[package]}:${key}` | ||
] = `yarn workspace @${projectName}/${package} ${key}`; | ||
}); | ||
} | ||
} | ||
// write back the changes to the package.json | ||
shell | ||
.echo(JSON.stringify(projectPackage, "", 4)) | ||
.to(`packages/${package}/package.json`); | ||
Object.keys(projectPackage.scripts).forEach((key) => { | ||
packageJson.scripts[ | ||
`${packageNameMap[package]}:${key}` | ||
] = `yarn workspace @${projectName}/${package} ${key}`; | ||
}); | ||
} | ||
}); | ||
} | ||
}); | ||
shell.exec("rm -rf .git"); | ||
shell.exec("git init --quiet --initial-branch=main"); | ||
shell.exec("rm -rf .git"); | ||
shell.exec("git init --quiet --initial-branch=main"); | ||
spinner.stopAndPersist({ | ||
symbol: emoji.get("100"), | ||
text: chalk.green(" Done!"), | ||
}); | ||
shell.echo(JSON.stringify(packageJson, "", 4)).to("package.json"); | ||
} | ||
spinner.stopAndPersist({ | ||
symbol: emoji.get("100"), | ||
text: chalk.green(" Done!"), | ||
}); | ||
shell.echo(JSON.stringify(packageJson, "", 4)).to("package.json"); | ||
} | ||
}; | ||
async function isOutputDirectoryEmpty(outputFolder, force = false) { | ||
const files = await readdir(outputFolder); | ||
// TODO: Add --force option to overwrite existing files | ||
if (files.length > 0 && !force) { | ||
const { value } = await inquirer.prompt({ | ||
name: "value", | ||
type: "confirm", | ||
message: | ||
"Output directory is not empty. Are you sure you want to continue?", | ||
}); | ||
if (!value) { | ||
process.exit(1); | ||
const files = await readdir(outputFolder); | ||
// TODO: Add --force option to overwrite existing files | ||
if (files.length > 0 && !force) { | ||
const { value } = await inquirer.prompt({ | ||
name: "value", | ||
type: "confirm", | ||
message: | ||
"Output directory is not empty. Are you sure you want to continue?", | ||
}); | ||
if (!value) { | ||
process.exit(1); | ||
} | ||
} | ||
} | ||
} | ||
const loading = (message) => { | ||
return ora(message).start(); | ||
return ora(message).start(); | ||
}; | ||
module.exports = { | ||
createAsync, | ||
createAsync, | ||
}; |
{ | ||
"name": "@celo/celo-composer", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "Get started building dApps on Celo", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -92,5 +92,6 @@ <!-- TABLE OF CONTENTS --> | ||
- Creating examples and experiment with React for your libraries and components. | ||
- Start the dApp with `yarn dev`/`npm run dev` and you are good to go. | ||
- Install dependencies with `yarn` or `npm i`. | ||
- Start the dApp with `yarn react-app:dev`/`npm run react-app:dev` and you are good to go. | ||
- Support for Website and Progressive Web Application. | ||
- Works with all major crypto wallet. | ||
- Works with all major crypto wallets. | ||
@@ -97,0 +98,0 @@ Check here to learn more about [Celo Composer - React](https://github.com/celo-org/celo-composer/main/packages/react-app/README.md) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
22066
332
180
0