mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
added init and version commands
This commit is contained in:
parent
f919ded673
commit
fb87751156
@ -1,4 +1,4 @@
|
||||
version: '2'
|
||||
version: '3'
|
||||
services:
|
||||
|
||||
# mysql
|
||||
|
||||
1
docs/changelog.md
Normal file
1
docs/changelog.md
Normal file
@ -0,0 +1 @@
|
||||
# Changelog
|
||||
@ -23,7 +23,7 @@ Its all possible with TypeORM:
|
||||
* automatic migrations generation
|
||||
* replication
|
||||
* connection pooling
|
||||
* caching [TBD]
|
||||
* query caching
|
||||
* CLI to simplify and automate your work with database
|
||||
|
||||
And more...
|
||||
@ -1,5 +1,6 @@
|
||||
# Using CLI
|
||||
|
||||
* [Initialize a new TypeORM project](#initialize-a-new-typeorm-project)
|
||||
* [Create a new entity](#create-a-new-entity)
|
||||
* [Create a new subscriber](#create-a-new-subscriber)
|
||||
* [Create a new migration](#create-a-new-migration)
|
||||
@ -10,8 +11,46 @@
|
||||
* [Log sync database schema queries without actual running them](#log-sync-database-schema-queries-without-actual-running-them)
|
||||
* [Drop database schema](#drop-database-schema)
|
||||
* [Run any sql query](#run-any-sql-query)
|
||||
* [Check version](#check-version)
|
||||
* Create database backup [TBD]
|
||||
|
||||
## Initialize a new TypeORM project
|
||||
|
||||
You can create a new project with everything already setup using following command:
|
||||
|
||||
```
|
||||
typeorm init
|
||||
```
|
||||
|
||||
It creates all files needed for a basic project with TypeORM:
|
||||
|
||||
* package.json
|
||||
* README.md
|
||||
* tsconfig.json
|
||||
* ormconfig.json
|
||||
* src/entity/User.ts
|
||||
* src/index.ts
|
||||
|
||||
Then you can run `npm install` to install all dependencies.
|
||||
Once all dependencies are installed you need to modify `ormconfig.json` and insert your own database settings.
|
||||
After that you can run your application by running `npm start` command.
|
||||
|
||||
All files are generated inside current directory where you are.
|
||||
If you want to generate in a specific directory you can use `--name` option:
|
||||
|
||||
```
|
||||
typeorm init --name my-project
|
||||
```
|
||||
|
||||
You can also generate a `docker-compose.yml` file if you want to use `docker` in your project by running following command:
|
||||
|
||||
```
|
||||
typeorm init --docker
|
||||
```
|
||||
|
||||
Using `typeorm init` command is the easiest and fastest way to setup a TypeORM project.
|
||||
|
||||
|
||||
## Create a new entity
|
||||
|
||||
You can create a new entity using CLI:
|
||||
@ -175,3 +214,11 @@ You can execute any sql query you want directly in the database using following
|
||||
```
|
||||
typeorm query "SELECT * FROM USERS"
|
||||
```
|
||||
|
||||
## Check version
|
||||
|
||||
You can check what typeorm version you have installed (both local and global) by running following command:
|
||||
|
||||
```
|
||||
typeorm version
|
||||
```
|
||||
@ -10,6 +10,8 @@ import {MigrationRevertCommand} from "./commands/MigrationRevertCommand";
|
||||
import {SubscriberCreateCommand} from "./commands/SubscriberCreateCommand";
|
||||
import {SchemaLogCommand} from "./commands/SchemaLogCommand";
|
||||
import {MigrationGenerateCommand} from "./commands/MigrationGenerateCommand";
|
||||
import {VersionCommand} from "./commands/VersionCommand";
|
||||
import {InitCommand} from "./commands/InitCommand";
|
||||
|
||||
require("yargs")
|
||||
.usage("Usage: $0 <command> [options]")
|
||||
@ -23,6 +25,8 @@ require("yargs")
|
||||
.command(new MigrationGenerateCommand())
|
||||
.command(new MigrationRunCommand())
|
||||
.command(new MigrationRevertCommand())
|
||||
.command(new VersionCommand())
|
||||
.command(new InitCommand())
|
||||
.demand(1)
|
||||
.version(() => require("./package.json").version)
|
||||
.alias("v", "version")
|
||||
|
||||
@ -17,11 +17,23 @@ export class CommandUtils {
|
||||
/**
|
||||
* Creates a file with the given content in the given path.
|
||||
*/
|
||||
static async createFile(filePath: string, content: string): Promise<void> {
|
||||
static async createFile(filePath: string, content: string, override: boolean = true): Promise<void> {
|
||||
await CommandUtils.createDirectories(path.dirname(filePath));
|
||||
return new Promise<void>((ok, fail) => {
|
||||
if (override === false && fs.existsSync(filePath))
|
||||
return ok();
|
||||
|
||||
fs.writeFile(filePath, content, err => err ? fail(err) : ok());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads everything from a given file and returns its content as a string.
|
||||
*/
|
||||
static async readFile(filePath: string): Promise<string> {
|
||||
return new Promise<string>((ok, fail) => {
|
||||
fs.readFile(filePath, (err, data) => err ? fail(err) : ok(data.toString()));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
245
src/commands/InitCommand.ts
Normal file
245
src/commands/InitCommand.ts
Normal file
@ -0,0 +1,245 @@
|
||||
import {CommandUtils} from "./CommandUtils";
|
||||
const chalk = require("chalk");
|
||||
|
||||
/**
|
||||
* Generates a new project with TypeORM.
|
||||
*/
|
||||
export class InitCommand {
|
||||
command = "init";
|
||||
describe = "Generates initial TypeORM project structure. " +
|
||||
"If name specified then creates files inside directory called as name. " +
|
||||
"If its not specified then creates files inside current directory.";
|
||||
|
||||
builder(yargs: any) {
|
||||
return yargs
|
||||
.option("c", {
|
||||
alias: "connection",
|
||||
default: "default",
|
||||
describe: "Name of the connection on which to run a query"
|
||||
})
|
||||
.option("n", {
|
||||
alias: "name",
|
||||
describe: "Name of the project directory."
|
||||
})
|
||||
.option("d", {
|
||||
alias: "docker",
|
||||
describe: "Set to true if docker-compose must be generated as well. False by default."
|
||||
});
|
||||
}
|
||||
|
||||
async handler(argv: any) {
|
||||
try {
|
||||
const isDocker = argv.docker !== undefined ? true : false;
|
||||
const basePath = process.cwd() + (argv.name ? ("/" + argv.name) : "");
|
||||
await CommandUtils.createFile(basePath + "/package.json", InitCommand.getPackageJsonTemplate(), false);
|
||||
if (isDocker)
|
||||
await CommandUtils.createFile(basePath + "/docker-compose.yml", InitCommand.getDockerComposeTemplate(), false);
|
||||
await CommandUtils.createFile(basePath + "/README.md", InitCommand.getReadmeTemplate({ docker: isDocker }), false);
|
||||
await CommandUtils.createFile(basePath + "/tsconfig.json", InitCommand.getTsConfigTemplate());
|
||||
await CommandUtils.createFile(basePath + "/ormconfig.json", InitCommand.getOrmConfigTemplate());
|
||||
await CommandUtils.createFile(basePath + "/src/entity/User.ts", InitCommand.getUserEntityTemplate());
|
||||
await CommandUtils.createFile(basePath + "/src/index.ts", InitCommand.getAppIndexTemplate());
|
||||
await CommandUtils.createDirectories(basePath + "/src/migration");
|
||||
|
||||
const packageJsonContents = await CommandUtils.readFile(basePath + "/package.json");
|
||||
await CommandUtils.createFile(basePath + "/package.json", InitCommand.appendPackageJson(packageJsonContents));
|
||||
|
||||
if (argv.name) {
|
||||
console.log(chalk.green(`Project created inside ${chalk.blue(basePath)} directory.`));
|
||||
|
||||
} else {
|
||||
console.log(chalk.green(`Project created inside current directory.`));
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.log(chalk.black.bgRed("Error during project initialization:"));
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Static Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets contents of the ormconfig file.
|
||||
*/
|
||||
protected static getOrmConfigTemplate(): string {
|
||||
return JSON.stringify({
|
||||
type: "mysql",
|
||||
host: "localhost",
|
||||
port: 3306,
|
||||
username: "test",
|
||||
password: "test",
|
||||
database: "test",
|
||||
syncrhonize: true,
|
||||
logging: false,
|
||||
entities: [
|
||||
"src/entity/**/*.ts"
|
||||
],
|
||||
migrations: [
|
||||
"src/migration/**/*.ts"
|
||||
],
|
||||
subscribers: [
|
||||
"src/subscriber/**/*.ts"
|
||||
]
|
||||
}, undefined, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets contents of the ormconfig file.
|
||||
*/
|
||||
protected static getTsConfigTemplate(): string {
|
||||
return JSON.stringify({
|
||||
compilerOptions: {
|
||||
lib: ["es5", "es6"],
|
||||
target: "es5",
|
||||
module: "commonjs",
|
||||
moduleResolution: "node",
|
||||
emitDecoratorMetadata: true,
|
||||
experimentalDecorators: true,
|
||||
sourceMap: true
|
||||
}
|
||||
}
|
||||
, undefined, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets contents of the user entity.
|
||||
*/
|
||||
protected static getUserEntityTemplate(): string {
|
||||
return `import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
firstName: string;
|
||||
|
||||
@Column()
|
||||
lastName: string;
|
||||
|
||||
@Column()
|
||||
age: number;
|
||||
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets contents of the main (index) application file.
|
||||
*/
|
||||
protected static getAppIndexTemplate(): string {
|
||||
return `import "reflect-metadata";
|
||||
import {createConnection} from "typeorm";
|
||||
import {User} from "./entity/User";
|
||||
|
||||
createConnection().then(async connection => {
|
||||
|
||||
console.log("Inserting a new user into the database...");
|
||||
const user = new User();
|
||||
user.firstName = "Timber";
|
||||
user.lastName = "Saw";
|
||||
user.age = 25;
|
||||
await connection.manager.save(user);
|
||||
console.log("Saved a new user with id: " + user.id);
|
||||
|
||||
console.log("Loading users from the database...");
|
||||
const users = await connection.manager.find(User);
|
||||
console.log("Loaded users: ", users);
|
||||
|
||||
console.log("Here you can setup and run express/koa/any other framework.");
|
||||
});
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets contents of the new package.json file.
|
||||
*/
|
||||
protected static getPackageJsonTemplate(): string {
|
||||
return JSON.stringify({
|
||||
name: "typeorm",
|
||||
version: "0.0.1",
|
||||
description: "Awesome project developed with TypeORM.",
|
||||
devDependencies: {
|
||||
},
|
||||
dependencies: {
|
||||
},
|
||||
scripts: {
|
||||
}
|
||||
}, undefined, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets contents of the new docker-compose.yml file.
|
||||
*/
|
||||
protected static getDockerComposeTemplate(): string {
|
||||
return `version: '3'
|
||||
services:
|
||||
|
||||
mysql:
|
||||
image: "mysql:5.7.10"
|
||||
container_name: "typeorm-mysql"
|
||||
ports:
|
||||
- "3306:3306"
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "admin"
|
||||
MYSQL_USER: "test"
|
||||
MYSQL_PASSWORD: "test"
|
||||
MYSQL_DATABASE: "test"
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets contents of the new readme.md file.
|
||||
*/
|
||||
protected static getReadmeTemplate(options: { docker: boolean }): string {
|
||||
let template = `# Awesome Project Build with TypeORM
|
||||
|
||||
Steps to run this project:
|
||||
|
||||
1. Run \`npm i\` command
|
||||
`;
|
||||
|
||||
if (options.docker) {
|
||||
template += `2. Run \`docker-compose up\` command
|
||||
`;
|
||||
} else {
|
||||
template += `2. Setup database settings inside \`ormconfig.json\` file
|
||||
`;
|
||||
}
|
||||
|
||||
template += `3. Run \`npm start\` command
|
||||
`;
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends to a given package.json template everything needed.
|
||||
*/
|
||||
protected static appendPackageJson(packageJsonContents: string/*, docker: boolean*/): string {
|
||||
const packageJson = JSON.parse(packageJsonContents);
|
||||
|
||||
if (!packageJson.devDependencies) packageJson.devDependencies = {};
|
||||
Object.assign(packageJson.devDependencies, {
|
||||
"ts-node": "3.3.0",
|
||||
typescript: "2.5.2"
|
||||
});
|
||||
|
||||
if (!packageJson.dependencies) packageJson.dependencies = {};
|
||||
Object.assign(packageJson.dependencies, {
|
||||
typeorm: "0.1.0-alpha.42" // require("../package.json").version
|
||||
});
|
||||
|
||||
if (!packageJson.scripts) packageJson.scripts = {};
|
||||
Object.assign(packageJson.scripts, {
|
||||
start: /*(docker ? "docker-compose up && " : "") + */"ts-node src/index.ts"
|
||||
});
|
||||
return JSON.stringify(packageJson, undefined, 3);
|
||||
}
|
||||
|
||||
}
|
||||
48
src/commands/VersionCommand.ts
Normal file
48
src/commands/VersionCommand.ts
Normal file
@ -0,0 +1,48 @@
|
||||
const exec = require("child_process").exec;
|
||||
|
||||
/**
|
||||
* Shows typeorm version.
|
||||
*/
|
||||
export class VersionCommand {
|
||||
command = "version";
|
||||
describe = "Prints TypeORM version this project uses.";
|
||||
|
||||
async handler(argv: any) {
|
||||
|
||||
const localNpmList = await this.executeCommand("npm list --depth=0");
|
||||
const localMatches = localNpmList.match(/ typeorm@(.*)\n/);
|
||||
const localNpmVersion = (localMatches && localMatches[1] ? localMatches[1] : "").replace(/"invalid"/gi, "").trim();
|
||||
|
||||
const globalNpmList = await this.executeCommand("npm list -g --depth=0");
|
||||
const globalMatches = globalNpmList.match(/ typeorm@(.*)\n/);
|
||||
const globalNpmVersion = (globalMatches && globalMatches[1] ? globalMatches[1] : "").replace(/"invalid"/gi, "").trim();
|
||||
|
||||
if (localNpmVersion) {
|
||||
console.log("Local installed version:", localNpmVersion);
|
||||
} else {
|
||||
console.log("No local installed TypeORM was found.");
|
||||
}
|
||||
if (globalNpmVersion) {
|
||||
console.log("Global installed TypeORM version:", globalNpmVersion);
|
||||
} else {
|
||||
console.log("No global installed was found.");
|
||||
}
|
||||
|
||||
if (localNpmVersion && globalNpmVersion && localNpmVersion !== globalNpmVersion) {
|
||||
console.log("To avoid issues with CLI please make sure your global and local TypeORM versions match, " +
|
||||
"or you are using locally installed TypeORM instead of global one.");
|
||||
}
|
||||
}
|
||||
|
||||
protected executeCommand(command: string) {
|
||||
return new Promise<string>((ok, fail) => {
|
||||
exec(command, (error: any, stdout: any, stderr: any) => {
|
||||
if (stdout) return ok(stdout);
|
||||
if (stderr) return ok(stderr);
|
||||
if (error) return fail(error);
|
||||
ok("");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user