typeorm-extension
Version:
A library to create/drop database, simple seeding data sets, ...
276 lines (269 loc) • 10.9 kB
JavaScript
#!/usr/bin/env node
'use strict';
require('reflect-metadata');
var process$1 = require('node:process');
var yargs = require('yargs');
var helpers = require('yargs/helpers');
var consola = require('consola');
var typeormExtension = require('typeorm-extension');
var locter = require('locter');
var fs = require('node:fs');
var path = require('node:path');
var pascalCase = require('pascal-case');
class DatabaseCreateCommand {
builder(args) {
return args.option('preserveFilePaths', {
default: false,
type: 'boolean',
describe: 'This option indicates if file paths should be preserved.'
}).option('root', {
alias: 'r',
default: process.cwd(),
describe: 'Root directory of the project.'
}).option('tsconfig', {
alias: 'tc',
default: 'tsconfig.json',
describe: 'Name (or relative path incl. name) of the tsconfig file.'
}).option('dataSource', {
alias: 'd',
default: 'data-source',
describe: 'Name (or relative path incl. name) of the data-source file.'
}).option('synchronize', {
alias: 's',
default: 'yes',
describe: 'Create database schema for all entities.',
choices: [
'yes',
'no'
]
}).option('initialDatabase', {
describe: 'Specify the initial database to connect to.'
});
}
async handler(raw) {
const args = raw;
let tsconfig;
let sourcePath = typeormExtension.resolveFilePath(args.dataSource, args.root);
if (!args.preserveFilePaths) {
tsconfig = await typeormExtension.readTSConfig(typeormExtension.resolveFilePath(args.root, args.tsconfig));
sourcePath = await typeormExtension.adjustFilePath(sourcePath, tsconfig);
}
const source = typeormExtension.parseFilePath(sourcePath);
consola.consola.info(`DataSource Directory: ${source.directory}`);
consola.consola.info(`DataSource Name: ${source.name}`);
const dataSourceOptions = await typeormExtension.buildDataSourceOptions({
directory: source.directory,
dataSourceName: source.name,
tsconfig,
preserveFilePaths: args.preserveFilePaths
});
const context = {
ifNotExist: true,
options: dataSourceOptions
};
if (typeof args.initialDatabase === 'string' && args.initialDatabase !== '') {
context.initialDatabase = args.initialDatabase;
}
context.synchronize = args.synchronize === 'yes';
try {
await typeormExtension.createDatabase(context);
consola.consola.success('Created database.');
process.exit(0);
} catch (e) {
consola.consola.warn('Failed to create database.');
consola.consola.error(e);
process.exit(1);
}
}
constructor(){
this.command = 'db:create';
this.describe = 'Create database.';
}
}
class DatabaseDropCommand {
builder(args) {
return args.option('preserveFilePaths', {
default: false,
type: 'boolean',
describe: 'This option indicates if file paths should be preserved.'
}).option('root', {
alias: 'r',
default: process.cwd(),
describe: 'Root directory of the project.'
}).option('tsconfig', {
alias: 'tc',
default: 'tsconfig.json',
describe: 'Name (or relative path incl. name) of the tsconfig file.'
}).option('dataSource', {
alias: 'd',
default: 'data-source',
describe: 'Name (or relative path incl. name) of the data-source file.'
}).option('initialDatabase', {
describe: 'Specify the initial database to connect to.'
});
}
async handler(raw) {
const args = raw;
let tsconfig;
let sourcePath = typeormExtension.resolveFilePath(args.dataSource, args.root);
if (!args.preserveFilePaths) {
tsconfig = await typeormExtension.readTSConfig(typeormExtension.resolveFilePath(args.root, args.tsconfig));
sourcePath = await typeormExtension.adjustFilePath(sourcePath, tsconfig);
}
const source = typeormExtension.parseFilePath(sourcePath);
consola.consola.info(`DataSource Directory: ${source.directory}`);
consola.consola.info(`DataSource Name: ${source.name}`);
const dataSourceOptions = await typeormExtension.buildDataSourceOptions({
directory: source.directory,
dataSourceName: source.name,
tsconfig,
preserveFilePaths: args.preserveFilePaths
});
const context = {
ifExist: true,
options: dataSourceOptions
};
if (typeof args.initialDatabase === 'string' && args.initialDatabase !== '') {
context.initialDatabase = args.initialDatabase;
}
try {
await typeormExtension.dropDatabase(context);
consola.consola.success('Dropped database.');
process.exit(0);
} catch (e) {
consola.consola.warn('Failed to drop database.');
consola.consola.error(e);
process.exit(1);
}
}
constructor(){
this.command = 'db:drop';
this.describe = 'Drop database.';
}
}
class SeedCreateCommand {
builder(args) {
return args.option('root', {
alias: 'r',
default: process.cwd(),
describe: 'Root directory of the project.'
}).option('timestamp', {
alias: 't',
type: 'number',
describe: 'Custom timestamp for the seeder name.'
}).option('javascript', {
alias: 'j',
type: 'boolean',
default: false,
describe: 'Generate a seeder file for JavaScript instead of TypeScript.'
}).option('name', {
alias: 'n',
describe: 'Name (or relative path incl. name) of the seeder.',
demandOption: true
});
}
async handler(raw) {
const args = raw;
let timestamp;
if (Number.isNaN(args.timestamp) || !args.timestamp) {
timestamp = Date.now();
} else {
timestamp = args.timestamp;
}
const sourcePath = typeormExtension.parseFilePath(args.name, args.root);
const dirNameIsDirectory = await typeormExtension.isDirectory(sourcePath.directory);
if (!dirNameIsDirectory) {
consola.consola.warn(`The output directory ${sourcePath.directory} does not exist.`);
process.exit(1);
}
const extension = args.javascript ? '.js' : '.ts';
const nameExtension = locter.getFileNameExtension(sourcePath.name);
const nameWithoutExtension = locter.removeFileNameExtension(sourcePath.name);
let fileName;
if (nameExtension) {
fileName = `${timestamp}-${sourcePath.name}`;
} else {
fileName = `${timestamp}-${sourcePath.name}${extension}`;
}
const filePath = sourcePath.directory + path.sep + fileName;
const template = typeormExtension.buildSeederFileTemplate(nameWithoutExtension, timestamp);
consola.consola.info(`Seed Directory: ${sourcePath.directory}`);
consola.consola.info(`Seed FileName: ${fileName}`);
consola.consola.info(`Seed Name: ${pascalCase.pascalCase(nameWithoutExtension)}`);
try {
await fs.promises.writeFile(filePath, template, {
encoding: 'utf-8'
});
} catch (e) {
consola.consola.warn(`The seed could not be written to the path ${filePath}.`);
process.exit(1);
}
process.exit(0);
}
constructor(){
this.command = 'seed:create';
this.describe = 'Create a seeder file.';
}
}
class SeedRunCommand {
builder(args) {
return args.option('preserveFilePaths', {
default: false,
type: 'boolean',
describe: 'This option indicates if file paths should be preserved.'
}).option('root', {
alias: 'r',
default: process.cwd(),
describe: 'Root directory of the project.'
}).option('tsconfig', {
alias: 'tc',
default: 'tsconfig.json',
describe: 'Name (or relative path incl. name) of the tsconfig file.'
}).option('dataSource', {
alias: 'd',
default: 'data-source',
describe: 'Name (or relative path incl. name) of the data-source file.'
}).option('name', {
alias: 'n',
describe: 'Name (or relative path incl. name) of the seeder.'
});
}
async handler(raw) {
const args = raw;
let tsconfig;
let sourcePath = typeormExtension.resolveFilePath(args.dataSource, args.root);
if (!args.preserveFilePaths) {
tsconfig = await typeormExtension.readTSConfig(args.root);
sourcePath = await typeormExtension.adjustFilePath(sourcePath, tsconfig);
args.name = await typeormExtension.adjustFilePath(args.name, tsconfig);
}
const source = typeormExtension.parseFilePath(sourcePath);
consola.consola.info(`DataSource Directory: ${source.directory}`);
consola.consola.info(`DataSource Name: ${source.name}`);
const dataSourceOptions = await typeormExtension.buildDataSourceOptions({
dataSourceName: source.name,
directory: source.directory,
tsconfig,
preserveFilePaths: args.preserveFilePaths
});
typeormExtension.setDataSourceOptions(dataSourceOptions);
if (args.name) {
consola.consola.info(`Seed Name: ${args.name}`);
}
const dataSource = await typeormExtension.useDataSource();
const executor = new typeormExtension.SeederExecutor(dataSource, {
root: args.root,
tsconfig,
preserveFilePaths: args.preserveFilePaths
});
await executor.execute({
seedName: args.name
});
process.exit(0);
}
constructor(){
this.command = 'seed:run';
this.describe = 'Populate the database with an initial data set or generated data by a factory.';
}
}
yargs(helpers.hideBin(process$1.argv)).scriptName('typeorm-extension').usage('Usage: $0 <command> [options]').demandCommand(1).command(new DatabaseCreateCommand()).command(new DatabaseDropCommand()).command(new SeedRunCommand()).command(new SeedCreateCommand()).strict().alias('v', 'version').help('h').alias('h', 'help').parse();