lambdaorm-cli
Version:
The lambdaorm command line interface
343 lines • 16.5 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeLanguageService = void 0;
const lambdaorm_1 = require("lambdaorm");
const path_1 = __importDefault(require("path"));
class NodeLanguageService {
constructor(schemaState, helper) {
this.schemaState = schemaState;
this.helper = helper;
this.library = 'lambdaorm';
}
get name() {
return 'node';
}
build(args) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f;
let schema = yield this.schemaState.load(args.workspace);
if (schema === null) {
throw new Error(`Can't found schema in ${args.workspace}`);
}
if (!schema.infrastructure) {
schema.infrastructure = {};
}
const _srcPath = args.srcPath || ((_b = (_a = schema.infrastructure) === null || _a === void 0 ? void 0 : _a.paths) === null || _b === void 0 ? void 0 : _b.src) || 'src';
const _dataPath = args.dataPath || ((_d = (_c = schema.infrastructure) === null || _c === void 0 ? void 0 : _c.paths) === null || _d === void 0 ? void 0 : _d.state) || 'orm_state';
const _domainPath = args.domainPath || ((_f = (_e = schema.infrastructure) === null || _e === void 0 ? void 0 : _e.paths) === null || _f === void 0 ? void 0 : _f.domain) || 'domain';
schema = yield this.schemaState.load(schema);
yield this.updateStructure(args.workspace, _srcPath, _dataPath);
// add libraries for dialect
if (schema.infrastructure && schema.infrastructure.sources && schema.infrastructure.sources.length > 0) {
yield this.addDialects(args.workspace, schema.infrastructure);
}
if (_domainPath) {
const __domainPath = path_1.default.join(args.workspace, _srcPath, _domainPath);
if (args.options.includes('model')) {
yield this.buildModel(__domainPath, schema.domain);
}
if (args.options.includes('repositories')) {
yield this.buildRepositories(__domainPath, schema.domain);
}
}
});
}
localVersion(workspace) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.helper.cli.getPackage('lambdaorm', workspace);
});
}
/**
* if the package.json does not exist create it
*/
createPackage(workspace) {
return __awaiter(this, void 0, void 0, function* () {
const packagePath = path_1.default.join(workspace, 'package.json');
if (!(yield this.helper.fs.exists(packagePath))) {
yield this.helper.fs.write(packagePath, JSON.stringify({ dependencies: {} }, null, 2));
}
});
}
/**
* if the tsconfig.json does not exist create it
*/
createTsconfig(workspace) {
return __awaiter(this, void 0, void 0, function* () {
const tsconfigPath = path_1.default.join(workspace, 'tsconfig.json');
if (!(yield this.helper.fs.exists(tsconfigPath))) {
const tsconfigContent = this.getTypescriptContent();
yield this.helper.fs.write(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));
}
});
}
/**
* if the typescript is not installed locally it will be installed
*/
installTypescript(workspace) {
return __awaiter(this, void 0, void 0, function* () {
const typescriptLib = yield this.helper.cli.getPackage('typescript', workspace);
if (typescriptLib === '') {
yield this.helper.utils.exec('npm install typescript -D', workspace);
}
});
}
/**
* if the lambdaorm is not installed locally it will be installed
*/
installLibrary(workspace) {
return __awaiter(this, void 0, void 0, function* () {
const lambdaormLib = yield this.helper.cli.getPackage(this.library, workspace);
if (lambdaormLib === '') {
yield this.helper.utils.exec(`npm install ${this.library}`, workspace);
}
});
}
updateStructure(workspace, srcPath, dataPath) {
return __awaiter(this, void 0, void 0, function* () {
// create initial structure
yield this.helper.fs.create(path_1.default.join(workspace, srcPath));
if (dataPath) {
yield this.helper.fs.create(path_1.default.join(workspace, dataPath));
}
yield this.createPackage(workspace);
yield this.createTsconfig(workspace);
yield this.installTypescript(workspace);
yield this.installLibrary(workspace);
});
}
addDialects(path, infrastructure) {
return __awaiter(this, void 0, void 0, function* () {
for (const p in infrastructure.sources) {
const source = infrastructure.sources[p];
// if the library is not installed locally corresponding to the dialect it will be installed
const libs = this.getLibs(source.dialect);
for (const p in libs) {
const lib = libs[p];
const localLib = yield this.helper.cli.getPackage(lib, path);
if (localLib === '') {
yield this.helper.utils.exec(`npm install ${lib}`, path);
}
}
}
});
}
buildModel(domainPath, domain) {
return __awaiter(this, void 0, void 0, function* () {
const content = this.getModelContent(domain);
this.helper.fs.create(domainPath);
const schemaPath = path_1.default.join(domainPath, 'model.ts');
yield this.helper.fs.write(schemaPath, content);
});
}
buildRepositories(domainPath, domain) {
return __awaiter(this, void 0, void 0, function* () {
this.helper.fs.create(domainPath);
for (const entity of domain.entities) {
if (entity.abstract)
continue;
const singular = this.helper.str.notation(entity.singular ? entity.singular : this.helper.str.singular(entity.name), 'pascal');
const repositoryPath = path_1.default.join(domainPath, `repository${singular}.ts`);
if (!(yield this.helper.fs.exists(repositoryPath))) {
const repositoryContent = this.getRepositoryContent(entity);
yield this.helper.fs.write(repositoryPath, repositoryContent);
}
}
});
}
getLibs(dialect) {
switch (dialect) {
case lambdaorm_1.Dialect.MySQL:
case lambdaorm_1.Dialect.MariaDB:
return ['mysql2'];
// case 'sqlite':
// return ['sqlite3']
// case 'better-sqlite3':
// return ['better-sqlite3']
case lambdaorm_1.Dialect.PostgreSQL:
return ['pg'];
case lambdaorm_1.Dialect.SqlServer:
return ['tedious'];
case lambdaorm_1.Dialect.Oracle:
return ['oracledb'];
case lambdaorm_1.Dialect.MongoDB:
return ['mongodb'];
case lambdaorm_1.Dialect.SQLjs:
return ['sql.js'];
default:
throw new Error(`dialect: ${dialect} not supported`);
}
}
getTypescriptContent() {
return {
compilerOptions: {
experimentalDecorators: true,
emitDecoratorMetadata: true,
resolveJsonModule: true,
esModuleInterop: true,
strict: true,
declaration: true,
moduleResolution: 'node',
sourceMap: true,
target: 'ES6',
module: 'commonjs',
outDir: './build',
baseUrl: './src',
typeRoots: [
'node_modules/@types'
]
},
include: [
'src/**/*'
],
exclude: [
'node_modules'
]
};
}
getRepositoryContent(entity) {
const lines = [];
const singular = this.helper.str.notation(entity.singular ? entity.singular : this.helper.str.singular(entity.name), 'pascal');
lines.push(`import { Repository, IOrm } from '${this.library}'`);
lines.push(`import { ${singular}, Qry${singular} } from './model'`);
lines.push(`export class ${singular}Repository extends Repository<${singular}, Qry${singular}> {`);
lines.push('\tconstructor (stage?: string, orm?:IOrm) {');
lines.push(`\t\tsuper('${entity.name}', stage, orm)`);
lines.push('\t}');
lines.push('\t// Add your code here');
lines.push('}');
return lines.join('\n') + '\n';
}
getModelContent(source) {
const lines = [];
lines.push('/* eslint-disable no-use-before-define */');
lines.push('// THIS FILE IS NOT EDITABLE, IS MANAGED BY LAMBDA ORM');
lines.push('// eslint-disable-next-line @typescript-eslint/no-unused-vars');
lines.push(`import { Queryable, OneToMany, ManyToOne, OneToOne } from '${this.library}'`);
if (source.enums) {
for (const p in source.enums) {
const _enum = source.enums[p];
lines.push(`export enum ${_enum.name}{`);
for (let j = 0; j < _enum.values.length; j++) {
const value = _enum.values[j];
const separator = j === _enum.values.length - 1 ? '' : ',';
if (typeof value.value === 'number') {
lines.push(`\t${value.name} = ${value.value}${separator}`);
}
else {
lines.push(`\t${value.name} = '${value.value}'${separator}`);
}
}
lines.push('}');
}
}
if (source.entities) {
for (const entity of source.entities) {
const singular = this.helper.str.notation(entity.singular ? entity.singular : this.helper.str.singular(entity.name), 'pascal');
const _abstract = entity.abstract ? ' abstract ' : ' ';
const _extends = entity.extends ? ' extends ' + this.helper.str.singular(entity.extends) + ' ' : ' ';
// create class
lines.push(`export${_abstract}class ${singular}${_extends}{`);
if (entity.relations && entity.relations.some(p => p.type === 'manyToOne')) {
lines.push('\tconstructor () {');
if (entity.extends) {
lines.push('\t\tsuper()');
}
for (const q in entity.relations) {
const relation = entity.relations[q];
if (relation.type === 'manyToOne') {
lines.push(`\t\tthis.${relation.name} = []`);
}
}
lines.push('\t}');
lines.push('');
}
for (const q in entity.properties) {
const property = entity.properties[q];
const type = property.enum ? property.enum : this.getType(property.type);
if (property.required && property.default === undefined) {
lines.push(`\t${property.name}?: ${type}`);
}
else {
lines.push(`\t${property.name}?: ${type}`);
}
}
for (const q in entity.relations) {
const relation = entity.relations[q];
const relationEntity = source.entities.find(p => p.name === relation.entity);
if (relationEntity === undefined) {
throw new Error(`Not exists ${relation.entity} relation in ${entity.name} entity`);
}
const relationEntitySingularName = this.helper.str.notation(relationEntity.singular ? relationEntity.singular : this.helper.str.singular(relationEntity.name), 'pascal');
switch (relation.type) {
case 'oneToMany':
case 'oneToOne':
lines.push(`\t${relation.name}?: ${relationEntitySingularName}`);
break;
case 'manyToOne':
lines.push(`\t${relation.name}: ${relationEntitySingularName}[]`);
break;
}
}
lines.push('}');
// create interface
const _extendsInterface = entity.extends ? ' extends Qry' + this.helper.str.singular(entity.extends) + ' ' : ' ';
lines.push(`export interface Qry${singular}${_extendsInterface}{`);
for (const q in entity.properties) {
const property = entity.properties[q];
const type = property.enum ? property.enum : this.getType(property.type);
lines.push(`\t${property.name}: ${type}`);
}
for (const q in entity.relations) {
const relation = entity.relations[q];
const relationEntity = source.entities.find(p => p.name === relation.entity);
const relationEntitySingularName = this.helper.str.notation(relationEntity.singular ? relationEntity.singular : this.helper.str.singular(relationEntity.name), 'pascal');
switch (relation.type) {
case 'oneToMany':
lines.push(`\t${relation.name}: Qry${relationEntitySingularName} & OneToMany<Qry${relationEntitySingularName}> & ${relationEntitySingularName}`);
break;
case 'oneToOne':
lines.push(`\t${relation.name}: Qry${relationEntitySingularName} & OneToOne<Qry${relationEntitySingularName}> & ${relationEntitySingularName}`);
break;
case 'manyToOne':
lines.push(`\t${relation.name}: ManyToOne<Qry${relationEntitySingularName}> & ${relationEntitySingularName}[]`);
break;
}
}
lines.push('}');
}
for (const p in source.entities) {
const entity = source.entities[p];
if (!entity.abstract) {
const singular = this.helper.str.notation(entity.singular ? entity.singular : this.helper.str.singular(entity.name), 'pascal');
const entityName = this.helper.str.notation(entity.name, 'pascal');
lines.push(`export let ${entityName}: Queryable<Qry${singular}>`);
}
}
}
return lines.join('\n') + '\n';
}
getType(type) {
switch (type) {
case 'integer': return 'number';
case 'decimal': return 'number';
case 'dateTime': return 'Date';
case 'date': return 'Date';
case 'time': return 'Date';
default: return type;
}
}
}
exports.NodeLanguageService = NodeLanguageService;
//# sourceMappingURL=node.js.map