@productcraft/platform-auth 0.2.0 → 1.0.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,689 @@
1
+ // src/_generated/testing.ts
2
+ var ROUTES = [
3
+ { op: "wellKnown.oauthAuthorizationServer", method: "GET", pattern: /^\/\.well-known\/oauth-authorization-server$/, status: 200, contentType: "application/json", body: {
4
+ authority_model: "policy",
5
+ authorization_endpoint: "string",
6
+ code_challenge_methods_supported: ["S256"],
7
+ grant_types_supported: ["authorization_code", "refresh_token"],
8
+ introspection_endpoint: "string",
9
+ issuer: "https://api.platform-auth.productcraft.co",
10
+ jwks_uri: "string",
11
+ registration_endpoint: "string",
12
+ resource_indicators_supported: ["string"],
13
+ response_types_supported: ["code"],
14
+ revocation_endpoint: "string",
15
+ scope_descriptions: {},
16
+ scope_labels: {
17
+ full: "Full access",
18
+ mail: "Email",
19
+ readonly: "Read-only",
20
+ support: "Support assistant"
21
+ },
22
+ scopes_supported: ["readonly", "mail", "support", "full"],
23
+ service_documentation: "string",
24
+ token_endpoint: "string",
25
+ token_endpoint_auth_methods_supported: ["none", "client_secret_basic", "client_secret_post"]
26
+ } },
27
+ { op: "auth.password.requestReset", method: "POST", pattern: /^\/v1\/auth\/password\/request-reset$/, status: 204, contentType: null, body: null },
28
+ { op: "workspaces.invites.accept", method: "POST", pattern: /^\/v1\/workspaces\/invites\/accept$/, status: 201, contentType: "application/json", body: {
29
+ created_at: "2026-01-01T00:00:00.000Z",
30
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
31
+ display_name: "Acme Corp",
32
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
33
+ settings: {},
34
+ slug: "acme-corp",
35
+ status: "active",
36
+ updated_at: "2026-01-01T00:00:00.000Z"
37
+ } },
38
+ { op: "sessions.revokeOthers", method: "POST", pattern: /^\/v1\/session\/revoke-others$/, status: 200, contentType: "application/json", body: { revoked: 3 } },
39
+ { op: "wellKnown.jwks", method: "GET", pattern: /^\/\.well-known\/jwks\.json$/, status: 200, contentType: "application/json", body: { keys: [{ alg: "RS256", kid: "k_2026_05_01", kty: "RSA", use: "sig" }] } },
40
+ { op: "auth.logoutCurrent", method: "POST", pattern: /^\/v1\/auth\/logout-current$/, status: 204, contentType: null, body: null },
41
+ { op: "auth.password.reset", method: "POST", pattern: /^\/v1\/auth\/password\/reset$/, status: 204, contentType: null, body: null },
42
+ { op: "verification.resend", method: "POST", pattern: /^\/v1\/verification\/resend$/, status: 200, contentType: "application/json", body: { message: "Email verified successfully" } },
43
+ { op: "verification.verify", method: "POST", pattern: /^\/v1\/verification\/verify$/, status: 200, contentType: "application/json", body: { message: "Email verified successfully" } },
44
+ { op: "introspect.apiKey", method: "POST", pattern: /^\/v1\/introspect\/api-key$/, status: 201, contentType: "application/json", body: {
45
+ api_key_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
46
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
47
+ is_valid: true,
48
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
49
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
50
+ } },
51
+ { op: "oauth.connections.list", method: "GET", pattern: /^\/v1\/oauth\/connections$/, status: 200, contentType: "application/json", body: {
52
+ data: [
53
+ {
54
+ account_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
55
+ client_id: "string",
56
+ client_name: "string",
57
+ created_at: "2026-01-01T00:00:00.000Z",
58
+ first_tool_call_at: "2026-01-01T00:00:00.000Z",
59
+ grant_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
60
+ is_verified: true,
61
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
62
+ preset: "mail",
63
+ products: ["mail"],
64
+ resource: "string",
65
+ revoked_at: "2026-01-01T00:00:00.000Z",
66
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
67
+ }
68
+ ],
69
+ pagination: { next_cursor: null, has_more: false }
70
+ } },
71
+ { op: "me.hiddenGuides.list", method: "GET", pattern: /^\/v1\/me\/hidden-guides$/, status: 200, contentType: "application/json", body: {
72
+ guides: [
73
+ {
74
+ hidden_at: "2026-01-01T00:00:00.000Z",
75
+ key: "auth_app:3f2c9a4e-8b1d-4c6e-9f2a-1b2c3d4e5f60"
76
+ }
77
+ ]
78
+ } },
79
+ { op: "me.hiddenGuides.reset", method: "DELETE", pattern: /^\/v1\/me\/hidden-guides$/, status: 204, contentType: null, body: null },
80
+ { op: "apiKeys.self", method: "GET", pattern: /^\/v1\/api-keys\/self$/, status: 200, contentType: "application/json", body: {
81
+ actions: ["mail.read", "mail.send"],
82
+ allowed: ["Mail: Read domains and templates", "Mail: Send email from your verified domains"],
83
+ expires_at: "2026-01-01T00:00:00.000Z",
84
+ key_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
85
+ name: "Production mailer",
86
+ workspace: { id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b", name: "Acme", slug: "acme" },
87
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
88
+ } },
89
+ { op: "auth.refresh", method: "POST", pattern: /^\/v1\/auth\/refresh$/, status: 200, contentType: "application/json", body: {
90
+ access_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
91
+ expires_in: 3600,
92
+ refresh_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
93
+ token_type: "Bearer"
94
+ } },
95
+ { op: "auth.logout", method: "POST", pattern: /^\/v1\/auth\/logout$/, status: 204, contentType: null, body: null },
96
+ { op: "auth.signin", method: "POST", pattern: /^\/v1\/auth\/signin$/, status: 200, contentType: "application/json", body: {
97
+ access_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
98
+ expires_in: 3600,
99
+ refresh_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
100
+ token_type: "Bearer"
101
+ } },
102
+ { op: "auth.signup", method: "POST", pattern: /^\/v1\/auth\/signup$/, status: 200, contentType: "application/json", body: {
103
+ access_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
104
+ expires_in: 3600,
105
+ refresh_token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
106
+ token_type: "Bearer"
107
+ } },
108
+ { op: "introspect.retrieve", method: "GET", pattern: /^\/v1\/introspect$/, status: 200, contentType: "application/json", body: {
109
+ account: {
110
+ avatar_url: "string",
111
+ display_name: "string",
112
+ email: "string",
113
+ email_verified_at: "2026-01-01T00:00:00.000Z",
114
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
115
+ status: "string",
116
+ username: "string"
117
+ },
118
+ is_authenticated: true,
119
+ principal: {
120
+ email: "string",
121
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
122
+ name: "string",
123
+ sub: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
124
+ },
125
+ workspaces: [
126
+ {
127
+ avatar_url: "string",
128
+ display_name: "string",
129
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
130
+ role: "owner",
131
+ services: ["mail", "waitlist"],
132
+ slug: "string"
133
+ }
134
+ ]
135
+ } },
136
+ { op: "me.profile.update", method: "PATCH", pattern: /^\/v1\/me\/profile$/, status: 200, contentType: "application/json", body: {
137
+ avatar_url: "string",
138
+ display_name: "string",
139
+ email: "string",
140
+ email_verified_at: "2026-01-01T00:00:00.000Z",
141
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
142
+ status: "string",
143
+ username: "string"
144
+ } },
145
+ { op: "workspaces.create", method: "POST", pattern: /^\/v1\/workspaces$/, status: 201, contentType: "application/json", body: {
146
+ created_at: "2026-01-01T00:00:00.000Z",
147
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
148
+ display_name: "Acme Corp",
149
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
150
+ settings: {},
151
+ slug: "acme-corp",
152
+ status: "active",
153
+ updated_at: "2026-01-01T00:00:00.000Z"
154
+ } },
155
+ { op: "workspaces.list", method: "GET", pattern: /^\/v1\/workspaces$/, status: 200, contentType: "application/json", body: {
156
+ data: [
157
+ {
158
+ created_at: "2026-01-01T00:00:00.000Z",
159
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
160
+ display_name: "Acme Corp",
161
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
162
+ member_role: "owner",
163
+ member_role_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
164
+ settings: {},
165
+ slug: "acme-corp",
166
+ status: "active",
167
+ updated_at: "2026-01-01T00:00:00.000Z"
168
+ }
169
+ ],
170
+ pagination: { next_cursor: null, has_more: false }
171
+ } },
172
+ { op: "me.avatar.clear", method: "DELETE", pattern: /^\/v1\/me\/avatar$/, status: 204, contentType: null, body: null },
173
+ { op: "me.avatar.upload", method: "POST", pattern: /^\/v1\/me\/avatar$/, status: 200, contentType: "application/json", body: { avatar_url: "string" } },
174
+ { op: "account.erase", method: "DELETE", pattern: /^\/v1\/account$/, status: 204, contentType: null, body: null },
175
+ { op: "sessions.list", method: "GET", pattern: /^\/v1\/session$/, status: 200, contentType: "application/json", body: [
176
+ {
177
+ account_id: "acc_01HZY2F2B6N7M8Q9W4E6R2",
178
+ created_at: "2025-09-20T12:34:56.000Z",
179
+ current: true,
180
+ expires_at: "2025-09-21T12:34:56.000Z",
181
+ id: "sess_01HZY2G3A7M8Q9W4E6R2K1",
182
+ ip: "203.0.113.42",
183
+ last_used_at: "2025-09-20T18:00:00.000Z",
184
+ user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
185
+ }
186
+ ] },
187
+ { op: "me.retrieve", method: "GET", pattern: /^\/v1\/me$/, status: 200, contentType: "application/json", body: {
188
+ avatar_url: "string",
189
+ display_name: "string",
190
+ email: "string",
191
+ email_verified_at: "2026-01-01T00:00:00.000Z",
192
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
193
+ status: "string",
194
+ username: "string"
195
+ } },
196
+ { op: "workspaces.policies.actions.catalog", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/policies\/actions\/catalog$/, status: 200, contentType: "application/json", body: { actions: ["string"] } },
197
+ { op: "oauth.workspaces.connections.list", method: "GET", pattern: /^\/v1\/oauth\/workspaces\/[^\/]+\/connections$/, status: 200, contentType: "application/json", body: {
198
+ data: [
199
+ {
200
+ account_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
201
+ client_id: "string",
202
+ client_name: "string",
203
+ created_at: "2026-01-01T00:00:00.000Z",
204
+ first_tool_call_at: "2026-01-01T00:00:00.000Z",
205
+ grant_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
206
+ is_verified: true,
207
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
208
+ preset: "mail",
209
+ products: ["mail"],
210
+ resource: "string",
211
+ revoked_at: "2026-01-01T00:00:00.000Z",
212
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
213
+ }
214
+ ],
215
+ pagination: { next_cursor: null, has_more: false }
216
+ } },
217
+ { op: "workspaces.auditLogs.export", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/audit-logs\/export$/, status: 200, contentType: "application/x-ndjson", body: "" },
218
+ { op: "workspaces.apiKeys.presets.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys\/presets$/, status: 200, contentType: "application/json", body: {
219
+ data: [
220
+ {
221
+ actions: ["mail.send"],
222
+ allowed: ["Mail: Send email from your verified domains"],
223
+ description: "Send email from your verified domains and check what happened to it. Cannot read message bodies or change domains.",
224
+ key: "mail-send",
225
+ label: "Send email",
226
+ policy_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
227
+ }
228
+ ],
229
+ pagination: { next_cursor: null, has_more: false }
230
+ } },
231
+ { op: "workspaces.apiKeys.preview", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys\/preview$/, status: 200, contentType: "application/json", body: {
232
+ actions: ["mail.read", "mail.send"],
233
+ allowed: ["Mail: Read domains and templates", "Mail: Send email from your verified domains"],
234
+ grantable: true,
235
+ refusal: null
236
+ } },
237
+ { op: "introspect.workspaces.retrieve", method: "GET", pattern: /^\/v1\/introspect\/workspaces\/[^\/]+$/, status: 200, contentType: "application/json", body: {
238
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
239
+ is_member: true,
240
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
241
+ role: { id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b", name: "string" },
242
+ services: ["mail", "waitlist"]
243
+ } },
244
+ { op: "workspaces.auditFeed.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/audit-feed$/, status: 200, contentType: "application/json", body: {
245
+ data: [
246
+ {
247
+ action: "mail.domain.verified",
248
+ actor_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
249
+ actor_type: "platform_user",
250
+ metadata: {},
251
+ resource: "workspace_membership",
252
+ resource_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
253
+ source: "workspace_audit",
254
+ source_ref: "4e5f5c9e-b4ee-4401-9275-283feb66c178",
255
+ timestamp: "2026-01-01T00:00:00.000Z"
256
+ }
257
+ ],
258
+ pagination: { next_cursor: null, has_more: false },
259
+ sources: [{ count: 1, error: "string", included: true, source: "workspace_audit" }]
260
+ } },
261
+ { op: "workspaces.auditLogs.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/audit-logs$/, status: 200, contentType: "application/json", body: {
262
+ data: [
263
+ {
264
+ action: "workspace.member.removed",
265
+ actor_id: "string",
266
+ actor_type: "platform_user",
267
+ created_at: "2026-01-01T00:00:00.000Z",
268
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
269
+ ip: "string",
270
+ metadata: {},
271
+ resource: "workspace_membership",
272
+ resource_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
273
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
274
+ }
275
+ ],
276
+ pagination: { next_cursor: null, has_more: false }
277
+ } },
278
+ { op: "workspaces.apiKeys.create", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys$/, status: 201, contentType: "application/json", body: {
279
+ record: {
280
+ created_at: "2026-01-01T00:00:00.000Z",
281
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
282
+ description: "string",
283
+ expires_at: "2026-01-01T00:00:00.000Z",
284
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
285
+ last_used_at: "2026-01-01T00:00:00.000Z",
286
+ name: "string",
287
+ policies: [
288
+ {
289
+ description: "string",
290
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
291
+ name: "mail-readonly"
292
+ }
293
+ ],
294
+ revoked_at: "2026-01-01T00:00:00.000Z",
295
+ rotated_from: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
296
+ status: "active",
297
+ token_prefix: "pcft_live_abc123",
298
+ updated_at: "2026-01-01T00:00:00.000Z",
299
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
300
+ },
301
+ token: "pcft_live_abc123XYZ..."
302
+ } },
303
+ { op: "workspaces.apiKeys.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys$/, status: 200, contentType: "application/json", body: {
304
+ data: [
305
+ {
306
+ created_at: "2026-01-01T00:00:00.000Z",
307
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
308
+ description: "string",
309
+ expires_at: "2026-01-01T00:00:00.000Z",
310
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
311
+ last_used_at: "2026-01-01T00:00:00.000Z",
312
+ name: "string",
313
+ policies: [
314
+ {
315
+ description: "string",
316
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
317
+ name: "mail-readonly"
318
+ }
319
+ ],
320
+ revoked_at: "2026-01-01T00:00:00.000Z",
321
+ rotated_from: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
322
+ status: "active",
323
+ token_prefix: "pcft_live_abc123",
324
+ updated_at: "2026-01-01T00:00:00.000Z",
325
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
326
+ }
327
+ ],
328
+ pagination: { next_cursor: null, has_more: false }
329
+ } },
330
+ { op: "workspaces.policies.create", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/policies$/, status: 201, contentType: "application/json", body: {
331
+ created_at: "2026-01-01T00:00:00.000Z",
332
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
333
+ description: "string",
334
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
335
+ name: "mail-readonly",
336
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
337
+ preset_key: "mail-send",
338
+ updated_at: "2026-01-01T00:00:00.000Z",
339
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
340
+ } },
341
+ { op: "workspaces.policies.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/policies$/, status: 200, contentType: "application/json", body: {
342
+ data: [
343
+ {
344
+ created_at: "2026-01-01T00:00:00.000Z",
345
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
346
+ description: "string",
347
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
348
+ name: "mail-readonly",
349
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
350
+ preset_key: "mail-send",
351
+ updated_at: "2026-01-01T00:00:00.000Z",
352
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
353
+ }
354
+ ],
355
+ pagination: { next_cursor: null, has_more: false }
356
+ } },
357
+ { op: "workspaces.services.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/services$/, status: 200, contentType: "application/json", body: {
358
+ data: [
359
+ {
360
+ disabled_at: "2026-01-01T00:00:00.000Z",
361
+ disabled_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
362
+ enabled: true,
363
+ enabled_at: "2026-01-01T00:00:00.000Z",
364
+ enabled_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
365
+ service: "mail",
366
+ settings: {},
367
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
368
+ }
369
+ ]
370
+ } },
371
+ { op: "workspaces.invites.create", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/invites$/, status: 201, contentType: "application/json", body: {
372
+ code: "string",
373
+ created_at: "2026-01-01T00:00:00.000Z",
374
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
375
+ email: "ada@example.com",
376
+ expires_at: "2026-01-01T00:00:00.000Z",
377
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
378
+ max_uses: 1,
379
+ revoked_at: "2026-01-01T00:00:00.000Z",
380
+ role_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
381
+ use_count: 1,
382
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
383
+ } },
384
+ { op: "workspaces.invites.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/invites$/, status: 200, contentType: "application/json", body: {
385
+ data: [
386
+ {
387
+ code: "string",
388
+ created_at: "2026-01-01T00:00:00.000Z",
389
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
390
+ email: "ada@example.com",
391
+ expires_at: "2026-01-01T00:00:00.000Z",
392
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
393
+ max_uses: 1,
394
+ revoked_at: "2026-01-01T00:00:00.000Z",
395
+ role_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
396
+ role_name: "string",
397
+ use_count: 1,
398
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
399
+ }
400
+ ],
401
+ pagination: { next_cursor: null, has_more: false }
402
+ } },
403
+ { op: "workspaces.members.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/members$/, status: 200, contentType: "application/json", body: {
404
+ data: [
405
+ {
406
+ account_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
407
+ avatar_url: "string",
408
+ display_name: "string",
409
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
410
+ joined_at: "2026-01-01T00:00:00.000Z",
411
+ primary_email: "string",
412
+ role: "string",
413
+ role_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
414
+ role_is_system: true,
415
+ username: "string"
416
+ }
417
+ ],
418
+ pagination: { next_cursor: null, has_more: false }
419
+ } },
420
+ { op: "oauth.connections.delete", method: "DELETE", pattern: /^\/v1\/oauth\/connections\/[^\/]+$/, status: 204, contentType: null, body: null },
421
+ { op: "workspaces.avatar.clear", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+\/avatar$/, status: 204, contentType: null, body: null },
422
+ { op: "workspaces.avatar.upload", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/avatar$/, status: 200, contentType: "application/json", body: { avatar_url: "string" } },
423
+ { op: "me.hiddenGuides.hide", method: "PUT", pattern: /^\/v1\/me\/hidden-guides\/[^\/]+$/, status: 200, contentType: "application/json", body: {
424
+ hidden_at: "2026-01-01T00:00:00.000Z",
425
+ key: "auth_app:3f2c9a4e-8b1d-4c6e-9f2a-1b2c3d4e5f60"
426
+ } },
427
+ { op: "me.hiddenGuides.unhide", method: "DELETE", pattern: /^\/v1\/me\/hidden-guides\/[^\/]+$/, status: 204, contentType: null, body: null },
428
+ { op: "stats.retrieve", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/stats$/, status: 200, contentType: "application/json", body: {
429
+ generated_at: "2026-10-07T09:00:00.000Z",
430
+ in_window: { audit_events: 57, last_api_key_use_at: "2026-10-07T06:12:40.000Z" },
431
+ last_activity_at: "2026-10-07T08:41:12.000Z",
432
+ series: { granularity: "day", metric: "audit_events", points: [{ date: "2026-10-07", value: 7 }] },
433
+ totals: { active_api_keys: 2, members: 4 },
434
+ window: "30d"
435
+ } },
436
+ { op: "workspaces.roles.create", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/roles$/, status: 201, contentType: "application/json", body: {
437
+ description: "string",
438
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
439
+ is_system: true,
440
+ name: "string",
441
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
442
+ policy_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
443
+ } },
444
+ { op: "workspaces.roles.list", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/roles$/, status: 200, contentType: "application/json", body: {
445
+ data: [
446
+ {
447
+ description: "string",
448
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
449
+ is_system: true,
450
+ name: "string",
451
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
452
+ policy_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
453
+ }
454
+ ],
455
+ pagination: { next_cursor: null, has_more: false }
456
+ } },
457
+ { op: "workspaces.delete", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+$/, status: 204, contentType: null, body: null },
458
+ { op: "workspaces.retrieve", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+$/, status: 200, contentType: "application/json", body: {
459
+ created_at: "2026-01-01T00:00:00.000Z",
460
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
461
+ display_name: "Acme Corp",
462
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
463
+ settings: {},
464
+ slug: "acme-corp",
465
+ status: "active",
466
+ updated_at: "2026-01-01T00:00:00.000Z"
467
+ } },
468
+ { op: "workspaces.update", method: "PATCH", pattern: /^\/v1\/workspaces\/[^\/]+$/, status: 200, contentType: "application/json", body: {
469
+ created_at: "2026-01-01T00:00:00.000Z",
470
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
471
+ display_name: "Acme Corp",
472
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
473
+ settings: {},
474
+ slug: "acme-corp",
475
+ status: "active",
476
+ updated_at: "2026-01-01T00:00:00.000Z"
477
+ } },
478
+ { op: "sessions.delete", method: "DELETE", pattern: /^\/v1\/session\/[^\/]+$/, status: 200, contentType: "application/json", body: { revoked: true } },
479
+ { op: "oauth.workspaces.connections.restore", method: "POST", pattern: /^\/v1\/oauth\/workspaces\/[^\/]+\/connections\/[^\/]+\/restore$/, status: 204, contentType: null, body: null },
480
+ { op: "oauth.workspaces.connections.delete", method: "DELETE", pattern: /^\/v1\/oauth\/workspaces\/[^\/]+\/connections\/[^\/]+$/, status: 204, contentType: null, body: null },
481
+ { op: "workspaces.apiKeys.updateBindings", method: "PATCH", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys\/[^\/]+\/bindings$/, status: 200, contentType: "application/json", body: {
482
+ created_at: "2026-01-01T00:00:00.000Z",
483
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
484
+ description: "string",
485
+ expires_at: "2026-01-01T00:00:00.000Z",
486
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
487
+ last_used_at: "2026-01-01T00:00:00.000Z",
488
+ name: "string",
489
+ policies: [
490
+ {
491
+ description: "string",
492
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
493
+ name: "mail-readonly"
494
+ }
495
+ ],
496
+ revoked_at: "2026-01-01T00:00:00.000Z",
497
+ rotated_from: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
498
+ status: "active",
499
+ token_prefix: "pcft_live_abc123",
500
+ updated_at: "2026-01-01T00:00:00.000Z",
501
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
502
+ } },
503
+ { op: "workspaces.services.updateSettings", method: "PATCH", pattern: /^\/v1\/workspaces\/[^\/]+\/services\/[^\/]+\/settings$/, status: 200, contentType: "application/json", body: {
504
+ disabled_at: "2026-01-01T00:00:00.000Z",
505
+ disabled_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
506
+ enabled: true,
507
+ enabled_at: "2026-01-01T00:00:00.000Z",
508
+ enabled_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
509
+ service: "mail",
510
+ settings: {},
511
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
512
+ } },
513
+ { op: "workspaces.apiKeys.rotate", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys\/[^\/]+\/rotate$/, status: 201, contentType: "application/json", body: {
514
+ previous_key_expires_at: "2026-01-01T00:00:00.000Z",
515
+ record: {
516
+ created_at: "2026-01-01T00:00:00.000Z",
517
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
518
+ description: "string",
519
+ expires_at: "2026-01-01T00:00:00.000Z",
520
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
521
+ last_used_at: "2026-01-01T00:00:00.000Z",
522
+ name: "string",
523
+ policies: [
524
+ {
525
+ description: "string",
526
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
527
+ name: "mail-readonly"
528
+ }
529
+ ],
530
+ revoked_at: "2026-01-01T00:00:00.000Z",
531
+ rotated_from: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
532
+ status: "active",
533
+ token_prefix: "pcft_live_abc123",
534
+ updated_at: "2026-01-01T00:00:00.000Z",
535
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
536
+ },
537
+ rotated_from: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
538
+ token: "pcft_live_abc123XYZ..."
539
+ } },
540
+ { op: "workspaces.members.updateRole", method: "PATCH", pattern: /^\/v1\/workspaces\/[^\/]+\/members\/[^\/]+\/role$/, status: 200, contentType: "application/json", body: {
541
+ account_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
542
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
543
+ invited_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
544
+ joined_at: "2026-01-01T00:00:00.000Z",
545
+ role_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
546
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
547
+ } },
548
+ { op: "workspaces.apiKeys.delete", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys\/[^\/]+$/, status: 204, contentType: null, body: null },
549
+ { op: "workspaces.apiKeys.retrieve", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys\/[^\/]+$/, status: 200, contentType: "application/json", body: {
550
+ created_at: "2026-01-01T00:00:00.000Z",
551
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
552
+ description: "string",
553
+ expires_at: "2026-01-01T00:00:00.000Z",
554
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
555
+ last_used_at: "2026-01-01T00:00:00.000Z",
556
+ name: "string",
557
+ policies: [
558
+ {
559
+ description: "string",
560
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
561
+ name: "mail-readonly"
562
+ }
563
+ ],
564
+ revoked_at: "2026-01-01T00:00:00.000Z",
565
+ rotated_from: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
566
+ status: "active",
567
+ token_prefix: "pcft_live_abc123",
568
+ updated_at: "2026-01-01T00:00:00.000Z",
569
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
570
+ } },
571
+ { op: "workspaces.apiKeys.update", method: "PATCH", pattern: /^\/v1\/workspaces\/[^\/]+\/api-keys\/[^\/]+$/, status: 200, contentType: "application/json", body: {
572
+ created_at: "2026-01-01T00:00:00.000Z",
573
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
574
+ description: "string",
575
+ expires_at: "2026-01-01T00:00:00.000Z",
576
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
577
+ last_used_at: "2026-01-01T00:00:00.000Z",
578
+ name: "string",
579
+ policies: [
580
+ {
581
+ description: "string",
582
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
583
+ name: "mail-readonly"
584
+ }
585
+ ],
586
+ revoked_at: "2026-01-01T00:00:00.000Z",
587
+ rotated_from: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
588
+ status: "active",
589
+ token_prefix: "pcft_live_abc123",
590
+ updated_at: "2026-01-01T00:00:00.000Z",
591
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
592
+ } },
593
+ { op: "workspaces.policies.delete", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+\/policies\/[^\/]+$/, status: 200, contentType: "application/json", body: { bound_key_count: 3, deleted: true, id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b" } },
594
+ { op: "workspaces.policies.retrieve", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/policies\/[^\/]+$/, status: 200, contentType: "application/json", body: {
595
+ binding_count: { pak: 1, role: 1 },
596
+ bound_key_count: 3,
597
+ created_at: "2026-01-01T00:00:00.000Z",
598
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
599
+ description: "string",
600
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
601
+ name: "mail-readonly",
602
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
603
+ preset_key: "mail-send",
604
+ updated_at: "2026-01-01T00:00:00.000Z",
605
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
606
+ } },
607
+ { op: "workspaces.policies.update", method: "PATCH", pattern: /^\/v1\/workspaces\/[^\/]+\/policies\/[^\/]+$/, status: 200, contentType: "application/json", body: {
608
+ binding_count: { pak: 1, role: 1 },
609
+ bound_key_count: 3,
610
+ created_at: "2026-01-01T00:00:00.000Z",
611
+ created_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
612
+ description: "string",
613
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
614
+ name: "mail-readonly",
615
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
616
+ preset_key: "mail-send",
617
+ updated_at: "2026-01-01T00:00:00.000Z",
618
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
619
+ } },
620
+ { op: "workspaces.services.disable", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+\/services\/[^\/]+$/, status: 204, contentType: null, body: null },
621
+ { op: "workspaces.services.enable", method: "POST", pattern: /^\/v1\/workspaces\/[^\/]+\/services\/[^\/]+$/, status: 201, contentType: "application/json", body: {
622
+ disabled_at: "2026-01-01T00:00:00.000Z",
623
+ disabled_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
624
+ enabled: true,
625
+ enabled_at: "2026-01-01T00:00:00.000Z",
626
+ enabled_by: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
627
+ service: "mail",
628
+ settings: {},
629
+ workspace_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
630
+ } },
631
+ { op: "workspaces.invites.delete", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+\/invites\/[^\/]+$/, status: 204, contentType: null, body: null },
632
+ { op: "workspaces.members.delete", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+\/members\/[^\/]+$/, status: 204, contentType: null, body: null },
633
+ { op: "workspaces.roles.delete", method: "DELETE", pattern: /^\/v1\/workspaces\/[^\/]+\/roles\/[^\/]+$/, status: 204, contentType: null, body: null },
634
+ { op: "workspaces.roles.retrieve", method: "GET", pattern: /^\/v1\/workspaces\/[^\/]+\/roles\/[^\/]+$/, status: 200, contentType: "application/json", body: {
635
+ description: "string",
636
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
637
+ is_system: true,
638
+ name: "string",
639
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
640
+ policy_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
641
+ } },
642
+ { op: "workspaces.roles.update", method: "PATCH", pattern: /^\/v1\/workspaces\/[^\/]+\/roles\/[^\/]+$/, status: 200, contentType: "application/json", body: {
643
+ description: "string",
644
+ id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b",
645
+ is_system: true,
646
+ name: "string",
647
+ policy: [{ actions: ["social.read", "social.list"], effect: "allow", resources: ["*"] }],
648
+ policy_id: "9b2f6c1e-0d6a-4a63-9a43-2f1c3e4d5a6b"
649
+ } }
650
+ ];
651
+ function createMockFetch(overrides = {}) {
652
+ const calls = [];
653
+ const mock = async (input, init) => {
654
+ const request = input instanceof Request ? input : void 0;
655
+ const url = new URL(request ? request.url : String(input));
656
+ const method = (init?.method ?? request?.method ?? "GET").toUpperCase();
657
+ const headers = new Headers(init?.headers ?? request?.headers);
658
+ const raw = init?.body ?? (request ? await request.text() : void 0);
659
+ let body = raw;
660
+ if (typeof raw === "string") {
661
+ try {
662
+ body = JSON.parse(raw);
663
+ } catch {
664
+ body = raw;
665
+ }
666
+ }
667
+ const route = ROUTES.find((r) => r.method === method && r.pattern.test(url.pathname));
668
+ const call = { operation: route?.op, method, url, headers, body };
669
+ calls.push(call);
670
+ const requestId = `req_mock_${calls.length}`;
671
+ if (!route) {
672
+ return Response.json({ statusCode: 404, code: "NOT_FOUND", message: `No mock for ${method} ${url.pathname}` }, { status: 404, headers: { "x-request-id": requestId } });
673
+ }
674
+ let value = route.body;
675
+ if (route.op in overrides) {
676
+ const o = overrides[route.op];
677
+ value = typeof o === "function" ? await o(call) : o;
678
+ if (value instanceof Response) return value;
679
+ }
680
+ if (route.contentType === null || route.status === 204) return new Response(null, { status: route.status, headers: { "x-request-id": requestId } });
681
+ const text = route.contentType === "application/json" ? JSON.stringify(value) : String(value);
682
+ return new Response(text, { status: route.status, headers: { "content-type": route.contentType, "x-request-id": requestId } });
683
+ };
684
+ return Object.assign(mock, { calls });
685
+ }
686
+
687
+ export { createMockFetch };
688
+ //# sourceMappingURL=testing.js.map
689
+ //# sourceMappingURL=testing.js.map