-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(create-tensei-app): create the create-tensei-app package
Create the create-tensei-app package for rapidly setting up new tensei packages
- Loading branch information
Frantz Kati
committed
Nov 29, 2020
1 parent
333c8c6
commit 1188a0f
Showing
23 changed files
with
524 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<div align="center"> | ||
<br /> | ||
<br /> | ||
<img src="https://res.cloudinary.com/bahdcoder/image/upload/v1604236130/Asset_1_4x_fhcfyg.png" width="450px"> | ||
</div> | ||
|
||
<br /> | ||
|
||
<br /> | ||
|
||
<div align="center"> | ||
<h3> | ||
<strong> | ||
The fastest and easiest way to build powerful and secure APIs | ||
</strong> | ||
</h3> | ||
<p>Open source Node.js Headless CMS 🚀. </p> | ||
</div> | ||
|
||
<br /> | ||
|
||
<div align="center"> | ||
|
||
|
||
[![github-actions-image]][github-actions-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] | ||
|
||
</div> | ||
|
||
<div align="center"> | ||
<h3> | ||
<a href="https://tenseijs.com"> | ||
Website | ||
</a> | ||
<span> | </span> | ||
<a href="https://tenseijs.com/docs"> | ||
Guides | ||
</a> | ||
<span> | </span> | ||
<a href="CONTRIBUTING.md"> | ||
Contributing | ||
</a> | ||
</h3> | ||
</div> | ||
|
||
<div align="center"> | ||
<sub>Built with ❤︎ by <a href="https://github.com/bahdcoder">Kati Frantz</a> | ||
</div> | ||
|
||
[github-actions-image]: https://img.shields.io/github/workflow/status/tenseijs/tensei/Tests?style=for-the-badge | ||
[github-actions-url]: https://github.com/tenseijs/tensei/actions?query=workflow%3ATests "github-actions" | ||
|
||
[npm-image]: https://img.shields.io/npm/v/@tensei/core.svg?style=for-the-badge&logo=npm | ||
[npm-url]: https://www.npmjs.com/package/@tensei/core "npm" | ||
|
||
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript | ||
|
||
[license-url]: LICENSE.md | ||
[license-image]: https://img.shields.io/github/license/tenseijs/tensei?style=for-the-badge |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ | ||
"name": "create-tensei-app", | ||
"version": "0.0.1", | ||
"main": "./build/index.js", | ||
"license": "MIT", | ||
"types": "./build/index.d.ts", | ||
"files": [ | ||
"build/" | ||
], | ||
"bin": { | ||
"create-tensei-app": "./build/index.js" | ||
}, | ||
"devDependencies": {}, | ||
"scripts": { | ||
"prettier": "prettier --write './**/*.{js,json,ts,css}'", | ||
"build": "tsc --p tsconfig.json", | ||
"dev": "tsc --watch --p tsconfig.json", | ||
"test": "jest --verbose --runInBand --forceExit" | ||
}, | ||
"dependencies": { | ||
"@types/change-case": "^2.3.1", | ||
"@types/commander": "^2.12.2", | ||
"@types/node": "^14.14.10", | ||
"@types/signale": "^1.4.1", | ||
"change-case": "^4.1.1", | ||
"commander": "^6.2.0", | ||
"edge.js": "^1.1.4", | ||
"execa": "^4.1.0", | ||
"latest-version": "^5.1.0", | ||
"ora": "^5.1.0", | ||
"signale": "^1.4.0" | ||
}, | ||
"config": { | ||
"commitizen": { | ||
"path": "cz-conventional-changelog" | ||
} | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" | ||
} | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { Command } from 'commander' | ||
import { snakeCase } from 'change-case' | ||
|
||
import Signale from './utils/signale' | ||
import { | ||
getAvailableTemplates, | ||
getAvailableDatabases, | ||
getPackageVersions, | ||
parseTemplateFiles, | ||
projectDirectoryExists, | ||
createProjectFolder, | ||
createProjectFile, | ||
hasYarnInstalled, | ||
installProjectDependencies, | ||
} from './utils/helpers' | ||
|
||
export const cli = async (program: Command) => { | ||
const packageManager = program.npm | ||
? 'npm' | ||
: hasYarnInstalled() | ||
? 'yarn' | ||
: 'npm' | ||
|
||
const project_name = program.args[0] | ||
|
||
const api = program.rest ? 'rest' : 'graphql' | ||
const database = program.database || 'sqlite' | ||
const template = program.template || 'quickstart' | ||
let mikro_orm_db_name = program.dbname || snakeCase(program.args[0]) | ||
const mikro_orm_db_pass = program.dbpassword | ||
const mikro_orm_db_host = program.dbhost | ||
const mikro_orm_db_username = program.dbusername | ||
|
||
mikro_orm_db_name = database === 'sqlite' ? `${mikro_orm_db_name}.sqlite` : mikro_orm_db_name | ||
|
||
if (!getAvailableTemplates().includes(template)) { | ||
Signale.error(`The ${template} template does not exist.`) | ||
|
||
process.exit(1) | ||
} | ||
|
||
if (!getAvailableDatabases().includes(database)) { | ||
Signale.error(`The ${template} database is not supported yet.`) | ||
|
||
process.exit(1) | ||
} | ||
|
||
if (projectDirectoryExists(project_name)) { | ||
Signale.error(`The directory ${project_name} already exists.`) | ||
|
||
process.exit(1) | ||
} | ||
|
||
const [ | ||
mikro_orm_package_version, | ||
core_package_version, | ||
auth_package_version, | ||
api_package_version, | ||
nodemon_version | ||
] = await getPackageVersions(database, api) | ||
|
||
const templateVariables = { | ||
api_package: api, | ||
project_name, | ||
mikro_orm_database: database, | ||
mikro_orm_package_version, | ||
core_package_version, | ||
auth_package_version, | ||
api_package_version, | ||
nodemon_version, | ||
mikro_orm_db_name, | ||
mikro_orm_db_pass, | ||
mikro_orm_db_host, | ||
mikro_orm_db_username | ||
} | ||
|
||
createProjectFolder(project_name) | ||
|
||
parseTemplateFiles(template, templateVariables).map(([file, content]) => | ||
createProjectFile(project_name, file, content) | ||
) | ||
|
||
installProjectDependencies(packageManager, project_name) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#!/usr/bin/env node | ||
'use strict' | ||
|
||
import { cli } from './cli' | ||
import { Command } from 'commander' | ||
import Signale from './utils/signale' | ||
const packageJson = require('../package.json') | ||
|
||
const program = new Command(packageJson.name) | ||
|
||
program | ||
.version(packageJson.version) | ||
.arguments('<directory>') | ||
.option('--template <template>', 'Specify a supported template') | ||
.option('--rest', 'Bootstrap a rest API project') | ||
.option('--database <database>', 'Specify the database to setup') | ||
.option('--dbname <dbname>', 'Database name') | ||
.option('--dbhost <dbhost>', 'Database host') | ||
.option('--dbusername <dbusername>', 'Database username') | ||
.option('--dbpassword <dbpassword>', 'Database password') | ||
.option('--no-run', 'Do not start the application after it is created') | ||
.option('--npm', 'Use npm package manager in place of yarn') | ||
.description('Scaffold a new tensei application') | ||
.parse(process.argv) | ||
|
||
if (!program.args[0]) { | ||
Signale.error('Please specify a valid project name.') | ||
|
||
process.exit(1) | ||
} | ||
|
||
cli(program as any) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import Fs from 'fs' | ||
import Ora from 'ora' | ||
import Path from 'path' | ||
import Execa from 'execa' | ||
import Edge from 'edge.js' | ||
import latestVersion from 'latest-version' | ||
import signale from './signale' | ||
|
||
export const getAvailableTemplates = () => ['quickstart'] | ||
|
||
export const getAvailableDatabases = () => ['sqlite', 'mysql', 'postgresql'] | ||
|
||
export const getPackageVersions = (database: string, api: string) => | ||
Promise.all([ | ||
latestVersion(`@mikro-orm/${database}`), | ||
latestVersion(`@tensei/core`), | ||
latestVersion(`@tensei/auth`), | ||
latestVersion(`@tensei/${api}`), | ||
latestVersion(`nodemon`) | ||
]) | ||
|
||
export const parseTemplateFiles = ( | ||
template: string, | ||
templateVariables: any | ||
) => { | ||
const basePath = Path.resolve(__dirname, '..', '..', 'templates', template) | ||
|
||
return Fs.readdirSync(basePath).map(file => [ | ||
file, | ||
Edge.renderString( | ||
Fs.readFileSync(Path.resolve(basePath, file)).toString(), | ||
templateVariables | ||
) | ||
]) | ||
} | ||
|
||
export const projectDirectoryExists = (project: string) => | ||
Fs.existsSync(Path.resolve(process.cwd(), project)) | ||
|
||
export const createProjectFolder = (project: string) => | ||
console.log(Path.resolve(process.cwd(), project)) as any || Fs.mkdirSync(Path.resolve(process.cwd(), project)) | ||
|
||
export const createProjectFile = ( | ||
project: string, | ||
file: string, | ||
content: string | ||
) => | ||
Fs.writeFileSync( | ||
Path.resolve( | ||
process.cwd(), | ||
project, | ||
file.endsWith('.edge') ? file.substring(0, file.length - 5) : file | ||
), | ||
content | ||
) | ||
|
||
export const hasYarnInstalled = () => { | ||
try { | ||
return Execa.commandSync('yarn --version').exitCode === 0 | ||
} catch (e) { | ||
return false | ||
} | ||
} | ||
|
||
export const installProjectDependencies = (packageManager: string, project: string, runDev =true) => { | ||
try { | ||
const spinner = Ora(`Installing dependencies with ${packageManager}`).start() | ||
|
||
Execa.sync(packageManager, ['install'], { | ||
cwd: Path.resolve(process.cwd(), project), | ||
stdin: 'ignore' | ||
}) | ||
|
||
spinner.stop() | ||
|
||
signale.success(`🚀 Done installing project.\n\n🎉 Congratulations on the start of something amazing!\n\n💻 Run the following command to get started:\n\ncd ${project} && ${packageManager} run dev\n\n`) | ||
|
||
process.exit(0) | ||
} catch (e) { | ||
signale.error(e) | ||
|
||
process.exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { Signale } from 'signale' | ||
|
||
export default new Signale() |
4 changes: 4 additions & 0 deletions
4
packages/create-tensei-app/templates/quickstart/.gitignore.edge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules/ | ||
@if(mikro_orm_database === 'sqlite') | ||
{{ mikro_orm_db_name }} | ||
@endif |
26 changes: 26 additions & 0 deletions
26
packages/create-tensei-app/templates/quickstart/index.js.edge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const { auth } = require('@tensei/auth') | ||
const { tensei } = require('@tensei/core') | ||
const { {{ api_package }} } = require('@tensei/{{ api_package }}') | ||
|
||
tensei() | ||
.plugins([ | ||
auth() | ||
.noCookies() | ||
.plugin(), | ||
{{ api_package }}() | ||
.plugin() | ||
]) | ||
.databaseConfig({ | ||
type: '{{ mikro_orm_database }}', | ||
dbName: '{{ mikro_orm_db_name }}', | ||
@if(mikro_orm_db_pass !== undefined) | ||
password: '{{ mikro_orm_db_pass }}', | ||
@endif | ||
@if(mikro_orm_db_host !== undefined) | ||
host: '{{ mikro_orm_db_host }}', | ||
@endif | ||
@if(mikro_orm_db_username !== undefined) | ||
user: '{{ mikro_orm_db_username }}', | ||
@endif | ||
}) | ||
.start() |
Oops, something went wrong.