feat(core): scaffold account manager platform

This commit is contained in:
dmg
2026-08-01 13:03:26 -04:00
commit 9d305e5dc9
36 changed files with 11898 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
{
"name": "@minecraft-account-manager/contracts",
"version": "0.1.0",
"private": true,
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"test": "vitest run",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"zod": "^4.3.6"
},
"devDependencies": {
"typescript": "^5.9.3",
"vitest": "^4.1.0"
}
}
+47
View File
@@ -0,0 +1,47 @@
import { z } from "zod";
const isoDateTimeSchema = z.iso.datetime({ offset: true });
const minecraftUuidSchema = z
.string()
.regex(/^[0-9a-f]{32}$/i, "Expected a compact Java Edition UUID");
const minecraftUsernameSchema = z
.string()
.regex(/^[A-Za-z0-9_]{3,16}$/, "Expected a valid Java Edition username");
export const cloudEventSchema = z.object({
id: z.uuid(),
specversion: z.literal("1.0"),
source: z.string().startsWith("/"),
type: z.string().min(1),
subject: z.string().min(1).optional(),
time: isoDateTimeSchema,
datacontenttype: z.literal("application/json").default("application/json"),
dataschema: z.url().optional(),
data: z.record(z.string(), z.unknown()),
});
export type CloudEvent = z.infer<typeof cloudEventSchema>;
export const velocityAccessRequestSchema = z.object({
requestId: z.uuid(),
serverId: z.string().min(1).max(100),
minecraftUuid: minecraftUuidSchema,
username: minecraftUsernameSchema,
ipAddress: z.union([z.ipv4(), z.ipv6()]),
occurredAt: isoDateTimeSchema,
});
export type VelocityAccessRequest = z.infer<typeof velocityAccessRequestSchema>;
export const velocityAccessResponseSchema = z.discriminatedUnion("allowed", [
z.object({
allowed: z.literal(true),
message: z.string().min(1).optional(),
}),
z.object({
allowed: z.literal(false),
message: z.string().min(1),
}),
]);
export type VelocityAccessResponse = z.infer<typeof velocityAccessResponseSchema>;
+51
View File
@@ -0,0 +1,51 @@
import { describe, expect, it } from "vitest";
import {
cloudEventSchema,
velocityAccessRequestSchema,
velocityAccessResponseSchema,
} from "../src/index";
describe("shared service contracts", () => {
it("accepts a game login event in CloudEvents format", () => {
const event = cloudEventSchema.parse({
id: "8cf5b035-4368-4fa8-b9bb-2835da752f20",
specversion: "1.0",
source: "/velocity/main",
type: "games.minecraft.account-manager.game.login.allowed",
subject: "minecraft-account/8667ba71b85a4004af54457a9734eed7",
time: "2026-03-06T12:00:00.000Z",
datacontenttype: "application/json",
data: { username: "Notch" },
});
expect(event.specversion).toBe("1.0");
});
it("requires Velocity to send a Java UUID, username, and IP address", () => {
const request = velocityAccessRequestSchema.parse({
requestId: "6f1fd065-5298-42fa-b1ad-87a8916c6a8a",
serverId: "velocity-main",
minecraftUuid: "069a79f444e94726a5befca90e38aaf5",
username: "Notch",
ipAddress: "203.0.113.10",
occurredAt: "2026-03-06T12:00:00.000Z",
});
expect(request.username).toBe("Notch");
expect(() =>
velocityAccessRequestSchema.parse({ ...request, minecraftUuid: "not-a-uuid" }),
).toThrow();
});
it("only returns explicit allow or deny decisions to Velocity", () => {
expect(
velocityAccessResponseSchema.parse({
allowed: false,
message: "Please register your Minecraft account before joining.",
}),
).toEqual({
allowed: false,
message: "Please register your Minecraft account before joining.",
});
});
});
+7
View File
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["vitest/globals"]
},
"include": ["src/**/*.ts", "test/**/*.ts"]
}