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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type LockExpression } from './lock-art.js';
|
|
2
|
+
import type { CompletionData } from '../lib/events.js';
|
|
2
3
|
/** Pre-built completion summaries shared by CLI and Dashboard adapters. */
|
|
3
|
-
export declare function renderCompletionSummary(success: boolean, summary?: string): string;
|
|
4
|
+
export declare function renderCompletionSummary(success: boolean, summary?: string, completion?: CompletionData): string;
|
|
4
5
|
export interface SummaryBoxItem {
|
|
5
6
|
type: 'done' | 'pending' | 'error';
|
|
6
7
|
text: string;
|
|
@@ -11,6 +12,12 @@ export interface SummaryBoxOptions {
|
|
|
11
12
|
items?: SummaryBoxItem[];
|
|
12
13
|
footer?: string;
|
|
13
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* The install opener: the WorkOS lock (in brand indigo) beside the wordmark.
|
|
17
|
+
* A compact, de-boxed replacement for the full block-letter banner — the same
|
|
18
|
+
* lock that closes the install, so the two ends bookend each other.
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderBrandMark(subtitle?: string): string;
|
|
14
21
|
/**
|
|
15
22
|
* Render a branded summary box with the WorkOS lock character,
|
|
16
23
|
* a title, optional checklist items, and an optional footer.
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { isUnicodeSupported } from './vendor/is-unicorn-supported.js';
|
|
3
3
|
import { getLockArt, LOCK_WIDTH } from './lock-art.js';
|
|
4
|
-
import { symbols } from './cli-symbols.js';
|
|
4
|
+
import { symbols, palette } from './cli-symbols.js';
|
|
5
|
+
/** Max number of changed files listed in the success box before collapsing. */
|
|
6
|
+
const MAX_SUMMARY_FILES = 5;
|
|
5
7
|
/** Pre-built completion summaries shared by CLI and Dashboard adapters. */
|
|
6
|
-
export function renderCompletionSummary(success, summary) {
|
|
8
|
+
export function renderCompletionSummary(success, summary, completion) {
|
|
7
9
|
if (success) {
|
|
8
|
-
|
|
10
|
+
if (completion) {
|
|
11
|
+
const files = completion.files;
|
|
12
|
+
const shown = files.slice(0, MAX_SUMMARY_FILES).map((f) => ({ type: 'done', text: f }));
|
|
13
|
+
if (files.length > MAX_SUMMARY_FILES) {
|
|
14
|
+
shown.push({ type: 'done', text: `…and ${files.length - MAX_SUMMARY_FILES} more` });
|
|
15
|
+
}
|
|
16
|
+
const steps = completion.nextSteps.map((s) => ({ type: 'pending', text: s }));
|
|
17
|
+
return renderFlatSummary({
|
|
18
|
+
expression: 'success',
|
|
19
|
+
title: 'WorkOS AuthKit Installed',
|
|
20
|
+
items: [...shown, ...steps],
|
|
21
|
+
footer: completion.docsUrl,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// Fallback: preserve the original static next-steps when no structured data is present.
|
|
25
|
+
return renderFlatSummary({
|
|
9
26
|
expression: 'success',
|
|
10
27
|
title: 'WorkOS AuthKit Installed',
|
|
11
28
|
items: [
|
|
@@ -15,7 +32,7 @@ export function renderCompletionSummary(success, summary) {
|
|
|
15
32
|
footer: 'https://workos.com/docs/authkit',
|
|
16
33
|
});
|
|
17
34
|
}
|
|
18
|
-
return
|
|
35
|
+
return renderFlatSummary({
|
|
19
36
|
expression: 'error',
|
|
20
37
|
title: 'Installation Failed',
|
|
21
38
|
items: summary ? [{ type: 'error', text: summary }] : [],
|
|
@@ -31,6 +48,52 @@ const ITEM_ICONS = {
|
|
|
31
48
|
pending: chalk.cyan(symbols.arrow),
|
|
32
49
|
error: chalk.red(symbols.error),
|
|
33
50
|
};
|
|
51
|
+
// ── Flat (de-boxed) rendering — the install opener + closer ───────────────────
|
|
52
|
+
const { accent, cyan: flatCyan } = palette;
|
|
53
|
+
/** Flat glyphs matching the ui facade (green ✓ / accent › / red ✗). */
|
|
54
|
+
const FLAT_ICONS = {
|
|
55
|
+
done: chalk.green('✓'),
|
|
56
|
+
pending: accent('›'),
|
|
57
|
+
error: chalk.red('✗'),
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* The install opener: the WorkOS lock (in brand indigo) beside the wordmark.
|
|
61
|
+
* A compact, de-boxed replacement for the full block-letter banner — the same
|
|
62
|
+
* lock that closes the install, so the two ends bookend each other.
|
|
63
|
+
*/
|
|
64
|
+
export function renderBrandMark(subtitle) {
|
|
65
|
+
const lock = getLockArt('success', false); // raw lines; recolor to brand indigo
|
|
66
|
+
const titleLine = 2; // "WorkOS" sits beside the top of the lock body
|
|
67
|
+
const subtitleLine = 3;
|
|
68
|
+
return lock
|
|
69
|
+
.map((l, i) => {
|
|
70
|
+
const left = ` ${accent(l)}`;
|
|
71
|
+
if (i === titleLine)
|
|
72
|
+
return `${left} ${accent.bold('WorkOS')}`;
|
|
73
|
+
if (i === subtitleLine && subtitle)
|
|
74
|
+
return `${left} ${chalk.dim(subtitle)}`;
|
|
75
|
+
return left;
|
|
76
|
+
})
|
|
77
|
+
.join('\n');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The install closer: the WorkOS lock (colored by outcome) above a flat title,
|
|
81
|
+
* checklist, and footer — no border. Shared by the CLI and Dashboard adapters.
|
|
82
|
+
* The lock is the same mark that opens the install (see renderBrandMark).
|
|
83
|
+
*/
|
|
84
|
+
function renderFlatSummary(options) {
|
|
85
|
+
const { expression, title, items = [], footer } = options;
|
|
86
|
+
const out = getLockArt(expression, true).map((l) => ` ${l}`);
|
|
87
|
+
out.push('', ` ${chalk.bold(title)}`);
|
|
88
|
+
for (const item of items) {
|
|
89
|
+
// File paths (done) read better in cyan; next-step prose stays default weight.
|
|
90
|
+
const text = item.type === 'done' ? flatCyan(item.text) : item.text;
|
|
91
|
+
out.push(` ${FLAT_ICONS[item.type]} ${text}`);
|
|
92
|
+
}
|
|
93
|
+
if (footer)
|
|
94
|
+
out.push('', ` ${chalk.dim(footer)}`);
|
|
95
|
+
return out.join('\n');
|
|
96
|
+
}
|
|
34
97
|
const MIN_WIDTH = 42;
|
|
35
98
|
// Item prefix " X " = 4 visible chars before text
|
|
36
99
|
const ITEM_PREFIX_LEN = 4;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summary-box.js","sourceRoot":"","sources":["../../src/utils/summary-box.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { isUnicodeSupported } from './vendor/is-unicorn-supported.js';\nimport { type LockExpression, getLockArt, LOCK_WIDTH } from './lock-art.js';\nimport { symbols } from './cli-symbols.js';\n\n/** Pre-built completion summaries shared by CLI and Dashboard adapters. */\nexport function renderCompletionSummary(success: boolean, summary?: string): string {\n if (success) {\n return renderSummaryBox({\n expression: 'success',\n title: 'WorkOS AuthKit Installed',\n items: [\n { type: 'pending', text: 'Start dev server to test authentication' },\n { type: 'pending', text: 'Visit WorkOS Dashboard to manage users' },\n ],\n footer: 'https://workos.com/docs/authkit',\n });\n }\n return renderSummaryBox({\n expression: 'error',\n title: 'Installation Failed',\n items: summary ? [{ type: 'error', text: summary }] : [],\n footer: 'https://github.com/workos/cli/issues',\n });\n}\n\nexport interface SummaryBoxItem {\n type: 'done' | 'pending' | 'error';\n text: string;\n}\n\nexport interface SummaryBoxOptions {\n expression: LockExpression;\n title: string;\n items?: SummaryBoxItem[];\n footer?: string;\n}\n\nconst unicode = isUnicodeSupported();\n\nconst BOX = unicode\n ? { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│', ml: '├', mr: '┤' }\n : { tl: '+', tr: '+', bl: '+', br: '+', h: '-', v: '|', ml: '+', mr: '+' };\n\nconst ITEM_ICONS: Record<SummaryBoxItem['type'], string> = {\n done: chalk.green(symbols.success),\n pending: chalk.cyan(symbols.arrow),\n error: chalk.red(symbols.error),\n};\n\nconst MIN_WIDTH = 42;\n// Item prefix \" X \" = 4 visible chars before text\nconst ITEM_PREFIX_LEN = 4;\n// Footer prefix \" \" = 2 visible chars before text\nconst FOOTER_PREFIX_LEN = 2;\n\nfunction hLine(left: string, right: string, width: number): string {\n return `${left}${BOX.h.repeat(width - 2)}${right}`;\n}\n\nfunction padRight(text: string, visibleLen: number, targetLen: number): string {\n const padding = Math.max(0, targetLen - visibleLen);\n return text + ' '.repeat(padding);\n}\n\n/** Word-wrap text to fit within maxLen, returning multiple lines. */\nfunction wrapText(text: string, maxLen: number): string[] {\n if (text.length <= maxLen) return [text];\n const words = text.split(' ');\n const wrapped: string[] = [];\n let current = '';\n for (const word of words) {\n const candidate = current ? `${current} ${word}` : word;\n if (candidate.length > maxLen && current) {\n wrapped.push(current);\n current = word;\n } else {\n current = candidate;\n }\n }\n if (current) wrapped.push(current);\n return wrapped;\n}\n\nfunction getTerminalWidth(): number {\n return process.stdout.columns || 80;\n}\n\n/**\n * Render a branded summary box with the WorkOS lock character,\n * a title, optional checklist items, and an optional footer.\n */\nexport function renderSummaryBox(options: SummaryBoxOptions): string {\n const { expression, title, items = [], footer } = options;\n\n const lockColored = getLockArt(expression, true);\n const lockRaw = getLockArt(expression, false);\n const lockLines = lockColored.length;\n\n // \" \" + lock + \" \" = lock column width\n const lockColWidth = LOCK_WIDTH + 3;\n\n // Cap box width to terminal width\n const termWidth = getTerminalWidth();\n // innerWidth must fit: lock+title, items, footer — but capped to terminal\n const maxInner = Math.max(MIN_WIDTH - 2, termWidth - 2);\n\n // Compute ideal inner width from content\n const titleRowWidth = lockColWidth + title.length;\n const itemWidths = items.map((item) => ITEM_PREFIX_LEN + item.text.length);\n const footerWidth = footer ? FOOTER_PREFIX_LEN + footer.length : 0;\n const idealInner = Math.max(titleRowWidth, ...itemWidths, footerWidth) + 1;\n\n const innerWidth = Math.min(Math.max(MIN_WIDTH - 2, idealInner), maxInner);\n const boxWidth = innerWidth + 2;\n\n // Available text width for items and footer (after prefix, before right padding + border)\n const itemTextMax = innerWidth - ITEM_PREFIX_LEN - 1;\n const footerTextMax = innerWidth - FOOTER_PREFIX_LEN - 1;\n\n const lines: string[] = [];\n\n // Top border\n lines.push(hLine(BOX.tl, BOX.tr, boxWidth));\n\n // Lock + title rows\n const titleLineIndex = 3;\n for (let i = 0; i < lockLines; i++) {\n const lockPart = ` ${lockColored[i]} `;\n const lockPartRaw = ` ${lockRaw[i]} `;\n let rightPart: string;\n let rightPartLen: number;\n if (i === titleLineIndex) {\n rightPart = chalk.bold(title);\n rightPartLen = title.length;\n } else {\n rightPart = '';\n rightPartLen = 0;\n }\n const row = BOX.v + padRight(lockPart + rightPart, lockPartRaw.length + rightPartLen, innerWidth) + BOX.v;\n lines.push(row);\n }\n\n // Items\n if (items.length > 0) {\n lines.push(`${BOX.v}${' '.repeat(innerWidth)}${BOX.v}`);\n\n for (const item of items) {\n const icon = ITEM_ICONS[item.type];\n const wrappedLines = wrapText(item.text, itemTextMax);\n // First line gets the icon\n const first = ` ${icon} ${wrappedLines[0]}`;\n const firstLen = ITEM_PREFIX_LEN + wrappedLines[0].length;\n lines.push(`${BOX.v}${padRight(first, firstLen, innerWidth)}${BOX.v}`);\n // Continuation lines are indented to align with text after icon\n for (let j = 1; j < wrappedLines.length; j++) {\n const cont = ` ${wrappedLines[j]}`;\n const contLen = 4 + wrappedLines[j].length;\n lines.push(`${BOX.v}${padRight(cont, contLen, innerWidth)}${BOX.v}`);\n }\n }\n }\n\n // Footer\n if (footer) {\n lines.push(hLine(BOX.ml, BOX.mr, boxWidth));\n const wrappedFooter = wrapText(footer, footerTextMax);\n for (const fLine of wrappedFooter) {\n const content = ` ${chalk.dim(fLine)}`;\n const visibleLen = FOOTER_PREFIX_LEN + fLine.length;\n lines.push(`${BOX.v}${padRight(content, visibleLen, innerWidth)}${BOX.v}`);\n }\n }\n\n // Bottom border\n lines.push(hLine(BOX.bl, BOX.br, boxWidth));\n\n return lines.join('\\n');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"summary-box.js","sourceRoot":"","sources":["../../src/utils/summary-box.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { isUnicodeSupported } from './vendor/is-unicorn-supported.js';\nimport { type LockExpression, getLockArt, LOCK_WIDTH } from './lock-art.js';\nimport { symbols, palette } from './cli-symbols.js';\nimport type { CompletionData } from '../lib/events.js';\n\n/** Max number of changed files listed in the success box before collapsing. */\nconst MAX_SUMMARY_FILES = 5;\n\n/** Pre-built completion summaries shared by CLI and Dashboard adapters. */\nexport function renderCompletionSummary(success: boolean, summary?: string, completion?: CompletionData): string {\n if (success) {\n if (completion) {\n const files = completion.files;\n const shown: SummaryBoxItem[] = files.slice(0, MAX_SUMMARY_FILES).map((f) => ({ type: 'done', text: f }));\n if (files.length > MAX_SUMMARY_FILES) {\n shown.push({ type: 'done', text: `…and ${files.length - MAX_SUMMARY_FILES} more` });\n }\n const steps: SummaryBoxItem[] = completion.nextSteps.map((s) => ({ type: 'pending', text: s }));\n return renderFlatSummary({\n expression: 'success',\n title: 'WorkOS AuthKit Installed',\n items: [...shown, ...steps],\n footer: completion.docsUrl,\n });\n }\n // Fallback: preserve the original static next-steps when no structured data is present.\n return renderFlatSummary({\n expression: 'success',\n title: 'WorkOS AuthKit Installed',\n items: [\n { type: 'pending', text: 'Start dev server to test authentication' },\n { type: 'pending', text: 'Visit WorkOS Dashboard to manage users' },\n ],\n footer: 'https://workos.com/docs/authkit',\n });\n }\n return renderFlatSummary({\n expression: 'error',\n title: 'Installation Failed',\n items: summary ? [{ type: 'error', text: summary }] : [],\n footer: 'https://github.com/workos/cli/issues',\n });\n}\n\nexport interface SummaryBoxItem {\n type: 'done' | 'pending' | 'error';\n text: string;\n}\n\nexport interface SummaryBoxOptions {\n expression: LockExpression;\n title: string;\n items?: SummaryBoxItem[];\n footer?: string;\n}\n\nconst unicode = isUnicodeSupported();\n\nconst BOX = unicode\n ? { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│', ml: '├', mr: '┤' }\n : { tl: '+', tr: '+', bl: '+', br: '+', h: '-', v: '|', ml: '+', mr: '+' };\n\nconst ITEM_ICONS: Record<SummaryBoxItem['type'], string> = {\n done: chalk.green(symbols.success),\n pending: chalk.cyan(symbols.arrow),\n error: chalk.red(symbols.error),\n};\n\n// ── Flat (de-boxed) rendering — the install opener + closer ───────────────────\n\nconst { accent, cyan: flatCyan } = palette;\n\n/** Flat glyphs matching the ui facade (green ✓ / accent › / red ✗). */\nconst FLAT_ICONS: Record<SummaryBoxItem['type'], string> = {\n done: chalk.green('✓'),\n pending: accent('›'),\n error: chalk.red('✗'),\n};\n\n/**\n * The install opener: the WorkOS lock (in brand indigo) beside the wordmark.\n * A compact, de-boxed replacement for the full block-letter banner — the same\n * lock that closes the install, so the two ends bookend each other.\n */\nexport function renderBrandMark(subtitle?: string): string {\n const lock = getLockArt('success', false); // raw lines; recolor to brand indigo\n const titleLine = 2; // \"WorkOS\" sits beside the top of the lock body\n const subtitleLine = 3;\n return lock\n .map((l, i) => {\n const left = ` ${accent(l)}`;\n if (i === titleLine) return `${left} ${accent.bold('WorkOS')}`;\n if (i === subtitleLine && subtitle) return `${left} ${chalk.dim(subtitle)}`;\n return left;\n })\n .join('\\n');\n}\n\n/**\n * The install closer: the WorkOS lock (colored by outcome) above a flat title,\n * checklist, and footer — no border. Shared by the CLI and Dashboard adapters.\n * The lock is the same mark that opens the install (see renderBrandMark).\n */\nfunction renderFlatSummary(options: SummaryBoxOptions): string {\n const { expression, title, items = [], footer } = options;\n const out: string[] = getLockArt(expression, true).map((l) => ` ${l}`);\n out.push('', ` ${chalk.bold(title)}`);\n for (const item of items) {\n // File paths (done) read better in cyan; next-step prose stays default weight.\n const text = item.type === 'done' ? flatCyan(item.text) : item.text;\n out.push(` ${FLAT_ICONS[item.type]} ${text}`);\n }\n if (footer) out.push('', ` ${chalk.dim(footer)}`);\n return out.join('\\n');\n}\n\nconst MIN_WIDTH = 42;\n// Item prefix \" X \" = 4 visible chars before text\nconst ITEM_PREFIX_LEN = 4;\n// Footer prefix \" \" = 2 visible chars before text\nconst FOOTER_PREFIX_LEN = 2;\n\nfunction hLine(left: string, right: string, width: number): string {\n return `${left}${BOX.h.repeat(width - 2)}${right}`;\n}\n\nfunction padRight(text: string, visibleLen: number, targetLen: number): string {\n const padding = Math.max(0, targetLen - visibleLen);\n return text + ' '.repeat(padding);\n}\n\n/** Word-wrap text to fit within maxLen, returning multiple lines. */\nfunction wrapText(text: string, maxLen: number): string[] {\n if (text.length <= maxLen) return [text];\n const words = text.split(' ');\n const wrapped: string[] = [];\n let current = '';\n for (const word of words) {\n const candidate = current ? `${current} ${word}` : word;\n if (candidate.length > maxLen && current) {\n wrapped.push(current);\n current = word;\n } else {\n current = candidate;\n }\n }\n if (current) wrapped.push(current);\n return wrapped;\n}\n\nfunction getTerminalWidth(): number {\n return process.stdout.columns || 80;\n}\n\n/**\n * Render a branded summary box with the WorkOS lock character,\n * a title, optional checklist items, and an optional footer.\n */\nexport function renderSummaryBox(options: SummaryBoxOptions): string {\n const { expression, title, items = [], footer } = options;\n\n const lockColored = getLockArt(expression, true);\n const lockRaw = getLockArt(expression, false);\n const lockLines = lockColored.length;\n\n // \" \" + lock + \" \" = lock column width\n const lockColWidth = LOCK_WIDTH + 3;\n\n // Cap box width to terminal width\n const termWidth = getTerminalWidth();\n // innerWidth must fit: lock+title, items, footer — but capped to terminal\n const maxInner = Math.max(MIN_WIDTH - 2, termWidth - 2);\n\n // Compute ideal inner width from content\n const titleRowWidth = lockColWidth + title.length;\n const itemWidths = items.map((item) => ITEM_PREFIX_LEN + item.text.length);\n const footerWidth = footer ? FOOTER_PREFIX_LEN + footer.length : 0;\n const idealInner = Math.max(titleRowWidth, ...itemWidths, footerWidth) + 1;\n\n const innerWidth = Math.min(Math.max(MIN_WIDTH - 2, idealInner), maxInner);\n const boxWidth = innerWidth + 2;\n\n // Available text width for items and footer (after prefix, before right padding + border)\n const itemTextMax = innerWidth - ITEM_PREFIX_LEN - 1;\n const footerTextMax = innerWidth - FOOTER_PREFIX_LEN - 1;\n\n const lines: string[] = [];\n\n // Top border\n lines.push(hLine(BOX.tl, BOX.tr, boxWidth));\n\n // Lock + title rows\n const titleLineIndex = 3;\n for (let i = 0; i < lockLines; i++) {\n const lockPart = ` ${lockColored[i]} `;\n const lockPartRaw = ` ${lockRaw[i]} `;\n let rightPart: string;\n let rightPartLen: number;\n if (i === titleLineIndex) {\n rightPart = chalk.bold(title);\n rightPartLen = title.length;\n } else {\n rightPart = '';\n rightPartLen = 0;\n }\n const row = BOX.v + padRight(lockPart + rightPart, lockPartRaw.length + rightPartLen, innerWidth) + BOX.v;\n lines.push(row);\n }\n\n // Items\n if (items.length > 0) {\n lines.push(`${BOX.v}${' '.repeat(innerWidth)}${BOX.v}`);\n\n for (const item of items) {\n const icon = ITEM_ICONS[item.type];\n const wrappedLines = wrapText(item.text, itemTextMax);\n // First line gets the icon\n const first = ` ${icon} ${wrappedLines[0]}`;\n const firstLen = ITEM_PREFIX_LEN + wrappedLines[0].length;\n lines.push(`${BOX.v}${padRight(first, firstLen, innerWidth)}${BOX.v}`);\n // Continuation lines are indented to align with text after icon\n for (let j = 1; j < wrappedLines.length; j++) {\n const cont = ` ${wrappedLines[j]}`;\n const contLen = 4 + wrappedLines[j].length;\n lines.push(`${BOX.v}${padRight(cont, contLen, innerWidth)}${BOX.v}`);\n }\n }\n }\n\n // Footer\n if (footer) {\n lines.push(hLine(BOX.ml, BOX.mr, boxWidth));\n const wrappedFooter = wrapText(footer, footerTextMax);\n for (const fLine of wrappedFooter) {\n const content = ` ${chalk.dim(fLine)}`;\n const visibleLen = FOOTER_PREFIX_LEN + fLine.length;\n lines.push(`${BOX.v}${padRight(content, visibleLen, innerWidth)}${BOX.v}`);\n }\n }\n\n // Bottom border\n lines.push(hLine(BOX.bl, BOX.br, boxWidth));\n\n return lines.join('\\n');\n}\n"]}
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CredentialSource } from '../lib/installer-core.types.js';
|
|
1
2
|
export type InstallerOptions = {
|
|
2
3
|
/**
|
|
3
4
|
* Whether to enable debug mode.
|
|
@@ -36,6 +37,13 @@ export type InstallerOptions = {
|
|
|
36
37
|
* WorkOS Client ID (client_xxx)
|
|
37
38
|
*/
|
|
38
39
|
clientId?: string;
|
|
40
|
+
/**
|
|
41
|
+
* How the WorkOS credentials were resolved by the state machine
|
|
42
|
+
* (`cli`|`env`|`stored`|`device`|`manual`). Threaded downstream so
|
|
43
|
+
* user-facing copy can be source-accurate (e.g. avoid claiming the user
|
|
44
|
+
* "provided" credentials on the auto-provisioned path).
|
|
45
|
+
*/
|
|
46
|
+
credentialSource?: CredentialSource;
|
|
39
47
|
/**
|
|
40
48
|
* App homepage URL for WorkOS dashboard config.
|
|
41
49
|
* Defaults to http://localhost:{detected_port}
|
|
@@ -99,6 +107,8 @@ export type InstallerOptions = {
|
|
|
99
107
|
* Overrides detection from npm_config_user_agent.
|
|
100
108
|
*/
|
|
101
109
|
pm?: string;
|
|
110
|
+
/** Next.js router to target when detection is ambiguous (from --router). */
|
|
111
|
+
router?: 'app' | 'pages';
|
|
102
112
|
};
|
|
103
113
|
export interface Feature {
|
|
104
114
|
id: string;
|
package/dist/utils/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CredentialSource } from '../lib/installer-core.types.js';\n\nexport type InstallerOptions = {\n /**\n * Whether to enable debug mode.\n */\n debug: boolean;\n\n /**\n * Whether to force install the SDK package to continue with the installation in case\n * any package manager checks are failing (e.g. peer dependency versions).\n *\n * Use with caution and only if you know what you're doing.\n *\n * Does not apply to all wizard flows (currently NPM only)\n */\n forceInstall: boolean;\n\n /**\n * The directory to run the wizard in.\n */\n installDir: string;\n\n /**\n * Whether to use local services (LLM gateway on localhost:8000)\n */\n local: boolean;\n\n /**\n * CI mode - non-interactive execution\n */\n ci: boolean;\n\n /**\n * Skip authentication check (for local development only)\n */\n skipAuth: boolean;\n\n /**\n * WorkOS API key (sk_xxx)\n */\n apiKey?: string;\n\n /**\n * WorkOS Client ID (client_xxx)\n */\n clientId?: string;\n\n /**\n * How the WorkOS credentials were resolved by the state machine\n * (`cli`|`env`|`stored`|`device`|`manual`). Threaded downstream so\n * user-facing copy can be source-accurate (e.g. avoid claiming the user\n * \"provided\" credentials on the auto-provisioned path).\n */\n credentialSource?: CredentialSource;\n\n /**\n * App homepage URL for WorkOS dashboard config.\n * Defaults to http://localhost:{detected_port}\n */\n homepageUrl?: string;\n\n /**\n * Redirect URI for WorkOS callback.\n * Defaults to framework-specific convention (e.g., /api/auth/callback)\n */\n redirectUri?: string;\n\n /**\n * [Experimental] Enable visual dashboard mode\n */\n dashboard?: boolean;\n\n /**\n * Event emitter for dashboard mode\n */\n emitter?: import('../lib/events.js').InstallerEventEmitter;\n\n /**\n * Enable XState inspector - opens browser to visualize state machine live\n */\n inspect?: boolean;\n\n /**\n * Skip post-installation validation (includes build check)\n */\n noValidate?: boolean;\n\n /**\n * Skip post-install commit and PR workflow\n */\n noCommit?: boolean;\n\n /**\n * Skip branch creation (continue on current branch)\n */\n noBranch?: boolean;\n\n /**\n * Auto-create pull request after installation\n */\n createPr?: boolean;\n\n /**\n * Skip git dirty working tree check\n */\n noGitCheck?: boolean;\n\n /**\n * Direct mode - bypass llm-gateway and use user's own Anthropic API key.\n * Requires ANTHROPIC_API_KEY environment variable.\n */\n direct?: boolean;\n\n /**\n * Max correction attempts after initial agent run.\n * The agent gets this many chances to fix validation failures (typecheck/build).\n * Default: 2. Set to 0 to disable retries entirely.\n */\n maxRetries?: number;\n\n /**\n * Scaffold a new Next.js app when run in an empty directory.\n * Auto-enabled in headless mode; opt-in via --scaffold in interactive mode.\n */\n scaffold?: boolean;\n\n /**\n * Package manager for the scaffolded app (npm/pnpm/yarn/bun).\n * Overrides detection from npm_config_user_agent.\n */\n pm?: string;\n\n /** Next.js router to target when detection is ambiguous (from --router). */\n router?: 'app' | 'pages';\n};\n\nexport interface Feature {\n id: string;\n prompt: string;\n enabledHint?: string;\n disabledHint?: string;\n}\n\nexport type FileChange = {\n filePath: string;\n oldContent?: string;\n newContent: string;\n};\n"]}
|
|
@@ -88,7 +88,7 @@ export declare function isUsingTypeScript({ installDir }: Pick<InstallerOptions,
|
|
|
88
88
|
* Get WorkOS credentials (API Key and Client ID) from user or CLI options
|
|
89
89
|
* @param requireApiKey - Whether API key is needed (false for client-only SDKs like React, Vanilla JS)
|
|
90
90
|
*/
|
|
91
|
-
export declare function getOrAskForWorkOSCredentials(_options: Pick<InstallerOptions, 'ci' | 'apiKey' | 'clientId' | 'installDir' | 'dashboard'>, requireApiKey?: boolean): Promise<{
|
|
91
|
+
export declare function getOrAskForWorkOSCredentials(_options: Pick<InstallerOptions, 'ci' | 'apiKey' | 'clientId' | 'installDir' | 'dashboard' | 'credentialSource'>, requireApiKey?: boolean): Promise<{
|
|
92
92
|
apiKey: string;
|
|
93
93
|
clientId: string;
|
|
94
94
|
}>;
|
|
@@ -12,9 +12,11 @@ import { fulfillsVersionRange } from './semver.js';
|
|
|
12
12
|
import { getPackageVersion } from './package-json.js';
|
|
13
13
|
import { ISSUES_URL } from '../lib/constants.js';
|
|
14
14
|
import { analytics } from './analytics.js';
|
|
15
|
-
import
|
|
15
|
+
import ui from './ui.js';
|
|
16
16
|
import { INTEGRATION_CONFIG } from '../lib/config.js';
|
|
17
17
|
import { SPAWN_OPTS } from './platform.js';
|
|
18
|
+
import { isPromptAllowed } from './interaction-mode.js';
|
|
19
|
+
import { exitWithError, isJsonMode } from './output.js';
|
|
18
20
|
/**
|
|
19
21
|
* Redact sensitive info (API keys, client secrets) from a string.
|
|
20
22
|
*/
|
|
@@ -24,16 +26,37 @@ export function redactSensitiveInfo(str) {
|
|
|
24
26
|
}
|
|
25
27
|
export async function abort(message, status) {
|
|
26
28
|
await analytics.shutdown('cancelled');
|
|
27
|
-
|
|
29
|
+
ui.outro(message ?? 'Installer setup cancelled.');
|
|
28
30
|
return process.exit(status ?? 1);
|
|
29
31
|
}
|
|
30
32
|
export async function abortIfCancelled(input, integration) {
|
|
31
|
-
|
|
33
|
+
if (!isPromptAllowed()) {
|
|
34
|
+
// Never await `input` in non-interactive mode — awaiting a never-resolving
|
|
35
|
+
// prompt is exactly the hang this guard fixes. Fail fast with a structured
|
|
36
|
+
// error instead. Placed before analytics.shutdown('cancelled') so a
|
|
37
|
+
// non-interactive block is not mislabeled as a user cancel.
|
|
38
|
+
exitWithError({
|
|
39
|
+
code: 'non_interactive_prompt',
|
|
40
|
+
message: `This step requires interactive input${integration ? ` for ${integration}` : ''}, but the CLI is running ` +
|
|
41
|
+
`in a non-interactive mode (agent/CI/non-TTY). Pass the required flags (e.g. --router app|pages for Next.js) ` +
|
|
42
|
+
`or run in an interactive terminal.`,
|
|
43
|
+
recovery: {
|
|
44
|
+
hints: [
|
|
45
|
+
{
|
|
46
|
+
description: 'Re-run in an interactive terminal, or pass the flags that answer this prompt (e.g. --router).',
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
32
52
|
const resolvedInput = await input;
|
|
33
|
-
if (
|
|
34
|
-
|
|
53
|
+
if (ui.isCancel(resolvedInput)) {
|
|
54
|
+
// Flush a 'cancelled' session end ONLY on an actual cancel. Running this on
|
|
55
|
+
// every prompt (the previous behavior) emitted a bogus session end and added
|
|
56
|
+
// up to 3s of flush dead-time to each prompt on the happy path.
|
|
57
|
+
await analytics.shutdown('cancelled');
|
|
35
58
|
const docsUrl = integration ? INTEGRATION_CONFIG[integration].docsUrl : 'https://workos.com/docs/user-management';
|
|
36
|
-
|
|
59
|
+
ui.cancel(`Installer setup cancelled. You can read the documentation for ${integration ?? 'WorkOS AuthKit'} at ${chalk.cyan(docsUrl)} to continue with the setup manually.`);
|
|
37
60
|
process.exit(0);
|
|
38
61
|
}
|
|
39
62
|
else {
|
|
@@ -41,12 +64,10 @@ export async function abortIfCancelled(input, integration) {
|
|
|
41
64
|
}
|
|
42
65
|
}
|
|
43
66
|
export function printWelcome(options) {
|
|
44
|
-
|
|
45
|
-
console.log('');
|
|
46
|
-
clack.intro(chalk.inverse(` ${options.wizardName} `));
|
|
67
|
+
ui.intro('WorkOS', options.wizardName);
|
|
47
68
|
const welcomeText = options.message ||
|
|
48
69
|
`The ${options.wizardName} will help you set up WorkOS AuthKit for your application.\nThank you for using WorkOS AuthKit :)`;
|
|
49
|
-
|
|
70
|
+
ui.note(welcomeText);
|
|
50
71
|
}
|
|
51
72
|
export async function confirmContinueIfNoOrDirtyGitRepo(options) {
|
|
52
73
|
return traceStep('check-git-status', async () => {
|
|
@@ -54,7 +75,7 @@ export async function confirmContinueIfNoOrDirtyGitRepo(options) {
|
|
|
54
75
|
// CI mode: auto-continue without git
|
|
55
76
|
const continueWithoutGit = options.ci
|
|
56
77
|
? true
|
|
57
|
-
: await abortIfCancelled(
|
|
78
|
+
: await abortIfCancelled(ui.confirm({
|
|
58
79
|
message: 'You are not inside a git repository. The installer will create and update files. Do you want to continue anyway?',
|
|
59
80
|
}));
|
|
60
81
|
analytics.setTag('continue-without-git', continueWithoutGit);
|
|
@@ -68,16 +89,16 @@ export async function confirmContinueIfNoOrDirtyGitRepo(options) {
|
|
|
68
89
|
if (uncommittedOrUntrackedFiles.length) {
|
|
69
90
|
// CI mode: auto-continue with dirty repo
|
|
70
91
|
if (options.ci) {
|
|
71
|
-
|
|
92
|
+
ui.log.info(`CI mode: continuing with uncommitted/untracked files in repo`);
|
|
72
93
|
analytics.setTag('continue-with-dirty-repo', true);
|
|
73
94
|
return;
|
|
74
95
|
}
|
|
75
|
-
|
|
96
|
+
ui.log.warn(`You have uncommitted or untracked files in your repo:
|
|
76
97
|
|
|
77
98
|
${uncommittedOrUntrackedFiles.join('\n')}
|
|
78
99
|
|
|
79
100
|
The installer will create and update files.`);
|
|
80
|
-
const continueWithDirtyRepo = await abortIfCancelled(
|
|
101
|
+
const continueWithDirtyRepo = await abortIfCancelled(ui.confirm({
|
|
81
102
|
message: 'Do you want to continue anyway?',
|
|
82
103
|
}));
|
|
83
104
|
analytics.setTag('continue-with-dirty-repo', continueWithDirtyRepo);
|
|
@@ -118,7 +139,7 @@ export function getUncommittedOrUntrackedFiles() {
|
|
|
118
139
|
}
|
|
119
140
|
}
|
|
120
141
|
export async function askForItemSelection(items, message) {
|
|
121
|
-
const selection = await abortIfCancelled(
|
|
142
|
+
const selection = await abortIfCancelled(ui.select({
|
|
122
143
|
maxItems: 12,
|
|
123
144
|
message: message,
|
|
124
145
|
options: items.map((item, index) => {
|
|
@@ -142,11 +163,11 @@ export async function confirmContinueIfPackageVersionNotSupported({ packageId, p
|
|
|
142
163
|
analytics.setTag(`${packageName.toLowerCase()}-supported`, true);
|
|
143
164
|
return;
|
|
144
165
|
}
|
|
145
|
-
|
|
166
|
+
ui.log.warn(`You have an unsupported version of ${packageName} installed:
|
|
146
167
|
|
|
147
168
|
${packageId}@${packageVersion}`);
|
|
148
|
-
|
|
149
|
-
const continueWithUnsupportedVersion = await abortIfCancelled(
|
|
169
|
+
ui.note(note ?? `Please upgrade to ${acceptableVersions} if you wish to use the WorkOS AuthKit installer.`);
|
|
170
|
+
const continueWithUnsupportedVersion = await abortIfCancelled(ui.confirm({
|
|
150
171
|
message: 'Do you want to continue anyway?',
|
|
151
172
|
}));
|
|
152
173
|
analytics.setTag(`${packageName.toLowerCase()}-continue-with-unsupported-version`, continueWithUnsupportedVersion);
|
|
@@ -181,14 +202,14 @@ export async function isReact19Installed({ installDir }) {
|
|
|
181
202
|
export async function installPackage({ packageName, alreadyInstalled, askBeforeUpdating = true, packageNameDisplayLabel, packageManager, forceInstall = false, integration, installDir, }) {
|
|
182
203
|
return traceStep('install-package', async () => {
|
|
183
204
|
if (alreadyInstalled && askBeforeUpdating) {
|
|
184
|
-
const shouldUpdatePackage = await abortIfCancelled(
|
|
205
|
+
const shouldUpdatePackage = await abortIfCancelled(ui.confirm({
|
|
185
206
|
message: `The ${chalk.bold.cyan(packageNameDisplayLabel ?? packageName)} package is already installed. Do you want to update it to the latest version?`,
|
|
186
207
|
}));
|
|
187
208
|
if (!shouldUpdatePackage) {
|
|
188
209
|
return {};
|
|
189
210
|
}
|
|
190
211
|
}
|
|
191
|
-
const sdkInstallSpinner =
|
|
212
|
+
const sdkInstallSpinner = ui.spinner();
|
|
192
213
|
const pkgManager = packageManager || (await getPackageManager({ installDir }));
|
|
193
214
|
// Most packages aren't compatible with React 19 yet, skip strict peer dependency checks if needed.
|
|
194
215
|
const isReact19 = await isReact19Installed({ installDir });
|
|
@@ -230,7 +251,7 @@ export async function installPackage({ packageName, alreadyInstalled, askBeforeU
|
|
|
230
251
|
}
|
|
231
252
|
catch (e) {
|
|
232
253
|
sdkInstallSpinner.stop('Installation failed.');
|
|
233
|
-
|
|
254
|
+
ui.log.error(`${chalk.red('Encountered the following error during installation:')}\n\n${e}\n\n${chalk.dim(`The installer has created an \`workos-installation-error-*.log\` file. If you think this issue is caused by the WorkOS AuthKit installer, create an issue on GitHub and include the log file's content:\n${ISSUES_URL}`)}`);
|
|
234
255
|
await abort();
|
|
235
256
|
}
|
|
236
257
|
sdkInstallSpinner.stop(`${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(packageNameDisplayLabel ?? packageName)} with ${chalk.bold(pkgManager.label)}.`);
|
|
@@ -262,7 +283,7 @@ export async function ensurePackageIsInstalled(packageJson, packageId, packageNa
|
|
|
262
283
|
if (options?.dashboard) {
|
|
263
284
|
return;
|
|
264
285
|
}
|
|
265
|
-
const continueWithoutPackage = await abortIfCancelled(
|
|
286
|
+
const continueWithoutPackage = await abortIfCancelled(ui.confirm({
|
|
266
287
|
message: `${packageName} does not seem to be installed. Do you still want to continue?`,
|
|
267
288
|
initialValue: false,
|
|
268
289
|
}));
|
|
@@ -274,7 +295,7 @@ export async function ensurePackageIsInstalled(packageJson, packageId, packageNa
|
|
|
274
295
|
}
|
|
275
296
|
export async function getPackageDotJson({ installDir }) {
|
|
276
297
|
const packageJsonFileContents = await fs.promises.readFile(join(installDir, 'package.json'), 'utf8').catch(() => {
|
|
277
|
-
|
|
298
|
+
ui.log.error('Could not find package.json. Make sure to run the installer in the root of your app!');
|
|
278
299
|
return abort();
|
|
279
300
|
});
|
|
280
301
|
let packageJson = undefined;
|
|
@@ -283,7 +304,7 @@ export async function getPackageDotJson({ installDir }) {
|
|
|
283
304
|
packageJson = JSON.parse(packageJsonFileContents);
|
|
284
305
|
}
|
|
285
306
|
catch {
|
|
286
|
-
|
|
307
|
+
ui.log.error(`Unable to parse your ${chalk.cyan('package.json')}. Make sure it has a valid format!`);
|
|
287
308
|
await abort();
|
|
288
309
|
}
|
|
289
310
|
return packageJson || {};
|
|
@@ -298,7 +319,7 @@ export async function updatePackageDotJson(packageDotJson, { installDir }) {
|
|
|
298
319
|
});
|
|
299
320
|
}
|
|
300
321
|
catch {
|
|
301
|
-
|
|
322
|
+
ui.log.error(`Unable to update your ${chalk.cyan('package.json')}.`);
|
|
302
323
|
await abort();
|
|
303
324
|
}
|
|
304
325
|
}
|
|
@@ -315,7 +336,7 @@ export async function getPackageManager(options) {
|
|
|
315
336
|
// CI mode: auto-select first detected or npm
|
|
316
337
|
if (options.ci) {
|
|
317
338
|
const selectedPackageManager = detectedPackageManagers.length > 0 ? detectedPackageManagers[0] : npm;
|
|
318
|
-
|
|
339
|
+
ui.log.info(`CI mode: auto-selected package manager: ${selectedPackageManager.label}`);
|
|
319
340
|
analytics.setTag('package-manager', selectedPackageManager.name);
|
|
320
341
|
return selectedPackageManager;
|
|
321
342
|
}
|
|
@@ -324,7 +345,7 @@ export async function getPackageManager(options) {
|
|
|
324
345
|
const message = detectedPackageManagers.length > 1
|
|
325
346
|
? 'Multiple package managers detected. Please select one:'
|
|
326
347
|
: 'Please select your package manager.';
|
|
327
|
-
const selectedPackageManager = await abortIfCancelled(
|
|
348
|
+
const selectedPackageManager = await abortIfCancelled(ui.select({
|
|
328
349
|
message,
|
|
329
350
|
options: pkgOptions.map((packageManager) => ({
|
|
330
351
|
value: packageManager,
|
|
@@ -351,9 +372,15 @@ export async function getOrAskForWorkOSCredentials(_options, requireApiKey = tru
|
|
|
351
372
|
let clientId = _options.clientId;
|
|
352
373
|
// If credentials provided via CLI (e.g., CI mode or dashboard mode), use them
|
|
353
374
|
if ((!requireApiKey || apiKey) && clientId) {
|
|
354
|
-
//
|
|
355
|
-
|
|
356
|
-
|
|
375
|
+
// Say "you provided" only when the user actually supplied credentials
|
|
376
|
+
// (cli/manual, or an unknown source). For device/stored/env the state
|
|
377
|
+
// machine already announced the source accurately before this runs, so
|
|
378
|
+
// stay silent rather than double-announce. Gate on human output mode so
|
|
379
|
+
// this never pollutes JSON/NDJSON.
|
|
380
|
+
const source = _options.credentialSource;
|
|
381
|
+
const userProvided = source === 'cli' || source === 'manual' || source === undefined;
|
|
382
|
+
if (!_options.dashboard && !isJsonMode() && userProvided) {
|
|
383
|
+
ui.log.info('Using the WorkOS credentials you provided');
|
|
357
384
|
}
|
|
358
385
|
return { apiKey: apiKey || '', clientId };
|
|
359
386
|
}
|
|
@@ -368,7 +395,7 @@ export async function getOrAskForWorkOSCredentials(_options, requireApiKey = tru
|
|
|
368
395
|
// Use existing credentials if both are present (or API key not required)
|
|
369
396
|
if (existingClientId && (!requireApiKey || existingApiKey)) {
|
|
370
397
|
if (!_options.dashboard) {
|
|
371
|
-
|
|
398
|
+
ui.log.success(`Found existing WorkOS credentials in .env.local`);
|
|
372
399
|
}
|
|
373
400
|
return {
|
|
374
401
|
apiKey: existingApiKey || '',
|
|
@@ -382,10 +409,10 @@ export async function getOrAskForWorkOSCredentials(_options, requireApiKey = tru
|
|
|
382
409
|
}
|
|
383
410
|
}
|
|
384
411
|
// Otherwise, prompt user for credentials
|
|
385
|
-
|
|
412
|
+
ui.log.step(`Get your credentials from ${chalk.cyan('https://dashboard.workos.com')}`);
|
|
386
413
|
if (requireApiKey && !apiKey) {
|
|
387
|
-
|
|
388
|
-
apiKey = (await abortIfCancelled(
|
|
414
|
+
ui.log.info(`${chalk.dim('ℹ️ Your API key will be hidden for security and saved to .env.local')}`);
|
|
415
|
+
apiKey = (await abortIfCancelled(ui.password({
|
|
389
416
|
message: 'Enter your WorkOS API Key',
|
|
390
417
|
validate: (value) => {
|
|
391
418
|
if (!value)
|
|
@@ -398,10 +425,10 @@ export async function getOrAskForWorkOSCredentials(_options, requireApiKey = tru
|
|
|
398
425
|
})));
|
|
399
426
|
}
|
|
400
427
|
else if (!requireApiKey) {
|
|
401
|
-
|
|
428
|
+
ui.log.info(`${chalk.dim('ℹ️ Client-only SDK - API key not required')}`);
|
|
402
429
|
}
|
|
403
430
|
if (!clientId) {
|
|
404
|
-
clientId = (await abortIfCancelled(
|
|
431
|
+
clientId = (await abortIfCancelled(ui.text({
|
|
405
432
|
message: 'Enter your WorkOS Client ID',
|
|
406
433
|
placeholder: 'client_...',
|
|
407
434
|
validate: (value) => {
|
|
@@ -419,4 +446,4 @@ export async function getOrAskForWorkOSCredentials(_options, requireApiKey = tru
|
|
|
419
446
|
/**
|
|
420
447
|
* Fetch project data using a personal API key (for CI mode)
|
|
421
448
|
*/
|
|
422
|
-
//# sourceMappingURL=
|
|
449
|
+
//# sourceMappingURL=ui-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-utils.js","sourceRoot":"","sources":["../../src/utils/ui-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as childProcess from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport { join } from 'node:path';\n\nimport chalk from 'chalk';\nimport { traceStep } from '../telemetry.js';\nimport { debug } from './debug.js';\nimport { parseEnvFile } from './env-parser.js';\nimport { type PackageDotJson, hasPackageInstalled } from './package-json.js';\nimport { type PackageManager, detectAllPackageManagers, packageManagers, NPM as npm } from './package-manager.js';\nimport { fulfillsVersionRange } from './semver.js';\nimport type { InstallerOptions } from './types.js';\nimport { getPackageVersion } from './package-json.js';\nimport { ISSUES_URL, type Integration } from '../lib/constants.js';\nimport { analytics } from './analytics.js';\nimport ui from './ui.js';\nimport { INTEGRATION_CONFIG } from '../lib/config.js';\nimport { SPAWN_OPTS } from './platform.js';\nimport { isPromptAllowed } from './interaction-mode.js';\nimport { exitWithError, isJsonMode } from './output.js';\n\n/**\n * Redact sensitive info (API keys, client secrets) from a string.\n */\nexport function redactSensitiveInfo(str: string): string {\n // Redact WorkOS API keys (sk_...), client secrets, etc.\n return str.replace(/sk_[a-zA-Z0-9]+/g, 'sk_***').replace(/client_[a-zA-Z0-9]{20,}/g, 'client_***');\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n gitignore: boolean;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n\n likelyAlreadyHasUrl?(contents: string): boolean;\n urlContent?(url: string): string;\n}\n\nexport interface CliSetupConfigContent {\n authToken: string;\n org?: string;\n project?: string;\n url?: string;\n}\n\nexport async function abort(message?: string, status?: number): Promise<never> {\n await analytics.shutdown('cancelled');\n\n ui.outro(message ?? 'Installer setup cancelled.');\n return process.exit(status ?? 1);\n}\n\nexport async function abortIfCancelled<T>(\n input: T | Promise<T>,\n integration?: Integration,\n): Promise<Exclude<T, symbol>> {\n if (!isPromptAllowed()) {\n // Never await `input` in non-interactive mode — awaiting a never-resolving\n // prompt is exactly the hang this guard fixes. Fail fast with a structured\n // error instead. Placed before analytics.shutdown('cancelled') so a\n // non-interactive block is not mislabeled as a user cancel.\n exitWithError({\n code: 'non_interactive_prompt',\n message:\n `This step requires interactive input${integration ? ` for ${integration}` : ''}, but the CLI is running ` +\n `in a non-interactive mode (agent/CI/non-TTY). Pass the required flags (e.g. --router app|pages for Next.js) ` +\n `or run in an interactive terminal.`,\n recovery: {\n hints: [\n {\n description:\n 'Re-run in an interactive terminal, or pass the flags that answer this prompt (e.g. --router).',\n },\n ],\n },\n });\n }\n\n const resolvedInput = await input;\n\n if (ui.isCancel(resolvedInput)) {\n // Flush a 'cancelled' session end ONLY on an actual cancel. Running this on\n // every prompt (the previous behavior) emitted a bogus session end and added\n // up to 3s of flush dead-time to each prompt on the happy path.\n await analytics.shutdown('cancelled');\n\n const docsUrl = integration ? INTEGRATION_CONFIG[integration].docsUrl : 'https://workos.com/docs/user-management';\n\n ui.cancel(\n `Installer setup cancelled. You can read the documentation for ${\n integration ?? 'WorkOS AuthKit'\n } at ${chalk.cyan(docsUrl)} to continue with the setup manually.`,\n );\n process.exit(0);\n } else {\n return input as Exclude<T, symbol>;\n }\n}\n\nexport function printWelcome(options: { wizardName: string; message?: string }): void {\n ui.intro('WorkOS', options.wizardName);\n\n const welcomeText =\n options.message ||\n `The ${options.wizardName} will help you set up WorkOS AuthKit for your application.\\nThank you for using WorkOS AuthKit :)`;\n\n ui.note(welcomeText);\n}\n\nexport async function confirmContinueIfNoOrDirtyGitRepo(options: Pick<InstallerOptions, 'ci'>): Promise<void> {\n return traceStep('check-git-status', async () => {\n if (!isInGitRepo()) {\n // CI mode: auto-continue without git\n const continueWithoutGit = options.ci\n ? true\n : await abortIfCancelled(\n ui.confirm({\n message:\n 'You are not inside a git repository. The installer will create and update files. Do you want to continue anyway?',\n }),\n );\n\n analytics.setTag('continue-without-git', continueWithoutGit);\n\n if (!continueWithoutGit) {\n await abort(undefined, 0);\n }\n // return early to avoid checking for uncommitted files\n return;\n }\n\n const uncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles();\n if (uncommittedOrUntrackedFiles.length) {\n // CI mode: auto-continue with dirty repo\n if (options.ci) {\n ui.log.info(`CI mode: continuing with uncommitted/untracked files in repo`);\n analytics.setTag('continue-with-dirty-repo', true);\n return;\n }\n\n ui.log.warn(\n `You have uncommitted or untracked files in your repo:\n\n${uncommittedOrUntrackedFiles.join('\\n')}\n\nThe installer will create and update files.`,\n );\n const continueWithDirtyRepo = await abortIfCancelled(\n ui.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n\n analytics.setTag('continue-with-dirty-repo', continueWithDirtyRepo);\n\n if (!continueWithDirtyRepo) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport function isInGitRepo() {\n try {\n childProcess.execSync('git rev-parse --is-inside-work-tree', {\n stdio: 'ignore',\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getUncommittedOrUntrackedFiles(): string[] {\n try {\n const gitStatus = childProcess\n .execSync('git status --porcelain=v1', {\n // we only care about stdout\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString();\n\n const files = gitStatus\n .split(os.EOL)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((f) => `- ${f.split(/\\s+/)[1]}`);\n\n return files;\n } catch {\n return [];\n }\n}\n\nexport async function askForItemSelection(items: string[], message: string): Promise<{ value: string; index: number }> {\n const selection = await abortIfCancelled<{ value: string; index: number } | symbol>(\n ui.select({\n maxItems: 12,\n message: message,\n options: items.map((item, index) => {\n return {\n value: { value: item, index: index },\n label: item,\n };\n }),\n }),\n );\n\n return selection as { value: string; index: number };\n}\n\nexport async function confirmContinueIfPackageVersionNotSupported({\n packageId,\n packageName,\n packageVersion,\n acceptableVersions,\n note,\n}: {\n packageId: string;\n packageName: string;\n packageVersion: string;\n acceptableVersions: string;\n note?: string;\n}): Promise<void> {\n return traceStep(`check-package-version`, async () => {\n analytics.setTag(`${packageName.toLowerCase()}-version`, packageVersion);\n const isSupportedVersion = fulfillsVersionRange({\n acceptableVersions,\n version: packageVersion,\n canBeLatest: true,\n });\n\n if (isSupportedVersion) {\n analytics.setTag(`${packageName.toLowerCase()}-supported`, true);\n return;\n }\n\n ui.log.warn(\n `You have an unsupported version of ${packageName} installed:\n\n ${packageId}@${packageVersion}`,\n );\n\n ui.note(note ?? `Please upgrade to ${acceptableVersions} if you wish to use the WorkOS AuthKit installer.`);\n const continueWithUnsupportedVersion = await abortIfCancelled(\n ui.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n analytics.setTag(`${packageName.toLowerCase()}-continue-with-unsupported-version`, continueWithUnsupportedVersion);\n\n if (!continueWithUnsupportedVersion) {\n await abort(undefined, 0);\n }\n });\n}\n\nexport async function isReact19Installed({ installDir }: Pick<InstallerOptions, 'installDir'>): Promise<boolean> {\n try {\n const packageJson = await getPackageDotJson({ installDir });\n const reactVersion = getPackageVersion('react', packageJson);\n\n if (!reactVersion) {\n return false;\n }\n\n return fulfillsVersionRange({\n version: reactVersion,\n acceptableVersions: '>=19.0.0',\n canBeLatest: true,\n });\n } catch {\n return false;\n }\n}\n\n/**\n * Installs or updates a package with the user's package manager.\n *\n * IMPORTANT: This function modifies the `package.json`! Be sure to re-read\n * it if you make additional modifications to it after calling this function!\n */\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n askBeforeUpdating = true,\n packageNameDisplayLabel,\n packageManager,\n forceInstall = false,\n integration,\n installDir,\n}: {\n /** The string that is passed to the package manager CLI as identifier to install (e.g. `@workos-inc/authkit-nextjs`, or `@workos-inc/authkit-nextjs@^2.0.0`) */\n packageName: string;\n alreadyInstalled: boolean;\n askBeforeUpdating?: boolean;\n /** Overrides what is shown in the installation logs in place of the `packageName` option. Useful if the `packageName` is ugly */\n packageNameDisplayLabel?: string;\n packageManager?: PackageManager;\n /** Add force install flag to command to skip install precondition fails */\n forceInstall?: boolean;\n /** The integration that is being used */\n integration?: string;\n /** The directory to install the package in */\n installDir: string;\n}): Promise<{ packageManager?: PackageManager }> {\n return traceStep('install-package', async () => {\n if (alreadyInstalled && askBeforeUpdating) {\n const shouldUpdatePackage = await abortIfCancelled(\n ui.confirm({\n message: `The ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} package is already installed. Do you want to update it to the latest version?`,\n }),\n );\n\n if (!shouldUpdatePackage) {\n return {};\n }\n }\n\n const sdkInstallSpinner = ui.spinner();\n\n const pkgManager = packageManager || (await getPackageManager({ installDir }));\n\n // Most packages aren't compatible with React 19 yet, skip strict peer dependency checks if needed.\n const isReact19 = await isReact19Installed({ installDir });\n const legacyPeerDepsFlag = isReact19 && pkgManager.name === 'npm' ? '--legacy-peer-deps' : '';\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n try {\n await new Promise<void>((resolve, reject) => {\n const [cmd, ...baseArgs] = pkgManager.installCommand.split(' ');\n const args = [\n ...baseArgs,\n packageName,\n ...pkgManager.flags.split(/\\s+/).filter(Boolean),\n ...(forceInstall && pkgManager.forceInstallFlag ? pkgManager.forceInstallFlag.split(/\\s+/) : []),\n ...(legacyPeerDepsFlag ? [legacyPeerDepsFlag] : []),\n ];\n const proc = childProcess.spawn(cmd, args, { cwd: installDir, ...SPAWN_OPTS });\n let stdout = '';\n let stderr = '';\n proc.stdout?.on('data', (d: Buffer) => {\n stdout += d.toString();\n });\n proc.stderr?.on('data', (d: Buffer) => {\n stderr += d.toString();\n });\n proc.on('close', (code) => {\n if (code !== 0) {\n fs.writeFileSync(\n join(process.cwd(), `workos-installation-error-${Date.now()}.log`),\n JSON.stringify({\n stdout: redactSensitiveInfo(stdout),\n stderr: redactSensitiveInfo(stderr),\n }),\n { encoding: 'utf8' },\n );\n reject(new Error(`${cmd} exited with code ${code}\\n${stderr}`));\n } else {\n resolve();\n }\n });\n proc.on('error', reject);\n });\n } catch (e) {\n sdkInstallSpinner.stop('Installation failed.');\n ui.log.error(\n `${chalk.red(\n 'Encountered the following error during installation:',\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n )}\\n\\n${e}\\n\\n${chalk.dim(\n `The installer has created an \\`workos-installation-error-*.log\\` file. If you think this issue is caused by the WorkOS AuthKit installer, create an issue on GitHub and include the log file's content:\\n${ISSUES_URL}`,\n )}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk.bold.cyan(\n packageNameDisplayLabel ?? packageName,\n )} with ${chalk.bold(pkgManager.label)}.`,\n );\n\n analytics.capture('installer interaction', {\n action: 'package installed',\n package_name: packageName,\n package_manager: pkgManager.name,\n integration,\n });\n\n return { packageManager: pkgManager };\n });\n}\n\n/**\n * Checks if @param packageId is listed as a dependency in @param packageJson.\n * If not, it will ask users if they want to continue without the package.\n *\n * Use this function to check if e.g. a the framework of the SDK is installed\n *\n * @param packageJson the package.json object\n * @param packageId the npm name of the package\n * @param packageName a human readable name of the package\n */\nexport async function ensurePackageIsInstalled(\n packageJson: PackageDotJson,\n packageId: string,\n packageName: string,\n options?: Pick<InstallerOptions, 'dashboard'>,\n): Promise<void> {\n return traceStep('ensure-package-installed', async () => {\n const installed = hasPackageInstalled(packageId, packageJson);\n\n analytics.setTag(`${packageName.toLowerCase()}-installed`, installed);\n\n if (!installed) {\n // In dashboard mode, auto-continue (integration was already detected)\n if (options?.dashboard) {\n return;\n }\n\n const continueWithoutPackage = await abortIfCancelled(\n ui.confirm({\n message: `${packageName} does not seem to be installed. Do you still want to continue?`,\n initialValue: false,\n }),\n );\n\n if (!continueWithoutPackage) {\n await abort(undefined, 0);\n }\n }\n });\n}\n\nexport async function getPackageDotJson({ installDir }: Pick<InstallerOptions, 'installDir'>): Promise<PackageDotJson> {\n const packageJsonFileContents = await fs.promises.readFile(join(installDir, 'package.json'), 'utf8').catch(() => {\n ui.log.error('Could not find package.json. Make sure to run the installer in the root of your app!');\n return abort();\n });\n\n let packageJson: PackageDotJson | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch {\n ui.log.error(`Unable to parse your ${chalk.cyan('package.json')}. Make sure it has a valid format!`);\n\n await abort();\n }\n\n return packageJson || {};\n}\n\nexport async function updatePackageDotJson(\n packageDotJson: PackageDotJson,\n { installDir }: Pick<InstallerOptions, 'installDir'>,\n): Promise<void> {\n try {\n await fs.promises.writeFile(\n join(installDir, 'package.json'),\n // TODO: maybe figure out the original indentation\n JSON.stringify(packageDotJson, null, 2),\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n } catch {\n ui.log.error(`Unable to update your ${chalk.cyan('package.json')}.`);\n\n await abort();\n }\n}\n\nexport async function getPackageManager(\n options: Pick<InstallerOptions, 'installDir'> & { ci?: boolean },\n): Promise<PackageManager> {\n const detectedPackageManagers = detectAllPackageManagers({\n installDir: options.installDir,\n });\n\n // If exactly one package manager detected, use it automatically\n if (detectedPackageManagers.length === 1) {\n const detectedPackageManager = detectedPackageManagers[0];\n analytics.setTag('package-manager', detectedPackageManager.name);\n return detectedPackageManager;\n }\n\n // CI mode: auto-select first detected or npm\n if (options.ci) {\n const selectedPackageManager = detectedPackageManagers.length > 0 ? detectedPackageManagers[0] : npm;\n ui.log.info(`CI mode: auto-selected package manager: ${selectedPackageManager.label}`);\n analytics.setTag('package-manager', selectedPackageManager.name);\n return selectedPackageManager;\n }\n\n // If multiple or no package managers detected, prompt user to select\n const pkgOptions = detectedPackageManagers.length > 0 ? detectedPackageManagers : packageManagers;\n\n const message =\n detectedPackageManagers.length > 1\n ? 'Multiple package managers detected. Please select one:'\n : 'Please select your package manager.';\n\n const selectedPackageManager = await abortIfCancelled<PackageManager | symbol>(\n ui.select({\n message,\n options: pkgOptions.map((packageManager) => ({\n value: packageManager,\n label: packageManager.label,\n })),\n }),\n );\n\n analytics.setTag('package-manager', (selectedPackageManager as PackageManager).name);\n return selectedPackageManager as PackageManager;\n}\n\nexport function isUsingTypeScript({ installDir }: Pick<InstallerOptions, 'installDir'>) {\n try {\n return fs.existsSync(join(installDir, 'tsconfig.json'));\n } catch {\n return false;\n }\n}\n\n/**\n * Get WorkOS credentials (API Key and Client ID) from user or CLI options\n * @param requireApiKey - Whether API key is needed (false for client-only SDKs like React, Vanilla JS)\n */\nexport async function getOrAskForWorkOSCredentials(\n _options: Pick<InstallerOptions, 'ci' | 'apiKey' | 'clientId' | 'installDir' | 'dashboard' | 'credentialSource'>,\n requireApiKey: boolean = true,\n): Promise<{\n apiKey: string;\n clientId: string;\n}> {\n let apiKey = _options.apiKey;\n let clientId = _options.clientId;\n\n // If credentials provided via CLI (e.g., CI mode or dashboard mode), use them\n if ((!requireApiKey || apiKey) && clientId) {\n // Say \"you provided\" only when the user actually supplied credentials\n // (cli/manual, or an unknown source). For device/stored/env the state\n // machine already announced the source accurately before this runs, so\n // stay silent rather than double-announce. Gate on human output mode so\n // this never pollutes JSON/NDJSON.\n const source = _options.credentialSource;\n const userProvided = source === 'cli' || source === 'manual' || source === undefined;\n if (!_options.dashboard && !isJsonMode() && userProvided) {\n ui.log.info('Using the WorkOS credentials you provided');\n }\n return { apiKey: apiKey || '', clientId };\n }\n\n // Check if credentials already exist in .env.local\n const envPath = join(_options.installDir, '.env.local');\n if (fs.existsSync(envPath)) {\n try {\n const envContent = fs.readFileSync(envPath, 'utf-8');\n const envVars = parseEnvFile(envContent);\n\n const existingApiKey = envVars.WORKOS_API_KEY;\n const existingClientId = envVars.WORKOS_CLIENT_ID;\n\n // Use existing credentials if both are present (or API key not required)\n if (existingClientId && (!requireApiKey || existingApiKey)) {\n if (!_options.dashboard) {\n ui.log.success(`Found existing WorkOS credentials in .env.local`);\n }\n return {\n apiKey: existingApiKey || '',\n clientId: existingClientId,\n };\n }\n } catch (error) {\n // If we can't read/parse .env.local, just continue to prompt\n debug('Failed to read .env.local:', error);\n }\n }\n\n // Otherwise, prompt user for credentials\n ui.log.step(`Get your credentials from ${chalk.cyan('https://dashboard.workos.com')}`);\n\n if (requireApiKey && !apiKey) {\n ui.log.info(`${chalk.dim('ℹ️ Your API key will be hidden for security and saved to .env.local')}`);\n apiKey = (await abortIfCancelled(\n ui.password({\n message: 'Enter your WorkOS API Key',\n validate: (value) => {\n if (!value) return 'API Key is required';\n if (!value.startsWith('sk_')) {\n return 'API Key should start with sk_';\n }\n return undefined;\n },\n }),\n )) as string;\n } else if (!requireApiKey) {\n ui.log.info(`${chalk.dim('ℹ️ Client-only SDK - API key not required')}`);\n }\n\n if (!clientId) {\n clientId = (await abortIfCancelled(\n ui.text({\n message: 'Enter your WorkOS Client ID',\n placeholder: 'client_...',\n validate: (value) => {\n if (!value) return 'Client ID is required';\n if (!value.startsWith('client_')) {\n return 'Client ID should start with client_';\n }\n return undefined;\n },\n }),\n )) as string;\n }\n\n return { apiKey: apiKey || '', clientId };\n}\n\n/**\n * Fetch project data using a personal API key (for CI mode)\n */\n"]}
|