workos 0.11.2 → 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 (169) hide show
  1. package/README.md +163 -6
  2. package/dist/bin.js +20 -1
  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/emulate/core/id.d.ts +33 -0
  12. package/dist/emulate/core/id.js +58 -0
  13. package/dist/emulate/core/id.js.map +1 -0
  14. package/dist/emulate/core/index.d.ts +8 -0
  15. package/dist/emulate/core/index.js +8 -0
  16. package/dist/emulate/core/index.js.map +1 -0
  17. package/dist/emulate/core/jwt.d.ts +28 -0
  18. package/dist/emulate/core/jwt.js +78 -0
  19. package/dist/emulate/core/jwt.js.map +1 -0
  20. package/dist/emulate/core/middleware/auth.d.ts +18 -0
  21. package/dist/emulate/core/middleware/auth.js +28 -0
  22. package/dist/emulate/core/middleware/auth.js.map +1 -0
  23. package/dist/emulate/core/middleware/error-handler.d.ts +22 -0
  24. package/dist/emulate/core/middleware/error-handler.js +72 -0
  25. package/dist/emulate/core/middleware/error-handler.js.map +1 -0
  26. package/dist/emulate/core/pagination.d.ts +21 -0
  27. package/dist/emulate/core/pagination.js +35 -0
  28. package/dist/emulate/core/pagination.js.map +1 -0
  29. package/dist/emulate/core/plugin.d.ts +15 -0
  30. package/dist/emulate/core/plugin.js +2 -0
  31. package/dist/emulate/core/plugin.js.map +1 -0
  32. package/dist/emulate/core/server.d.ts +17 -0
  33. package/dist/emulate/core/server.js +116 -0
  34. package/dist/emulate/core/server.js.map +1 -0
  35. package/dist/emulate/core/store.d.ts +42 -0
  36. package/dist/emulate/core/store.js +148 -0
  37. package/dist/emulate/core/store.js.map +1 -0
  38. package/dist/emulate/index.d.ts +25 -0
  39. package/dist/emulate/index.js +47 -0
  40. package/dist/emulate/index.js.map +1 -0
  41. package/dist/emulate/workos/entities.d.ts +360 -0
  42. package/dist/emulate/workos/entities.js +2 -0
  43. package/dist/emulate/workos/entities.js.map +1 -0
  44. package/dist/emulate/workos/event-bus.d.ts +12 -0
  45. package/dist/emulate/workos/event-bus.js +45 -0
  46. package/dist/emulate/workos/event-bus.js.map +1 -0
  47. package/dist/emulate/workos/helpers.d.ts +63 -0
  48. package/dist/emulate/workos/helpers.js +518 -0
  49. package/dist/emulate/workos/helpers.js.map +1 -0
  50. package/dist/emulate/workos/index.d.ts +91 -0
  51. package/dist/emulate/workos/index.js +319 -0
  52. package/dist/emulate/workos/index.js.map +1 -0
  53. package/dist/emulate/workos/routes/api-keys.d.ts +2 -0
  54. package/dist/emulate/workos/routes/api-keys.js +35 -0
  55. package/dist/emulate/workos/routes/api-keys.js.map +1 -0
  56. package/dist/emulate/workos/routes/audit-logs.d.ts +2 -0
  57. package/dist/emulate/workos/routes/audit-logs.js +107 -0
  58. package/dist/emulate/workos/routes/audit-logs.js.map +1 -0
  59. package/dist/emulate/workos/routes/auth-challenges.d.ts +2 -0
  60. package/dist/emulate/workos/routes/auth-challenges.js +51 -0
  61. package/dist/emulate/workos/routes/auth-challenges.js.map +1 -0
  62. package/dist/emulate/workos/routes/auth-factors.d.ts +2 -0
  63. package/dist/emulate/workos/routes/auth-factors.js +51 -0
  64. package/dist/emulate/workos/routes/auth-factors.js.map +1 -0
  65. package/dist/emulate/workos/routes/auth.d.ts +2 -0
  66. package/dist/emulate/workos/routes/auth.js +349 -0
  67. package/dist/emulate/workos/routes/auth.js.map +1 -0
  68. package/dist/emulate/workos/routes/authorization-checks.d.ts +10 -0
  69. package/dist/emulate/workos/routes/authorization-checks.js +135 -0
  70. package/dist/emulate/workos/routes/authorization-checks.js.map +1 -0
  71. package/dist/emulate/workos/routes/authorization-org-roles.d.ts +2 -0
  72. package/dist/emulate/workos/routes/authorization-org-roles.js +206 -0
  73. package/dist/emulate/workos/routes/authorization-org-roles.js.map +1 -0
  74. package/dist/emulate/workos/routes/authorization-permissions.d.ts +2 -0
  75. package/dist/emulate/workos/routes/authorization-permissions.js +78 -0
  76. package/dist/emulate/workos/routes/authorization-permissions.js.map +1 -0
  77. package/dist/emulate/workos/routes/authorization-resources.d.ts +2 -0
  78. package/dist/emulate/workos/routes/authorization-resources.js +128 -0
  79. package/dist/emulate/workos/routes/authorization-resources.js.map +1 -0
  80. package/dist/emulate/workos/routes/authorization-roles.d.ts +2 -0
  81. package/dist/emulate/workos/routes/authorization-roles.js +136 -0
  82. package/dist/emulate/workos/routes/authorization-roles.js.map +1 -0
  83. package/dist/emulate/workos/routes/config.d.ts +2 -0
  84. package/dist/emulate/workos/routes/config.js +56 -0
  85. package/dist/emulate/workos/routes/config.js.map +1 -0
  86. package/dist/emulate/workos/routes/connect.d.ts +2 -0
  87. package/dist/emulate/workos/routes/connect.js +69 -0
  88. package/dist/emulate/workos/routes/connect.js.map +1 -0
  89. package/dist/emulate/workos/routes/connections.d.ts +2 -0
  90. package/dist/emulate/workos/routes/connections.js +77 -0
  91. package/dist/emulate/workos/routes/connections.js.map +1 -0
  92. package/dist/emulate/workos/routes/data-integrations.d.ts +2 -0
  93. package/dist/emulate/workos/routes/data-integrations.js +55 -0
  94. package/dist/emulate/workos/routes/data-integrations.js.map +1 -0
  95. package/dist/emulate/workos/routes/directories.d.ts +2 -0
  96. package/dist/emulate/workos/routes/directories.js +106 -0
  97. package/dist/emulate/workos/routes/directories.js.map +1 -0
  98. package/dist/emulate/workos/routes/email-verification.d.ts +2 -0
  99. package/dist/emulate/workos/routes/email-verification.js +49 -0
  100. package/dist/emulate/workos/routes/email-verification.js.map +1 -0
  101. package/dist/emulate/workos/routes/events.d.ts +2 -0
  102. package/dist/emulate/workos/routes/events.js +21 -0
  103. package/dist/emulate/workos/routes/events.js.map +1 -0
  104. package/dist/emulate/workos/routes/feature-flags.d.ts +2 -0
  105. package/dist/emulate/workos/routes/feature-flags.js +131 -0
  106. package/dist/emulate/workos/routes/feature-flags.js.map +1 -0
  107. package/dist/emulate/workos/routes/invitations.d.ts +2 -0
  108. package/dist/emulate/workos/routes/invitations.js +125 -0
  109. package/dist/emulate/workos/routes/invitations.js.map +1 -0
  110. package/dist/emulate/workos/routes/legacy-mfa.d.ts +2 -0
  111. package/dist/emulate/workos/routes/legacy-mfa.js +75 -0
  112. package/dist/emulate/workos/routes/legacy-mfa.js.map +1 -0
  113. package/dist/emulate/workos/routes/magic-auth.d.ts +2 -0
  114. package/dist/emulate/workos/routes/magic-auth.js +32 -0
  115. package/dist/emulate/workos/routes/magic-auth.js.map +1 -0
  116. package/dist/emulate/workos/routes/memberships.d.ts +2 -0
  117. package/dist/emulate/workos/routes/memberships.js +118 -0
  118. package/dist/emulate/workos/routes/memberships.js.map +1 -0
  119. package/dist/emulate/workos/routes/organization-domains.d.ts +2 -0
  120. package/dist/emulate/workos/routes/organization-domains.js +58 -0
  121. package/dist/emulate/workos/routes/organization-domains.js.map +1 -0
  122. package/dist/emulate/workos/routes/organizations.d.ts +2 -0
  123. package/dist/emulate/workos/routes/organizations.js +133 -0
  124. package/dist/emulate/workos/routes/organizations.js.map +1 -0
  125. package/dist/emulate/workos/routes/password-reset.d.ts +2 -0
  126. package/dist/emulate/workos/routes/password-reset.js +61 -0
  127. package/dist/emulate/workos/routes/password-reset.js.map +1 -0
  128. package/dist/emulate/workos/routes/pipes.d.ts +2 -0
  129. package/dist/emulate/workos/routes/pipes.js +86 -0
  130. package/dist/emulate/workos/routes/pipes.js.map +1 -0
  131. package/dist/emulate/workos/routes/portal.d.ts +2 -0
  132. package/dist/emulate/workos/routes/portal.js +18 -0
  133. package/dist/emulate/workos/routes/portal.js.map +1 -0
  134. package/dist/emulate/workos/routes/radar.d.ts +2 -0
  135. package/dist/emulate/workos/routes/radar.js +45 -0
  136. package/dist/emulate/workos/routes/radar.js.map +1 -0
  137. package/dist/emulate/workos/routes/sessions.d.ts +2 -0
  138. package/dist/emulate/workos/routes/sessions.js +51 -0
  139. package/dist/emulate/workos/routes/sessions.js.map +1 -0
  140. package/dist/emulate/workos/routes/sso.d.ts +2 -0
  141. package/dist/emulate/workos/routes/sso.js +160 -0
  142. package/dist/emulate/workos/routes/sso.js.map +1 -0
  143. package/dist/emulate/workos/routes/user-features.d.ts +2 -0
  144. package/dist/emulate/workos/routes/user-features.js +50 -0
  145. package/dist/emulate/workos/routes/user-features.js.map +1 -0
  146. package/dist/emulate/workos/routes/users.d.ts +2 -0
  147. package/dist/emulate/workos/routes/users.js +133 -0
  148. package/dist/emulate/workos/routes/users.js.map +1 -0
  149. package/dist/emulate/workos/routes/webhook-endpoints.d.ts +2 -0
  150. package/dist/emulate/workos/routes/webhook-endpoints.js +70 -0
  151. package/dist/emulate/workos/routes/webhook-endpoints.js.map +1 -0
  152. package/dist/emulate/workos/routes/widgets.d.ts +2 -0
  153. package/dist/emulate/workos/routes/widgets.js +27 -0
  154. package/dist/emulate/workos/routes/widgets.js.map +1 -0
  155. package/dist/emulate/workos/store.d.ts +48 -0
  156. package/dist/emulate/workos/store.js +93 -0
  157. package/dist/emulate/workos/store.js.map +1 -0
  158. package/dist/emulate/workos/webhook-signer.d.ts +1 -0
  159. package/dist/emulate/workos/webhook-signer.js +8 -0
  160. package/dist/emulate/workos/webhook-signer.js.map +1 -0
  161. package/dist/gen-routes-lib.spec.ts +659 -0
  162. package/dist/gen-routes-lib.ts +647 -0
  163. package/dist/gen-routes.ts +96 -0
  164. package/dist/lib/dev-command.d.ts +26 -0
  165. package/dist/lib/dev-command.js +122 -0
  166. package/dist/lib/dev-command.js.map +1 -0
  167. package/dist/utils/help-json.js +23 -0
  168. package/dist/utils/help-json.js.map +1 -1
  169. package/package.json +20 -7
@@ -0,0 +1,128 @@
1
+ import { notFound, validationError, parseJsonBody } from '../../core/index.js';
2
+ import { getWorkOSStore } from '../store.js';
3
+ import { formatAuthorizationResource, formatMembership, parseListParams } from '../helpers.js';
4
+ export function authorizationResourceRoutes(ctx) {
5
+ const { app, store } = ctx;
6
+ app.post('/authorization/resources', async (c) => {
7
+ const ws = getWorkOSStore(store);
8
+ const body = await parseJsonBody(c);
9
+ const resourceTypeSlug = body.resource_type_slug;
10
+ const externalId = body.external_id;
11
+ const organizationId = body.organization_id;
12
+ if (!resourceTypeSlug) {
13
+ throw validationError('resource_type_slug is required', [{ field: 'resource_type_slug', code: 'required' }]);
14
+ }
15
+ if (!externalId) {
16
+ throw validationError('external_id is required', [{ field: 'external_id', code: 'required' }]);
17
+ }
18
+ if (!organizationId) {
19
+ throw validationError('organization_id is required', [{ field: 'organization_id', code: 'required' }]);
20
+ }
21
+ const resource = ws.authorizationResources.insert({
22
+ object: 'authorization_resource',
23
+ resource_type_slug: resourceTypeSlug,
24
+ external_id: externalId,
25
+ organization_id: organizationId,
26
+ metadata: body.metadata ?? {},
27
+ });
28
+ return c.json(formatAuthorizationResource(resource), 201);
29
+ });
30
+ app.get('/authorization/resources', (c) => {
31
+ const ws = getWorkOSStore(store);
32
+ const url = new URL(c.req.url);
33
+ const params = parseListParams(url);
34
+ const organizationId = url.searchParams.get('organization_id') ?? undefined;
35
+ const resourceTypeSlug = url.searchParams.get('resource_type_slug') ?? undefined;
36
+ const result = ws.authorizationResources.list({
37
+ ...params,
38
+ filter: (r) => {
39
+ if (organizationId && r.organization_id !== organizationId)
40
+ return false;
41
+ if (resourceTypeSlug && r.resource_type_slug !== resourceTypeSlug)
42
+ return false;
43
+ return true;
44
+ },
45
+ });
46
+ return c.json({
47
+ object: 'list',
48
+ data: result.data.map(formatAuthorizationResource),
49
+ list_metadata: result.list_metadata,
50
+ });
51
+ });
52
+ app.get('/authorization/resources/:resource_id', (c) => {
53
+ const ws = getWorkOSStore(store);
54
+ const resourceId = c.req.param('resource_id');
55
+ const resource = ws.authorizationResources.get(resourceId);
56
+ if (!resource)
57
+ throw notFound('AuthorizationResource');
58
+ return c.json(formatAuthorizationResource(resource));
59
+ });
60
+ app.put('/authorization/resources/:resource_id', async (c) => {
61
+ const ws = getWorkOSStore(store);
62
+ const resourceId = c.req.param('resource_id');
63
+ const resource = ws.authorizationResources.get(resourceId);
64
+ if (!resource)
65
+ throw notFound('AuthorizationResource');
66
+ const body = await parseJsonBody(c);
67
+ const updates = {};
68
+ if ('metadata' in body)
69
+ updates.metadata = body.metadata;
70
+ const updated = ws.authorizationResources.update(resourceId, updates);
71
+ return c.json(formatAuthorizationResource(updated));
72
+ });
73
+ app.delete('/authorization/resources/:resource_id', (c) => {
74
+ const ws = getWorkOSStore(store);
75
+ const resourceId = c.req.param('resource_id');
76
+ const resource = ws.authorizationResources.get(resourceId);
77
+ if (!resource)
78
+ throw notFound('AuthorizationResource');
79
+ ws.authorizationResources.delete(resourceId);
80
+ return c.body(null, 204);
81
+ });
82
+ // Memberships with access to a resource (by resource ID)
83
+ app.get('/authorization/resources/:resource_id/organization_memberships', (c) => {
84
+ const ws = getWorkOSStore(store);
85
+ const resourceId = c.req.param('resource_id');
86
+ const resource = ws.authorizationResources.get(resourceId);
87
+ if (!resource)
88
+ throw notFound('AuthorizationResource');
89
+ const memberships = ws.organizationMemberships.findBy('organization_id', resource.organization_id);
90
+ return c.json({
91
+ object: 'list',
92
+ data: memberships.map(formatMembership),
93
+ list_metadata: { before: null, after: null },
94
+ });
95
+ });
96
+ // Get resource by type + external ID within an org
97
+ app.get('/authorization/organizations/:orgId/resources/:type_slug/:external_id', (c) => {
98
+ const ws = getWorkOSStore(store);
99
+ const orgId = c.req.param('orgId');
100
+ const typeSlug = c.req.param('type_slug');
101
+ const externalId = c.req.param('external_id');
102
+ const resource = ws.authorizationResources
103
+ .findBy('organization_id', orgId)
104
+ .find((r) => r.resource_type_slug === typeSlug && r.external_id === externalId);
105
+ if (!resource)
106
+ throw notFound('AuthorizationResource');
107
+ return c.json(formatAuthorizationResource(resource));
108
+ });
109
+ // Memberships for resource by type + external ID within an org
110
+ app.get('/authorization/organizations/:orgId/resources/:type_slug/:external_id/organization_memberships', (c) => {
111
+ const ws = getWorkOSStore(store);
112
+ const orgId = c.req.param('orgId');
113
+ const typeSlug = c.req.param('type_slug');
114
+ const externalId = c.req.param('external_id');
115
+ const resource = ws.authorizationResources
116
+ .findBy('organization_id', orgId)
117
+ .find((r) => r.resource_type_slug === typeSlug && r.external_id === externalId);
118
+ if (!resource)
119
+ throw notFound('AuthorizationResource');
120
+ const memberships = ws.organizationMemberships.findBy('organization_id', resource.organization_id);
121
+ return c.json({
122
+ object: 'list',
123
+ data: memberships.map(formatMembership),
124
+ list_metadata: { before: null, after: null },
125
+ });
126
+ });
127
+ }
128
+ //# sourceMappingURL=authorization-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization-resources.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/authorization-resources.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, validationError, parseJsonBody } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatAuthorizationResource, formatMembership, parseListParams } from '../helpers.js';\n\nexport function authorizationResourceRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n\n app.post('/authorization/resources', async (c) => {\n const ws = getWorkOSStore(store);\n const body = await parseJsonBody(c);\n\n const resourceTypeSlug = body.resource_type_slug as string;\n const externalId = body.external_id as string;\n const organizationId = body.organization_id as string;\n\n if (!resourceTypeSlug) {\n throw validationError('resource_type_slug is required', [{ field: 'resource_type_slug', code: 'required' }]);\n }\n if (!externalId) {\n throw validationError('external_id is required', [{ field: 'external_id', code: 'required' }]);\n }\n if (!organizationId) {\n throw validationError('organization_id is required', [{ field: 'organization_id', code: 'required' }]);\n }\n\n const resource = ws.authorizationResources.insert({\n object: 'authorization_resource',\n resource_type_slug: resourceTypeSlug,\n external_id: externalId,\n organization_id: organizationId,\n metadata: (body.metadata as Record<string, string>) ?? {},\n });\n\n return c.json(formatAuthorizationResource(resource), 201);\n });\n\n app.get('/authorization/resources', (c) => {\n const ws = getWorkOSStore(store);\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const organizationId = url.searchParams.get('organization_id') ?? undefined;\n const resourceTypeSlug = url.searchParams.get('resource_type_slug') ?? undefined;\n\n const result = ws.authorizationResources.list({\n ...params,\n filter: (r) => {\n if (organizationId && r.organization_id !== organizationId) return false;\n if (resourceTypeSlug && r.resource_type_slug !== resourceTypeSlug) return false;\n return true;\n },\n });\n\n return c.json({\n object: 'list',\n data: result.data.map(formatAuthorizationResource),\n list_metadata: result.list_metadata,\n });\n });\n\n app.get('/authorization/resources/:resource_id', (c) => {\n const ws = getWorkOSStore(store);\n const resourceId = c.req.param('resource_id');\n const resource = ws.authorizationResources.get(resourceId);\n if (!resource) throw notFound('AuthorizationResource');\n return c.json(formatAuthorizationResource(resource));\n });\n\n app.put('/authorization/resources/:resource_id', async (c) => {\n const ws = getWorkOSStore(store);\n const resourceId = c.req.param('resource_id');\n const resource = ws.authorizationResources.get(resourceId);\n if (!resource) throw notFound('AuthorizationResource');\n\n const body = await parseJsonBody(c);\n const updates: Record<string, unknown> = {};\n if ('metadata' in body) updates.metadata = body.metadata;\n\n const updated = ws.authorizationResources.update(resourceId, updates);\n return c.json(formatAuthorizationResource(updated!));\n });\n\n app.delete('/authorization/resources/:resource_id', (c) => {\n const ws = getWorkOSStore(store);\n const resourceId = c.req.param('resource_id');\n const resource = ws.authorizationResources.get(resourceId);\n if (!resource) throw notFound('AuthorizationResource');\n\n ws.authorizationResources.delete(resourceId);\n return c.body(null, 204);\n });\n\n // Memberships with access to a resource (by resource ID)\n app.get('/authorization/resources/:resource_id/organization_memberships', (c) => {\n const ws = getWorkOSStore(store);\n const resourceId = c.req.param('resource_id');\n const resource = ws.authorizationResources.get(resourceId);\n if (!resource) throw notFound('AuthorizationResource');\n\n const memberships = ws.organizationMemberships.findBy('organization_id', resource.organization_id);\n return c.json({\n object: 'list',\n data: memberships.map(formatMembership),\n list_metadata: { before: null, after: null },\n });\n });\n\n // Get resource by type + external ID within an org\n app.get('/authorization/organizations/:orgId/resources/:type_slug/:external_id', (c) => {\n const ws = getWorkOSStore(store);\n const orgId = c.req.param('orgId');\n const typeSlug = c.req.param('type_slug');\n const externalId = c.req.param('external_id');\n\n const resource = ws.authorizationResources\n .findBy('organization_id', orgId)\n .find((r) => r.resource_type_slug === typeSlug && r.external_id === externalId);\n if (!resource) throw notFound('AuthorizationResource');\n return c.json(formatAuthorizationResource(resource));\n });\n\n // Memberships for resource by type + external ID within an org\n app.get('/authorization/organizations/:orgId/resources/:type_slug/:external_id/organization_memberships', (c) => {\n const ws = getWorkOSStore(store);\n const orgId = c.req.param('orgId');\n const typeSlug = c.req.param('type_slug');\n const externalId = c.req.param('external_id');\n\n const resource = ws.authorizationResources\n .findBy('organization_id', orgId)\n .find((r) => r.resource_type_slug === typeSlug && r.external_id === externalId);\n if (!resource) throw notFound('AuthorizationResource');\n\n const memberships = ws.organizationMemberships.findBy('organization_id', resource.organization_id);\n return c.json({\n object: 'list',\n data: memberships.map(formatMembership),\n list_metadata: { before: null, after: null },\n });\n });\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { type RouteContext } from '../../core/index.js';
2
+ export declare function authorizationRoleRoutes(ctx: RouteContext): void;
@@ -0,0 +1,136 @@
1
+ import { notFound, validationError, parseJsonBody } from '../../core/index.js';
2
+ import { getWorkOSStore } from '../store.js';
3
+ import { formatRole, formatPermission, parseListParams } from '../helpers.js';
4
+ export function authorizationRoleRoutes(ctx) {
5
+ const { app, store } = ctx;
6
+ app.post('/authorization/roles', async (c) => {
7
+ const ws = getWorkOSStore(store);
8
+ const body = await parseJsonBody(c);
9
+ const slug = body.slug;
10
+ const name = body.name;
11
+ if (!slug || typeof slug !== 'string') {
12
+ throw validationError('slug is required', [{ field: 'slug', code: 'required' }]);
13
+ }
14
+ if (!name || typeof name !== 'string') {
15
+ throw validationError('name is required', [{ field: 'name', code: 'required' }]);
16
+ }
17
+ // Check uniqueness among environment roles
18
+ const existing = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');
19
+ if (existing) {
20
+ throw validationError('Role with this slug already exists', [{ field: 'slug', code: 'duplicate' }]);
21
+ }
22
+ const role = ws.roles.insert({
23
+ object: 'role',
24
+ slug,
25
+ name,
26
+ description: body.description ?? null,
27
+ type: 'EnvironmentRole',
28
+ organization_id: null,
29
+ is_default_role: Boolean(body.is_default_role),
30
+ priority: typeof body.priority === 'number' ? body.priority : 0,
31
+ });
32
+ return c.json(formatRole(role), 201);
33
+ });
34
+ app.get('/authorization/roles', (c) => {
35
+ const ws = getWorkOSStore(store);
36
+ const url = new URL(c.req.url);
37
+ const params = parseListParams(url);
38
+ const result = ws.roles.list({
39
+ ...params,
40
+ filter: (r) => r.type === 'EnvironmentRole',
41
+ });
42
+ return c.json({
43
+ object: 'list',
44
+ data: result.data.map(formatRole),
45
+ list_metadata: result.list_metadata,
46
+ });
47
+ });
48
+ app.get('/authorization/roles/:slug', (c) => {
49
+ const ws = getWorkOSStore(store);
50
+ const slug = c.req.param('slug');
51
+ const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');
52
+ if (!role)
53
+ throw notFound('Role');
54
+ return c.json(formatRole(role));
55
+ });
56
+ app.put('/authorization/roles/:slug', async (c) => {
57
+ const ws = getWorkOSStore(store);
58
+ const slug = c.req.param('slug');
59
+ const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');
60
+ if (!role)
61
+ throw notFound('Role');
62
+ const body = await parseJsonBody(c);
63
+ const updates = {};
64
+ if ('name' in body)
65
+ updates.name = body.name;
66
+ if ('description' in body)
67
+ updates.description = body.description ?? null;
68
+ if ('is_default_role' in body)
69
+ updates.is_default_role = Boolean(body.is_default_role);
70
+ if ('priority' in body)
71
+ updates.priority = body.priority;
72
+ const updated = ws.roles.update(role.id, updates);
73
+ return c.json(formatRole(updated));
74
+ });
75
+ app.delete('/authorization/roles/:slug', (c) => {
76
+ const ws = getWorkOSStore(store);
77
+ const slug = c.req.param('slug');
78
+ const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');
79
+ if (!role)
80
+ throw notFound('Role');
81
+ // Cascade: remove role-permission joins and role assignments
82
+ const rps = ws.rolePermissions.findBy('role_id', role.id);
83
+ for (const rp of rps)
84
+ ws.rolePermissions.delete(rp.id);
85
+ const ras = ws.roleAssignments.findBy('role_id', role.id);
86
+ for (const ra of ras)
87
+ ws.roleAssignments.delete(ra.id);
88
+ ws.roles.delete(role.id);
89
+ return c.body(null, 204);
90
+ });
91
+ // Role permissions management
92
+ app.get('/authorization/roles/:slug/permissions', (c) => {
93
+ const ws = getWorkOSStore(store);
94
+ const slug = c.req.param('slug');
95
+ const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');
96
+ if (!role)
97
+ throw notFound('Role');
98
+ const rps = ws.rolePermissions.findBy('role_id', role.id);
99
+ const permissions = rps.map((rp) => ws.permissions.get(rp.permission_id)).filter(Boolean);
100
+ return c.json({
101
+ object: 'list',
102
+ data: permissions.map((p) => formatPermission(p)),
103
+ list_metadata: { before: null, after: null },
104
+ });
105
+ });
106
+ app.post('/authorization/roles/:slug/permissions', async (c) => {
107
+ const ws = getWorkOSStore(store);
108
+ const slug = c.req.param('slug');
109
+ const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');
110
+ if (!role)
111
+ throw notFound('Role');
112
+ const body = await parseJsonBody(c);
113
+ const permissionSlugs = body.permissions;
114
+ if (!Array.isArray(permissionSlugs)) {
115
+ throw validationError('permissions must be an array of slugs', [{ field: 'permissions', code: 'invalid' }]);
116
+ }
117
+ // Replace all: delete existing, add new
118
+ const existing = ws.rolePermissions.findBy('role_id', role.id);
119
+ for (const rp of existing)
120
+ ws.rolePermissions.delete(rp.id);
121
+ for (const permSlug of permissionSlugs) {
122
+ const perm = ws.permissions.findOneBy('slug', permSlug);
123
+ if (!perm)
124
+ throw notFound('Permission');
125
+ ws.rolePermissions.insert({ role_id: role.id, permission_id: perm.id });
126
+ }
127
+ const rps = ws.rolePermissions.findBy('role_id', role.id);
128
+ const permissions = rps.map((rp) => ws.permissions.get(rp.permission_id)).filter(Boolean);
129
+ return c.json({
130
+ object: 'list',
131
+ data: permissions.map((p) => formatPermission(p)),
132
+ list_metadata: { before: null, after: null },
133
+ });
134
+ });
135
+ }
136
+ //# sourceMappingURL=authorization-roles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization-roles.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/authorization-roles.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, validationError, parseJsonBody } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatRole, formatPermission, parseListParams } from '../helpers.js';\n\nexport function authorizationRoleRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n\n app.post('/authorization/roles', async (c) => {\n const ws = getWorkOSStore(store);\n const body = await parseJsonBody(c);\n const slug = body.slug as string;\n const name = body.name as string;\n\n if (!slug || typeof slug !== 'string') {\n throw validationError('slug is required', [{ field: 'slug', code: 'required' }]);\n }\n if (!name || typeof name !== 'string') {\n throw validationError('name is required', [{ field: 'name', code: 'required' }]);\n }\n\n // Check uniqueness among environment roles\n const existing = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');\n if (existing) {\n throw validationError('Role with this slug already exists', [{ field: 'slug', code: 'duplicate' }]);\n }\n\n const role = ws.roles.insert({\n object: 'role',\n slug,\n name,\n description: (body.description as string) ?? null,\n type: 'EnvironmentRole',\n organization_id: null,\n is_default_role: Boolean(body.is_default_role),\n priority: typeof body.priority === 'number' ? body.priority : 0,\n });\n\n return c.json(formatRole(role), 201);\n });\n\n app.get('/authorization/roles', (c) => {\n const ws = getWorkOSStore(store);\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n\n const result = ws.roles.list({\n ...params,\n filter: (r) => r.type === 'EnvironmentRole',\n });\n\n return c.json({\n object: 'list',\n data: result.data.map(formatRole),\n list_metadata: result.list_metadata,\n });\n });\n\n app.get('/authorization/roles/:slug', (c) => {\n const ws = getWorkOSStore(store);\n const slug = c.req.param('slug');\n const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');\n if (!role) throw notFound('Role');\n return c.json(formatRole(role));\n });\n\n app.put('/authorization/roles/:slug', async (c) => {\n const ws = getWorkOSStore(store);\n const slug = c.req.param('slug');\n const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');\n if (!role) throw notFound('Role');\n\n const body = await parseJsonBody(c);\n const updates: Record<string, unknown> = {};\n if ('name' in body) updates.name = body.name;\n if ('description' in body) updates.description = body.description ?? null;\n if ('is_default_role' in body) updates.is_default_role = Boolean(body.is_default_role);\n if ('priority' in body) updates.priority = body.priority;\n\n const updated = ws.roles.update(role.id, updates);\n return c.json(formatRole(updated!));\n });\n\n app.delete('/authorization/roles/:slug', (c) => {\n const ws = getWorkOSStore(store);\n const slug = c.req.param('slug');\n const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');\n if (!role) throw notFound('Role');\n\n // Cascade: remove role-permission joins and role assignments\n const rps = ws.rolePermissions.findBy('role_id', role.id);\n for (const rp of rps) ws.rolePermissions.delete(rp.id);\n const ras = ws.roleAssignments.findBy('role_id', role.id);\n for (const ra of ras) ws.roleAssignments.delete(ra.id);\n\n ws.roles.delete(role.id);\n return c.body(null, 204);\n });\n\n // Role permissions management\n app.get('/authorization/roles/:slug/permissions', (c) => {\n const ws = getWorkOSStore(store);\n const slug = c.req.param('slug');\n const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');\n if (!role) throw notFound('Role');\n\n const rps = ws.rolePermissions.findBy('role_id', role.id);\n const permissions = rps.map((rp) => ws.permissions.get(rp.permission_id)).filter(Boolean);\n\n return c.json({\n object: 'list',\n data: permissions.map((p) => formatPermission(p!)),\n list_metadata: { before: null, after: null },\n });\n });\n\n app.post('/authorization/roles/:slug/permissions', async (c) => {\n const ws = getWorkOSStore(store);\n const slug = c.req.param('slug');\n const role = ws.roles.findBy('slug', slug).find((r) => r.type === 'EnvironmentRole');\n if (!role) throw notFound('Role');\n\n const body = await parseJsonBody(c);\n const permissionSlugs = body.permissions as string[];\n if (!Array.isArray(permissionSlugs)) {\n throw validationError('permissions must be an array of slugs', [{ field: 'permissions', code: 'invalid' }]);\n }\n\n // Replace all: delete existing, add new\n const existing = ws.rolePermissions.findBy('role_id', role.id);\n for (const rp of existing) ws.rolePermissions.delete(rp.id);\n\n for (const permSlug of permissionSlugs) {\n const perm = ws.permissions.findOneBy('slug', permSlug);\n if (!perm) throw notFound('Permission');\n ws.rolePermissions.insert({ role_id: role.id, permission_id: perm.id });\n }\n\n const rps = ws.rolePermissions.findBy('role_id', role.id);\n const permissions = rps.map((rp) => ws.permissions.get(rp.permission_id)).filter(Boolean);\n\n return c.json({\n object: 'list',\n data: permissions.map((p) => formatPermission(p!)),\n list_metadata: { before: null, after: null },\n });\n });\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { type RouteContext } from '../../core/index.js';
2
+ export declare function configRoutes(ctx: RouteContext): void;
@@ -0,0 +1,56 @@
1
+ import { parseJsonBody, WorkOSApiError, validationError } from '../../core/index.js';
2
+ import { getWorkOSStore } from '../store.js';
3
+ import { formatRedirectUri, formatCorsOrigin } from '../helpers.js';
4
+ export function configRoutes(ctx) {
5
+ const { app, store } = ctx;
6
+ const ws = getWorkOSStore(store);
7
+ app.post('/user_management/redirect_uris', async (c) => {
8
+ const body = await parseJsonBody(c);
9
+ const uri = body.uri;
10
+ if (!uri) {
11
+ throw validationError('uri is required', [{ field: 'uri', code: 'required' }]);
12
+ }
13
+ const existing = ws.redirectUris.findOneBy('uri', uri);
14
+ if (existing) {
15
+ throw new WorkOSApiError(422, 'Redirect URI already exists', 'redirect_uri_already_exists');
16
+ }
17
+ const redirectUri = ws.redirectUris.insert({
18
+ object: 'redirect_uri',
19
+ uri,
20
+ });
21
+ return c.json(formatRedirectUri(redirectUri), 201);
22
+ });
23
+ app.post('/user_management/cors_origins', async (c) => {
24
+ const body = await parseJsonBody(c);
25
+ const origin = body.origin;
26
+ if (!origin) {
27
+ throw validationError('origin is required', [{ field: 'origin', code: 'required' }]);
28
+ }
29
+ const existing = ws.corsOrigins.findOneBy('origin', origin);
30
+ if (existing) {
31
+ throw new WorkOSApiError(422, 'CORS origin already exists', 'cors_origin_already_exists');
32
+ }
33
+ const corsOrigin = ws.corsOrigins.insert({
34
+ object: 'cors_origin',
35
+ origin,
36
+ });
37
+ return c.json(formatCorsOrigin(corsOrigin), 201);
38
+ });
39
+ app.get('/user_management/jwt_template', (c) => {
40
+ const template = store.getData('jwt_template') ?? {
41
+ object: 'jwt_template',
42
+ custom_claims: {},
43
+ };
44
+ return c.json(template);
45
+ });
46
+ app.put('/user_management/jwt_template', async (c) => {
47
+ const body = await parseJsonBody(c);
48
+ const template = {
49
+ object: 'jwt_template',
50
+ custom_claims: body.custom_claims ?? {},
51
+ };
52
+ store.setData('jwt_template', template);
53
+ return c.json(template);
54
+ });
55
+ }
56
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, parseJsonBody, WorkOSApiError, validationError } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatRedirectUri, formatCorsOrigin } from '../helpers.js';\n\nexport function configRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n app.post('/user_management/redirect_uris', async (c) => {\n const body = await parseJsonBody(c);\n const uri = body.uri as string | undefined;\n if (!uri) {\n throw validationError('uri is required', [{ field: 'uri', code: 'required' }]);\n }\n\n const existing = ws.redirectUris.findOneBy('uri', uri);\n if (existing) {\n throw new WorkOSApiError(422, 'Redirect URI already exists', 'redirect_uri_already_exists');\n }\n\n const redirectUri = ws.redirectUris.insert({\n object: 'redirect_uri',\n uri,\n });\n\n return c.json(formatRedirectUri(redirectUri), 201);\n });\n\n app.post('/user_management/cors_origins', async (c) => {\n const body = await parseJsonBody(c);\n const origin = body.origin as string | undefined;\n if (!origin) {\n throw validationError('origin is required', [{ field: 'origin', code: 'required' }]);\n }\n\n const existing = ws.corsOrigins.findOneBy('origin', origin);\n if (existing) {\n throw new WorkOSApiError(422, 'CORS origin already exists', 'cors_origin_already_exists');\n }\n\n const corsOrigin = ws.corsOrigins.insert({\n object: 'cors_origin',\n origin,\n });\n\n return c.json(formatCorsOrigin(corsOrigin), 201);\n });\n\n app.get('/user_management/jwt_template', (c) => {\n const template = store.getData<Record<string, unknown>>('jwt_template') ?? {\n object: 'jwt_template',\n custom_claims: {},\n };\n return c.json(template);\n });\n\n app.put('/user_management/jwt_template', async (c) => {\n const body = await parseJsonBody(c);\n const template = {\n object: 'jwt_template',\n custom_claims: (body.custom_claims as Record<string, unknown>) ?? {},\n };\n store.setData('jwt_template', template);\n return c.json(template);\n });\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { type RouteContext } from '../../core/index.js';
2
+ export declare function connectRoutes(ctx: RouteContext): void;
@@ -0,0 +1,69 @@
1
+ import { notFound, parseJsonBody, validationError } from '../../core/index.js';
2
+ import { generateId } from '../../core/index.js';
3
+ import { getWorkOSStore } from '../store.js';
4
+ import { formatConnectApplication, formatClientSecret, parseListParams, generateVerificationToken, } from '../helpers.js';
5
+ export function connectRoutes(ctx) {
6
+ const { app, store } = ctx;
7
+ const ws = getWorkOSStore(store);
8
+ // List applications
9
+ app.get('/connect/applications', (c) => {
10
+ const url = new URL(c.req.url);
11
+ const params = parseListParams(url);
12
+ const result = ws.connectApplications.list({ ...params });
13
+ return c.json({
14
+ object: 'list',
15
+ data: result.data.map(formatConnectApplication),
16
+ list_metadata: result.list_metadata,
17
+ });
18
+ });
19
+ // Create application
20
+ app.post('/connect/applications', async (c) => {
21
+ const body = await parseJsonBody(c);
22
+ const name = body.name;
23
+ if (!name || typeof name !== 'string' || name.trim().length === 0) {
24
+ throw validationError('name is required', [{ field: 'name', code: 'required' }]);
25
+ }
26
+ const application = ws.connectApplications.insert({
27
+ object: 'connect_application',
28
+ name: name.trim(),
29
+ redirect_uris: body.redirect_uris ?? [],
30
+ client_id: `client_${generateId('connect')}`,
31
+ logo_url: body.logo_url ?? null,
32
+ });
33
+ return c.json(formatConnectApplication(application), 201);
34
+ });
35
+ // Get application
36
+ app.get('/connect/applications/:id', (c) => {
37
+ const application = ws.connectApplications.get(c.req.param('id'));
38
+ if (!application)
39
+ throw notFound('ConnectApplication');
40
+ return c.json(formatConnectApplication(application));
41
+ });
42
+ // Create client secret
43
+ app.post('/connect/applications/:id/client_secrets', (c) => {
44
+ const application = ws.connectApplications.get(c.req.param('id'));
45
+ if (!application)
46
+ throw notFound('ConnectApplication');
47
+ const value = `secret_${generateVerificationToken()}`;
48
+ const secret = ws.clientSecrets.insert({
49
+ object: 'client_secret',
50
+ application_id: application.id,
51
+ value,
52
+ last_four: value.slice(-4),
53
+ });
54
+ // Return full value only on creation
55
+ return c.json({
56
+ ...formatClientSecret(secret),
57
+ value: secret.value,
58
+ }, 201);
59
+ });
60
+ // Revoke client secret
61
+ app.delete('/connect/client_secrets/:id', (c) => {
62
+ const secret = ws.clientSecrets.get(c.req.param('id'));
63
+ if (!secret)
64
+ throw notFound('ClientSecret');
65
+ ws.clientSecrets.delete(secret.id);
66
+ return c.body(null, 204);
67
+ });
68
+ }
69
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/connect.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, parseJsonBody, validationError } from '../../core/index.js';\nimport { generateId } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport {\n formatConnectApplication,\n formatClientSecret,\n parseListParams,\n generateVerificationToken,\n} from '../helpers.js';\n\nexport function connectRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n // List applications\n app.get('/connect/applications', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const result = ws.connectApplications.list({ ...params });\n return c.json({\n object: 'list',\n data: result.data.map(formatConnectApplication),\n list_metadata: result.list_metadata,\n });\n });\n\n // Create application\n app.post('/connect/applications', async (c) => {\n const body = await parseJsonBody(c);\n const name = body.name as string | undefined;\n if (!name || typeof name !== 'string' || name.trim().length === 0) {\n throw validationError('name is required', [{ field: 'name', code: 'required' }]);\n }\n\n const application = ws.connectApplications.insert({\n object: 'connect_application',\n name: name.trim(),\n redirect_uris: (body.redirect_uris as string[]) ?? [],\n client_id: `client_${generateId('connect')}`,\n logo_url: (body.logo_url as string) ?? null,\n });\n\n return c.json(formatConnectApplication(application), 201);\n });\n\n // Get application\n app.get('/connect/applications/:id', (c) => {\n const application = ws.connectApplications.get(c.req.param('id'));\n if (!application) throw notFound('ConnectApplication');\n return c.json(formatConnectApplication(application));\n });\n\n // Create client secret\n app.post('/connect/applications/:id/client_secrets', (c) => {\n const application = ws.connectApplications.get(c.req.param('id'));\n if (!application) throw notFound('ConnectApplication');\n\n const value = `secret_${generateVerificationToken()}`;\n const secret = ws.clientSecrets.insert({\n object: 'client_secret',\n application_id: application.id,\n value,\n last_four: value.slice(-4),\n });\n\n // Return full value only on creation\n return c.json(\n {\n ...formatClientSecret(secret),\n value: secret.value,\n },\n 201,\n );\n });\n\n // Revoke client secret\n app.delete('/connect/client_secrets/:id', (c) => {\n const secret = ws.clientSecrets.get(c.req.param('id'));\n if (!secret) throw notFound('ClientSecret');\n ws.clientSecrets.delete(secret.id);\n return c.body(null, 204);\n });\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { type RouteContext } from '../../core/index.js';
2
+ export declare function connectionRoutes(ctx: RouteContext): void;
@@ -0,0 +1,77 @@
1
+ import { notFound, parseJsonBody, generateId } from '../../core/index.js';
2
+ import { getWorkOSStore } from '../store.js';
3
+ import { formatConnection, parseListParams } from '../helpers.js';
4
+ export function connectionRoutes(ctx) {
5
+ const { app, store } = ctx;
6
+ const ws = getWorkOSStore(store);
7
+ app.post('/connections', async (c) => {
8
+ const body = await parseJsonBody(c);
9
+ const name = body.name;
10
+ const organizationId = body.organization_id;
11
+ const connectionType = body.connection_type ?? 'GenericSAML';
12
+ const domainsList = body.domains ?? [];
13
+ if (!organizationId) {
14
+ throw notFound('Organization');
15
+ }
16
+ const org = ws.organizations.get(organizationId);
17
+ if (!org)
18
+ throw notFound('Organization');
19
+ const domains = domainsList.map((d) => ({
20
+ object: 'connection_domain',
21
+ id: generateId('conn_domain'),
22
+ domain: d,
23
+ }));
24
+ const conn = ws.connections.insert({
25
+ object: 'connection',
26
+ organization_id: organizationId,
27
+ connection_type: connectionType,
28
+ name: name ?? `${org.name} SSO`,
29
+ state: 'active',
30
+ domains,
31
+ });
32
+ return c.json(formatConnection(conn), 201);
33
+ });
34
+ app.get('/connections', (c) => {
35
+ const url = new URL(c.req.url);
36
+ const params = parseListParams(url);
37
+ const orgFilter = url.searchParams.get('organization_id') ?? undefined;
38
+ const typeFilter = url.searchParams.get('connection_type') ?? undefined;
39
+ const domainFilter = url.searchParams.get('domain') ?? undefined;
40
+ const result = ws.connections.list({
41
+ ...params,
42
+ filter: (conn) => {
43
+ if (orgFilter && conn.organization_id !== orgFilter)
44
+ return false;
45
+ if (typeFilter && conn.connection_type !== typeFilter)
46
+ return false;
47
+ if (domainFilter && !conn.domains.some((d) => d.domain === domainFilter))
48
+ return false;
49
+ return true;
50
+ },
51
+ });
52
+ return c.json({
53
+ object: 'list',
54
+ data: result.data.map(formatConnection),
55
+ list_metadata: result.list_metadata,
56
+ });
57
+ });
58
+ app.get('/connections/:id', (c) => {
59
+ const conn = ws.connections.get(c.req.param('id'));
60
+ if (!conn)
61
+ throw notFound('Connection');
62
+ return c.json(formatConnection(conn));
63
+ });
64
+ app.delete('/connections/:id', (c) => {
65
+ const conn = ws.connections.get(c.req.param('id'));
66
+ if (!conn)
67
+ throw notFound('Connection');
68
+ for (const auth of ws.ssoAuthorizations.all()) {
69
+ if (auth.connection_id === conn.id) {
70
+ ws.ssoAuthorizations.delete(auth.id);
71
+ }
72
+ }
73
+ ws.connections.delete(conn.id);
74
+ return c.body(null, 204);
75
+ });
76
+ }
77
+ //# sourceMappingURL=connections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/connections.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, parseJsonBody, generateId } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatConnection, parseListParams } from '../helpers.js';\nimport type { WorkOSConnectionType } from '../entities.js';\n\nexport function connectionRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n app.post('/connections', async (c) => {\n const body = await parseJsonBody(c);\n const name = body.name as string;\n const organizationId = body.organization_id as string;\n const connectionType = (body.connection_type as WorkOSConnectionType) ?? 'GenericSAML';\n const domainsList = (body.domains as string[]) ?? [];\n\n if (!organizationId) {\n throw notFound('Organization');\n }\n const org = ws.organizations.get(organizationId);\n if (!org) throw notFound('Organization');\n\n const domains = domainsList.map((d) => ({\n object: 'connection_domain' as const,\n id: generateId('conn_domain'),\n domain: d,\n }));\n\n const conn = ws.connections.insert({\n object: 'connection',\n organization_id: organizationId,\n connection_type: connectionType,\n name: name ?? `${org.name} SSO`,\n state: 'active',\n domains,\n });\n\n return c.json(formatConnection(conn), 201);\n });\n\n app.get('/connections', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const orgFilter = url.searchParams.get('organization_id') ?? undefined;\n const typeFilter = url.searchParams.get('connection_type') ?? undefined;\n const domainFilter = url.searchParams.get('domain') ?? undefined;\n\n const result = ws.connections.list({\n ...params,\n filter: (conn) => {\n if (orgFilter && conn.organization_id !== orgFilter) return false;\n if (typeFilter && conn.connection_type !== typeFilter) return false;\n if (domainFilter && !conn.domains.some((d) => d.domain === domainFilter)) return false;\n return true;\n },\n });\n\n return c.json({\n object: 'list',\n data: result.data.map(formatConnection),\n list_metadata: result.list_metadata,\n });\n });\n\n app.get('/connections/:id', (c) => {\n const conn = ws.connections.get(c.req.param('id'));\n if (!conn) throw notFound('Connection');\n return c.json(formatConnection(conn));\n });\n\n app.delete('/connections/:id', (c) => {\n const conn = ws.connections.get(c.req.param('id'));\n if (!conn) throw notFound('Connection');\n\n for (const auth of ws.ssoAuthorizations.all()) {\n if (auth.connection_id === conn.id) {\n ws.ssoAuthorizations.delete(auth.id);\n }\n }\n\n ws.connections.delete(conn.id);\n return c.body(null, 204);\n });\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { type RouteContext } from '../../core/index.js';
2
+ export declare function dataIntegrationRoutes(ctx: RouteContext): void;