UNPKG

plugin-postgresql-connector

Version:

NocoBase plugin for connecting to external PostgreSQL databases

199 lines 6.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SavedQuery = void 0; const sequelize_1 = require("sequelize"); class SavedQuery extends sequelize_1.Model { static init(database) { super.init({ id: { type: sequelize_1.DataTypes.UUID, defaultValue: sequelize_1.DataTypes.UUIDV4, primaryKey: true, }, connectionId: { type: sequelize_1.DataTypes.UUID, allowNull: false, references: { model: 'postgresql_connections', key: 'id', }, validate: { notEmpty: true, }, }, name: { type: sequelize_1.DataTypes.STRING, allowNull: false, validate: { notEmpty: true, len: [1, 255], }, }, query: { type: sequelize_1.DataTypes.TEXT, allowNull: false, validate: { notEmpty: true, }, }, queryType: { type: sequelize_1.DataTypes.ENUM('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'PROCEDURE', 'FUNCTION', 'VIEW', 'OTHER'), allowNull: false, defaultValue: 'SELECT', }, parameters: { type: sequelize_1.DataTypes.JSON, defaultValue: [], validate: { isValidParameters(value) { if (!Array.isArray(value)) { throw new Error('Parameters must be an array'); } }, }, }, description: { type: sequelize_1.DataTypes.TEXT, allowNull: true, }, category: { type: sequelize_1.DataTypes.STRING, allowNull: true, defaultValue: 'general', }, tags: { type: sequelize_1.DataTypes.JSON, defaultValue: [], validate: { isValidTags(value) { if (!Array.isArray(value)) { throw new Error('Tags must be an array'); } }, }, }, isPublic: { type: sequelize_1.DataTypes.BOOLEAN, defaultValue: false, }, executionCount: { type: sequelize_1.DataTypes.INTEGER, defaultValue: 0, }, lastExecutedAt: { type: sequelize_1.DataTypes.DATE, allowNull: true, }, createdBy: { type: sequelize_1.DataTypes.UUID, allowNull: true, // For future user association }, createdAt: { type: sequelize_1.DataTypes.DATE, defaultValue: sequelize_1.DataTypes.NOW, }, updatedAt: { type: sequelize_1.DataTypes.DATE, defaultValue: sequelize_1.DataTypes.NOW, }, }, { sequelize: database.sequelize, modelName: 'SavedQuery', tableName: 'postgresql_saved_queries', timestamps: true, paranoid: true, // Soft delete indexes: [ { fields: ['connectionId'], }, { fields: ['queryType'], }, { fields: ['category'], }, { fields: ['isPublic'], }, { fields: ['createdBy'], }, { fields: ['name', 'connectionId'], unique: true, where: { deletedAt: null, }, }, ], }); } static associate(models) { this.belongsTo(models.Connection, { foreignKey: 'connectionId', as: 'connection', onDelete: 'CASCADE', }); // Future: User association // this.belongsTo(models.User, { // foreignKey: 'createdBy', // as: 'creator', // }); } // Instance methods async execute() { // This will be implemented in service layer return {}; } incrementExecutionCount() { this.setDataValue('executionCount', this.getDataValue('executionCount') + 1); this.setDataValue('lastExecutedAt', new Date()); } addTag(tag) { const tags = this.getDataValue('tags') || []; if (!tags.includes(tag)) { tags.push(tag); this.setDataValue('tags', tags); } } removeTag(tag) { const tags = this.getDataValue('tags') || []; const filteredTags = tags.filter((t) => t !== tag); this.setDataValue('tags', filteredTags); } getParameterNames() { const query = this.getDataValue('query'); const parameterRegex = /\$\{(\w+)\}/g; const parameters = []; let match; while ((match = parameterRegex.exec(query)) !== null) { if (!parameters.includes(match[1])) { parameters.push(match[1]); } } return parameters; } // Validate query syntax validateQuery() { const query = this.getDataValue('query').trim(); const errors = []; if (!query) { errors.push('Query cannot be empty'); } // Basic SQL validation const dangerousKeywords = ['DROP', 'TRUNCATE', 'ALTER', 'CREATE USER', 'GRANT', 'REVOKE']; const upperQuery = query.toUpperCase(); for (const keyword of dangerousKeywords) { if (upperQuery.includes(keyword)) { errors.push(`Potentially dangerous keyword detected: ${keyword}`); } } return { isValid: errors.length === 0, errors, }; } } exports.SavedQuery = SavedQuery; exports.default = SavedQuery; //# sourceMappingURL=SavedQuery.js.map