diff --git a/packages/cli/generators/relation/index.js b/packages/cli/generators/relation/index.js index 0c7cb5703e50..25f140721943 100644 --- a/packages/cli/generators/relation/index.js +++ b/packages/cli/generators/relation/index.js @@ -230,6 +230,26 @@ module.exports = class RelationGenerator extends ArtifactGenerator { /* istanbul ignore next */ return this.exit(err); } + // Check if modelDir contains subdirectories + const subdirectories = await utils.getSubdirectories( + this.artifactInfo.modelDir, + ); + // If subdirectories exist, retrieve models from them + if (subdirectories.length > 0) { + for (const subdirectory of subdirectories) { + try { + const subdirectoryModelList = await utils.getArtifactList( + subdirectory, + 'model', + ); + modelList = modelList.concat(subdirectoryModelList); + } catch (err) { + console.error( + `Error retrieving models from subdirectory ${subdirectory}: ${err}`, + ); + } + } + } let repoList; try { debug(`repository list dir ${this.artifactInfo.repoDir}`); diff --git a/packages/cli/generators/repository/index.js b/packages/cli/generators/repository/index.js index 6a0619f59021..0a864f81f6b0 100644 --- a/packages/cli/generators/repository/index.js +++ b/packages/cli/generators/repository/index.js @@ -101,14 +101,48 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator { this.artifactInfo.modelDir, utils.getModelFileName(modelName), ); - try { - fileContent = this.fs.read(modelFile, {}); - } catch (err) { - debug(`${ERROR_READING_FILE} ${modelFile}: ${err.message}`); - return this.exit(err); + + // Check if the model file exists directly in the modelDir + if (fs.existsSync(modelFile)) { + try { + fileContent = this.fs.read(modelFile, {}); + } catch (err) { + debug(`${ERROR_READING_FILE} ${modelFile}: ${err.message}`); + return this.exit(err); + } + + return tsquery.getIdFromModel(fileContent); } - return tsquery.getIdFromModel(fileContent); + // If the model file is not found directly, search in subdirectories + const subdirectories = await utils.getSubdirectories( + this.artifactInfo.modelDir, + ); + + for (const subdirectory of subdirectories) { + const subdirectoryModelFile = path.join( + subdirectory, + utils.getModelFileName(modelName), + ); + + if (fs.existsSync(subdirectoryModelFile)) { + try { + fileContent = this.fs.read(subdirectoryModelFile, {}); + } catch (err) { + debug( + `${ERROR_READING_FILE} ${subdirectoryModelFile}: ${err.message}`, + ); + return this.exit(err); + } + + return tsquery.getIdFromModel(fileContent); + } + } + + // If the model file is not found in any subdirectory, return an error + return this.exit( + new Error(`Model ${modelName} not found in any subdirectory.`), + ); } /** @@ -330,6 +364,34 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator { return this.exit(err); } + // Check if modelDir contains subdirectories + const subdirectories = await utils.getSubdirectories( + this.artifactInfo.modelDir, + ); + // If subdirectories exist, retrieve models from them + if (subdirectories.length > 0) { + for (const subdirectory of subdirectories) { + try { + const subdirectoryModelList = await utils.getArtifactList( + subdirectory, + 'model', + ); + const subdir = subdirectory.split('models')[1]; + if (!this.artifactInfo.modelSubDirs) { + this.artifactInfo.modelSubDirs = {}; + } + subdirectoryModelList.forEach(model => { + this.artifactInfo.modelSubDirs[model] = subdir; + }); + modelList = modelList.concat(subdirectoryModelList); + } catch (err) { + console.error( + `Error retrieving models from subdirectory ${subdirectory}: ${err}`, + ); + } + } + } + if (this.options.model) { debug(`Model name received from command line: ${this.options.model}`); @@ -529,6 +591,15 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator { this.artifactInfo.modelName, ); + const outFile = `${ + this.artifactInfo.modelSubDirs[ + this.artifactInfo.modelName || this.artifactInfo.name + ] + }/${this.artifactInfo.outFile}`; + if (!outFile.includes('undefined')) { + this.artifactInfo.outFile = outFile.slice(1, outFile.length); + } + this.artifactInfo.indexesToBeUpdated.push({ dir: this.artifactInfo.outDir, file: this.artifactInfo.outFile, diff --git a/packages/cli/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs b/packages/cli/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs index b150d57bb050..f3b6932e8154 100644 --- a/packages/cli/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs +++ b/packages/cli/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs @@ -2,8 +2,16 @@ import {inject} from '@loopback/core'; <%if (isRepositoryBaseBuiltin) { -%> import {<%= repositoryTypeClass %>} from '@loopback/repository'; <% } -%> -import {<%= dataSourceClassName %>} from '../datasources'; -import {<%= modelName %>, <%= modelName %>Relations} from '../models'; +<%if (modelSubDirs[modelName]) { -%> + import {<%= dataSourceClassName %>} from '../../datasources'; + import {<%= modelName %>, <%= modelName %>Relations} from '../../models'; +<% } -%> + +<%if (!modelSubDirs[modelName]) { -%> + import {<%= dataSourceClassName %>} from '../datasources'; + import {<%= modelName %>, <%= modelName %>Relations} from '../models'; +<% } -%> + <%if ( !isRepositoryBaseBuiltin ) { -%> import {<%=repositoryBaseClass %>} from './<%=repositoryBaseFile %>'; <% } -%> diff --git a/packages/cli/lib/utils.js b/packages/cli/lib/utils.js index 8ce58b2f2d69..a9512dd70a57 100644 --- a/packages/cli/lib/utils.js +++ b/packages/cli/lib/utils.js @@ -6,6 +6,7 @@ 'use strict'; const fs = require('node:fs'); +const fsp = require('fs/promises'); const path = require('node:path'); const util = require('node:util'); const stream = require('node:stream'); @@ -383,6 +384,21 @@ exports.getArtifactList = async function ( }); }; +/** + * Retrieves a list of subdirectories within a given directory. + * + * @param {string} dir The directory path to search for subdirectories. + */ +exports.getSubdirectories = async function (dir) { + const entries = await fsp.readdir(dir, {withFileTypes: true}); + + const subdirectories = entries + .filter(entry => entry.isDirectory()) + .map(entry => path.join(dir, entry.name)); + + return subdirectories; +}; + /** * Check package.json and dependencies.json to find out versions for generated * dependencies