@squord/sdk 0.0.0-stage → 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/MockRest.ts","../../src/testing/MockGateway.ts","../../src/testing/fixtures.ts","../../src/testing/index.ts"],"sourcesContent":["/**\n * MockRest: um servidor REST em memória para testar bots sem rede.\n *\n * Implementa `fetch` (passado ao cliente em `fetchImpl`) e responde às\n * rotas registradas com padrões tipo `GET /channels/:channelId/messages`.\n * Rotas não registradas respondem `404 NOT_FOUND` com o envelope oficial,\n * e as validações mínimas do protocolo (token presente, JSON válido) são\n * aplicadas como a API real faria.\n */\n\nexport interface MockRestCall {\n method: string;\n path: string;\n params: Record<string, string>;\n query: URLSearchParams;\n body: unknown;\n headers: Record<string, string>;\n requestId: string | null;\n}\n\nexport interface MockRouteMatch {\n params: Record<string, string>;\n query: URLSearchParams;\n body: unknown;\n call: MockRestCall;\n}\n\nexport interface MockRouteHandler {\n (match: MockRouteMatch): { status: number; body?: unknown; headers?: Record<string, string> } | Promise<unknown>;\n}\n\ninterface Route {\n method: string;\n pattern: string;\n segments: string[];\n handler: MockRouteHandler;\n}\n\nconst API_ERROR_HEADERS = { \"x-request-id\": \"mock-request-id\" };\n\nexport class MockRest {\n private routes: Route[] = [];\n private readonly calls: MockRestCall[] = [];\n /** Quando definido, todo request recebe esta resposta (testes de falha). */\n private failingHandler: ((call: MockRestCall) => Promise<Response> | Response) | null = null;\n /** Token esperado no header Authorization (sem o prefixo `Bot `). */\n expectedToken: string | null = null;\n\n /** Registra uma rota. `handler` devolve `{ status, body }` ou o corpo puro (status 200). */\n on(method: string, pattern: string, handler: MockRouteHandler): this {\n this.routes.push({\n method: method.toUpperCase(),\n pattern,\n segments: pattern.split(\"/\").filter(Boolean),\n handler,\n });\n return this;\n }\n\n get(pattern: string, handler: MockRouteHandler): this {\n return this.on(\"GET\", pattern, handler);\n }\n post(pattern: string, handler: MockRouteHandler): this {\n return this.on(\"POST\", pattern, handler);\n }\n put(pattern: string, handler: MockRouteHandler): this {\n return this.on(\"PUT\", pattern, handler);\n }\n patch(pattern: string, handler: MockRouteHandler): this {\n return this.on(\"PATCH\", pattern, handler);\n }\n delete(pattern: string, handler: MockRouteHandler): this {\n return this.on(\"DELETE\", pattern, handler);\n }\n\n /** Força falha em todas as requisições (ex.: simular queda de rede). */\n failWith(handler: (call: MockRestCall) => Promise<Response> | Response): void {\n this.failingHandler = handler;\n }\n\n /** Volta ao comportamento normal. */\n clearFailure(): void {\n this.failingHandler = null;\n }\n\n /** Histórico de chamadas recebidas. */\n get callLog(): readonly MockRestCall[] {\n return this.calls;\n }\n\n /** Última chamada registrada. */\n get lastCall(): MockRestCall | undefined {\n return this.calls[this.calls.length - 1];\n }\n\n /** Remove rotas e histórico. */\n reset(): void {\n this.routes = [];\n this.calls.length = 0;\n this.failingHandler = null;\n }\n\n /** A implementação de `fetch` para passar em `new SquordClient({ fetchImpl })`. */\n readonly fetch = async (input: string | URL | Request, init?: RequestInit): Promise<Response> => {\n const request = input instanceof Request ? input : new Request(input as string | URL, init);\n const url = new URL(request.url);\n const method = request.method.toUpperCase();\n\n let body: unknown = undefined;\n const rawBody = init?.body ?? (input instanceof Request ? undefined : undefined);\n if (rawBody !== undefined && rawBody !== null) {\n if (typeof rawBody === \"string\") {\n body = rawBody ? JSON.parse(rawBody) : undefined;\n } else if (rawBody instanceof ArrayBuffer || ArrayBuffer.isView(rawBody)) {\n body = rawBody;\n } else {\n body = rawBody;\n }\n } else if (input instanceof Request) {\n const clone = input.clone();\n const text = await clone.text().catch(() => \"\");\n if (text) {\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n }\n }\n\n const headers: Record<string, string> = {};\n for (const [key, value] of request.headers) headers[key] = value;\n\n const call: MockRestCall = {\n method,\n path: url.pathname,\n params: {},\n query: url.searchParams,\n body,\n headers,\n requestId: headers[\"x-request-id\"] ?? null,\n };\n this.calls.push(call);\n\n if (this.failingHandler) {\n return this.failingHandler(call);\n }\n\n if (this.expectedToken) {\n const auth = headers.authorization ?? \"\";\n if (auth !== `Bot ${this.expectedToken}`) {\n return jsonResponse(401, {\n statusCode: 401,\n code: \"INVALID_TOKEN\",\n message: \"Invalid token\",\n });\n }\n }\n\n const pathSegments = url.pathname.split(\"/\").filter(Boolean);\n for (const route of this.routes) {\n if (route.method !== method) continue;\n const match = matchSegments(route.segments, pathSegments);\n if (!match) continue;\n\n const matchInfo: MockRouteMatch = {\n params: match,\n query: url.searchParams,\n body,\n call: { ...call, params: match },\n };\n const result = await route.handler(matchInfo);\n const response =\n result && typeof result === \"object\" && \"status\" in result\n ? (result as { status: number; body?: unknown; headers?: Record<string, string> })\n : { status: 200, body: result };\n return jsonResponse(response.status, response.body, response.headers);\n }\n\n return jsonResponse(404, {\n statusCode: 404,\n code: \"NOT_FOUND\",\n message: `Rota não mockada: ${method} ${url.pathname}`,\n });\n };\n}\n\nfunction matchSegments(pattern: string[], path: string[]): Record<string, string> | null {\n if (pattern.length !== path.length) return null;\n const params: Record<string, string> = {};\n for (let i = 0; i < pattern.length; i++) {\n const p = pattern[i]!;\nconst s = path[i]!;\n if (p.startsWith(\":\")) {\n params[p.slice(1)] = decodeURIComponent(s);\n } else if (p !== s) {\n return null;\n }\n }\n return params;\n}\n\nfunction jsonResponse(status: number, body: unknown, headers?: Record<string, string>): Response {\n const payload = body === undefined || body === null ? undefined : JSON.stringify(body);\n return new Response(payload, {\n status,\n headers: {\n ...(payload !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n ...API_ERROR_HEADERS,\n ...headers,\n },\n });\n}\n\n/** Cria um `MockRest` já com as rotas mínimas que o `login()` usa. */\nexport function createMockRest(options: { token?: string } = {}): MockRest {\n const rest = new MockRest();\n if (options.token) rest.expectedToken = options.token;\n return rest;\n}\n","/**\n * MockGateway: um gateway do Squord simulado em memória.\n *\n * Fala o protocolo real — `hello`, `identify`, `ready`, `heartbeat`,\n * `heartbeat.ack`, `resume`, `resumed`, `invalid_session`, `reconnect` —\n * para testar o ciclo de vida do cliente (login, reconexão, resume,\n * deduplicação) sem rede. Passe `wsFactory` em `new SquordClient({ ws })`.\n *\n * Os eventos emitidos são guardados num buffer global com sequência `s`\n * crescente, como o histórico do gateway real (até 500 eventos), e o\n * `resume` reenvia tudo que veio depois do `lastSequence` informado.\n *\n * ```ts\n * const gateway = createMockGateway();\n * const client = new SquordClient({ token: \"sqb_1.segredo\", ws: gateway.wsFactory });\n * await client.login();\n * gateway.emitEvent(\"message.created\", { message: fixtures.message() });\n * ```\n */\n\nexport interface MockGatewayOptions {\n /** Intervalo de heartbeat anunciado no hello. Padrão: 30000. */\n heartbeatIntervalMs?: number;\n /** Token aceito no identify. Aceita qualquer token por padrão. */\n token?: string;\n /** Payload do ready (userId e guilds). */\n ready?: { userId: string; guilds?: Array<{ id: string; name: string; iconUrl: string | null }> };\n /** `true` para recusar o próximo resume (treinar o fluxo `invalid_session`). */\n refuseResumeOnce?: boolean;\n /** `true` para nunca responder heartbeat.ack (treinar detecção de zumbi). */\n suppressHeartbeatAck?: boolean;\n}\n\ninterface StoredEvent {\n type: string;\n d: unknown;\n s: number;\n}\n\n/** WebSocket simulado (lado cliente). */\nclass MockWebSocket {\n static OPEN = 1;\n static CLOSING = 2;\n static CLOSED = 3;\n\n readyState = 0; // CONNECTING\n private listeners = new Map<string, Array<(event: Record<string, unknown>) => void>>();\n\n constructor(readonly server: MockGatewayServer) {\n queueMicrotask(() => {\n this.readyState = MockWebSocket.OPEN;\n this.dispatch(\"open\", {});\n this.server.handleClientOpen(this);\n });\n }\n\n addEventListener(type: string, listener: (event: never) => void): void {\n const list = this.listeners.get(type) ?? [];\n list.push(listener as (event: Record<string, unknown>) => void);\n this.listeners.set(type, list);\n }\n\n removeEventListener(type: string, listener: (event: never) => void): void {\n const list = this.listeners.get(type) ?? [];\n const index = list.indexOf(listener as (event: Record<string, unknown>) => void);\n if (index >= 0) list.splice(index, 1);\n }\n\n dispatch(type: string, event: Record<string, unknown>): void {\n for (const listener of [...(this.listeners.get(type) ?? [])]) {\n listener(event);\n }\n }\n\n /** Frame do cliente: entrega ao servidor. */\n send(data: string): void {\n if (this.readyState !== MockWebSocket.OPEN) return;\n if (Buffer.byteLength(data, \"utf8\") > 65_536) {\n this.serverClose(1009, \"frame too large\");\n return;\n }\n let frame: Record<string, unknown>;\n try {\n frame = JSON.parse(data) as Record<string, unknown>;\n } catch {\n this.serverClose(4002, \"decode error\");\n return;\n }\n this.server.handleClientFrame(this, frame);\n }\n\n close(code = 1000, reason = \"\"): void {\n if (this.readyState === MockWebSocket.CLOSED) return;\n this.readyState = MockWebSocket.CLOSED;\n this.server.handleClientClose(this, code, reason);\n this.dispatch(\"close\", { code, reason, wasClean: true });\n }\n\n /** Servidor fecha a conexão. */\n serverClose(code: number, reason: string): void {\n if (this.readyState === MockWebSocket.CLOSED) return;\n this.readyState = MockWebSocket.CLOSED;\n this.server.handleClientClose(this, code, reason, true);\n this.dispatch(\"close\", { code, reason, wasClean: true });\n }\n\n /** Servidor envia frame. */\n receive(frame: Record<string, unknown>): void {\n this.dispatch(\"message\", { data: JSON.stringify(frame) });\n }\n}\n\ninterface ClientSession {\n authenticated: boolean;\n sessionId: string;\n}\n\ninterface SocketState {\n session?: ClientSession;\n}\n\nexport class MockGatewayServer {\n readonly options: MockGatewayOptions;\n private sockets = new Set<MockWebSocket>();\n private eventBuffer: StoredEvent[] = [];\n private globalSequence = 0;\n private refuseResumePending: boolean;\n private knownSessionIds = new Set<string>();\n\n constructor(options: MockGatewayOptions = {}) {\n this.options = options;\n this.refuseResumePending = options.refuseResumeOnce ?? false;\n }\n\n /** Fábrica de WebSocket para passar ao cliente. */\n readonly wsFactory = (url: string): MockWebSocket => {\n const pathname = (() => {\n try {\n return new URL(url.replace(/^wss/, \"https\")).pathname;\n } catch {\n return url;\n }\n })();\n if (!/\\/gateway$/.test(pathname)) {\n throw new Error(`MockGateway: caminho inválido ${url} (use wss://.../gateway)`);\n }\n return new MockWebSocket(this);\n };\n\n /** Conexões abertas no momento. */\n get connectionCount(): number {\n return this.sockets.size;\n }\n\n /** Última sequência emitida. */\n get lastSequence(): number {\n return this.eventBuffer.length > 0 ? this.eventBuffer[this.eventBuffer.length - 1]!.s : 0;\n }\n\n /** Total de eventos já emitidos. */\n get totalEvents(): number {\n return this.globalSequence;\n }\n\n /**\n * Emite um evento durável: guarda no buffer (sequência crescente) e\n * entrega às conexões autenticadas.\n */\n emitEvent(type: string, d: unknown): void {\n const s = ++this.globalSequence;\n this.eventBuffer.push({ type, d, s });\n if (this.eventBuffer.length > 500) this.eventBuffer.shift();\n for (const socket of this.sockets) {\n const state = socket as unknown as SocketState;\n if (state.session?.authenticated) {\n socket.receive({ op: \"event\", type, d, s, timestamp: Date.now() });\n }\n }\n }\n\n /** Envia um frame cru às conexões autenticadas (sem `s`). */\n sendFrame(frame: Record<string, unknown>): void {\n for (const socket of this.sockets) {\n const state = socket as unknown as SocketState;\n if (state.session?.authenticated) socket.receive({ ...frame, timestamp: Date.now() });\n }\n }\n\n /**\n * Envia um evento com sequência arbitrária (para treinar a deduplicação\n * do cliente: `s` repetido ou antigo deve ser descartado).\n */\n sendEventWithSequence(type: string, d: unknown, s: number): void {\n for (const socket of this.sockets) {\n const state = socket as unknown as SocketState;\n if (state.session?.authenticated) {\n socket.receive({ op: \"event\", type, d, s, timestamp: Date.now() });\n }\n }\n }\n\n /** Fecha as conexões com um código (ex.: 4009 para treinar resume). */\n closeAll(code: number, reason: string): void {\n for (const socket of [...this.sockets]) {\n socket.serverClose(code, reason);\n }\n }\n\n /** Pede reconexão (frame `reconnect` + fechamento 4007, como o real). */\n requestReconnect(reason = \"gateway shutting down\"): void {\n for (const socket of [...this.sockets]) {\n socket.receive({\n op: \"reconnect\",\n d: { reason, resumable: true },\n timestamp: Date.now(),\n });\n }\n this.closeAll(4007, reason);\n }\n\n /** Descarta o histórico de eventos (o próximo resume falha com `invalid_session`). */\n expireHistory(): void {\n this.eventBuffer = [];\n }\n\n /** Reinicia o estado do mock. */\n reset(): void {\n this.sockets.clear();\n this.eventBuffer = [];\n this.globalSequence = 0;\n this.knownSessionIds.clear();\n this.refuseResumePending = this.options.refuseResumeOnce ?? false;\n }\n\n // ------------------------------------------------------------------\n // \"Servidor\": handlers chamados pelo MockWebSocket\n // ------------------------------------------------------------------\n\n handleClientOpen(socket: MockWebSocket): void {\n this.sockets.add(socket);\n socket.receive({\n op: \"hello\",\n d: {\n heartbeatIntervalMs: this.options.heartbeatIntervalMs ?? 30_000,\n sessionId: `mock-${Math.random().toString(36).slice(2, 12)}`,\n protocolVersion: 1,\n },\n timestamp: Date.now(),\n });\n }\n\n handleClientFrame(socket: MockWebSocket, frame: Record<string, unknown>): void {\n const op = frame.op as string;\n const d = (frame.d ?? {}) as Record<string, unknown>;\n const state = socket as unknown as SocketState;\n\n switch (op) {\n case \"identify\": {\n if (state.session?.authenticated) {\n socket.serverClose(4005, \"already authenticated\");\n return;\n }\n if (this.options.token && d.token !== this.options.token) {\n socket.serverClose(4004, \"invalid token\");\n return;\n }\n const sessionId = `mock-${Math.random().toString(36).slice(2, 12)}`;\n this.knownSessionIds.add(sessionId);\n state.session = { authenticated: true, sessionId };\n socket.receive({\n op: \"ready\",\n d: {\n sessionId,\n userId: this.options.ready?.userId ?? \"1300000000000000010\",\n guilds: this.options.ready?.guilds ?? [],\n resumeGatewayUrl: \"wss://gateway.squord.com.br/gateway\",\n },\n timestamp: Date.now(),\n });\n return;\n }\n case \"resume\": {\n const sessionId = d.sessionId as string;\n const lastSequence = (d.lastSequence as number) ?? 0;\n if (this.refuseResumePending) {\n this.refuseResumePending = false;\n socket.receive({\n op: \"invalid_session\",\n d: { resumable: false },\n timestamp: Date.now(),\n });\n return;\n }\n if (!this.knownSessionIds.has(sessionId)) {\n socket.receive({\n op: \"invalid_session\",\n d: { resumable: false },\n timestamp: Date.now(),\n });\n return;\n }\n state.session = { authenticated: true, sessionId };\n const replay = this.eventBuffer.filter((event) => event.s > lastSequence);\n for (const event of replay) {\n socket.receive({\n op: \"event\",\n type: event.type,\n d: event.d,\n s: event.s,\n timestamp: Date.now(),\n });\n }\n const sequence = replay.length > 0 ? replay[replay.length - 1]!.s : lastSequence;\n socket.receive({\n op: \"resumed\",\n d: { sessionId, replayed: replay.length, sequence },\n timestamp: Date.now(),\n });\n return;\n }\n case \"heartbeat\": {\n if (!state.session?.authenticated) {\n socket.serverClose(4003, \"not authenticated\");\n return;\n }\n if (this.options.suppressHeartbeatAck) return;\n socket.receive({\n op: \"heartbeat.ack\",\n d: { sequence: this.lastSequence },\n timestamp: Date.now(),\n });\n return;\n }\n case \"presence.update\":\n case \"subscribe\":\n case \"unsubscribe\":\n case \"typing.start\":\n case \"voice.state.update\":\n return; // aceitos e ignorados, como o real\n default:\n socket.serverClose(4001, \"unknown opcode\");\n }\n }\n\n handleClientClose(socket: MockWebSocket, code: number, reason: string, byServer = false): void {\n this.sockets.delete(socket);\n (socket as unknown as SocketState).session = undefined;\n void code;\n void reason;\n void byServer;\n }\n}\n\n/** Cria o mock do gateway. Use `ws: gateway.wsFactory` no `SquordClient`. */\nexport function createMockGateway(options: MockGatewayOptions = {}): MockGatewayServer {\n return new MockGatewayServer(options);\n}\n","/**\n * Fixtures: payloads de exemplo no formato real da API, para testes de bots\n * e de handlers sem uma comunidade de verdade.\n */\n\nimport type {\n APIChannel,\n APIGuild,\n APIInteraction,\n APIMember,\n APIMessage,\n APIRole,\n APIUser,\n APICommand,\n} from \"../types/api\";\n\n/** Um usuário (Ana, dos exemplos da documentação). */\nexport function user(overrides: Partial<APIUser> = {}): APIUser {\n return {\n id: \"1300000000000000020\",\n username: \"ana\",\n displayName: \"Ana\",\n avatarUrl: null,\n avatarAnimatedUrl: null,\n nameStyle: null,\n flags: 0,\n deleted: false,\n suspended: false,\n premium: false,\n ...overrides,\n };\n}\n\n/** A conta do bot. */\nexport function botUser(overrides: Partial<APIUser> = {}): APIUser {\n return user({\n id: \"1300000000000000010\",\n username: \"bot~meubot\",\n displayName: \"Meu Bot\",\n flags: 32, // BOT\n ...overrides,\n });\n}\n\n/** Um membro de um Space. */\nexport function member(overrides: Partial<APIMember> = {}): APIMember {\n return {\n id: \"1300000000000000011\",\n guildId: \"1300000000000000001\",\n userId: \"1300000000000000020\",\n user: user(),\n type: \"INTERNAL\",\n nickname: null,\n avatarUrl: null,\n avatarAnimatedUrl: null,\n bannerUrl: null,\n bannerAnimatedUrl: null,\n bio: null,\n bioEmojis: [],\n nameStyle: null,\n profileFont: null,\n profileTheme: null,\n roleIds: [],\n joinedAt: \"2026-10-01T10:00:00.000Z\",\n timeoutUntil: null,\n deaf: false,\n mute: false,\n pending: false,\n boostingSince: null,\n createdAt: \"2026-10-01T10:00:00.000Z\",\n updatedAt: \"2026-10-01T10:00:00.000Z\",\n ...overrides,\n };\n}\n\n/** Um canal de texto. */\nexport function channel(overrides: Partial<APIChannel> = {}): APIChannel {\n return {\n id: \"1300000000000000040\",\n guildId: \"1300000000000000001\",\n categoryId: null,\n name: \"geral\",\n type: \"TEXT\",\n position: 0,\n topic: null,\n topicUpdatedAt: null,\n topicUpdatedById: null,\n isPrivate: false,\n rateLimitPerUser: 0,\n bitrate: null,\n userLimit: null,\n chatEnabled: true,\n lastMessageId: null,\n overwrites: [],\n availableTags: [],\n requireTag: false,\n defaultAutoArchiveMinutes: null,\n createdAt: \"2026-10-01T10:00:00.000Z\",\n updatedAt: \"2026-10-01T10:00:00.000Z\",\n ...overrides,\n };\n}\n\n/** Um cargo. */\nexport function role(overrides: Partial<APIRole> = {}): APIRole {\n return {\n id: \"1300000000000000001\",\n guildId: \"1300000000000000001\",\n name: \"@everyone\",\n color: null,\n position: 0,\n permissions: \"1685839112193\",\n hoist: false,\n mentionable: false,\n managed: false,\n managedKind: null,\n botId: null,\n icon: null,\n selfAssignable: false,\n createdAt: \"2026-10-01T10:00:00.000Z\",\n updatedAt: \"2026-10-01T10:00:00.000Z\",\n ...overrides,\n };\n}\n\n/** Um Space com o bloco `self` do bot. */\nexport function guild(overrides: Partial<APIGuild> = {}): APIGuild {\n return {\n id: \"1300000000000000001\",\n ownerId: \"1300000000000000009\",\n name: \"Meu Space\",\n slug: \"meu-space\",\n description: null,\n iconUrl: null,\n iconAnimatedUrl: null,\n bannerUrl: null,\n bannerAnimatedUrl: null,\n bannerPlaceholder: null,\n defaultChannelId: \"1300000000000000040\",\n systemChannelId: null,\n visibility: \"PUBLIC\",\n verificationLevel: \"NONE\",\n accessMode: \"LINK\",\n requireVerifiedEmail: false,\n requireTwoFactor: false,\n moderationMfaRequired: false,\n joinRequestRoleIds: [],\n requireJoinMessage: false,\n joinRequestRetryDays: 0,\n memberCount: 2,\n flags: 0,\n planId: \"free\",\n vanityLapsesAt: null,\n vanityInvite: false,\n boostCount: 0,\n boostLevel: 0,\n boostMessages: false,\n discoveryCategory: null,\n locale: null,\n rules: [],\n rulesUpdatedAt: null,\n discoverable: false,\n discoverableSince: null,\n minAccountAgeDays: 0,\n createdAt: \"2026-10-01T10:00:00.000Z\",\n updatedAt: \"2026-10-01T10:00:00.000Z\",\n self: {\n memberId: \"1300000000000000012\",\n roleIds: [\"1300000000000000031\"],\n permissions: \"155649\",\n isOwner: false,\n },\n ...overrides,\n };\n}\n\n/** Uma mensagem. */\nexport function message(overrides: Partial<APIMessage> = {}): APIMessage {\n return {\n id: \"1300000000000000100\",\n guildId: \"1300000000000000001\",\n channelId: \"1300000000000000040\",\n authorId: \"1300000000000000020\",\n type: \"DEFAULT\",\n content: \"Olá!\",\n replyToId: null,\n attachments: [],\n embeds: [],\n components: [],\n interaction: null,\n mentions: { userIds: [], roleIds: [], channelIds: [], everyone: false },\n reactions: [],\n pinned: false,\n editedAt: null,\n deletedAt: null,\n moderated: false,\n nonce: null,\n call: null,\n poll: null,\n forward: null,\n relay: null,\n relayedCount: null,\n stickers: [],\n emojis: [],\n thread: null,\n automod: null,\n createdAt: \"2026-10-05T14:30:00.000Z\",\n updatedAt: \"2026-10-05T14:30:00.000Z\",\n author: user(),\n memberNickname: null,\n memberAvatarUrl: null,\n memberNameStyle: null,\n replyTo: null,\n ...overrides,\n };\n}\n\n/** Uma interação de comando (`interaction.created` com `type: \"COMMAND\"`). */\nexport function commandInteraction(overrides: Partial<APIInteraction> = {}): APIInteraction {\n return {\n id: \"1300000000000000400\",\n token: \"tk_9f2c1d7e8a4b\",\n type: \"COMMAND\",\n guildId: \"1300000000000000001\",\n channelId: \"1300000000000000040\",\n user: user(),\n member: member(),\n command: {\n id: \"1300000000000000500\",\n name: \"ping\",\n options: [],\n },\n createdAt: \"2026-10-05T14:40:00.000Z\",\n ...overrides,\n };\n}\n\n/** Uma interação de componente (`type: \"COMPONENT\"`). */\nexport function componentInteraction(overrides: Partial<APIInteraction> = {}): APIInteraction {\n return {\n id: \"1300000000000000401\",\n token: \"tk_1b3d5f7a9c2e\",\n type: \"COMPONENT\",\n guildId: \"1300000000000000001\",\n channelId: \"1300000000000000040\",\n user: user(),\n member: member(),\n component: {\n messageId: \"1300000000000000100\",\n customId: \"confirmar\",\n type: \"button\",\n values: [],\n },\n createdAt: \"2026-10-05T14:41:00.000Z\",\n ...overrides,\n };\n}\n\n/** Um comando de aplicação registrado. */\nexport function command(overrides: Partial<APICommand> = {}): APICommand {\n return {\n id: \"1300000000000000500\",\n botId: \"1300000000000000010\",\n guildId: null,\n name: \"ping\",\n description: \"Verifica a latência do bot\",\n options: [],\n updatedAt: \"2026-10-05T14:00:00.000Z\",\n ...overrides,\n };\n}\n\n/** Um bot (visão do dono, `GET /bots/@me`). */\nexport function bot(overrides: Record<string, unknown> = {}): Record<string, unknown> {\n return {\n id: \"1300000000000000010\",\n user: botUser(),\n description: \"Bot de exemplo\",\n ownerUsername: \"ana\",\n public: false,\n verified: false,\n installCount: 1,\n termsUrl: null,\n privacyUrl: null,\n createdAt: \"2026-10-01T10:00:00.000Z\",\n intents: 13,\n ...overrides,\n };\n}\n","/**\n * @squord/sdk/testing — ferramentas para testar bots sem uma comunidade real.\n *\n * - `createMockRest()`: servidor REST em memória (passe `fetchImpl` ao cliente).\n * - `createMockGateway()`: gateway simulado que fala o protocolo real\n * (passe `wsFactory` ao cliente).\n * - `createMockEnvironment()`: REST + gateway já conectados, com a rota de\n * login respondendo — espalhe `...env.options` no `SquordClient` e pronto.\n * - `fixtures`: payloads de exemplo no formato da API.\n */\n\nexport { MockRest, createMockRest } from \"./MockRest\";\nexport type { MockRestCall, MockRouteHandler, MockRouteMatch } from \"./MockRest\";\nexport { MockGatewayServer, createMockGateway } from \"./MockGateway\";\nexport type { MockGatewayOptions } from \"./MockGateway\";\nexport * as fixtures from \"./fixtures\";\n\nimport { createMockRest } from \"./MockRest\";\nimport type { MockRest } from \"./MockRest\";\nimport { createMockGateway } from \"./MockGateway\";\nimport type { MockGatewayServer } from \"./MockGateway\";\nimport * as fixtures from \"./fixtures\";\n\n/** Opções aceitas por `createMockEnvironment`. */\nexport interface MockEnvironmentOptions {\n /** Token que o mock aceita no identify. Padrão: aceita qualquer. */\n token?: string;\n /** Intervalo de heartbeat anunciado. Padrão: 200 (testes rápidos). */\n heartbeatIntervalMs?: number;\n /** Backoff de reconexão curto para testes. Padrão: 20. */\n reconnectBaseMs?: number;\n}\n\nexport interface MockEnvironment {\n /** Opções prontas para espalhar no `SquordClient`. */\n options: {\n apiBaseURL: string;\n fetchImpl: typeof fetch;\n ws: (url: string) => unknown;\n gatewayReconnectBaseMs: number;\n };\n /** O gateway simulado: use `emitEvent` para simular eventos do Squord. */\n gateway: MockGatewayServer;\n /** O REST em memória: registre rotas e inspecione `callLog`. */\n rest: MockRest;\n}\n\n/**\n * Monta o ambiente completo de teste: `createMockRest` com a rota de login\n * (`GET /bots/@me`) já respondendo com um bot de exemplo, e `createMockGateway`\n * falando o protocolo real.\n *\n * ```js\n * import { SquordClient } from \"@squord/sdk\";\n * import { createMockEnvironment, fixtures } from \"@squord/sdk/testing\";\n *\n * const env = createMockEnvironment();\n * const client = new SquordClient({ token: \"sqb_1.demo\", ...env.options });\n * client.on(\"message.created\", (m) => { /* ... *\\/ });\n * await client.login();\n * env.gateway.emitEvent(\"message.created\", { message: fixtures.message() });\n * ```\n */\nexport function createMockEnvironment(\n options: MockEnvironmentOptions = {},\n): MockEnvironment {\n const rest = createMockRest();\n\n // Rota de login (usada pelo SquordClient.login()).\n rest.get(\"/bots/@me\", () => ({ status: 200, body: fixtures.bot() }));\n\n // Envio de mensagens: ecoa o corpo como uma Message real.\n rest.post(\"/channels/:channelId/messages\", (match) => {\n const body = (match.body ?? {}) as {\n content?: string;\n replyToId?: string;\n nonce?: string;\n };\n return {\n status: 201,\n body: fixtures.message({\n channelId: match.params.channelId,\n content: body.content ?? \"\",\n replyToId: body.replyToId ?? null,\n nonce: body.nonce ?? null,\n author: fixtures.botUser(),\n }),\n };\n });\n\n // Sincronização de comandos (CommandRegistry.sync): lista vazia por padrão.\n rest.put(\"/bots/@me/commands\", () => ({ status: 200, body: [] }));\n rest.put(\"/bots/@me/guilds/:guildId/commands\", () => ({ status: 200, body: [] }));\n\n const gateway = createMockGateway({\n heartbeatIntervalMs: options.heartbeatIntervalMs ?? 200,\n token: options.token,\n });\n\n return {\n options: {\n apiBaseURL: \"https://mock.test\",\n fetchImpl: rest.fetch,\n ws: gateway.wsFactory,\n gatewayReconnectBaseMs: options.reconnectBaseMs ?? 20,\n },\n gateway,\n rest,\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,72 @@
1
1
  {
2
2
  "name": "@squord/sdk",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "O SDK oficial do Squord para criar bots em JavaScript e TypeScript: REST tipado, gateway em tempo real, comandos, interações e moderação.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "engines": {
9
+ "node": ">=20.0.0"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "main": "./dist/index.cjs",
16
+ "module": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.cjs",
23
+ "default": "./dist/index.js"
24
+ },
25
+ "./testing": {
26
+ "types": "./dist/testing/index.d.ts",
27
+ "import": "./dist/testing/index.js",
28
+ "require": "./dist/testing/index.cjs",
29
+ "default": "./dist/testing/index.js"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest",
37
+ "typecheck": "tsc --noEmit",
38
+ "lint": "tsc --noEmit",
39
+ "prepublishOnly": "tsup"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^22.0.0",
43
+ "tsup": "^8.0.0",
44
+ "typescript": "^5.6.0",
45
+ "vitest": "^3.0.0"
46
+ },
47
+ "keywords": [
48
+ "squord",
49
+ "bot",
50
+ "sdk",
51
+ "gateway",
52
+ "websocket",
53
+ "discord-like",
54
+ "space"
55
+ ],
56
+ "author": {
57
+ "name": "Squord",
58
+ "url": "https://squord.com.br"
59
+ },
60
+ "repository": {
61
+ "type": "git",
62
+ "url": "git+https://github.com/Squord/squord-sdk.git",
63
+ "directory": "packages/sdk"
64
+ },
65
+ "bugs": {
66
+ "url": "https://github.com/Squord/squord-sdk/issues"
67
+ },
68
+ "homepage": "https://docs.squord.com.br",
69
+ "publishConfig": {
70
+ "access": "public"
71
+ }
72
+ }