@drax/ai-back 3.43.0 → 3.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/TTSVoiceController.js +18 -0
- package/dist/factory/services/TTSVoiceServiceFactory.js +28 -0
- package/dist/index.js +14 -4
- package/dist/interfaces/ITTSVoice.js +1 -0
- package/dist/interfaces/ITTSVoiceRepository.js +1 -0
- package/dist/models/TTSVoiceModel.js +25 -0
- package/dist/permissions/TTSVoicePermissions.js +10 -0
- package/dist/repository/mongo/TTSVoiceMongoRepository.js +13 -0
- package/dist/repository/sqlite/TTSVoiceSqliteRepository.js +27 -0
- package/dist/routes/TTSVoiceRoutes.js +21 -0
- package/dist/schemas/TTSVoiceSchema.js +19 -0
- package/dist/services/TTSVoiceService.js +9 -0
- package/dist/tools/BuildContextTool.js +267 -0
- package/package.json +3 -3
- package/src/controllers/TTSVoiceController.ts +27 -0
- package/src/factory/services/TTSVoiceServiceFactory.ts +36 -0
- package/src/index.ts +30 -0
- package/src/interfaces/ITTSVoice.ts +20 -0
- package/src/interfaces/ITTSVoiceRepository.ts +8 -0
- package/src/models/TTSVoiceModel.ts +37 -0
- package/src/permissions/TTSVoicePermissions.ts +12 -0
- package/src/repository/mongo/TTSVoiceMongoRepository.ts +19 -0
- package/src/repository/sqlite/TTSVoiceSqliteRepository.ts +33 -0
- package/src/routes/TTSVoiceRoutes.ts +26 -0
- package/src/schemas/TTSVoiceSchema.ts +23 -0
- package/src/services/TTSVoiceService.ts +16 -0
- package/src/tools/BuildContextTool.ts +388 -0
- package/test/BuildContextTool.test.ts +183 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/TTSVoiceController.d.ts +8 -0
- package/types/controllers/TTSVoiceController.d.ts.map +1 -0
- package/types/factory/services/TTSVoiceServiceFactory.d.ts +8 -0
- package/types/factory/services/TTSVoiceServiceFactory.d.ts.map +1 -0
- package/types/index.d.ts +14 -2
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/ITTSVoice.d.ts +16 -0
- package/types/interfaces/ITTSVoice.d.ts.map +1 -0
- package/types/interfaces/ITTSVoiceRepository.d.ts +6 -0
- package/types/interfaces/ITTSVoiceRepository.d.ts.map +1 -0
- package/types/models/TTSVoiceModel.d.ts +15 -0
- package/types/models/TTSVoiceModel.d.ts.map +1 -0
- package/types/permissions/TTSVoicePermissions.d.ts +10 -0
- package/types/permissions/TTSVoicePermissions.d.ts.map +1 -0
- package/types/repository/mongo/TTSVoiceMongoRepository.d.ts +9 -0
- package/types/repository/mongo/TTSVoiceMongoRepository.d.ts.map +1 -0
- package/types/repository/sqlite/TTSVoiceSqliteRepository.d.ts +23 -0
- package/types/repository/sqlite/TTSVoiceSqliteRepository.d.ts.map +1 -0
- package/types/routes/TTSVoiceRoutes.d.ts +4 -0
- package/types/routes/TTSVoiceRoutes.d.ts.map +1 -0
- package/types/schemas/TTSVoiceSchema.d.ts +36 -0
- package/types/schemas/TTSVoiceSchema.d.ts.map +1 -0
- package/types/services/TTSVoiceService.d.ts +10 -0
- package/types/services/TTSVoiceService.d.ts.map +1 -0
- package/types/tools/BuildContextTool.d.ts +33 -0
- package/types/tools/BuildContextTool.d.ts.map +1 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import TTSVoiceServiceFactory from "../factory/services/TTSVoiceServiceFactory.js";
|
|
2
|
+
import { AbstractFastifyController } from "@drax/crud-back";
|
|
3
|
+
import TTSVoicePermissions from "../permissions/TTSVoicePermissions.js";
|
|
4
|
+
class TTSVoiceController extends AbstractFastifyController {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(TTSVoiceServiceFactory.instance, TTSVoicePermissions);
|
|
7
|
+
this.tenantField = "tenant";
|
|
8
|
+
this.userField = "user";
|
|
9
|
+
this.tenantFilter = true;
|
|
10
|
+
this.tenantSetter = true;
|
|
11
|
+
this.tenantAssert = true;
|
|
12
|
+
this.userFilter = false;
|
|
13
|
+
this.userSetter = false;
|
|
14
|
+
this.userAssert = false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export default TTSVoiceController;
|
|
18
|
+
export { TTSVoiceController };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import TTSVoiceMongoRepository from '../../repository/mongo/TTSVoiceMongoRepository.js';
|
|
2
|
+
import TTSVoiceSqliteRepository from '../../repository/sqlite/TTSVoiceSqliteRepository.js';
|
|
3
|
+
import { TTSVoiceService } from '../../services/TTSVoiceService.js';
|
|
4
|
+
import { TTSVoiceBaseSchema, TTSVoiceSchema } from "../../schemas/TTSVoiceSchema.js";
|
|
5
|
+
import { COMMON, CommonConfig, DraxConfig } from "@drax/common-back";
|
|
6
|
+
class TTSVoiceServiceFactory {
|
|
7
|
+
static get instance() {
|
|
8
|
+
if (!TTSVoiceServiceFactory.service) {
|
|
9
|
+
let repository;
|
|
10
|
+
switch (DraxConfig.getOrLoad(CommonConfig.DbEngine)) {
|
|
11
|
+
case COMMON.DB_ENGINES.MONGODB:
|
|
12
|
+
repository = new TTSVoiceMongoRepository();
|
|
13
|
+
break;
|
|
14
|
+
case COMMON.DB_ENGINES.SQLITE:
|
|
15
|
+
const dbFile = DraxConfig.getOrLoad(CommonConfig.SqliteDbFile);
|
|
16
|
+
repository = new TTSVoiceSqliteRepository(dbFile, false);
|
|
17
|
+
repository.build();
|
|
18
|
+
break;
|
|
19
|
+
default:
|
|
20
|
+
throw new Error("DraxConfig.DB_ENGINE must be one of " + Object.values(COMMON.DB_ENGINES).join(", "));
|
|
21
|
+
}
|
|
22
|
+
TTSVoiceServiceFactory.service = new TTSVoiceService(repository, TTSVoiceBaseSchema, TTSVoiceSchema);
|
|
23
|
+
}
|
|
24
|
+
return TTSVoiceServiceFactory.service;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export default TTSVoiceServiceFactory;
|
|
28
|
+
export { TTSVoiceServiceFactory };
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,14 @@ import { OllamaAiConfig } from "./config/OllamaAiConfig.js";
|
|
|
4
4
|
import { DeepSeekConfig } from "./config/DeepSeekConfig.js";
|
|
5
5
|
import { ElevenLabsTTSConfig } from "./config/ElevenLabsTTSConfig.js";
|
|
6
6
|
import { AILogSchema, AILogBaseSchema } from "./schemas/AILogSchema.js";
|
|
7
|
+
import { TTSVoiceSchema, TTSVoiceBaseSchema, TTSVoiceProviderSchema } from "./schemas/TTSVoiceSchema.js";
|
|
7
8
|
import { TTSRequestSchema, TTSVoiceSettingsSchema } from "./schemas/TTSRequestSchema.js";
|
|
8
9
|
import AILogModel from "./models/AILogModel.js";
|
|
10
|
+
import TTSVoiceModel from "./models/TTSVoiceModel.js";
|
|
9
11
|
import AILogMongoRepository from "./repository/mongo/AILogMongoRepository.js";
|
|
10
12
|
import AILogSqliteRepository from "./repository/sqlite/AILogSqliteRepository.js";
|
|
13
|
+
import TTSVoiceMongoRepository from "./repository/mongo/TTSVoiceMongoRepository.js";
|
|
14
|
+
import TTSVoiceSqliteRepository from "./repository/sqlite/TTSVoiceSqliteRepository.js";
|
|
11
15
|
import { OpenAiProviderFactory } from "./factory/ai/OpenAiProviderFactory.js";
|
|
12
16
|
import { GoogleAiProviderFactory } from "./factory/ai/GoogleAiProviderFactory.js";
|
|
13
17
|
import { OllamaAiProviderFactory } from "./factory/ai/OllamaAiProviderFactory.js";
|
|
@@ -17,6 +21,7 @@ import { ElevenLabsTTSProviderFactory } from "./factory/tts/ElevenLabsTTSProvide
|
|
|
17
21
|
import { TTSProviderFactory } from "./factory/tts/TTSProviderFactory.js";
|
|
18
22
|
import { DraxAgentFactory } from "./factory/DraxAgentFactory.js";
|
|
19
23
|
import AILogServiceFactory from "./factory/services/AILogServiceFactory.js";
|
|
24
|
+
import TTSVoiceServiceFactory from "./factory/services/TTSVoiceServiceFactory.js";
|
|
20
25
|
import { OpenAiProvider } from "./providers/ai/OpenAiProvider.js";
|
|
21
26
|
import { GoogleAiProvider } from "./providers/ai/GoogleAiProvider.js";
|
|
22
27
|
import { OllamaAiProvider } from "./providers/ai/OllamaAiProvider.js";
|
|
@@ -25,6 +30,7 @@ import { ElevenLabsTTSProvider } from "./providers/tts/ElevenLabsTTSProvider.js"
|
|
|
25
30
|
import { BuilderTool } from "./tools/BuilderTool.js";
|
|
26
31
|
import { KnowledgeService } from "./services/KnowledgeService.js";
|
|
27
32
|
import { AILogService } from "./services/AILogService.js";
|
|
33
|
+
import { TTSVoiceService } from "./services/TTSVoiceService.js";
|
|
28
34
|
import { TTSGenericService } from "./services/TTSGenericService.js";
|
|
29
35
|
import { PromptAudioService } from "./services/PromptAudioService.js";
|
|
30
36
|
import AILogPermissions from "./permissions/AILogPermissions.js";
|
|
@@ -32,22 +38,26 @@ import AgentPermissions from "./permissions/AgentPermissions.js";
|
|
|
32
38
|
import AgentSessionPermissions from "./permissions/AgentSessionPermissions.js";
|
|
33
39
|
import AIPermissions from "./permissions/AIPermissions.js";
|
|
34
40
|
import TTSPermissions from "./permissions/TTSPermissions.js";
|
|
41
|
+
import TTSVoicePermissions from "./permissions/TTSVoicePermissions.js";
|
|
35
42
|
import AILogController from "./controllers/AILogController.js";
|
|
36
43
|
import AICrudController from "./controllers/AICrudController.js";
|
|
37
44
|
import AIGenericController from "./controllers/AIGenericController.js";
|
|
38
45
|
import TTSGenericController from "./controllers/TTSGenericController.js";
|
|
46
|
+
import TTSVoiceController from "./controllers/TTSVoiceController.js";
|
|
39
47
|
import DraxAgentController from "./controllers/DraxAgentController.js";
|
|
40
48
|
import AgentSessionController from "./controllers/AgentSessionController.js";
|
|
41
49
|
import AILogRoutes from "./routes/AILogRoutes.js";
|
|
42
50
|
import AIRoutes from "./routes/AIRoutes.js";
|
|
43
51
|
import TTSRoutes from "./routes/TTSRoutes.js";
|
|
52
|
+
import TTSVoiceRoutes from "./routes/TTSVoiceRoutes.js";
|
|
44
53
|
import DraxAgentRoutes from "./routes/DraxAgentRoutes.js";
|
|
45
54
|
import AgentSessionRoutes from "./routes/AgentSessionRoutes.js";
|
|
46
55
|
import { DraxAgent } from "./agents/DraxAgent.js";
|
|
47
|
-
|
|
56
|
+
import { BuildContextTool } from "./tools/BuildContextTool.js";
|
|
57
|
+
export { OpenAiConfig, GoogleAiConfig, OllamaAiConfig, DeepSeekConfig, ElevenLabsTTSConfig, AILogSchema, AILogBaseSchema, TTSVoiceSchema, TTSVoiceBaseSchema, TTSVoiceProviderSchema, TTSRequestSchema, TTSVoiceSettingsSchema, AILogModel, TTSVoiceModel, AILogMongoRepository, AILogSqliteRepository, TTSVoiceMongoRepository, TTSVoiceSqliteRepository, OpenAiProviderFactory, GoogleAiProviderFactory, OllamaAiProviderFactory, DeepSeekAiProviderFactory, AiProviderFactory, ElevenLabsTTSProviderFactory, TTSProviderFactory, DraxAgentFactory, AILogServiceFactory, TTSVoiceServiceFactory, OpenAiProvider, GoogleAiProvider, OllamaAiProvider, DeepSeekAiProvider, ElevenLabsTTSProvider, BuilderTool, BuildContextTool,
|
|
48
58
|
//Service
|
|
49
|
-
KnowledgeService, AILogService, TTSGenericService, PromptAudioService,
|
|
59
|
+
KnowledgeService, AILogService, TTSVoiceService, TTSGenericService, PromptAudioService,
|
|
50
60
|
//Permissions
|
|
51
|
-
AILogPermissions, AgentPermissions, AIPermissions, TTSPermissions, AgentSessionPermissions,
|
|
61
|
+
AILogPermissions, AgentPermissions, AIPermissions, TTSPermissions, TTSVoicePermissions, AgentSessionPermissions,
|
|
52
62
|
//Controllers
|
|
53
|
-
AILogController, AICrudController, AIGenericController, TTSGenericController, DraxAgentController, AgentSessionController, DraxAgent, AILogRoutes, AIRoutes, TTSRoutes, DraxAgentRoutes, AgentSessionRoutes };
|
|
63
|
+
AILogController, AICrudController, AIGenericController, TTSGenericController, TTSVoiceController, DraxAgentController, AgentSessionController, DraxAgent, AILogRoutes, AIRoutes, TTSRoutes, TTSVoiceRoutes, DraxAgentRoutes, AgentSessionRoutes };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { mongoose } from '@drax/common-back';
|
|
2
|
+
import uniqueValidator from 'mongoose-unique-validator';
|
|
3
|
+
import mongoosePaginate from 'mongoose-paginate-v2';
|
|
4
|
+
const TTSVoiceSchema = new mongoose.Schema({
|
|
5
|
+
name: { type: String, required: true, index: true, unique: false },
|
|
6
|
+
ttsProvider: { type: String, enum: ['ElevenLabs'], required: true, index: true, unique: false },
|
|
7
|
+
voiceId: { type: String, required: true, index: true, unique: false },
|
|
8
|
+
model: { type: String, required: false, index: true, unique: false },
|
|
9
|
+
languageCode: { type: String, required: false, index: true, unique: false },
|
|
10
|
+
tenant: { type: mongoose.Schema.Types.ObjectId, ref: 'Tenant', required: false, index: true, unique: false },
|
|
11
|
+
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: false, index: true, unique: false }
|
|
12
|
+
}, { timestamps: true });
|
|
13
|
+
TTSVoiceSchema.index({ ttsProvider: 1, voiceId: 1, tenant: 1 }, { unique: true, sparse: true });
|
|
14
|
+
TTSVoiceSchema.plugin(uniqueValidator, { message: 'validation.unique' });
|
|
15
|
+
TTSVoiceSchema.plugin(mongoosePaginate);
|
|
16
|
+
TTSVoiceSchema.virtual("id").get(function () {
|
|
17
|
+
return this._id.toString();
|
|
18
|
+
});
|
|
19
|
+
TTSVoiceSchema.set('toJSON', { getters: true, virtuals: true });
|
|
20
|
+
TTSVoiceSchema.set('toObject', { getters: true, virtuals: true });
|
|
21
|
+
const MODEL_NAME = 'TTSVoice';
|
|
22
|
+
const COLLECTION_NAME = 'TTSVoice';
|
|
23
|
+
const TTSVoiceModel = mongoose.model(MODEL_NAME, TTSVoiceSchema, COLLECTION_NAME);
|
|
24
|
+
export { TTSVoiceSchema, TTSVoiceModel };
|
|
25
|
+
export default TTSVoiceModel;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var TTSVoicePermissions;
|
|
2
|
+
(function (TTSVoicePermissions) {
|
|
3
|
+
TTSVoicePermissions["Create"] = "ttsvoice:create";
|
|
4
|
+
TTSVoicePermissions["Update"] = "ttsvoice:update";
|
|
5
|
+
TTSVoicePermissions["Delete"] = "ttsvoice:delete";
|
|
6
|
+
TTSVoicePermissions["View"] = "ttsvoice:view";
|
|
7
|
+
TTSVoicePermissions["Manage"] = "ttsvoice:manage";
|
|
8
|
+
})(TTSVoicePermissions || (TTSVoicePermissions = {}));
|
|
9
|
+
export { TTSVoicePermissions };
|
|
10
|
+
export default TTSVoicePermissions;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AbstractMongoRepository } from "@drax/crud-back";
|
|
2
|
+
import { TTSVoiceModel } from "../../models/TTSVoiceModel.js";
|
|
3
|
+
class TTSVoiceMongoRepository extends AbstractMongoRepository {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
this._model = TTSVoiceModel;
|
|
7
|
+
this._searchFields = ['name', 'ttsProvider', 'voiceId', 'model', 'languageCode'];
|
|
8
|
+
this._populateFields = ['tenant', 'user'];
|
|
9
|
+
this._lean = true;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export default TTSVoiceMongoRepository;
|
|
13
|
+
export { TTSVoiceMongoRepository };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AbstractSqliteRepository } from "@drax/crud-back";
|
|
2
|
+
class TTSVoiceSqliteRepository extends AbstractSqliteRepository {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
this.tableName = 'TTSVoice';
|
|
6
|
+
this.searchFields = ['name', 'ttsProvider', 'voiceId', 'model', 'languageCode'];
|
|
7
|
+
this.booleanFields = [];
|
|
8
|
+
this.jsonFields = [];
|
|
9
|
+
this.identifier = '_id';
|
|
10
|
+
this.populateFields = [
|
|
11
|
+
{ field: 'tenant', table: 'tenant', identifier: '_id' },
|
|
12
|
+
{ field: 'user', table: 'user', identifier: '_id' }
|
|
13
|
+
];
|
|
14
|
+
this.verbose = false;
|
|
15
|
+
this.tableFields = [
|
|
16
|
+
{ name: "name", type: "TEXT", unique: false, primary: false },
|
|
17
|
+
{ name: "ttsProvider", type: "TEXT", unique: false, primary: false },
|
|
18
|
+
{ name: "voiceId", type: "TEXT", unique: false, primary: false },
|
|
19
|
+
{ name: "model", type: "TEXT", unique: false, primary: false },
|
|
20
|
+
{ name: "languageCode", type: "TEXT", unique: false, primary: false },
|
|
21
|
+
{ name: "tenant", type: "TEXT", unique: false, primary: false },
|
|
22
|
+
{ name: "user", type: "TEXT", unique: false, primary: false }
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export default TTSVoiceSqliteRepository;
|
|
27
|
+
export { TTSVoiceSqliteRepository };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import TTSVoiceController from "../controllers/TTSVoiceController.js";
|
|
2
|
+
import { CrudSchemaBuilder } from "@drax/crud-back";
|
|
3
|
+
import { TTSVoiceSchema, TTSVoiceBaseSchema } from '../schemas/TTSVoiceSchema.js';
|
|
4
|
+
async function TTSVoiceRoutes(fastify, options) {
|
|
5
|
+
const controller = new TTSVoiceController();
|
|
6
|
+
const schemas = new CrudSchemaBuilder(TTSVoiceSchema, TTSVoiceBaseSchema, TTSVoiceBaseSchema, 'TTSVoice', 'openapi-3.0', ['ai']);
|
|
7
|
+
fastify.get('/api/ttsvoice', { schema: schemas.paginateSchema }, (req, rep) => controller.paginate(req, rep));
|
|
8
|
+
fastify.get('/api/ttsvoice/find', { schema: schemas.findSchema }, (req, rep) => controller.find(req, rep));
|
|
9
|
+
fastify.get('/api/ttsvoice/search', { schema: schemas.searchSchema }, (req, rep) => controller.search(req, rep));
|
|
10
|
+
fastify.get('/api/ttsvoice/:id', { schema: schemas.findByIdSchema }, (req, rep) => controller.findById(req, rep));
|
|
11
|
+
fastify.get('/api/ttsvoice/find-one', { schema: schemas.findOneSchema }, (req, rep) => controller.findOne(req, rep));
|
|
12
|
+
fastify.get('/api/ttsvoice/group-by', { schema: schemas.groupBySchema }, (req, rep) => controller.groupBy(req, rep));
|
|
13
|
+
fastify.post('/api/ttsvoice', { schema: schemas.createSchema }, (req, rep) => controller.create(req, rep));
|
|
14
|
+
fastify.put('/api/ttsvoice/:id', { schema: schemas.updateSchema }, (req, rep) => controller.update(req, rep));
|
|
15
|
+
fastify.patch('/api/ttsvoice/:id', { schema: schemas.updateSchema }, (req, rep) => controller.updatePartial(req, rep));
|
|
16
|
+
fastify.delete('/api/ttsvoice/:id', { schema: schemas.deleteSchema }, (req, rep) => controller.delete(req, rep));
|
|
17
|
+
fastify.get('/api/ttsvoice/export', (req, rep) => controller.export(req, rep));
|
|
18
|
+
fastify.post('/api/ttsvoice/import', (req, rep) => controller.import(req, rep));
|
|
19
|
+
}
|
|
20
|
+
export default TTSVoiceRoutes;
|
|
21
|
+
export { TTSVoiceRoutes };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const TTSVoiceProviderSchema = z.enum(['ElevenLabs']);
|
|
3
|
+
const TTSVoiceBaseSchema = z.object({
|
|
4
|
+
name: z.string().min(1, 'validation.required'),
|
|
5
|
+
ttsProvider: TTSVoiceProviderSchema,
|
|
6
|
+
voiceId: z.string().min(1, 'validation.required'),
|
|
7
|
+
model: z.string().optional().nullable(),
|
|
8
|
+
languageCode: z.string().optional().nullable(),
|
|
9
|
+
tenant: z.coerce.string().optional().nullable(),
|
|
10
|
+
user: z.coerce.string().optional().nullable()
|
|
11
|
+
});
|
|
12
|
+
const TTSVoiceSchema = TTSVoiceBaseSchema
|
|
13
|
+
.extend({
|
|
14
|
+
_id: z.coerce.string(),
|
|
15
|
+
tenant: z.object({ _id: z.coerce.string(), name: z.string().optional() }).nullable().optional(),
|
|
16
|
+
user: z.object({ _id: z.coerce.string(), username: z.string().optional() }).nullable().optional()
|
|
17
|
+
});
|
|
18
|
+
export default TTSVoiceSchema;
|
|
19
|
+
export { TTSVoiceSchema, TTSVoiceBaseSchema, TTSVoiceProviderSchema };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AbstractService } from "@drax/crud-back";
|
|
2
|
+
class TTSVoiceService extends AbstractService {
|
|
3
|
+
constructor(TTSVoiceRepository, baseSchema, fullSchema) {
|
|
4
|
+
super(TTSVoiceRepository, baseSchema, fullSchema);
|
|
5
|
+
this._validateOutput = true;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export default TTSVoiceService;
|
|
9
|
+
export { TTSVoiceService };
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { setNestedValue, UnauthorizedError } from "@drax/common-back";
|
|
2
|
+
import { BuilderTool } from "./BuilderTool.js";
|
|
3
|
+
class BuildContextTool extends BuilderTool {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
super({
|
|
6
|
+
...options,
|
|
7
|
+
service: BuildContextTool.createContextService(options),
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
static fromPromptContext(options, promptContext) {
|
|
11
|
+
return new BuildContextTool({
|
|
12
|
+
...options,
|
|
13
|
+
context: {
|
|
14
|
+
userId: promptContext.input?.userId ?? promptContext.session.userId ?? null,
|
|
15
|
+
tenantId: promptContext.input?.tenantId ?? promptContext.session.tenantId ?? null,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
static createContextService(options) {
|
|
20
|
+
const service = options.service;
|
|
21
|
+
const helper = new BuildContextToolServiceHelper(options);
|
|
22
|
+
const contextService = { ...service };
|
|
23
|
+
if (typeof service.create === "function") {
|
|
24
|
+
contextService.create = async (data) => service.create?.(helper.applySetters(helper.clonePayload(data)));
|
|
25
|
+
}
|
|
26
|
+
if (typeof service.update === "function") {
|
|
27
|
+
contextService.update = async (id, data) => {
|
|
28
|
+
const preItem = await service.findById?.(id);
|
|
29
|
+
helper.assertWritable(preItem, "update");
|
|
30
|
+
const payload = helper.removeSetterFields(helper.clonePayload(data));
|
|
31
|
+
return service.update?.(id, payload);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (typeof service.updatePartial === "function") {
|
|
35
|
+
contextService.updatePartial = async (id, data) => {
|
|
36
|
+
const preItem = await service.findById?.(id);
|
|
37
|
+
helper.assertWritable(preItem, "update");
|
|
38
|
+
const payload = helper.removeSetterFields(helper.clonePayload(data));
|
|
39
|
+
return service.updatePartial?.(id, payload);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (typeof service.delete === "function") {
|
|
43
|
+
contextService.delete = async (id) => {
|
|
44
|
+
const item = await service.findById?.(id);
|
|
45
|
+
helper.assertWritable(item, "delete");
|
|
46
|
+
return service.delete?.(id);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (typeof service.findById === "function") {
|
|
50
|
+
contextService.findById = async (id) => {
|
|
51
|
+
const item = await service.findById?.(id);
|
|
52
|
+
helper.assertReadable(item);
|
|
53
|
+
return item;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (typeof service.findByIds === "function") {
|
|
57
|
+
contextService.findByIds = async (ids) => {
|
|
58
|
+
const items = await service.findByIds?.(ids);
|
|
59
|
+
helper.assertReadableItems(items);
|
|
60
|
+
return items;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (typeof service.findOneBy === "function") {
|
|
64
|
+
contextService.findOneBy = async (field, value, filters = []) => service.findOneBy?.(field, value, helper.applyReadFilters(filters));
|
|
65
|
+
}
|
|
66
|
+
if (typeof service.findOne === "function") {
|
|
67
|
+
contextService.findOne = async (findOptions) => service.findOne?.({
|
|
68
|
+
...findOptions,
|
|
69
|
+
filters: helper.applyReadFilters(findOptions?.filters ?? []),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (typeof service.findBy === "function") {
|
|
73
|
+
contextService.findBy = async (field, value, limit = helper.defaultLimit, filters = []) => service.findBy?.(field, value, limit, helper.applyReadFilters(filters));
|
|
74
|
+
}
|
|
75
|
+
if (typeof service.fetchAll === "function") {
|
|
76
|
+
contextService.fetchAll = async () => {
|
|
77
|
+
const filters = helper.applyReadFilters([]);
|
|
78
|
+
if (filters.length > 0 && typeof service.find === "function") {
|
|
79
|
+
return service.find({
|
|
80
|
+
search: "",
|
|
81
|
+
filters,
|
|
82
|
+
order: false,
|
|
83
|
+
orderBy: "",
|
|
84
|
+
limit: helper.defaultLimit,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return service.fetchAll?.();
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (typeof service.findFirst === "function") {
|
|
91
|
+
contextService.findFirst = async (quantity, filters = []) => service.findFirst?.(quantity, helper.applyReadFilters(filters));
|
|
92
|
+
}
|
|
93
|
+
if (typeof service.findLast === "function") {
|
|
94
|
+
contextService.findLast = async (quantity, filters = []) => service.findLast?.(quantity, helper.applyReadFilters(filters));
|
|
95
|
+
}
|
|
96
|
+
if (typeof service.search === "function") {
|
|
97
|
+
contextService.search = async (value, limit = helper.defaultLimit, filters = []) => service.search?.(value, limit, helper.applyReadFilters(filters));
|
|
98
|
+
}
|
|
99
|
+
if (typeof service.find === "function") {
|
|
100
|
+
contextService.find = async (findOptions) => service.find?.({
|
|
101
|
+
...findOptions,
|
|
102
|
+
filters: helper.applyReadFilters(findOptions?.filters ?? []),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (typeof service.paginate === "function") {
|
|
106
|
+
contextService.paginate = async (paginateOptions) => service.paginate?.({
|
|
107
|
+
...paginateOptions,
|
|
108
|
+
filters: helper.applyReadFilters(paginateOptions?.filters ?? []),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (typeof service.groupBy === "function") {
|
|
112
|
+
contextService.groupBy = async (groupByOptions) => service.groupBy?.({
|
|
113
|
+
...groupByOptions,
|
|
114
|
+
filters: helper.applyReadFilters(groupByOptions?.filters ?? []),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return contextService;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
class BuildContextToolServiceHelper {
|
|
121
|
+
constructor(options) {
|
|
122
|
+
this.context = options.context ?? {};
|
|
123
|
+
this.permission = options.permission;
|
|
124
|
+
this.tenantField = options.tenantField ?? "tenant";
|
|
125
|
+
this.userField = options.userField ?? "user";
|
|
126
|
+
this.tenantFilter = options.tenantFilter ?? false;
|
|
127
|
+
this.tenantSetter = options.tenantSetter ?? false;
|
|
128
|
+
this.tenantAssert = options.tenantAssert ?? false;
|
|
129
|
+
this.userFilter = options.userFilter ?? false;
|
|
130
|
+
this.userSetter = options.userSetter ?? false;
|
|
131
|
+
this.userAssert = options.userAssert ?? false;
|
|
132
|
+
this.defaultLimit = options.defaultLimit ?? 1000;
|
|
133
|
+
}
|
|
134
|
+
clonePayload(payload) {
|
|
135
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
136
|
+
return payload;
|
|
137
|
+
}
|
|
138
|
+
return { ...payload };
|
|
139
|
+
}
|
|
140
|
+
applySetters(payload) {
|
|
141
|
+
if (!payload || typeof payload !== "object") {
|
|
142
|
+
return payload;
|
|
143
|
+
}
|
|
144
|
+
if (this.tenantSetter && this.context.tenantId) {
|
|
145
|
+
setNestedValue(payload, this.tenantField, this.context.tenantId);
|
|
146
|
+
}
|
|
147
|
+
if (this.userSetter && this.context.userId) {
|
|
148
|
+
setNestedValue(payload, this.userField, this.context.userId);
|
|
149
|
+
}
|
|
150
|
+
return payload;
|
|
151
|
+
}
|
|
152
|
+
removeSetterFields(payload) {
|
|
153
|
+
if (!payload || typeof payload !== "object") {
|
|
154
|
+
return payload;
|
|
155
|
+
}
|
|
156
|
+
if (this.tenantSetter) {
|
|
157
|
+
this.deleteNestedValue(payload, this.tenantField);
|
|
158
|
+
}
|
|
159
|
+
if (this.userSetter) {
|
|
160
|
+
this.deleteNestedValue(payload, this.userField);
|
|
161
|
+
}
|
|
162
|
+
return payload;
|
|
163
|
+
}
|
|
164
|
+
applyReadFilters(filters = []) {
|
|
165
|
+
const nextFilters = [...filters];
|
|
166
|
+
if (this.tenantFilter && this.context.tenantId) {
|
|
167
|
+
nextFilters.push({ field: this.tenantField, operator: "eq", value: this.context.tenantId });
|
|
168
|
+
}
|
|
169
|
+
if (this.userFilter &&
|
|
170
|
+
this.context.userId &&
|
|
171
|
+
!this.hasSomePermission([this.permission?.All, this.permission?.ViewAll])) {
|
|
172
|
+
nextFilters.push({ field: this.userField, operator: "eq", value: this.context.userId });
|
|
173
|
+
}
|
|
174
|
+
return nextFilters;
|
|
175
|
+
}
|
|
176
|
+
assertReadable(item) {
|
|
177
|
+
if (this.hasSomePermission([this.permission?.All, this.permission?.ViewAll])) {
|
|
178
|
+
this.assertTenant(item);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this.assertTenant(item);
|
|
182
|
+
this.assertUser(item);
|
|
183
|
+
}
|
|
184
|
+
assertReadableItems(items) {
|
|
185
|
+
if (!Array.isArray(items)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
items.forEach(item => this.assertReadable(item));
|
|
189
|
+
}
|
|
190
|
+
assertWritable(item, operation) {
|
|
191
|
+
const allPermission = this.permission?.All;
|
|
192
|
+
const operationAllPermission = operation === "update"
|
|
193
|
+
? this.permission?.UpdateAll
|
|
194
|
+
: this.permission?.DeleteAll;
|
|
195
|
+
if (!this.hasSomePermission([allPermission, operationAllPermission])) {
|
|
196
|
+
this.assertUser(item);
|
|
197
|
+
}
|
|
198
|
+
this.assertTenant(item);
|
|
199
|
+
}
|
|
200
|
+
assertTenant(item) {
|
|
201
|
+
if (!this.tenantAssert || !this.context.tenantId) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const tenantId = this.resolveItemFieldId(item, this.tenantField);
|
|
205
|
+
if (tenantId) {
|
|
206
|
+
this.assertId(this.context.tenantId, tenantId);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
assertUser(item) {
|
|
210
|
+
if (!this.userAssert || !this.context.userId) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const userId = this.resolveItemFieldId(item, this.userField);
|
|
214
|
+
if (userId) {
|
|
215
|
+
this.assertId(this.context.userId, userId);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
assertId(expectedId, actualId) {
|
|
219
|
+
if (expectedId !== actualId) {
|
|
220
|
+
throw new UnauthorizedError();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
hasSomePermission(permissions) {
|
|
224
|
+
const requiredPermissions = permissions.filter((permission) => !!permission);
|
|
225
|
+
if (requiredPermissions.length === 0) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
if (this.context.hasSomePermission?.(requiredPermissions)) {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
return requiredPermissions.some(permission => this.context.permissions?.includes(permission));
|
|
232
|
+
}
|
|
233
|
+
resolveItemFieldId(item, field) {
|
|
234
|
+
const value = this.getNestedValue(item, field);
|
|
235
|
+
return this.stringifyRelationId(value);
|
|
236
|
+
}
|
|
237
|
+
getNestedValue(item, path) {
|
|
238
|
+
return path.split(".").reduce((value, key) => value?.[key], item);
|
|
239
|
+
}
|
|
240
|
+
stringifyRelationId(value) {
|
|
241
|
+
if (value === null || value === undefined || value === "") {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
const id = value?._id ?? value?.id ?? value;
|
|
245
|
+
if (typeof id === "string" || typeof id === "number" || typeof id === "boolean") {
|
|
246
|
+
return String(id);
|
|
247
|
+
}
|
|
248
|
+
if (typeof id?.toString === "function") {
|
|
249
|
+
const stringId = id.toString();
|
|
250
|
+
return stringId && stringId !== "[object Object]" ? stringId : null;
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
deleteNestedValue(payload, path) {
|
|
255
|
+
const keys = path.split(".");
|
|
256
|
+
const lastKey = keys.pop();
|
|
257
|
+
if (!lastKey) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const parent = keys.reduce((value, key) => value?.[key], payload);
|
|
261
|
+
if (parent && typeof parent === "object") {
|
|
262
|
+
delete parent[lastKey];
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
export default BuildContextTool;
|
|
267
|
+
export { BuildContextTool };
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "3.
|
|
6
|
+
"version": "3.45.0",
|
|
7
7
|
"description": "Ai utils",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "types/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"author": "Cristian Incarnato & Drax Team",
|
|
19
19
|
"license": "ISC",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@drax/ai-share": "^3.
|
|
21
|
+
"@drax/ai-share": "^3.45.0",
|
|
22
22
|
"@drax/crud-back": "^3.39.0",
|
|
23
23
|
"mongoose": "^8.23.0",
|
|
24
24
|
"mongoose-paginate-v2": "^1.8.3"
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"typescript": "^5.9.3",
|
|
47
47
|
"vitest": "^3.0.8"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "825b67f313cc64dd26bf455b2503fbeb606df308"
|
|
50
50
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import TTSVoiceServiceFactory from "../factory/services/TTSVoiceServiceFactory.js";
|
|
2
|
+
import {AbstractFastifyController} from "@drax/crud-back";
|
|
3
|
+
import TTSVoicePermissions from "../permissions/TTSVoicePermissions.js";
|
|
4
|
+
import type {ITTSVoice, ITTSVoiceBase} from "../interfaces/ITTSVoice";
|
|
5
|
+
|
|
6
|
+
class TTSVoiceController extends AbstractFastifyController<ITTSVoice, ITTSVoiceBase, ITTSVoiceBase> {
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
super(TTSVoiceServiceFactory.instance, TTSVoicePermissions)
|
|
10
|
+
this.tenantField = "tenant";
|
|
11
|
+
this.userField = "user";
|
|
12
|
+
|
|
13
|
+
this.tenantFilter = true;
|
|
14
|
+
this.tenantSetter = true;
|
|
15
|
+
this.tenantAssert = true;
|
|
16
|
+
|
|
17
|
+
this.userFilter = false;
|
|
18
|
+
this.userSetter = false;
|
|
19
|
+
this.userAssert = false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default TTSVoiceController;
|
|
25
|
+
export {
|
|
26
|
+
TTSVoiceController
|
|
27
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import TTSVoiceMongoRepository from '../../repository/mongo/TTSVoiceMongoRepository.js'
|
|
2
|
+
import TTSVoiceSqliteRepository from '../../repository/sqlite/TTSVoiceSqliteRepository.js'
|
|
3
|
+
import type {ITTSVoiceRepository} from "../../interfaces/ITTSVoiceRepository";
|
|
4
|
+
import {TTSVoiceService} from '../../services/TTSVoiceService.js'
|
|
5
|
+
import {TTSVoiceBaseSchema, TTSVoiceSchema} from "../../schemas/TTSVoiceSchema.js";
|
|
6
|
+
import {COMMON, CommonConfig, DraxConfig} from "@drax/common-back";
|
|
7
|
+
|
|
8
|
+
class TTSVoiceServiceFactory {
|
|
9
|
+
private static service: TTSVoiceService;
|
|
10
|
+
|
|
11
|
+
public static get instance(): TTSVoiceService {
|
|
12
|
+
if (!TTSVoiceServiceFactory.service) {
|
|
13
|
+
let repository: ITTSVoiceRepository
|
|
14
|
+
switch (DraxConfig.getOrLoad(CommonConfig.DbEngine)) {
|
|
15
|
+
case COMMON.DB_ENGINES.MONGODB:
|
|
16
|
+
repository = new TTSVoiceMongoRepository()
|
|
17
|
+
break;
|
|
18
|
+
case COMMON.DB_ENGINES.SQLITE:
|
|
19
|
+
const dbFile = DraxConfig.getOrLoad(CommonConfig.SqliteDbFile)
|
|
20
|
+
repository = new TTSVoiceSqliteRepository(dbFile, false)
|
|
21
|
+
repository.build()
|
|
22
|
+
break;
|
|
23
|
+
default:
|
|
24
|
+
throw new Error("DraxConfig.DB_ENGINE must be one of " + Object.values(COMMON.DB_ENGINES).join(", "));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
TTSVoiceServiceFactory.service = new TTSVoiceService(repository, TTSVoiceBaseSchema, TTSVoiceSchema);
|
|
28
|
+
}
|
|
29
|
+
return TTSVoiceServiceFactory.service;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default TTSVoiceServiceFactory
|
|
34
|
+
export {
|
|
35
|
+
TTSVoiceServiceFactory
|
|
36
|
+
}
|