Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
# Changelog

## 0.13.3
## 0.13.5

<!-- release:start -->

### New Features
### Bug Fixes

- **WorkOS `organizations.deleteOrganization`** — the WorkOS emulator now supports the SDK's org delete (`DELETE /organizations/:id`), returning 204 No Content like the real API. Deletion cascades to the organization's memberships, so a subsequent `getOrganization` 404s and the org drops out of `listOrganizationMemberships`, matching real WorkOS.
- **WorkOS `authorization.listOrganizationRoles`** — the WorkOS emulator now serves organization roles on the Authorization-API path (`GET /authorization/organizations/:id/roles`) the v10 Node SDK calls, alongside the legacy `GET /organizations/:id/roles`. Before this, `authorization.listOrganizationRoles` hit a 404, so any app loading an org's roles (a members page role picker, for example) got a 500.

<!-- release:end -->

## 0.13.4

### New Features

- **WorkOS invitation revocation on pending-membership delete** — deleting a pending organization membership now revokes the matching outstanding invitation, so seat counts stay coherent (a deleted pending member frees its seat instead of leaving a dangling invite).

## 0.13.3

### New Features

- **WorkOS `organizations.deleteOrganization`** — the WorkOS emulator now supports the SDK's org delete (`DELETE /organizations/:id`), returning 204 No Content like the real API. Deletion cascades to the organization's memberships, so a subsequent `getOrganization` 404s and the org drops out of `listOrganizationMemberships`, matching real WorkOS.

## 0.13.2

### New Features
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/adapter-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/adapter-next",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/apple/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/apple",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/autumn/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/autumn",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/aws/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/aws",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/clerk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/clerk",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/cloudflare/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/cloudflare",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("cloudflare worker routing", () => {
};
const passedThrough: string[] = [];
const realFetch = globalThis.fetch;
globalThis.fetch = (async (input: RequestInfo | URL) => {
globalThis.fetch = (async (input: Request | string | URL) => {
passedThrough.push(input instanceof Request ? input.url : String(input));
return new Response("docs site");
}) as typeof fetch;
Expand Down
6 changes: 3 additions & 3 deletions packages/@emulators/cloudflare/src/durable-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ export class EmulatorDurableObject {
private async readLedger(legacyLedger: LedgerSnapshot | undefined): Promise<LedgerSnapshot | undefined> {
const meta = await this.state.storage.get<LedgerMeta>(LEDGER_META_KEY);
if (!meta) return legacyLedger;
const entries = (
await inBatches(meta.ids, (id) => this.state.storage.get<LedgerEntry>(ledgerEntryKey(id)))
).filter((entry): entry is LedgerEntry => entry != null);
const entries = (await inBatches(meta.ids, (id) => this.state.storage.get<LedgerEntry>(ledgerEntryKey(id)))).filter(
(entry): entry is LedgerEntry => entry != null,
);
return { entries, counter: meta.counter };
}

Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/core",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/github/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/github",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/gitlab/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/gitlab",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/google/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/google",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/mcp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/mcp",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/microsoft/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/microsoft",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
10 changes: 5 additions & 5 deletions packages/@emulators/microsoft/src/routes/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,10 +450,7 @@ export function graphRoutes({ app, store, baseUrl }: RouteContext): void {
id: event.graph_id,
summary: `Created event '${event.subject}'`,
});
c.header(
"Location",
`${baseUrl}/v1.0/users('${user.email}')/events('${event.graph_id}')`,
);
c.header("Location", `${baseUrl}/v1.0/users('${user.email}')/events('${event.graph_id}')`);
return c.json(
{
"@odata.context": `${baseUrl}/v1.0/$metadata#users('${encodeURIComponent(user.email)}')/events/$entity`,
Expand All @@ -472,7 +469,10 @@ export function graphRoutes({ app, store, baseUrl }: RouteContext): void {
const eventId = c.req.param("id");
const event = findEvent(ms.events.findBy("user_email", user.email), eventId);
if (!event) {
return malformedEventId(c, eventId) ?? graphError(c, 404, "ErrorItemNotFound", "The specified object was not found in the store.");
return (
malformedEventId(c, eventId) ??
graphError(c, 404, "ErrorItemNotFound", "The specified object was not found in the store.")
);
}
const calendarRef = ms.calendars.findOneBy("graph_id", event.calendar_id);
return c.json({
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/mongoatlas/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/mongoatlas",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/okta/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/okta",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/posthog/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/posthog",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/resend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/resend",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/slack/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/slack",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/spotify/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/spotify",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/stripe/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/stripe",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/vercel/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/vercel",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/workos/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/workos",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
12 changes: 9 additions & 3 deletions packages/@emulators/workos/src/__tests__/workos.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ describe("workos emulator with the real @workos-inc/node SDK", () => {
}
});

it("lists organization roles through the SDK's Authorization surface", async () => {
const org = await workos.organizations.createOrganization({ name: "Roles Org" });
// The v10 SDK calls /authorization/organizations/:id/roles; the emulator
// must serve that path, not only the legacy /organizations/:id/roles.
const roles = await workos.authorization.listOrganizationRoles(org.id);
expect(roles.data.map((role) => role.slug).sort()).toEqual(["admin", "member"]);
});

it("deletes an organization and cascades its memberships", async () => {
const code = await signInAndGetCode("dana@example.com");
const auth = await workos.userManagement.authenticateWithCode({
Expand Down Expand Up @@ -203,9 +211,7 @@ describe("workos emulator with the real @workos-inc/node SDK", () => {
const invitations = await workos.userManagement.listInvitations({
organizationId: org.id,
});
expect(invitations.data.find((candidate) => candidate.id === invitation.id)?.state).toBe(
"revoked",
);
expect(invitations.data.find((candidate) => candidate.id === invitation.id)?.state).toBe("revoked");
});

it("round-trips vault objects through workos.vault", async () => {
Expand Down
12 changes: 9 additions & 3 deletions packages/@emulators/workos/src/routes/organizations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RouteContext } from "@emulators/core";
import type { Context, RouteContext } from "@emulators/core";

import { getWorkosStore } from "../store.js";
import { listEnvelope, serializeOrganization, workosError, workosId } from "../helpers.js";
Expand Down Expand Up @@ -47,7 +47,11 @@ export function organizationRoutes(ctx: RouteContext): void {
return c.body(null, 204);
});

app.get("/organizations/:id/roles", (c) => {
// Organization roles. The legacy path is `/organizations/:id/roles`; the
// WorkOS Node SDK v10 (`authorization.listOrganizationRoles`) calls the
// Authorization-API path `/authorization/organizations/:id/roles`. Serve
// both from one handler so either SDK generation resolves.
const organizationRoles = (c: Context) => {
const organization = ws().organizations.findOneBy("workos_id", c.req.param("id"));
if (!organization) return workosError(c, 404, "entity_not_found", "Organization not found.");
const now = new Date().toISOString();
Expand All @@ -64,7 +68,9 @@ export function organizationRoutes(ctx: RouteContext): void {
updated_at: now,
});
return c.json(listEnvelope([role("admin", "Admin"), role("member", "Member")]));
});
};
app.get("/organizations/:id/roles", organizationRoles);
app.get("/authorization/organizations/:id/roles", organizationRoles);

// Domain-verification portal link (cloud's org routes call this).
app.post("/portal/generate_link", async (c) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/@emulators/x/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@emulators/x",
"version": "0.13.4",
"version": "0.13.5",
"license": "Apache-2.0",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/emulate/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@executor-js/emulate",
"version": "0.13.4",
"version": "0.13.5",
"description": "Local drop-in replacement services for CI and no-network sandboxes",
"license": "Apache-2.0",
"type": "module",
Expand Down
Loading