workos 0.7.3 → 0.8.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.
- package/README.md +353 -8
- package/dist/bin.js +938 -128
- package/dist/bin.js.map +1 -1
- package/dist/commands/api-key-mgmt.d.ts +16 -0
- package/dist/commands/api-key-mgmt.js +96 -0
- package/dist/commands/api-key-mgmt.js.map +1 -0
- package/dist/commands/audit-log.d.ts +26 -0
- package/dist/commands/audit-log.js +155 -0
- package/dist/commands/audit-log.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.js +54 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/connection.d.ts +13 -0
- package/dist/commands/connection.js +94 -0
- package/dist/commands/connection.js.map +1 -0
- package/dist/commands/debug-sso.d.ts +1 -0
- package/dist/commands/debug-sso.js +78 -0
- package/dist/commands/debug-sso.js.map +1 -0
- package/dist/commands/debug-sync.d.ts +1 -0
- package/dist/commands/debug-sync.js +102 -0
- package/dist/commands/debug-sync.js.map +1 -0
- package/dist/commands/directory.d.ts +27 -0
- package/dist/commands/directory.js +174 -0
- package/dist/commands/directory.js.map +1 -0
- package/dist/commands/env.js +41 -28
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/event.d.ts +9 -0
- package/dist/commands/event.js +43 -0
- package/dist/commands/event.js.map +1 -0
- package/dist/commands/feature-flag.d.ts +12 -0
- package/dist/commands/feature-flag.js +96 -0
- package/dist/commands/feature-flag.js.map +1 -0
- package/dist/commands/install-skill.js +3 -5
- package/dist/commands/install-skill.js.map +1 -1
- package/dist/commands/install.js +13 -20
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/invitation.d.ts +19 -0
- package/dist/commands/invitation.js +94 -0
- package/dist/commands/invitation.js.map +1 -0
- package/dist/commands/membership.d.ts +20 -0
- package/dist/commands/membership.js +129 -0
- package/dist/commands/membership.js.map +1 -0
- package/dist/commands/onboard-user.d.ts +7 -0
- package/dist/commands/onboard-user.js +61 -0
- package/dist/commands/onboard-user.js.map +1 -0
- package/dist/commands/org-domain.d.ts +4 -0
- package/dist/commands/org-domain.js +45 -0
- package/dist/commands/org-domain.js.map +1 -0
- package/dist/commands/organization.d.ts +1 -5
- package/dist/commands/organization.js +34 -73
- package/dist/commands/organization.js.map +1 -1
- package/dist/commands/permission.d.ts +20 -0
- package/dist/commands/permission.js +93 -0
- package/dist/commands/permission.js.map +1 -0
- package/dist/commands/portal.d.ts +7 -0
- package/dist/commands/portal.js +26 -0
- package/dist/commands/portal.js.map +1 -0
- package/dist/commands/role.d.ts +17 -0
- package/dist/commands/role.js +122 -0
- package/dist/commands/role.js.map +1 -0
- package/dist/commands/seed.d.ts +4 -0
- package/dist/commands/seed.js +238 -0
- package/dist/commands/seed.js.map +1 -0
- package/dist/commands/session.d.ts +8 -0
- package/dist/commands/session.js +63 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup-org.d.ts +6 -0
- package/dist/commands/setup-org.js +99 -0
- package/dist/commands/setup-org.js.map +1 -0
- package/dist/commands/user.js +35 -71
- package/dist/commands/user.js.map +1 -1
- package/dist/commands/vault.d.ts +24 -0
- package/dist/commands/vault.js +120 -0
- package/dist/commands/vault.js.map +1 -0
- package/dist/commands/webhook.d.ts +3 -0
- package/dist/commands/webhook.js +73 -0
- package/dist/commands/webhook.js.map +1 -0
- package/dist/dashboard/components/DiffPanel.js.map +1 -1
- package/dist/dashboard/lib/logo-frames.js +1 -1
- package/dist/dashboard/lib/logo-frames.js.map +1 -1
- package/dist/doctor/checks/dashboard.js.map +1 -1
- package/dist/doctor/checks/environment.js.map +1 -1
- package/dist/integrations/go/index.js +1 -3
- package/dist/integrations/go/index.js.map +1 -1
- package/dist/lib/adapters/headless-adapter.d.ts +67 -0
- package/dist/lib/adapters/headless-adapter.js +263 -0
- package/dist/lib/adapters/headless-adapter.js.map +1 -0
- package/dist/lib/adapters/index.d.ts +1 -0
- package/dist/lib/adapters/index.js +1 -0
- package/dist/lib/adapters/index.js.map +1 -1
- package/dist/lib/agent-interface.d.ts +3 -11
- package/dist/lib/agent-interface.js +3 -19
- package/dist/lib/agent-interface.js.map +1 -1
- package/dist/lib/api-error-handler.d.ts +6 -0
- package/dist/lib/api-error-handler.js +58 -0
- package/dist/lib/api-error-handler.js.map +1 -0
- package/dist/lib/api-key.js +5 -1
- package/dist/lib/api-key.js.map +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/credential-proxy.js +0 -6
- package/dist/lib/credential-proxy.js.map +1 -1
- package/dist/lib/device-auth.js +1 -1
- package/dist/lib/device-auth.js.map +1 -1
- package/dist/lib/ensure-auth.js +25 -4
- package/dist/lib/ensure-auth.js.map +1 -1
- package/dist/lib/installer-core.d.ts +12 -12
- package/dist/lib/run-with-core.js +25 -4
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/validation/validator.js +0 -1
- package/dist/lib/validation/validator.js.map +1 -1
- package/dist/lib/workos-client.d.ts +58 -0
- package/dist/lib/workos-client.js +137 -0
- package/dist/lib/workos-client.js.map +1 -0
- package/dist/run.d.ts +7 -0
- package/dist/run.js +5 -2
- package/dist/run.js.map +1 -1
- package/dist/smoke-test.ts +881 -0
- package/dist/steps/run-prettier.js +1 -1
- package/dist/steps/run-prettier.js.map +1 -1
- package/dist/utils/analytics.d.ts +1 -1
- package/dist/utils/analytics.js.map +1 -1
- package/dist/utils/clack-utils.js +1 -1
- package/dist/utils/clack-utils.js.map +1 -1
- package/dist/utils/environment.js +8 -0
- package/dist/utils/environment.js.map +1 -1
- package/dist/utils/exit-codes.d.ts +22 -0
- package/dist/utils/exit-codes.js +30 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/help-json.d.ts +45 -0
- package/dist/utils/help-json.js +1161 -0
- package/dist/utils/help-json.js.map +1 -0
- package/dist/utils/ndjson.d.ts +16 -0
- package/dist/utils/ndjson.js +18 -0
- package/dist/utils/ndjson.js.map +1 -0
- package/dist/utils/output.d.ts +40 -0
- package/dist/utils/output.js +95 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/package-manager.js +2 -3
- package/dist/utils/package-manager.js.map +1 -1
- package/dist/utils/paths.d.ts +5 -0
- package/dist/utils/paths.js +18 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/register-subcommand.d.ts +7 -0
- package/dist/utils/register-subcommand.js +36 -0
- package/dist/utils/register-subcommand.js.map +1 -0
- package/dist/utils/telemetry-types.d.ts +1 -1
- package/dist/utils/telemetry-types.js.map +1 -1
- package/dist/utils/types.d.ts +12 -0
- package/dist/utils/types.js.map +1 -1
- package/package.json +20 -16
- package/skills/workos-management/SKILL.md +250 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { parse as parseYaml } from 'yaml';
|
|
4
|
+
import { createWorkOSClient } from '../lib/workos-client.js';
|
|
5
|
+
import { outputJson, outputSuccess, isJsonMode, exitWithError } from '../utils/output.js';
|
|
6
|
+
const STATE_FILE = '.workos-seed-state.json';
|
|
7
|
+
function loadState() {
|
|
8
|
+
if (!existsSync(STATE_FILE))
|
|
9
|
+
return null;
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(readFileSync(STATE_FILE, 'utf-8'));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function saveState(state) {
|
|
18
|
+
writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));
|
|
19
|
+
}
|
|
20
|
+
export async function runSeed(options, apiKey, baseUrl) {
|
|
21
|
+
if (options.clean) {
|
|
22
|
+
await runSeedClean(apiKey, baseUrl);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!options.file) {
|
|
26
|
+
return exitWithError({
|
|
27
|
+
code: 'missing_args',
|
|
28
|
+
message: 'Provide a seed file: workos seed --file=workos-seed.yml',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (!existsSync(options.file)) {
|
|
32
|
+
return exitWithError({
|
|
33
|
+
code: 'file_not_found',
|
|
34
|
+
message: `Seed file not found: ${options.file}. Create workos-seed.yml or run \`workos seed\` without --file for interactive mode.`,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const raw = readFileSync(options.file, 'utf-8');
|
|
38
|
+
let seedConfig;
|
|
39
|
+
try {
|
|
40
|
+
seedConfig = parseYaml(raw);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
exitWithError({
|
|
44
|
+
code: 'invalid_yaml',
|
|
45
|
+
message: `Failed to parse seed file: ${error instanceof Error ? error.message : 'Invalid YAML'}`,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
49
|
+
const state = { permissions: [], roles: [], organizations: [], createdAt: new Date().toISOString() };
|
|
50
|
+
try {
|
|
51
|
+
// 1. Create permissions
|
|
52
|
+
if (seedConfig.permissions) {
|
|
53
|
+
for (const perm of seedConfig.permissions) {
|
|
54
|
+
try {
|
|
55
|
+
await client.sdk.authorization.createPermission({
|
|
56
|
+
slug: perm.slug,
|
|
57
|
+
name: perm.name,
|
|
58
|
+
...(perm.description && { description: perm.description }),
|
|
59
|
+
});
|
|
60
|
+
state.permissions.push({ slug: perm.slug });
|
|
61
|
+
if (!isJsonMode())
|
|
62
|
+
console.log(chalk.green(` Created permission: ${perm.slug}`));
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (isAlreadyExists(error)) {
|
|
66
|
+
if (!isJsonMode())
|
|
67
|
+
console.log(chalk.dim(` Permission exists: ${perm.slug} (skipped)`));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// 2. Create roles + assign permissions
|
|
76
|
+
if (seedConfig.roles) {
|
|
77
|
+
for (const role of seedConfig.roles) {
|
|
78
|
+
try {
|
|
79
|
+
await client.sdk.authorization.createEnvironmentRole({
|
|
80
|
+
slug: role.slug,
|
|
81
|
+
name: role.name,
|
|
82
|
+
...(role.description && { description: role.description }),
|
|
83
|
+
});
|
|
84
|
+
state.roles.push({ slug: role.slug });
|
|
85
|
+
if (!isJsonMode())
|
|
86
|
+
console.log(chalk.green(` Created role: ${role.slug}`));
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (isAlreadyExists(error)) {
|
|
90
|
+
if (!isJsonMode())
|
|
91
|
+
console.log(chalk.dim(` Role exists: ${role.slug} (skipped)`));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (role.permissions?.length) {
|
|
98
|
+
try {
|
|
99
|
+
await client.sdk.authorization.setEnvironmentRolePermissions(role.slug, {
|
|
100
|
+
permissions: role.permissions,
|
|
101
|
+
});
|
|
102
|
+
if (!isJsonMode())
|
|
103
|
+
console.log(chalk.green(` Set permissions on ${role.slug}: ${role.permissions.join(', ')}`));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
if (!isJsonMode())
|
|
107
|
+
console.log(chalk.yellow(` Warning: Failed to set permissions on ${role.slug}`));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// 3. Create organizations
|
|
113
|
+
if (seedConfig.organizations) {
|
|
114
|
+
for (const org of seedConfig.organizations) {
|
|
115
|
+
try {
|
|
116
|
+
const created = await client.sdk.organizations.createOrganization({
|
|
117
|
+
name: org.name,
|
|
118
|
+
...(org.domains?.length && {
|
|
119
|
+
domainData: org.domains.map((d) => ({ domain: d, state: 'verified' })),
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
state.organizations.push({ id: created.id, name: created.name });
|
|
123
|
+
if (!isJsonMode())
|
|
124
|
+
console.log(chalk.green(` Created org: ${created.name} (${created.id})`));
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (isAlreadyExists(error)) {
|
|
128
|
+
if (!isJsonMode())
|
|
129
|
+
console.log(chalk.dim(` Org may exist: ${org.name} (skipped)`));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// 4. Configure redirect URIs, CORS, homepage
|
|
138
|
+
if (seedConfig.config) {
|
|
139
|
+
await applyConfig(client, seedConfig.config);
|
|
140
|
+
}
|
|
141
|
+
saveState(state);
|
|
142
|
+
if (isJsonMode()) {
|
|
143
|
+
outputJson({ status: 'ok', message: 'Seed complete', state });
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
console.log(chalk.green('\nSeed complete.'));
|
|
147
|
+
console.log(chalk.dim(`State saved to ${STATE_FILE}`));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
// Partial failure — save what was created so --clean can tear down
|
|
152
|
+
saveState(state);
|
|
153
|
+
exitWithError({
|
|
154
|
+
code: 'seed_failed',
|
|
155
|
+
message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run \`workos seed --clean\` to tear down.`,
|
|
156
|
+
details: state,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async function runSeedClean(apiKey, baseUrl) {
|
|
161
|
+
const state = loadState();
|
|
162
|
+
if (!state) {
|
|
163
|
+
return exitWithError({
|
|
164
|
+
code: 'no_state',
|
|
165
|
+
message: `No seed state found (${STATE_FILE}). Nothing to clean.`,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
169
|
+
// Delete in reverse order: orgs → roles → permissions
|
|
170
|
+
for (const org of state.organizations.reverse()) {
|
|
171
|
+
try {
|
|
172
|
+
await client.sdk.organizations.deleteOrganization(org.id);
|
|
173
|
+
if (!isJsonMode())
|
|
174
|
+
console.log(chalk.green(` Deleted org: ${org.name} (${org.id})`));
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
if (!isJsonMode())
|
|
178
|
+
console.log(chalk.yellow(` Warning: Could not delete org ${org.id}`));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
for (const role of state.roles.reverse()) {
|
|
182
|
+
try {
|
|
183
|
+
// Env roles can't be deleted via SDK — skip silently
|
|
184
|
+
if (!isJsonMode())
|
|
185
|
+
console.log(chalk.dim(` Env role ${role.slug}: skipped (env roles cannot be deleted)`));
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// ignore
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
for (const perm of state.permissions.reverse()) {
|
|
192
|
+
try {
|
|
193
|
+
await client.sdk.authorization.deletePermission(perm.slug);
|
|
194
|
+
if (!isJsonMode())
|
|
195
|
+
console.log(chalk.green(` Deleted permission: ${perm.slug}`));
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
if (!isJsonMode())
|
|
199
|
+
console.log(chalk.yellow(` Warning: Could not delete permission ${perm.slug}`));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
unlinkSync(STATE_FILE);
|
|
203
|
+
outputSuccess('Seed cleanup complete', { stateFile: STATE_FILE });
|
|
204
|
+
}
|
|
205
|
+
async function applyConfig(client, config) {
|
|
206
|
+
if (config.redirect_uris) {
|
|
207
|
+
for (const uri of config.redirect_uris) {
|
|
208
|
+
const result = await client.redirectUris.add(uri);
|
|
209
|
+
if (!isJsonMode()) {
|
|
210
|
+
console.log(result.alreadyExists
|
|
211
|
+
? chalk.dim(` Redirect URI exists: ${uri}`)
|
|
212
|
+
: chalk.green(` Added redirect URI: ${uri}`));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (config.cors_origins) {
|
|
217
|
+
for (const origin of config.cors_origins) {
|
|
218
|
+
const result = await client.corsOrigins.add(origin);
|
|
219
|
+
if (!isJsonMode()) {
|
|
220
|
+
console.log(result.alreadyExists
|
|
221
|
+
? chalk.dim(` CORS origin exists: ${origin}`)
|
|
222
|
+
: chalk.green(` Added CORS origin: ${origin}`));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (config.homepage_url) {
|
|
227
|
+
await client.homepageUrl.set(config.homepage_url);
|
|
228
|
+
if (!isJsonMode())
|
|
229
|
+
console.log(chalk.green(` Set homepage URL: ${config.homepage_url}`));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function isAlreadyExists(error) {
|
|
233
|
+
if (!(error instanceof Error))
|
|
234
|
+
return false;
|
|
235
|
+
const msg = error.message.toLowerCase();
|
|
236
|
+
return msg.includes('already exists') || msg.includes('conflict') || msg.includes('duplicate');
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/commands/seed.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';\nimport chalk from 'chalk';\nimport { parse as parseYaml } from 'yaml';\nimport type { DomainData } from '@workos-inc/node';\nimport { createWorkOSClient, type WorkOSCLIClient } from '../lib/workos-client.js';\nimport { outputJson, outputSuccess, isJsonMode, exitWithError } from '../utils/output.js';\n\nconst STATE_FILE = '.workos-seed-state.json';\n\ninterface SeedConfig {\n organizations?: Array<{ name: string; domains?: string[] }>;\n permissions?: Array<{ name: string; slug: string; description?: string }>;\n roles?: Array<{ name: string; slug: string; description?: string; permissions?: string[] }>;\n config?: {\n redirect_uris?: string[];\n cors_origins?: string[];\n homepage_url?: string;\n };\n}\n\ninterface SeedState {\n permissions: Array<{ slug: string }>;\n roles: Array<{ slug: string }>;\n organizations: Array<{ id: string; name: string }>;\n createdAt: string;\n}\n\nfunction loadState(): SeedState | null {\n if (!existsSync(STATE_FILE)) return null;\n try {\n return JSON.parse(readFileSync(STATE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction saveState(state: SeedState): void {\n writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));\n}\n\nexport async function runSeed(\n options: { file?: string; clean?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (options.clean) {\n await runSeedClean(apiKey, baseUrl);\n return;\n }\n\n if (!options.file) {\n return exitWithError({\n code: 'missing_args',\n message: 'Provide a seed file: workos seed --file=workos-seed.yml',\n });\n }\n\n if (!existsSync(options.file)) {\n return exitWithError({\n code: 'file_not_found',\n message: `Seed file not found: ${options.file}. Create workos-seed.yml or run \\`workos seed\\` without --file for interactive mode.`,\n });\n }\n\n const raw = readFileSync(options.file, 'utf-8');\n let seedConfig: SeedConfig;\n try {\n seedConfig = parseYaml(raw) as SeedConfig;\n } catch (error) {\n exitWithError({\n code: 'invalid_yaml',\n message: `Failed to parse seed file: ${error instanceof Error ? error.message : 'Invalid YAML'}`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n const state: SeedState = { permissions: [], roles: [], organizations: [], createdAt: new Date().toISOString() };\n\n try {\n // 1. Create permissions\n if (seedConfig.permissions) {\n for (const perm of seedConfig.permissions) {\n try {\n await client.sdk.authorization.createPermission({\n slug: perm.slug,\n name: perm.name,\n ...(perm.description && { description: perm.description }),\n });\n state.permissions.push({ slug: perm.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created permission: ${perm.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Permission exists: ${perm.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 2. Create roles + assign permissions\n if (seedConfig.roles) {\n for (const role of seedConfig.roles) {\n try {\n await client.sdk.authorization.createEnvironmentRole({\n slug: role.slug,\n name: role.name,\n ...(role.description && { description: role.description }),\n });\n state.roles.push({ slug: role.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created role: ${role.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Role exists: ${role.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n\n if (role.permissions?.length) {\n try {\n await client.sdk.authorization.setEnvironmentRolePermissions(role.slug, {\n permissions: role.permissions,\n });\n if (!isJsonMode())\n console.log(chalk.green(` Set permissions on ${role.slug}: ${role.permissions.join(', ')}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Failed to set permissions on ${role.slug}`));\n }\n }\n }\n }\n\n // 3. Create organizations\n if (seedConfig.organizations) {\n for (const org of seedConfig.organizations) {\n try {\n const created = await client.sdk.organizations.createOrganization({\n name: org.name,\n ...(org.domains?.length && {\n domainData: org.domains.map((d) => ({ domain: d, state: 'verified' as DomainData['state'] })),\n }),\n });\n state.organizations.push({ id: created.id, name: created.name });\n if (!isJsonMode()) console.log(chalk.green(` Created org: ${created.name} (${created.id})`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Org may exist: ${org.name} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 4. Configure redirect URIs, CORS, homepage\n if (seedConfig.config) {\n await applyConfig(client, seedConfig.config);\n }\n\n saveState(state);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: 'Seed complete', state });\n } else {\n console.log(chalk.green('\\nSeed complete.'));\n console.log(chalk.dim(`State saved to ${STATE_FILE}`));\n }\n } catch (error) {\n // Partial failure — save what was created so --clean can tear down\n saveState(state);\n exitWithError({\n code: 'seed_failed',\n message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run \\`workos seed --clean\\` to tear down.`,\n details: state,\n });\n }\n}\n\nasync function runSeedClean(apiKey: string, baseUrl?: string): Promise<void> {\n const state = loadState();\n if (!state) {\n return exitWithError({\n code: 'no_state',\n message: `No seed state found (${STATE_FILE}). Nothing to clean.`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n // Delete in reverse order: orgs → roles → permissions\n for (const org of state.organizations.reverse()) {\n try {\n await client.sdk.organizations.deleteOrganization(org.id);\n if (!isJsonMode()) console.log(chalk.green(` Deleted org: ${org.name} (${org.id})`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete org ${org.id}`));\n }\n }\n\n for (const role of state.roles.reverse()) {\n try {\n // Env roles can't be deleted via SDK — skip silently\n if (!isJsonMode()) console.log(chalk.dim(` Env role ${role.slug}: skipped (env roles cannot be deleted)`));\n } catch {\n // ignore\n }\n }\n\n for (const perm of state.permissions.reverse()) {\n try {\n await client.sdk.authorization.deletePermission(perm.slug);\n if (!isJsonMode()) console.log(chalk.green(` Deleted permission: ${perm.slug}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete permission ${perm.slug}`));\n }\n }\n\n unlinkSync(STATE_FILE);\n outputSuccess('Seed cleanup complete', { stateFile: STATE_FILE });\n}\n\nasync function applyConfig(client: WorkOSCLIClient, config: NonNullable<SeedConfig['config']>): Promise<void> {\n if (config.redirect_uris) {\n for (const uri of config.redirect_uris) {\n const result = await client.redirectUris.add(uri);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` Redirect URI exists: ${uri}`)\n : chalk.green(` Added redirect URI: ${uri}`),\n );\n }\n }\n }\n\n if (config.cors_origins) {\n for (const origin of config.cors_origins) {\n const result = await client.corsOrigins.add(origin);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` CORS origin exists: ${origin}`)\n : chalk.green(` Added CORS origin: ${origin}`),\n );\n }\n }\n }\n\n if (config.homepage_url) {\n await client.homepageUrl.set(config.homepage_url);\n if (!isJsonMode()) console.log(chalk.green(` Set homepage URL: ${config.homepage_url}`));\n }\n}\n\nfunction isAlreadyExists(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n return msg.includes('already exists') || msg.includes('conflict') || msg.includes('duplicate');\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SessionListOptions {
|
|
2
|
+
limit?: number;
|
|
3
|
+
before?: string;
|
|
4
|
+
after?: string;
|
|
5
|
+
order?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function runSessionList(userId: string, options: SessionListOptions, apiKey: string, baseUrl?: string): Promise<void>;
|
|
8
|
+
export declare function runSessionRevoke(sessionId: string, apiKey: string, baseUrl?: string): Promise<void>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { createWorkOSClient } from '../lib/workos-client.js';
|
|
3
|
+
import { formatTable } from '../utils/table.js';
|
|
4
|
+
import { outputSuccess, outputJson, isJsonMode } from '../utils/output.js';
|
|
5
|
+
import { createApiErrorHandler } from '../lib/api-error-handler.js';
|
|
6
|
+
const handleApiError = createApiErrorHandler('Session');
|
|
7
|
+
export async function runSessionList(userId, options, apiKey, baseUrl) {
|
|
8
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
9
|
+
try {
|
|
10
|
+
const result = await client.sdk.userManagement.listSessions(userId, {
|
|
11
|
+
limit: options.limit,
|
|
12
|
+
before: options.before,
|
|
13
|
+
after: options.after,
|
|
14
|
+
order: options.order,
|
|
15
|
+
});
|
|
16
|
+
if (isJsonMode()) {
|
|
17
|
+
outputJson({ data: result.data, listMetadata: result.listMetadata });
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (result.data.length === 0) {
|
|
21
|
+
console.log('No sessions found.');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const rows = result.data.map((s) => [
|
|
25
|
+
s.id,
|
|
26
|
+
s.userAgent ?? chalk.dim('-'),
|
|
27
|
+
s.ipAddress ?? chalk.dim('-'),
|
|
28
|
+
s.createdAt,
|
|
29
|
+
s.expiresAt,
|
|
30
|
+
]);
|
|
31
|
+
console.log(formatTable([
|
|
32
|
+
{ header: 'ID' },
|
|
33
|
+
{ header: 'User Agent' },
|
|
34
|
+
{ header: 'IP Address' },
|
|
35
|
+
{ header: 'Created' },
|
|
36
|
+
{ header: 'Expires' },
|
|
37
|
+
], rows));
|
|
38
|
+
const { before, after } = result.listMetadata;
|
|
39
|
+
if (before && after) {
|
|
40
|
+
console.log(chalk.dim(`Before: ${before} After: ${after}`));
|
|
41
|
+
}
|
|
42
|
+
else if (before) {
|
|
43
|
+
console.log(chalk.dim(`Before: ${before}`));
|
|
44
|
+
}
|
|
45
|
+
else if (after) {
|
|
46
|
+
console.log(chalk.dim(`After: ${after}`));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
handleApiError(error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function runSessionRevoke(sessionId, apiKey, baseUrl) {
|
|
54
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
55
|
+
try {
|
|
56
|
+
await client.sdk.userManagement.revokeSession({ sessionId });
|
|
57
|
+
outputSuccess('Revoked session', { id: sessionId });
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
handleApiError(error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { createWorkOSClient } from '../lib/workos-client.js';\nimport { formatTable } from '../utils/table.js';\nimport { outputSuccess, outputJson, isJsonMode } from '../utils/output.js';\nimport { createApiErrorHandler } from '../lib/api-error-handler.js';\n\nconst handleApiError = createApiErrorHandler('Session');\n\nexport interface SessionListOptions {\n limit?: number;\n before?: string;\n after?: string;\n order?: string;\n}\n\nexport async function runSessionList(\n userId: string,\n options: SessionListOptions,\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n const result = await client.sdk.userManagement.listSessions(userId, {\n limit: options.limit,\n before: options.before,\n after: options.after,\n order: options.order as 'asc' | 'desc' | undefined,\n });\n\n if (isJsonMode()) {\n outputJson({ data: result.data, listMetadata: result.listMetadata });\n return;\n }\n\n if (result.data.length === 0) {\n console.log('No sessions found.');\n return;\n }\n\n const rows = result.data.map((s) => [\n s.id,\n s.userAgent ?? chalk.dim('-'),\n s.ipAddress ?? chalk.dim('-'),\n s.createdAt,\n s.expiresAt,\n ]);\n\n console.log(\n formatTable(\n [\n { header: 'ID' },\n { header: 'User Agent' },\n { header: 'IP Address' },\n { header: 'Created' },\n { header: 'Expires' },\n ],\n rows,\n ),\n );\n\n const { before, after } = result.listMetadata;\n if (before && after) {\n console.log(chalk.dim(`Before: ${before} After: ${after}`));\n } else if (before) {\n console.log(chalk.dim(`Before: ${before}`));\n } else if (after) {\n console.log(chalk.dim(`After: ${after}`));\n }\n } catch (error) {\n handleApiError(error);\n }\n}\n\nexport async function runSessionRevoke(sessionId: string, apiKey: string, baseUrl?: string): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n await client.sdk.userManagement.revokeSession({ sessionId });\n outputSuccess('Revoked session', { id: sessionId });\n } catch (error) {\n handleApiError(error);\n }\n}\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { createWorkOSClient } from '../lib/workos-client.js';
|
|
3
|
+
import { outputJson, isJsonMode } from '../utils/output.js';
|
|
4
|
+
import { createApiErrorHandler } from '../lib/api-error-handler.js';
|
|
5
|
+
const handleApiError = createApiErrorHandler('SetupOrg');
|
|
6
|
+
export async function runSetupOrg(options, apiKey, baseUrl) {
|
|
7
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
8
|
+
const summary = {};
|
|
9
|
+
try {
|
|
10
|
+
// 1. Create organization
|
|
11
|
+
if (!isJsonMode())
|
|
12
|
+
console.log(chalk.bold(`Setting up organization: ${options.name}`));
|
|
13
|
+
const org = await client.sdk.organizations.createOrganization({
|
|
14
|
+
name: options.name,
|
|
15
|
+
});
|
|
16
|
+
summary.organizationId = org.id;
|
|
17
|
+
if (!isJsonMode())
|
|
18
|
+
console.log(chalk.green(` Created org: ${org.name} (${org.id})`));
|
|
19
|
+
// 2. Add domain
|
|
20
|
+
if (options.domain) {
|
|
21
|
+
const domainResult = await client.sdk.organizationDomains.create({
|
|
22
|
+
domain: options.domain,
|
|
23
|
+
organizationId: org.id,
|
|
24
|
+
});
|
|
25
|
+
summary.domainId = domainResult.id;
|
|
26
|
+
if (!isJsonMode())
|
|
27
|
+
console.log(chalk.green(` Added domain: ${options.domain}`));
|
|
28
|
+
// 3. Verify domain
|
|
29
|
+
try {
|
|
30
|
+
await client.sdk.organizationDomains.verify(domainResult.id);
|
|
31
|
+
summary.domainVerified = true;
|
|
32
|
+
if (!isJsonMode())
|
|
33
|
+
console.log(chalk.green(` Verified domain: ${options.domain}`));
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
summary.domainVerified = false;
|
|
37
|
+
if (!isJsonMode())
|
|
38
|
+
console.log(chalk.yellow(` Domain verification pending: ${options.domain}`));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// 4. Create org-scoped roles (copy from env role names)
|
|
42
|
+
if (options.roles?.length) {
|
|
43
|
+
summary.roles = [];
|
|
44
|
+
for (const roleSlug of options.roles) {
|
|
45
|
+
try {
|
|
46
|
+
const role = await client.sdk.authorization.createOrganizationRole(org.id, {
|
|
47
|
+
slug: roleSlug,
|
|
48
|
+
name: roleSlug,
|
|
49
|
+
});
|
|
50
|
+
summary.roles.push(role.slug);
|
|
51
|
+
if (!isJsonMode())
|
|
52
|
+
console.log(chalk.green(` Created org role: ${roleSlug}`));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof Error && error.message.toLowerCase().includes('already exists')) {
|
|
56
|
+
if (!isJsonMode())
|
|
57
|
+
console.log(chalk.dim(` Role exists: ${roleSlug} (skipped)`));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
if (!isJsonMode())
|
|
61
|
+
console.log(chalk.yellow(` Warning: Could not create role ${roleSlug}`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// 5. Generate Admin Portal link
|
|
67
|
+
try {
|
|
68
|
+
const portal = await client.sdk.portal.generateLink({
|
|
69
|
+
intent: 'sso',
|
|
70
|
+
organization: org.id,
|
|
71
|
+
});
|
|
72
|
+
summary.portalLink = portal.link;
|
|
73
|
+
if (!isJsonMode()) {
|
|
74
|
+
console.log(chalk.green(` Portal link: ${portal.link}`));
|
|
75
|
+
console.log(chalk.dim(' Note: Portal links expire after 5 minutes.'));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
if (!isJsonMode())
|
|
80
|
+
console.log(chalk.dim(' Portal link: skipped (may require plan upgrade)'));
|
|
81
|
+
}
|
|
82
|
+
// 6. Print summary
|
|
83
|
+
if (isJsonMode()) {
|
|
84
|
+
outputJson({ status: 'ok', ...summary });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
console.log(chalk.bold('\nSetup complete:'));
|
|
88
|
+
console.log(` Organization: ${org.id}`);
|
|
89
|
+
if (options.domain)
|
|
90
|
+
console.log(` Domain: ${options.domain} (${summary.domainVerified ? 'verified' : 'pending'})`);
|
|
91
|
+
if (summary.portalLink)
|
|
92
|
+
console.log(` Portal: ${summary.portalLink}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
handleApiError(error);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=setup-org.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-org.js","sourceRoot":"","sources":["../../src/commands/setup-org.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { createWorkOSClient } from '../lib/workos-client.js';\nimport { outputJson, isJsonMode } from '../utils/output.js';\nimport { createApiErrorHandler } from '../lib/api-error-handler.js';\n\nconst handleApiError = createApiErrorHandler('SetupOrg');\n\nexport interface SetupOrgOptions {\n name: string;\n domain?: string;\n roles?: string[];\n}\n\nexport async function runSetupOrg(options: SetupOrgOptions, apiKey: string, baseUrl?: string): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n const summary: Record<string, unknown> = {};\n\n try {\n // 1. Create organization\n if (!isJsonMode()) console.log(chalk.bold(`Setting up organization: ${options.name}`));\n\n const org = await client.sdk.organizations.createOrganization({\n name: options.name,\n });\n summary.organizationId = org.id;\n if (!isJsonMode()) console.log(chalk.green(` Created org: ${org.name} (${org.id})`));\n\n // 2. Add domain\n if (options.domain) {\n const domainResult = await client.sdk.organizationDomains.create({\n domain: options.domain,\n organizationId: org.id,\n });\n summary.domainId = domainResult.id;\n if (!isJsonMode()) console.log(chalk.green(` Added domain: ${options.domain}`));\n\n // 3. Verify domain\n try {\n await client.sdk.organizationDomains.verify(domainResult.id);\n summary.domainVerified = true;\n if (!isJsonMode()) console.log(chalk.green(` Verified domain: ${options.domain}`));\n } catch {\n summary.domainVerified = false;\n if (!isJsonMode()) console.log(chalk.yellow(` Domain verification pending: ${options.domain}`));\n }\n }\n\n // 4. Create org-scoped roles (copy from env role names)\n if (options.roles?.length) {\n summary.roles = [];\n for (const roleSlug of options.roles) {\n try {\n const role = await client.sdk.authorization.createOrganizationRole(org.id, {\n slug: roleSlug,\n name: roleSlug,\n });\n (summary.roles as string[]).push(role.slug);\n if (!isJsonMode()) console.log(chalk.green(` Created org role: ${roleSlug}`));\n } catch (error: unknown) {\n if (error instanceof Error && error.message.toLowerCase().includes('already exists')) {\n if (!isJsonMode()) console.log(chalk.dim(` Role exists: ${roleSlug} (skipped)`));\n } else {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not create role ${roleSlug}`));\n }\n }\n }\n }\n\n // 5. Generate Admin Portal link\n try {\n const portal = await client.sdk.portal.generateLink({\n intent: 'sso' as Parameters<typeof client.sdk.portal.generateLink>[0]['intent'],\n organization: org.id,\n });\n summary.portalLink = portal.link;\n if (!isJsonMode()) {\n console.log(chalk.green(` Portal link: ${portal.link}`));\n console.log(chalk.dim(' Note: Portal links expire after 5 minutes.'));\n }\n } catch {\n if (!isJsonMode()) console.log(chalk.dim(' Portal link: skipped (may require plan upgrade)'));\n }\n\n // 6. Print summary\n if (isJsonMode()) {\n outputJson({ status: 'ok', ...summary });\n } else {\n console.log(chalk.bold('\\nSetup complete:'));\n console.log(` Organization: ${org.id}`);\n if (options.domain)\n console.log(` Domain: ${options.domain} (${summary.domainVerified ? 'verified' : 'pending'})`);\n if (summary.portalLink) console.log(` Portal: ${summary.portalLink}`);\n }\n } catch (error) {\n handleApiError(error);\n }\n}\n"]}
|
package/dist/commands/user.js
CHANGED
|
@@ -1,56 +1,34 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import {
|
|
2
|
+
import { createWorkOSClient } from '../lib/workos-client.js';
|
|
3
3
|
import { formatTable } from '../utils/table.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
console.error(chalk.red('Invalid API key. Check your environment configuration.'));
|
|
8
|
-
}
|
|
9
|
-
else if (error.statusCode === 404) {
|
|
10
|
-
console.error(chalk.red('User not found.'));
|
|
11
|
-
}
|
|
12
|
-
else if (error.statusCode === 422 && error.errors?.length) {
|
|
13
|
-
console.error(chalk.red(error.errors.map((e) => e.message).join(', ')));
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
console.error(chalk.red(error.message));
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
console.error(chalk.red(error instanceof Error ? error.message : 'Unknown error'));
|
|
21
|
-
}
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
4
|
+
import { outputSuccess, outputJson, isJsonMode } from '../utils/output.js';
|
|
5
|
+
import { createApiErrorHandler } from '../lib/api-error-handler.js';
|
|
6
|
+
const handleApiError = createApiErrorHandler('User');
|
|
24
7
|
export async function runUserGet(userId, apiKey, baseUrl) {
|
|
8
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
25
9
|
try {
|
|
26
|
-
const user = await
|
|
27
|
-
|
|
28
|
-
path: `/user_management/users/${userId}`,
|
|
29
|
-
apiKey,
|
|
30
|
-
baseUrl,
|
|
31
|
-
});
|
|
32
|
-
console.log(JSON.stringify(user, null, 2));
|
|
10
|
+
const user = await client.sdk.userManagement.getUser(userId);
|
|
11
|
+
outputJson(user);
|
|
33
12
|
}
|
|
34
13
|
catch (error) {
|
|
35
14
|
handleApiError(error);
|
|
36
15
|
}
|
|
37
16
|
}
|
|
38
17
|
export async function runUserList(options, apiKey, baseUrl) {
|
|
18
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
39
19
|
try {
|
|
40
|
-
const result = await
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
organization_id: options.organization,
|
|
48
|
-
limit: options.limit,
|
|
49
|
-
before: options.before,
|
|
50
|
-
after: options.after,
|
|
51
|
-
order: options.order,
|
|
52
|
-
},
|
|
20
|
+
const result = await client.sdk.userManagement.listUsers({
|
|
21
|
+
email: options.email,
|
|
22
|
+
organizationId: options.organization,
|
|
23
|
+
limit: options.limit,
|
|
24
|
+
before: options.before,
|
|
25
|
+
after: options.after,
|
|
26
|
+
order: options.order,
|
|
53
27
|
});
|
|
28
|
+
if (isJsonMode()) {
|
|
29
|
+
outputJson({ data: result.data, listMetadata: result.listMetadata });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
54
32
|
if (result.data.length === 0) {
|
|
55
33
|
console.log('No users found.');
|
|
56
34
|
return;
|
|
@@ -58,9 +36,9 @@ export async function runUserList(options, apiKey, baseUrl) {
|
|
|
58
36
|
const rows = result.data.map((user) => [
|
|
59
37
|
user.id,
|
|
60
38
|
user.email,
|
|
61
|
-
user.
|
|
62
|
-
user.
|
|
63
|
-
user.
|
|
39
|
+
user.firstName || chalk.dim('-'),
|
|
40
|
+
user.lastName || chalk.dim('-'),
|
|
41
|
+
user.emailVerified ? 'Yes' : 'No',
|
|
64
42
|
]);
|
|
65
43
|
console.log(formatTable([
|
|
66
44
|
{ header: 'ID' },
|
|
@@ -69,7 +47,7 @@ export async function runUserList(options, apiKey, baseUrl) {
|
|
|
69
47
|
{ header: 'Last Name' },
|
|
70
48
|
{ header: 'Verified' },
|
|
71
49
|
], rows));
|
|
72
|
-
const { before, after } = result.
|
|
50
|
+
const { before, after } = result.listMetadata;
|
|
73
51
|
if (before && after) {
|
|
74
52
|
console.log(chalk.dim(`Before: ${before} After: ${after}`));
|
|
75
53
|
}
|
|
@@ -85,41 +63,27 @@ export async function runUserList(options, apiKey, baseUrl) {
|
|
|
85
63
|
}
|
|
86
64
|
}
|
|
87
65
|
export async function runUserUpdate(userId, apiKey, options, baseUrl) {
|
|
88
|
-
const
|
|
89
|
-
if (options.firstName !== undefined)
|
|
90
|
-
body.first_name = options.firstName;
|
|
91
|
-
if (options.lastName !== undefined)
|
|
92
|
-
body.last_name = options.lastName;
|
|
93
|
-
if (options.emailVerified !== undefined)
|
|
94
|
-
body.email_verified = options.emailVerified;
|
|
95
|
-
if (options.password !== undefined)
|
|
96
|
-
body.password = options.password;
|
|
97
|
-
if (options.externalId !== undefined)
|
|
98
|
-
body.external_id = options.externalId;
|
|
66
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
99
67
|
try {
|
|
100
|
-
const user = await
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
68
|
+
const user = await client.sdk.userManagement.updateUser({
|
|
69
|
+
userId,
|
|
70
|
+
...(options.firstName !== undefined && { firstName: options.firstName }),
|
|
71
|
+
...(options.lastName !== undefined && { lastName: options.lastName }),
|
|
72
|
+
...(options.emailVerified !== undefined && { emailVerified: options.emailVerified }),
|
|
73
|
+
...(options.password !== undefined && { password: options.password }),
|
|
74
|
+
...(options.externalId !== undefined && { externalId: options.externalId }),
|
|
106
75
|
});
|
|
107
|
-
|
|
108
|
-
console.log(JSON.stringify(user, null, 2));
|
|
76
|
+
outputSuccess('Updated user', user);
|
|
109
77
|
}
|
|
110
78
|
catch (error) {
|
|
111
79
|
handleApiError(error);
|
|
112
80
|
}
|
|
113
81
|
}
|
|
114
82
|
export async function runUserDelete(userId, apiKey, baseUrl) {
|
|
83
|
+
const client = createWorkOSClient(apiKey, baseUrl);
|
|
115
84
|
try {
|
|
116
|
-
await
|
|
117
|
-
|
|
118
|
-
path: `/user_management/users/${userId}`,
|
|
119
|
-
apiKey,
|
|
120
|
-
baseUrl,
|
|
121
|
-
});
|
|
122
|
-
console.log(chalk.green(`Deleted user ${userId}`));
|
|
85
|
+
await client.sdk.userManagement.deleteUser(userId);
|
|
86
|
+
outputSuccess('Deleted user', { id: userId });
|
|
123
87
|
}
|
|
124
88
|
catch (error) {
|
|
125
89
|
handleApiError(error);
|