Skip to content

Commit 50ed023

Browse files
fix: improve event truncation and add seed/emulator backwards compat
- Truncate events at whole-token boundaries and show hidden count instead of total (e.g. '… (+3 more)' not '… (+5)') - Add url fallback in seedFromConfig for legacy seed configs - Add regression tests for legacy url input on POST/PUT Co-Authored-By: nick.nisi@workos.com <nick@nisi.org>
1 parent 6be28f1 commit 50ed023

3 files changed

Lines changed: 49 additions & 7 deletions

File tree

src/commands/webhook.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,23 @@ export async function runWebhookList(apiKey: string, baseUrl?: string): Promise<
2929
return;
3030
}
3131

32+
const maxEventsChars = 60;
3233
const rows = result.data.map((ep) => {
33-
const eventStr = ep.events.join(', ');
34-
const maxEvents = 60;
35-
const truncatedEvents =
36-
eventStr.length > maxEvents ? `${eventStr.slice(0, maxEvents)}… (+${ep.events.length})` : eventStr;
37-
return [ep.id, ep.endpoint_url, truncatedEvents, ep.created_at];
34+
const joined = ep.events.join(', ');
35+
if (joined.length <= maxEventsChars) {
36+
return [ep.id, ep.endpoint_url, joined, ep.created_at];
37+
}
38+
const visible: string[] = [];
39+
let len = 0;
40+
for (const evt of ep.events) {
41+
const next = len === 0 ? evt.length : len + 2 + evt.length;
42+
if (next > maxEventsChars) break;
43+
visible.push(evt);
44+
len = next;
45+
}
46+
const hidden = ep.events.length - visible.length;
47+
const prefix = visible.length > 0 ? `${visible.join(', ')}, ` : '';
48+
return [ep.id, ep.endpoint_url, `${prefix}… (+${hidden} more)`, ep.created_at];
3849
});
3950

4051
console.log(formatTable([{ header: 'ID' }, { header: 'URL' }, { header: 'Events' }, { header: 'Created' }], rows));

src/emulate/workos/index.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ export interface WorkOSSeedPermission {
131131
}
132132

133133
export interface WorkOSSeedWebhookEndpoint {
134-
endpoint_url: string;
134+
endpoint_url?: string;
135+
/** @deprecated Use endpoint_url */
136+
url?: string;
135137
events?: string[];
136138
enabled?: boolean;
137139
}
@@ -315,9 +317,13 @@ export function seedFromConfig(store: Store, _baseUrl: string, config: WorkOSSee
315317

316318
if (config.webhookEndpoints) {
317319
for (const whConfig of config.webhookEndpoints) {
320+
const endpointUrl = whConfig.endpoint_url ?? whConfig.url;
321+
if (!endpointUrl) {
322+
throw new Error('workos seed config: webhookEndpoints[].endpoint_url is required');
323+
}
318324
ws.webhookEndpoints.insert({
319325
object: 'webhook_endpoint',
320-
endpoint_url: whConfig.endpoint_url,
326+
endpoint_url: endpointUrl,
321327
secret: randomBytes(32).toString('hex'),
322328
enabled: whConfig.enabled !== false,
323329
events: whConfig.events ?? [],

src/emulate/workos/routes/webhook-endpoints.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,31 @@ describe('Webhook endpoint routes', () => {
105105
expect(getRes.status).toBe(404);
106106
});
107107

108+
it('accepts legacy url on create for backward compatibility', async () => {
109+
const res = await req('/webhook_endpoints', {
110+
method: 'POST',
111+
body: JSON.stringify({ url: 'http://localhost:3000/legacy' }),
112+
});
113+
expect(res.status).toBe(201);
114+
const ep = await json(res);
115+
expect(ep.endpoint_url).toBe('http://localhost:3000/legacy');
116+
});
117+
118+
it('accepts legacy url on update for backward compatibility', async () => {
119+
const createRes = await req('/webhook_endpoints', {
120+
method: 'POST',
121+
body: JSON.stringify({ endpoint_url: 'http://localhost:3000/webhooks' }),
122+
});
123+
const created = await json(createRes);
124+
const updateRes = await req(`/webhook_endpoints/${created.id}`, {
125+
method: 'PUT',
126+
body: JSON.stringify({ url: 'http://localhost:3000/updated-legacy' }),
127+
});
128+
expect(updateRes.status).toBe(200);
129+
const updated = await json(updateRes);
130+
expect(updated.endpoint_url).toBe('http://localhost:3000/updated-legacy');
131+
});
132+
108133
it('returns 422 for missing url', async () => {
109134
const res = await req('/webhook_endpoints', {
110135
method: 'POST',

0 commit comments

Comments
 (0)