酸酸编译版 by Teddysun

转载自秋水逸冰

https://teddysun.com/666.html

最近花了点时间制作了 shadowsocks-libev,shadowsocks-rust,go-shadowsocks2,v2ray-plugin,xray-plugin 的 rpm 包。
以后在 CentOS 7 或 CentOS Stream 8 / Rocky Linux 8 / AlmaLinux 8 或 CentOS Stream 9 / Rocky Linux 9 / AlmaLinux 9 等系统下,可以一键安装,自动解决依赖,可以说是非常方便了。
多说一句,其实 Docker Image 就能搞定一切了,但是安装 rpm 包的话,系统资源开销更小一些,适用于小内存的机器。
以上的 rpm 包,不出意外的话,我将会持续更新。

写在前面

2022 年 6 月 18 日适用于 CentOS 7 或 CentOS Stream 8 / Rocky Linux 8 / AlmaLinux 8 等或 CentOS Stream 9 / Rocky Linux 9 / AlmaLinux 9 等的 Teddysun Linux Repository 发布了。
通过这种方式可以非常方便地安装,升级 rpm 包。

由于需要安装依赖包,所以事先要开启 EPEL Repository

yum install -y yum-utils epel-release
yum-config-manager --enable epel

1. 创建以下 repo 文件
/etc/yum.repos.d/teddysun.repo

文件的内容如下:

# Name: Teddysun Linux Repository
# URL: https://teddysun.com/666.html

[teddysun]
name=Teddysun Linux Repository for EL $releasever
baseurl=https://dl.lamp.sh/shadowsocks/el$releasever/$basearch/
	https://fr1.teddyvps.com/shadowsocks/el$releasever/$basearch/
enabled=1
gpgcheck=0

或者执行以下命令直接安装 teddysun.repo:

yum-config-manager --add-repo https://dl.lamp.sh/shadowsocks/teddysun.repo

2. 重建 repo 缓存,执行如下命令:

yum makecache

3. 通过 yum 来安装软件包,比如:

yum install shadowsocks-libev v2ray-plugin xray-plugin

4. 以后软件若有升级,也可通过 yum 来升级软件包,比如:

yum update shadowsocks-libev v2ray-plugin xray-plugin

5. 若想卸载,也可通过 yum 来卸载软件包,比如:

yum remove shadowsocks-libev v2ray-plugin xray-plugin

目前,Teddysun Linux Repository 里有如下几款软件,欢迎使用。如有问题需要反馈,请到我的 Telegram 群里提出。
shadowsocks-libev
shadowsocks-rust
go-shadowsocks2
v2ray-plugin
xray-plugin

2022 年 6 月 19 日 Teddysun Linux Repository 支持 aarch64 架构。
1. 查看 Teddysun Linux Repository 里所有软件包:

yum repo-pkgs teddysun list

2. 一次性安装 Teddysun Linux Repository 里所有软件包:

yum repo-pkgs teddysun install

Shadowsocks-libev

2022 年 6 月 24 日更新日志:
编译了 shadowsocks-libev 最新代码 (Commits on Jun 23, 2022);
2022 年 6 月 16 日更新日志:
编译了 shadowsocks-libev 最新代码 (Commits on Jun 4, 2022);

使用 root 用户执行以下命令安装:

yum install -y shadowsocks-libev

成功安装后,执行以下命令查看版本号:

ss-server -h

返回值节选:

shadowsocks-libev 3.3.5

默认配置文件如下,如需自定义端口,密码,插件等信息,请自行修改

/etc/shadowsocks/shadowsocks-libev-config.json

服务端 service 文件

/usr/lib/systemd/system/shadowsocks-libev-server.service

启动服务端

systemctl start shadowsocks-libev-server

停止服务端

systemctl stop shadowsocks-libev-server

查看服务端状态

systemctl status shadowsocks-libev-server

设置服务端 service 开机自启动

systemctl enable shadowsocks-libev-server

其他 service 文件,用法同服务端 service 一致,但需要事先修改配置文件

/usr/lib/systemd/system/shadowsocks-libev-manager.service
/usr/lib/systemd/system/shadowsocks-libev-client.service
/usr/lib/systemd/system/shadowsocks-libev-redir.service
/usr/lib/systemd/system/shadowsocks-libev-tunnel.service
/usr/lib/systemd/system/shadowsocks-libev-nat.service

Shadowsocks-rust

2022 年 10 月 24 日更新日志:
编译了shadowsocks-rust 版本 1.15.0-alpha.9;

2022 年 6 月 18 日更新日志:
编译了 shadowsocks-rust 最新稳定版 v1.14.3;

使用 root 用户执行以下命令安装:

yum install -y shadowsocks-rust

成功安装后,执行以下命令查看版本号:

ssserver --version

返回值:

shadowsocks 1.15.0-alpha.9

默认配置文件如下,如需自定义端口,密码,插件等信息,请自行修改

/etc/shadowsocks/shadowsocks-rust-config.json

服务端 service 文件

/usr/lib/systemd/system/shadowsocks-rust-server.service

启动服务端

systemctl start shadowsocks-rust-server

停止服务端

systemctl stop shadowsocks-rust-server

查看服务端状态

systemctl status shadowsocks-rust-server

设置服务端 service 开机自启动

systemctl enable shadowsocks-rust-server

其他 service 文件,用法同服务端 service 一致,但需要事先修改配置文件

/usr/lib/systemd/system/shadowsocks-rust-client.service

v2ray-plugin

2022 年 9 月 7 日更新日志:
编译了 v2ray-plugin 最新版 v5.1.0;
2022 年 8 月 20 日更新日志:
编译了 v2ray-plugin 最新版 v5.0.8;
2022 年 6 月 16 日更新日志:
编译了 v2ray-plugin 最新版 v5.0.7;

使用 root 用户执行以下命令安装:

yum install -y v2ray-plugin

成功安装后,执行以下命令查看版本号:

v2ray-plugin -version

返回值:

v2ray-plugin v5.1.0
Go version go1.19.1
Yet another SIP003 plugin for shadowsocks

该插件兼容 shadowsocks-libev 和 shadowsocks-rust,修改其默认配置文件即可调用插件。

xray-plugin

2022 年 11 月 28 日更新日志:
编译了 xray-plugin 最新版 v1.6.5;

2022 年 11 月 14 日更新日志:
编译了 xray-plugin 最新版 v1.6.4;

2022 年 11 月 7 日更新日志:
编译了 xray-plugin 最新版 v1.6.3;

2022 年 10 月 29 日更新日志:
编译了 xray-plugin 最新版 v1.6.2;

2022 年 10 月 22 日更新日志:
编译了 xray-plugin 最新版 v1.6.1;

2022 年 9 月 20 日更新日志:
编译了 xray-plugin 最新版 v1.6.0;

2022 年 8 月 29 日更新日志:
编译了 xray-plugin 最新版 v1.5.10;

2022 年 7 月 16 日更新日志:
编译了 xray-plugin 最新版 v1.5.9;

2022 年 6 月 20 日更新日志:
编译了 xray-plugin 最新版 v1.5.8;

2022 年 6 月 16 日更新日志:
编译了 xray-plugin 最新版 v1.5.7;

使用 root 用户执行以下命令安装:

yum install -y xray-plugin

成功安装后,执行以下命令查看版本号:

xray-plugin -version

返回值:

xray-plugin v1.6.5
Go version go1.19.3
Yet another SIP003 plugin for shadowsocks

该插件同样兼容 shadowsocks-libev 和 shadowsocks-rust,修改其默认配置文件即可调用插件。

One more thing

1. 统一下载地址:
https://dl.lamp.sh/shadowsocks/

2. 以上所有 rpm 包可以安装在同一系统下,不会产生冲突。

二进制文件路径:

写在最后

隐私保护协议

欢迎来到芒斯特。

芒斯特(简称“我们”)深知个人信息对您的重要性,我们将按照法律法规的规定,保护您的个人信息及隐私安全。我们致力于维持您对我们的信任,保护您的个人信息,本应用尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本应用会按照本隐私权政策的规定使用和披露您的个人信息。但本应用将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在未征得您事先许可的情况下,本应用不会将这些信息对外披露或向第三方提供。本应用会不时更新本隐私权政策。 您在同意本应用服务使用协议之时,即视为您已经同意本隐私权政策全部内容。本隐私权政策属于本应用服务使用协议不可分割的一部分。

请在使用我们的产品(或服务)前,仔细阅读并了解本《隐私保护协议》。

如果您不同意本隐私保护协议条款,我们无法为你提供完整的产品和服务,您也可以选择停止使用。当您选择继续或再次使用时,基于提供产品和服务所必需,将视为您接受和认可我们按照本协议条款对您的相关信息进行处理。

一、个人信息的收集和使用

个人信息的收集

在您使用“芒斯特”软件及相关服务的过程中,我们将根据合法、正当、必要的原则,向您明示收集、使用的目的、方式和范围,进行信息收集。我们为了向所有用户提供更好的服务和更完善的功能,可能会收集、储存和使用与您有关的信息以保障产品的正常基础运行;同时在不断优化、改善产品和服务过程中;及保障产品、服务以及用户使用安全的情况下也可能收集、使用、存储您的相关信息。如果您不提供相关信息,可能无法注册成为芒斯特的用户或无法享受我们提供的某些服务或功能,或者无法达到相关服务拟达到的效果。

(1)您在注册账户时填写的信息

例如,您在注册时填写的昵称和手机号码。

(2)您在使用服务时上传的信息

例如:您在使用我们APP时上传的头像及个人基本资料。

(3)您通过我们的客服或参加我们举办的活动提交的信息

例如:您参与我们线上活动提交的资料中包含的信息。

若您主动提供个人信息,即表示您同意我们按本政策所述目的和方式来处理您的个人信息。您提供的上述信息,将在您使用本服务期间持续授权我们使用。在您注销账号时,我们将停止使用并删除上述信息。

二、 我们在您使用服务时获取的信息

(1)日志信息

当您使用我们的服务时,我们可能会自动存储手机相关信息为服务日志信息: 设备信息,例如,设备型号,操作系统版本等信息;软件信息,例如,软件的版本号;IP地址。

(2) 从第三方合作伙伴获取的信息

我们可能会获得您在使用第三方合作伙伴服务时所产生或分享的信息。例如您使用微信服务时,我们会获取您登录第三方合作伙伴服务的名称,登陆时间,方便您进行授权管理。请您仔细阅读第三方合作伙伴服务的用户协议或隐私政策。

三、我们如何使用收集的信息

我们严格遵守法律法规的规定及与用户的规定,将手机的信息用于以下用途。若我们超出以下用途使用您的信息,我们将在此向您说明,并征得您的同意。

(1)向您提供服务。

(2)满足您的个性化需求。例如,语言设定,位置设定,个性化服务。

(3)产品开发和服务优化。例如,当我们的系统发生故障时,我们会记录和分析系统故障时产生的信息,优化我们的服务。

(4)安全保障。例如,我们将您的信息用于身份验证,安全防范,存档备份、客户的安全服务等用途。

(5)评估和改善我们的推广活动效果。

(6)管理软件。例如,进行软件认证,软件更新升级等。

为了让您有更好的体验,改善我们的服务或经您同意的其他用途,在符合相关法律法规的前提下,我们可能将通过某些服务所收集的信息用于我们的其他服务。

为了确保服务的安全,帮助我们更好的了解我们应用程序的运行情况,我们可能会记录相关信息。例如您使用应用程序的频率、故障信息、总体使用情况、性能数据以及应用程序的来源。 我们不会将我们存储在分析软件中的信息与您应用程序中提供的个人身份信息相结合。

四、分享

未经您同意,我们不会与我们之外的任何第三方分享您的信息。

您可以通过我们的服务与您的好友,家人及其他用户分享您的相关信息。例如,您在微信朋友圈中公开分享的文字和照片。请注意,这其中可能包含您的个人身份信息、个人财产信息等敏感信息。请您谨慎考虑披露您的相关个人敏感信息。

五、披露

我们仅会在以下情况下,且采取符合业界标准的安全防护措施的前提下,才会披露您的信息:

1、根据您的需求,在您明确同意的披露方式下披露您所指定的信息;

2、根据法律、法规的要求、强制性的行政执法或司法要求所必须提供您信息的情况下,我们可能会依据所要求的信息类型和披露方式披露您的信息。在符合法律法规的前提下,当我们收到上述披露信息的请求时,我们会要求接收方必须出具与之相应的法律文件,如传票或调查函。我们坚信,对于要求我们提供的信息,应该在法律允许的范围内尽可能保持透明。我们对所有的请求都进行了慎重的审查,以确保其具备合法依据,且仅限于执法部门因特定调查目的且有合法权利获取的数据。

六、个人信息的保护和安全措施

(1)我们已使用符合业界标准的安全防护措施保护您提供的个人信息,防止数据遭到未经授权访问、公开披露、使用、修改、损坏或丢失。我们会采取一切合理可行的措施,保护您的个人信息。

(2)我们会采取一切合理可行的措施,确保未收集无关的个人信息。我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。

(3)互联网并非绝对安全的环境,而且电子邮件、即时通讯、及与其他我们用户的交流方式并未加密,我们强烈建议您不要通过此类方式发送个人信息。请使用复杂密码,协助我们保证您的账号安全。

(4)互联网环境并非百分之百安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。

(5)在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。

同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。

七、您的权利

按照中国相关的法律、法规、标准,以及其他国家、地区的通行做法,我们保障您对自己的个人信息行使以下权利:

(1)访问您的个人信息

您有权访问您的个人信息,法律法规规定的例外情况除外。如果您想行使数据访问权,可以通过以下方式自行访问:

账户信息——如果您希望访问或编辑您的账户中的个人资料信息和支付信息、更改您的密码、添加安全信息或关闭您的账户等,您可以通过访问个人中心执行此类操作。

如果您无法通过上述链接访问这些个人信息,您可以随时发送电子邮件至service@imajp.net。我们将在15天内回复您的访问请求。

对于您在使用我们的产品或服务过程中产生的其他个人信息,只要我们不需要过多投入,我们会向您提供。如果您想行使数据访问权,请发送电子邮件至service@imajp.net。

(2)更正您的个人信息

当您发现我们处理的关于您的个人信息有错误时,您有权要求我们做出更正。您可以通过“(一)访问您的个人信息”中罗列的方式提出更正申请。

如果您无法通过上述链接更正这些个人信息,您可以随时发送电子邮件至service@imajp.net。我们将在15天内回复您的更正请求。

(3)删除您的个人信息

在以下情形中,您可以向我们提出删除个人信息的请求:

1、如果我们处理个人信息的行为违反法律法规;

2、如果我们收集、使用您的个人信息,却未征得您的同意;

3、如果我们处理个人信息的行为违反了与您的约定;

4、如果您不再使用我们的产品或服务;

5、如果我们不再为您提供产品或服务。

若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。

当您从我们的服务中删除信息后,我们可能不会立即备份系统中删除相应的信息,但会在备份更新时删除这些信息。

八、我们如何处理儿童的个人信息

我们的产品、网站和服务主要面向成人。如果没有父母或监护人的同意,儿童不得创建自己的用户账户。

对于经父母同意而收集儿童个人信息的情况,我们只会在受到法律允许、父母或监护人明确同意或者保护儿童所必要的情况下使用或公开披露此信息。

尽管当地法律和习俗对儿童的定义不同,但我们将不满 14 周岁的任何人均视为儿童。

如果我们发现自己在未事先获得可证实的父母同意的情况下收集了儿童的个人信息,则会设法尽快删除相关数据。

九、本隐私权政策如何更新

为了给您提供更好的服务,我们及相关服务将不时更新与变化,我们会适时对本隐私政策进行修订,这些修订构成本隐私政策的一部分并具有等同于本隐私政策的效力,未经您明确同意,我们不会削减您依据当前生效的本隐私政策所应享受的权利。本隐私政策更新后,我们会在芒斯特出更新版本,并在更新后的条款生效前通过官方公告或其他适当的方式提醒您更新的内容,以便您及时了解本隐私政策的最新版本。

 十、如何联系我们

如果您对本隐私政策有任何疑问、意见或建议及合作事宜,通过以下方式与我们联系:邮箱:chen.raim@qq.com ,我们将尽快审核所涉问题,并在三十天内予以回复。

使用openwrt的uttpd实现Wake On Lan(WOL)

没错,今年我又搞崩路由器了,还好有备份,但是WOL相关配置没有备份,所以还是得做一下笔记。

要做一个siri控制PC打开的功能,流程就是如下所示

siri->快捷指令(打开url)->openwrt uttpd(接受请求)->lua(调用etherwake)->PC监听WOL唤醒

这边要记录的就是如何搭建一个openwrt的uttpd的配置

  1. uttpd记得安装luci,增加一个监听81端口的服务
  2. Lua 脚本处理程序的完整真实路径:/root/lua/http.lua。
  3. 文档根:/root/www(当初作为rewrite路径,但是遗失相关代码,忽略)

新建 /root/lua/http.lua

function handle_request(env)
    uhttpd.send("Status: 200 OK\r\n")
    uhttpd.send("Content-Type: text/plain\r\n\r\n")
    local rsfile = io.popen('/usr/bin/etherwake -D -i br-lan -b xx:xx:xx:xx:xx:2A')
    local rschar = rsfile:read("*all")
    uhttpd.send(rschar)
end

记得重启uttpd服务

然后创建siri的快捷指令访问就行了,甚至可以在上面返回一些文字,让siri读出来


2022/09/21更新 后来发现可能还需要path,做了一点更新

function handle_request(env)
    uhttpd.send("Status: 200 OK\r\n")
    uhttpd.send("Content-Type: text/plain\r\n\r\n")
    local path = env.PATH_INFO
    if (path == '/wol')
    then
        local rsfile = io.popen('/usr/bin/etherwake -D -i br-lan -b xx:xx:xx:xx:xx:2A')
        local rschar = rsfile:read("*all")
        uhttpd.send(path)
    else
        uhttpd.send("Hello World.")
    end
end

日日日!又搞崩路由器了!

每年总会手贱搞崩路由器,然后又手贱的没有备份,每次都要重新装一大堆软件,又要到处去找,麻烦。

那就把荒废很久的博客利用起来,算是做个备份。

记录系统:openwrt

官方软件:

  • luci-i18n-base-zh-cn (中文luci界面语言包)
  • ipset(ss前置)
  • vsftpd openssh-sftp-server (sftp)
  • ddns-scripts luci-app-ddns luci-i18n-ddns-zh-cn (ddns)
  • dnsmasq-full(注意必须是full,并删除原有的dnsmasq)

其他:

  • SSH登录key添加
  • DHCP分配静态地址,手机,pc,switch
  • wifi设置AZ,iw reg set AZ

自用软件:

其他注意事项:

  • 17.09好像不太稳定,很多lib都没编译进去,如 luci-lib-ipkgluci-compat

type-graphql初体验 – 增删改查

最近在用graphql来重写原来的数据查询方式,难免要重新学习如何编写增删改查,网上对于查的文档比较多,但是对于增删改的记录都比较少,本文旨在记录node server端的体验记录。

阅读本文之前,请先确认已经接入了graphql,可先参照例子

因使用的框架是Nest.js,不免要看文档是如何使用的,文档中提供了两种编写方式,一种是直接编写SDL,一种是通过代码的方式来生成SDL,所以本文采用第二种方案,type-graphql

我们先简单定义一个User实体。

import { Column, Entity, PrimaryGeneratedColumn, Unique } from 'typeorm';
import { Field, ID, ObjectType } from 'type-graphql';

@ObjectType()
@Entity()
@Unique(['username'])
export class User {
  @Field(type => ID)
  @PrimaryGeneratedColumn()
  id: number;

  @Field()
  @Column()
  username: string;

  @Field()
  @Column()
  password: string;
}

可以看出User实体就两个字段,一个username,一个password,剩下的那个是自增长的id。

从行首引入的包可以看出,我是typeorm和graphql的字段定义是放在一起的,这样可以节省代码,也不需要两边维护。

这样一个简单的实体就定义好了。

接下来是如何使用graphql和typeorm结合在一起。

我们先来确认一下接入graphql需要新建的定义,resolver,这是原来使用typeorm所没有的概念。

resolver的使用意义就是建立一个graphql的数据映射。

我目前使用的数据链路是这样的:

graphql client => resolver => service => typeorm

这么一个链路还是比较直观的,可以很简单的分析出来,新建一个resolver,需要注入service依赖。

我们先简单写一个

import { NotFoundException } from '@nestjs/common';
import { Query, Resolver } from '@nestjs/graphql';
import { User } from './user.entity';
import { UserService } from './user.service';

@Resolver(of => User) // 对该类进行Resolver定义,类似REST框架中的控制器
export class UserResolver {
  constructor(
    private readonly userService: UserService, // 注入UserService
  ) {}

  @Query(returns => User) // 添加Query装饰器,把方法标记为graphql查询
  async user(@Args('id') id: number): Promise<User> { // 定义入参出参
    const user = await this.userService.findOne(id); // 使用service进行查询
    if (!user) {
      throw new NotFoundException(id);
    }
    return user; // 返回user
  }

  @Query(returns => User) // 添加Query装饰器,把方法标记为graphql查询
  async userByUsername(@Args('username') username: string): Promise<User> { // 定义入参出参
    const user = await this.userService.findOneByUsername(username); // 使用service进行查询
    if (!user) {
      throw new NotFoundException(username);
    }
    return user; // 返回user
  }
}

上面的代码还是比较清晰易懂的,跟用控制器时候的开发体验比较一致,获取入参,通过入参查询数据,之后返回数据。

那么经过上述定义后,type-graphql会自动生成schema。(感叹号是必填的意思)

type Query {
  user(id: Float!): User!
  userByUsername(username: String!): User!
}

type User {
  id: ID!
  username: String!
  password: String!
}

调试

同时可以打开http://localhost:3000/graphql 进行接口调用。

通过id查询

query {
  user(id: 1) {
    username,
    password
  }
}

返回

{
  "data": {
    "user": {
      "username": "root",
      "password": "root"
    }
  }
}

使用用户名查询

query {
  userByUsername(username: "root") {
    username,
    password
  }
}

返回

{
  "data": {
    "userByUsername": {
      "username": "root",
      "password": "root"
    }
  }
}

直接上代码

@Mutation(returns => User) // 定义为graphql改动
async create(@Args('payload') payload: UserCreateInput): Promise<User> {// 创建入参
  return await this.userService.create(payload);
}

依然比较简单,这里把Query改为Mutation,就是把查询操作改为更改操作。

内容体中的语句依然是符合控制器时期的习惯的。

唯一需要注意的是入参,这边定义了一个UserCreateInput去定义入参,并用class-validator去验证入参,同时用Partial<User>去表示是User实体的子集

import { Length, MaxLength } from 'class-validator';
import { Field, InputType } from 'type-graphql';
import { User } from './user.entity';

@InputType()
export class UserCreateInput implements Partial<User> {
  @Field()
  @MaxLength(30)
  username: string;

  @Field()
  @Length(8, 255)
  password: string;
}

调试

mutation {
  create(payload: { username: "root2", password: "root2" }) {
        id,
    username,
    password
  }
}

返回

{
  "data": {
    "create": {
      "id": "2",
      "username": "root2",
      "password": "root2"
    }
  }
}

可以看到返回的是新创建的user的数据。

直接上代码

@Mutation(returns => User)
async update(@Args('id') id: number, @Args('payload') payload: UserUpdateInput): Promise<User> { // 注意这边新定义了UserUpdateInput,用于定义可更新的值
  return await this.userService.update(id, payload);
}

可以看出来其实是类似增的一个写法,也是Mutation,所以这次就不过多讲述了。

不过有些人可能对返回一个User感到不习惯,因为其实并不需要更新的数据,可能只是一个简单的post请求。

那么就可以针对resolve方法进行更改

@Mutation(returns => Boolean) // 更改返回为boolean值
async update(@Args('id') id: number, @Args('payload') payload: UserUpdateInput): Promise<User> {
  await this.userService.update(id, payload); // 更新
    return true; // 返回true,表示更新完成,假如上述更新出错,那么将会抛出错误,并且不会走到这一行
}

@Mutation(returns => Boolean)
async remove(@Args('id') id: number): Promise<boolean> {
  await this.userService.remove(id);
    return true;
}

删除就可以直接用到之前提到直接返回布尔值的方式。

mutation {
  remove(id: 2)
}

返回

{
  "data": {
    "remove": true
  }
}

残留问题

  • 能不能通过重载,实现自动识别入参,达到数字时查询id,字符串时查询用户名,对象时通过筛选条件查询用户。
  • 我为了约束入参,定义了UserCreateInput和UserUpdateInput,能不能通过User实体的配置解决,否则依然是维护多套代码。这可能是ts的使用范畴,需要学习。
  • 我目前就一个User实体,定义了增删改的mutation,但是名字过于通用,无法与后续代码区分。不知道实际项目会怎么处理这个问题。需要查看一些开源项目来学习。