UNPKG

lambdaorm-cli

Version:
343 lines 16.5 kB
"use strict"; 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