Skip to content

Commit e0f0684

Browse files
authored
Merge branch 'master' into chore/dependabot
2 parents 6ccd787 + f580693 commit e0f0684

File tree

516 files changed

+33832
-10571
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

516 files changed

+33832
-10571
lines changed

.clabot

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,40 @@
11
{
22
"contributors": [
3+
"almeidx",
4+
"axisiscool",
35
"BanTheNons",
6+
"Benricheson101",
7+
"brawaru",
48
"CleverSource",
9+
"Dalkskkskk",
510
"DarkView",
611
"DenverCoder1",
7-
"Jernik",
8-
"Rstar284",
9-
"almeidx",
10-
"axisiscool",
1112
"dexbiobot",
1213
"greenbigfrog",
14+
"hawkeye7662",
15+
"iamshoXy",
16+
"Jernik",
1317
"k200-1",
18+
"LilyBergonzat",
19+
"martinbndr",
1420
"metal0",
21+
"Obliie",
1522
"paolojpa",
1623
"roflmaoqwerty",
24+
"Rstar284",
25+
"rubyowo",
26+
"rukogit",
27+
"Scraayp",
28+
"TheKodeToad",
1729
"thewilloftheshadow",
1830
"usoka",
1931
"vcokltfre",
32+
"WeebHiroyuki",
33+
"zayKenyon",
34+
2035
"Dragory",
21-
"rubyowo",
22-
"Dalkskkskk",
23-
"iamshoXy",
24-
"Scraayp",
2536
"app/dependabot",
26-
"dependabot[bot]",
27-
"zayKenyon",
28-
"rukogit",
29-
"Obliie",
30-
"brawaru",
31-
"Benricheson101",
32-
"hawkeye7662",
33-
"LilyBergonzat",
34-
"martinbndr"
37+
"dependabot[bot]"
3538
],
3639
"message": "Thank you for contributing to Zeppelin! We require contributors to sign our Contributor License Agreement (CLA). To let us review and merge your code, please visit https://github.com/ZeppelinBot/CLA to sign the CLA!"
3740
}

.env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ STAFF=
2222
DEFAULT_ALLOWED_SERVERS=
2323

2424
# Only required if relevant feature is used
25-
#PHISHERMAN_API_KEY=
25+
#FISHFISH_API_KEY=
2626

27+
#DEFAULT_SUCCESS_EMOJI=
28+
#DEFAULT_ERROR_EMOJI=
2729

2830
# ==========================
2931
# DEVELOPMENT

.github/workflows/codequality.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88

99
strategy:
1010
matrix:
11-
node-version: [18.16]
11+
node-version: [22]
1212

1313
steps:
1414
- uses: actions/checkout@v1

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
18
1+
22

Dockerfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:20
1+
FROM node:22 AS build
22

33
RUN mkdir /zeppelin
44
RUN chown node:node /zeppelin
@@ -32,3 +32,8 @@ RUN npm run build
3232
# Prune dev dependencies
3333
WORKDIR /zeppelin
3434
RUN npm prune --omit=dev
35+
36+
FROM node:22-alpine AS main
37+
38+
USER node
39+
COPY --from=build --chown=node:node /zeppelin /zeppelin

backend/package.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"description": "",
55
"private": true,
66
"type": "module",
7+
"exports": {
8+
"./*": "./dist/*"
9+
},
710
"scripts": {
811
"watch": "tsc-watch --build --onSuccess \"node start-dev.js\"",
912
"watch-yaml-parse-test": "tsc-watch --build --onSuccess \"node dist/yamlParseTest.js\"",
@@ -26,7 +29,7 @@
2629
"migrate-rollback-prod": "npm run migrate-rollback",
2730
"migrate-rollback-dev": "npm run build && npm run migrate-rollback",
2831
"validate-active-configs": "node --enable-source-maps dist/validateActiveConfigs.js > ../config-errors.txt",
29-
"export-config-json-schema": "node --enable-source-maps dist/exportSchemas.js > ../config-schema.json",
32+
"export-config-json-schema": "node --enable-source-maps dist/exportSchemas.js ../config-checker/public/config-schema.json",
3033
"test": "npm run build && npm run run-tests",
3134
"run-tests": "ava",
3235
"test-watch": "tsc-watch --build --onSuccess \"npx ava\""
@@ -38,18 +41,18 @@
3841
"cors": "^2.8.5",
3942
"cross-env": "^7.0.3",
4043
"deep-diff": "^1.0.2",
41-
"discord.js": "^14.14.1",
44+
"discord.js": "^14.19.3",
4245
"dotenv": "^4.0.0",
4346
"emoji-regex": "^8.0.0",
4447
"escape-string-regexp": "^1.0.5",
4548
"express": "^4.20.0",
4649
"fp-ts": "^2.0.1",
4750
"humanize-duration": "^3.15.0",
48-
"js-yaml": "^3.13.1",
49-
"knub": "^32.0.0-next.21",
51+
"js-yaml": "^4.1.0",
52+
"knub": "^32.0.0-next.25",
5053
"knub-command-manager": "^9.1.0",
5154
"last-commit-log": "^2.1.0",
52-
"lodash": "^4.17.21",
55+
"lodash-es": "^4.17.21",
5356
"moment-timezone": "^0.5.21",
5457
"multer": "^1.4.5-lts.1",
5558
"mysql2": "^3.9.8",
@@ -72,15 +75,14 @@
7275
"utf-8-validate": "^5.0.5",
7376
"uuid": "^9.0.0",
7477
"yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build",
75-
"zlib-sync": "^0.1.7",
76-
"zod": "^3.7.2"
78+
"zod": "^3.25.17"
7779
},
7880
"devDependencies": {
7981
"@types/cors": "^2.8.5",
8082
"@types/express": "^4.16.1",
8183
"@types/jest": "^24.0.15",
8284
"@types/js-yaml": "^3.12.1",
83-
"@types/lodash.at": "^4.6.3",
85+
"@types/lodash-es": "^4.17.12",
8486
"@types/moment-timezone": "^0.5.6",
8587
"@types/multer": "^1.4.7",
8688
"@types/passport": "^1.0.0",

backend/src/RegExpRunner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { EventEmitter } from "events";
21
import { CooldownManager } from "knub";
2+
import { EventEmitter } from "node:events";
33
import { RegExpWorker, TimeoutError } from "regexp-worker";
44
import { MINUTES, SECONDS } from "./utils.js";
55
import Timeout = NodeJS.Timeout;

backend/src/SimpleCache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export class SimpleCache<T = any> {
4646
});
4747

4848
if (this.maxItems && this.store.size > this.maxItems) {
49-
const keyToDelete = this.store.keys().next().value;
49+
const keyToDelete = this.store.keys().next().value!;
5050
this.store.delete(keyToDelete);
5151
}
5252
}

backend/src/api/docs.ts

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,135 @@
11
import express from "express";
2-
import z from "zod";
3-
import { guildPlugins } from "../plugins/availablePlugins.js";
4-
import { guildPluginInfo } from "../plugins/pluginInfo.js";
2+
import z from "zod/v4";
3+
import { availableGuildPlugins } from "../plugins/availablePlugins.js";
4+
import { ZeppelinGuildPluginInfo } from "../types.js";
55
import { indentLines } from "../utils.js";
66
import { notFound } from "./responses.js";
7+
import { $ZodPipeDef } from "zod/v4/core";
78

8-
function isZodObject(schema: z.ZodTypeAny): schema is z.ZodObject<any> {
9-
return schema._def.typeName === "ZodObject";
9+
function isZodObject(schema: z.ZodType): schema is z.ZodObject<any> {
10+
return schema.def.type === "object";
1011
}
1112

12-
function isZodRecord(schema: z.ZodTypeAny): schema is z.ZodRecord<any> {
13-
return schema._def.typeName === "ZodRecord";
13+
function isZodRecord(schema: z.ZodType): schema is z.ZodRecord<any> {
14+
return schema.def.type === "record";
1415
}
1516

16-
function isZodEffects(schema: z.ZodTypeAny): schema is z.ZodEffects<any, any> {
17-
return schema._def.typeName === "ZodEffects";
17+
function isZodOptional(schema: z.ZodType): schema is z.ZodOptional<any> {
18+
return schema.def.type === "optional";
1819
}
1920

20-
function isZodOptional(schema: z.ZodTypeAny): schema is z.ZodOptional<any> {
21-
return schema._def.typeName === "ZodOptional";
21+
function isZodArray(schema: z.ZodType): schema is z.ZodArray<any> {
22+
return schema.def.type === "array";
2223
}
2324

24-
function isZodArray(schema: z.ZodTypeAny): schema is z.ZodArray<any> {
25-
return schema._def.typeName === "ZodArray";
25+
function isZodUnion(schema: z.ZodType): schema is z.ZodUnion<any> {
26+
return schema.def.type === "union";
2627
}
2728

28-
function isZodUnion(schema: z.ZodTypeAny): schema is z.ZodUnion<any> {
29-
return schema._def.typeName === "ZodUnion";
29+
function isZodNullable(schema: z.ZodType): schema is z.ZodNullable<any> {
30+
return schema.def.type === "nullable";
3031
}
3132

32-
function isZodNullable(schema: z.ZodTypeAny): schema is z.ZodNullable<any> {
33-
return schema._def.typeName === "ZodNullable";
33+
function isZodDefault(schema: z.ZodType): schema is z.ZodDefault<any> {
34+
return schema.def.type === "default";
3435
}
3536

36-
function isZodDefault(schema: z.ZodTypeAny): schema is z.ZodDefault<any> {
37-
return schema._def.typeName === "ZodDefault";
37+
function isZodLiteral(schema: z.ZodType): schema is z.ZodLiteral<any> {
38+
return schema.def.type === "literal";
3839
}
3940

40-
function isZodLiteral(schema: z.ZodTypeAny): schema is z.ZodLiteral<any> {
41-
return schema._def.typeName === "ZodLiteral";
41+
function isZodIntersection(schema: z.ZodType): schema is z.ZodIntersection<any, any> {
42+
return schema.def.type === "intersection";
4243
}
4344

44-
function isZodIntersection(schema: z.ZodTypeAny): schema is z.ZodIntersection<any, any> {
45-
return schema._def.typeName === "ZodIntersection";
46-
}
47-
48-
function formatZodConfigSchema(schema: z.ZodTypeAny) {
45+
function formatZodConfigSchema(schema: z.ZodType) {
4946
if (isZodObject(schema)) {
5047
return (
5148
`{\n` +
52-
Object.entries(schema._def.shape())
53-
.map(([k, value]) => indentLines(`${k}: ${formatZodConfigSchema(value as z.ZodTypeAny)}`, 2))
49+
Object.entries(schema.def.shape)
50+
.map(([k, value]) => indentLines(`${k}: ${formatZodConfigSchema(value as z.ZodType)}`, 2))
5451
.join("\n") +
5552
"\n}"
5653
);
5754
}
5855
if (isZodRecord(schema)) {
59-
return "{\n" + indentLines(`[string]: ${formatZodConfigSchema(schema._def.valueType)}`, 2) + "\n}";
60-
}
61-
if (isZodEffects(schema)) {
62-
return formatZodConfigSchema(schema._def.schema);
56+
return "{\n" + indentLines(`[string]: ${formatZodConfigSchema(schema.valueType as z.ZodType)}`, 2) + "\n}";
6357
}
6458
if (isZodOptional(schema)) {
65-
return `Optional<${formatZodConfigSchema(schema._def.innerType)}>`;
59+
return `Optional<${formatZodConfigSchema(schema.def.innerType)}>`;
6660
}
6761
if (isZodArray(schema)) {
68-
return `Array<${formatZodConfigSchema(schema._def.type)}>`;
62+
return `Array<${formatZodConfigSchema(schema.def.element)}>`;
6963
}
7064
if (isZodUnion(schema)) {
71-
return schema._def.options.map((t) => formatZodConfigSchema(t)).join(" | ");
65+
return schema.def.options.map((t) => formatZodConfigSchema(t)).join(" | ");
7266
}
7367
if (isZodNullable(schema)) {
74-
return `Nullable<${formatZodConfigSchema(schema._def.innerType)}>`;
68+
return `Nullable<${formatZodConfigSchema(schema.def.innerType)}>`;
7569
}
7670
if (isZodDefault(schema)) {
77-
return formatZodConfigSchema(schema._def.innerType);
71+
return formatZodConfigSchema(schema.def.innerType);
7872
}
7973
if (isZodLiteral(schema)) {
80-
return schema._def.value;
74+
return schema.def.values;
8175
}
8276
if (isZodIntersection(schema)) {
83-
return [formatZodConfigSchema(schema._def.left), formatZodConfigSchema(schema._def.right)].join(" & ");
77+
return [
78+
formatZodConfigSchema(schema.def.left as z.ZodType),
79+
formatZodConfigSchema(schema.def.right as z.ZodType),
80+
].join(" & ");
8481
}
85-
if (schema._def.typeName === "ZodString") {
82+
if (schema.def.type === "string") {
8683
return "string";
8784
}
88-
if (schema._def.typeName === "ZodNumber") {
85+
if (schema.def.type === "number") {
8986
return "number";
9087
}
91-
if (schema._def.typeName === "ZodBoolean") {
88+
if (schema.def.type === "boolean") {
9289
return "boolean";
9390
}
94-
if (schema._def.typeName === "ZodNever") {
91+
if (schema.def.type === "never") {
9592
return "never";
9693
}
94+
if (schema.def.type === "pipe") {
95+
return formatZodConfigSchema((schema.def as $ZodPipeDef).in as z.ZodType);
96+
}
9797
return "unknown";
9898
}
9999

100+
const availableGuildPluginsByName = availableGuildPlugins.reduce<Record<string, ZeppelinGuildPluginInfo>>(
101+
(map, obj) => {
102+
map[obj.plugin.name] = obj;
103+
return map;
104+
},
105+
{},
106+
);
107+
100108
export function initDocs(router: express.Router) {
101-
const docsPluginNames = Object.keys(guildPluginInfo).filter((k) => guildPluginInfo[k].showInDocs);
109+
const docsPlugins = availableGuildPlugins.filter((obj) => obj.docs.type !== "internal");
102110

103111
router.get("/docs/plugins", (req: express.Request, res: express.Response) => {
104112
res.json(
105-
docsPluginNames.map((pluginName) => {
106-
const info = guildPluginInfo[pluginName];
107-
const thinInfo = info ? { prettyName: info.prettyName, legacy: info.legacy ?? false } : {};
108-
return {
109-
name: pluginName,
110-
info: thinInfo,
111-
};
112-
}),
113+
docsPlugins.map((obj) => ({
114+
name: obj.plugin.name,
115+
info: {
116+
prettyName: obj.docs.prettyName,
117+
type: obj.docs.type,
118+
},
119+
})),
113120
);
114121
});
115122

116123
router.get("/docs/plugins/:pluginName", (req: express.Request, res: express.Response) => {
117-
const name = req.params.pluginName;
118-
const baseInfo = guildPluginInfo[name];
119-
if (!baseInfo) {
124+
const pluginInfo = availableGuildPluginsByName[req.params.pluginName];
125+
if (!pluginInfo) {
120126
return notFound(res);
121127
}
122128

123-
const plugin = guildPlugins.find((p) => p.name === name)!;
124-
const { configSchema, ...info } = baseInfo;
129+
const { configSchema, ...info } = pluginInfo.docs;
125130
const formattedConfigSchema = formatZodConfigSchema(configSchema);
126131

127-
const messageCommands = (plugin.messageCommands || []).map((cmd) => ({
132+
const messageCommands = (pluginInfo.plugin.messageCommands || []).map((cmd) => ({
128133
trigger: cmd.trigger,
129134
permission: cmd.permission,
130135
signature: cmd.signature,
@@ -133,10 +138,10 @@ export function initDocs(router: express.Router) {
133138
config: cmd.config,
134139
}));
135140

136-
const defaultOptions = plugin.defaultOptions || {};
141+
const defaultOptions = pluginInfo.docs.configSchema.safeParse({}).data ?? {};
137142

138143
res.json({
139-
name,
144+
name: pluginInfo.plugin.name,
140145
info,
141146
configSchema: formattedConfigSchema,
142147
defaultOptions,

backend/src/api/guilds/importExport.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ApiPermissions } from "@zeppelinbot/shared/apiPermissions.js";
22
import express, { Request, Response } from "express";
33
import moment from "moment-timezone";
4-
import { z } from "zod";
4+
import { z } from "zod/v4";
55
import { GuildCases } from "../../data/GuildCases.js";
66
import { Case } from "../../data/entities/Case.js";
77
import { MINUTES } from "../../utils.js";

0 commit comments

Comments
 (0)