From 3820dd60dab476412e7e6b0c4d5a8b4c4d8b4d63 Mon Sep 17 00:00:00 2001 From: Victor Ivens Pereira Date: Mon, 30 Oct 2017 14:15:32 -0200 Subject: [PATCH 1/2] Add the hability to parse Glob and Folder path in modelPaths Changed the usage of FS to GLOB. If the Path isn't a glob, it's a folder path and to work with glob, must be turned into a glob (by adding /* in the end). I think the check if it `hasMagic` should be an outside function, chained in a `map` before `arg.reduce`. --- lib/services/models.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/services/models.ts b/lib/services/models.ts index d8a963e7..41d5aadd 100644 --- a/lib/services/models.ts +++ b/lib/services/models.ts @@ -1,5 +1,5 @@ import 'reflect-metadata'; -import * as fs from 'fs'; +import * as glob from 'glob'; import * as path from 'path'; import {DataTypeAbstract, DefineOptions} from 'sequelize'; import {Model} from "../models/Model"; @@ -182,14 +182,16 @@ export function getModels(arg: Array): Array { - const _models = fs - .readdirSync(dir as string) + if (!glob.hasMagic(dir)) dir = path.join(dir, '/*'); + const _models = glob + .sync(dir as string) .filter(isImportable) - .map(getFilenameWithoutExtension) + .map(getFullfilepathWithoutExtension) .filter(uniqueFilter) - .map(fileName => { - const fullPath = path.join(dir, fileName); + .map(fullPath => { + const module = require(fullPath); + const fileName = getFilenameWithoutExtension(fullPath); if (!module[fileName] && !module.default) { throw new Error(`No default export defined for file "${fileName}" or ` + @@ -313,3 +315,11 @@ function isImportable(file: string): boolean { function getFilenameWithoutExtension(file: string): string { return path.parse(file).name; } + +/** + * Return the value of the full path with filename, without extension + */ +function getFullfilepathWithoutExtension(file: string): string { + const parsedFile = path.parse(file); + return path.join(parsedFile.dir, parsedFile.name); +} From 1c4e4f85eaea76f80ab1010baa7eaf9712f40011 Mon Sep 17 00:00:00 2001 From: Victor Ivens Pereira Date: Tue, 31 Oct 2017 13:33:58 -0200 Subject: [PATCH 2/2] Created tests to check if glob on modelPaths is working As suggested, I created 2 folders. In the first, all the files are already inside and should work normally. The other one has subfolders and must be matched via glob. --- test/models/globs/match-dir-only/PlayerDir.ts | 7 ++ test/models/globs/match-dir-only/ShoeDir.ts | 9 +++ test/models/globs/match-dir-only/TeamDir.ts | 8 +++ .../players/player.model.ts | 7 ++ .../match-sub-dir-files/shoes/shoe.model.ts | 9 +++ .../match-sub-dir-files/teams/team.model.ts | 8 +++ test/specs/models/sequelize.spec.ts | 67 ++++++++++++++++++- 7 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 test/models/globs/match-dir-only/PlayerDir.ts create mode 100644 test/models/globs/match-dir-only/ShoeDir.ts create mode 100644 test/models/globs/match-dir-only/TeamDir.ts create mode 100644 test/models/globs/match-sub-dir-files/players/player.model.ts create mode 100644 test/models/globs/match-sub-dir-files/shoes/shoe.model.ts create mode 100644 test/models/globs/match-sub-dir-files/teams/team.model.ts diff --git a/test/models/globs/match-dir-only/PlayerDir.ts b/test/models/globs/match-dir-only/PlayerDir.ts new file mode 100644 index 00000000..b3c35bc2 --- /dev/null +++ b/test/models/globs/match-dir-only/PlayerDir.ts @@ -0,0 +1,7 @@ +import {Table, Model, Column,} from "../../../../index"; + +@Table +export default class PlayerDir extends Model { + @Column + name: string; +} diff --git a/test/models/globs/match-dir-only/ShoeDir.ts b/test/models/globs/match-dir-only/ShoeDir.ts new file mode 100644 index 00000000..1bdbd872 --- /dev/null +++ b/test/models/globs/match-dir-only/ShoeDir.ts @@ -0,0 +1,9 @@ +import {Table, Model, Column} from "../../../../index"; + +@Table +export default class ShoeDir extends Model { + + @Column + brand: string; + +} diff --git a/test/models/globs/match-dir-only/TeamDir.ts b/test/models/globs/match-dir-only/TeamDir.ts new file mode 100644 index 00000000..77a8f3d6 --- /dev/null +++ b/test/models/globs/match-dir-only/TeamDir.ts @@ -0,0 +1,8 @@ +import {Table, Model, Column} from "../../../../index"; + +@Table +export default class TeamDir extends Model { + + @Column + name: string; +} diff --git a/test/models/globs/match-sub-dir-files/players/player.model.ts b/test/models/globs/match-sub-dir-files/players/player.model.ts new file mode 100644 index 00000000..d7f1072e --- /dev/null +++ b/test/models/globs/match-sub-dir-files/players/player.model.ts @@ -0,0 +1,7 @@ +import {Table, Model, Column,} from "../../../../../index"; + +@Table +export default class PlayerGlob extends Model { + @Column + name: string; +} diff --git a/test/models/globs/match-sub-dir-files/shoes/shoe.model.ts b/test/models/globs/match-sub-dir-files/shoes/shoe.model.ts new file mode 100644 index 00000000..c735f4b8 --- /dev/null +++ b/test/models/globs/match-sub-dir-files/shoes/shoe.model.ts @@ -0,0 +1,9 @@ +import {Table, Model, Column} from "../../../../../index"; + +@Table +export default class ShoeGlob extends Model { + + @Column + brand: string; + +} diff --git a/test/models/globs/match-sub-dir-files/teams/team.model.ts b/test/models/globs/match-sub-dir-files/teams/team.model.ts new file mode 100644 index 00000000..ca8c6ae9 --- /dev/null +++ b/test/models/globs/match-sub-dir-files/teams/team.model.ts @@ -0,0 +1,8 @@ +import {Table, Model, Column} from "../../../../../index"; + +@Table +export default class TeamGlob extends Model { + + @Column + name: string; +} diff --git a/test/specs/models/sequelize.spec.ts b/test/specs/models/sequelize.spec.ts index ae9a8d1d..94b9302b 100644 --- a/test/specs/models/sequelize.spec.ts +++ b/test/specs/models/sequelize.spec.ts @@ -7,6 +7,12 @@ import Gamer from "../../models/exports/gamer.model"; import {Sequelize} from "../../../lib/models/Sequelize"; import {Model} from '../../../lib/models/Model'; import {Table} from '../../../lib/annotations/Table'; +import PlayerGlob from "../../models/globs/match-sub-dir-files/players/player.model"; +import ShoeGlob from "../../models/globs/match-sub-dir-files/shoes/shoe.model"; +import TeamGlob from "../../models/globs/match-sub-dir-files/teams/team.model"; +import PlayerDir from "../../models/globs/match-dir-only/PlayerDir"; +import TeamDir from "../../models/globs/match-dir-only/TeamDir"; +import ShoeDir from "../../models/globs/match-dir-only/ShoeDir"; describe('sequelize', () => { @@ -104,7 +110,7 @@ describe('sequelize', () => { .to.have.property('options') .that.has.property('define') .that.eqls(DEFINE_OPTIONS) - ; + ; }); it('should set define options for models', () => { @@ -188,4 +194,63 @@ describe('sequelize', () => { }); }); + + describe('Add models as glob and dir', () => { + it('should load classes from subfolders matching glob criteria', () => { + const db = '__'; + const sequelizeGlob = new Sequelize({ + name: db, + dialect: 'sqlite', + username: 'root', + password: '', + storage: ':memory:', + logging: !('SEQ_SILENT' in process.env), + modelPaths: [__dirname + '/../../models/globs/match-sub-dir-files/**/*.model.ts'] + }); + + expect(sequelizeGlob._).to.have.property('PlayerGlob', PlayerGlob); + expect(sequelizeGlob._).to.have.property('TeamGlob', TeamGlob); + expect(sequelizeGlob._).to.have.property('ShoeGlob', ShoeGlob); + + }); + + it('should load classes from folders', () => { + const db = '__'; + const sequelizeFolder = new Sequelize({ + name: db, + dialect: 'sqlite', + username: 'root', + password: '', + storage: ':memory:', + logging: !('SEQ_SILENT' in process.env), + modelPaths: [__dirname + '/../../models/globs/match-dir-only'] + }); + + expect(sequelizeFolder._).to.have.property('PlayerDir', PlayerDir); + expect(sequelizeFolder._).to.have.property('TeamDir', TeamDir); + expect(sequelizeFolder._).to.have.property('ShoeDir', ShoeDir); + + }); + + it('should load classes from folders and from glob', () => { + const db = '__'; + const sequelizeGlobFolder = new Sequelize({ + name: db, + dialect: 'sqlite', + username: 'root', + password: '', + storage: ':memory:', + logging: !('SEQ_SILENT' in process.env), + modelPaths: [__dirname + '/../../models/globs/match-dir-only', __dirname + '/../../models/globs/match-sub-dir-files/**/*.model.ts'] + }); + + expect(sequelizeGlobFolder._).to.have.property('PlayerDir', PlayerDir); + expect(sequelizeGlobFolder._).to.have.property('TeamDir', TeamDir); + expect(sequelizeGlobFolder._).to.have.property('ShoeDir', ShoeDir); + expect(sequelizeGlobFolder._).to.have.property('PlayerGlob', PlayerGlob); + expect(sequelizeGlobFolder._).to.have.property('TeamGlob', TeamGlob); + expect(sequelizeGlobFolder._).to.have.property('ShoeGlob', ShoeGlob); + + }); + }); });