This commit is contained in:
parent
7affca2bbc
commit
6e1595a7c5
8
ts/.idea/.gitignore
generated
vendored
Normal file
8
ts/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
6
ts/.idea/jsLibraryMappings.xml
generated
Normal file
6
ts/.idea/jsLibraryMappings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptLibraryMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$" libraries="{Node.js Core}" />
|
||||||
|
</component>
|
||||||
|
</project>
|
6
ts/.idea/misc.xml
generated
Normal file
6
ts/.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
ts/.idea/modules.xml
generated
Normal file
8
ts/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/ts.iml" filepath="$PROJECT_DIR$/.idea/ts.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
9
ts/.idea/ts.iml
generated
Normal file
9
ts/.idea/ts.iml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
6
ts/.idea/vcs.xml
generated
Normal file
6
ts/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
Binary file not shown.
@ -14,4 +14,7 @@ COPY --from=builder /build/node_modules node_modules
|
|||||||
COPY tsconfig.json package.json cli .
|
COPY tsconfig.json package.json cli .
|
||||||
COPY src src
|
COPY src src
|
||||||
|
|
||||||
|
# make sure it passes compilation before compiling
|
||||||
|
RUN yarn tsc
|
||||||
|
|
||||||
ENTRYPOINT ["/app/cli"]
|
ENTRYPOINT ["/app/cli"]
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "backend",
|
"name": "backend",
|
||||||
"packageManager": "yarn@4.6.0",
|
"packageManager": "yarn@4.6.0+sha512.5383cc12567a95f1d668fbe762dfe0075c595b4bfff433be478dbbe24e05251a8e8c3eb992a986667c1d53b6c3a9c85b8398c35a960587fbd9fa3a0915406728",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"barrels": "barrelsby -c barrelsby.json --delete"
|
"barrels": "barrelsby -c barrelsby.json --delete"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/object-hash": "^3",
|
"@types/object-hash": "^3",
|
||||||
"barrelsby": "^2.8.1",
|
"barrelsby": "^2.8.1",
|
||||||
|
"knip": "^5.45.0",
|
||||||
"rollup": "^4.34.8",
|
"rollup": "^4.34.8",
|
||||||
"typescript": "5.7.3"
|
"typescript": "5.7.3"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { WApiV3ItemDatabase } from "#/lib/types";
|
import { WApiV3ItemDatabase } from "#/lib/wynn/types";
|
||||||
import { WApi } from "#/lib/wapi";
|
import { WApi } from "#/lib/wynn/wapi";
|
||||||
import { ArkError, ArkErrors } from "arktype";
|
import { ArkError, ArkErrors } from "arktype";
|
||||||
|
|
||||||
export async function update_wynn_items() {
|
export async function update_wynn_items() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { container, T_PG } from "#/di";
|
import { c } from "#/di";
|
||||||
import { WapiV3GuildOverview } from "#/lib/types";
|
import { WapiV3GuildOverview } from "#/lib/wynn/types";
|
||||||
import { WApi } from "#/lib/wapi";
|
import { WApi } from "#/lib/wynn/wapi";
|
||||||
|
import { PG } from "#/services/pg";
|
||||||
import { type } from "arktype";
|
import { type } from "arktype";
|
||||||
import {parseDate} from "chrono-node";
|
import {parseDate} from "chrono-node";
|
||||||
|
|
||||||
@ -17,7 +18,7 @@ export async function update_all_guilds() {
|
|||||||
}
|
}
|
||||||
}).assert(ans.data)
|
}).assert(ans.data)
|
||||||
|
|
||||||
const db = container.get(T_PG)
|
const { db } = await c.getAsync(PG)
|
||||||
await db.begin(async (sql) => {
|
await db.begin(async (sql) => {
|
||||||
for(const [guild_name, guild] of Object.entries(parsed)){
|
for(const [guild_name, guild] of Object.entries(parsed)){
|
||||||
await sql`insert into wynn_guild_info
|
await sql`insert into wynn_guild_info
|
||||||
@ -45,7 +46,7 @@ export async function update_guild({
|
|||||||
}
|
}
|
||||||
const parsed = WapiV3GuildOverview.assert(ans.data)
|
const parsed = WapiV3GuildOverview.assert(ans.data)
|
||||||
|
|
||||||
const db = container.get(T_PG)
|
const { db } = await c.getAsync(PG)
|
||||||
|
|
||||||
await db.begin(async (sql) => {
|
await db.begin(async (sql) => {
|
||||||
await sql`insert into wynn_guild_info
|
await sql`insert into wynn_guild_info
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { container, T_PG } from "#/di"
|
import { c } from "#/di"
|
||||||
import { WApi } from "#/lib/wapi"
|
import { WApi } from "#/lib/wynn/wapi"
|
||||||
|
import { PG } from "#/services/pg"
|
||||||
import { log } from "@temporalio/activity"
|
import { log } from "@temporalio/activity"
|
||||||
import { type } from "arktype"
|
import { type } from "arktype"
|
||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
@ -66,7 +67,7 @@ export const scrape_online_players = async()=>{
|
|||||||
}).assert(raw.data)
|
}).assert(raw.data)
|
||||||
|
|
||||||
|
|
||||||
const sql = container.get(T_PG)
|
const { sql } = await c.getAsync(PG)
|
||||||
|
|
||||||
for(const [playerName, server] of Object.entries(onlineList.players)){
|
for(const [playerName, server] of Object.entries(onlineList.players)){
|
||||||
// we do this optimistically without a tx, because temporal will probably handle
|
// we do this optimistically without a tx, because temporal will probably handle
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import {bot} from "#/bot"
|
import {bot} from "#/bot"
|
||||||
import { ActivityTypes, ApplicationCommandOptionTypes, InteractionTypes } from "discordeno"
|
import { ActivityTypes, ApplicationCommandOptionTypes, InteractionTypes } from "discordeno"
|
||||||
import { InteractionHandler, MuxHandler, SlashHandler } from "./types"
|
import { InteractionHandler, MuxHandler, SlashHandler } from "./types"
|
||||||
import { root } from "./slash_commands"
|
import { SlashCommandHandler } from "./slash_commands"
|
||||||
import { uuid4 } from "@temporalio/workflow"
|
import { uuid4 } from "@temporalio/workflow"
|
||||||
|
import { c } from "#/di"
|
||||||
|
|
||||||
|
|
||||||
export const slashHandler: InteractionHandler = async (interaction) => {
|
export const slashHandler: InteractionHandler = async (interaction) => {
|
||||||
@ -21,7 +22,7 @@ export const slashHandler: InteractionHandler = async (interaction) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let rootHandler: SlashHandler = root
|
const rootHandler = (await c.getAsync(SlashCommandHandler)).root()
|
||||||
|
|
||||||
let cur: SlashHandler | MuxHandler<any> = rootHandler
|
let cur: SlashHandler | MuxHandler<any> = rootHandler
|
||||||
for(let i = 0; i < commandPath.length; i++) {
|
for(let i = 0; i < commandPath.length; i++) {
|
45
ts/src/bot/botevent/slash_commands.ts
Normal file
45
ts/src/bot/botevent/slash_commands.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { formGuildLeaderboardMessage, formGuildOnlineMessage } from "#/bot/common/guild"
|
||||||
|
import { WYNN_GUILD_ID } from "#/constants"
|
||||||
|
import { inject, injectable } from "@needle-di/core"
|
||||||
|
import { SlashHandler } from "./types"
|
||||||
|
import { PG } from "#/services/pg"
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class SlashCommandHandler {
|
||||||
|
constructor(
|
||||||
|
public readonly db = inject(PG)
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
root(): SlashHandler {
|
||||||
|
return {
|
||||||
|
guild: {
|
||||||
|
info: async (interaction) => {
|
||||||
|
interaction.respond("TODO: guild info")
|
||||||
|
},
|
||||||
|
online: async (interaction) => {
|
||||||
|
const msg = await formGuildOnlineMessage(
|
||||||
|
WYNN_GUILD_ID,
|
||||||
|
this.db.sql,
|
||||||
|
)
|
||||||
|
await interaction.respond(msg, {
|
||||||
|
withResponse: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
leaderboard: async (interaction) => {
|
||||||
|
const leaderboard = await formGuildLeaderboardMessage(
|
||||||
|
WYNN_GUILD_ID,
|
||||||
|
this.db.sql,
|
||||||
|
)
|
||||||
|
await interaction.respond(leaderboard, {
|
||||||
|
withResponse: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
set_wynn_guild: async (interaction) => {
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { Sql } from "postgres";
|
import { Sql } from "postgres";
|
||||||
import { CreateMessageOptions, Embed, InteractionCallbackOptions } from "discordeno"
|
import { CreateMessageOptions, Embed, InteractionCallbackOptions } from "discordeno"
|
||||||
import {type} from "arktype"
|
import {type} from "arktype"
|
||||||
import { TabWriter } from "#/lib/tabwriter"
|
import { TabWriter } from "#/lib/util/tabwriter"
|
||||||
import * as md from 'ts-markdown-builder';
|
import * as md from 'ts-markdown-builder';
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,11 +18,36 @@ const intents = [
|
|||||||
Intents.Guilds ,
|
Intents.Guilds ,
|
||||||
Intents.GuildInvites ,
|
Intents.GuildInvites ,
|
||||||
Intents.GuildMessages,
|
Intents.GuildMessages,
|
||||||
]
|
] as const
|
||||||
|
|
||||||
export const bot = createBot({
|
export const createBotWithToken = (token: string) => createBot({
|
||||||
intents: intents.reduce((acc, curr) => acc | curr, Intents.Guilds),
|
intents: intents.reduce((acc, curr) => acc | curr, Intents.Guilds),
|
||||||
token: config.DISCORD_TOKEN,
|
token: token,
|
||||||
|
desiredProperties: {
|
||||||
|
interaction: {
|
||||||
|
id: true,
|
||||||
|
data: true,
|
||||||
|
type: true,
|
||||||
|
token: true,
|
||||||
|
message: true,
|
||||||
|
channelId: true,
|
||||||
|
channel: true,
|
||||||
|
guildId: true,
|
||||||
|
guild: true,
|
||||||
|
user: true,
|
||||||
|
member: true,
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
id: true,
|
||||||
|
member: true,
|
||||||
|
guildId: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export const bot = createBot({
|
||||||
|
intents: intents.reduce((acc, curr) => acc | curr, Intents.Guilds),
|
||||||
|
token: config.DISCORD_TOKEN || "",
|
||||||
desiredProperties: {
|
desiredProperties: {
|
||||||
interaction: {
|
interaction: {
|
||||||
id: true,
|
id: true,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { container } from "#/di";
|
import { c } from "#/di";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
import { formGuildLeaderboardMessage, formGuildOnlineMessage } from "#/bot/common/guild"
|
|
||||||
import { WYNN_GUILD_ID } from "#/constants"
|
|
||||||
import { container, T_PG } from "#/di"
|
|
||||||
import { SlashHandler } from "./types"
|
|
||||||
|
|
||||||
export const root: SlashHandler = {
|
|
||||||
guild: {
|
|
||||||
info: async (interaction) => {
|
|
||||||
interaction.respond("TODO: guild info")
|
|
||||||
},
|
|
||||||
online: async (interaction) => {
|
|
||||||
const db = container.get(T_PG)
|
|
||||||
const msg = await formGuildOnlineMessage(
|
|
||||||
WYNN_GUILD_ID,
|
|
||||||
db,
|
|
||||||
)
|
|
||||||
await interaction.respond(msg, {
|
|
||||||
withResponse: true,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
leaderboard: async (interaction) => {
|
|
||||||
const db = container.get(T_PG)
|
|
||||||
const leaderboard = await formGuildLeaderboardMessage(
|
|
||||||
WYNN_GUILD_ID,
|
|
||||||
db,
|
|
||||||
)
|
|
||||||
await interaction.respond(leaderboard, {
|
|
||||||
withResponse: true,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
admin: {
|
|
||||||
set_wynn_guild: async (interaction) => {
|
|
||||||
const db = container.get(T_PG)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
90
ts/src/cmd/bot.js
Normal file
90
ts/src/cmd/bot.js
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
"use strict";
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = function (d, b) {
|
||||||
|
extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||||
|
return extendStatics(d, b);
|
||||||
|
};
|
||||||
|
return function (d, b) {
|
||||||
|
if (typeof b !== "function" && b !== null)
|
||||||
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
||||||
|
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||||
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
|
function step(op) {
|
||||||
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
|
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||||||
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
|
switch (op[0]) {
|
||||||
|
case 0: case 1: t = op; break;
|
||||||
|
case 4: _.label++; return { value: op[1], done: false };
|
||||||
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||||
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||||
|
default:
|
||||||
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||||
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||||
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||||
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||||
|
if (t[2]) _.ops.pop();
|
||||||
|
_.trys.pop(); continue;
|
||||||
|
}
|
||||||
|
op = body.call(thisArg, _);
|
||||||
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||||
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.BotCommand = void 0;
|
||||||
|
var clipanion_1 = require("clipanion");
|
||||||
|
var BotCommands = require("#/slashcommands");
|
||||||
|
// di
|
||||||
|
require("#/services/pg");
|
||||||
|
var constants_1 = require("#/constants");
|
||||||
|
var bot_1 = require("#/bot");
|
||||||
|
var handler_1 = require("#/bot/botevent/handler");
|
||||||
|
var BotCommand = /** @class */ (function (_super) {
|
||||||
|
__extends(BotCommand, _super);
|
||||||
|
function BotCommand() {
|
||||||
|
return _super !== null && _super.apply(this, arguments) || this;
|
||||||
|
}
|
||||||
|
BotCommand.prototype.execute = function () {
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
bot_1.bot.events = handler_1.events;
|
||||||
|
console.log('registring slash commands');
|
||||||
|
return [4 /*yield*/, bot_1.bot.rest.upsertGuildApplicationCommands(constants_1.DISCORD_GUILD_ID, Object.values(BotCommands))];
|
||||||
|
case 1:
|
||||||
|
_a.sent();
|
||||||
|
console.log('connecting bot to gateway');
|
||||||
|
return [4 /*yield*/, bot_1.bot.start()];
|
||||||
|
case 2:
|
||||||
|
_a.sent();
|
||||||
|
console.log('bot connected');
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
BotCommand.paths = [['bot']];
|
||||||
|
return BotCommand;
|
||||||
|
}(clipanion_1.Command));
|
||||||
|
exports.BotCommand = BotCommand;
|
@ -6,8 +6,7 @@ import * as BotCommands from "#/slashcommands";
|
|||||||
import "#/services/pg"
|
import "#/services/pg"
|
||||||
import { DISCORD_GUILD_ID } from '#/constants';
|
import { DISCORD_GUILD_ID } from '#/constants';
|
||||||
import { bot } from '#/bot';
|
import { bot } from '#/bot';
|
||||||
import { events } from '#/botevent';
|
import { events } from '#/bot/botevent/handler';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export class BotCommand extends Command {
|
export class BotCommand extends Command {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Command } from 'clipanion';
|
import { Command } from 'clipanion';
|
||||||
|
|
||||||
import { container, T_PG } from '#/di';
|
import { c } from '#/di';
|
||||||
import { runMigrations } from '#/services/pg/migrations';
|
import { runMigrations } from '#/services/pg/migrations';
|
||||||
|
|
||||||
// di
|
// di
|
||||||
@ -13,6 +13,7 @@ import * as activities from '../activities';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { Client, ScheduleNotFoundError, ScheduleOptions, ScheduleOverlapPolicy } from '@temporalio/client';
|
import { Client, ScheduleNotFoundError, ScheduleOptions, ScheduleOverlapPolicy } from '@temporalio/client';
|
||||||
import { workflowSyncAllGuilds, workflowSyncGuilds, workflowSyncOnline } from '#/workflows';
|
import { workflowSyncAllGuilds, workflowSyncGuilds, workflowSyncOnline } from '#/workflows';
|
||||||
|
import { PG } from '#/services/pg';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -88,10 +89,11 @@ const addSchedules = async (c: Client) => {
|
|||||||
export class WorkerCommand extends Command {
|
export class WorkerCommand extends Command {
|
||||||
static paths = [['worker']];
|
static paths = [['worker']];
|
||||||
async execute() {
|
async execute() {
|
||||||
const pg = container.get(T_PG);
|
const { db } = await c.getAsync(PG);
|
||||||
await runMigrations(pg);
|
|
||||||
|
|
||||||
const client = await container.getAsync(Client);
|
await runMigrations(db);
|
||||||
|
|
||||||
|
const client = await c.getAsync(Client);
|
||||||
// schedules
|
// schedules
|
||||||
await addSchedules(client);
|
await addSchedules(client);
|
||||||
|
|
||||||
@ -119,10 +121,8 @@ export class WorkerCommand extends Command {
|
|||||||
await worker.run();
|
await worker.run();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log("worked.run exited");
|
console.log("worked.run exited");
|
||||||
await pg.end();
|
await db.end();
|
||||||
await connection.close();
|
await connection.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { Command } from 'clipanion';
|
|
||||||
|
|
||||||
import { container, T_PG } from '#/di';
|
|
||||||
import { runMigrations } from '#/services/pg/migrations';
|
|
||||||
|
|
||||||
// di
|
|
||||||
import "#/services/pg"
|
|
||||||
|
|
||||||
|
|
||||||
export const WynnCommands = [
|
|
||||||
class extends Command {
|
|
||||||
static paths = [['wynn', 'refetch']];
|
|
||||||
|
|
||||||
async execute() {
|
|
||||||
const pg = container.get(T_PG);
|
|
||||||
await runMigrations(pg);
|
|
||||||
await pg.end()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
@ -4,7 +4,7 @@ import {config as dotenvConfig} from 'dotenv';
|
|||||||
dotenvConfig();
|
dotenvConfig();
|
||||||
|
|
||||||
const schemaConfig = {
|
const schemaConfig = {
|
||||||
DISCORD_TOKEN: z.string(),
|
DISCORD_TOKEN: z.string().optional(),
|
||||||
|
|
||||||
TEMPORAL_HOSTPORT: z.string().default('localhost:7233'),
|
TEMPORAL_HOSTPORT: z.string().default('localhost:7233'),
|
||||||
TEMPORAL_NAMESPACE: z.string().default('default'),
|
TEMPORAL_NAMESPACE: z.string().default('default'),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Container, InjectionToken } from "@needle-di/core";
|
import { Container, InjectionToken } from "@needle-di/core";
|
||||||
import { Sql } from "postgres";
|
import { Sql } from "postgres";
|
||||||
|
|
||||||
export const container = new Container();
|
export const c = new Container();
|
||||||
export const T_PG = new InjectionToken<Sql>("T_PG")
|
export const T_PG = new InjectionToken<Sql>("T_PG")
|
||||||
|
9
ts/src/main.js
Normal file
9
ts/src/main.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
var clipanion_1 = require("clipanion");
|
||||||
|
var worker_1 = require("#/cmd/worker");
|
||||||
|
var bot_1 = require("#/cmd/bot");
|
||||||
|
(0, clipanion_1.runExit)([
|
||||||
|
worker_1.WorkerCommand,
|
||||||
|
bot_1.BotCommand,
|
||||||
|
]);
|
@ -1,12 +1,10 @@
|
|||||||
import { runExit } from "clipanion";
|
import { runExit } from "clipanion";
|
||||||
|
|
||||||
import { WorkerCommand } from "#/cmd/worker";
|
import { WorkerCommand } from "#/cmd/worker";
|
||||||
import { WynnCommands } from "#/cmd/wynn";
|
import { BotCommand } from "#/cmd/bot";
|
||||||
import { BotCommand } from "./cmd/bot";
|
|
||||||
|
|
||||||
|
|
||||||
runExit([
|
runExit([
|
||||||
WorkerCommand,
|
WorkerCommand,
|
||||||
BotCommand,
|
BotCommand,
|
||||||
...WynnCommands,
|
|
||||||
])
|
])
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
import { config } from "#/config";
|
import { config } from "#/config";
|
||||||
import { container, T_PG } from "#/di";
|
import { injectable } from "@needle-di/core";
|
||||||
import postgres from "postgres";
|
import postgres, { Sql } from "postgres";
|
||||||
|
|
||||||
container.bind({
|
@injectable()
|
||||||
provide: T_PG,
|
export class PG {
|
||||||
useFactory: () => {
|
readonly db: Sql;
|
||||||
|
get sql() {
|
||||||
|
return this.db
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
const opts = {
|
const opts = {
|
||||||
onnotice: () => {},
|
onnotice: () => {},
|
||||||
}
|
}
|
||||||
|
let db: Sql;
|
||||||
if(config.PG_URL) {
|
if(config.PG_URL) {
|
||||||
return postgres(config.PG_URL, opts);
|
db = postgres(config.PG_URL, opts);
|
||||||
}
|
}else {
|
||||||
return postgres({
|
db = postgres({
|
||||||
host: config.PG_HOST,
|
host: config.PG_HOST,
|
||||||
port: config.PG_PORT,
|
port: config.PG_PORT,
|
||||||
user: config.PG_USER,
|
user: config.PG_USER,
|
||||||
@ -20,5 +26,8 @@ container.bind({
|
|||||||
ssl: (config.PG_SSLMODE as any) || 'prefer',
|
ssl: (config.PG_SSLMODE as any) || 'prefer',
|
||||||
...opts,
|
...opts,
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
});
|
this.db = db
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { config } from "#/config";
|
import { config } from "#/config";
|
||||||
import { container } from "#/di";
|
import { c } from "#/di";
|
||||||
import { Client, Connection} from '@temporalio/client';
|
import { Client, Connection} from '@temporalio/client';
|
||||||
|
|
||||||
container.bind({
|
c.bind({
|
||||||
provide: Client,
|
provide: Client,
|
||||||
async: true,
|
async: true,
|
||||||
useFactory: async () => {
|
useFactory: async () => {
|
||||||
|
692
ts/yarn.lock
692
ts/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user