diff --git a/packages/create-waku-app/build.js b/packages/create-waku-app/build.js new file mode 100644 index 0000000..32327f1 --- /dev/null +++ b/packages/create-waku-app/build.js @@ -0,0 +1,42 @@ +#!/usr/bin/env node +const path = require("path"); +const fs = require("fs-extra"); + +const packageJson = require("./package.json"); +const examplesFolder = path.resolve("./examples"); + +async function run() { + fs.ensureDirSync(examplesFolder); + + const supportedExamples = Object.entries(packageJson.wakuExamples); + + console.log("Started copying supported Waku examples."); + + const copyPromises = supportedExamples.map(([name, relativePath]) => { + const resolvedPath = path.resolve(__dirname, relativePath); + const destinationPath = path.resolve(examplesFolder, name); + + return fs.copy(resolvedPath, destinationPath, { filter: nodeModulesFiler }).catch((error) => { + console.error(`Failed to copy example ${name} to ${destinationPath} with ${error.message}`); + throw Error(error.message); + }); + }); + + await Promise.all(copyPromises) + .then(() => { + console.log("Finished copying examples."); + }) + .catch((error) => { + console.error("Failed to copy examples due to " + error.message); + }); +} + +function nodeModulesFiler(src) { + if (src.includes("node_modules")) { + return false; + } + + return true; +} + +run(); diff --git a/packages/create-waku-app/createApp.js b/packages/create-waku-app/createApp.js new file mode 100644 index 0000000..0b4444f --- /dev/null +++ b/packages/create-waku-app/createApp.js @@ -0,0 +1,76 @@ +const fs = require("fs-extra"); +const path = require("path"); +const { Command } = require('commander'); +const validateProjectName = require('validate-npm-package-name'); + +const supportedExamplesDir = path.resolve("./examples"); + +const init = (name, description, version, supportedExamples) => { + let appName; + const program = new Command() + .name(name) + .description(description) + .version(version, "-v, --version", "output the version number") + .arguments("", "Project directory to initialize Waku app") + .action(_appName => { + appName = _appName; + }) + .option( + "-t, --template ", + "specify a template for the created project" + ) + .allowUnknownOption() + .parse(); + + const options = program.opts(); + const template = options.template || "web-chat"; + + if (!supportedExamples[template]) { + const supportedExamplesMessage = Object.keys(supportedExamples).reduce((acc, v) => { + acc += `\t${v}\n`; + return acc; + }, ""); + + console.error(`Unknown template: ${template}`); + console.error(`We support only following templates:\n${supportedExamplesMessage}`) + process.exit(1); + } + + createApp(appName, template); +}; + +function createApp(name, template) { + const appRoot = path.resolve(name); + const appName = path.basename(appRoot); + + const templateDir = path.resolve(supportedExamplesDir, template); + + terminateIfAppExists(appName); + terminateIfProjectNameInvalid(appName); + + console.log(`Initializing ${appName} from ${template} template.`); + + fs.copySync(templateDir, appRoot); + // initNpmOrYarn(appRoot); +} + +function terminateIfProjectNameInvalid(name) { + const validationResult = validateProjectName(name); + + if (!validationResult.validForNewPackages) { + console.error(`Cannot create a project named ${name} because of npm naming restrictions:\n`); + [...(validationResult.errors || []), ...(validationResult.warnings || [])] + .forEach(error => console.error(` * ${error}`)); + console.error("\nPlease choose a different project name."); + process.exit(1); + } +} + +function terminateIfAppExists(appRoot) { + if (fs.existsSync(appRoot)) { + console.error(`Cannot create a project because it already exists by the name: ${appRoot}`); + process.exit(1); + } +} + +module.exports = { init }; \ No newline at end of file diff --git a/packages/create-waku-app/createWakuApp.js b/packages/create-waku-app/createWakuApp.js deleted file mode 100644 index 4285fb2..0000000 --- a/packages/create-waku-app/createWakuApp.js +++ /dev/null @@ -1,28 +0,0 @@ -const { Command } = require('commander'); - -const packageJson = require('./package.json'); - -let appName; - -const createApp = () => { - const program = new Command() - .name(packageJson.name) - .description(packageJson.description) - .version(packageJson.version) - .arguments("", "Project directory to initialize Waku app") - .action(name => { - appName = name; - }) - .option( - "-t, --template ", - "specify a template for the created project" - ) - .allowUnknownOption() - .parse(); - - const options = program.opts(); - - console.log(`Initializing ${appName} from template ${options.template || "default"}`); -}; - -module.exports = { createApp }; \ No newline at end of file diff --git a/packages/create-waku-app/index.js b/packages/create-waku-app/index.js index 28bb83d..c8bd301 100644 --- a/packages/create-waku-app/index.js +++ b/packages/create-waku-app/index.js @@ -1,4 +1,19 @@ #!/usr/bin/env node -const { createApp } = require("./createWakuApp"); +const packageJson = require("./package.json"); +const semver = require("semver"); -createApp(); +const currentNodeVersion = process.versions.node; +const supportedNodeVersion = packageJson.engines.node; + +if (!semver.satisfies(currentNodeVersion, supportedNodeVersion)) { + console.error( + `You are running Node ${currentNodeVersion}.\n` + + `@waku/create-app works only with ${packageJson.engines.node}.\n` + + `Please update your version of Node.` + ); + process.exit(1); +} + +const { init } = require("./createApp"); + +init(packageJson.name, packageJson.description, packageJson.version, packageJson.wakuExamples); diff --git a/packages/create-waku-app/package.json b/packages/create-waku-app/package.json index 1ba317a..90d8738 100644 --- a/packages/create-waku-app/package.json +++ b/packages/create-waku-app/package.json @@ -1,22 +1,55 @@ { - "name": "create-waku-app", - "version": "0.1.0", + "name": "create-dementor-app", + "version": "0.1.13", "description": "Helper package to bootstrap Waku app ", + "repository": { + "type": "git", + "url": "https://github.com/waku-org/js-waku-examples.git", + "directory": "packages/create-app" + }, + "engines": { + "node": ">=16" + }, + "bugs": { + "url": "https://github.com/waku-org/js-waku-examples/issues" + }, + "files": [ + "index.js", + "createApp.js", + "examples" + ], "main": "index.js", + "bin": { + "create-waku-app": "./index.js" + }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "node ./build.js", + "prepublishOnly": "npm run build" }, "keywords": [ - "waku", - "decentralised", - "communication", - "web3", - "ethereum", - "dapps" + "waku", + "decentralised", + "communication", + "web3", + "ethereum", + "dapps" ], - "license": "MIT OR Apache-2.0", + "license": "MIT", + "wakuExamples": { + "eth-pm": "../../eth-pm", + "light-js": "../../light-js", + "relay-angular-chat": "../../relay-angular-chat", + "relay-js": "../../relay-js", + "relay-reactjs-chat": "../../relay-reactjs-chat", + "rln-js": "../../rln-js", + "store-js": "../../store-js", + "store-reactjs-chat": "../../store-reactjs-chat", + "web-chat": "../../web-chat" + }, "dependencies": { - "commander": "^9.4.1" + "commander": "^9.4.1", + "fs-extra": "^11.1.0", + "semver": "^7.3.8", + "validate-npm-package-name": "^5.0.0" } - } - \ No newline at end of file +}