@keywaysh/cli 0.1.10 → 0.1.12

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 (2) hide show
  1. package/dist/cli.js +118 -37
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -101,7 +101,7 @@ var INTERNAL_POSTHOG_HOST = "https://eu.i.posthog.com";
101
101
  // package.json
102
102
  var package_default = {
103
103
  name: "@keywaysh/cli",
104
- version: "0.1.10",
104
+ version: "0.1.12",
105
105
  description: "One link to all your secrets",
106
106
  type: "module",
107
107
  bin: {
@@ -409,9 +409,10 @@ async function deleteConnection(accessToken, connectionId) {
409
409
  });
410
410
  await handleResponse(response);
411
411
  }
412
- function getProviderAuthUrl(provider, redirectUri) {
413
- const params = redirectUri ? `?redirect_uri=${encodeURIComponent(redirectUri)}` : "";
414
- return `${API_BASE_URL}/v1/integrations/${provider}/authorize${params}`;
412
+ function getProviderAuthUrl(provider, accessToken, redirectUri) {
413
+ const params = new URLSearchParams({ token: accessToken });
414
+ if (redirectUri) params.set("redirect_uri", redirectUri);
415
+ return `${API_BASE_URL}/v1/integrations/${provider}/authorize?${params}`;
415
416
  }
416
417
  async function getConnectionProjects(accessToken, connectionId) {
417
418
  const response = await fetchWithTimeout(`${API_BASE_URL}/v1/integrations/connections/${connectionId}/projects`, {
@@ -1312,23 +1313,20 @@ async function ensureLoginAndGitHubApp(repoFullName, options = {}) {
1312
1313
  if (!allowPrompt || !isInteractive()) {
1313
1314
  throw new Error('No Keyway session found. Run "keyway login" to authenticate.');
1314
1315
  }
1315
- console.log("");
1316
- console.log(pc6.gray(" Keyway uses a GitHub App for secure access."));
1317
- console.log(pc6.gray(" Installing the app will also log you in."));
1316
+ const deviceStart = await startDeviceLogin(repoFullName);
1317
+ const installUrl = deviceStart.githubAppInstallUrl || "https://github.com/apps/keyway/installations/new";
1318
1318
  console.log("");
1319
1319
  const { shouldProceed } = await prompts4({
1320
1320
  type: "confirm",
1321
1321
  name: "shouldProceed",
1322
- message: "Open browser to install Keyway & sign in?",
1322
+ message: "Open browser to sign in?",
1323
1323
  initial: true
1324
1324
  });
1325
1325
  if (!shouldProceed) {
1326
1326
  throw new Error('Setup required. Run "keyway init" when ready.');
1327
1327
  }
1328
- const deviceStart = await startDeviceLogin(repoFullName);
1329
- const installUrl = deviceStart.githubAppInstallUrl || "https://github.com/apps/keyway/installations/new";
1330
- await openUrl(installUrl);
1331
- console.log(pc6.blue("\u23F3 Waiting for installation & authorization..."));
1328
+ await openUrl(deviceStart.verificationUriComplete);
1329
+ console.log(pc6.blue("\u23F3 Waiting for authorization..."));
1332
1330
  console.log(pc6.gray(" (Press Ctrl+C to cancel)\n"));
1333
1331
  const pollIntervalMs = Math.max((deviceStart.interval ?? 5) * 1e3, POLL_INTERVAL_MS);
1334
1332
  const startTime = Date.now();
@@ -1337,30 +1335,73 @@ async function ensureLoginAndGitHubApp(repoFullName, options = {}) {
1337
1335
  while (Date.now() - startTime < POLL_TIMEOUT_MS) {
1338
1336
  await sleep(pollIntervalMs);
1339
1337
  try {
1340
- if (!accessToken) {
1341
- const result = await pollDeviceLogin(deviceStart.deviceCode);
1342
- if (result.status === "approved" && result.keywayToken) {
1343
- accessToken = result.keywayToken;
1344
- await saveAuthToken(result.keywayToken, {
1345
- githubLogin: result.githubLogin,
1346
- expiresAt: result.expiresAt
1338
+ const result = await pollDeviceLogin(deviceStart.deviceCode);
1339
+ if (result.status === "approved" && result.keywayToken) {
1340
+ accessToken = result.keywayToken;
1341
+ await saveAuthToken(result.keywayToken, {
1342
+ githubLogin: result.githubLogin,
1343
+ expiresAt: result.expiresAt
1344
+ });
1345
+ console.log(pc6.green("\u2713 Signed in!"));
1346
+ if (result.githubLogin) {
1347
+ identifyUser(result.githubLogin, {
1348
+ github_username: result.githubLogin,
1349
+ login_method: "device_flow"
1347
1350
  });
1348
- console.log(pc6.green("\u2713 Signed in!"));
1349
- if (result.githubLogin) {
1350
- identifyUser(result.githubLogin, {
1351
- github_username: result.githubLogin,
1352
- login_method: "github_app"
1353
- });
1354
- }
1355
1351
  }
1352
+ break;
1356
1353
  }
1357
- if (accessToken) {
1358
- const installStatus = await checkGitHubAppInstallation(repoOwner, repoName, accessToken);
1359
- if (installStatus.installed) {
1360
- console.log(pc6.green("\u2713 GitHub App installed!"));
1361
- console.log("");
1362
- return accessToken;
1363
- }
1354
+ consecutiveErrors = 0;
1355
+ process.stdout.write(pc6.gray("."));
1356
+ } catch (error) {
1357
+ consecutiveErrors++;
1358
+ if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
1359
+ const errorMsg = error instanceof Error ? error.message : "Unknown error";
1360
+ throw new Error(`Login failed after ${MAX_CONSECUTIVE_ERRORS} consecutive errors: ${errorMsg}`);
1361
+ }
1362
+ }
1363
+ }
1364
+ if (!accessToken) {
1365
+ console.log("");
1366
+ console.log(pc6.yellow("\u26A0 Timed out waiting for sign in."));
1367
+ throw new Error("Sign in timed out. Please try again.");
1368
+ }
1369
+ const installStatus = await checkGitHubAppInstallation(repoOwner, repoName, accessToken);
1370
+ if (installStatus.installed) {
1371
+ console.log(pc6.green("\u2713 GitHub App installed"));
1372
+ console.log("");
1373
+ return accessToken;
1374
+ }
1375
+ console.log("");
1376
+ console.log(pc6.yellow("\u26A0 GitHub App not installed on this repository"));
1377
+ console.log(pc6.gray(" The Keyway GitHub App is required for secure access."));
1378
+ console.log("");
1379
+ const { shouldInstall } = await prompts4({
1380
+ type: "confirm",
1381
+ name: "shouldInstall",
1382
+ message: "Open browser to install GitHub App?",
1383
+ initial: true
1384
+ });
1385
+ if (!shouldInstall) {
1386
+ console.log(pc6.gray(`
1387
+ Install later: ${installUrl}`));
1388
+ throw new Error("GitHub App installation required.");
1389
+ }
1390
+ await openUrl(installUrl);
1391
+ console.log(pc6.blue("\u23F3 Waiting for GitHub App installation..."));
1392
+ console.log(pc6.gray(' Add this repository and click "Install"'));
1393
+ console.log(pc6.gray(" Then return here - the CLI will detect it automatically"));
1394
+ console.log(pc6.gray(" (Press Ctrl+C to cancel)\n"));
1395
+ const installStartTime = Date.now();
1396
+ consecutiveErrors = 0;
1397
+ while (Date.now() - installStartTime < POLL_TIMEOUT_MS) {
1398
+ await sleep(POLL_INTERVAL_MS);
1399
+ try {
1400
+ const pollStatus = await checkGitHubAppInstallation(repoOwner, repoName, accessToken);
1401
+ if (pollStatus.installed) {
1402
+ console.log(pc6.green("\u2713 GitHub App installed!"));
1403
+ console.log("");
1404
+ return accessToken;
1364
1405
  }
1365
1406
  consecutiveErrors = 0;
1366
1407
  process.stdout.write(pc6.gray("."));
@@ -1368,14 +1409,14 @@ async function ensureLoginAndGitHubApp(repoFullName, options = {}) {
1368
1409
  consecutiveErrors++;
1369
1410
  if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
1370
1411
  const errorMsg = error instanceof Error ? error.message : "Unknown error";
1371
- throw new Error(`Setup failed after ${MAX_CONSECUTIVE_ERRORS} consecutive errors: ${errorMsg}`);
1412
+ throw new Error(`Installation check failed after ${MAX_CONSECUTIVE_ERRORS} consecutive errors: ${errorMsg}`);
1372
1413
  }
1373
1414
  }
1374
1415
  }
1375
1416
  console.log("");
1376
- console.log(pc6.yellow("\u26A0 Timed out waiting for setup."));
1417
+ console.log(pc6.yellow("\u26A0 Timed out waiting for installation."));
1377
1418
  console.log(pc6.gray(` Install the GitHub App: ${installUrl}`));
1378
- throw new Error("Setup timed out. Please try again.");
1419
+ throw new Error("GitHub App installation timed out.");
1379
1420
  }
1380
1421
  async function ensureGitHubAppInstalledOnly(repoFullName, accessToken) {
1381
1422
  const [repoOwner, repoName] = repoFullName.split("/");
@@ -1970,7 +2011,7 @@ async function connectWithTokenFlow(accessToken, provider, displayName) {
1970
2011
  }
1971
2012
  }
1972
2013
  async function connectWithOAuthFlow(accessToken, provider, displayName) {
1973
- const authUrl = getProviderAuthUrl(provider);
2014
+ const authUrl = getProviderAuthUrl(provider, accessToken);
1974
2015
  const startTime = /* @__PURE__ */ new Date();
1975
2016
  await openUrl(authUrl);
1976
2017
  console.log(pc9.gray("Waiting for authorization..."));
@@ -2136,12 +2177,24 @@ function mapToRailwayEnvironment(keywayEnv) {
2136
2177
  };
2137
2178
  return mapping[keywayEnv.toLowerCase()] || "production";
2138
2179
  }
2180
+ function mapToNetlifyEnvironment(keywayEnv) {
2181
+ const mapping = {
2182
+ production: "production",
2183
+ staging: "branch-deploy",
2184
+ preview: "deploy-preview",
2185
+ dev: "dev",
2186
+ development: "dev"
2187
+ };
2188
+ return mapping[keywayEnv.toLowerCase()] || "production";
2189
+ }
2139
2190
  function mapToProviderEnvironment(provider, keywayEnv) {
2140
2191
  switch (provider.toLowerCase()) {
2141
2192
  case "vercel":
2142
2193
  return mapToVercelEnvironment(keywayEnv);
2143
2194
  case "railway":
2144
2195
  return mapToRailwayEnvironment(keywayEnv);
2196
+ case "netlify":
2197
+ return mapToNetlifyEnvironment(keywayEnv);
2145
2198
  default:
2146
2199
  return keywayEnv;
2147
2200
  }
@@ -2263,6 +2316,32 @@ async function syncCommand(provider, options = {}) {
2263
2316
  process.exit(1);
2264
2317
  }
2265
2318
  console.log(pc10.gray(`Repository: ${repoFullName}`));
2319
+ const vaultExists = await checkVaultExists(accessToken, repoFullName);
2320
+ if (!vaultExists) {
2321
+ console.log(pc10.yellow(`
2322
+ No vault found for ${repoFullName}.`));
2323
+ const { shouldCreate } = await prompts7({
2324
+ type: "confirm",
2325
+ name: "shouldCreate",
2326
+ message: "Create vault now?",
2327
+ initial: true
2328
+ });
2329
+ if (!shouldCreate) {
2330
+ console.log(pc10.gray("Cancelled. Run `keyway init` to create a vault first."));
2331
+ process.exit(0);
2332
+ }
2333
+ console.log(pc10.gray("\nCreating vault..."));
2334
+ try {
2335
+ await initVault(repoFullName, accessToken);
2336
+ console.log(pc10.green(`\u2713 Vault created for ${repoFullName}
2337
+ `));
2338
+ } catch (error) {
2339
+ const message = error instanceof Error ? error.message : "Failed to create vault";
2340
+ console.error(pc10.red(`
2341
+ \u2717 ${message}`));
2342
+ process.exit(1);
2343
+ }
2344
+ }
2266
2345
  let { connections } = await getConnections(accessToken);
2267
2346
  let connection = connections.find((c) => c.provider === provider.toLowerCase());
2268
2347
  if (!connection) {
@@ -2556,6 +2635,8 @@ async function executeSyncOperation(accessToken, repoFullName, connectionId, pro
2556
2635
  const preview = await getSyncPreview(accessToken, repoFullName, {
2557
2636
  connectionId,
2558
2637
  projectId: project.id,
2638
+ serviceId: project.serviceId,
2639
+ // Railway: service ID for service-specific variables
2559
2640
  keywayEnvironment: keywayEnv,
2560
2641
  providerEnvironment: providerEnv,
2561
2642
  direction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keywaysh/cli",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "One link to all your secrets",
5
5
  "type": "module",
6
6
  "bin": {