workos 0.12.0-beta.1 → 0.12.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.
- package/README.md +6 -4
- package/dist/bin.js +4 -2
- package/dist/bin.js.map +1 -1
- package/dist/commands/debug.js +0 -1
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/login.js +0 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/emulate/core/id.d.ts +16 -1
- package/dist/emulate/core/id.js +16 -1
- package/dist/emulate/core/id.js.map +1 -1
- package/dist/emulate/core/index.d.ts +1 -1
- package/dist/emulate/core/index.js +1 -1
- package/dist/emulate/core/index.js.map +1 -1
- package/dist/emulate/core/middleware/auth.d.ts +1 -4
- package/dist/emulate/core/middleware/auth.js +7 -18
- package/dist/emulate/core/middleware/auth.js.map +1 -1
- package/dist/emulate/core/pagination.d.ts +6 -0
- package/dist/emulate/core/pagination.js +9 -1
- package/dist/emulate/core/pagination.js.map +1 -1
- package/dist/emulate/core/server.js +20 -46
- package/dist/emulate/core/server.js.map +1 -1
- package/dist/emulate/core/store.d.ts +2 -0
- package/dist/emulate/core/store.js +22 -1
- package/dist/emulate/core/store.js.map +1 -1
- package/dist/emulate/workos/constants.d.ts +56 -0
- package/dist/emulate/workos/constants.js +56 -0
- package/dist/emulate/workos/constants.js.map +1 -0
- package/dist/emulate/workos/entities.js.map +1 -1
- package/dist/emulate/workos/event-bus.d.ts +6 -1
- package/dist/emulate/workos/event-bus.js +33 -8
- package/dist/emulate/workos/event-bus.js.map +1 -1
- package/dist/emulate/workos/helpers.d.ts +17 -8
- package/dist/emulate/workos/helpers.js +61 -368
- package/dist/emulate/workos/helpers.js.map +1 -1
- package/dist/emulate/workos/index.js +42 -39
- package/dist/emulate/workos/index.js.map +1 -1
- package/dist/emulate/workos/role-helpers.d.ts +21 -0
- package/dist/emulate/workos/role-helpers.js +130 -0
- package/dist/emulate/workos/role-helpers.js.map +1 -0
- package/dist/emulate/workos/routes/api-keys.js +5 -8
- package/dist/emulate/workos/routes/api-keys.js.map +1 -1
- package/dist/emulate/workos/routes/audit-logs.js +6 -9
- package/dist/emulate/workos/routes/audit-logs.js.map +1 -1
- package/dist/emulate/workos/routes/auth.js +7 -6
- package/dist/emulate/workos/routes/auth.js.map +1 -1
- package/dist/emulate/workos/routes/authorization-checks.js +5 -17
- package/dist/emulate/workos/routes/authorization-checks.js.map +1 -1
- package/dist/emulate/workos/routes/authorization-org-roles.js +29 -171
- package/dist/emulate/workos/routes/authorization-org-roles.js.map +1 -1
- package/dist/emulate/workos/routes/authorization-permissions.js +5 -16
- package/dist/emulate/workos/routes/authorization-permissions.js.map +1 -1
- package/dist/emulate/workos/routes/authorization-resources.js +4 -15
- package/dist/emulate/workos/routes/authorization-resources.js.map +1 -1
- package/dist/emulate/workos/routes/authorization-roles.d.ts +1 -1
- package/dist/emulate/workos/routes/authorization-roles.js +9 -132
- package/dist/emulate/workos/routes/authorization-roles.js.map +1 -1
- package/dist/emulate/workos/routes/config.js +3 -2
- package/dist/emulate/workos/routes/config.js.map +1 -1
- package/dist/emulate/workos/routes/connect.js +3 -7
- package/dist/emulate/workos/routes/connect.js.map +1 -1
- package/dist/emulate/workos/routes/connections.js +3 -7
- package/dist/emulate/workos/routes/connections.js.map +1 -1
- package/dist/emulate/workos/routes/directories.js +7 -23
- package/dist/emulate/workos/routes/directories.js.map +1 -1
- package/dist/emulate/workos/routes/events.js +3 -6
- package/dist/emulate/workos/routes/events.js.map +1 -1
- package/dist/emulate/workos/routes/feature-flags.js +20 -48
- package/dist/emulate/workos/routes/feature-flags.js.map +1 -1
- package/dist/emulate/workos/routes/invitations.js +10 -13
- package/dist/emulate/workos/routes/invitations.js.map +1 -1
- package/dist/emulate/workos/routes/memberships.js +3 -7
- package/dist/emulate/workos/routes/memberships.js.map +1 -1
- package/dist/emulate/workos/routes/organizations.js +13 -15
- package/dist/emulate/workos/routes/organizations.js.map +1 -1
- package/dist/emulate/workos/routes/pipes.js +3 -7
- package/dist/emulate/workos/routes/pipes.js.map +1 -1
- package/dist/emulate/workos/routes/radar.js +3 -7
- package/dist/emulate/workos/routes/radar.js.map +1 -1
- package/dist/emulate/workos/routes/sso.js +7 -6
- package/dist/emulate/workos/routes/sso.js.map +1 -1
- package/dist/emulate/workos/routes/users.js +3 -7
- package/dist/emulate/workos/routes/users.js.map +1 -1
- package/dist/emulate/workos/routes/webhook-endpoints.js +3 -7
- package/dist/emulate/workos/routes/webhook-endpoints.js.map +1 -1
- package/dist/emulate/workos/store.js +68 -59
- package/dist/emulate/workos/store.js.map +1 -1
- package/dist/lib/run-with-core.js +0 -3
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/settings.js +1 -1
- package/dist/lib/settings.js.map +1 -1
- package/dist/utils/help-json.js +1 -23
- package/dist/utils/help-json.js.map +1 -1
- package/dist/utils/register-subcommand.d.ts +5 -2
- package/dist/utils/register-subcommand.js +16 -19
- package/dist/utils/register-subcommand.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/connections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
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, parseListParams } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatConnection, formatListResponse } 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(formatListResponse(result, formatConnection));\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"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { notFound } from '../../core/index.js';
|
|
1
|
+
import { notFound, parseListParams } from '../../core/index.js';
|
|
2
2
|
import { getWorkOSStore } from '../store.js';
|
|
3
|
-
import { formatDirectory, formatDirectoryUser, formatDirectoryGroup,
|
|
3
|
+
import { formatDirectory, formatDirectoryUser, formatDirectoryGroup, formatListResponse } from '../helpers.js';
|
|
4
4
|
export function directoryRoutes(ctx) {
|
|
5
5
|
const { app, store } = ctx;
|
|
6
6
|
const ws = getWorkOSStore(store);
|
|
@@ -20,11 +20,7 @@ export function directoryRoutes(ctx) {
|
|
|
20
20
|
return true;
|
|
21
21
|
},
|
|
22
22
|
});
|
|
23
|
-
return c.json(
|
|
24
|
-
object: 'list',
|
|
25
|
-
data: result.data.map(formatDirectory),
|
|
26
|
-
list_metadata: result.list_metadata,
|
|
27
|
-
});
|
|
23
|
+
return c.json(formatListResponse(result, formatDirectory));
|
|
28
24
|
});
|
|
29
25
|
// Get directory
|
|
30
26
|
app.get('/directories/:id', (c) => {
|
|
@@ -38,12 +34,8 @@ export function directoryRoutes(ctx) {
|
|
|
38
34
|
const dir = ws.directories.get(c.req.param('id'));
|
|
39
35
|
if (!dir)
|
|
40
36
|
throw notFound('Directory');
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
ws.directoryUsers.delete(u.id);
|
|
44
|
-
const groups = ws.directoryGroups.findBy('directory_id', dir.id);
|
|
45
|
-
for (const g of groups)
|
|
46
|
-
ws.directoryGroups.delete(g.id);
|
|
37
|
+
ws.directoryUsers.deleteBy('directory_id', dir.id);
|
|
38
|
+
ws.directoryGroups.deleteBy('directory_id', dir.id);
|
|
47
39
|
ws.directories.delete(dir.id);
|
|
48
40
|
return c.body(null, 204);
|
|
49
41
|
});
|
|
@@ -63,11 +55,7 @@ export function directoryRoutes(ctx) {
|
|
|
63
55
|
return true;
|
|
64
56
|
},
|
|
65
57
|
});
|
|
66
|
-
return c.json(
|
|
67
|
-
object: 'list',
|
|
68
|
-
data: result.data.map(formatDirectoryUser),
|
|
69
|
-
list_metadata: result.list_metadata,
|
|
70
|
-
});
|
|
58
|
+
return c.json(formatListResponse(result, formatDirectoryUser));
|
|
71
59
|
});
|
|
72
60
|
// Get directory user
|
|
73
61
|
app.get('/directory_users/:id', (c) => {
|
|
@@ -89,11 +77,7 @@ export function directoryRoutes(ctx) {
|
|
|
89
77
|
return true;
|
|
90
78
|
},
|
|
91
79
|
});
|
|
92
|
-
return c.json(
|
|
93
|
-
object: 'list',
|
|
94
|
-
data: result.data.map(formatDirectoryGroup),
|
|
95
|
-
list_metadata: result.list_metadata,
|
|
96
|
-
});
|
|
80
|
+
return c.json(formatListResponse(result, formatDirectoryGroup));
|
|
97
81
|
});
|
|
98
82
|
// Get directory group
|
|
99
83
|
app.get('/directory_groups/:id', (c) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directories.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/directories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"directories.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/directories.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, parseListParams } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatDirectory, formatDirectoryUser, formatDirectoryGroup, formatListResponse } from '../helpers.js';\n\nexport function directoryRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n // List directories\n app.get('/directories', (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 search = url.searchParams.get('search') ?? undefined;\n\n const result = ws.directories.list({\n ...params,\n filter: (d) => {\n if (orgFilter && d.organization_id !== orgFilter) return false;\n if (search && !d.name.toLowerCase().includes(search.toLowerCase())) return false;\n return true;\n },\n });\n\n return c.json(formatListResponse(result, formatDirectory));\n });\n\n // Get directory\n app.get('/directories/:id', (c) => {\n const dir = ws.directories.get(c.req.param('id'));\n if (!dir) throw notFound('Directory');\n return c.json(formatDirectory(dir));\n });\n\n // Delete directory (cascade users + groups)\n app.delete('/directories/:id', (c) => {\n const dir = ws.directories.get(c.req.param('id'));\n if (!dir) throw notFound('Directory');\n\n ws.directoryUsers.deleteBy('directory_id', dir.id);\n ws.directoryGroups.deleteBy('directory_id', dir.id);\n\n ws.directories.delete(dir.id);\n return c.body(null, 204);\n });\n\n // List directory users\n app.get('/directory_users', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const directoryId = url.searchParams.get('directory_id') ?? undefined;\n const groupId = url.searchParams.get('group_id') ?? undefined;\n\n const result = ws.directoryUsers.list({\n ...params,\n filter: (u) => {\n if (directoryId && u.directory_id !== directoryId) return false;\n if (groupId && !u.groups.some((g) => g.id === groupId)) return false;\n return true;\n },\n });\n\n return c.json(formatListResponse(result, formatDirectoryUser));\n });\n\n // Get directory user\n app.get('/directory_users/:id', (c) => {\n const user = ws.directoryUsers.get(c.req.param('id'));\n if (!user) throw notFound('DirectoryUser');\n return c.json(formatDirectoryUser(user));\n });\n\n // List directory groups\n app.get('/directory_groups', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const directoryId = url.searchParams.get('directory_id') ?? undefined;\n\n const result = ws.directoryGroups.list({\n ...params,\n filter: (g) => {\n if (directoryId && g.directory_id !== directoryId) return false;\n return true;\n },\n });\n\n return c.json(formatListResponse(result, formatDirectoryGroup));\n });\n\n // Get directory group\n app.get('/directory_groups/:id', (c) => {\n const group = ws.directoryGroups.get(c.req.param('id'));\n if (!group) throw notFound('DirectoryGroup');\n return c.json(formatDirectoryGroup(group));\n });\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { parseListParams } from '../../core/index.js';
|
|
1
2
|
import { getWorkOSStore } from '../store.js';
|
|
2
|
-
import { formatEvent,
|
|
3
|
+
import { formatEvent, formatListResponse } from '../helpers.js';
|
|
3
4
|
export function eventRoutes(ctx) {
|
|
4
5
|
const { app, store } = ctx;
|
|
5
6
|
const ws = getWorkOSStore(store);
|
|
@@ -11,11 +12,7 @@ export function eventRoutes(ctx) {
|
|
|
11
12
|
...params,
|
|
12
13
|
filter: eventTypes.length > 0 ? (e) => eventTypes.includes(e.event) : undefined,
|
|
13
14
|
});
|
|
14
|
-
return c.json(
|
|
15
|
-
object: 'list',
|
|
16
|
-
data: result.data.map(formatEvent),
|
|
17
|
-
list_metadata: result.list_metadata,
|
|
18
|
-
});
|
|
15
|
+
return c.json(formatListResponse(result, formatEvent));
|
|
19
16
|
});
|
|
20
17
|
}
|
|
21
18
|
//# sourceMappingURL=events.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEhE,MAAM,UAAU,WAAW,CAAC,GAAiB;IAC3C,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;IAC3B,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAEjC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACvB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;YAC5B,GAAG,MAAM;YACT,MAAM,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;SAChF,CAAC,CAAC;QAEH,OAAO,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { type RouteContext, parseListParams } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatEvent, formatListResponse } from '../helpers.js';\n\nexport function eventRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n app.get('/events', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const eventTypes = url.searchParams.getAll('events[]');\n\n const result = ws.events.list({\n ...params,\n filter: eventTypes.length > 0 ? (e) => eventTypes.includes(e.event) : undefined,\n });\n\n return c.json(formatListResponse(result, formatEvent));\n });\n}\n"]}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import { notFound, parseJsonBody } from '../../core/index.js';
|
|
1
|
+
import { notFound, parseJsonBody, parseListParams } from '../../core/index.js';
|
|
2
2
|
import { getWorkOSStore } from '../store.js';
|
|
3
|
-
import { formatFeatureFlag,
|
|
3
|
+
import { formatFeatureFlag, formatFlagTarget, formatListResponse } from '../helpers.js';
|
|
4
|
+
function evaluateFlags(ws, resourceId) {
|
|
5
|
+
const flags = ws.featureFlags.all();
|
|
6
|
+
return flags.map((flag) => {
|
|
7
|
+
const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === resourceId);
|
|
8
|
+
return {
|
|
9
|
+
slug: flag.slug,
|
|
10
|
+
type: flag.type,
|
|
11
|
+
value: target ? target.value : flag.enabled ? flag.default_value : null,
|
|
12
|
+
enabled: flag.enabled,
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
}
|
|
4
16
|
export function featureFlagRoutes(ctx) {
|
|
5
17
|
const { app, store } = ctx;
|
|
6
18
|
const ws = getWorkOSStore(store);
|
|
@@ -9,11 +21,7 @@ export function featureFlagRoutes(ctx) {
|
|
|
9
21
|
const url = new URL(c.req.url);
|
|
10
22
|
const params = parseListParams(url);
|
|
11
23
|
const result = ws.featureFlags.list({ ...params });
|
|
12
|
-
return c.json(
|
|
13
|
-
object: 'list',
|
|
14
|
-
data: result.data.map(formatFeatureFlag),
|
|
15
|
-
list_metadata: result.list_metadata,
|
|
16
|
-
});
|
|
24
|
+
return c.json(formatListResponse(result, formatFeatureFlag));
|
|
17
25
|
});
|
|
18
26
|
// Get flag by slug
|
|
19
27
|
app.get('/feature-flags/:slug', (c) => {
|
|
@@ -52,14 +60,7 @@ export function featureFlagRoutes(ctx) {
|
|
|
52
60
|
value: body.value,
|
|
53
61
|
resource_type: body.resource_type ?? existing.resource_type,
|
|
54
62
|
});
|
|
55
|
-
return c.json(
|
|
56
|
-
object: 'flag_target',
|
|
57
|
-
id: updated.id,
|
|
58
|
-
flag_slug: updated.flag_slug,
|
|
59
|
-
resource_id: updated.resource_id,
|
|
60
|
-
resource_type: updated.resource_type,
|
|
61
|
-
value: updated.value,
|
|
62
|
-
});
|
|
63
|
+
return c.json(formatFlagTarget(updated));
|
|
63
64
|
}
|
|
64
65
|
const target = ws.flagTargets.insert({
|
|
65
66
|
object: 'flag_target',
|
|
@@ -68,14 +69,7 @@ export function featureFlagRoutes(ctx) {
|
|
|
68
69
|
resource_type: body.resource_type ?? 'user',
|
|
69
70
|
value: body.value,
|
|
70
71
|
});
|
|
71
|
-
return c.json(
|
|
72
|
-
object: 'flag_target',
|
|
73
|
-
id: target.id,
|
|
74
|
-
flag_slug: target.flag_slug,
|
|
75
|
-
resource_id: target.resource_id,
|
|
76
|
-
resource_type: target.resource_type,
|
|
77
|
-
value: target.value,
|
|
78
|
-
}, 201);
|
|
72
|
+
return c.json(formatFlagTarget(target), 201);
|
|
79
73
|
});
|
|
80
74
|
// Remove target
|
|
81
75
|
app.delete('/feature-flags/:slug/targets/:resourceId', (c) => {
|
|
@@ -91,39 +85,17 @@ export function featureFlagRoutes(ctx) {
|
|
|
91
85
|
});
|
|
92
86
|
// Evaluate flags for organization
|
|
93
87
|
app.get('/organizations/:orgId/feature-flags', (c) => {
|
|
94
|
-
const orgId = c.req.param('orgId');
|
|
95
|
-
const flags = ws.featureFlags.all();
|
|
96
|
-
const evaluations = flags.map((flag) => {
|
|
97
|
-
const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === orgId);
|
|
98
|
-
return {
|
|
99
|
-
slug: flag.slug,
|
|
100
|
-
type: flag.type,
|
|
101
|
-
value: target ? target.value : flag.enabled ? flag.default_value : null,
|
|
102
|
-
enabled: flag.enabled,
|
|
103
|
-
};
|
|
104
|
-
});
|
|
105
88
|
return c.json({
|
|
106
89
|
object: 'list',
|
|
107
|
-
data:
|
|
90
|
+
data: evaluateFlags(ws, c.req.param('orgId')),
|
|
108
91
|
list_metadata: { before: null, after: null },
|
|
109
92
|
});
|
|
110
93
|
});
|
|
111
|
-
// Evaluate flags for user
|
|
94
|
+
// Evaluate flags for user
|
|
112
95
|
app.get('/user_management/users/:userId/feature-flags', (c) => {
|
|
113
|
-
const userId = c.req.param('userId');
|
|
114
|
-
const flags = ws.featureFlags.all();
|
|
115
|
-
const evaluations = flags.map((flag) => {
|
|
116
|
-
const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === userId);
|
|
117
|
-
return {
|
|
118
|
-
slug: flag.slug,
|
|
119
|
-
type: flag.type,
|
|
120
|
-
value: target ? target.value : flag.enabled ? flag.default_value : null,
|
|
121
|
-
enabled: flag.enabled,
|
|
122
|
-
};
|
|
123
|
-
});
|
|
124
96
|
return c.json({
|
|
125
97
|
object: 'list',
|
|
126
|
-
data:
|
|
98
|
+
data: evaluateFlags(ws, c.req.param('userId')),
|
|
127
99
|
list_metadata: { before: null, after: null },
|
|
128
100
|
});
|
|
129
101
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/feature-flags.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, parseJsonBody } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatFeatureFlag, parseListParams } from '../helpers.js';\n\nexport function featureFlagRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n // List all flags\n app.get('/feature-flags', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const result = ws.featureFlags.list({ ...params });\n return c.json({\n object: 'list',\n data: result.data.map(formatFeatureFlag),\n list_metadata: result.list_metadata,\n });\n });\n\n // Get flag by slug\n app.get('/feature-flags/:slug', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n return c.json(formatFeatureFlag(flag));\n });\n\n // Enable flag\n app.post('/feature-flags/:slug/enable', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n const updated = ws.featureFlags.update(flag.id, { enabled: true });\n return c.json(formatFeatureFlag(updated!));\n });\n\n // Disable flag\n app.post('/feature-flags/:slug/disable', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n const updated = ws.featureFlags.update(flag.id, { enabled: false });\n return c.json(formatFeatureFlag(updated!));\n });\n\n // Add/update target\n app.put('/feature-flags/:slug/targets/:resourceId', async (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n\n const resourceId = c.req.param('resourceId');\n const body = await parseJsonBody(c);\n\n // Upsert: find existing target or create\n const existing = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === resourceId);\n\n if (existing) {\n const updated = ws.flagTargets.update(existing.id, {\n value: body.value,\n resource_type: (body.resource_type as string) ?? existing.resource_type,\n });\n return c.json({\n object: 'flag_target',\n id: updated!.id,\n flag_slug: updated!.flag_slug,\n resource_id: updated!.resource_id,\n resource_type: updated!.resource_type,\n value: updated!.value,\n });\n }\n\n const target = ws.flagTargets.insert({\n object: 'flag_target',\n flag_slug: flag.slug,\n resource_id: resourceId,\n resource_type: (body.resource_type as string) ?? 'user',\n value: body.value,\n });\n\n return c.json(\n {\n object: 'flag_target',\n id: target.id,\n flag_slug: target.flag_slug,\n resource_id: target.resource_id,\n resource_type: target.resource_type,\n value: target.value,\n },\n 201,\n );\n });\n\n // Remove target\n app.delete('/feature-flags/:slug/targets/:resourceId', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n\n const resourceId = c.req.param('resourceId');\n const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === resourceId);\n if (!target) throw notFound('FlagTarget');\n\n ws.flagTargets.delete(target.id);\n return c.body(null, 204);\n });\n\n // Evaluate flags for organization\n app.get('/organizations/:orgId/feature-flags', (c) => {\n const orgId = c.req.param('orgId');\n const flags = ws.featureFlags.all();\n\n const evaluations = flags.map((flag) => {\n const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === orgId);\n\n return {\n slug: flag.slug,\n type: flag.type,\n value: target ? target.value : flag.enabled ? flag.default_value : null,\n enabled: flag.enabled,\n };\n });\n\n return c.json({\n object: 'list',\n data: evaluations,\n list_metadata: { before: null, after: null },\n });\n });\n\n // Evaluate flags for user (replaces stub in user-features.ts)\n app.get('/user_management/users/:userId/feature-flags', (c) => {\n const userId = c.req.param('userId');\n const flags = ws.featureFlags.all();\n\n const evaluations = flags.map((flag) => {\n const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === userId);\n\n return {\n slug: flag.slug,\n type: flag.type,\n value: target ? target.value : flag.enabled ? flag.default_value : null,\n enabled: flag.enabled,\n };\n });\n\n return c.json({\n object: 'list',\n data: evaluations,\n list_metadata: { before: null, after: null },\n });\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/feature-flags.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, parseJsonBody, parseListParams } from '../../core/index.js';\nimport { getWorkOSStore, type WorkOSStore } from '../store.js';\nimport { formatFeatureFlag, formatFlagTarget, formatListResponse } from '../helpers.js';\n\nfunction evaluateFlags(ws: WorkOSStore, resourceId: string) {\n const flags = ws.featureFlags.all();\n return flags.map((flag) => {\n const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === resourceId);\n return {\n slug: flag.slug,\n type: flag.type,\n value: target ? target.value : flag.enabled ? flag.default_value : null,\n enabled: flag.enabled,\n };\n });\n}\n\nexport function featureFlagRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n // List all flags\n app.get('/feature-flags', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const result = ws.featureFlags.list({ ...params });\n return c.json(formatListResponse(result, formatFeatureFlag));\n });\n\n // Get flag by slug\n app.get('/feature-flags/:slug', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n return c.json(formatFeatureFlag(flag));\n });\n\n // Enable flag\n app.post('/feature-flags/:slug/enable', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n const updated = ws.featureFlags.update(flag.id, { enabled: true });\n return c.json(formatFeatureFlag(updated!));\n });\n\n // Disable flag\n app.post('/feature-flags/:slug/disable', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n const updated = ws.featureFlags.update(flag.id, { enabled: false });\n return c.json(formatFeatureFlag(updated!));\n });\n\n // Add/update target\n app.put('/feature-flags/:slug/targets/:resourceId', async (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n\n const resourceId = c.req.param('resourceId');\n const body = await parseJsonBody(c);\n\n // Upsert: find existing target or create\n const existing = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === resourceId);\n\n if (existing) {\n const updated = ws.flagTargets.update(existing.id, {\n value: body.value,\n resource_type: (body.resource_type as string) ?? existing.resource_type,\n });\n return c.json(formatFlagTarget(updated!));\n }\n\n const target = ws.flagTargets.insert({\n object: 'flag_target',\n flag_slug: flag.slug,\n resource_id: resourceId,\n resource_type: (body.resource_type as string) ?? 'user',\n value: body.value,\n });\n\n return c.json(formatFlagTarget(target), 201);\n });\n\n // Remove target\n app.delete('/feature-flags/:slug/targets/:resourceId', (c) => {\n const flag = ws.featureFlags.findOneBy('slug', c.req.param('slug'));\n if (!flag) throw notFound('FeatureFlag');\n\n const resourceId = c.req.param('resourceId');\n const target = ws.flagTargets.findBy('flag_slug', flag.slug).find((t) => t.resource_id === resourceId);\n if (!target) throw notFound('FlagTarget');\n\n ws.flagTargets.delete(target.id);\n return c.body(null, 204);\n });\n\n // Evaluate flags for organization\n app.get('/organizations/:orgId/feature-flags', (c) => {\n return c.json({\n object: 'list',\n data: evaluateFlags(ws, c.req.param('orgId')),\n list_metadata: { before: null, after: null },\n });\n });\n\n // Evaluate flags for user\n app.get('/user_management/users/:userId/feature-flags', (c) => {\n return c.json({\n object: 'list',\n data: evaluateFlags(ws, c.req.param('userId')),\n list_metadata: { before: null, after: null },\n });\n });\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { notFound, validationError, parseJsonBody, WorkOSApiError } from '../../core/index.js';
|
|
1
|
+
import { notFound, validationError, parseJsonBody, WorkOSApiError, parseListParams, } from '../../core/index.js';
|
|
2
2
|
import { getWorkOSStore } from '../store.js';
|
|
3
|
-
import { formatInvitation, generateVerificationToken, expiresIn,
|
|
3
|
+
import { formatInvitation, generateVerificationToken, expiresIn, formatListResponse } from '../helpers.js';
|
|
4
|
+
import { STORE_KEYS, EVENTS } from '../constants.js';
|
|
4
5
|
export function invitationRoutes(ctx) {
|
|
5
6
|
const { app, store, baseUrl } = ctx;
|
|
6
7
|
const ws = getWorkOSStore(store);
|
|
@@ -39,11 +40,7 @@ export function invitationRoutes(ctx) {
|
|
|
39
40
|
return true;
|
|
40
41
|
},
|
|
41
42
|
});
|
|
42
|
-
return c.json(
|
|
43
|
-
object: 'list',
|
|
44
|
-
data: result.data.map(formatInvitation),
|
|
45
|
-
list_metadata: result.list_metadata,
|
|
46
|
-
});
|
|
43
|
+
return c.json(formatListResponse(result, formatInvitation));
|
|
47
44
|
});
|
|
48
45
|
app.get('/user_management/invitations/by_token/:token', (c) => {
|
|
49
46
|
const inv = ws.invitations.findOneBy('token', c.req.param('token'));
|
|
@@ -65,8 +62,8 @@ export function invitationRoutes(ctx) {
|
|
|
65
62
|
throw new WorkOSApiError(400, `Invitation is ${inv.state}`, 'invalid_invitation_state');
|
|
66
63
|
}
|
|
67
64
|
ws.invitations.update(inv.id, { state: 'accepted' });
|
|
68
|
-
const eventBus = store.getData(
|
|
69
|
-
eventBus?.emit({ event:
|
|
65
|
+
const eventBus = store.getData(STORE_KEYS.eventBus);
|
|
66
|
+
eventBus?.emit({ event: EVENTS.invitationAccepted, data: formatInvitation(ws.invitations.get(inv.id)) });
|
|
70
67
|
// Create org membership if invitation has an organization
|
|
71
68
|
if (inv.organization_id) {
|
|
72
69
|
const user = ws.users.findOneBy('email', inv.email);
|
|
@@ -93,8 +90,8 @@ export function invitationRoutes(ctx) {
|
|
|
93
90
|
throw new WorkOSApiError(400, `Invitation is ${inv.state}`, 'invalid_invitation_state');
|
|
94
91
|
}
|
|
95
92
|
ws.invitations.update(inv.id, { state: 'revoked' });
|
|
96
|
-
const eventBus = store.getData(
|
|
97
|
-
eventBus?.emit({ event:
|
|
93
|
+
const eventBus = store.getData(STORE_KEYS.eventBus);
|
|
94
|
+
eventBus?.emit({ event: EVENTS.invitationRevoked, data: formatInvitation(ws.invitations.get(inv.id)) });
|
|
98
95
|
const updated = ws.invitations.get(inv.id);
|
|
99
96
|
return c.json(formatInvitation(updated));
|
|
100
97
|
});
|
|
@@ -109,8 +106,8 @@ export function invitationRoutes(ctx) {
|
|
|
109
106
|
expires_at: expiresIn(72 * 60),
|
|
110
107
|
state: 'pending',
|
|
111
108
|
});
|
|
112
|
-
const eventBus = store.getData(
|
|
113
|
-
eventBus?.emit({ event:
|
|
109
|
+
const eventBus = store.getData(STORE_KEYS.eventBus);
|
|
110
|
+
eventBus?.emit({ event: EVENTS.invitationResent, data: formatInvitation(ws.invitations.get(inv.id)) });
|
|
114
111
|
const updated = ws.invitations.get(inv.id);
|
|
115
112
|
return c.json(formatInvitation(updated));
|
|
116
113
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invitations.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/invitations.ts"],"names":[],"mappings":"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","sourcesContent":["import { type RouteContext, notFound, validationError, parseJsonBody, WorkOSApiError } from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatInvitation, generateVerificationToken, expiresIn, parseListParams } from '../helpers.js';\nimport type { EventBus } from '../event-bus.js';\n\nexport function invitationRoutes(ctx: RouteContext): void {\n const { app, store, baseUrl } = ctx;\n const ws = getWorkOSStore(store);\n\n app.post('/user_management/invitations', async (c) => {\n const body = await parseJsonBody(c);\n const email = body.email as string | undefined;\n if (!email) {\n throw validationError('email is required', [{ field: 'email', code: 'required' }]);\n }\n\n const token = generateVerificationToken();\n const inv = ws.invitations.insert({\n object: 'invitation',\n email,\n state: 'pending',\n token,\n accept_invitation_url: `${baseUrl}/user_management/invitations/accept?token=${token}`,\n organization_id: (body.organization_id as string) ?? null,\n inviter_user_id: (body.inviter_user_id as string) ?? null,\n role_slug: (body.role_slug as string) ?? null,\n expires_at: expiresIn(72 * 60), // 72 hours\n });\n\n return c.json(formatInvitation(inv), 201);\n });\n\n app.get('/user_management/invitations', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const emailFilter = url.searchParams.get('email') ?? undefined;\n const orgFilter = url.searchParams.get('organization_id') ?? undefined;\n\n const result = ws.invitations.list({\n ...params,\n filter: (inv) => {\n if (emailFilter && inv.email !== emailFilter) return false;\n if (orgFilter && inv.organization_id !== orgFilter) return false;\n return true;\n },\n });\n\n return c.json({\n object: 'list',\n data: result.data.map(formatInvitation),\n list_metadata: result.list_metadata,\n });\n });\n\n app.get('/user_management/invitations/by_token/:token', (c) => {\n const inv = ws.invitations.findOneBy('token', c.req.param('token'));\n if (!inv) throw notFound('Invitation');\n return c.json(formatInvitation(inv));\n });\n\n app.get('/user_management/invitations/:id', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n return c.json(formatInvitation(inv));\n });\n\n app.post('/user_management/invitations/:id/accept', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n\n if (inv.state !== 'pending') {\n throw new WorkOSApiError(400, `Invitation is ${inv.state}`, 'invalid_invitation_state');\n }\n\n ws.invitations.update(inv.id, { state: 'accepted' });\n const eventBus = store.getData<EventBus>('eventBus');\n eventBus?.emit({ event: 'invitation.accepted', data: formatInvitation(ws.invitations.get(inv.id)!) });\n\n // Create org membership if invitation has an organization\n if (inv.organization_id) {\n const user = ws.users.findOneBy('email', inv.email);\n if (user) {\n ws.organizationMemberships.insert({\n object: 'organization_membership',\n organization_id: inv.organization_id,\n user_id: user.id,\n role: { slug: inv.role_slug ?? 'member' },\n status: 'active',\n external_id: null,\n metadata: {},\n });\n }\n }\n\n const updated = ws.invitations.get(inv.id)!;\n return c.json(formatInvitation(updated));\n });\n\n app.post('/user_management/invitations/:id/revoke', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n\n if (inv.state !== 'pending') {\n throw new WorkOSApiError(400, `Invitation is ${inv.state}`, 'invalid_invitation_state');\n }\n\n ws.invitations.update(inv.id, { state: 'revoked' });\n const eventBus = store.getData<EventBus>('eventBus');\n eventBus?.emit({ event: 'invitation.revoked', data: formatInvitation(ws.invitations.get(inv.id)!) });\n const updated = ws.invitations.get(inv.id)!;\n return c.json(formatInvitation(updated));\n });\n\n app.post('/user_management/invitations/:id/resend', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n\n const newToken = generateVerificationToken();\n ws.invitations.update(inv.id, {\n token: newToken,\n accept_invitation_url: `${baseUrl}/user_management/invitations/accept?token=${newToken}`,\n expires_at: expiresIn(72 * 60),\n state: 'pending',\n });\n\n const eventBus = store.getData<EventBus>('eventBus');\n eventBus?.emit({ event: 'invitation.resent', data: formatInvitation(ws.invitations.get(inv.id)!) });\n const updated = ws.invitations.get(inv.id)!;\n return c.json(formatInvitation(updated));\n });\n\n app.delete('/user_management/invitations/:id', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n ws.invitations.delete(inv.id);\n return c.body(null, 204);\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"invitations.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/invitations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type RouteContext,\n notFound,\n validationError,\n parseJsonBody,\n WorkOSApiError,\n parseListParams,\n} from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatInvitation, generateVerificationToken, expiresIn, formatListResponse } from '../helpers.js';\nimport type { EventBus } from '../event-bus.js';\nimport { STORE_KEYS, EVENTS } from '../constants.js';\n\nexport function invitationRoutes(ctx: RouteContext): void {\n const { app, store, baseUrl } = ctx;\n const ws = getWorkOSStore(store);\n\n app.post('/user_management/invitations', async (c) => {\n const body = await parseJsonBody(c);\n const email = body.email as string | undefined;\n if (!email) {\n throw validationError('email is required', [{ field: 'email', code: 'required' }]);\n }\n\n const token = generateVerificationToken();\n const inv = ws.invitations.insert({\n object: 'invitation',\n email,\n state: 'pending',\n token,\n accept_invitation_url: `${baseUrl}/user_management/invitations/accept?token=${token}`,\n organization_id: (body.organization_id as string) ?? null,\n inviter_user_id: (body.inviter_user_id as string) ?? null,\n role_slug: (body.role_slug as string) ?? null,\n expires_at: expiresIn(72 * 60), // 72 hours\n });\n\n return c.json(formatInvitation(inv), 201);\n });\n\n app.get('/user_management/invitations', (c) => {\n const url = new URL(c.req.url);\n const params = parseListParams(url);\n const emailFilter = url.searchParams.get('email') ?? undefined;\n const orgFilter = url.searchParams.get('organization_id') ?? undefined;\n\n const result = ws.invitations.list({\n ...params,\n filter: (inv) => {\n if (emailFilter && inv.email !== emailFilter) return false;\n if (orgFilter && inv.organization_id !== orgFilter) return false;\n return true;\n },\n });\n\n return c.json(formatListResponse(result, formatInvitation));\n });\n\n app.get('/user_management/invitations/by_token/:token', (c) => {\n const inv = ws.invitations.findOneBy('token', c.req.param('token'));\n if (!inv) throw notFound('Invitation');\n return c.json(formatInvitation(inv));\n });\n\n app.get('/user_management/invitations/:id', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n return c.json(formatInvitation(inv));\n });\n\n app.post('/user_management/invitations/:id/accept', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n\n if (inv.state !== 'pending') {\n throw new WorkOSApiError(400, `Invitation is ${inv.state}`, 'invalid_invitation_state');\n }\n\n ws.invitations.update(inv.id, { state: 'accepted' });\n const eventBus = store.getData<EventBus>(STORE_KEYS.eventBus);\n eventBus?.emit({ event: EVENTS.invitationAccepted, data: formatInvitation(ws.invitations.get(inv.id)!) });\n\n // Create org membership if invitation has an organization\n if (inv.organization_id) {\n const user = ws.users.findOneBy('email', inv.email);\n if (user) {\n ws.organizationMemberships.insert({\n object: 'organization_membership',\n organization_id: inv.organization_id,\n user_id: user.id,\n role: { slug: inv.role_slug ?? 'member' },\n status: 'active',\n external_id: null,\n metadata: {},\n });\n }\n }\n\n const updated = ws.invitations.get(inv.id)!;\n return c.json(formatInvitation(updated));\n });\n\n app.post('/user_management/invitations/:id/revoke', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n\n if (inv.state !== 'pending') {\n throw new WorkOSApiError(400, `Invitation is ${inv.state}`, 'invalid_invitation_state');\n }\n\n ws.invitations.update(inv.id, { state: 'revoked' });\n const eventBus = store.getData<EventBus>(STORE_KEYS.eventBus);\n eventBus?.emit({ event: EVENTS.invitationRevoked, data: formatInvitation(ws.invitations.get(inv.id)!) });\n const updated = ws.invitations.get(inv.id)!;\n return c.json(formatInvitation(updated));\n });\n\n app.post('/user_management/invitations/:id/resend', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n\n const newToken = generateVerificationToken();\n ws.invitations.update(inv.id, {\n token: newToken,\n accept_invitation_url: `${baseUrl}/user_management/invitations/accept?token=${newToken}`,\n expires_at: expiresIn(72 * 60),\n state: 'pending',\n });\n\n const eventBus = store.getData<EventBus>(STORE_KEYS.eventBus);\n eventBus?.emit({ event: EVENTS.invitationResent, data: formatInvitation(ws.invitations.get(inv.id)!) });\n const updated = ws.invitations.get(inv.id)!;\n return c.json(formatInvitation(updated));\n });\n\n app.delete('/user_management/invitations/:id', (c) => {\n const inv = ws.invitations.get(c.req.param('id'));\n if (!inv) throw notFound('Invitation');\n ws.invitations.delete(inv.id);\n return c.body(null, 204);\n });\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { notFound, validationError, parseJsonBody, WorkOSApiError } from '../../core/index.js';
|
|
1
|
+
import { notFound, validationError, parseJsonBody, WorkOSApiError, parseListParams, } from '../../core/index.js';
|
|
2
2
|
import { getWorkOSStore } from '../store.js';
|
|
3
|
-
import { formatMembership,
|
|
3
|
+
import { formatMembership, formatListResponse } from '../helpers.js';
|
|
4
4
|
export function membershipRoutes(ctx) {
|
|
5
5
|
const { app, store } = ctx;
|
|
6
6
|
const ws = getWorkOSStore(store);
|
|
@@ -53,11 +53,7 @@ export function membershipRoutes(ctx) {
|
|
|
53
53
|
return true;
|
|
54
54
|
},
|
|
55
55
|
});
|
|
56
|
-
return c.json(
|
|
57
|
-
object: 'list',
|
|
58
|
-
data: result.data.map(formatMembership),
|
|
59
|
-
list_metadata: result.list_metadata,
|
|
60
|
-
});
|
|
56
|
+
return c.json(formatListResponse(result, formatMembership));
|
|
61
57
|
});
|
|
62
58
|
app.get('/user_management/organization_memberships/:id', (c) => {
|
|
63
59
|
const m = ws.organizationMemberships.get(c.req.param('id'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memberships.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/memberships.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"memberships.js","sourceRoot":"","sources":["../../../../src/emulate/workos/routes/memberships.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type RouteContext,\n notFound,\n validationError,\n parseJsonBody,\n WorkOSApiError,\n parseListParams,\n} from '../../core/index.js';\nimport { getWorkOSStore } from '../store.js';\nimport { formatMembership, formatListResponse } from '../helpers.js';\n\nexport function membershipRoutes(ctx: RouteContext): void {\n const { app, store } = ctx;\n const ws = getWorkOSStore(store);\n\n app.post('/user_management/organization_memberships', async (c) => {\n const body = await parseJsonBody(c);\n const organizationId = body.organization_id as string | undefined;\n const userId = body.user_id as string | undefined;\n\n if (!organizationId) {\n throw validationError('organization_id is required', [{ field: 'organization_id', code: 'required' }]);\n }\n if (!userId) {\n throw validationError('user_id is required', [{ field: 'user_id', code: 'required' }]);\n }\n\n const org = ws.organizations.get(organizationId);\n if (!org) throw notFound('Organization');\n\n const existing = ws.organizationMemberships\n .findBy('organization_id', organizationId)\n .find((m) => m.user_id === userId && m.status !== 'inactive');\n if (existing) {\n throw new WorkOSApiError(409, 'Membership already exists', 'conflict');\n }\n\n const roleSlug = (body.role_slug as string) ?? 'member';\n\n const membership = ws.organizationMemberships.insert({\n object: 'organization_membership',\n organization_id: organizationId,\n user_id: userId,\n role: { slug: roleSlug },\n status: 'active',\n external_id: (body.external_id as string) ?? null,\n metadata: (body.metadata as Record<string, string>) ?? {},\n });\n\n return c.json(formatMembership(membership), 201);\n });\n\n app.get('/user_management/organization_memberships', (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 userFilter = url.searchParams.get('user_id') ?? undefined;\n const statusesParam = url.searchParams.getAll('statuses[]');\n\n const result = ws.organizationMemberships.list({\n ...params,\n filter: (m) => {\n if (orgFilter && m.organization_id !== orgFilter) return false;\n if (userFilter && m.user_id !== userFilter) return false;\n if (statusesParam.length > 0 && !statusesParam.includes(m.status)) return false;\n return true;\n },\n });\n\n return c.json(formatListResponse(result, formatMembership));\n });\n\n app.get('/user_management/organization_memberships/:id', (c) => {\n const m = ws.organizationMemberships.get(c.req.param('id'));\n if (!m) throw notFound('Organization Membership');\n return c.json(formatMembership(m));\n });\n\n app.put('/user_management/organization_memberships/:id', async (c) => {\n const m = ws.organizationMemberships.get(c.req.param('id'));\n if (!m) throw notFound('Organization Membership');\n\n const body = await parseJsonBody(c);\n const updates: Record<string, unknown> = {};\n\n if ('role_slug' in body) {\n updates.role = { slug: body.role_slug as string };\n }\n if ('external_id' in body) {\n updates.external_id = body.external_id ?? null;\n }\n if ('metadata' in body) {\n updates.metadata = body.metadata ?? {};\n }\n\n const updated = ws.organizationMemberships.update(m.id, updates);\n return c.json(formatMembership(updated!));\n });\n\n app.delete('/user_management/organization_memberships/:id', (c) => {\n const m = ws.organizationMemberships.get(c.req.param('id'));\n if (!m) throw notFound('Organization Membership');\n ws.organizationMemberships.delete(m.id);\n return c.body(null, 204);\n });\n\n app.put('/user_management/organization_memberships/:id/deactivate', (c) => {\n const m = ws.organizationMemberships.get(c.req.param('id'));\n if (!m) throw notFound('Organization Membership');\n if (m.status === 'inactive') {\n throw validationError('Membership is already inactive');\n }\n const updated = ws.organizationMemberships.update(m.id, {\n status: 'inactive',\n });\n return c.json(formatMembership(updated!));\n });\n\n app.put('/user_management/organization_memberships/:id/reactivate', (c) => {\n const m = ws.organizationMemberships.get(c.req.param('id'));\n if (!m) throw notFound('Organization Membership');\n if (m.status === 'active') {\n throw validationError('Membership is already active');\n }\n const updated = ws.organizationMemberships.update(m.id, {\n status: 'active',\n });\n return c.json(formatMembership(updated!));\n });\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { notFound, validationError, parseJsonBody } from '../../core/index.js';
|
|
1
|
+
import { notFound, validationError, parseJsonBody, parseListParams } from '../../core/index.js';
|
|
2
2
|
import { getWorkOSStore } from '../store.js';
|
|
3
|
-
import { formatOrganization, generateVerificationToken,
|
|
3
|
+
import { formatOrganization, generateVerificationToken, formatListResponse } from '../helpers.js';
|
|
4
4
|
export function organizationRoutes(ctx) {
|
|
5
5
|
const { app, store } = ctx;
|
|
6
6
|
const ws = getWorkOSStore(store);
|
|
@@ -53,11 +53,15 @@ export function organizationRoutes(ctx) {
|
|
|
53
53
|
return true;
|
|
54
54
|
},
|
|
55
55
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
// Pre-fetch all domains once to avoid N+1 lookups per org
|
|
57
|
+
const allDomains = ws.organizationDomains.all();
|
|
58
|
+
const domainsByOrg = new Map();
|
|
59
|
+
for (const d of allDomains) {
|
|
60
|
+
const list = domainsByOrg.get(d.organization_id) ?? [];
|
|
61
|
+
list.push(d);
|
|
62
|
+
domainsByOrg.set(d.organization_id, list);
|
|
63
|
+
}
|
|
64
|
+
return c.json(formatListResponse(result, (org) => formatOrganization(org, ws, { domains: domainsByOrg.get(org.id) ?? [] })));
|
|
61
65
|
});
|
|
62
66
|
app.get('/organizations/:id', (c) => {
|
|
63
67
|
const org = ws.organizations.get(c.req.param('id'));
|
|
@@ -118,14 +122,8 @@ export function organizationRoutes(ctx) {
|
|
|
118
122
|
const org = ws.organizations.get(c.req.param('id'));
|
|
119
123
|
if (!org)
|
|
120
124
|
throw notFound('Organization');
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
ws.organizationDomains.delete(d.id);
|
|
124
|
-
}
|
|
125
|
-
const memberships = ws.organizationMemberships.findBy('organization_id', org.id);
|
|
126
|
-
for (const m of memberships) {
|
|
127
|
-
ws.organizationMemberships.delete(m.id);
|
|
128
|
-
}
|
|
125
|
+
ws.organizationDomains.deleteBy('organization_id', org.id);
|
|
126
|
+
ws.organizationMemberships.deleteBy('organization_id', org.id);
|
|
129
127
|
ws.organizations.delete(org.id);
|
|
130
128
|
return c.body(null, 204);
|
|
131
129
|
});
|