workos 0.18.0 → 0.19.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 +8 -145
- package/dist/bin.js +129 -50
- package/dist/bin.js.map +1 -1
- package/dist/commands/api/index.js +18 -10
- package/dist/commands/api/index.js.map +1 -1
- package/dist/commands/api/interactive.js +11 -11
- package/dist/commands/api/interactive.js.map +1 -1
- package/dist/commands/claim.js +28 -16
- package/dist/commands/claim.js.map +1 -1
- package/dist/commands/connection.js +3 -3
- package/dist/commands/connection.js.map +1 -1
- package/dist/commands/debug.js +6 -6
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/dev.d.ts +7 -8
- package/dist/commands/dev.js +14 -14
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/directory.js +3 -3
- package/dist/commands/directory.js.map +1 -1
- package/dist/commands/doctor.js +2 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/emulate.d.ts +1 -0
- package/dist/commands/emulate.js +3 -2
- package/dist/commands/emulate.js.map +1 -1
- package/dist/commands/env.d.ts +10 -0
- package/dist/commands/env.js +94 -18
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/install.js +8 -13
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.d.ts +25 -15
- package/dist/commands/login.js +126 -71
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +4 -4
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/mcp.js +7 -16
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/migrations.js +2 -1
- package/dist/commands/migrations.js.map +1 -1
- package/dist/commands/seed.js +5 -4
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/setup.d.ts +50 -0
- package/dist/commands/setup.js +237 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/vault-run.js +3 -2
- package/dist/commands/vault-run.js.map +1 -1
- package/dist/commands/verify-login.d.ts +25 -0
- package/dist/commands/verify-login.js +158 -0
- package/dist/commands/verify-login.js.map +1 -0
- package/dist/doctor/issues.js +3 -2
- package/dist/doctor/issues.js.map +1 -1
- package/dist/doctor/output.js +2 -1
- package/dist/doctor/output.js.map +1 -1
- package/dist/integrations/dotnet/index.js +1 -1
- package/dist/integrations/dotnet/index.js.map +1 -1
- package/dist/integrations/elixir/index.js +1 -1
- package/dist/integrations/elixir/index.js.map +1 -1
- package/dist/integrations/go/index.js +1 -1
- package/dist/integrations/go/index.js.map +1 -1
- package/dist/integrations/nextjs/index.js +8 -5
- package/dist/integrations/nextjs/index.js.map +1 -1
- package/dist/integrations/nextjs/utils.d.ts +1 -1
- package/dist/integrations/nextjs/utils.js +21 -6
- package/dist/integrations/nextjs/utils.js.map +1 -1
- package/dist/integrations/react-router/index.js +5 -5
- package/dist/integrations/react-router/index.js.map +1 -1
- package/dist/integrations/react-router/utils.js +28 -12
- package/dist/integrations/react-router/utils.js.map +1 -1
- package/dist/integrations/ruby/index.js +1 -1
- package/dist/integrations/ruby/index.js.map +1 -1
- package/dist/lib/adapters/cli-adapter.d.ts +33 -4
- package/dist/lib/adapters/cli-adapter.js +251 -135
- package/dist/lib/adapters/cli-adapter.js.map +1 -1
- package/dist/lib/adapters/dashboard-adapter.js +3 -3
- package/dist/lib/adapters/dashboard-adapter.js.map +1 -1
- package/dist/lib/adapters/headless-adapter.d.ts +7 -0
- package/dist/lib/adapters/headless-adapter.js +42 -5
- package/dist/lib/adapters/headless-adapter.js.map +1 -1
- package/dist/lib/agent-interface.js +15 -1
- package/dist/lib/agent-interface.js.map +1 -1
- package/dist/lib/agent-runner.js +1 -1
- package/dist/lib/agent-runner.js.map +1 -1
- package/dist/lib/api-key.js +2 -1
- package/dist/lib/api-key.js.map +1 -1
- package/dist/lib/completion-data.d.ts +33 -0
- package/dist/lib/completion-data.js +33 -0
- package/dist/lib/completion-data.js.map +1 -0
- package/dist/lib/config-store.d.ts +13 -0
- package/dist/lib/config-store.js +24 -0
- package/dist/lib/config-store.js.map +1 -1
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +8 -0
- package/dist/lib/constants.js +8 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/events.d.ts +34 -1
- package/dist/lib/events.js.map +1 -1
- package/dist/lib/framework-config.d.ts +6 -0
- package/dist/lib/framework-config.js.map +1 -1
- package/dist/lib/installer-core.d.ts +14 -1
- package/dist/lib/installer-core.js +24 -5
- package/dist/lib/installer-core.js.map +1 -1
- package/dist/lib/installer-core.types.d.ts +3 -1
- package/dist/lib/installer-core.types.js.map +1 -1
- package/dist/lib/mcp-clients.d.ts +6 -0
- package/dist/lib/mcp-clients.js +13 -0
- package/dist/lib/mcp-clients.js.map +1 -1
- package/dist/lib/port-detection.js +19 -13
- package/dist/lib/port-detection.js.map +1 -1
- package/dist/lib/preferences.d.ts +30 -2
- package/dist/lib/preferences.js +34 -8
- package/dist/lib/preferences.js.map +1 -1
- package/dist/lib/run-with-core.js +40 -3
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/telemetry-notice.d.ts +5 -5
- package/dist/lib/telemetry-notice.js +7 -8
- package/dist/lib/telemetry-notice.js.map +1 -1
- package/dist/lib/unclaimed-env-provision.js +15 -12
- package/dist/lib/unclaimed-env-provision.js.map +1 -1
- package/dist/lib/unclaimed-warning.js +4 -3
- package/dist/lib/unclaimed-warning.js.map +1 -1
- package/dist/lib/validation/security-checks.js +2 -1
- package/dist/lib/validation/security-checks.js.map +1 -1
- package/dist/lib/validation/validator.js +30 -3
- package/dist/lib/validation/validator.js.map +1 -1
- package/dist/lib/workos-management.js +26 -19
- package/dist/lib/workos-management.js.map +1 -1
- package/dist/run.d.ts +1 -0
- package/dist/run.js +5 -1
- package/dist/run.js.map +1 -1
- package/dist/steps/add-or-update-environment-variables.js +10 -10
- package/dist/steps/add-or-update-environment-variables.js.map +1 -1
- package/dist/steps/run-prettier.js +3 -3
- package/dist/steps/run-prettier.js.map +1 -1
- package/dist/steps/upload-environment-variables/index.js +15 -3
- package/dist/steps/upload-environment-variables/index.js.map +1 -1
- package/dist/steps/upload-environment-variables/providers/vercel.js +2 -2
- package/dist/steps/upload-environment-variables/providers/vercel.js.map +1 -1
- package/dist/utils/box.d.ts +6 -30
- package/dist/utils/box.js +8 -95
- package/dist/utils/box.js.map +1 -1
- package/dist/utils/cli-symbols.d.ts +14 -2
- package/dist/utils/cli-symbols.js +12 -0
- package/dist/utils/cli-symbols.js.map +1 -1
- package/dist/utils/debug.js +3 -3
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/environment.js +1 -1
- package/dist/utils/environment.js.map +1 -1
- package/dist/utils/help-json.js +115 -4
- package/dist/utils/help-json.js.map +1 -1
- package/dist/utils/package-manager.js +1 -1
- package/dist/utils/package-manager.js.map +1 -1
- package/dist/utils/recovery-hints.d.ts +5 -0
- package/dist/utils/recovery-hints.js +12 -0
- package/dist/utils/recovery-hints.js.map +1 -1
- package/dist/utils/summary-box.d.ts +8 -1
- package/dist/utils/summary-box.js +67 -4
- package/dist/utils/summary-box.js.map +1 -1
- package/dist/utils/types.d.ts +10 -0
- package/dist/utils/types.js.map +1 -1
- package/dist/utils/{clack-utils.d.ts → ui-utils.d.ts} +1 -1
- package/dist/utils/{clack-utils.js → ui-utils.js} +64 -37
- package/dist/utils/ui-utils.js.map +1 -0
- package/dist/utils/ui.d.ts +148 -0
- package/dist/utils/ui.js +368 -0
- package/dist/utils/ui.js.map +1 -0
- package/package.json +5 -13
- package/dist/check-coverage.ts +0 -237
- package/dist/emulate/core/id.d.ts +0 -48
- package/dist/emulate/core/id.js +0 -73
- package/dist/emulate/core/id.js.map +0 -1
- package/dist/emulate/core/index.d.ts +0 -8
- package/dist/emulate/core/index.js +0 -8
- package/dist/emulate/core/index.js.map +0 -1
- package/dist/emulate/core/jwt.d.ts +0 -28
- package/dist/emulate/core/jwt.js +0 -78
- package/dist/emulate/core/jwt.js.map +0 -1
- package/dist/emulate/core/middleware/auth.d.ts +0 -15
- package/dist/emulate/core/middleware/auth.js +0 -17
- package/dist/emulate/core/middleware/auth.js.map +0 -1
- package/dist/emulate/core/middleware/error-handler.d.ts +0 -22
- package/dist/emulate/core/middleware/error-handler.js +0 -72
- package/dist/emulate/core/middleware/error-handler.js.map +0 -1
- package/dist/emulate/core/pagination.d.ts +0 -27
- package/dist/emulate/core/pagination.js +0 -43
- package/dist/emulate/core/pagination.js.map +0 -1
- package/dist/emulate/core/plugin.d.ts +0 -15
- package/dist/emulate/core/plugin.js +0 -2
- package/dist/emulate/core/plugin.js.map +0 -1
- package/dist/emulate/core/server.d.ts +0 -17
- package/dist/emulate/core/server.js +0 -90
- package/dist/emulate/core/server.js.map +0 -1
- package/dist/emulate/core/store.d.ts +0 -44
- package/dist/emulate/core/store.js +0 -169
- package/dist/emulate/core/store.js.map +0 -1
- package/dist/emulate/index.d.ts +0 -25
- package/dist/emulate/index.js +0 -47
- package/dist/emulate/index.js.map +0 -1
- package/dist/emulate/workos/constants.d.ts +0 -56
- package/dist/emulate/workos/constants.js +0 -56
- package/dist/emulate/workos/constants.js.map +0 -1
- package/dist/emulate/workos/entities.d.ts +0 -360
- package/dist/emulate/workos/entities.js +0 -2
- package/dist/emulate/workos/entities.js.map +0 -1
- package/dist/emulate/workos/event-bus.d.ts +0 -17
- package/dist/emulate/workos/event-bus.js +0 -70
- package/dist/emulate/workos/event-bus.js.map +0 -1
- package/dist/emulate/workos/helpers.d.ts +0 -72
- package/dist/emulate/workos/helpers.js +0 -211
- package/dist/emulate/workos/helpers.js.map +0 -1
- package/dist/emulate/workos/index.d.ts +0 -93
- package/dist/emulate/workos/index.js +0 -326
- package/dist/emulate/workos/index.js.map +0 -1
- package/dist/emulate/workos/role-helpers.d.ts +0 -21
- package/dist/emulate/workos/role-helpers.js +0 -130
- package/dist/emulate/workos/role-helpers.js.map +0 -1
- package/dist/emulate/workos/routes/api-keys.d.ts +0 -2
- package/dist/emulate/workos/routes/api-keys.js +0 -32
- package/dist/emulate/workos/routes/api-keys.js.map +0 -1
- package/dist/emulate/workos/routes/audit-logs.d.ts +0 -2
- package/dist/emulate/workos/routes/audit-logs.js +0 -104
- package/dist/emulate/workos/routes/audit-logs.js.map +0 -1
- package/dist/emulate/workos/routes/auth-challenges.d.ts +0 -2
- package/dist/emulate/workos/routes/auth-challenges.js +0 -51
- package/dist/emulate/workos/routes/auth-challenges.js.map +0 -1
- package/dist/emulate/workos/routes/auth-factors.d.ts +0 -2
- package/dist/emulate/workos/routes/auth-factors.js +0 -51
- package/dist/emulate/workos/routes/auth-factors.js.map +0 -1
- package/dist/emulate/workos/routes/auth.d.ts +0 -2
- package/dist/emulate/workos/routes/auth.js +0 -350
- package/dist/emulate/workos/routes/auth.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-checks.d.ts +0 -10
- package/dist/emulate/workos/routes/authorization-checks.js +0 -123
- package/dist/emulate/workos/routes/authorization-checks.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-org-roles.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-org-roles.js +0 -64
- package/dist/emulate/workos/routes/authorization-org-roles.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-permissions.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-permissions.js +0 -67
- package/dist/emulate/workos/routes/authorization-permissions.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-resources.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-resources.js +0 -117
- package/dist/emulate/workos/routes/authorization-resources.js.map +0 -1
- package/dist/emulate/workos/routes/authorization-roles.d.ts +0 -2
- package/dist/emulate/workos/routes/authorization-roles.js +0 -13
- package/dist/emulate/workos/routes/authorization-roles.js.map +0 -1
- package/dist/emulate/workos/routes/config.d.ts +0 -2
- package/dist/emulate/workos/routes/config.js +0 -57
- package/dist/emulate/workos/routes/config.js.map +0 -1
- package/dist/emulate/workos/routes/connect.d.ts +0 -2
- package/dist/emulate/workos/routes/connect.js +0 -65
- package/dist/emulate/workos/routes/connect.js.map +0 -1
- package/dist/emulate/workos/routes/connections.d.ts +0 -2
- package/dist/emulate/workos/routes/connections.js +0 -73
- package/dist/emulate/workos/routes/connections.js.map +0 -1
- package/dist/emulate/workos/routes/data-integrations.d.ts +0 -2
- package/dist/emulate/workos/routes/data-integrations.js +0 -55
- package/dist/emulate/workos/routes/data-integrations.js.map +0 -1
- package/dist/emulate/workos/routes/directories.d.ts +0 -2
- package/dist/emulate/workos/routes/directories.js +0 -90
- package/dist/emulate/workos/routes/directories.js.map +0 -1
- package/dist/emulate/workos/routes/email-verification.d.ts +0 -2
- package/dist/emulate/workos/routes/email-verification.js +0 -49
- package/dist/emulate/workos/routes/email-verification.js.map +0 -1
- package/dist/emulate/workos/routes/events.d.ts +0 -2
- package/dist/emulate/workos/routes/events.js +0 -18
- package/dist/emulate/workos/routes/events.js.map +0 -1
- package/dist/emulate/workos/routes/feature-flags.d.ts +0 -2
- package/dist/emulate/workos/routes/feature-flags.js +0 -103
- package/dist/emulate/workos/routes/feature-flags.js.map +0 -1
- package/dist/emulate/workos/routes/invitations.d.ts +0 -2
- package/dist/emulate/workos/routes/invitations.js +0 -122
- package/dist/emulate/workos/routes/invitations.js.map +0 -1
- package/dist/emulate/workos/routes/legacy-mfa.d.ts +0 -2
- package/dist/emulate/workos/routes/legacy-mfa.js +0 -75
- package/dist/emulate/workos/routes/legacy-mfa.js.map +0 -1
- package/dist/emulate/workos/routes/magic-auth.d.ts +0 -2
- package/dist/emulate/workos/routes/magic-auth.js +0 -32
- package/dist/emulate/workos/routes/magic-auth.js.map +0 -1
- package/dist/emulate/workos/routes/memberships.d.ts +0 -2
- package/dist/emulate/workos/routes/memberships.js +0 -114
- package/dist/emulate/workos/routes/memberships.js.map +0 -1
- package/dist/emulate/workos/routes/organization-domains.d.ts +0 -2
- package/dist/emulate/workos/routes/organization-domains.js +0 -58
- package/dist/emulate/workos/routes/organization-domains.js.map +0 -1
- package/dist/emulate/workos/routes/organizations.d.ts +0 -2
- package/dist/emulate/workos/routes/organizations.js +0 -131
- package/dist/emulate/workos/routes/organizations.js.map +0 -1
- package/dist/emulate/workos/routes/password-reset.d.ts +0 -2
- package/dist/emulate/workos/routes/password-reset.js +0 -61
- package/dist/emulate/workos/routes/password-reset.js.map +0 -1
- package/dist/emulate/workos/routes/pipes.d.ts +0 -2
- package/dist/emulate/workos/routes/pipes.js +0 -82
- package/dist/emulate/workos/routes/pipes.js.map +0 -1
- package/dist/emulate/workos/routes/portal.d.ts +0 -2
- package/dist/emulate/workos/routes/portal.js +0 -18
- package/dist/emulate/workos/routes/portal.js.map +0 -1
- package/dist/emulate/workos/routes/radar.d.ts +0 -2
- package/dist/emulate/workos/routes/radar.js +0 -41
- package/dist/emulate/workos/routes/radar.js.map +0 -1
- package/dist/emulate/workos/routes/sessions.d.ts +0 -2
- package/dist/emulate/workos/routes/sessions.js +0 -51
- package/dist/emulate/workos/routes/sessions.js.map +0 -1
- package/dist/emulate/workos/routes/sso.d.ts +0 -2
- package/dist/emulate/workos/routes/sso.js +0 -161
- package/dist/emulate/workos/routes/sso.js.map +0 -1
- package/dist/emulate/workos/routes/user-features.d.ts +0 -2
- package/dist/emulate/workos/routes/user-features.js +0 -50
- package/dist/emulate/workos/routes/user-features.js.map +0 -1
- package/dist/emulate/workos/routes/users.d.ts +0 -2
- package/dist/emulate/workos/routes/users.js +0 -129
- package/dist/emulate/workos/routes/users.js.map +0 -1
- package/dist/emulate/workos/routes/webhook-endpoints.d.ts +0 -2
- package/dist/emulate/workos/routes/webhook-endpoints.js +0 -67
- package/dist/emulate/workos/routes/webhook-endpoints.js.map +0 -1
- package/dist/emulate/workos/routes/widgets.d.ts +0 -2
- package/dist/emulate/workos/routes/widgets.js +0 -27
- package/dist/emulate/workos/routes/widgets.js.map +0 -1
- package/dist/emulate/workos/store.d.ts +0 -48
- package/dist/emulate/workos/store.js +0 -102
- package/dist/emulate/workos/store.js.map +0 -1
- package/dist/emulate/workos/webhook-signer.d.ts +0 -1
- package/dist/emulate/workos/webhook-signer.js +0 -8
- package/dist/emulate/workos/webhook-signer.js.map +0 -1
- package/dist/gen-routes-lib.spec.ts +0 -659
- package/dist/gen-routes-lib.ts +0 -647
- package/dist/gen-routes.ts +0 -96
- package/dist/lib/mcp-notice.d.ts +0 -72
- package/dist/lib/mcp-notice.js +0 -275
- package/dist/lib/mcp-notice.js.map +0 -1
- package/dist/utils/clack-utils.js.map +0 -1
- package/dist/utils/clack.d.ts +0 -5
- package/dist/utils/clack.js +0 -34
- package/dist/utils/clack.js.map +0 -1
|
@@ -5,29 +5,29 @@ import { apiRequest } from './request.js';
|
|
|
5
5
|
import { resolveApiBaseUrl } from '../../lib/api-key.js';
|
|
6
6
|
import { exitWithError, isJsonMode, outputJson } from '../../utils/output.js';
|
|
7
7
|
import { ExitCode, exitWithCode } from '../../utils/exit-codes.js';
|
|
8
|
-
import { isCiMode, isPromptAllowed } from '../../utils/interaction-mode.js';
|
|
9
|
-
import { confirmationRecovery } from '../../utils/recovery-hints.js';
|
|
10
|
-
import { formatWorkOSCommandArgs } from '../../utils/command-invocation.js';
|
|
8
|
+
import { isCiMode, isPromptAllowed, getInteractionMode } from '../../utils/interaction-mode.js';
|
|
9
|
+
import { confirmationRecovery, authLoginRecovery, missingArgsRecovery } from '../../utils/recovery-hints.js';
|
|
10
|
+
import { formatWorkOSCommand, formatWorkOSCommandArgs } from '../../utils/command-invocation.js';
|
|
11
11
|
import { colorMethod, printResponse } from './format.js';
|
|
12
12
|
export { colorMethod } from './format.js';
|
|
13
13
|
const MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);
|
|
14
14
|
export async function runApiInteractive(options) {
|
|
15
|
-
// Interactive mode is inherently human-oriented (
|
|
15
|
+
// Interactive mode is inherently human-oriented (interactive prompts, preview text,
|
|
16
16
|
// etc.). Refuse to enter it whenever JSON output was requested, regardless of
|
|
17
17
|
// TTY status, so stdout stays machine-readable.
|
|
18
18
|
if (isJsonMode()) {
|
|
19
19
|
exitWithError({
|
|
20
20
|
code: 'tty_required',
|
|
21
|
-
message:
|
|
21
|
+
message: `Interactive mode is not available with --json. Provide an endpoint or use \`${formatWorkOSCommand('api ls')}\`.`,
|
|
22
22
|
details: {
|
|
23
|
-
usage: ['
|
|
23
|
+
usage: [formatWorkOSCommand('api <endpoint>'), formatWorkOSCommand('api ls [filter]')],
|
|
24
24
|
},
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
if (!isPromptAllowed()) {
|
|
28
28
|
exitWithError({
|
|
29
29
|
code: 'tty_required',
|
|
30
|
-
message:
|
|
30
|
+
message: `Interactive API mode requires human mode. Usage: ${formatWorkOSCommand('api <endpoint>')} or ${formatWorkOSCommand('api ls [filter]')}. Example: ${formatWorkOSCommand('api /user_management/users')}`,
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
const { apiInteractive } = await import('./interactive.js');
|
|
@@ -116,12 +116,12 @@ export async function runApiRequest(endpoint, options) {
|
|
|
116
116
|
recovery: confirmationRecovery(confirmCommand),
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
|
-
const
|
|
119
|
+
const ui = (await import('../../utils/ui.js')).default;
|
|
120
120
|
console.log(`\n${chalk.yellow('About to')} ${method} ${endpoint}`);
|
|
121
121
|
if (hasBody)
|
|
122
122
|
prettyPrint(body);
|
|
123
|
-
const ok = await
|
|
124
|
-
if (!ok ||
|
|
123
|
+
const ok = await ui.confirm({ message: 'Proceed?' });
|
|
124
|
+
if (!ok || ui.isCancel(ok)) {
|
|
125
125
|
exitWithCode(ExitCode.CANCELLED);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
@@ -134,10 +134,18 @@ export async function runApiRequest(endpoint, options) {
|
|
|
134
134
|
});
|
|
135
135
|
printResponse(response, { includeStatus: options.include });
|
|
136
136
|
if (response.status >= 400) {
|
|
137
|
+
// Give the caller a concrete next step keyed off the status: re-auth for
|
|
138
|
+
// 401/403, discover endpoints for 404.
|
|
139
|
+
const recovery = response.status === 401 || response.status === 403
|
|
140
|
+
? authLoginRecovery({ mode: getInteractionMode().mode })
|
|
141
|
+
: response.status === 404
|
|
142
|
+
? missingArgsRecovery(formatWorkOSCommand('api ls'), 'List available endpoints, then re-run with a valid path.')
|
|
143
|
+
: undefined;
|
|
137
144
|
exitWithError({
|
|
138
145
|
code: `http_${response.status}`,
|
|
139
146
|
message: `API request failed with status ${response.status}`,
|
|
140
147
|
apiContext: { status: response.status },
|
|
148
|
+
...(recovery && { recovery }),
|
|
141
149
|
});
|
|
142
150
|
}
|
|
143
151
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/api/index.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { readFile } from 'node:fs/promises';\nimport { loadCatalog, endpointsByTag } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { exitWithError, isJsonMode, outputJson } from '../../utils/output.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { isCiMode, isPromptAllowed } from '../../utils/interaction-mode.js';\nimport { confirmationRecovery } from '../../utils/recovery-hints.js';\nimport { formatWorkOSCommandArgs } from '../../utils/command-invocation.js';\nimport { colorMethod, printResponse } from './format.js';\n\nexport { colorMethod } from './format.js';\n\nexport interface ApiCommandOptions {\n method?: string;\n data?: string;\n file?: string;\n include?: boolean;\n apiKey?: string;\n dryRun?: boolean;\n yes?: boolean;\n}\n\nconst MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);\n\nexport async function runApiInteractive(options?: { apiKey?: string }): Promise<void> {\n // Interactive mode is inherently human-oriented (clack prompts, preview text,\n // etc.). Refuse to enter it whenever JSON output was requested, regardless of\n // TTY status, so stdout stays machine-readable.\n if (isJsonMode()) {\n exitWithError({\n code: 'tty_required',\n message: 'Interactive mode is not available with --json. Provide an endpoint or use `workos api ls`.',\n details: {\n usage: ['workos api <endpoint>', 'workos api ls [filter]'],\n },\n });\n }\n\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'tty_required',\n message:\n 'Interactive API mode requires human mode. Usage: workos api <endpoint> or workos api ls [filter]. Example: workos api /user_management/users',\n });\n }\n\n const { apiInteractive } = await import('./interactive.js');\n await apiInteractive({ apiKey: options?.apiKey });\n}\n\nexport async function runApiLs(filter?: string): Promise<void> {\n const catalog = await loadCatalog();\n let endpoints = catalog.endpoints;\n\n if (filter) {\n const lower = filter.toLowerCase();\n endpoints = endpoints.filter(\n (e) =>\n e.path.toLowerCase().includes(lower) ||\n e.tag.toLowerCase().includes(lower) ||\n e.summary.toLowerCase().includes(lower) ||\n e.operationId.toLowerCase().includes(lower),\n );\n }\n\n if (isJsonMode()) {\n outputJson({\n data: endpoints.map((e) => ({\n method: e.method,\n path: e.path,\n summary: e.summary,\n tag: e.tag,\n })),\n });\n return;\n }\n\n if (endpoints.length === 0) {\n console.log(filter ? `No endpoints matching \"${filter}\".` : 'No endpoints found.');\n return;\n }\n\n const grouped = endpointsByTag(endpoints);\n\n for (const [tag, eps] of grouped) {\n console.log(`\\n${chalk.bold(tag)}`);\n for (const ep of eps) {\n const method = colorMethod(ep.method).padEnd(18);\n console.log(` ${method} ${ep.path} ${chalk.dim(ep.summary)}`);\n }\n }\n console.log();\n}\n\nexport async function runApiRequest(endpoint: string, options: ApiCommandOptions): Promise<void> {\n const body = await resolveBody(options);\n const hasBody = body !== undefined;\n const method = (options.method ?? (hasBody ? 'POST' : 'GET')).toUpperCase();\n const baseUrl = resolveApiBaseUrl();\n\n if (options.dryRun) {\n if (isJsonMode()) {\n let parsedBody: unknown;\n if (hasBody) {\n try {\n parsedBody = JSON.parse(body);\n } catch {\n exitWithError({ code: 'invalid_json_body', message: 'Request body is not valid JSON.' });\n }\n }\n outputJson({\n dryRun: true,\n method,\n url: `${baseUrl}${normalizePath(endpoint)}`,\n body: parsedBody,\n });\n } else {\n console.log(`${chalk.dim('[dry-run]')} ${method} ${baseUrl}${normalizePath(endpoint)}`);\n if (hasBody) prettyPrint(body);\n }\n return;\n }\n\n if (MUTATING_METHODS.has(method) && !options.yes) {\n const confirmCommand = buildConfirmationCommand(endpoint, method, options);\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'confirmation_required',\n message: isCiMode()\n ? `Mutating requests in CI mode require --yes. Refusing to ${method} ${endpoint}.`\n : `Mutating requests in agent mode require --yes. Refusing to ${method} ${endpoint}.`,\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n if (isJsonMode()) {\n exitWithError({\n code: 'confirmation_required',\n message: 'Mutating requests in JSON mode require --yes to keep stdout machine-readable.',\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n const clack = (await import('../../utils/clack.js')).default;\n console.log(`\\n${chalk.yellow('About to')} ${method} ${endpoint}`);\n if (hasBody) prettyPrint(body);\n const ok = await clack.confirm({ message: 'Proceed?' });\n if (!ok || clack.isCancel(ok)) {\n exitWithCode(ExitCode.CANCELLED);\n }\n }\n\n const response = await apiRequest({\n method,\n path: normalizePath(endpoint),\n apiKey: options.apiKey,\n body,\n baseUrl,\n });\n\n printResponse(response, { includeStatus: options.include });\n\n if (response.status >= 400) {\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n });\n }\n}\n\nfunction normalizePath(path: string): string {\n if (!path.startsWith('/')) return `/${path}`;\n return path;\n}\n\nfunction buildConfirmationCommand(endpoint: string, method: string, options: ApiCommandOptions): string | undefined {\n if (options.apiKey || options.file === '-') {\n return undefined;\n }\n\n const args = ['api', endpoint, '--method', method];\n if (options.data !== undefined) {\n args.push(`--data=${options.data}`);\n }\n if (options.file) {\n args.push(`--file=${options.file}`);\n }\n if (options.include) {\n args.push('--include');\n }\n args.push('--yes');\n return formatWorkOSCommandArgs(args);\n}\n\nasync function resolveBody(options: ApiCommandOptions): Promise<string | undefined> {\n if (options.data !== undefined) return options.data;\n if (options.file) {\n if (options.file === '-') {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinBody = Buffer.concat(chunks).toString('utf-8');\n if (stdinBody.length === 0) {\n exitWithError({\n code: 'empty_stdin_body',\n message:\n 'Reading request body from stdin (--file -) yielded no data. Pipe data into the command or pass --data instead.',\n });\n }\n return stdinBody;\n }\n try {\n return await readFile(options.file, 'utf-8');\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n exitWithError({\n code: 'file_read_error',\n message: `Could not read request body file \"${options.file}\": ${message}`,\n });\n }\n }\n return undefined;\n}\n\nfunction prettyPrint(jsonString: string): void {\n try {\n console.log(JSON.stringify(JSON.parse(jsonString), null, 2));\n } catch {\n console.log(jsonString);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAC7G,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAY1C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAA6B;IACnE,oFAAoF;IACpF,8EAA8E;IAC9E,gDAAgD;IAChD,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,aAAa,CAAC;YACZ,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,+EAA+E,mBAAmB,CAAC,QAAQ,CAAC,KAAK;YAC1H,OAAO,EAAE;gBACP,KAAK,EAAE,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;aACvF;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,aAAa,CAAC;YACZ,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,oDAAoD,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,mBAAmB,CAAC,iBAAiB,CAAC,cAAc,mBAAmB,CAAC,4BAA4B,CAAC,EAAE;SACjN,CAAC,CAAC;IACL,CAAC;IAED,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC5D,MAAM,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAe;IAC5C,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;IACpC,IAAI,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAElC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACnC,SAAS,GAAG,SAAS,CAAC,MAAM,CAC1B,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YACpC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YACnC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;YACvC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAC9C,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,UAAU,CAAC;YACT,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,GAAG,EAAE,CAAC,CAAC,GAAG;aACX,CAAC,CAAC;SACJ,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,0BAA0B,MAAM,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;QACnF,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,OAA0B;IAC9E,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,KAAK,SAAS,CAAC;IACnC,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5E,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,IAAI,UAAmB,CAAC;YACxB,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC;oBACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChC,CAAC;gBAAC,MAAM,CAAC;oBACP,aAAa,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC,CAAC;gBAC3F,CAAC;YACH,CAAC;YACD,UAAU,CAAC;gBACT,MAAM,EAAE,IAAI;gBACZ,MAAM;gBACN,GAAG,EAAE,GAAG,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,EAAE;gBAC3C,IAAI,EAAE,UAAU;aACjB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,MAAM,IAAI,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACxF,IAAI,OAAO;gBAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjD,MAAM,cAAc,GAAG,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3E,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,aAAa,CAAC;gBACZ,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,QAAQ,EAAE;oBACjB,CAAC,CAAC,2DAA2D,MAAM,IAAI,QAAQ,GAAG;oBAClF,CAAC,CAAC,8DAA8D,MAAM,IAAI,QAAQ,GAAG;gBACvF,QAAQ,EAAE,oBAAoB,CAAC,cAAc,CAAC;aAC/C,CAAC,CAAC;QACL,CAAC;QACD,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,aAAa,CAAC;gBACZ,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,+EAA+E;gBACxF,QAAQ,EAAE,oBAAoB,CAAC,cAAc,CAAC;aAC/C,CAAC,CAAC;QACL,CAAC;QACD,MAAM,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC;QACnE,IAAI,OAAO;YAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3B,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC;QAChC,MAAM;QACN,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC;QAC7B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,IAAI;QACJ,OAAO;KACR,CAAC,CAAC;IAEH,aAAa,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAE5D,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC3B,yEAAyE;QACzE,uCAAuC;QACvC,MAAM,QAAQ,GACZ,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAChD,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,IAAI,EAAE,CAAC;YACxD,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG;gBACvB,CAAC,CAAC,mBAAmB,CACjB,mBAAmB,CAAC,QAAQ,CAAC,EAC7B,0DAA0D,CAC3D;gBACH,CAAC,CAAC,SAAS,CAAC;QAClB,aAAa,CAAC;YACZ,IAAI,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE;YAC/B,OAAO,EAAE,kCAAkC,QAAQ,CAAC,MAAM,EAAE;YAC5D,UAAU,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE;YACvC,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,IAAI,EAAE,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,wBAAwB,CAAC,QAAgB,EAAE,MAAc,EAAE,OAA0B;IAC5F,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;QAC3C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAA0B;IACnD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IACpD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,OAAO,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC1D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,aAAa,CAAC;oBACZ,IAAI,EAAE,kBAAkB;oBACxB,OAAO,EACL,gHAAgH;iBACnH,CAAC,CAAC;YACL,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,CAAC;YACH,OAAO,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,aAAa,CAAC;gBACZ,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,qCAAqC,OAAO,CAAC,IAAI,MAAM,OAAO,EAAE;aAC1E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,WAAW,CAAC,UAAkB;IACrC,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC","sourcesContent":["import chalk from 'chalk';\nimport { readFile } from 'node:fs/promises';\nimport { loadCatalog, endpointsByTag } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { exitWithError, isJsonMode, outputJson } from '../../utils/output.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { isCiMode, isPromptAllowed, getInteractionMode } from '../../utils/interaction-mode.js';\nimport { confirmationRecovery, authLoginRecovery, missingArgsRecovery } from '../../utils/recovery-hints.js';\nimport { formatWorkOSCommand, formatWorkOSCommandArgs } from '../../utils/command-invocation.js';\nimport { colorMethod, printResponse } from './format.js';\n\nexport { colorMethod } from './format.js';\n\nexport interface ApiCommandOptions {\n method?: string;\n data?: string;\n file?: string;\n include?: boolean;\n apiKey?: string;\n dryRun?: boolean;\n yes?: boolean;\n}\n\nconst MUTATING_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE']);\n\nexport async function runApiInteractive(options?: { apiKey?: string }): Promise<void> {\n // Interactive mode is inherently human-oriented (interactive prompts, preview text,\n // etc.). Refuse to enter it whenever JSON output was requested, regardless of\n // TTY status, so stdout stays machine-readable.\n if (isJsonMode()) {\n exitWithError({\n code: 'tty_required',\n message: `Interactive mode is not available with --json. Provide an endpoint or use \\`${formatWorkOSCommand('api ls')}\\`.`,\n details: {\n usage: [formatWorkOSCommand('api <endpoint>'), formatWorkOSCommand('api ls [filter]')],\n },\n });\n }\n\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'tty_required',\n message: `Interactive API mode requires human mode. Usage: ${formatWorkOSCommand('api <endpoint>')} or ${formatWorkOSCommand('api ls [filter]')}. Example: ${formatWorkOSCommand('api /user_management/users')}`,\n });\n }\n\n const { apiInteractive } = await import('./interactive.js');\n await apiInteractive({ apiKey: options?.apiKey });\n}\n\nexport async function runApiLs(filter?: string): Promise<void> {\n const catalog = await loadCatalog();\n let endpoints = catalog.endpoints;\n\n if (filter) {\n const lower = filter.toLowerCase();\n endpoints = endpoints.filter(\n (e) =>\n e.path.toLowerCase().includes(lower) ||\n e.tag.toLowerCase().includes(lower) ||\n e.summary.toLowerCase().includes(lower) ||\n e.operationId.toLowerCase().includes(lower),\n );\n }\n\n if (isJsonMode()) {\n outputJson({\n data: endpoints.map((e) => ({\n method: e.method,\n path: e.path,\n summary: e.summary,\n tag: e.tag,\n })),\n });\n return;\n }\n\n if (endpoints.length === 0) {\n console.log(filter ? `No endpoints matching \"${filter}\".` : 'No endpoints found.');\n return;\n }\n\n const grouped = endpointsByTag(endpoints);\n\n for (const [tag, eps] of grouped) {\n console.log(`\\n${chalk.bold(tag)}`);\n for (const ep of eps) {\n const method = colorMethod(ep.method).padEnd(18);\n console.log(` ${method} ${ep.path} ${chalk.dim(ep.summary)}`);\n }\n }\n console.log();\n}\n\nexport async function runApiRequest(endpoint: string, options: ApiCommandOptions): Promise<void> {\n const body = await resolveBody(options);\n const hasBody = body !== undefined;\n const method = (options.method ?? (hasBody ? 'POST' : 'GET')).toUpperCase();\n const baseUrl = resolveApiBaseUrl();\n\n if (options.dryRun) {\n if (isJsonMode()) {\n let parsedBody: unknown;\n if (hasBody) {\n try {\n parsedBody = JSON.parse(body);\n } catch {\n exitWithError({ code: 'invalid_json_body', message: 'Request body is not valid JSON.' });\n }\n }\n outputJson({\n dryRun: true,\n method,\n url: `${baseUrl}${normalizePath(endpoint)}`,\n body: parsedBody,\n });\n } else {\n console.log(`${chalk.dim('[dry-run]')} ${method} ${baseUrl}${normalizePath(endpoint)}`);\n if (hasBody) prettyPrint(body);\n }\n return;\n }\n\n if (MUTATING_METHODS.has(method) && !options.yes) {\n const confirmCommand = buildConfirmationCommand(endpoint, method, options);\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'confirmation_required',\n message: isCiMode()\n ? `Mutating requests in CI mode require --yes. Refusing to ${method} ${endpoint}.`\n : `Mutating requests in agent mode require --yes. Refusing to ${method} ${endpoint}.`,\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n if (isJsonMode()) {\n exitWithError({\n code: 'confirmation_required',\n message: 'Mutating requests in JSON mode require --yes to keep stdout machine-readable.',\n recovery: confirmationRecovery(confirmCommand),\n });\n }\n const ui = (await import('../../utils/ui.js')).default;\n console.log(`\\n${chalk.yellow('About to')} ${method} ${endpoint}`);\n if (hasBody) prettyPrint(body);\n const ok = await ui.confirm({ message: 'Proceed?' });\n if (!ok || ui.isCancel(ok)) {\n exitWithCode(ExitCode.CANCELLED);\n }\n }\n\n const response = await apiRequest({\n method,\n path: normalizePath(endpoint),\n apiKey: options.apiKey,\n body,\n baseUrl,\n });\n\n printResponse(response, { includeStatus: options.include });\n\n if (response.status >= 400) {\n // Give the caller a concrete next step keyed off the status: re-auth for\n // 401/403, discover endpoints for 404.\n const recovery =\n response.status === 401 || response.status === 403\n ? authLoginRecovery({ mode: getInteractionMode().mode })\n : response.status === 404\n ? missingArgsRecovery(\n formatWorkOSCommand('api ls'),\n 'List available endpoints, then re-run with a valid path.',\n )\n : undefined;\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n ...(recovery && { recovery }),\n });\n }\n}\n\nfunction normalizePath(path: string): string {\n if (!path.startsWith('/')) return `/${path}`;\n return path;\n}\n\nfunction buildConfirmationCommand(endpoint: string, method: string, options: ApiCommandOptions): string | undefined {\n if (options.apiKey || options.file === '-') {\n return undefined;\n }\n\n const args = ['api', endpoint, '--method', method];\n if (options.data !== undefined) {\n args.push(`--data=${options.data}`);\n }\n if (options.file) {\n args.push(`--file=${options.file}`);\n }\n if (options.include) {\n args.push('--include');\n }\n args.push('--yes');\n return formatWorkOSCommandArgs(args);\n}\n\nasync function resolveBody(options: ApiCommandOptions): Promise<string | undefined> {\n if (options.data !== undefined) return options.data;\n if (options.file) {\n if (options.file === '-') {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk);\n }\n const stdinBody = Buffer.concat(chunks).toString('utf-8');\n if (stdinBody.length === 0) {\n exitWithError({\n code: 'empty_stdin_body',\n message:\n 'Reading request body from stdin (--file -) yielded no data. Pipe data into the command or pass --data instead.',\n });\n }\n return stdinBody;\n }\n try {\n return await readFile(options.file, 'utf-8');\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n exitWithError({\n code: 'file_read_error',\n message: `Could not read request body file \"${options.file}\": ${message}`,\n });\n }\n }\n return undefined;\n}\n\nfunction prettyPrint(jsonString: string): void {\n try {\n console.log(JSON.stringify(JSON.parse(jsonString), null, 2));\n } catch {\n console.log(jsonString);\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ui from '../../utils/ui.js';
|
|
2
2
|
import { loadCatalog, endpointsByTag } from './catalog.js';
|
|
3
3
|
import { apiRequest } from './request.js';
|
|
4
4
|
import { colorMethod, printResponse } from './format.js';
|
|
@@ -6,14 +6,14 @@ import { resolveApiKey, resolveApiBaseUrl } from '../../lib/api-key.js';
|
|
|
6
6
|
import { ExitCode, exitWithCode } from '../../utils/exit-codes.js';
|
|
7
7
|
import { exitWithError } from '../../utils/output.js';
|
|
8
8
|
function assertNotCancelled(value) {
|
|
9
|
-
if (
|
|
9
|
+
if (ui.isCancel(value))
|
|
10
10
|
exitWithCode(ExitCode.CANCELLED);
|
|
11
11
|
return value;
|
|
12
12
|
}
|
|
13
13
|
export async function apiInteractive(options) {
|
|
14
14
|
const catalog = await loadCatalog();
|
|
15
15
|
const grouped = endpointsByTag(catalog.endpoints);
|
|
16
|
-
const tag = assertNotCancelled(await
|
|
16
|
+
const tag = assertNotCancelled(await ui.select({
|
|
17
17
|
message: 'Select a category:',
|
|
18
18
|
options: catalog.tags.map((t) => {
|
|
19
19
|
const count = grouped.get(t)?.length ?? 0;
|
|
@@ -21,7 +21,7 @@ export async function apiInteractive(options) {
|
|
|
21
21
|
}),
|
|
22
22
|
}));
|
|
23
23
|
const endpoints = grouped.get(tag);
|
|
24
|
-
const ep = assertNotCancelled(await
|
|
24
|
+
const ep = assertNotCancelled(await ui.select({
|
|
25
25
|
message: 'Select an endpoint:',
|
|
26
26
|
options: endpoints.map((e) => ({
|
|
27
27
|
value: e,
|
|
@@ -31,7 +31,7 @@ export async function apiInteractive(options) {
|
|
|
31
31
|
}));
|
|
32
32
|
let resolvedPath = ep.path;
|
|
33
33
|
for (const param of ep.pathParams) {
|
|
34
|
-
const value = assertNotCancelled(await
|
|
34
|
+
const value = assertNotCancelled(await ui.text({
|
|
35
35
|
message: `${param.name}:`,
|
|
36
36
|
placeholder: param.description || undefined,
|
|
37
37
|
validate: (v) => {
|
|
@@ -47,7 +47,7 @@ export async function apiInteractive(options) {
|
|
|
47
47
|
const optionalParams = ep.queryParams.filter((qp) => !qp.required);
|
|
48
48
|
const params = [];
|
|
49
49
|
for (const qp of requiredParams) {
|
|
50
|
-
const value = assertNotCancelled(await
|
|
50
|
+
const value = assertNotCancelled(await ui.text({
|
|
51
51
|
message: `${qp.name} (required):`,
|
|
52
52
|
placeholder: qp.description || undefined,
|
|
53
53
|
validate: (v) => {
|
|
@@ -58,13 +58,13 @@ export async function apiInteractive(options) {
|
|
|
58
58
|
params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(value.trim())}`);
|
|
59
59
|
}
|
|
60
60
|
if (optionalParams.length > 0) {
|
|
61
|
-
const wantsOptional = assertNotCancelled(await
|
|
61
|
+
const wantsOptional = assertNotCancelled(await ui.confirm({
|
|
62
62
|
message: `Add optional query parameters? (${optionalParams.length} available)`,
|
|
63
63
|
initialValue: false,
|
|
64
64
|
}));
|
|
65
65
|
if (wantsOptional) {
|
|
66
66
|
for (const qp of optionalParams) {
|
|
67
|
-
const value = assertNotCancelled(await
|
|
67
|
+
const value = assertNotCancelled(await ui.text({
|
|
68
68
|
message: `${qp.name}:`,
|
|
69
69
|
placeholder: qp.description || undefined,
|
|
70
70
|
}));
|
|
@@ -83,13 +83,13 @@ export async function apiInteractive(options) {
|
|
|
83
83
|
if (ep.hasRequestBody) {
|
|
84
84
|
let collectBody = ep.requestBodyRequired;
|
|
85
85
|
if (!collectBody) {
|
|
86
|
-
collectBody = assertNotCancelled(await
|
|
86
|
+
collectBody = assertNotCancelled(await ui.confirm({
|
|
87
87
|
message: 'Provide a request body?',
|
|
88
88
|
initialValue: ep.method === 'POST' || ep.method === 'PUT',
|
|
89
89
|
}));
|
|
90
90
|
}
|
|
91
91
|
if (collectBody) {
|
|
92
|
-
body = assertNotCancelled(await
|
|
92
|
+
body = assertNotCancelled(await ui.text({
|
|
93
93
|
message: 'Request body (JSON):',
|
|
94
94
|
placeholder: '{"key": "value"}',
|
|
95
95
|
validate: (v) => {
|
|
@@ -111,7 +111,7 @@ export async function apiInteractive(options) {
|
|
|
111
111
|
console.log(JSON.stringify(JSON.parse(body), null, 2));
|
|
112
112
|
}
|
|
113
113
|
console.log();
|
|
114
|
-
const ok = assertNotCancelled(await
|
|
114
|
+
const ok = assertNotCancelled(await ui.confirm({ message: 'Execute this request?' }));
|
|
115
115
|
if (!ok)
|
|
116
116
|
exitWithCode(ExitCode.CANCELLED);
|
|
117
117
|
const response = await apiRequest({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../../src/commands/api/interactive.ts"],"names":[],"mappings":"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","sourcesContent":["import clack from '../../utils/clack.js';\nimport { loadCatalog, endpointsByTag, type EndpointInfo } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { colorMethod, printResponse } from './format.js';\nimport { resolveApiKey, resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { exitWithError } from '../../utils/output.js';\n\nfunction assertNotCancelled<T>(value: T | symbol): T {\n if (clack.isCancel(value)) exitWithCode(ExitCode.CANCELLED);\n return value as T;\n}\n\nexport async function apiInteractive(options?: { apiKey?: string }): Promise<void> {\n const catalog = await loadCatalog();\n const grouped = endpointsByTag(catalog.endpoints);\n\n const tag = assertNotCancelled(\n await clack.select({\n message: 'Select a category:',\n options: catalog.tags.map((t) => {\n const count = grouped.get(t)?.length ?? 0;\n return { value: t, label: `${t} (${count})` };\n }),\n }),\n );\n\n const endpoints = grouped.get(tag)!;\n const ep = assertNotCancelled(\n await clack.select<EndpointInfo>({\n message: 'Select an endpoint:',\n options: endpoints.map((e) => ({\n value: e,\n label: `${colorMethod(e.method).padEnd(18)} ${e.path}`,\n hint: e.summary,\n })),\n }),\n );\n\n let resolvedPath = ep.path;\n for (const param of ep.pathParams) {\n const value = assertNotCancelled(\n await clack.text({\n message: `${param.name}:`,\n placeholder: param.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${param.name} is required`;\n },\n }),\n );\n resolvedPath = resolvedPath.replaceAll(`{${param.name}}`, encodeURIComponent(value.trim()));\n }\n\n let queryString = '';\n if (ep.queryParams.length > 0) {\n const requiredParams = ep.queryParams.filter((qp) => qp.required);\n const optionalParams = ep.queryParams.filter((qp) => !qp.required);\n const params: string[] = [];\n\n for (const qp of requiredParams) {\n const value = assertNotCancelled(\n await clack.text({\n message: `${qp.name} (required):`,\n placeholder: qp.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${qp.name} is required`;\n },\n }),\n );\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(value.trim())}`);\n }\n\n if (optionalParams.length > 0) {\n const wantsOptional = assertNotCancelled(\n await clack.confirm({\n message: `Add optional query parameters? (${optionalParams.length} available)`,\n initialValue: false,\n }),\n );\n\n if (wantsOptional) {\n for (const qp of optionalParams) {\n const value = assertNotCancelled(\n await clack.text({\n message: `${qp.name}:`,\n placeholder: qp.description || undefined,\n }),\n );\n const trimmed = value.trim();\n if (trimmed) {\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(trimmed)}`);\n }\n }\n }\n }\n\n if (params.length > 0) {\n queryString = `?${params.join('&')}`;\n }\n }\n\n let body: string | undefined;\n if (ep.hasRequestBody) {\n let collectBody = ep.requestBodyRequired;\n if (!collectBody) {\n collectBody = assertNotCancelled(\n await clack.confirm({\n message: 'Provide a request body?',\n initialValue: ep.method === 'POST' || ep.method === 'PUT',\n }),\n );\n }\n\n if (collectBody) {\n body = assertNotCancelled(\n await clack.text({\n message: 'Request body (JSON):',\n placeholder: '{\"key\": \"value\"}',\n validate: (v) => {\n if (!v?.trim()) return 'Body cannot be empty';\n try {\n JSON.parse(v);\n } catch {\n return 'Invalid JSON';\n }\n },\n }),\n ).trim();\n }\n }\n\n const fullPath = `${resolvedPath}${queryString}`;\n\n console.log(`\\n ${colorMethod(ep.method)} ${fullPath}`);\n if (body) {\n console.log(JSON.stringify(JSON.parse(body), null, 2));\n }\n console.log();\n\n const ok = assertNotCancelled(await clack.confirm({ message: 'Execute this request?' }));\n if (!ok) exitWithCode(ExitCode.CANCELLED);\n\n const response = await apiRequest({\n method: ep.method,\n path: fullPath,\n apiKey: options?.apiKey ?? resolveApiKey(),\n baseUrl: resolveApiBaseUrl(),\n body,\n });\n\n printResponse(response, { includeStatus: true });\n\n if (response.status >= 400) {\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../../src/commands/api/interactive.ts"],"names":[],"mappings":"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","sourcesContent":["import ui from '../../utils/ui.js';\nimport { loadCatalog, endpointsByTag, type EndpointInfo } from './catalog.js';\nimport { apiRequest } from './request.js';\nimport { colorMethod, printResponse } from './format.js';\nimport { resolveApiKey, resolveApiBaseUrl } from '../../lib/api-key.js';\nimport { ExitCode, exitWithCode } from '../../utils/exit-codes.js';\nimport { exitWithError } from '../../utils/output.js';\n\nfunction assertNotCancelled<T>(value: T | symbol): T {\n if (ui.isCancel(value)) exitWithCode(ExitCode.CANCELLED);\n return value as T;\n}\n\nexport async function apiInteractive(options?: { apiKey?: string }): Promise<void> {\n const catalog = await loadCatalog();\n const grouped = endpointsByTag(catalog.endpoints);\n\n const tag = assertNotCancelled(\n await ui.select({\n message: 'Select a category:',\n options: catalog.tags.map((t) => {\n const count = grouped.get(t)?.length ?? 0;\n return { value: t, label: `${t} (${count})` };\n }),\n }),\n );\n\n const endpoints = grouped.get(tag)!;\n const ep = assertNotCancelled(\n await ui.select<EndpointInfo>({\n message: 'Select an endpoint:',\n options: endpoints.map((e) => ({\n value: e,\n label: `${colorMethod(e.method).padEnd(18)} ${e.path}`,\n hint: e.summary,\n })),\n }),\n );\n\n let resolvedPath = ep.path;\n for (const param of ep.pathParams) {\n const value = assertNotCancelled(\n await ui.text({\n message: `${param.name}:`,\n placeholder: param.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${param.name} is required`;\n },\n }),\n );\n resolvedPath = resolvedPath.replaceAll(`{${param.name}}`, encodeURIComponent(value.trim()));\n }\n\n let queryString = '';\n if (ep.queryParams.length > 0) {\n const requiredParams = ep.queryParams.filter((qp) => qp.required);\n const optionalParams = ep.queryParams.filter((qp) => !qp.required);\n const params: string[] = [];\n\n for (const qp of requiredParams) {\n const value = assertNotCancelled(\n await ui.text({\n message: `${qp.name} (required):`,\n placeholder: qp.description || undefined,\n validate: (v) => {\n if (!v?.trim()) return `${qp.name} is required`;\n },\n }),\n );\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(value.trim())}`);\n }\n\n if (optionalParams.length > 0) {\n const wantsOptional = assertNotCancelled(\n await ui.confirm({\n message: `Add optional query parameters? (${optionalParams.length} available)`,\n initialValue: false,\n }),\n );\n\n if (wantsOptional) {\n for (const qp of optionalParams) {\n const value = assertNotCancelled(\n await ui.text({\n message: `${qp.name}:`,\n placeholder: qp.description || undefined,\n }),\n );\n const trimmed = value.trim();\n if (trimmed) {\n params.push(`${encodeURIComponent(qp.name)}=${encodeURIComponent(trimmed)}`);\n }\n }\n }\n }\n\n if (params.length > 0) {\n queryString = `?${params.join('&')}`;\n }\n }\n\n let body: string | undefined;\n if (ep.hasRequestBody) {\n let collectBody = ep.requestBodyRequired;\n if (!collectBody) {\n collectBody = assertNotCancelled(\n await ui.confirm({\n message: 'Provide a request body?',\n initialValue: ep.method === 'POST' || ep.method === 'PUT',\n }),\n );\n }\n\n if (collectBody) {\n body = assertNotCancelled(\n await ui.text({\n message: 'Request body (JSON):',\n placeholder: '{\"key\": \"value\"}',\n validate: (v) => {\n if (!v?.trim()) return 'Body cannot be empty';\n try {\n JSON.parse(v);\n } catch {\n return 'Invalid JSON';\n }\n },\n }),\n ).trim();\n }\n }\n\n const fullPath = `${resolvedPath}${queryString}`;\n\n console.log(`\\n ${colorMethod(ep.method)} ${fullPath}`);\n if (body) {\n console.log(JSON.stringify(JSON.parse(body), null, 2));\n }\n console.log();\n\n const ok = assertNotCancelled(await ui.confirm({ message: 'Execute this request?' }));\n if (!ok) exitWithCode(ExitCode.CANCELLED);\n\n const response = await apiRequest({\n method: ep.method,\n path: fullPath,\n apiKey: options?.apiKey ?? resolveApiKey(),\n baseUrl: resolveApiBaseUrl(),\n body,\n });\n\n printResponse(response, { includeStatus: true });\n\n if (response.status >= 400) {\n exitWithError({\n code: `http_${response.status}`,\n message: `API request failed with status ${response.status}`,\n apiContext: { status: response.status },\n });\n }\n}\n"]}
|
package/dist/commands/claim.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* until the environment is claimed.
|
|
7
7
|
*/
|
|
8
8
|
import open from 'open';
|
|
9
|
-
import
|
|
9
|
+
import ui from '../utils/ui.js';
|
|
10
10
|
import { getActiveEnvironment, isUnclaimedEnvironment, markEnvironmentClaimed } from '../lib/config-store.js';
|
|
11
11
|
import { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api.js';
|
|
12
12
|
import { observeHostFailure } from '../lib/host-probe.js';
|
|
@@ -15,6 +15,7 @@ import { isJsonMode, outputJson, exitWithError } from '../utils/output.js';
|
|
|
15
15
|
import { isAgentMode, isCiMode } from '../utils/interaction-mode.js';
|
|
16
16
|
import { sleep } from '../lib/helper-functions.js';
|
|
17
17
|
import { formatWorkOSCommand } from '../utils/command-invocation.js';
|
|
18
|
+
import { networkRetryRecovery } from '../utils/recovery-hints.js';
|
|
18
19
|
const POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
19
20
|
const POLL_INTERVAL_MS = 5_000; // 5 seconds
|
|
20
21
|
const MAX_CONSECUTIVE_FAILURES = 10;
|
|
@@ -28,14 +29,14 @@ export async function runClaim() {
|
|
|
28
29
|
outputJson({ status: 'no_unclaimed_environment', message: 'No unclaimed environment found. Nothing to claim.' });
|
|
29
30
|
}
|
|
30
31
|
else {
|
|
31
|
-
|
|
32
|
+
ui.log.info('No unclaimed environment found. Nothing to claim.');
|
|
32
33
|
}
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
// claimToken and clientId guaranteed present by UnclaimedEnvironmentConfig
|
|
36
37
|
logInfo('[claim] Starting claim flow for environment:', activeEnv.name);
|
|
37
38
|
try {
|
|
38
|
-
|
|
39
|
+
ui.log.step('Generating claim link...');
|
|
39
40
|
const result = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);
|
|
40
41
|
if (result.alreadyClaimed) {
|
|
41
42
|
markEnvironmentClaimed();
|
|
@@ -43,14 +44,20 @@ export async function runClaim() {
|
|
|
43
44
|
outputJson({ status: 'already_claimed', message: 'Environment already claimed!' });
|
|
44
45
|
}
|
|
45
46
|
else {
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
ui.log.success('Environment already claimed!');
|
|
48
|
+
ui.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
|
|
48
49
|
}
|
|
49
50
|
return;
|
|
50
51
|
}
|
|
51
52
|
const claimUrl = `https://dashboard.workos.com/claim?nonce=${result.nonce}`;
|
|
52
53
|
if (isJsonMode()) {
|
|
53
|
-
outputJson({
|
|
54
|
+
outputJson({
|
|
55
|
+
status: 'claim_url',
|
|
56
|
+
claimUrl,
|
|
57
|
+
nonce: result.nonce,
|
|
58
|
+
permanent: true,
|
|
59
|
+
note: 'Claiming permanently links this environment to your account and cannot be undone.',
|
|
60
|
+
});
|
|
54
61
|
return;
|
|
55
62
|
}
|
|
56
63
|
if (isCiMode()) {
|
|
@@ -60,14 +67,15 @@ export async function runClaim() {
|
|
|
60
67
|
details: { claimUrl, nonce: result.nonce },
|
|
61
68
|
});
|
|
62
69
|
}
|
|
63
|
-
|
|
70
|
+
ui.log.warn('Claiming permanently links this environment to your account and cannot be undone.');
|
|
71
|
+
ui.log.info(`Open this URL to claim your environment:\n\n ${claimUrl}`);
|
|
64
72
|
try {
|
|
65
73
|
await open(claimUrl, { wait: false });
|
|
66
74
|
if (isAgentMode()) {
|
|
67
|
-
|
|
75
|
+
ui.log.info('Browser launch attempted. If it did not open on the host, use the URL above.');
|
|
68
76
|
}
|
|
69
77
|
else {
|
|
70
|
-
|
|
78
|
+
ui.log.info('Browser opened automatically');
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
catch (openError) {
|
|
@@ -77,10 +85,10 @@ export async function runClaim() {
|
|
|
77
85
|
label: 'environment claim browser',
|
|
78
86
|
});
|
|
79
87
|
logError('[claim] Failed to open browser:', openError instanceof Error ? openError.message : String(openError));
|
|
80
|
-
|
|
88
|
+
ui.log.info('Could not open browser — open the URL above manually.');
|
|
81
89
|
}
|
|
82
90
|
// Poll for claim completion
|
|
83
|
-
const spinner =
|
|
91
|
+
const spinner = ui.spinner();
|
|
84
92
|
spinner.start('Waiting for claim...');
|
|
85
93
|
const startTime = Date.now();
|
|
86
94
|
let consecutiveFailures = 0;
|
|
@@ -91,7 +99,7 @@ export async function runClaim() {
|
|
|
91
99
|
if (check.alreadyClaimed) {
|
|
92
100
|
spinner.stop('Environment claimed!');
|
|
93
101
|
markEnvironmentClaimed();
|
|
94
|
-
|
|
102
|
+
ui.log.info(`Run \`${formatWorkOSCommand('auth login')}\` to connect your account.`);
|
|
95
103
|
return;
|
|
96
104
|
}
|
|
97
105
|
consecutiveFailures = 0;
|
|
@@ -103,14 +111,14 @@ export async function runClaim() {
|
|
|
103
111
|
// when the environment is claimed. Safe to promote to sandbox.
|
|
104
112
|
spinner.stop('Claim token is invalid or expired.');
|
|
105
113
|
markEnvironmentClaimed();
|
|
106
|
-
|
|
114
|
+
ui.log.warn(`Run \`${formatWorkOSCommand('auth login')}\` to set up your environment.`);
|
|
107
115
|
return;
|
|
108
116
|
}
|
|
109
117
|
consecutiveFailures++;
|
|
110
118
|
logError('[claim] Poll error:', pollError instanceof Error ? pollError.message : 'Unknown');
|
|
111
119
|
if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
|
|
112
120
|
spinner.stop('Too many connection failures');
|
|
113
|
-
|
|
121
|
+
ui.log.error(`Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\n` +
|
|
114
122
|
`You can also complete the claim at: ${claimUrl}`);
|
|
115
123
|
return;
|
|
116
124
|
}
|
|
@@ -120,12 +128,16 @@ export async function runClaim() {
|
|
|
120
128
|
}
|
|
121
129
|
}
|
|
122
130
|
spinner.stop('Claim timed out');
|
|
123
|
-
|
|
131
|
+
ui.log.info(`Complete the claim in your browser, then run \`${formatWorkOSCommand('env list')}\` to verify.`);
|
|
124
132
|
}
|
|
125
133
|
catch (error) {
|
|
126
134
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
127
135
|
logError('[claim] Error:', message);
|
|
128
|
-
exitWithError({
|
|
136
|
+
exitWithError({
|
|
137
|
+
code: 'claim_failed',
|
|
138
|
+
message: `Could not claim this environment: ${message}`,
|
|
139
|
+
recovery: networkRetryRecovery({ command: formatWorkOSCommand('env claim') }),
|
|
140
|
+
});
|
|
129
141
|
}
|
|
130
142
|
}
|
|
131
143
|
//# sourceMappingURL=claim.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claim.js","sourceRoot":"","sources":["../../src/commands/claim.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `workos env claim` — claim an unclaimed environment.\n *\n * Reads claim token from active environment, generates a nonce via\n * createClaimNonce(), opens browser to dashboard claim URL, and polls\n * until the environment is claimed.\n */\n\nimport open from 'open';\nimport clack from '../utils/clack.js';\nimport { getActiveEnvironment, isUnclaimedEnvironment, markEnvironmentClaimed } from '../lib/config-store.js';\nimport { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api.js';\nimport { observeHostFailure } from '../lib/host-probe.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { isJsonMode, outputJson, exitWithError } from '../utils/output.js';\nimport { isAgentMode, isCiMode } from '../utils/interaction-mode.js';\nimport { sleep } from '../lib/helper-functions.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\n\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nconst POLL_INTERVAL_MS = 5_000; // 5 seconds\nconst MAX_CONSECUTIVE_FAILURES = 10;\n\n/**\n * Run the claim flow.\n */\nexport async function runClaim(): Promise<void> {\n const activeEnv = getActiveEnvironment();\n\n if (!activeEnv || !isUnclaimedEnvironment(activeEnv)) {\n if (isJsonMode()) {\n outputJson({ status: 'no_unclaimed_environment', message: 'No unclaimed environment found. Nothing to claim.' });\n } else {\n clack.log.info('No unclaimed environment found. Nothing to claim.');\n }\n return;\n }\n\n // claimToken and clientId guaranteed present by UnclaimedEnvironmentConfig\n\n logInfo('[claim] Starting claim flow for environment:', activeEnv.name);\n\n try {\n clack.log.step('Generating claim link...');\n\n const result = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n\n if (result.alreadyClaimed) {\n markEnvironmentClaimed();\n if (isJsonMode()) {\n outputJson({ status: 'already_claimed', message: 'Environment already claimed!' });\n } else {\n clack.log.success('Environment already claimed!');\n clack.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n }\n return;\n }\n\n const claimUrl = `https://dashboard.workos.com/claim?nonce=${result.nonce}`;\n\n if (isJsonMode()) {\n outputJson({ status: 'claim_url', claimUrl, nonce: result.nonce });\n return;\n }\n\n if (isCiMode()) {\n exitWithError({\n code: 'unsupported_in_ci',\n message: 'Environment claim requires opening the claim URL outside CI.',\n details: { claimUrl, nonce: result.nonce },\n });\n }\n\n clack.log.info(`Open this URL to claim your environment:\\n\\n ${claimUrl}`);\n\n try {\n await open(claimUrl, { wait: false });\n if (isAgentMode()) {\n clack.log.info('Browser launch attempted. If it did not open on the host, use the URL above.');\n } else {\n clack.log.info('Browser opened automatically');\n }\n } catch (openError) {\n observeHostFailure('browser-launch', openError, {\n operation: 'open',\n target: claimUrl,\n label: 'environment claim browser',\n });\n logError('[claim] Failed to open browser:', openError instanceof Error ? openError.message : String(openError));\n clack.log.info('Could not open browser — open the URL above manually.');\n }\n\n // Poll for claim completion\n const spinner = clack.spinner();\n spinner.start('Waiting for claim...');\n\n const startTime = Date.now();\n let consecutiveFailures = 0;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n await sleep(POLL_INTERVAL_MS);\n try {\n const check = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n if (check.alreadyClaimed) {\n spinner.stop('Environment claimed!');\n markEnvironmentClaimed();\n clack.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n return;\n }\n consecutiveFailures = 0;\n } catch (pollError) {\n const statusCode = pollError instanceof UnclaimedEnvApiError ? pollError.statusCode : undefined;\n if (statusCode === 401) {\n // 401 means the server invalidated the claim token — this happens\n // when the environment is claimed. Safe to promote to sandbox.\n spinner.stop('Claim token is invalid or expired.');\n markEnvironmentClaimed();\n clack.log.warn(`Run \\`${formatWorkOSCommand('auth login')}\\` to set up your environment.`);\n return;\n }\n consecutiveFailures++;\n logError('[claim] Poll error:', pollError instanceof Error ? pollError.message : 'Unknown');\n if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {\n spinner.stop('Too many connection failures');\n clack.log.error(\n `Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\\n` +\n `You can also complete the claim at: ${claimUrl}`,\n );\n return;\n }\n if (consecutiveFailures >= 3) {\n spinner.message('Still waiting... (connection issues detected)');\n }\n }\n }\n\n spinner.stop('Claim timed out');\n clack.log.info('Complete the claim in your browser, then run `workos env list` to verify.');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logError('[claim] Error:', message);\n exitWithError({ code: 'claim_failed', message: `Claim failed: ${message}` });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"claim.js","sourceRoot":"","sources":["../../src/commands/claim.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC9G,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AACnD,MAAM,gBAAgB,GAAG,KAAK,CAAC,CAAC,YAAY;AAC5C,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,SAAS,GAAG,oBAAoB,EAAE,CAAC;IAEzC,IAAI,CAAC,SAAS,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;QACrD,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,UAAU,CAAC,EAAE,MAAM,EAAE,0BAA0B,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC,CAAC;QACnH,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;QACnE,CAAC;QACD,OAAO;IACT,CAAC;IAED,2EAA2E;IAE3E,OAAO,CAAC,8CAA8C,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAExE,IAAI,CAAC;QACH,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QAEhF,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YAC1B,sBAAsB,EAAE,CAAC;YACzB,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,UAAU,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;gBAC/C,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,mBAAmB,CAAC,YAAY,CAAC,6BAA6B,CAAC,CAAC;YACvF,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,4CAA4C,MAAM,CAAC,KAAK,EAAE,CAAC;QAE5E,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,UAAU,CAAC;gBACT,MAAM,EAAE,WAAW;gBACnB,QAAQ;gBACR,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,SAAS,EAAE,IAAI;gBACf,IAAI,EAAE,mFAAmF;aAC1F,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,EAAE,EAAE,CAAC;YACf,aAAa,CAAC;gBACZ,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,8DAA8D;gBACvE,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE;aAC3C,CAAC,CAAC;QACL,CAAC;QAED,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,mFAAmF,CAAC,CAAC;QACjG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,iDAAiD,QAAQ,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACtC,IAAI,WAAW,EAAE,EAAE,CAAC;gBAClB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;YAC9F,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAAC,OAAO,SAAS,EAAE,CAAC;YACnB,kBAAkB,CAAC,gBAAgB,EAAE,SAAS,EAAE;gBAC9C,SAAS,EAAE,MAAM;gBACjB,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,2BAA2B;aACnC,CAAC,CAAC;YACH,QAAQ,CAAC,iCAAiC,EAAE,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;YAChH,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QACvE,CAAC;QAED,4BAA4B;QAC5B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,mBAAmB,GAAG,CAAC,CAAC;QAE5B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;YAChD,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC9B,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;gBAC/E,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;oBACzB,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;oBACrC,sBAAsB,EAAE,CAAC;oBACzB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,mBAAmB,CAAC,YAAY,CAAC,6BAA6B,CAAC,CAAC;oBACrF,OAAO;gBACT,CAAC;gBACD,mBAAmB,GAAG,CAAC,CAAC;YAC1B,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,MAAM,UAAU,GAAG,SAAS,YAAY,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;gBAChG,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;oBACvB,kEAAkE;oBAClE,+DAA+D;oBAC/D,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;oBACnD,sBAAsB,EAAE,CAAC;oBACzB,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,mBAAmB,CAAC,YAAY,CAAC,gCAAgC,CAAC,CAAC;oBACxF,OAAO;gBACT,CAAC;gBACD,mBAAmB,EAAE,CAAC;gBACtB,QAAQ,CAAC,qBAAqB,EAAE,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBAC5F,IAAI,mBAAmB,IAAI,wBAAwB,EAAE,CAAC;oBACpD,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;oBAC7C,EAAE,CAAC,GAAG,CAAC,KAAK,CACV,kBAAkB,mBAAmB,sDAAsD;wBACzF,uCAAuC,QAAQ,EAAE,CACpD,CAAC;oBACF,OAAO;gBACT,CAAC;gBACD,IAAI,mBAAmB,IAAI,CAAC,EAAE,CAAC;oBAC7B,OAAO,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,kDAAkD,mBAAmB,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IAChH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACpC,aAAa,CAAC;YACZ,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,qCAAqC,OAAO,EAAE;YACvD,QAAQ,EAAE,oBAAoB,CAAC,EAAE,OAAO,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC;SAC9E,CAAC,CAAC;IACL,CAAC;AACH,CAAC","sourcesContent":["/**\n * `workos env claim` — claim an unclaimed environment.\n *\n * Reads claim token from active environment, generates a nonce via\n * createClaimNonce(), opens browser to dashboard claim URL, and polls\n * until the environment is claimed.\n */\n\nimport open from 'open';\nimport ui from '../utils/ui.js';\nimport { getActiveEnvironment, isUnclaimedEnvironment, markEnvironmentClaimed } from '../lib/config-store.js';\nimport { createClaimNonce, UnclaimedEnvApiError } from '../lib/unclaimed-env-api.js';\nimport { observeHostFailure } from '../lib/host-probe.js';\nimport { logInfo, logError } from '../utils/debug.js';\nimport { isJsonMode, outputJson, exitWithError } from '../utils/output.js';\nimport { isAgentMode, isCiMode } from '../utils/interaction-mode.js';\nimport { sleep } from '../lib/helper-functions.js';\nimport { formatWorkOSCommand } from '../utils/command-invocation.js';\nimport { networkRetryRecovery } from '../utils/recovery-hints.js';\n\nconst POLL_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nconst POLL_INTERVAL_MS = 5_000; // 5 seconds\nconst MAX_CONSECUTIVE_FAILURES = 10;\n\n/**\n * Run the claim flow.\n */\nexport async function runClaim(): Promise<void> {\n const activeEnv = getActiveEnvironment();\n\n if (!activeEnv || !isUnclaimedEnvironment(activeEnv)) {\n if (isJsonMode()) {\n outputJson({ status: 'no_unclaimed_environment', message: 'No unclaimed environment found. Nothing to claim.' });\n } else {\n ui.log.info('No unclaimed environment found. Nothing to claim.');\n }\n return;\n }\n\n // claimToken and clientId guaranteed present by UnclaimedEnvironmentConfig\n\n logInfo('[claim] Starting claim flow for environment:', activeEnv.name);\n\n try {\n ui.log.step('Generating claim link...');\n\n const result = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n\n if (result.alreadyClaimed) {\n markEnvironmentClaimed();\n if (isJsonMode()) {\n outputJson({ status: 'already_claimed', message: 'Environment already claimed!' });\n } else {\n ui.log.success('Environment already claimed!');\n ui.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n }\n return;\n }\n\n const claimUrl = `https://dashboard.workos.com/claim?nonce=${result.nonce}`;\n\n if (isJsonMode()) {\n outputJson({\n status: 'claim_url',\n claimUrl,\n nonce: result.nonce,\n permanent: true,\n note: 'Claiming permanently links this environment to your account and cannot be undone.',\n });\n return;\n }\n\n if (isCiMode()) {\n exitWithError({\n code: 'unsupported_in_ci',\n message: 'Environment claim requires opening the claim URL outside CI.',\n details: { claimUrl, nonce: result.nonce },\n });\n }\n\n ui.log.warn('Claiming permanently links this environment to your account and cannot be undone.');\n ui.log.info(`Open this URL to claim your environment:\\n\\n ${claimUrl}`);\n\n try {\n await open(claimUrl, { wait: false });\n if (isAgentMode()) {\n ui.log.info('Browser launch attempted. If it did not open on the host, use the URL above.');\n } else {\n ui.log.info('Browser opened automatically');\n }\n } catch (openError) {\n observeHostFailure('browser-launch', openError, {\n operation: 'open',\n target: claimUrl,\n label: 'environment claim browser',\n });\n logError('[claim] Failed to open browser:', openError instanceof Error ? openError.message : String(openError));\n ui.log.info('Could not open browser — open the URL above manually.');\n }\n\n // Poll for claim completion\n const spinner = ui.spinner();\n spinner.start('Waiting for claim...');\n\n const startTime = Date.now();\n let consecutiveFailures = 0;\n\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n await sleep(POLL_INTERVAL_MS);\n try {\n const check = await createClaimNonce(activeEnv.clientId, activeEnv.claimToken);\n if (check.alreadyClaimed) {\n spinner.stop('Environment claimed!');\n markEnvironmentClaimed();\n ui.log.info(`Run \\`${formatWorkOSCommand('auth login')}\\` to connect your account.`);\n return;\n }\n consecutiveFailures = 0;\n } catch (pollError) {\n const statusCode = pollError instanceof UnclaimedEnvApiError ? pollError.statusCode : undefined;\n if (statusCode === 401) {\n // 401 means the server invalidated the claim token — this happens\n // when the environment is claimed. Safe to promote to sandbox.\n spinner.stop('Claim token is invalid or expired.');\n markEnvironmentClaimed();\n ui.log.warn(`Run \\`${formatWorkOSCommand('auth login')}\\` to set up your environment.`);\n return;\n }\n consecutiveFailures++;\n logError('[claim] Poll error:', pollError instanceof Error ? pollError.message : 'Unknown');\n if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {\n spinner.stop('Too many connection failures');\n ui.log.error(\n `Polling failed ${consecutiveFailures} times in a row. Check your network and try again.\\n` +\n `You can also complete the claim at: ${claimUrl}`,\n );\n return;\n }\n if (consecutiveFailures >= 3) {\n spinner.message('Still waiting... (connection issues detected)');\n }\n }\n }\n\n spinner.stop('Claim timed out');\n ui.log.info(`Complete the claim in your browser, then run \\`${formatWorkOSCommand('env list')}\\` to verify.`);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n logError('[claim] Error:', message);\n exitWithError({\n code: 'claim_failed',\n message: `Could not claim this environment: ${message}`,\n recovery: networkRetryRecovery({ command: formatWorkOSCommand('env claim') }),\n });\n }\n}\n"]}
|
|
@@ -4,7 +4,7 @@ import { formatTable } from '../utils/table.js';
|
|
|
4
4
|
import { outputSuccess, outputJson, isJsonMode, exitWithError } from '../utils/output.js';
|
|
5
5
|
import { createApiErrorHandler } from '../lib/api-error-handler.js';
|
|
6
6
|
import { isCiMode, isPromptAllowed } from '../utils/interaction-mode.js';
|
|
7
|
-
import
|
|
7
|
+
import ui from '../utils/ui.js';
|
|
8
8
|
const handleApiError = createApiErrorHandler('Connection');
|
|
9
9
|
export async function runConnectionList(options, apiKey, baseUrl) {
|
|
10
10
|
const client = createWorkOSClient(apiKey, baseUrl);
|
|
@@ -76,10 +76,10 @@ export async function runConnectionDelete(id, options, apiKey, baseUrl) {
|
|
|
76
76
|
: 'Destructive operation requires --force flag in agent mode.',
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
|
-
const confirmed = await
|
|
79
|
+
const confirmed = await ui.confirm({
|
|
80
80
|
message: `Delete connection ${id}? This cannot be undone.`,
|
|
81
81
|
});
|
|
82
|
-
if (
|
|
82
|
+
if (ui.isCancel(confirmed) || !confirmed) {
|
|
83
83
|
console.log('Delete cancelled.');
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/commands/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/commands/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,MAAM,cAAc,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;AAW3D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA8B,EAC9B,MAAc,EACd,OAAgB;IAEhB,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;YAClD,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;YACzE,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,cAAgC,EAAE,CAAC;YAC3F,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAmC;SACnD,CAAC,CAAC;QAEH,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,EAAE;YACP,IAAI,CAAC,IAAI;YACT,IAAI,CAAC,IAAI;YACT,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YACrC,IAAI,CAAC,KAAK;YACV,IAAI,CAAC,SAAS;SACf,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CACT,WAAW,CACT;YACE,EAAE,MAAM,EAAE,IAAI,EAAE;YAChB,EAAE,MAAM,EAAE,MAAM,EAAE;YAClB,EAAE,MAAM,EAAE,MAAM,EAAE;YAClB,EAAE,MAAM,EAAE,QAAQ,EAAE;YACpB,EAAE,MAAM,EAAE,OAAO,EAAE;YACnB,EAAE,MAAM,EAAE,SAAS,EAAE;SACtB,EACD,IAAI,CACL,CACF,CAAC;QAEF,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC;QAC9C,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,MAAM,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,IAAI,MAAM,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,KAAK,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAU,EAAE,MAAc,EAAE,OAAgB;IACjF,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAC1D,UAAU,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAU,EACV,OAA4B,EAC5B,MAAc,EACd,OAAgB;IAEhB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YACvB,aAAa,CAAC;gBACZ,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,QAAQ,EAAE;oBACjB,CAAC,CAAC,yDAAyD;oBAC3D,CAAC,CAAC,4DAA4D;aACjE,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YACjC,OAAO,EAAE,qBAAqB,EAAE,0BAA0B;SAC3D,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC1C,aAAa,CAAC,oBAAoB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;AACH,CAAC","sourcesContent":["import chalk from 'chalk';\nimport type { ConnectionType } from '@workos-inc/node';\nimport { createWorkOSClient } from '../lib/workos-client.js';\nimport { formatTable } from '../utils/table.js';\nimport { outputSuccess, outputJson, isJsonMode, exitWithError } from '../utils/output.js';\nimport { createApiErrorHandler } from '../lib/api-error-handler.js';\nimport { isCiMode, isPromptAllowed } from '../utils/interaction-mode.js';\nimport ui from '../utils/ui.js';\n\nconst handleApiError = createApiErrorHandler('Connection');\n\nexport interface ConnectionListOptions {\n organizationId?: string;\n connectionType?: string;\n limit?: number;\n before?: string;\n after?: string;\n order?: string;\n}\n\nexport async function runConnectionList(\n options: ConnectionListOptions,\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n const result = await client.sdk.sso.listConnections({\n ...(options.organizationId && { organizationId: options.organizationId }),\n ...(options.connectionType && { connectionType: options.connectionType as ConnectionType }),\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 connections found.');\n return;\n }\n\n const rows = result.data.map((conn) => [\n conn.id,\n conn.name,\n conn.type,\n conn.organizationId || chalk.dim('-'),\n conn.state,\n conn.createdAt,\n ]);\n\n console.log(\n formatTable(\n [\n { header: 'ID' },\n { header: 'Name' },\n { header: 'Type' },\n { header: 'Org ID' },\n { header: 'State' },\n { header: 'Created' },\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 runConnectionGet(id: string, apiKey: string, baseUrl?: string): Promise<void> {\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n const connection = await client.sdk.sso.getConnection(id);\n outputJson(connection);\n } catch (error) {\n handleApiError(error);\n }\n}\n\nexport async function runConnectionDelete(\n id: string,\n options: { force?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (!options.force) {\n if (!isPromptAllowed()) {\n exitWithError({\n code: 'confirmation_required',\n message: isCiMode()\n ? 'Destructive operation requires --force flag in CI mode.'\n : 'Destructive operation requires --force flag in agent mode.',\n });\n }\n\n const confirmed = await ui.confirm({\n message: `Delete connection ${id}? This cannot be undone.`,\n });\n\n if (ui.isCancel(confirmed) || !confirmed) {\n console.log('Delete cancelled.');\n return;\n }\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n try {\n await client.sdk.sso.deleteConnection(id);\n outputSuccess('Deleted connection', { id });\n } catch (error) {\n handleApiError(error);\n }\n}\n"]}
|
package/dist/commands/debug.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import
|
|
2
|
+
import ui from '../utils/ui.js';
|
|
3
3
|
import { getCredentials, saveCredentials, clearCredentials, isTokenExpired, diagnoseCredentials, getCredentialsPath, setInsecureStorage, } from '../lib/credentials.js';
|
|
4
4
|
import { getConfig, saveConfig, clearConfig, getConfigPath, setInsecureConfigStorage, diagnoseConfig, } from '../lib/config-store.js';
|
|
5
5
|
import { clearPreferences, getPreferencesPath, getTelemetrySource, isNoticeShown, isTelemetryEnabled, isTelemetryOptedOut, } from '../lib/preferences.js';
|
|
@@ -191,15 +191,15 @@ export async function runDebugReset({ force, credentialsOnly, configOnly, }) {
|
|
|
191
191
|
message: 'Use --force to reset in agent or CI mode',
|
|
192
192
|
});
|
|
193
193
|
}
|
|
194
|
-
const confirmed = await
|
|
194
|
+
const confirmed = await ui.confirm({
|
|
195
195
|
message: `Clear all ${targets}? This cannot be undone.`,
|
|
196
196
|
});
|
|
197
|
-
if (
|
|
197
|
+
if (ui.isCancel(confirmed) || !confirmed) {
|
|
198
198
|
if (isJsonMode()) {
|
|
199
199
|
outputJson({ cleared: false, cancelled: true });
|
|
200
200
|
}
|
|
201
201
|
else {
|
|
202
|
-
|
|
202
|
+
ui.log.info('Reset cancelled');
|
|
203
203
|
}
|
|
204
204
|
return;
|
|
205
205
|
}
|
|
@@ -214,7 +214,7 @@ export async function runDebugReset({ force, credentialsOnly, configOnly, }) {
|
|
|
214
214
|
outputJson({ cleared: true, credentials: clearCreds, config: clearConf, preferences: clearPrefs });
|
|
215
215
|
}
|
|
216
216
|
else {
|
|
217
|
-
|
|
217
|
+
ui.log.success(`Cleared ${targets}`);
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
220
|
// --- debug simulate ---
|
|
@@ -287,7 +287,7 @@ export async function runDebugSimulate({ expiredToken, noKeyring, unclaimed, noA
|
|
|
287
287
|
}
|
|
288
288
|
else {
|
|
289
289
|
for (const action of actions) {
|
|
290
|
-
|
|
290
|
+
ui.log.success(action);
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
}
|