oauth-init 1.0.0 → 1.1.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.
Files changed (3) hide show
  1. package/README.md +3 -0
  2. package/dist/index.js +181 -5
  3. package/package.json +4 -2
package/README.md CHANGED
@@ -47,6 +47,9 @@ The CLI will:
47
47
  |----------|------------|
48
48
  | Google | OAuth 2.0 (External) |
49
49
  | GitHub | OAuth App, GitHub App |
50
+ | Discord | OAuth 2.0 |
51
+ | GitLab | OAuth 2.0 |
52
+ | Vercel | OAuth Token |
50
53
 
51
54
  ## Tech Stack
52
55
 
package/dist/index.js CHANGED
@@ -10221,6 +10221,159 @@ ${callbackUrl}`, "Save this URL");
10221
10221
  }
10222
10222
  }
10223
10223
 
10224
+ // src/lib/providers/vercel.ts
10225
+ init_dist2();
10226
+ function logStep5(message) {
10227
+ if (!globalConfig.quiet)
10228
+ R2.step(message);
10229
+ }
10230
+ function logInfo2(message) {
10231
+ if (!globalConfig.quiet)
10232
+ R2.info(message);
10233
+ }
10234
+ function logMessage5(message) {
10235
+ if (!globalConfig.quiet)
10236
+ R2.message(message);
10237
+ }
10238
+ async function checkVercelCLI() {
10239
+ const s = bt2();
10240
+ s.start("Checking Vercel CLI...");
10241
+ try {
10242
+ await execa("vercel", ["--version"]);
10243
+ } catch {
10244
+ s.stop("Vercel CLI not found.");
10245
+ R2.error(`Vercel CLI is required for Vercel OAuth setup.
10246
+ ` + `Install it: npm i -g vercel
10247
+ ` + "Then run: vercel login");
10248
+ return false;
10249
+ }
10250
+ s.stop("Vercel CLI found.");
10251
+ return true;
10252
+ }
10253
+ async function checkVercelAuth() {
10254
+ const authSpinner = bt2();
10255
+ authSpinner.start("Checking Vercel authentication...");
10256
+ try {
10257
+ const { stdout } = await execa("vercel", ["whoami"]);
10258
+ if (!stdout.trim()) {
10259
+ authSpinner.stop("Not authenticated.");
10260
+ return { authenticated: false };
10261
+ }
10262
+ authSpinner.stop(`Logged in as: ${stdout.trim()}`);
10263
+ return { authenticated: true, user: stdout.trim() };
10264
+ } catch {
10265
+ authSpinner.stop("Not authenticated.");
10266
+ return { authenticated: false };
10267
+ }
10268
+ }
10269
+ async function getVercelTeams() {
10270
+ const loadingSpinner = bt2();
10271
+ loadingSpinner.start("Fetching Vercel teams...");
10272
+ try {
10273
+ const { stdout, stderr } = await execa("vercel", ["teams", "ls", "--format", "json"]);
10274
+ const teamsJson = JSON.parse(stdout);
10275
+ const teams = teamsJson.teams.map((team) => ({
10276
+ name: team.name,
10277
+ slug: team.slug
10278
+ }));
10279
+ loadingSpinner.stop("Fetched teams.");
10280
+ return teams;
10281
+ } catch (stderr) {
10282
+ loadingSpinner.stop("No teams found or not a team member. " + stderr);
10283
+ return [];
10284
+ }
10285
+ }
10286
+
10287
+ class VercelAuthProvider {
10288
+ async run(_appName) {
10289
+ try {
10290
+ const isCLIInstalled = await checkVercelCLI();
10291
+ if (!isCLIInstalled) {
10292
+ R2.error("Please install Vercel CLI and authenticate before continuing.");
10293
+ process.exit(1);
10294
+ }
10295
+ const auth = await checkVercelAuth();
10296
+ if (!auth.authenticated) {
10297
+ R2.error("Please run: vercel login");
10298
+ process.exit(1);
10299
+ }
10300
+ const teams = await getVercelTeams();
10301
+ let selectedTeam;
10302
+ if (teams.length === 0) {
10303
+ R2.error("No teams found. Please ensure you have a Vercel team or personal account.");
10304
+ process.exit(1);
10305
+ } else if (teams.length === 1) {
10306
+ selectedTeam = teams[0];
10307
+ logInfo2(`Using team: ${selectedTeam.name}`);
10308
+ } else {
10309
+ const teamId = await Je({
10310
+ message: "Select your team",
10311
+ options: teams.map((team) => ({
10312
+ label: team.name,
10313
+ value: team.slug
10314
+ }))
10315
+ });
10316
+ selectedTeam = { name: teamId, slug: teamId };
10317
+ }
10318
+ const teamSlug = selectedTeam.slug;
10319
+ const appsUrl = teamSlug ? `https://vercel.com/${teamSlug}/~/settings/apps` : `https://vercel.com/settings/apps`;
10320
+ logStep5("Step 1: Create Vercel OAuth App");
10321
+ logMessage5("Create an App in your Vercel dashboard to get OAuth credentials.");
10322
+ Ve(`Required Authorization Callback URL:
10323
+ ${_appName}`, "Save this URL");
10324
+ if (!globalConfig.noOpen) {
10325
+ const shouldOpen = globalConfig.skipPrompts ? true : await Re({
10326
+ message: "Open Vercel Apps settings page?",
10327
+ initialValue: true
10328
+ });
10329
+ if (Ct(shouldOpen))
10330
+ return Ne("Setup aborted.");
10331
+ if (shouldOpen)
10332
+ await open_default(appsUrl);
10333
+ }
10334
+ if (!globalConfig.skipPrompts) {
10335
+ Ve(`1. Go to ${appsUrl}
10336
+ 2. Click 'Create' to create a new App
10337
+ 3. Enter Name and Slug for your app
10338
+ 4. Configure Authorization Callback URL (use the URL above)
10339
+ 5. Choose client authentication method
10340
+ 6. Click Save
10341
+ 7. Go to authentication tab, scroll down and generate secret`, "Action Required");
10342
+ await Ze({
10343
+ message: "Press Enter once you've created the app and generated a client secret (or type 'skip' if done previously)"
10344
+ });
10345
+ }
10346
+ logStep5("Step 2: Enter Vercel OAuth Credentials");
10347
+ let clientId;
10348
+ let clientSecret;
10349
+ if (globalConfig.skipPrompts) {
10350
+ R2.error("Client ID and Secret required in non-interactive mode. Run without --skip-prompts");
10351
+ process.exit(1);
10352
+ }
10353
+ clientId = await Ze({
10354
+ message: "Paste your Vercel Client ID:",
10355
+ placeholder: "your_client_id",
10356
+ validate: (value) => value && value.length > 0 ? undefined : "Client ID is required"
10357
+ });
10358
+ if (Ct(clientId))
10359
+ return Ne("Setup aborted.");
10360
+ clientSecret = await He({
10361
+ message: "Paste your Vercel Client Secret:"
10362
+ });
10363
+ if (Ct(clientSecret))
10364
+ return Ne("Setup aborted.");
10365
+ logStep5("Step 3: Save credentials");
10366
+ const saveOption = await askSaveOption();
10367
+ if (Ct(saveOption))
10368
+ return Ne("Setup aborted.");
10369
+ await saveCredentials(clientId, clientSecret, "vercel", saveOption);
10370
+ } catch (err) {
10371
+ R2.error(`Setup Failed: ${err.message}`);
10372
+ process.exit(1);
10373
+ }
10374
+ }
10375
+ }
10376
+
10224
10377
  // src/index.ts
10225
10378
  var AUTH_LIBRARIES = [
10226
10379
  { name: "next-auth", callbackPattern: "/api/auth/callback/[provider]" },
@@ -10280,7 +10433,15 @@ GitLab OAuth Setup:
10280
10433
  1. Requires GitLab.com or GitLab Self-Managed
10281
10434
  2. Redirect URI: http://localhost:3000/api/auth/callback/gitlab
10282
10435
  3. Need: Application ID and Client Secret from GitLab Applications
10283
- 4. Supports user-owned, group-owned, or instance-wide apps`
10436
+ 4. Supports user-owned, group-owned, or instance-wide apps`,
10437
+ vercel: `
10438
+ Vercel OAuth Setup:
10439
+ 1. Uses Vercel CLI to list your teams and open the correct settings page
10440
+ 2. Requires: npm i -g vercel and vercel login
10441
+ 3. Configure Authorization Callback URL: http://localhost:3000/api/auth/callback/vercel
10442
+ 4. Generate a Client Secret in your app settings
10443
+ 5. Get the Client ID from your app settings
10444
+ 6. For better-auth: https://www.better-auth.com/docs/plugins/oauth#vercel`
10284
10445
  };
10285
10446
  function showProviderHelp(provider) {
10286
10447
  const help = PROVIDER_HELP[provider.toLowerCase()];
@@ -10356,6 +10517,19 @@ async function setupOAuthServices(oauthServices, customCallbackUrl) {
10356
10517
  }
10357
10518
  const gitlabProvider = new GitLabAuthProvider;
10358
10519
  await gitlabProvider.run(gitlabOauthCallback);
10520
+ } else if (service === "vercel") {
10521
+ R2.step("Vercel OAuth Setup");
10522
+ const vercelOauthCallback = globalConfig.skipPrompts ? defaultCallback : await Ze({
10523
+ message: "Enter the Vercel OAuth callback URL:",
10524
+ placeholder: defaultCallback,
10525
+ defaultValue: defaultCallback
10526
+ });
10527
+ if (Ct(vercelOauthCallback)) {
10528
+ Ne("Setup aborted.");
10529
+ return;
10530
+ }
10531
+ const vercelProvider = new VercelAuthProvider;
10532
+ await vercelProvider.run(vercelOauthCallback);
10359
10533
  }
10360
10534
  }
10361
10535
  Le("OAuth setup completed! Thank you for using oauth-init!");
@@ -10371,7 +10545,7 @@ async function main() {
10371
10545
  callbackUrl: args.find((arg) => arg.startsWith("--callback-url="))?.split("=")[1] || args.find((arg) => arg.startsWith("-c="))?.split("=")[1]
10372
10546
  };
10373
10547
  const providerArg = args.find((arg) => !arg.startsWith("-"));
10374
- if (providerArg && (providerArg === "google" || providerArg === "github" || providerArg === "discord" || providerArg === "gitlab")) {
10548
+ if (providerArg && (providerArg === "google" || providerArg === "github" || providerArg === "discord" || providerArg === "gitlab" || providerArg === "vercel")) {
10375
10549
  showProviderHelp(providerArg);
10376
10550
  }
10377
10551
  if (flags.help) {
@@ -10383,7 +10557,7 @@ Options:
10383
10557
  -q, --quiet Reduce output verbosity
10384
10558
  -n, --no-open Don't open browser URLs automatically
10385
10559
  -y, --skip-prompts Use default options (for CI/CD)
10386
- -p, --provider= Specify providers (comma-separated): google,github,discord
10560
+ -p, --provider= Specify providers (comma-separated): google,github,discord,gitlab,vercel
10387
10561
  -c, --callback-url= Base callback URL (default: http://localhost:3000)
10388
10562
 
10389
10563
  Examples:
@@ -10398,7 +10572,7 @@ Examples:
10398
10572
  process.exit(0);
10399
10573
  }
10400
10574
  if (flags.provider) {
10401
- const validProviders = ["google", "github", "discord", "gitlab"];
10575
+ const validProviders = ["google", "github", "discord", "gitlab", "vercel"];
10402
10576
  const providers = flags.provider.split(",").map((p) => p.trim().toLowerCase());
10403
10577
  const invalid = providers.filter((p) => !validProviders.includes(p));
10404
10578
  if (invalid.length > 0) {
@@ -10441,7 +10615,9 @@ Examples:
10441
10615
  { value: "google", label: "Google" },
10442
10616
  { value: "github", label: "Github" },
10443
10617
  { value: "discord", label: "Discord" },
10444
- { value: "gitlab", label: "GitLab" }
10618
+ { value: "gitlab", label: "GitLab" },
10619
+ { value: "vercel", label: "Vercel" },
10620
+ { value: "microsoft", label: "Microsoft", disabled: true, hint: "Coming soon" }
10445
10621
  ]
10446
10622
  });
10447
10623
  if (Ct(oauthToSetup)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oauth-init",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "CLI for setting up OAuth providers for your project",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,7 +27,9 @@
27
27
  "setup",
28
28
  "interactive",
29
29
  "bun",
30
- "typescript"
30
+ "typescript",
31
+ "vercel",
32
+ "gitlab"
31
33
  ],
32
34
  "dependencies": {
33
35
  "@clack/prompts": "^1.0.1",