workos 0.11.1 → 0.12.0-beta.1

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.
Files changed (172) hide show
  1. package/README.md +163 -6
  2. package/dist/bin.js +22 -2
  3. package/dist/bin.js.map +1 -1
  4. package/dist/check-coverage.ts +237 -0
  5. package/dist/commands/dev.d.ts +23 -0
  6. package/dist/commands/dev.js +139 -0
  7. package/dist/commands/dev.js.map +1 -0
  8. package/dist/commands/emulate.d.ts +6 -0
  9. package/dist/commands/emulate.js +64 -0
  10. package/dist/commands/emulate.js.map +1 -0
  11. package/dist/commands/seed.d.ts +2 -0
  12. package/dist/commands/seed.js +60 -1
  13. package/dist/commands/seed.js.map +1 -1
  14. package/dist/emulate/core/id.d.ts +33 -0
  15. package/dist/emulate/core/id.js +58 -0
  16. package/dist/emulate/core/id.js.map +1 -0
  17. package/dist/emulate/core/index.d.ts +8 -0
  18. package/dist/emulate/core/index.js +8 -0
  19. package/dist/emulate/core/index.js.map +1 -0
  20. package/dist/emulate/core/jwt.d.ts +28 -0
  21. package/dist/emulate/core/jwt.js +78 -0
  22. package/dist/emulate/core/jwt.js.map +1 -0
  23. package/dist/emulate/core/middleware/auth.d.ts +18 -0
  24. package/dist/emulate/core/middleware/auth.js +28 -0
  25. package/dist/emulate/core/middleware/auth.js.map +1 -0
  26. package/dist/emulate/core/middleware/error-handler.d.ts +22 -0
  27. package/dist/emulate/core/middleware/error-handler.js +72 -0
  28. package/dist/emulate/core/middleware/error-handler.js.map +1 -0
  29. package/dist/emulate/core/pagination.d.ts +21 -0
  30. package/dist/emulate/core/pagination.js +35 -0
  31. package/dist/emulate/core/pagination.js.map +1 -0
  32. package/dist/emulate/core/plugin.d.ts +15 -0
  33. package/dist/emulate/core/plugin.js +2 -0
  34. package/dist/emulate/core/plugin.js.map +1 -0
  35. package/dist/emulate/core/server.d.ts +17 -0
  36. package/dist/emulate/core/server.js +116 -0
  37. package/dist/emulate/core/server.js.map +1 -0
  38. package/dist/emulate/core/store.d.ts +42 -0
  39. package/dist/emulate/core/store.js +148 -0
  40. package/dist/emulate/core/store.js.map +1 -0
  41. package/dist/emulate/index.d.ts +25 -0
  42. package/dist/emulate/index.js +47 -0
  43. package/dist/emulate/index.js.map +1 -0
  44. package/dist/emulate/workos/entities.d.ts +360 -0
  45. package/dist/emulate/workos/entities.js +2 -0
  46. package/dist/emulate/workos/entities.js.map +1 -0
  47. package/dist/emulate/workos/event-bus.d.ts +12 -0
  48. package/dist/emulate/workos/event-bus.js +45 -0
  49. package/dist/emulate/workos/event-bus.js.map +1 -0
  50. package/dist/emulate/workos/helpers.d.ts +63 -0
  51. package/dist/emulate/workos/helpers.js +518 -0
  52. package/dist/emulate/workos/helpers.js.map +1 -0
  53. package/dist/emulate/workos/index.d.ts +91 -0
  54. package/dist/emulate/workos/index.js +319 -0
  55. package/dist/emulate/workos/index.js.map +1 -0
  56. package/dist/emulate/workos/routes/api-keys.d.ts +2 -0
  57. package/dist/emulate/workos/routes/api-keys.js +35 -0
  58. package/dist/emulate/workos/routes/api-keys.js.map +1 -0
  59. package/dist/emulate/workos/routes/audit-logs.d.ts +2 -0
  60. package/dist/emulate/workos/routes/audit-logs.js +107 -0
  61. package/dist/emulate/workos/routes/audit-logs.js.map +1 -0
  62. package/dist/emulate/workos/routes/auth-challenges.d.ts +2 -0
  63. package/dist/emulate/workos/routes/auth-challenges.js +51 -0
  64. package/dist/emulate/workos/routes/auth-challenges.js.map +1 -0
  65. package/dist/emulate/workos/routes/auth-factors.d.ts +2 -0
  66. package/dist/emulate/workos/routes/auth-factors.js +51 -0
  67. package/dist/emulate/workos/routes/auth-factors.js.map +1 -0
  68. package/dist/emulate/workos/routes/auth.d.ts +2 -0
  69. package/dist/emulate/workos/routes/auth.js +349 -0
  70. package/dist/emulate/workos/routes/auth.js.map +1 -0
  71. package/dist/emulate/workos/routes/authorization-checks.d.ts +10 -0
  72. package/dist/emulate/workos/routes/authorization-checks.js +135 -0
  73. package/dist/emulate/workos/routes/authorization-checks.js.map +1 -0
  74. package/dist/emulate/workos/routes/authorization-org-roles.d.ts +2 -0
  75. package/dist/emulate/workos/routes/authorization-org-roles.js +206 -0
  76. package/dist/emulate/workos/routes/authorization-org-roles.js.map +1 -0
  77. package/dist/emulate/workos/routes/authorization-permissions.d.ts +2 -0
  78. package/dist/emulate/workos/routes/authorization-permissions.js +78 -0
  79. package/dist/emulate/workos/routes/authorization-permissions.js.map +1 -0
  80. package/dist/emulate/workos/routes/authorization-resources.d.ts +2 -0
  81. package/dist/emulate/workos/routes/authorization-resources.js +128 -0
  82. package/dist/emulate/workos/routes/authorization-resources.js.map +1 -0
  83. package/dist/emulate/workos/routes/authorization-roles.d.ts +2 -0
  84. package/dist/emulate/workos/routes/authorization-roles.js +136 -0
  85. package/dist/emulate/workos/routes/authorization-roles.js.map +1 -0
  86. package/dist/emulate/workos/routes/config.d.ts +2 -0
  87. package/dist/emulate/workos/routes/config.js +56 -0
  88. package/dist/emulate/workos/routes/config.js.map +1 -0
  89. package/dist/emulate/workos/routes/connect.d.ts +2 -0
  90. package/dist/emulate/workos/routes/connect.js +69 -0
  91. package/dist/emulate/workos/routes/connect.js.map +1 -0
  92. package/dist/emulate/workos/routes/connections.d.ts +2 -0
  93. package/dist/emulate/workos/routes/connections.js +77 -0
  94. package/dist/emulate/workos/routes/connections.js.map +1 -0
  95. package/dist/emulate/workos/routes/data-integrations.d.ts +2 -0
  96. package/dist/emulate/workos/routes/data-integrations.js +55 -0
  97. package/dist/emulate/workos/routes/data-integrations.js.map +1 -0
  98. package/dist/emulate/workos/routes/directories.d.ts +2 -0
  99. package/dist/emulate/workos/routes/directories.js +106 -0
  100. package/dist/emulate/workos/routes/directories.js.map +1 -0
  101. package/dist/emulate/workos/routes/email-verification.d.ts +2 -0
  102. package/dist/emulate/workos/routes/email-verification.js +49 -0
  103. package/dist/emulate/workos/routes/email-verification.js.map +1 -0
  104. package/dist/emulate/workos/routes/events.d.ts +2 -0
  105. package/dist/emulate/workos/routes/events.js +21 -0
  106. package/dist/emulate/workos/routes/events.js.map +1 -0
  107. package/dist/emulate/workos/routes/feature-flags.d.ts +2 -0
  108. package/dist/emulate/workos/routes/feature-flags.js +131 -0
  109. package/dist/emulate/workos/routes/feature-flags.js.map +1 -0
  110. package/dist/emulate/workos/routes/invitations.d.ts +2 -0
  111. package/dist/emulate/workos/routes/invitations.js +125 -0
  112. package/dist/emulate/workos/routes/invitations.js.map +1 -0
  113. package/dist/emulate/workos/routes/legacy-mfa.d.ts +2 -0
  114. package/dist/emulate/workos/routes/legacy-mfa.js +75 -0
  115. package/dist/emulate/workos/routes/legacy-mfa.js.map +1 -0
  116. package/dist/emulate/workos/routes/magic-auth.d.ts +2 -0
  117. package/dist/emulate/workos/routes/magic-auth.js +32 -0
  118. package/dist/emulate/workos/routes/magic-auth.js.map +1 -0
  119. package/dist/emulate/workos/routes/memberships.d.ts +2 -0
  120. package/dist/emulate/workos/routes/memberships.js +118 -0
  121. package/dist/emulate/workos/routes/memberships.js.map +1 -0
  122. package/dist/emulate/workos/routes/organization-domains.d.ts +2 -0
  123. package/dist/emulate/workos/routes/organization-domains.js +58 -0
  124. package/dist/emulate/workos/routes/organization-domains.js.map +1 -0
  125. package/dist/emulate/workos/routes/organizations.d.ts +2 -0
  126. package/dist/emulate/workos/routes/organizations.js +133 -0
  127. package/dist/emulate/workos/routes/organizations.js.map +1 -0
  128. package/dist/emulate/workos/routes/password-reset.d.ts +2 -0
  129. package/dist/emulate/workos/routes/password-reset.js +61 -0
  130. package/dist/emulate/workos/routes/password-reset.js.map +1 -0
  131. package/dist/emulate/workos/routes/pipes.d.ts +2 -0
  132. package/dist/emulate/workos/routes/pipes.js +86 -0
  133. package/dist/emulate/workos/routes/pipes.js.map +1 -0
  134. package/dist/emulate/workos/routes/portal.d.ts +2 -0
  135. package/dist/emulate/workos/routes/portal.js +18 -0
  136. package/dist/emulate/workos/routes/portal.js.map +1 -0
  137. package/dist/emulate/workos/routes/radar.d.ts +2 -0
  138. package/dist/emulate/workos/routes/radar.js +45 -0
  139. package/dist/emulate/workos/routes/radar.js.map +1 -0
  140. package/dist/emulate/workos/routes/sessions.d.ts +2 -0
  141. package/dist/emulate/workos/routes/sessions.js +51 -0
  142. package/dist/emulate/workos/routes/sessions.js.map +1 -0
  143. package/dist/emulate/workos/routes/sso.d.ts +2 -0
  144. package/dist/emulate/workos/routes/sso.js +160 -0
  145. package/dist/emulate/workos/routes/sso.js.map +1 -0
  146. package/dist/emulate/workos/routes/user-features.d.ts +2 -0
  147. package/dist/emulate/workos/routes/user-features.js +50 -0
  148. package/dist/emulate/workos/routes/user-features.js.map +1 -0
  149. package/dist/emulate/workos/routes/users.d.ts +2 -0
  150. package/dist/emulate/workos/routes/users.js +133 -0
  151. package/dist/emulate/workos/routes/users.js.map +1 -0
  152. package/dist/emulate/workos/routes/webhook-endpoints.d.ts +2 -0
  153. package/dist/emulate/workos/routes/webhook-endpoints.js +70 -0
  154. package/dist/emulate/workos/routes/webhook-endpoints.js.map +1 -0
  155. package/dist/emulate/workos/routes/widgets.d.ts +2 -0
  156. package/dist/emulate/workos/routes/widgets.js +27 -0
  157. package/dist/emulate/workos/routes/widgets.js.map +1 -0
  158. package/dist/emulate/workos/store.d.ts +48 -0
  159. package/dist/emulate/workos/store.js +93 -0
  160. package/dist/emulate/workos/store.js.map +1 -0
  161. package/dist/emulate/workos/webhook-signer.d.ts +1 -0
  162. package/dist/emulate/workos/webhook-signer.js +8 -0
  163. package/dist/emulate/workos/webhook-signer.js.map +1 -0
  164. package/dist/gen-routes-lib.spec.ts +659 -0
  165. package/dist/gen-routes-lib.ts +647 -0
  166. package/dist/gen-routes.ts +96 -0
  167. package/dist/lib/dev-command.d.ts +26 -0
  168. package/dist/lib/dev-command.js +122 -0
  169. package/dist/lib/dev-command.js.map +1 -0
  170. package/dist/utils/help-json.js +31 -0
  171. package/dist/utils/help-json.js.map +1 -1
  172. package/package.json +20 -7
package/README.md CHANGED
@@ -77,6 +77,10 @@ Resource Management:
77
77
  api-key Manage per-org API keys
78
78
  org-domain Manage organization domains
79
79
 
80
+ Local Development:
81
+ emulate Start a local WorkOS API emulator
82
+ dev Start emulator + your app in one command
83
+
80
84
  Workflows:
81
85
  seed Declarative resource provisioning from YAML
82
86
  setup-org One-shot organization onboarding
@@ -192,6 +196,158 @@ Inspects a directory's sync state, user/group counts, recent events, and detects
192
196
  workos debug-sync directory_01ABC123
193
197
  ```
194
198
 
199
+ ### Local Development
200
+
201
+ Test your WorkOS integration locally without hitting the live API. The emulator provides a full in-memory WorkOS API replacement with all major endpoints.
202
+
203
+ #### `workos dev` — One command to start everything
204
+
205
+ The fastest way to develop locally. Starts the emulator and your app together, auto-detecting your framework and injecting the right environment variables.
206
+
207
+ ```bash
208
+ # Auto-detects framework (Next.js, Vite, Remix, SvelteKit, etc.) and dev command
209
+ workos dev
210
+
211
+ # Override the dev command
212
+ workos dev -- npx vite --port 5173
213
+
214
+ # Custom emulator port and seed data
215
+ workos dev --port 8080 --seed workos-emulate.config.yaml
216
+ ```
217
+
218
+ Your app receives these environment variables automatically:
219
+
220
+ - `WORKOS_API_BASE_URL` — points to the local emulator (e.g. `http://localhost:4100`)
221
+ - `WORKOS_API_KEY` — `sk_test_default`
222
+ - `WORKOS_CLIENT_ID` — `client_emulate`
223
+
224
+ #### `workos emulate` — Standalone emulator
225
+
226
+ Run the emulator on its own for CI, test suites, or when you want manual control.
227
+
228
+ ```bash
229
+ # Start with defaults (port 4100)
230
+ workos emulate
231
+
232
+ # CI-friendly: JSON output, custom port
233
+ workos emulate --port 9100 --json
234
+ # → {"url":"http://localhost:9100","port":9100,"apiKey":"sk_test_default","health":"http://localhost:9100/health"}
235
+
236
+ # Pre-load seed data
237
+ workos emulate --seed workos-emulate.config.yaml
238
+ ```
239
+
240
+ The emulator supports `GET /health` for readiness polling and shuts down cleanly on Ctrl+C.
241
+
242
+ #### Seed configuration
243
+
244
+ Create a `workos-emulate.config.yaml` (auto-detected) or pass `--seed <path>`:
245
+
246
+ ```yaml
247
+ users:
248
+ - email: alice@acme.com
249
+ first_name: Alice
250
+ password: test123
251
+ email_verified: true
252
+
253
+ organizations:
254
+ - name: Acme Corp
255
+ domains:
256
+ - domain: acme.com
257
+ state: verified
258
+ memberships:
259
+ - user_id: <user_id>
260
+ role: admin
261
+
262
+ connections:
263
+ - name: Acme SSO
264
+ organization: Acme Corp
265
+ connection_type: GenericSAML
266
+ domains: [acme.com]
267
+
268
+ roles:
269
+ - slug: admin
270
+ name: Admin
271
+ permissions: [posts:read, posts:write]
272
+
273
+ permissions:
274
+ - slug: posts:read
275
+ name: Read Posts
276
+ - slug: posts:write
277
+ name: Write Posts
278
+
279
+ webhookEndpoints:
280
+ - url: http://localhost:3000/webhooks
281
+ events: [user.created, organization.updated]
282
+ ```
283
+
284
+ #### Programmatic API
285
+
286
+ Use the emulator directly in test suites without the CLI:
287
+
288
+ ```typescript
289
+ import { createEmulator } from 'workos/emulate';
290
+
291
+ const emulator = await createEmulator({
292
+ port: 0, // random available port
293
+ seed: {
294
+ users: [{ email: 'test@example.com', password: 'secret' }],
295
+ },
296
+ });
297
+
298
+ // Use emulator.url as your WORKOS_API_BASE_URL
299
+ const res = await fetch(`${emulator.url}/user_management/users`, {
300
+ headers: { Authorization: 'Bearer sk_test_default' },
301
+ });
302
+
303
+ // Reset between tests (clears data, re-applies seed)
304
+ emulator.reset();
305
+
306
+ // Clean up
307
+ await emulator.close();
308
+ ```
309
+
310
+ #### Emulated endpoints
311
+
312
+ The emulator covers the full WorkOS API surface (~84% of OpenAPI spec endpoints). Run `pnpm check:coverage <openapi-spec>` to see exact coverage.
313
+
314
+ | Endpoint Group | Routes |
315
+ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
316
+ | Organizations | CRUD, external_id lookup, domain management |
317
+ | Users | CRUD, email uniqueness, password management |
318
+ | Organization memberships | CRUD, role assignment, deactivate/reactivate |
319
+ | Organization domains | CRUD, verification |
320
+ | SSO connections | CRUD, domain-based lookup |
321
+ | SSO flow | Authorize, token exchange, profile, JWKS, SSO logout |
322
+ | AuthKit | OAuth authorize (login_hint, multi-user), authenticate (7 grant types incl. refresh_token, MFA TOTP, org selection, device code), PKCE, sealed sessions, impersonation |
323
+ | Sessions | List, revoke, logout redirect, JWKS per client |
324
+ | Email verification | Send code, confirm |
325
+ | Password reset | Create token, confirm |
326
+ | Magic auth | Create code |
327
+ | Auth factors | TOTP enrollment, delete |
328
+ | MFA challenges | Create challenge, verify code |
329
+ | Invitations | CRUD, accept, revoke, resend, get by token |
330
+ | Config | Redirect URIs, CORS origins, JWT template |
331
+ | User features | Authorized apps, connected accounts, data providers |
332
+ | Widgets | Token generation |
333
+ | Authorization (RBAC) | Environment roles, org roles (priority ordering), permissions, role-permission management |
334
+ | Authorization (FGA) | Resources CRUD, permission checks, role assignments |
335
+ | Directory Sync | List/get/delete directories, users, groups |
336
+ | Audit Logs | Actions, schemas, events, exports, org config/retention |
337
+ | Feature Flags | List/get, enable/disable, targets, org/user evaluations |
338
+ | Connect | Applications CRUD, client secrets |
339
+ | Data Integrations | OAuth authorize + token exchange |
340
+ | Radar | Attempts list/get, allow/deny lists |
341
+ | API Keys | Validate, delete, list by org |
342
+ | Portal | Generate admin portal links |
343
+ | Legacy MFA | Enroll/get/delete factors, challenge/verify |
344
+ | Webhook Endpoints | CRUD with auto-generated secrets, secret masking |
345
+ | Events | Paginated event stream with type filtering |
346
+ | Event Bus | Auto-emits events on entity CRUD via collection hooks, fire-and-forget webhook delivery with HMAC signatures |
347
+ | Pipes | Connection CRUD, mock `getAccessToken()` |
348
+
349
+ JWT tokens include `role` and `permissions` claims for org-scoped sessions. All list endpoints support cursor pagination (`before`, `after`, `limit`, `order`). Error responses match the WorkOS format (`{ message, code, errors }`).
350
+
195
351
  ### Environment Management
196
352
 
197
353
  ```bash
@@ -466,12 +622,13 @@ workos install --api-key sk_test_xxx --client-id client_xxx --no-commit 2>/dev/n
466
622
 
467
623
  ### Environment Variables
468
624
 
469
- | Variable | Effect |
470
- | ------------------------ | -------------------------------------------------------- |
471
- | `WORKOS_API_KEY` | API key for management commands (bypasses stored config) |
472
- | `WORKOS_NO_PROMPT=1` | Force non-interactive mode + JSON output |
473
- | `WORKOS_FORCE_TTY=1` | Force interactive mode even when piped |
474
- | `WORKOS_TELEMETRY=false` | Disable telemetry |
625
+ | Variable | Effect |
626
+ | ------------------------ | --------------------------------------------------------- |
627
+ | `WORKOS_API_KEY` | API key for management commands (bypasses stored config) |
628
+ | `WORKOS_API_BASE_URL` | Override API base URL (set automatically by `workos dev`) |
629
+ | `WORKOS_NO_PROMPT=1` | Force non-interactive mode + JSON output |
630
+ | `WORKOS_FORCE_TTY=1` | Force interactive mode even when piped |
631
+ | `WORKOS_TELEMETRY=false` | Disable telemetry |
475
632
 
476
633
  ### Command Discovery
477
634
 
package/dist/bin.js CHANGED
@@ -159,6 +159,7 @@ const installerOptions = {
159
159
  if (!isJsonMode())
160
160
  await checkForUpdates();
161
161
  yargs(rawArgs)
162
+ .parserConfiguration({ 'populate--': true })
162
163
  .env('WORKOS_INSTALLER')
163
164
  .option('json', {
164
165
  type: 'boolean',
@@ -171,7 +172,7 @@ yargs(rawArgs)
171
172
  // Excluded: auth/claim/install/dashboard handle their own credential flows;
172
173
  // skills/doctor/env/debug are utility commands where the warning is unnecessary.
173
174
  const command = String(argv._?.[0] ?? '');
174
- if (['auth', 'skills', 'doctor', 'env', 'claim', 'install', 'debug', 'dashboard', ''].includes(command))
175
+ if (['auth', 'skills', 'doctor', 'env', 'claim', 'install', 'debug', 'dashboard', 'emulate', 'dev', ''].includes(command))
175
176
  return;
176
177
  await applyInsecureStorage(argv.insecureStorage);
177
178
  await maybeWarnUnclaimed();
@@ -1154,11 +1155,12 @@ yargs(rawArgs)
1154
1155
  'api-key': { type: 'string', describe: 'WorkOS API key' },
1155
1156
  file: { type: 'string', describe: 'Path to seed YAML file' },
1156
1157
  clean: { type: 'boolean', default: false, describe: 'Tear down seeded resources' },
1158
+ init: { type: 'boolean', default: false, describe: 'Create an example workos-seed.yml file' },
1157
1159
  }), async (argv) => {
1158
1160
  await applyInsecureStorage(argv.insecureStorage);
1159
1161
  const { resolveApiKey, resolveApiBaseUrl } = await import('./lib/api-key.js');
1160
1162
  const { runSeed } = await import('./commands/seed.js');
1161
- await runSeed({ file: argv.file, clean: argv.clean }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1163
+ await runSeed({ file: argv.file, clean: argv.clean, init: argv.init }, resolveApiKey({ apiKey: argv.apiKey }), resolveApiBaseUrl());
1162
1164
  })
1163
1165
  .command('setup-org <name>', 'One-shot organization onboarding (create org, domain, roles, portal link)', (yargs) => yargs.positional('name', { type: 'string', demandOption: true, describe: 'Organization name' }).options({
1164
1166
  ...insecureStorageOption,
@@ -1214,6 +1216,24 @@ yargs(rawArgs)
1214
1216
  await resolveInstallCredentials(argv.apiKey, argv.installDir, argv.skipAuth, ensureAuthenticated);
1215
1217
  const { handleInstall } = await import('./commands/install.js');
1216
1218
  await handleInstall(argv);
1219
+ })
1220
+ .command('emulate', 'Start a local WorkOS API emulator', (yargs) => yargs.options({
1221
+ port: { type: 'number', default: 4100, describe: 'Port to listen on' },
1222
+ seed: { type: 'string', describe: 'Path to seed config file (YAML or JSON)' },
1223
+ }), async (argv) => {
1224
+ const { runEmulate } = await import('./commands/emulate.js');
1225
+ await runEmulate({ port: argv.port, seed: argv.seed, json: argv.json });
1226
+ })
1227
+ .command('dev', 'Start emulator + your app in one command', (yargs) => yargs.options({
1228
+ port: { type: 'number', default: 4100, describe: 'Emulator port' },
1229
+ seed: { type: 'string', describe: 'Path to seed config file' },
1230
+ }), async (argv) => {
1231
+ const { runDev } = await import('./commands/dev.js');
1232
+ await runDev({
1233
+ port: argv.port,
1234
+ seed: argv.seed,
1235
+ '--': argv['--'],
1236
+ });
1217
1237
  })
1218
1238
  .command('debug', false, (yargs) => {
1219
1239
  yargs.options(insecureStorageOption);