@helyx/bot 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -28
- package/README.md +65 -11
- package/dist/cloud-connector.d.ts +11 -4
- package/dist/cloud-connector.js +52 -15
- package/dist/cloud-control-dispatcher.d.ts +8 -3
- package/dist/cloud-control-dispatcher.js +62 -4
- package/dist/control-errors.d.ts +4 -0
- package/dist/control-errors.js +8 -0
- package/dist/control-server-schemas.d.ts +84 -0
- package/dist/control-server-schemas.js +101 -0
- package/dist/control-server.d.ts +21 -7
- package/dist/control-server.js +88 -132
- package/dist/core-retention.d.ts +26 -0
- package/dist/core-retention.js +49 -0
- package/dist/creator-guild-join-service.d.ts +25 -0
- package/dist/creator-guild-join-service.js +218 -0
- package/dist/creator-invite-service.d.ts +37 -0
- package/dist/creator-invite-service.js +686 -0
- package/dist/creator-onboarding-control.d.ts +12 -0
- package/dist/creator-onboarding-control.js +65 -0
- package/dist/creator-onboarding-platform.d.ts +20 -0
- package/dist/creator-onboarding-platform.js +58 -0
- package/dist/dashboard-action-control.d.ts +2 -2
- package/dist/dashboard-action-control.js +2 -3
- package/dist/database-bootstrap.d.ts +36 -0
- package/dist/database-bootstrap.js +101 -0
- package/dist/developer-operations-module.d.ts +1 -0
- package/dist/developer-operations-module.js +34 -16
- package/dist/discord-owned-message-service.d.ts +1 -0
- package/dist/discord-owned-message-service.js +3 -0
- package/dist/guild-command-read-service.d.ts +8 -3
- package/dist/guild-command-read-service.js +14 -7
- package/dist/guild-command-release.d.ts +15 -8
- package/dist/guild-command-release.js +10 -3
- package/dist/guild-command-worker.d.ts +17 -4
- package/dist/guild-command-worker.js +17 -6
- package/dist/guilds.d.ts +24 -3
- package/dist/guilds.js +185 -64
- package/dist/hosted-server-moderation.d.ts +2 -2
- package/dist/hosted-server-moderation.js +10 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +200 -82
- package/dist/interactions.js +16 -3
- package/dist/module-configuration.d.ts +1 -1
- package/dist/module-configuration.js +5 -2
- package/dist/module-logging.d.ts +8 -3
- package/dist/module-logging.js +13 -7
- package/dist/modules.d.ts +1 -0
- package/dist/modules.js +8 -1
- package/dist/mysql-runtime-persistence.d.ts +46 -0
- package/dist/mysql-runtime-persistence.js +91 -0
- package/dist/oauth-module.js +2 -2
- package/dist/oauth-service.d.ts +7 -0
- package/dist/oauth-service.js +3 -0
- package/dist/scheduled-task-runner.d.ts +9 -85
- package/dist/scheduled-task-runner.js +1 -1
- package/dist/shard-contracts.d.ts +135 -0
- package/dist/shard-contracts.js +13 -1
- package/dist/shard-router.d.ts +2 -1
- package/dist/shard-router.js +7 -0
- package/dist/shard-supervisor.js +43 -9
- package/dist/shard-worker.d.ts +5 -2
- package/dist/shard-worker.js +41 -5
- package/dist/supervisor-cloud-directory.d.ts +9 -3
- package/dist/supervisor-cloud-directory.js +8 -12
- package/dist/trivia-data-provider.d.ts +11 -0
- package/dist/trivia-data-provider.js +46 -26
- package/dist/verification-service.d.ts +2 -2
- package/dist/verification-service.js +6 -3
- package/documentation/README.md +5 -3
- package/documentation/examples/.env.example +15 -11
- package/documentation/guides/getting-started.md +29 -12
- package/documentation/guides/privacy-and-support.md +6 -5
- package/documentation/guides/self-hosting.md +16 -11
- package/documentation/modules/auto-moderation.md +7 -5
- package/documentation/modules/building-a-module.md +48 -2
- package/documentation/modules/moderation.md +5 -5
- package/documentation/modules/publishing-a-module.md +6 -4
- package/documentation/modules/testing-a-module.md +39 -4
- package/documentation/reference/environment.md +43 -9
- package/documentation/runbooks/backup-and-recovery.md +26 -7
- package/documentation/runbooks/installation-and-upgrades.md +97 -27
- package/package.json +20 -16
package/dist/modules.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ interface LoadedDefinition {
|
|
|
10
10
|
export interface ConfiguredModulePackage extends LoadedDefinition {
|
|
11
11
|
packageRoot: string;
|
|
12
12
|
}
|
|
13
|
+
export declare function assertConfiguredModuleDatabaseCompatibility(modules: readonly ConfiguredModulePackage[], engine: BotEnvironment["DATABASE_ENGINE"]): void;
|
|
13
14
|
export declare const secureRandomSelectionWorkerKeyName = "HELYX_INTERNAL_SECURE_RANDOM_SELECTION_KEY";
|
|
14
15
|
interface PlatformServiceEnvironment extends Pick<BotEnvironment, "HELYX_DATA_ENCRYPTION_KEY"> {
|
|
15
16
|
HELYX_RUNTIME_PROFILE?: BotEnvironment["HELYX_RUNTIME_PROFILE"];
|
package/dist/modules.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import { orderModuleManifests, parseModuleManifest, } from "@helyx/module-manifest";
|
|
1
|
+
import { getModuleDatabaseEngines, orderModuleManifests, parseModuleManifest, } from "@helyx/module-manifest";
|
|
2
2
|
import { NEXUS_COMMAND_SPECS, NEXUS_ROOT_MODULE_ID, sharedCommandFamilySpec, sharedCommandPathSpec, } from "@helyx/sdk";
|
|
3
3
|
import { createHmac } from "node:crypto";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import { dirname } from "node:path";
|
|
7
7
|
import { assertCommandPathContract } from "./command-path-contract.js";
|
|
8
|
+
export function assertConfiguredModuleDatabaseCompatibility(modules, engine) {
|
|
9
|
+
for (const { definition } of modules) {
|
|
10
|
+
if (!getModuleDatabaseEngines(definition.manifest).includes(engine)) {
|
|
11
|
+
throw new Error(`Module ${definition.manifest.id} does not support DATABASE_ENGINE=${engine}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
8
15
|
const officialModulePackage = /^@helyx\/module-[a-z0-9][a-z0-9-]*$/u;
|
|
9
16
|
const giveawaysModuleId = "helyx.giveaways";
|
|
10
17
|
const inviteTrackingModuleId = "helyx.invite-tracking";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BotEnvironment } from "@helyx/config";
|
|
2
|
+
import type { GuildCommandRepository as MysqlGuildCommandRepository, InstallationRepository as MysqlInstallationRepository, MysqlPool, RuntimeStateRepository as MysqlRuntimeStateRepository } from "@helyx/database-mysql";
|
|
3
|
+
import type { MysqlMemberRoleGrantOwnershipStore, createMysqlPlatformServices } from "@helyx/platform";
|
|
4
|
+
import type { ModuleDefinition } from "@helyx/sdk";
|
|
5
|
+
import { type BotDatabaseHandle } from "./database-bootstrap.js";
|
|
6
|
+
import type { CloudConnectorStore } from "./cloud-control-dispatcher.js";
|
|
7
|
+
import { type BotControlPersistence } from "./control-server.js";
|
|
8
|
+
import { type CoreRetentionRepositories } from "./core-retention.js";
|
|
9
|
+
import type { GuildCommandReadRepositories } from "./guild-command-read-service.js";
|
|
10
|
+
import type { GuildCommandWorkerRepositories } from "./guild-command-worker.js";
|
|
11
|
+
import { type GuildTrackingPersistence } from "./guilds.js";
|
|
12
|
+
import type { ModuleLoggingRepositories } from "./module-logging.js";
|
|
13
|
+
import type { ConfiguredModulePackage } from "./modules.js";
|
|
14
|
+
import type { ScheduledTaskRepositoryContract } from "./scheduled-task-runner.js";
|
|
15
|
+
type MysqlRuntimeEnvironment = Pick<BotEnvironment, "DATABASE_ENGINE" | "DATABASE_URL" | "DATABASE_SSL" | "HELYX_RUNTIME_PROFILE" | "HELYX_SHARD_MODE" | "HELYX_HOSTED_MODERATION_ENABLED" | "HELYX_VERIFICATION_ENABLED" | "HELYX_PRIVACY_ENABLED" | "HELYX_PRIVACY_EXECUTOR_DATABASE_URL" | "HELYX_OAUTH_ENABLED" | "HELYX_ECKO_TRANSPORT_SECRET" | "HELYX_SUPPORT_STAFF_CHANNEL_ID" | "STRIPE_ENVIRONMENT">;
|
|
16
|
+
export interface MysqlBotRuntimePersistence {
|
|
17
|
+
/** The adapter owns this single pool and closes it via database.close(). */
|
|
18
|
+
readonly database: BotDatabaseHandle<{
|
|
19
|
+
pool: MysqlPool;
|
|
20
|
+
}>;
|
|
21
|
+
readonly pool: MysqlPool;
|
|
22
|
+
readonly cloudConnector: CloudConnectorStore;
|
|
23
|
+
readonly guildTracking: GuildTrackingPersistence;
|
|
24
|
+
readonly control: BotControlPersistence;
|
|
25
|
+
readonly coreRetention: CoreRetentionRepositories;
|
|
26
|
+
readonly scheduledTasks: ScheduledTaskRepositoryContract;
|
|
27
|
+
readonly commandWorker: GuildCommandWorkerRepositories;
|
|
28
|
+
readonly commandRead: GuildCommandReadRepositories;
|
|
29
|
+
readonly commandRelease: {
|
|
30
|
+
installations: Pick<MysqlInstallationRepository, "listActiveGuilds">;
|
|
31
|
+
commands: Pick<MysqlGuildCommandRepository, "getState" | "schedule">;
|
|
32
|
+
runtime: Pick<MysqlRuntimeStateRepository, "get" | "compareAndSet">;
|
|
33
|
+
};
|
|
34
|
+
readonly logging: ModuleLoggingRepositories;
|
|
35
|
+
readonly memberRoleOwnership: MysqlMemberRoleGrantOwnershipStore;
|
|
36
|
+
readonly createPlatformServices: (modules: readonly ModuleDefinition[], options?: Parameters<typeof createMysqlPlatformServices>[2]) => ReturnType<typeof createMysqlPlatformServices>;
|
|
37
|
+
}
|
|
38
|
+
export interface OpenMysqlBotRuntimePersistenceInput {
|
|
39
|
+
readonly environment: MysqlRuntimeEnvironment;
|
|
40
|
+
readonly modulePackages: readonly ConfiguredModulePackage[];
|
|
41
|
+
readonly applicationName?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Connect, migrate, and compose ordinary self-host persistence from one pool. */
|
|
44
|
+
export declare function openMysqlBotRuntimePersistence(input: OpenMysqlBotRuntimePersistenceInput): Promise<MysqlBotRuntimePersistence>;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=mysql-runtime-persistence.d.ts.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { openBotDatabaseWithAdapter, } from "./database-bootstrap.js";
|
|
2
|
+
import { createMysqlBotControlPersistence, } from "./control-server.js";
|
|
3
|
+
import { createMysqlCoreRetentionRepositories, } from "./core-retention.js";
|
|
4
|
+
import { createMysqlGuildTrackingPersistence, } from "./guilds.js";
|
|
5
|
+
/** Connect, migrate, and compose ordinary self-host persistence from one pool. */
|
|
6
|
+
export async function openMysqlBotRuntimePersistence(input) {
|
|
7
|
+
assertMysqlRuntimeOptions(input.environment);
|
|
8
|
+
const mysql = await import("@helyx/database-mysql");
|
|
9
|
+
const adapter = mysql.createMysqlDatabaseAdapter({
|
|
10
|
+
repositories: (_executor, pool) => ({ pool }),
|
|
11
|
+
});
|
|
12
|
+
const database = await openBotDatabaseWithAdapter(input, adapter);
|
|
13
|
+
try {
|
|
14
|
+
const pool = database.session.repositories.pool;
|
|
15
|
+
const installations = new mysql.InstallationRepository(pool);
|
|
16
|
+
const commands = new mysql.GuildCommandRepository(pool);
|
|
17
|
+
const availability = new mysql.ModuleAvailabilityRepository(pool);
|
|
18
|
+
const runtime = new mysql.RuntimeStateRepository(pool);
|
|
19
|
+
const [guildTracking, control, coreRetention, platform] = await Promise.all([
|
|
20
|
+
createMysqlGuildTrackingPersistence(pool),
|
|
21
|
+
createMysqlBotControlPersistence(pool),
|
|
22
|
+
createMysqlCoreRetentionRepositories(pool),
|
|
23
|
+
import("@helyx/platform"),
|
|
24
|
+
]);
|
|
25
|
+
return {
|
|
26
|
+
database,
|
|
27
|
+
pool,
|
|
28
|
+
cloudConnector: new mysql.CloudConnectorRepository(pool),
|
|
29
|
+
guildTracking,
|
|
30
|
+
control,
|
|
31
|
+
coreRetention,
|
|
32
|
+
scheduledTasks: new mysql.ScheduledTaskRepository(pool),
|
|
33
|
+
commandWorker: {
|
|
34
|
+
commands,
|
|
35
|
+
installations,
|
|
36
|
+
availability,
|
|
37
|
+
},
|
|
38
|
+
commandRead: { commands, installations },
|
|
39
|
+
commandRelease: { commands, installations, runtime },
|
|
40
|
+
logging: {
|
|
41
|
+
installations,
|
|
42
|
+
configuration: new mysql.ModuleConfigurationRepository(pool),
|
|
43
|
+
policies: new mysql.ModuleLoggingPolicyRepository(pool),
|
|
44
|
+
},
|
|
45
|
+
memberRoleOwnership: new platform.MysqlMemberRoleGrantOwnershipStore(pool),
|
|
46
|
+
createPlatformServices: (modules, options) => platform.createMysqlPlatformServices(pool, modules, {
|
|
47
|
+
...options,
|
|
48
|
+
runtimeProfile: "self-hosted",
|
|
49
|
+
}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
await database.close().catch(() => undefined);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function assertMysqlRuntimeOptions(environment) {
|
|
58
|
+
if (environment.DATABASE_ENGINE !== "mysql") {
|
|
59
|
+
throw new Error("MySQL bot runtime requires DATABASE_ENGINE=mysql");
|
|
60
|
+
}
|
|
61
|
+
if (environment.HELYX_RUNTIME_PROFILE !== "self-hosted") {
|
|
62
|
+
throw new Error("MySQL bot runtime requires HELYX_RUNTIME_PROFILE=self-hosted");
|
|
63
|
+
}
|
|
64
|
+
if (environment.HELYX_SHARD_MODE !== "off") {
|
|
65
|
+
throw new Error("MySQL bot runtime does not support shard mode");
|
|
66
|
+
}
|
|
67
|
+
const unsupported = [
|
|
68
|
+
[
|
|
69
|
+
"HELYX_HOSTED_MODERATION_ENABLED",
|
|
70
|
+
environment.HELYX_HOSTED_MODERATION_ENABLED,
|
|
71
|
+
],
|
|
72
|
+
["HELYX_VERIFICATION_ENABLED", environment.HELYX_VERIFICATION_ENABLED],
|
|
73
|
+
["HELYX_PRIVACY_ENABLED", environment.HELYX_PRIVACY_ENABLED],
|
|
74
|
+
[
|
|
75
|
+
"HELYX_PRIVACY_EXECUTOR_DATABASE_URL",
|
|
76
|
+
environment.HELYX_PRIVACY_EXECUTOR_DATABASE_URL,
|
|
77
|
+
],
|
|
78
|
+
["HELYX_OAUTH_ENABLED", environment.HELYX_OAUTH_ENABLED],
|
|
79
|
+
["HELYX_ECKO_TRANSPORT_SECRET", environment.HELYX_ECKO_TRANSPORT_SECRET],
|
|
80
|
+
[
|
|
81
|
+
"HELYX_SUPPORT_STAFF_CHANNEL_ID",
|
|
82
|
+
environment.HELYX_SUPPORT_STAFF_CHANNEL_ID,
|
|
83
|
+
],
|
|
84
|
+
["STRIPE_ENVIRONMENT", environment.STRIPE_ENVIRONMENT],
|
|
85
|
+
];
|
|
86
|
+
for (const [name, value] of unsupported) {
|
|
87
|
+
if (value)
|
|
88
|
+
throw new Error(`MySQL bot runtime does not support ${name}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=mysql-runtime-persistence.js.map
|
package/dist/oauth-module.js
CHANGED
|
@@ -204,7 +204,7 @@ export function createOAuthModule() {
|
|
|
204
204
|
text: [
|
|
205
205
|
{
|
|
206
206
|
content: result.outcome === "processing"
|
|
207
|
-
? `${providerName(result.provider)} access removal is
|
|
207
|
+
? `${providerName(result.provider)} access removal is in progress. Helyx is handling local cleanup automatically. Provider-side revocation is not confirmed yet, so you can also remove Helyx from your ${providerName(result.provider)} connected-app settings. Run \`/helyx connections\` to check whether local access remains.`
|
|
208
208
|
: result.outcome === "cleanup_pending"
|
|
209
209
|
? `${providerName(result.provider)} credentials were deleted. Helyx is still removing related roles and connection records.`
|
|
210
210
|
: result.providerRevocation === "completed"
|
|
@@ -235,7 +235,7 @@ function unavailable() {
|
|
|
235
235
|
componentsV2: {
|
|
236
236
|
text: [
|
|
237
237
|
{
|
|
238
|
-
content: "
|
|
238
|
+
content: "Helyx could not confirm the final result. The removal may still be finishing automatically. Run /helyx connections to check before trying again.",
|
|
239
239
|
},
|
|
240
240
|
],
|
|
241
241
|
},
|
package/dist/oauth-service.d.ts
CHANGED
|
@@ -2,6 +2,13 @@ import type { OAuthConnectionSummary, OAuthConnectionIdentity, OAuthEligibilityR
|
|
|
2
2
|
export declare class HttpOAuthService implements OAuthService {
|
|
3
3
|
#private;
|
|
4
4
|
private readonly internalSecret;
|
|
5
|
+
resolveCreatorIdentity(input: {
|
|
6
|
+
provider: "twitch";
|
|
7
|
+
login: string;
|
|
8
|
+
}): Promise<{
|
|
9
|
+
userId: string;
|
|
10
|
+
login: string;
|
|
11
|
+
}>;
|
|
5
12
|
constructor(baseUrl: string, internalSecret: string);
|
|
6
13
|
listConnections(input: {
|
|
7
14
|
discordUserId: string;
|
package/dist/oauth-service.js
CHANGED
|
@@ -1,91 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ScheduledTaskRepository, type ScheduledTaskDefinition, type SchedulerHealth } from "@helyx/database";
|
|
2
2
|
import { type Logger, type ModuleDefinition, type ModuleScheduledTaskExecution, type ScheduledTaskExecutionResult, type ServiceAccess } from "@helyx/sdk";
|
|
3
3
|
import type { Pool } from "pg";
|
|
4
4
|
export interface ScheduledTaskRoute {
|
|
5
5
|
(task: ModuleScheduledTaskExecution, signal: AbortSignal): Promise<ScheduledTaskExecutionResult>;
|
|
6
6
|
}
|
|
7
|
-
|
|
8
|
-
claimDue(input: {
|
|
9
|
-
workerId: string;
|
|
10
|
-
leaseMs: number;
|
|
11
|
-
limit?: number;
|
|
12
|
-
eligible?: readonly ScheduledTaskDefinition[];
|
|
13
|
-
}): Promise<ScheduledTaskRecord[]>;
|
|
14
|
-
claimCoalesced(input: {
|
|
15
|
-
workerId: string;
|
|
16
|
-
leaseMs: number;
|
|
17
|
-
limit?: number;
|
|
18
|
-
eligible?: readonly ScheduledTaskDefinition[];
|
|
19
|
-
}): Promise<CoalescedTaskRecord[]>;
|
|
20
|
-
heartbeat(input: {
|
|
21
|
-
taskId: string;
|
|
22
|
-
workerId: string;
|
|
23
|
-
leaseGeneration: number;
|
|
24
|
-
leaseMs: number;
|
|
25
|
-
}): Promise<boolean>;
|
|
26
|
-
heartbeatCoalesced(input: {
|
|
27
|
-
laneId: string;
|
|
28
|
-
workerId: string;
|
|
29
|
-
leaseGeneration: number;
|
|
30
|
-
claimedGeneration: number;
|
|
31
|
-
leaseMs: number;
|
|
32
|
-
}): Promise<boolean>;
|
|
33
|
-
complete(input: {
|
|
34
|
-
taskId: string;
|
|
35
|
-
workerId: string;
|
|
36
|
-
leaseGeneration: number;
|
|
37
|
-
}): Promise<boolean>;
|
|
38
|
-
completeCoalesced(input: {
|
|
39
|
-
laneId: string;
|
|
40
|
-
workerId: string;
|
|
41
|
-
leaseGeneration: number;
|
|
42
|
-
claimedGeneration: number;
|
|
43
|
-
}): Promise<boolean>;
|
|
44
|
-
defer(input: {
|
|
45
|
-
taskId: string;
|
|
46
|
-
workerId: string;
|
|
47
|
-
leaseGeneration: number;
|
|
48
|
-
delayMs: number;
|
|
49
|
-
safeCode: string;
|
|
50
|
-
}): Promise<boolean>;
|
|
51
|
-
deferCoalesced(input: {
|
|
52
|
-
laneId: string;
|
|
53
|
-
workerId: string;
|
|
54
|
-
leaseGeneration: number;
|
|
55
|
-
claimedGeneration: number;
|
|
56
|
-
delayMs: number;
|
|
57
|
-
safeCode: string;
|
|
58
|
-
}): Promise<boolean>;
|
|
59
|
-
retry(input: {
|
|
60
|
-
taskId: string;
|
|
61
|
-
workerId: string;
|
|
62
|
-
leaseGeneration: number;
|
|
63
|
-
delayMs: number;
|
|
64
|
-
safeCode: string;
|
|
65
|
-
}): Promise<boolean>;
|
|
66
|
-
retryCoalesced(input: {
|
|
67
|
-
laneId: string;
|
|
68
|
-
workerId: string;
|
|
69
|
-
leaseGeneration: number;
|
|
70
|
-
claimedGeneration: number;
|
|
71
|
-
delayMs: number;
|
|
72
|
-
safeCode: string;
|
|
73
|
-
}): Promise<boolean>;
|
|
74
|
-
markRequiresReview(input: {
|
|
75
|
-
taskId: string;
|
|
76
|
-
workerId: string;
|
|
77
|
-
leaseGeneration: number;
|
|
78
|
-
safeCode: string;
|
|
79
|
-
}): Promise<boolean>;
|
|
80
|
-
markCoalescedRequiresReview(input: {
|
|
81
|
-
laneId: string;
|
|
82
|
-
workerId: string;
|
|
83
|
-
leaseGeneration: number;
|
|
84
|
-
claimedGeneration: number;
|
|
85
|
-
safeCode: string;
|
|
86
|
-
}): Promise<boolean>;
|
|
87
|
-
getHealth(sampleLimit?: number): Promise<SchedulerHealth>;
|
|
88
|
-
}
|
|
7
|
+
export type ScheduledTaskRepositoryContract = Pick<ScheduledTaskRepository, "claimDue" | "claimCoalesced" | "heartbeat" | "heartbeatCoalesced" | "complete" | "completeCoalesced" | "defer" | "deferCoalesced" | "retry" | "retryCoalesced" | "markRequiresReview" | "markCoalescedRequiresReview" | "getHealth">;
|
|
89
8
|
export declare class ScheduledTaskRunner {
|
|
90
9
|
#private;
|
|
91
10
|
constructor(input: {
|
|
@@ -107,12 +26,17 @@ export declare class ScheduledTaskRunner {
|
|
|
107
26
|
getHealth(): Promise<SchedulerHealth>;
|
|
108
27
|
}
|
|
109
28
|
export declare function createScheduledTaskRunner(input: {
|
|
110
|
-
database: Pool;
|
|
111
29
|
modules: readonly ModuleDefinition[];
|
|
112
30
|
route: ScheduledTaskRoute;
|
|
113
31
|
logger: Logger;
|
|
114
32
|
workerId?: string;
|
|
115
|
-
}
|
|
33
|
+
} & ({
|
|
34
|
+
database: Pool;
|
|
35
|
+
repository?: never;
|
|
36
|
+
} | {
|
|
37
|
+
repository: ScheduledTaskRepositoryContract;
|
|
38
|
+
database?: never;
|
|
39
|
+
})): ScheduledTaskRunner;
|
|
116
40
|
export declare function schedulerOperationalHealth(health: SchedulerHealth): {
|
|
117
41
|
status: "available";
|
|
118
42
|
oneShot: ReturnType<typeof mapSchedulerWorkHealth>;
|
|
@@ -271,7 +271,7 @@ export class ScheduledTaskRunner {
|
|
|
271
271
|
}
|
|
272
272
|
export function createScheduledTaskRunner(input) {
|
|
273
273
|
return new ScheduledTaskRunner({
|
|
274
|
-
repository: new ScheduledTaskRepository(input.database),
|
|
274
|
+
repository: input.repository ?? new ScheduledTaskRepository(input.database),
|
|
275
275
|
route: input.route,
|
|
276
276
|
logger: input.logger,
|
|
277
277
|
eligibleTasks: [
|
|
@@ -167,6 +167,51 @@ export declare const shardHealthSnapshotSchema: z.ZodObject<{
|
|
|
167
167
|
}, z.core.$strict>;
|
|
168
168
|
export type ShardHealthSnapshot = z.infer<typeof shardHealthSnapshotSchema>;
|
|
169
169
|
export declare const shardControlOperationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
170
|
+
kind: z.ZodLiteral<"creator.onboarding">;
|
|
171
|
+
guildId: z.ZodString;
|
|
172
|
+
input: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
173
|
+
action: z.ZodLiteral<"page">;
|
|
174
|
+
guildId: z.ZodString;
|
|
175
|
+
reference: z.ZodUUID;
|
|
176
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
177
|
+
action: z.ZodLiteral<"consumer">;
|
|
178
|
+
guildId: z.ZodString;
|
|
179
|
+
overviewId: z.ZodUUID;
|
|
180
|
+
reference: z.ZodOptional<z.ZodUUID>;
|
|
181
|
+
configurationRevision: z.ZodOptional<z.ZodNumber>;
|
|
182
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
183
|
+
guildId: z.ZodString;
|
|
184
|
+
reference: z.ZodUUID;
|
|
185
|
+
configurationRevision: z.ZodNumber;
|
|
186
|
+
memberUserId: z.ZodString;
|
|
187
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
188
|
+
action: z.ZodLiteral<"inspect">;
|
|
189
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
190
|
+
guildId: z.ZodString;
|
|
191
|
+
reference: z.ZodUUID;
|
|
192
|
+
configurationRevision: z.ZodNumber;
|
|
193
|
+
memberUserId: z.ZodString;
|
|
194
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
195
|
+
action: z.ZodLiteral<"check">;
|
|
196
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
197
|
+
guildId: z.ZodString;
|
|
198
|
+
reference: z.ZodUUID;
|
|
199
|
+
configurationRevision: z.ZodNumber;
|
|
200
|
+
memberUserId: z.ZodString;
|
|
201
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
202
|
+
action: z.ZodLiteral<"deliver">;
|
|
203
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
204
|
+
sessionId: z.ZodUUID;
|
|
205
|
+
authorisationReference: z.ZodString;
|
|
206
|
+
withTwitch: z.ZodBoolean;
|
|
207
|
+
guildId: z.ZodString;
|
|
208
|
+
reference: z.ZodUUID;
|
|
209
|
+
configurationRevision: z.ZodNumber;
|
|
210
|
+
memberUserId: z.ZodString;
|
|
211
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
212
|
+
action: z.ZodLiteral<"join">;
|
|
213
|
+
}, z.core.$strict>], "action">;
|
|
214
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
170
215
|
kind: z.ZodLiteral<"automod.enhanced.configuration.page">;
|
|
171
216
|
cursor: z.ZodOptional<z.ZodString>;
|
|
172
217
|
limit: z.ZodNumber;
|
|
@@ -578,6 +623,51 @@ export declare const shardControlRequestSchema: z.ZodObject<{
|
|
|
578
623
|
fencingToken: z.ZodNumber;
|
|
579
624
|
deadlineAt: z.ZodISODateTime;
|
|
580
625
|
operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
626
|
+
kind: z.ZodLiteral<"creator.onboarding">;
|
|
627
|
+
guildId: z.ZodString;
|
|
628
|
+
input: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
629
|
+
action: z.ZodLiteral<"page">;
|
|
630
|
+
guildId: z.ZodString;
|
|
631
|
+
reference: z.ZodUUID;
|
|
632
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
633
|
+
action: z.ZodLiteral<"consumer">;
|
|
634
|
+
guildId: z.ZodString;
|
|
635
|
+
overviewId: z.ZodUUID;
|
|
636
|
+
reference: z.ZodOptional<z.ZodUUID>;
|
|
637
|
+
configurationRevision: z.ZodOptional<z.ZodNumber>;
|
|
638
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
639
|
+
guildId: z.ZodString;
|
|
640
|
+
reference: z.ZodUUID;
|
|
641
|
+
configurationRevision: z.ZodNumber;
|
|
642
|
+
memberUserId: z.ZodString;
|
|
643
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
644
|
+
action: z.ZodLiteral<"inspect">;
|
|
645
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
646
|
+
guildId: z.ZodString;
|
|
647
|
+
reference: z.ZodUUID;
|
|
648
|
+
configurationRevision: z.ZodNumber;
|
|
649
|
+
memberUserId: z.ZodString;
|
|
650
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
651
|
+
action: z.ZodLiteral<"check">;
|
|
652
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
653
|
+
guildId: z.ZodString;
|
|
654
|
+
reference: z.ZodUUID;
|
|
655
|
+
configurationRevision: z.ZodNumber;
|
|
656
|
+
memberUserId: z.ZodString;
|
|
657
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
658
|
+
action: z.ZodLiteral<"deliver">;
|
|
659
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
660
|
+
sessionId: z.ZodUUID;
|
|
661
|
+
authorisationReference: z.ZodString;
|
|
662
|
+
withTwitch: z.ZodBoolean;
|
|
663
|
+
guildId: z.ZodString;
|
|
664
|
+
reference: z.ZodUUID;
|
|
665
|
+
configurationRevision: z.ZodNumber;
|
|
666
|
+
memberUserId: z.ZodString;
|
|
667
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
668
|
+
action: z.ZodLiteral<"join">;
|
|
669
|
+
}, z.core.$strict>], "action">;
|
|
670
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
581
671
|
kind: z.ZodLiteral<"automod.enhanced.configuration.page">;
|
|
582
672
|
cursor: z.ZodOptional<z.ZodString>;
|
|
583
673
|
limit: z.ZodNumber;
|
|
@@ -1494,6 +1584,51 @@ export declare const supervisorMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObje
|
|
|
1494
1584
|
fencingToken: z.ZodNumber;
|
|
1495
1585
|
deadlineAt: z.ZodISODateTime;
|
|
1496
1586
|
operation: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1587
|
+
kind: z.ZodLiteral<"creator.onboarding">;
|
|
1588
|
+
guildId: z.ZodString;
|
|
1589
|
+
input: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1590
|
+
action: z.ZodLiteral<"page">;
|
|
1591
|
+
guildId: z.ZodString;
|
|
1592
|
+
reference: z.ZodUUID;
|
|
1593
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1594
|
+
action: z.ZodLiteral<"consumer">;
|
|
1595
|
+
guildId: z.ZodString;
|
|
1596
|
+
overviewId: z.ZodUUID;
|
|
1597
|
+
reference: z.ZodOptional<z.ZodUUID>;
|
|
1598
|
+
configurationRevision: z.ZodOptional<z.ZodNumber>;
|
|
1599
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1600
|
+
guildId: z.ZodString;
|
|
1601
|
+
reference: z.ZodUUID;
|
|
1602
|
+
configurationRevision: z.ZodNumber;
|
|
1603
|
+
memberUserId: z.ZodString;
|
|
1604
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
1605
|
+
action: z.ZodLiteral<"inspect">;
|
|
1606
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1607
|
+
guildId: z.ZodString;
|
|
1608
|
+
reference: z.ZodUUID;
|
|
1609
|
+
configurationRevision: z.ZodNumber;
|
|
1610
|
+
memberUserId: z.ZodString;
|
|
1611
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
1612
|
+
action: z.ZodLiteral<"check">;
|
|
1613
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1614
|
+
guildId: z.ZodString;
|
|
1615
|
+
reference: z.ZodUUID;
|
|
1616
|
+
configurationRevision: z.ZodNumber;
|
|
1617
|
+
memberUserId: z.ZodString;
|
|
1618
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
1619
|
+
action: z.ZodLiteral<"deliver">;
|
|
1620
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1621
|
+
sessionId: z.ZodUUID;
|
|
1622
|
+
authorisationReference: z.ZodString;
|
|
1623
|
+
withTwitch: z.ZodBoolean;
|
|
1624
|
+
guildId: z.ZodString;
|
|
1625
|
+
reference: z.ZodUUID;
|
|
1626
|
+
configurationRevision: z.ZodNumber;
|
|
1627
|
+
memberUserId: z.ZodString;
|
|
1628
|
+
accountSlot: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>]>;
|
|
1629
|
+
action: z.ZodLiteral<"join">;
|
|
1630
|
+
}, z.core.$strict>], "action">;
|
|
1631
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1497
1632
|
kind: z.ZodLiteral<"automod.enhanced.configuration.page">;
|
|
1498
1633
|
cursor: z.ZodOptional<z.ZodString>;
|
|
1499
1634
|
limit: z.ZodNumber;
|
package/dist/shard-contracts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { CLOUD_MAX_RESOURCE_IMPORT_BYTES } from "@helyx/control-protocol";
|
|
2
|
+
import { CLOUD_MAX_RESOURCE_IMPORT_BYTES, creatorOnboardingRequestSchema, } from "@helyx/control-protocol";
|
|
3
3
|
import { AUTOMOD_SCANNER_LIMITS } from "@helyx/sdk";
|
|
4
4
|
import { signedAssessmentEnvelopeSchema } from "@helyx/verification-contracts";
|
|
5
5
|
export const SHARD_CONTRACT_VERSION = 1;
|
|
@@ -254,6 +254,14 @@ export const shardHealthSnapshotSchema = z
|
|
|
254
254
|
});
|
|
255
255
|
});
|
|
256
256
|
export const shardControlOperationSchema = z.discriminatedUnion("kind", [
|
|
257
|
+
z
|
|
258
|
+
.object({
|
|
259
|
+
kind: z.literal("creator.onboarding"),
|
|
260
|
+
guildId: snowflake,
|
|
261
|
+
input: creatorOnboardingRequestSchema,
|
|
262
|
+
})
|
|
263
|
+
.strict()
|
|
264
|
+
.refine((value) => value.guildId === value.input.guildId),
|
|
257
265
|
z
|
|
258
266
|
.object({
|
|
259
267
|
kind: z.literal("automod.enhanced.configuration.page"),
|
|
@@ -1273,6 +1281,10 @@ export async function executeShardControlOperation(handler, operation) {
|
|
|
1273
1281
|
? { actorAuthenticatedAt: operation.actorAuthenticatedAt }
|
|
1274
1282
|
: {}),
|
|
1275
1283
|
});
|
|
1284
|
+
case "creator.onboarding":
|
|
1285
|
+
if (!handler.creatorOnboarding)
|
|
1286
|
+
throw new Error("Creator onboarding is unavailable");
|
|
1287
|
+
return handler.creatorOnboarding(operation.input);
|
|
1276
1288
|
case "oauth.consumer.cleanup":
|
|
1277
1289
|
return handler.cleanupOAuthConsumer({
|
|
1278
1290
|
consumerBindingId: operation.consumerBindingId,
|
package/dist/shard-router.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AutoModerationEnhancedResultOutcome } from "@helyx/sdk";
|
|
1
|
+
import { type AutoModerationEnhancedResultOutcome, type CreatorOnboardingRequest, type CreatorOnboardingResponse } from "@helyx/sdk";
|
|
2
2
|
import { type BotControlHandler } from "./control-server.js";
|
|
3
3
|
import { type ShardControlRequest, type ShardControlResponse } from "./shard-contracts.js";
|
|
4
4
|
import type { ShardCoordinator, ShardLeaderLease, ShardLease } from "./shard-coordinator.js";
|
|
@@ -8,6 +8,7 @@ type LocalDispatcher = (shardId: number, request: ShardControlRequest) => Promis
|
|
|
8
8
|
export declare class ShardControlRouter implements BotControlHandler {
|
|
9
9
|
#private;
|
|
10
10
|
private readonly input;
|
|
11
|
+
creatorOnboarding(input: CreatorOnboardingRequest): Promise<CreatorOnboardingResponse>;
|
|
11
12
|
constructor(input: {
|
|
12
13
|
generation: string;
|
|
13
14
|
shardCount: number;
|
package/dist/shard-router.js
CHANGED
|
@@ -11,6 +11,13 @@ const LEASE_VALIDATION_TIMEOUT_MS = 3_000;
|
|
|
11
11
|
const ECKO_RESULT_TIMEOUT_MS = AUTOMOD_SCANNER_LIMITS.resultAcknowledgementSeconds * 1_000;
|
|
12
12
|
export class ShardControlRouter {
|
|
13
13
|
input;
|
|
14
|
+
creatorOnboarding(input) {
|
|
15
|
+
return this.#route({
|
|
16
|
+
kind: "creator.onboarding",
|
|
17
|
+
guildId: input.guildId,
|
|
18
|
+
input,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
14
21
|
constructor(input) {
|
|
15
22
|
this.input = input;
|
|
16
23
|
}
|