workos 0.3.2 → 0.3.3

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/dist/bin.js CHANGED
@@ -11,6 +11,7 @@ import { getConfig } from './lib/settings.js';
11
11
  import yargs from 'yargs';
12
12
  import { hideBin } from 'yargs/helpers';
13
13
  import { ensureAuthenticated } from './lib/ensure-auth.js';
14
+ import { checkForUpdates } from './lib/version-check.js';
14
15
  const NODE_VERSION_RANGE = getConfig().nodeVersion;
15
16
  // Have to run this above the other imports because they are importing clack that
16
17
  // has the problematic imports.
@@ -110,6 +111,8 @@ const installerOptions = {
110
111
  type: 'boolean',
111
112
  },
112
113
  };
114
+ // Check for updates (blocks up to 500ms)
115
+ await checkForUpdates();
113
116
  yargs(hideBin(process.argv))
114
117
  .env('WORKOS_INSTALLER')
115
118
  .command('login', 'Authenticate with WorkOS', {}, async () => {
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\n// Load .env.local for local development when --local flag is used\nif (process.argv.includes('--local') || process.env.INSTALLER_DEV) {\n const { config } = await import('dotenv');\n // bin.ts compiles to dist/bin.js, so go up one level to find .env.local\n config({ path: new URL('../.env.local', import.meta.url).pathname });\n}\n\nimport { satisfies } from 'semver';\nimport { red } from './utils/logging.js';\nimport { getConfig } from './lib/settings.js';\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport chalk from 'chalk';\nimport { ensureAuthenticated } from './lib/ensure-auth.js';\n\nconst NODE_VERSION_RANGE = getConfig().nodeVersion;\n\n// Have to run this above the other imports because they are importing clack that\n// has the problematic imports.\nif (!satisfies(process.version, NODE_VERSION_RANGE)) {\n red(\n `WorkOS AuthKit installer requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`,\n );\n process.exit(1);\n}\n\nimport { isNonInteractiveEnvironment } from './utils/environment.js';\nimport clack from './utils/clack.js';\n\n// Shared options for wizard commands (default and dashboard)\n/**\n * Wrap a command handler with authentication check.\n * Ensures valid auth before executing the handler.\n * Respects --skip-auth flag for CI/testing.\n */\nfunction withAuth<T>(handler: (argv: T) => Promise<void>): (argv: T) => Promise<void> {\n return async (argv: T) => {\n if (!(argv as { skipAuth?: boolean }).skipAuth) {\n await ensureAuthenticated();\n }\n await handler(argv);\n };\n}\n\nconst installerOptions = {\n direct: {\n alias: 'D',\n default: false,\n describe: 'Use your own Anthropic API key (bypass llm-gateway)',\n type: 'boolean' as const,\n },\n debug: {\n default: false,\n describe: 'Enable verbose logging',\n type: 'boolean' as const,\n },\n // Hidden dev/automation flags (use env vars)\n local: {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n ci: {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n 'skip-auth': {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n 'api-key': {\n type: 'string' as const,\n hidden: true,\n },\n 'client-id': {\n type: 'string' as const,\n hidden: true,\n },\n inspect: {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n // User-facing flags\n 'homepage-url': {\n describe: 'App homepage URL for WorkOS (defaults to http://localhost:{port})',\n type: 'string' as const,\n },\n 'redirect-uri': {\n describe: 'Redirect URI for WorkOS callback (defaults to framework convention)',\n type: 'string' as const,\n },\n 'no-validate': {\n default: false,\n describe: 'Skip post-installation validation (includes build check)',\n type: 'boolean' as const,\n },\n 'install-dir': {\n describe: 'Directory to install WorkOS AuthKit in',\n type: 'string' as const,\n },\n integration: {\n describe: 'Integration to set up',\n choices: ['nextjs', 'react', 'tanstack-start', 'react-router', 'vanilla-js'] as const,\n type: 'string' as const,\n },\n 'force-install': {\n default: false,\n describe: 'Force install packages even if peer dependency checks fail',\n type: 'boolean' as const,\n },\n dashboard: {\n alias: 'd',\n default: false,\n describe: 'Run with visual dashboard mode',\n type: 'boolean' as const,\n },\n};\n\nyargs(hideBin(process.argv))\n .env('WORKOS_INSTALLER')\n .command('login', 'Authenticate with WorkOS', {}, async () => {\n const { runLogin } = await import('./commands/login.js');\n await runLogin();\n process.exit(0);\n })\n .command('logout', 'Remove stored credentials', {}, async () => {\n const { runLogout } = await import('./commands/logout.js');\n await runLogout();\n })\n .command(\n 'install-skill',\n 'Install bundled AuthKit skills to coding agents',\n (yargs) => {\n return yargs\n .option('list', {\n alias: 'l',\n type: 'boolean',\n description: 'List available skills without installing',\n })\n .option('skill', {\n alias: 's',\n type: 'array',\n string: true,\n description: 'Install specific skill(s)',\n })\n .option('agent', {\n alias: 'a',\n type: 'array',\n string: true,\n description: 'Target specific agent(s): claude-code, codex, cursor, goose',\n });\n },\n withAuth(async (argv) => {\n const { runInstallSkill } = await import('./commands/install-skill.js');\n await runInstallSkill({\n list: argv.list as boolean | undefined,\n skill: argv.skill as string[] | undefined,\n agent: argv.agent as string[] | undefined,\n });\n }),\n )\n .command(\n 'install',\n 'Install WorkOS AuthKit into your project',\n (yargs) => yargs.options(installerOptions),\n withAuth(async (argv) => {\n const { handleInstall } = await import('./commands/install.js');\n await handleInstall(argv);\n }),\n )\n .command(\n 'dashboard',\n false, // hidden from help\n (yargs) => yargs.options(installerOptions),\n withAuth(async (argv) => {\n const { handleInstall } = await import('./commands/install.js');\n await handleInstall({ ...argv, dashboard: true });\n }),\n )\n .command(\n ['$0'],\n 'WorkOS AuthKit CLI',\n (yargs) => yargs,\n async () => {\n // Non-TTY: show help\n if (isNonInteractiveEnvironment()) {\n yargs(hideBin(process.argv)).showHelp();\n return;\n }\n\n // TTY: ask if user wants to run installer\n const shouldInstall = await clack.confirm({\n message: 'Run the AuthKit installer?',\n });\n\n if (clack.isCancel(shouldInstall) || !shouldInstall) {\n process.exit(0);\n }\n\n // Auth check happens HERE, after user confirms\n await ensureAuthenticated();\n\n const { handleInstall } = await import('./commands/install.js');\n await handleInstall({ dashboard: false } as any);\n process.exit(0);\n },\n )\n .strict()\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY && process.stdout.columns ? process.stdout.columns : 80).argv;\n"]}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\n// Load .env.local for local development when --local flag is used\nif (process.argv.includes('--local') || process.env.INSTALLER_DEV) {\n const { config } = await import('dotenv');\n // bin.ts compiles to dist/bin.js, so go up one level to find .env.local\n config({ path: new URL('../.env.local', import.meta.url).pathname });\n}\n\nimport { satisfies } from 'semver';\nimport { red } from './utils/logging.js';\nimport { getConfig } from './lib/settings.js';\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport chalk from 'chalk';\nimport { ensureAuthenticated } from './lib/ensure-auth.js';\nimport { checkForUpdates } from './lib/version-check.js';\n\nconst NODE_VERSION_RANGE = getConfig().nodeVersion;\n\n// Have to run this above the other imports because they are importing clack that\n// has the problematic imports.\nif (!satisfies(process.version, NODE_VERSION_RANGE)) {\n red(\n `WorkOS AuthKit installer requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`,\n );\n process.exit(1);\n}\n\nimport { isNonInteractiveEnvironment } from './utils/environment.js';\nimport clack from './utils/clack.js';\n\n// Shared options for wizard commands (default and dashboard)\n/**\n * Wrap a command handler with authentication check.\n * Ensures valid auth before executing the handler.\n * Respects --skip-auth flag for CI/testing.\n */\nfunction withAuth<T>(handler: (argv: T) => Promise<void>): (argv: T) => Promise<void> {\n return async (argv: T) => {\n if (!(argv as { skipAuth?: boolean }).skipAuth) {\n await ensureAuthenticated();\n }\n await handler(argv);\n };\n}\n\nconst installerOptions = {\n direct: {\n alias: 'D',\n default: false,\n describe: 'Use your own Anthropic API key (bypass llm-gateway)',\n type: 'boolean' as const,\n },\n debug: {\n default: false,\n describe: 'Enable verbose logging',\n type: 'boolean' as const,\n },\n // Hidden dev/automation flags (use env vars)\n local: {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n ci: {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n 'skip-auth': {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n 'api-key': {\n type: 'string' as const,\n hidden: true,\n },\n 'client-id': {\n type: 'string' as const,\n hidden: true,\n },\n inspect: {\n default: false,\n type: 'boolean' as const,\n hidden: true,\n },\n // User-facing flags\n 'homepage-url': {\n describe: 'App homepage URL for WorkOS (defaults to http://localhost:{port})',\n type: 'string' as const,\n },\n 'redirect-uri': {\n describe: 'Redirect URI for WorkOS callback (defaults to framework convention)',\n type: 'string' as const,\n },\n 'no-validate': {\n default: false,\n describe: 'Skip post-installation validation (includes build check)',\n type: 'boolean' as const,\n },\n 'install-dir': {\n describe: 'Directory to install WorkOS AuthKit in',\n type: 'string' as const,\n },\n integration: {\n describe: 'Integration to set up',\n choices: ['nextjs', 'react', 'tanstack-start', 'react-router', 'vanilla-js'] as const,\n type: 'string' as const,\n },\n 'force-install': {\n default: false,\n describe: 'Force install packages even if peer dependency checks fail',\n type: 'boolean' as const,\n },\n dashboard: {\n alias: 'd',\n default: false,\n describe: 'Run with visual dashboard mode',\n type: 'boolean' as const,\n },\n};\n\n// Check for updates (blocks up to 500ms)\nawait checkForUpdates();\n\nyargs(hideBin(process.argv))\n .env('WORKOS_INSTALLER')\n .command('login', 'Authenticate with WorkOS', {}, async () => {\n const { runLogin } = await import('./commands/login.js');\n await runLogin();\n process.exit(0);\n })\n .command('logout', 'Remove stored credentials', {}, async () => {\n const { runLogout } = await import('./commands/logout.js');\n await runLogout();\n })\n .command(\n 'install-skill',\n 'Install bundled AuthKit skills to coding agents',\n (yargs) => {\n return yargs\n .option('list', {\n alias: 'l',\n type: 'boolean',\n description: 'List available skills without installing',\n })\n .option('skill', {\n alias: 's',\n type: 'array',\n string: true,\n description: 'Install specific skill(s)',\n })\n .option('agent', {\n alias: 'a',\n type: 'array',\n string: true,\n description: 'Target specific agent(s): claude-code, codex, cursor, goose',\n });\n },\n withAuth(async (argv) => {\n const { runInstallSkill } = await import('./commands/install-skill.js');\n await runInstallSkill({\n list: argv.list as boolean | undefined,\n skill: argv.skill as string[] | undefined,\n agent: argv.agent as string[] | undefined,\n });\n }),\n )\n .command(\n 'install',\n 'Install WorkOS AuthKit into your project',\n (yargs) => yargs.options(installerOptions),\n withAuth(async (argv) => {\n const { handleInstall } = await import('./commands/install.js');\n await handleInstall(argv);\n }),\n )\n .command(\n 'dashboard',\n false, // hidden from help\n (yargs) => yargs.options(installerOptions),\n withAuth(async (argv) => {\n const { handleInstall } = await import('./commands/install.js');\n await handleInstall({ ...argv, dashboard: true });\n }),\n )\n .command(\n ['$0'],\n 'WorkOS AuthKit CLI',\n (yargs) => yargs,\n async () => {\n // Non-TTY: show help\n if (isNonInteractiveEnvironment()) {\n yargs(hideBin(process.argv)).showHelp();\n return;\n }\n\n // TTY: ask if user wants to run installer\n const shouldInstall = await clack.confirm({\n message: 'Run the AuthKit installer?',\n });\n\n if (clack.isCancel(shouldInstall) || !shouldInstall) {\n process.exit(0);\n }\n\n // Auth check happens HERE, after user confirms\n await ensureAuthenticated();\n\n const { handleInstall } = await import('./commands/install.js');\n await handleInstall({ dashboard: false } as any);\n process.exit(0);\n },\n )\n .strict()\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY && process.stdout.columns ? process.stdout.columns : 80).argv;\n"]}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check npm registry for latest version and warn if outdated.
3
+ * Runs asynchronously, fails silently on any error.
4
+ * Safe to call without awaiting (fire-and-forget).
5
+ */
6
+ export declare function checkForUpdates(): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import { lt, valid } from 'semver';
2
+ import { yellow, dim } from '../utils/logging.js';
3
+ import { getVersion } from './settings.js';
4
+ const NPM_REGISTRY_URL = 'https://registry.npmjs.org/workos/latest';
5
+ const TIMEOUT_MS = 500;
6
+ let hasWarned = false;
7
+ /**
8
+ * Check npm registry for latest version and warn if outdated.
9
+ * Runs asynchronously, fails silently on any error.
10
+ * Safe to call without awaiting (fire-and-forget).
11
+ */
12
+ export async function checkForUpdates() {
13
+ if (hasWarned)
14
+ return;
15
+ try {
16
+ const response = await fetch(NPM_REGISTRY_URL, {
17
+ signal: AbortSignal.timeout(TIMEOUT_MS),
18
+ });
19
+ if (!response.ok)
20
+ return;
21
+ const data = (await response.json());
22
+ const latestVersion = data.version;
23
+ const currentVersion = getVersion();
24
+ // Validate both versions are valid semver
25
+ if (!valid(latestVersion) || !valid(currentVersion))
26
+ return;
27
+ // Only warn if current < latest
28
+ if (lt(currentVersion, latestVersion)) {
29
+ hasWarned = true;
30
+ yellow(`Update available: ${currentVersion} → ${latestVersion}`);
31
+ dim(`Run: npx workos@latest`);
32
+ }
33
+ }
34
+ catch {
35
+ // Silently ignore all errors (timeout, network, parse, etc.)
36
+ }
37
+ }
38
+ /**
39
+ * Reset warning state (for testing).
40
+ * @internal
41
+ */
42
+ export function _resetWarningState() {
43
+ hasWarned = false;
44
+ }
45
+ //# sourceMappingURL=version-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-check.js","sourceRoot":"","sources":["../../src/lib/version-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,gBAAgB,GAAG,0CAA0C,CAAC;AACpE,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB,IAAI,SAAS,GAAG,KAAK,CAAC;AAMtB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,SAAS;QAAE,OAAO;IAEtB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,gBAAgB,EAAE;YAC7C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC;SACxC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO;QAEzB,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;QACvD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC;QACnC,MAAM,cAAc,GAAG,UAAU,EAAE,CAAC;QAEpC,0CAA0C;QAC1C,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC;YAAE,OAAO;QAE5D,gCAAgC;QAChC,IAAI,EAAE,CAAC,cAAc,EAAE,aAAa,CAAC,EAAE,CAAC;YACtC,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM,CAAC,qBAAqB,cAAc,MAAM,aAAa,EAAE,CAAC,CAAC;YACjE,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;IAC/D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC","sourcesContent":["import { lt, valid } from 'semver';\nimport { yellow, dim } from '../utils/logging.js';\nimport { getVersion } from './settings.js';\n\nconst NPM_REGISTRY_URL = 'https://registry.npmjs.org/workos/latest';\nconst TIMEOUT_MS = 500;\n\nlet hasWarned = false;\n\ninterface NpmPackageInfo {\n version: string;\n}\n\n/**\n * Check npm registry for latest version and warn if outdated.\n * Runs asynchronously, fails silently on any error.\n * Safe to call without awaiting (fire-and-forget).\n */\nexport async function checkForUpdates(): Promise<void> {\n if (hasWarned) return;\n\n try {\n const response = await fetch(NPM_REGISTRY_URL, {\n signal: AbortSignal.timeout(TIMEOUT_MS),\n });\n\n if (!response.ok) return;\n\n const data = (await response.json()) as NpmPackageInfo;\n const latestVersion = data.version;\n const currentVersion = getVersion();\n\n // Validate both versions are valid semver\n if (!valid(latestVersion) || !valid(currentVersion)) return;\n\n // Only warn if current < latest\n if (lt(currentVersion, latestVersion)) {\n hasWarned = true;\n yellow(`Update available: ${currentVersion} → ${latestVersion}`);\n dim(`Run: npx workos@latest`);\n }\n } catch {\n // Silently ignore all errors (timeout, network, parse, etc.)\n }\n}\n\n/**\n * Reset warning state (for testing).\n * @internal\n */\nexport function _resetWarningState(): void {\n hasWarned = false;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ export interface ExecResult {
2
+ status: number;
3
+ stdout: string;
4
+ stderr: string;
5
+ }
6
+ export interface ExecOptions {
7
+ cwd?: string;
8
+ timeout?: number;
9
+ env?: NodeJS.ProcessEnv;
10
+ }
11
+ /**
12
+ * Execute a command without throwing on non-zero exit codes.
13
+ * Returns { status, stdout, stderr } for all outcomes.
14
+ */
15
+ export declare function execFileNoThrow(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
@@ -0,0 +1,38 @@
1
+ import { spawn } from 'node:child_process';
2
+ /**
3
+ * Execute a command without throwing on non-zero exit codes.
4
+ * Returns { status, stdout, stderr } for all outcomes.
5
+ */
6
+ export function execFileNoThrow(command, args, options = {}) {
7
+ return new Promise((resolve) => {
8
+ const child = spawn(command, args, {
9
+ cwd: options.cwd,
10
+ env: options.env ?? process.env,
11
+ timeout: options.timeout,
12
+ shell: false,
13
+ });
14
+ let stdout = '';
15
+ let stderr = '';
16
+ child.stdout?.on('data', (data) => {
17
+ stdout += data.toString();
18
+ });
19
+ child.stderr?.on('data', (data) => {
20
+ stderr += data.toString();
21
+ });
22
+ child.on('close', (code) => {
23
+ resolve({
24
+ status: code ?? 1,
25
+ stdout,
26
+ stderr,
27
+ });
28
+ });
29
+ child.on('error', (err) => {
30
+ resolve({
31
+ status: 1,
32
+ stdout,
33
+ stderr: err.message,
34
+ });
35
+ });
36
+ });
37
+ }
38
+ //# sourceMappingURL=exec-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-file.js","sourceRoot":"","sources":["../../src/utils/exec-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAc3C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,IAAc,EAAE,UAAuB,EAAE;IACxF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG;YAC/B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,OAAO,CAAC;gBACN,MAAM,EAAE,IAAI,IAAI,CAAC;gBACjB,MAAM;gBACN,MAAM;aACP,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,OAAO,CAAC;gBACN,MAAM,EAAE,CAAC;gBACT,MAAM;gBACN,MAAM,EAAE,GAAG,CAAC,OAAO;aACpB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { spawn } from 'node:child_process';\n\nexport interface ExecResult {\n status: number;\n stdout: string;\n stderr: string;\n}\n\nexport interface ExecOptions {\n cwd?: string;\n timeout?: number;\n env?: NodeJS.ProcessEnv;\n}\n\n/**\n * Execute a command without throwing on non-zero exit codes.\n * Returns { status, stdout, stderr } for all outcomes.\n */\nexport function execFileNoThrow(command: string, args: string[], options: ExecOptions = {}): Promise<ExecResult> {\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: options.env ?? process.env,\n timeout: options.timeout,\n shell: false,\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout?.on('data', (data) => {\n stdout += data.toString();\n });\n\n child.stderr?.on('data', (data) => {\n stderr += data.toString();\n });\n\n child.on('close', (code) => {\n resolve({\n status: code ?? 1,\n stdout,\n stderr,\n });\n });\n\n child.on('error', (err) => {\n resolve({\n status: 1,\n stdout,\n stderr: err.message,\n });\n });\n });\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workos",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "description": "The Official Workos CLI",
6
6
  "repository": {
@@ -63,6 +63,7 @@
63
63
  "@vitest/coverage-v8": "^4.0.18",
64
64
  "@vitest/ui": "^4.0.18",
65
65
  "dotenv": "^17.2.3",
66
+ "p-limit": "^7.2.0",
66
67
  "prettier": "^3.8.0",
67
68
  "tsx": "^4.20.3",
68
69
  "typescript": "^5.9.3",
@@ -86,6 +87,11 @@
86
87
  "test": "vitest run",
87
88
  "test:watch": "vitest",
88
89
  "test:coverage": "vitest run --coverage",
89
- "typecheck": "tsc --noEmit"
90
+ "typecheck": "tsc --noEmit",
91
+ "eval": "tsx tests/evals/index.ts",
92
+ "eval:history": "tsx tests/evals/index.ts history",
93
+ "eval:compare": "tsx tests/evals/index.ts compare",
94
+ "eval:logs": "tsx tests/evals/index.ts logs",
95
+ "eval:show": "tsx tests/evals/index.ts show"
90
96
  }
91
97
  }
@@ -55,6 +55,46 @@ Next.js version?
55
55
 
56
56
  Middleware/proxy code: See README for `authkitMiddleware()` export pattern.
57
57
 
58
+ ### Existing Middleware (IMPORTANT)
59
+
60
+ If `middleware.ts` already exists with custom logic (rate limiting, logging, headers, etc.), use the **`authkit()` composable function** instead of `authkitMiddleware`.
61
+
62
+ **Pattern for composing with existing middleware:**
63
+
64
+ ```typescript
65
+ import { NextRequest, NextResponse } from 'next/server';
66
+ import { authkit, handleAuthkitHeaders } from '@workos-inc/authkit-nextjs';
67
+
68
+ export default async function middleware(request: NextRequest) {
69
+ // 1. Get auth session and headers from AuthKit
70
+ const { session, headers, authorizationUrl } = await authkit(request);
71
+ const { pathname } = request.nextUrl;
72
+
73
+ // 2. === YOUR EXISTING MIDDLEWARE LOGIC ===
74
+ // Rate limiting, logging, custom headers, etc.
75
+ const rateLimitResult = checkRateLimit(request);
76
+ if (!rateLimitResult.allowed) {
77
+ return new NextResponse('Too Many Requests', { status: 429 });
78
+ }
79
+
80
+ // 3. Protect routes - redirect to auth if needed
81
+ if (pathname.startsWith('/dashboard') && !session.user && authorizationUrl) {
82
+ return handleAuthkitHeaders(request, headers, { redirect: authorizationUrl });
83
+ }
84
+
85
+ // 4. Continue with AuthKit headers properly handled
86
+ return handleAuthkitHeaders(request, headers);
87
+ }
88
+ ```
89
+
90
+ **Key functions:**
91
+
92
+ - `authkit(request)` - Returns `{ session, headers, authorizationUrl }` for composition
93
+ - `handleAuthkitHeaders(request, headers, options?)` - Ensures AuthKit headers pass through correctly
94
+ - For rewrites, use `partitionAuthkitHeaders()` and `applyResponseHeaders()` (see README)
95
+
96
+ **Critical:** Always return via `handleAuthkitHeaders()` to ensure `withAuth()` works in pages.
97
+
58
98
  ## Step 5: Create Callback Route
59
99
 
60
100
  Parse `NEXT_PUBLIC_WORKOS_REDIRECT_URI` to determine route path:
@@ -78,33 +118,58 @@ export const GET = handleAuth();
78
118
 
79
119
  Check README for exact usage. If build fails with "cookies outside request scope", the handler is likely missing async/await.
80
120
 
81
- ## Step 6: Provider Setup
121
+ ## Step 6: Provider Setup (REQUIRED)
122
+
123
+ **CRITICAL:** You MUST wrap the app in `AuthKitProvider` in `app/layout.tsx`.
124
+
125
+ This is required for:
126
+
127
+ - Client-side auth state via `useAuth()` hook
128
+ - Consistent auth UX across client/server boundaries
129
+ - Proper migration from Auth0 (which uses client-side auth)
130
+
131
+ ```tsx
132
+ // app/layout.tsx
133
+ import { AuthKitProvider } from '@workos-inc/authkit-nextjs';
134
+
135
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
136
+ return (
137
+ <html lang="en">
138
+ <body>
139
+ <AuthKitProvider>{children}</AuthKitProvider>
140
+ </body>
141
+ </html>
142
+ );
143
+ }
144
+ ```
145
+
146
+ Check README for exact import path - it may be a subpath export like `@workos-inc/authkit-nextjs/components`.
82
147
 
83
- Wrap app in `AuthKitProvider` in `app/layout.tsx`. See README for import path.
148
+ **Do NOT skip this step** even if using server-side auth patterns elsewhere.
84
149
 
85
150
  ## Step 7: UI Integration
86
151
 
87
152
  Add auth UI to `app/page.tsx` using SDK functions. See README for `getUser`, `getSignInUrl`, `signOut` usage.
88
153
 
89
- ## Verification Checklist
154
+ ## Verification Checklist (ALL MUST PASS)
90
155
 
91
- Run these commands to confirm integration:
156
+ Run these commands to confirm integration. **Do not mark complete until all pass:**
92
157
 
93
158
  ```bash
94
- # Check middleware/proxy exists (one should match)
159
+ # 1. Check middleware/proxy exists (one should match)
95
160
  ls proxy.ts middleware.ts src/proxy.ts src/middleware.ts 2>/dev/null
96
161
 
97
- # Check provider is wrapped
98
- grep -l "AuthKitProvider" app/layout.tsx
162
+ # 2. CRITICAL: Check AuthKitProvider is in layout (REQUIRED)
163
+ grep "AuthKitProvider" app/layout.tsx || echo "FAIL: AuthKitProvider missing from layout"
99
164
 
100
- # Check callback route exists
165
+ # 3. Check callback route exists
101
166
  find app -name "route.ts" -path "*/callback/*"
102
167
 
103
- # Build succeeds
168
+ # 4. Build succeeds
104
169
  npm run build
105
170
  ```
106
171
 
107
- All checks must pass before marking complete.
172
+ **If check #2 fails:** Go back to Step 6 and add AuthKitProvider. This is not optional.
108
173
 
109
174
  ## Error Recovery
110
175
 
@@ -12,9 +12,9 @@ description: Integrate WorkOS AuthKit with TanStack Start applications. Full-sta
12
12
  ├── Extract package name from install command
13
13
  └── README is source of truth for ALL code patterns
14
14
 
15
- 2. Verify TanStack Start project
16
- ├── @tanstack/start or @tanstack/react-start in package.json
17
- └── app.config.ts exists (vinxi)
15
+ 2. Detect directory structure
16
+ ├── src/ (TanStack Start v1.132+, default)
17
+ └── app/ (legacy vinxi-based projects)
18
18
 
19
19
  3. Follow README install/setup exactly
20
20
  └── Do not invent commands or patterns
@@ -28,7 +28,7 @@ WebFetch: `https://github.com/workos/authkit-tanstack-start/blob/main/README.md`
28
28
 
29
29
  From README, extract:
30
30
 
31
- 1. Package name from install command (e.g., `pnpm add @workos/...`)
31
+ 1. Package name: `@workos/authkit-tanstack-react-start`
32
32
  2. Use that exact name for all imports
33
33
 
34
34
  **README overrides this skill if conflict.**
@@ -37,9 +37,38 @@ From README, extract:
37
37
 
38
38
  - [ ] README fetched and package name extracted
39
39
  - [ ] `@tanstack/start` or `@tanstack/react-start` in package.json
40
- - [ ] `app.config.ts` exists
40
+ - [ ] Identify directory structure: `src/` (modern) or `app/` (legacy)
41
41
  - [ ] Environment variables set (see below)
42
42
 
43
+ ## Directory Structure Detection
44
+
45
+ **Modern TanStack Start (v1.132+)** uses `src/`:
46
+
47
+ ```
48
+ src/
49
+ ├── start.ts # Middleware config (CRITICAL)
50
+ ├── router.tsx # Router setup
51
+ ├── routes/
52
+ │ ├── __root.tsx # Root layout
53
+ │ ├── api.auth.callback.tsx # OAuth callback (flat route)
54
+ │ └── ...
55
+ ```
56
+
57
+ **Legacy (vinxi-based)** uses `app/`:
58
+
59
+ ```
60
+ app/
61
+ ├── start.ts or router.tsx
62
+ ├── routes/
63
+ │ └── api/auth/callback.tsx # OAuth callback (nested route)
64
+ ```
65
+
66
+ **Detection:**
67
+
68
+ ```bash
69
+ ls src/routes 2>/dev/null && echo "Modern (src/)" || echo "Legacy (app/)"
70
+ ```
71
+
43
72
  ## Environment Variables
44
73
 
45
74
  | Variable | Format | Required |
@@ -51,56 +80,184 @@ From README, extract:
51
80
 
52
81
  Generate password if missing: `openssl rand -base64 32`
53
82
 
83
+ Default redirect URI: `http://localhost:3000/api/auth/callback`
84
+
54
85
  ## Middleware Configuration (CRITICAL)
55
86
 
56
- **authkitMiddleware MUST be configured or auth will fail.**
87
+ **authkitMiddleware MUST be configured or auth will fail silently.**
57
88
 
58
- Find file with `createRouter` (typically `app/router.tsx` or `app.tsx`).
89
+ Create or update `src/start.ts` (or `app/start.ts` for legacy):
90
+
91
+ ```typescript
92
+ import { authkitMiddleware } from '@workos/authkit-tanstack-react-start';
93
+
94
+ export default {
95
+ requestMiddleware: [authkitMiddleware()],
96
+ };
97
+ ```
98
+
99
+ Alternative pattern with createStart:
100
+
101
+ ```typescript
102
+ import { createStart } from '@tanstack/react-start';
103
+ import { authkitMiddleware } from '@workos/authkit-tanstack-react-start';
104
+
105
+ export default createStart({
106
+ requestMiddleware: [authkitMiddleware()],
107
+ });
108
+ ```
59
109
 
60
110
  ### Verification Checklist
61
111
 
62
- - [ ] `authkitMiddleware` imported from SDK package
63
- - [ ] `middleware: [authkitMiddleware()]` in createRouter config
64
- - [ ] Array syntax used: `[authkitMiddleware()]` not `authkitMiddleware()`
112
+ - [ ] `authkitMiddleware` imported from `@workos/authkit-tanstack-react-start`
113
+ - [ ] Middleware in `requestMiddleware` array
114
+ - [ ] File exports the config (default export or named `startInstance`)
65
115
 
66
- Verify: `grep "authkitMiddleware" app/router.tsx app.tsx src/router.tsx`
116
+ Verify: `grep -r "authkitMiddleware" src/ app/ 2>/dev/null`
117
+
118
+ ## Callback Route (CRITICAL)
119
+
120
+ Path must match `WORKOS_REDIRECT_URI`. For `/api/auth/callback`:
121
+
122
+ **Modern (flat routes):** `src/routes/api.auth.callback.tsx`
123
+ **Legacy (nested routes):** `app/routes/api/auth/callback.tsx`
124
+
125
+ ```typescript
126
+ import { createFileRoute } from '@tanstack/react-router';
127
+ import { handleCallbackRoute } from '@workos/authkit-tanstack-react-start';
128
+
129
+ export const Route = createFileRoute('/api/auth/callback')({
130
+ server: {
131
+ handlers: {
132
+ GET: handleCallbackRoute(),
133
+ },
134
+ },
135
+ });
136
+ ```
67
137
 
68
- ## Logout Route Pattern
138
+ **Key points:**
69
139
 
70
- Logout requires `signOut()` followed by redirect in a route loader. See README for exact implementation.
140
+ - Use `handleCallbackRoute()` - do not write custom OAuth logic
141
+ - Route path string must match the URI path exactly
142
+ - This is a server-only route (no component needed)
71
143
 
72
- ## Callback Route
144
+ ## Protected Routes
73
145
 
74
- Path must match `WORKOS_REDIRECT_URI`. If URI is `/api/auth/callback`:
146
+ Use `getAuth()` in route loaders to check authentication:
75
147
 
76
- - File: `app/routes/api/auth/callback.tsx`
77
- - Use `handleAuth()` from SDK - do not write custom OAuth logic
148
+ ```typescript
149
+ import { createFileRoute, redirect } from '@tanstack/react-router';
150
+ import { getAuth, getSignInUrl } from '@workos/authkit-tanstack-react-start';
151
+
152
+ export const Route = createFileRoute('/dashboard')({
153
+ loader: async () => {
154
+ const { user } = await getAuth();
155
+ if (!user) {
156
+ const signInUrl = await getSignInUrl();
157
+ throw redirect({ href: signInUrl });
158
+ }
159
+ return { user };
160
+ },
161
+ component: Dashboard,
162
+ });
163
+ ```
164
+
165
+ ## Sign Out Route
166
+
167
+ ```typescript
168
+ import { createFileRoute, redirect } from '@tanstack/react-router';
169
+ import { signOut } from '@workos/authkit-tanstack-react-start';
170
+
171
+ export const Route = createFileRoute('/signout')({
172
+ loader: async () => {
173
+ await signOut();
174
+ throw redirect({ href: '/' });
175
+ },
176
+ });
177
+ ```
178
+
179
+ ## Client-Side Hooks (Optional)
180
+
181
+ Only needed if you want reactive auth state in components.
182
+
183
+ **1. Add AuthKitProvider to root:**
184
+
185
+ ```typescript
186
+ // src/routes/__root.tsx
187
+ import { AuthKitProvider } from '@workos/authkit-tanstack-react-start/client';
188
+
189
+ function RootComponent() {
190
+ return (
191
+ <AuthKitProvider>
192
+ <Outlet />
193
+ </AuthKitProvider>
194
+ );
195
+ }
196
+ ```
197
+
198
+ **2. Use hooks in components:**
199
+
200
+ ```typescript
201
+ import { useAuth } from '@workos/authkit-tanstack-react-start/client';
202
+
203
+ function Profile() {
204
+ const { user, isLoading } = useAuth();
205
+ // ...
206
+ }
207
+ ```
208
+
209
+ **Note:** Server-side `getAuth()` is preferred for most use cases.
78
210
 
79
211
  ## Error Recovery
80
212
 
81
213
  ### "AuthKit middleware is not configured"
82
214
 
83
- **Cause:** `authkitMiddleware()` not added to router
84
- **Fix:** Add `middleware: [authkitMiddleware()]` to createRouter config
85
- **Verify:** `grep "authkitMiddleware" app/router.tsx app.tsx`
215
+ **Cause:** `authkitMiddleware()` not in start.ts
216
+ **Fix:** Create/update `src/start.ts` with middleware config
217
+ **Verify:** `grep -r "authkitMiddleware" src/`
86
218
 
87
219
  ### "Module not found" for SDK
88
220
 
89
221
  **Cause:** Wrong package name or not installed
90
- **Fix:** Re-read README, extract correct package name, reinstall
91
- **Verify:** `ls node_modules/` + package name from README
222
+ **Fix:** `pnpm add @workos/authkit-tanstack-react-start`
223
+ **Verify:** `ls node_modules/@workos/authkit-tanstack-react-start`
92
224
 
93
225
  ### Callback 404
94
226
 
95
- **Cause:** Route path doesn't match WORKOS_REDIRECT_URI
96
- **Fix:** File path must mirror URI path under `app/routes/`
227
+ **Cause:** Route file path doesn't match WORKOS_REDIRECT_URI
228
+ **Fix:**
229
+
230
+ - URI `/api/auth/callback` → file `src/routes/api.auth.callback.tsx` (flat) or `app/routes/api/auth/callback.tsx` (nested)
231
+ - Route path string in `createFileRoute()` must match exactly
97
232
 
98
- ### getAuth returns undefined
233
+ ### getAuth returns undefined user
99
234
 
100
- **Cause:** Middleware not configured
101
- **Fix:** Same as "AuthKit middleware not configured" above
235
+ **Cause:** Middleware not configured or not running
236
+ **Fix:** Ensure `authkitMiddleware()` is in start.ts requestMiddleware array
102
237
 
103
238
  ### "Cookie password too short"
104
239
 
105
240
  **Cause:** WORKOS_COOKIE_PASSWORD < 32 chars
106
241
  **Fix:** `openssl rand -base64 32`, update .env
242
+
243
+ ### Build fails with route type errors
244
+
245
+ **Cause:** Route tree not regenerated after adding routes
246
+ **Fix:** `pnpm dev` to regenerate `routeTree.gen.ts`
247
+
248
+ ## SDK Exports Reference
249
+
250
+ **Server (main export):**
251
+
252
+ - `authkitMiddleware()` - Request middleware
253
+ - `handleCallbackRoute()` - OAuth callback handler
254
+ - `getAuth()` - Get current session
255
+ - `signOut()` - Sign out user
256
+ - `getSignInUrl()` / `getSignUpUrl()` - Auth URLs
257
+ - `switchToOrganization()` - Change org context
258
+
259
+ **Client (`/client` subpath):**
260
+
261
+ - `AuthKitProvider` - Context provider
262
+ - `useAuth()` - Auth state hook
263
+ - `useAccessToken()` - Token management