基于TypeScript自定义Strapi users-permissions插件接口

Strapi的官方文档提供了扩展插件的方式,例如在src/extensions/users-permissions/strapi-server.ts中自定义,但文档提供的例子直接重写了原有插件的函数,而无法通过类似自定义API调用super.find()等方式调用原有插件的函数。

// 自定义API的方式const uid: Common.UID.ContentType = 'api::api-name···';
export default factories.createCoreController(uid, ({ strapi: Strapi }) => ({async find(ctx: Context) {// TODO ...return await super.find(ctx);},
}));

此时需要将原插件的函数复制出来,并在重写的函数里调用,以自定义/users/me接口为例。

users-permissions的/users/me接口提供了对获得当前用户信息的方法,若需要自定义获得哪些信息,可通过修改原有me函数实现,users-permissions对me函数的定义位于@strapi/plugin-users-permissions/server/controllers/user.js中,尝试通过导入这个函数,并在自定义的me函数中调用这个函数。

失败的方案

进一步观察代码,该me函数位于user.js的导出对象中,user.js的导出对象是controllers导出对象的成员,位于@strapi/plugin-users-permissions/server/controllers/index.js中,controllers又是server导出函数的返回值成员,位于@strapi/plugin-users-permissions/server/index.js中,故要访问user.js中的方法,可通过以下方式。

const { controllers } = server();
controllers.user.me(ctx);

导入原有me函数时,要注意users-permissions插件的导出对象名,查看/@strapi/plugin-users-permissions/package.json发现,其exports对象导出名为strapi-server,故实际引用users-permissions的server对象,需要使用

import server from '@strapi/plugin-users-permissions/strapi-server';

此时,如果在重写的me函数中直接调用controllers.user.me(ctx);则会陷入死递归,因为Strapi初始化时已经将原有的me函数覆盖为自定义的me函数,实际上调用controllers.user.me(ctx);即调用的当前函数,故该方法无法实现。

可行的方案

既然如此,就把整个原有的me函数照搬过来,相当于复制了一份me函数,进入@strapi/plugin-users-permissions/server/controllers/user.js中,发现me函数的定义如下:

/*** Retrieve authenticated user.* @return {Object|Array}*/async me(ctx) {const authUser = ctx.state.user;const { query } = ctx;if (!authUser) {return ctx.unauthorized();}await validateQuery(query, ctx);const sanitizedQuery = await sanitizeQuery(query, ctx);const user = await getService('user').fetch(authUser.id, sanitizedQuery);ctx.body = await sanitizeOutput(user, ctx);},

其调用了validateQuerysanitizeQuerygetServicesanitizeOutput4个方法,其中validateQuerysanitizeQuerysanitizeOutput均在user.js中有定义,可直接照搬

// @strapi/plugin-users-permissions/server/controllers/user.js
const utils = require('@strapi/utils');
const { sanitize, validate } = utils;const sanitizeOutput = async (user, ctx) => {const schema = strapi.getModel('plugin::users-permissions.user');const { auth } = ctx.state;return sanitize.contentAPI.output(user, schema, { auth });
};const validateQuery = async (query, ctx) => {const schema = strapi.getModel('plugin::users-permissions.user');const { auth } = ctx.state;return validate.contentAPI.query(query, schema, { auth });
};const sanitizeQuery = async (query, ctx) => {const schema = strapi.getModel('plugin::users-permissions.user');const { auth } = ctx.state;return sanitize.contentAPI.query(query, schema, { auth });
};

getService位于@strapi/plugin-users-permissions/server/utils/index.js

// @strapi/plugin-users-permissions/server/utils/index.js
const sanitize = require('./sanitize');const getService = (name) => {return strapi.plugin('users-permissions').service(name);
};module.exports = {getService,sanitize,
};

观察@strapi/plugin-users-permissions/server/index.js发现,utils并未被server导出,故无法在外部引用该函数

// @strapi/plugin-users-permissions/server/index.js
const register = require('./register');
const bootstrap = require('./bootstrap');
const contentTypes = require('./content-types');
const middlewares = require('./middlewares');
const services = require('./services');
const routes = require('./routes');
const controllers = require('./controllers');
const config = require('./config');module.exports = () => ({register,bootstrap,config,routes,controllers,contentTypes,middlewares,services,
});

不过所幸getService仅为一句简单的return strapi.plugin('users-permissions').service(name);并未引用新的外部依赖,故可以在自定义的文件中重新定义一次该函数。

故最终实现代码如下:

// src/extensions/users-permissions/strapi-server.tsimport type { Strapi, Common, CoreApi } from '@strapi/types';
import { sanitize, validate } from '@strapi/utils';const getService = (name) => {return strapi.plugin('users-permissions').service(name);
};
const validateQuery = async (query, ctx) => {const schema = strapi.getModel('plugin::users-permissions.user');const { auth } = ctx.state;return validate.contentAPI.query(query, schema, { auth });
};const sanitizeQuery = async (query, ctx) => {const schema = strapi.getModel('plugin::users-permissions.user');const { auth } = ctx.state;return sanitize.contentAPI.query(query, schema, { auth });
};const sanitizeOutput = async (user, ctx) => {const schema = strapi.getModel('plugin::users-permissions.user');const { auth } = ctx.state;return sanitize.contentAPI.output(user, schema, { auth });
};const originMe = async (ctx) => {const authUser = ctx.state.user;const { query } = ctx;if (!authUser) {return ctx.unauthorized();}await validateQuery(query, ctx);const sanitizedQuery = await sanitizeQuery(query, ctx);const user = await getService('user').fetch(authUser.id, sanitizedQuery);// ctx.body = await sanitizeOutput(user, ctx);return await sanitizeOutput(user, ctx);
};export default async (plugin) => {const uid: Common.UID.ContentType = 'plugin::users-permissions.user';plugin.controllers.user.me = async (ctx) => {// Custom code here;const res = await originMe(ctx); // 调用了原有的me函数return res;};return plugin;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/826215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【VI/VIM】基本操作备忘录

简介 新建/打开文件 工作模式 常用命令 移动命令 文本选中 撤销、删除 复制粘贴 替换 缩排 查找 替换 插入 分屏 练习

【动态规划】C++简单多状态dp问题(打家劫舍、粉刷房子、买卖股票的最佳时机...)

文章目录 前言1. 前言 - 理解动态规划算法2. 关于 简单多状态的dp问题2.5 例题按摩师/打家劫舍 3. 算法题3.1_打家劫舍II3.2_删除并获得点数3.3_粉刷房子3.4_买卖股票的最佳时机含冷冻期3.5_买卖股票的最佳时机含手续费3.6_买卖股票的最佳时机III3.7_买卖股票的最佳时机IV 前言…

交换机的种类有哪些?主要都具有哪些作用?

在当今数字化时代,网络已经成为我们生活和工作中不可或缺的一部分。无论是家庭网络还是企业网络,都需要有效的网络设备来实现数据通信和资源共享。而网络交换机作为一种重要的网络设备,扮演着连接和管理网络设备的关键角色。本文将探讨交换机…

开源贡献代码之​探索一下CPython

探索一下Cython 本篇文章将会围绕最近给Apache提的一个feature为背景,展开讲讲CPython遇到的问题,以及尝试自己从0写一个库出来,代码也已经放星球了,感兴趣的同学可以去下载学习。 0.背景 最近在给apache arrow提的一个feature因为…

《TinyLlama: An Open-Source Small Language Model》全文翻译

【Title】 TinyLlama:开源小语言模型 【Abstract】 我们推出了 TinyLlama,这是一个紧凑的 1.1B 语言模型,在大约 1 万亿个令牌上进行了大约 3 个时期的预训练。 TinyLlama 基于 Llama 2(Touvron 等人,2023b&#xff…

VUE项目使用.env配置多种环境以及如何加载环境

第一步,创建多个环境配置文件 Vue CLI 项目默认使用 .env 文件来定义环境变量。你可以通过创建不同的 .env 文件来为不同环境设置不同的环境变量,例如: .env —— 所有模式共用.env.local —— 所有模式共用,但不会被 git 提交&…

C语言 三目运算符

C语言 逻辑分支语句中 还有一种 三目运算符 我们编写代码如下 #include <stdio.h>int main() {const char* a 1 1 ? "表达式1" : "表达式2";printf("%s", a);return 0; }这里 我们根据逻辑 先定义一个a 然后 它的值 等于一个 三目运算…

【CodeGeeX】国产的免费AI编程助手

CodeGeeX&#xff08;官网&#xff1a;https://codegeex.cn/&#xff09;是一款基于大模型的全能的智能编程助手。它可以实现代码的生成与补全、自动添加注释、代码翻译以及智能问答等功能&#xff0c;能够帮助开发者显著提高工作效率。CodeGeeX支持主流的编程语言&#xff0c;…

C++练级之路——类和对象(下)

目录 1、构造函数初始化列表 2、类型转换 3、explicit关键字 4、static成员 5、友元 友元函数 友元类 6、内部类 7、匿名对象 8、拷贝构造时的一些编译器优化 差不多结束了&#xff0c;类和对象&#xff01; 1、构造函数初始化列表 初始化列表&#xff1a;以一个冒号…

python:元组,字符串,切片

一、元组# 列表可以修改内容&#xff0c;元组可以不被修改 # 在程序内封装数据&#xff0c;不希望数据被篡改&#xff0c;所以使用元组 # 语法&#xff1a; 不限制类型 # 定于元组的字面量&#xff1a; &#xff08;元素&#xff0c;元素&#xff0c;元素.....&#xff09; # 定…

萌新_1 环境安装(基于QQNT框架 Python Flask)

遇到问题加QQ群聊 群主在线解答 点击加入群聊【星辰开发】 一&#xff1a;安装QQ 目前为开发&#xff0c;推荐都安装到一台电脑上 直接安装到本地windows电脑&#xff0c; 优点方便开发 一键安装 Windows 用户一键安装方案 https://github.com/super1207/install_llob/rel…

LLMs——扩展数据受限的语言模型解决方案

概述 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;大型语言模型的发展一直是研究的热点。这些模型通过增加参数数量和训练数据量来提升性能&#xff0c;但这种增长趋势是否会有一个极限&#xff1f;实际上&#xff0c;研究者们已经注意到&#xff0c;为了有效地…

大话设计模式-依赖倒转原则

依赖倒转原则 在大话设计模式这本书中&#xff0c;作者通过电话修电脑这个例子引入了面向对象设计的基本原则之一&#xff1a;依赖倒转原则。 概念 依赖倒转原则是面向对象设计的基本原则之一&#xff0c;它用于减少类之间的耦合&#xff0c;提高系统的灵活性和可维护性。在…

QT C++ sqlite 对多个数据库的操作

//本文描述&#xff0c;QT 对多数据库的操作。 //你可能会想&#xff0c;多数据库的操作时&#xff0c;查询语句怎么知道是哪个数据库。 //QT提供了这样一种构造函数 QSqlQuery(const QSqlDatabase &db) //指定数据库 //在QT6.2.4 MSVC2019调试通过。 //效果见下图&am…

Docker(二)Docker+ server部署极简前端页面

本篇文章介绍如何使用 Dockerserver 将一个极简前端页面进行部署 1.本地运行一个简单的前端页面&#xff0c;再把它部署到服务器上 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&quo…

prompt问题【中间不好】

问题1:longchain 关键词在中间容易被忽略掉 Found in the Middle: How Language Models Use Long Contexts Better via Plug-and-Play Positional Encoding 论文对大模型在长文本情况下的性能做了一系列实验研究&#xff0c;发现了一个有趣的“Lost in the middle”现象&#x…

贴片 AMC1200BDWVR 封装 SOIC-8 隔离放大器IC芯片

AMC1200BDWVR的应用领域相当广泛&#xff0c;主要涵盖以下几个方面&#xff1a; 工业控制&#xff1a;在工业自动化系统中&#xff0c;AMC1200BDWVR可用于精确地检测和控制电流&#xff0c;例如在电机驱动和电力转换系统中。 电源管理&#xff1a;该器件适用于各种电源系统&a…

【昇腾产品应用】英码科技EA500I基于昇腾Mind SDK实现实时人体关键点检测

在教育、体育、安防、交通、医疗等领域中&#xff0c;实时人体关键点检测应用发挥着至关重要的作用&#xff0c;比如在体育训练时&#xff0c;实时人体关键点检测可以精确、实时地捕捉运动员的动作&#xff0c;从而进行动作分析和优化&#xff1b;在安防应用场景中&#xff0c;…

Vue3:响应式数据的基本使用(ref、reactive)

一、前言 在Vue3中&#xff0c;如果数据不是响应式数据&#xff0c;当数据的值发生改变时&#xff0c;页面上的数据是不会发生改变的。因此本文主要介绍Vue3中响应式数据的使用&#xff0c;包括ref和reactive的基本使用。 二、ref 1、ref —— 创建基本类型的响应式数据 re…

Python-VBA函数之旅-globals函数

目录 一、globals函数的常见应用场景&#xff1a; 二、globals函数与locals函数对比分析&#xff1a; 1、globals函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;https://blog.csdn.net/ygb_1024?spm101…