@anvil-works/anvil-cli 0.6.3 → 0.7.0-canary.1

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/index.js CHANGED
@@ -1,7 +1,4 @@
1
1
  /*! For license information please see index.js.LICENSE.txt */
2
- const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
3
- return 'undefined' == typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
4
- }();
5
2
  var __webpack_modules__ = {
6
3
  "./node_modules/.pnpm/@kwsites+file-exists@1.1.1/node_modules/@kwsites/file-exists/dist/index.js" (__unused_rspack_module, exports1, __webpack_require__) {
7
4
  "use strict";
@@ -31355,13 +31352,13 @@ var __webpack_exports__ = {};
31355
31352
  requestDeviceAuthorization: ()=>requestDeviceAuthorization,
31356
31353
  validateAnvilApp: ()=>validation_validateAnvilApp,
31357
31354
  getGitPushUrl: ()=>anvil_api_getGitPushUrl,
31355
+ setAuthTokensForAccount: ()=>setAccountTokens,
31358
31356
  ValidateAppIdResponse: ()=>anvil_api_namespaceObject.ValidateAppIdResponse,
31359
31357
  formatValidationPath: ()=>formatValidationPath,
31360
31358
  resolveAnvilUrl: ()=>resolveAnvilUrl,
31361
31359
  parseCheckoutInput: ()=>parseCheckoutInput,
31362
- login: ()=>login,
31360
+ login: ()=>auth_login,
31363
31361
  resetConfig: ()=>resetConfig,
31364
- resolveCheckoutUsername: ()=>resolveCheckoutUsername,
31365
31362
  detectAppIdsByCommitLookup: ()=>anvil_api_detectAppIdsByCommitLookup,
31366
31363
  FormTemplateValidationResult: ()=>validators_namespaceObject.FormTemplateValidationResult,
31367
31364
  ValidationTarget: ()=>validators_namespaceObject.ValidationTarget,
@@ -31373,15 +31370,13 @@ var __webpack_exports__ = {};
31373
31370
  CheckoutAppListItem: ()=>anvil_api_namespaceObject.CheckoutAppListItem,
31374
31371
  getConfig: ()=>config_getConfig,
31375
31372
  CheckoutExecutionDeps: ()=>checkout_namespaceObject.CheckoutExecutionDeps,
31376
- openPathInEditorOrDefault: ()=>checkout_openPathInEditorOrDefault,
31373
+ ValidateBranchSyncStatusOptions: ()=>validation_namespaceObject.ValidateBranchSyncStatusOptions,
31377
31374
  BranchSyncStatus: ()=>validation_namespaceObject.BranchSyncStatus,
31378
31375
  getLatestVersion: ()=>getLatestVersion,
31379
31376
  isDirectoryNonEmpty: ()=>isDirectoryNonEmpty,
31380
31377
  syncToLatest: ()=>src_api_syncToLatest,
31381
31378
  filterCandidates: ()=>anvil_api_filterCandidates,
31382
- runInteractiveLoginFlow: ()=>runInteractiveLoginFlow,
31383
31379
  CheckoutOptions: ()=>checkout_namespaceObject.CheckoutOptions,
31384
- ensureCheckoutAuthToken: ()=>ensureCheckoutAuthToken,
31385
31380
  isPathInsideGitRepo: ()=>isPathInsideGitRepo,
31386
31381
  normalizeAnvilUrl: ()=>config_normalizeAnvilUrl,
31387
31382
  ValidationIssue: ()=>validators_namespaceObject.ValidationIssue,
@@ -31404,20 +31399,21 @@ var __webpack_exports__ = {};
31404
31399
  detectAppIdsFromAllRemotes: ()=>anvil_api_detectAppIdsFromAllRemotes,
31405
31400
  getWebSocketUrl: ()=>getWebSocketUrl,
31406
31401
  getAllConfig: ()=>getAllConfig,
31407
- isCommandAvailable: ()=>isCommandAvailable,
31402
+ isCommandAvailable: ()=>config_isCommandAvailable,
31408
31403
  validateAppId: ()=>anvil_api_validateAppId,
31409
31404
  pollDeviceAuthorization: ()=>pollDeviceAuthorization,
31410
31405
  getValidAuthToken: ()=>auth_getValidAuthToken,
31411
31406
  watch: ()=>src_api_watch,
31412
31407
  deleteConfig: ()=>deleteConfig,
31413
31408
  getGitFetchUrl: ()=>anvil_api_getGitFetchUrl,
31414
- resolveCheckoutUrl: ()=>resolveCheckoutUrl,
31415
31409
  PreferredEditor: ()=>config_namespaceObject.PreferredEditor,
31416
31410
  getAvailableAnvilUrls: ()=>getAvailableAnvilUrls,
31417
31411
  validateAnvilYaml: ()=>validateAnvilYaml,
31418
31412
  CheckoutCloneOptions: ()=>checkout_namespaceObject.CheckoutCloneOptions,
31413
+ ANVIL_SYNC_CLIENT_ID: ()=>ANVIL_SYNC_CLIENT_ID,
31419
31414
  formatCandidateLabel: ()=>anvil_api_formatCandidateLabel,
31420
31415
  StoredTokens: ()=>auth_namespaceObject.StoredTokens,
31416
+ CheckoutResult: ()=>checkout_namespaceObject.CheckoutResult,
31421
31417
  ParsedCheckoutInput: ()=>checkout_namespaceObject.ParsedCheckoutInput,
31422
31418
  getDefaultDestinationDirectory: ()=>getDefaultDestinationDirectory,
31423
31419
  lookupByCommit: ()=>lookupByCommit,
@@ -31433,25 +31429,27 @@ var __webpack_exports__ = {};
31433
31429
  WL: ()=>getInstalledPreferredEditors,
31434
31430
  uB: ()=>config_getPreferredEditorCommand,
31435
31431
  Bc: ()=>getSettableConfigKeys,
31436
- P$: ()=>isCommandAvailable,
31432
+ P$: ()=>config_isCommandAvailable,
31437
31433
  n: ()=>config_isDevMode,
31438
- Wj: ()=>isTestMode,
31434
+ Wj: ()=>config_isTestMode,
31439
31435
  Vl: ()=>config_normalizeAnvilUrl,
31440
31436
  PW: ()=>parseConfigSetValue,
31441
31437
  cx: ()=>preferredEditors,
31442
31438
  E6: ()=>resetConfig,
31443
31439
  mk: ()=>resolveAnvilUrl,
31440
+ Px: ()=>setAccountTokens,
31444
31441
  Nk: ()=>setConfig
31445
31442
  });
31446
31443
  var auth_namespaceObject = {};
31447
31444
  __webpack_require__.r(auth_namespaceObject);
31448
31445
  __webpack_require__.d(auth_namespaceObject, {
31446
+ fg: ()=>ANVIL_SYNC_CLIENT_ID,
31449
31447
  Fr: ()=>auth_getAccountsForUrl,
31450
31448
  u5: ()=>getAvailableAnvilUrls,
31451
31449
  BG: ()=>getTokensForUrl,
31452
31450
  _p: ()=>auth_getValidAuthToken,
31453
31451
  Fi: ()=>auth_hasTokensForUrl,
31454
- iD: ()=>login,
31452
+ iD: ()=>auth_login,
31455
31453
  ri: ()=>logout,
31456
31454
  _d: ()=>auth_verifyAuth
31457
31455
  });
@@ -31490,21 +31488,16 @@ var __webpack_exports__ = {};
31490
31488
  __webpack_require__.r(oauth_login_namespaceObject);
31491
31489
  __webpack_require__.d(oauth_login_namespaceObject, {
31492
31490
  T_: ()=>pollDeviceAuthorization,
31493
- Z6: ()=>requestDeviceAuthorization,
31494
- Pe: ()=>runInteractiveLoginFlow
31491
+ Z6: ()=>requestDeviceAuthorization
31495
31492
  });
31496
31493
  var checkout_namespaceObject = {};
31497
31494
  __webpack_require__.r(checkout_namespaceObject);
31498
31495
  __webpack_require__.d(checkout_namespaceObject, {
31499
- oy: ()=>ensureCheckoutAuthToken,
31500
31496
  sF: ()=>executeCheckout,
31501
31497
  RD: ()=>getDefaultDestinationDirectory,
31502
31498
  A9: ()=>isDirectoryNonEmpty,
31503
31499
  oU: ()=>isPathInsideGitRepo,
31504
- GJ: ()=>checkout_openPathInEditorOrDefault,
31505
31500
  Qx: ()=>parseCheckoutInput,
31506
- GK: ()=>resolveCheckoutUrl,
31507
- XM: ()=>resolveCheckoutUsername,
31508
31501
  KV: ()=>sanitizeDirectoryName,
31509
31502
  Bc: ()=>validateCheckoutDestination
31510
31503
  });
@@ -32790,13 +32783,13 @@ var __webpack_exports__ = {};
32790
32783
  values
32791
32784
  };
32792
32785
  }
32793
- function esm_configFilePath(filePath) {
32786
+ function configFilePath(filePath) {
32794
32787
  return filePath.replace(/^(file):/, "");
32795
32788
  }
32796
32789
  function* configParser(text, requestedKey = null) {
32797
32790
  const lines = text.split("\0");
32798
32791
  for(let i = 0, max = lines.length - 1; i < max;){
32799
- const file = esm_configFilePath(lines[i++]);
32792
+ const file = configFilePath(lines[i++]);
32800
32793
  let value = lines[i++];
32801
32794
  let key = requestedKey;
32802
32795
  if (value.includes("\n")) {
@@ -39800,7 +39793,7 @@ var __webpack_exports__ = {};
39800
39793
  return `anvil-cli:${url}`;
39801
39794
  }
39802
39795
  function keychainGet(url, username) {
39803
- if (isTestMode()) return null;
39796
+ if (config_isTestMode()) return null;
39804
39797
  const Ctor = loadKeyring();
39805
39798
  if (!Ctor) return null;
39806
39799
  try {
@@ -39816,7 +39809,7 @@ var __webpack_exports__ = {};
39816
39809
  }
39817
39810
  }
39818
39811
  function keychainSet(url, username, secrets) {
39819
- if (isTestMode()) return false;
39812
+ if (config_isTestMode()) return false;
39820
39813
  const Ctor = loadKeyring();
39821
39814
  if (!Ctor) return false;
39822
39815
  try {
@@ -39828,7 +39821,7 @@ var __webpack_exports__ = {};
39828
39821
  }
39829
39822
  }
39830
39823
  function keychainDelete(url, username) {
39831
- if (isTestMode()) return;
39824
+ if (config_isTestMode()) return;
39832
39825
  const Ctor = loadKeyring();
39833
39826
  if (!Ctor) return;
39834
39827
  try {
@@ -39839,12 +39832,13 @@ var __webpack_exports__ = {};
39839
39832
  const EMPTY_TOKENS = {
39840
39833
  authToken: null,
39841
39834
  refreshToken: null,
39842
- authTokenExpiresAt: null
39835
+ authTokenExpiresAt: null,
39836
+ clientId: null
39843
39837
  };
39844
39838
  function isAccountTokens(value) {
39845
39839
  if (!value || "object" != typeof value || Array.isArray(value)) return false;
39846
39840
  const obj = value;
39847
- return ("authToken" in obj || "refreshToken" in obj || "authTokenExpiresAt" in obj) && (null === obj.authToken || "string" == typeof obj.authToken) && (null === obj.refreshToken || "string" == typeof obj.refreshToken) && (null === obj.authTokenExpiresAt || "number" == typeof obj.authTokenExpiresAt);
39841
+ return ("authToken" in obj || "refreshToken" in obj || "authTokenExpiresAt" in obj) && (null === obj.authToken || "string" == typeof obj.authToken) && (null === obj.refreshToken || "string" == typeof obj.refreshToken) && (null === obj.authTokenExpiresAt || "number" == typeof obj.authTokenExpiresAt) && (!("clientId" in obj) || null === obj.clientId || "string" == typeof obj.clientId);
39848
39842
  }
39849
39843
  function isUrlTokens(value) {
39850
39844
  if (!value || "object" != typeof value || Array.isArray(value)) return false;
@@ -39908,7 +39902,8 @@ var __webpack_exports__ = {};
39908
39902
  if (keychainOk) store[normalized][username] = {
39909
39903
  authToken: null,
39910
39904
  refreshToken: null,
39911
- authTokenExpiresAt: tokens.authTokenExpiresAt
39905
+ authTokenExpiresAt: tokens.authTokenExpiresAt,
39906
+ clientId: tokens.clientId ?? null
39912
39907
  };
39913
39908
  else store[normalized][username] = tokens;
39914
39909
  setTokenStore(store);
@@ -40007,7 +40002,7 @@ var __webpack_exports__ = {};
40007
40002
  "verbose",
40008
40003
  "preferredEditor"
40009
40004
  ];
40010
- function isTestMode() {
40005
+ function config_isTestMode() {
40011
40006
  return "test" === process.env.NODE_ENV || !!process.env.RSTEST;
40012
40007
  }
40013
40008
  function setupConfConfig() {
@@ -40040,7 +40035,7 @@ var __webpack_exports__ = {};
40040
40035
  return wrapper;
40041
40036
  }
40042
40037
  let config_config;
40043
- config_config = isTestMode() ? setupMockConfConfig() : setupConfConfig();
40038
+ config_config = config_isTestMode() ? setupMockConfConfig() : setupConfConfig();
40044
40039
  function setConfig(key, value) {
40045
40040
  config_config.set(key, value);
40046
40041
  }
@@ -40127,7 +40122,7 @@ var __webpack_exports__ = {};
40127
40122
  return false;
40128
40123
  }
40129
40124
  }
40130
- function isCommandAvailable(command, env = process.env) {
40125
+ function config_isCommandAvailable(command, env = process.env) {
40131
40126
  const executable = extractExecutableFromCommand(command);
40132
40127
  if (!executable) return false;
40133
40128
  const hasPathSeparator = executable.includes(external_path_default().sep) || executable.includes("/");
@@ -40154,7 +40149,7 @@ var __webpack_exports__ = {};
40154
40149
  return false;
40155
40150
  }
40156
40151
  function getInstalledPreferredEditors() {
40157
- return preferredEditors.filter((editor)=>isCommandAvailable(config_getPreferredEditorCommand(editor)));
40152
+ return preferredEditors.filter((editor)=>config_isCommandAvailable(config_getPreferredEditorCommand(editor)));
40158
40153
  }
40159
40154
  function getAllConfig() {
40160
40155
  return config_config.store;
@@ -40172,7 +40167,7 @@ var __webpack_exports__ = {};
40172
40167
  function resolveAnvilUrl() {
40173
40168
  const fromConfig = config_getConfig("anvilUrl");
40174
40169
  if ("string" == typeof fromConfig && fromConfig.trim()) return fromConfig.trim();
40175
- if (isTestMode()) return process.env.ANVIL_API_ORIGIN || "http://localhost:3000";
40170
+ if (config_isTestMode()) return process.env.ANVIL_API_ORIGIN || "http://localhost:3000";
40176
40171
  return config_isDevMode() ? "http://localhost:3000" : "https://anvil.works";
40177
40172
  }
40178
40173
  function config_isDevMode() {
@@ -40186,6 +40181,10 @@ var __webpack_exports__ = {};
40186
40181
  function globalConfig_getGlobalOutputConfig() {
40187
40182
  return globalOutputConfig;
40188
40183
  }
40184
+ function globalConfig_assertCanPrompt(action = "This command", explicitAlternative = "Pass explicit flags instead.") {
40185
+ if (globalOutputConfig.jsonMode) throw new Error(`${action} requires interactive input, but --json disables prompts. ${explicitAlternative}`);
40186
+ if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error(`${action} requires interactive input, but stdin/stdout is not a TTY. ${explicitAlternative}`);
40187
+ }
40189
40188
  const logger_timestamp = ()=>new Date().toISOString();
40190
40189
  const logger_verboseTimestamp = ()=>{
40191
40190
  const now = new Date();
@@ -40223,11 +40222,11 @@ var __webpack_exports__ = {};
40223
40222
  });
40224
40223
  }
40225
40224
  debug(...args) {
40226
- if (config_isDevMode() && !isTestMode()) if (this.jsonMode) this.logJson("debug", args.map(String).join(" "));
40225
+ if (config_isDevMode() && !config_isTestMode()) if (this.jsonMode) this.logJson("debug", args.map(String).join(" "));
40227
40226
  else this.log(chalk_source.gray("[DEV]"), ...args);
40228
40227
  }
40229
40228
  verbose(...args) {
40230
- if (config_getConfig("verbose") && !isTestMode()) if (this.jsonMode) this.logJson("verbose", args.map(String).join(" "));
40229
+ if (config_getConfig("verbose") && !config_isTestMode()) if (this.jsonMode) this.logJson("verbose", args.map(String).join(" "));
40231
40230
  else this.log(chalk_source.gray(`[${logger_verboseTimestamp()}]`), ...args);
40232
40231
  }
40233
40232
  info(...args) {
@@ -40282,14 +40281,32 @@ var __webpack_exports__ = {};
40282
40281
  resume() {
40283
40282
  this.paused = false;
40284
40283
  }
40285
- async prompt(questions) {
40284
+ async prompt(questions, options) {
40285
+ globalConfig_assertCanPrompt(options?.action ?? "Prompt", options?.nonInteractiveHint);
40286
40286
  throw new Error("Prompting not supported in DefaultLogger. Use CLILogger for interactive prompts.");
40287
40287
  }
40288
- async confirm(message, defaultValue = true) {
40289
- throw new Error("Prompting not supported in DefaultLogger. Use CLILogger for interactive prompts.");
40288
+ async confirm(message, defaultValue = true, options) {
40289
+ const answer = await this.prompt([
40290
+ {
40291
+ type: "confirm",
40292
+ name: "value",
40293
+ message,
40294
+ default: defaultValue
40295
+ }
40296
+ ], options);
40297
+ return answer.value;
40290
40298
  }
40291
- async select(message, choices, defaultValue) {
40292
- throw new Error("Prompting not supported in DefaultLogger. Use CLILogger for interactive prompts.");
40299
+ async select(message, choices, defaultValue, options) {
40300
+ const answer = await this.prompt([
40301
+ {
40302
+ type: "list",
40303
+ name: "value",
40304
+ message,
40305
+ choices,
40306
+ default: defaultValue
40307
+ }
40308
+ ], options);
40309
+ return answer.value;
40293
40310
  }
40294
40311
  }
40295
40312
  let logger_logger = new DefaultLogger();
@@ -42478,6 +42495,7 @@ var __webpack_exports__ = {};
42478
42495
  function getDefaultAnvilUrl() {
42479
42496
  return resolveAnvilUrl();
42480
42497
  }
42498
+ const ANVIL_SYNC_CLIENT_ID = "anvil-sync";
42481
42499
  async function auth_verifyAuth(authToken, anvilUrl = getDefaultAnvilUrl()) {
42482
42500
  try {
42483
42501
  const resp = await fetch(`${anvilUrl}/ide/api/_/user`, {
@@ -42497,7 +42515,7 @@ var __webpack_exports__ = {};
42497
42515
  throw createAuthError.invalid(`Network error: ${e.message}`);
42498
42516
  }
42499
42517
  }
42500
- async function refreshAccessToken(refreshToken, anvilUrl = getDefaultAnvilUrl()) {
42518
+ async function refreshAccessToken(refreshToken, anvilUrl = getDefaultAnvilUrl(), clientId = ANVIL_SYNC_CLIENT_ID) {
42501
42519
  try {
42502
42520
  const tokenResponse = await fetch(`${anvilUrl}/oauth/token`, {
42503
42521
  method: "POST",
@@ -42507,7 +42525,7 @@ var __webpack_exports__ = {};
42507
42525
  body: new URLSearchParams({
42508
42526
  grant_type: "refresh_token",
42509
42527
  refresh_token: refreshToken,
42510
- client_id: "anvil-sync"
42528
+ client_id: clientId
42511
42529
  })
42512
42530
  });
42513
42531
  if (!tokenResponse.ok) {
@@ -42533,7 +42551,8 @@ var __webpack_exports__ = {};
42533
42551
  if (!tokens.authToken && !tokens.refreshToken) throw createAuthError.required("Not logged in. Please log in first.");
42534
42552
  const isExpired = null !== tokens.authTokenExpiresAt && tokens.authTokenExpiresAt <= Math.floor(Date.now() / 1000) + 60;
42535
42553
  if (tokens.refreshToken && isExpired) try {
42536
- const tokenData = await refreshAccessToken(tokens.refreshToken, normalized);
42554
+ const clientId = tokens.clientId ?? ANVIL_SYNC_CLIENT_ID;
42555
+ const tokenData = await refreshAccessToken(tokens.refreshToken, normalized, clientId);
42537
42556
  const newExpiresAt = Math.floor(Date.now() / 1000) + tokenData.expires_in;
42538
42557
  let accountUsername = username;
42539
42558
  if (!accountUsername) {
@@ -42550,7 +42569,8 @@ var __webpack_exports__ = {};
42550
42569
  setAccountTokens(normalized, accountUsername, {
42551
42570
  authToken: tokenData.access_token,
42552
42571
  refreshToken: tokenData.refresh_token,
42553
- authTokenExpiresAt: newExpiresAt
42572
+ authTokenExpiresAt: newExpiresAt,
42573
+ clientId
42554
42574
  });
42555
42575
  return tokenData.access_token;
42556
42576
  } catch (e) {
@@ -42568,14 +42588,15 @@ var __webpack_exports__ = {};
42568
42588
  if (account) deleteAccountTokens(normalized, account);
42569
42589
  }
42570
42590
  }
42571
- async function login(anvilUrl, tokenData) {
42591
+ async function auth_login(anvilUrl, tokenData) {
42572
42592
  const normalized = config_normalizeAnvilUrl(anvilUrl);
42573
42593
  const expiresAt = Math.floor(Date.now() / 1000) + tokenData.expires_in;
42574
42594
  const username = await auth_verifyAuth(tokenData.access_token, normalized);
42575
42595
  setAccountTokens(normalized, username, {
42576
42596
  authToken: tokenData.access_token,
42577
42597
  refreshToken: tokenData.refresh_token,
42578
- authTokenExpiresAt: expiresAt
42598
+ authTokenExpiresAt: expiresAt,
42599
+ clientId: ANVIL_SYNC_CLIENT_ID
42579
42600
  });
42580
42601
  return {
42581
42602
  success: true,
@@ -44018,7 +44039,9 @@ var __webpack_exports__ = {};
44018
44039
  };
44019
44040
  return null;
44020
44041
  }
44021
- async function loadFormTemplateData(repoPath, relativePath, stagedOnly, kind, format) {
44042
+ async function loadFormTemplateData(relativePath, templateInfo, context) {
44043
+ const { repoPath, stagedOnly = false } = context;
44044
+ const { kind, format } = templateInfo;
44022
44045
  try {
44023
44046
  const content = await readFileContent(repoPath, relativePath, stagedOnly);
44024
44047
  if ("yaml" === format) {
@@ -44106,7 +44129,8 @@ var __webpack_exports__ = {};
44106
44129
  if (formTemplateInfo) return "forms";
44107
44130
  return null;
44108
44131
  }
44109
- async function validateRename(fromPath, toPath, repoPath, editorYaml) {
44132
+ async function validateRename(fromPath, toPath, context) {
44133
+ const { repoPath, editorYaml } = context;
44110
44134
  const fromEntityType = await getEntityTypeFromPath(repoPath, fromPath, editorYaml);
44111
44135
  const toEntityType = await getEntityTypeFromPath(repoPath, toPath, editorYaml);
44112
44136
  if (null === fromEntityType || null === toEntityType) return {
@@ -44264,7 +44288,8 @@ var __webpack_exports__ = {};
44264
44288
  }
44265
44289
  return filtered;
44266
44290
  }
44267
- async function routeFileChange(repoPath, relativePath, changeType, editorYaml, stagedOnly = false, fromPath) {
44291
+ async function routeFileChange(change, context) {
44292
+ const { relativePath, changeType, fromPath } = change;
44268
44293
  logger_logger.verbose(chalk_source.gray(`Routing ${changeType}: ${relativePath}${fromPath ? ` (from: ${fromPath})` : ""}`));
44269
44294
  if (isGitRelatedFile(relativePath)) return {
44270
44295
  type: "ignore",
@@ -44277,9 +44302,12 @@ var __webpack_exports__ = {};
44277
44302
  type: "ignore",
44278
44303
  reason: "Rename operation missing from path"
44279
44304
  };
44280
- return await handleRename(repoPath, fromPath, relativePath, editorYaml, stagedOnly);
44305
+ return await handleRename({
44306
+ fromPath,
44307
+ toPath: relativePath
44308
+ }, context);
44281
44309
  }
44282
- return await routeSavableChange(repoPath, relativePath, changeType, editorYaml, stagedOnly);
44310
+ return await routeSavableChange(change, context);
44283
44311
  }
44284
44312
  function isGitRelatedFile(relativePath) {
44285
44313
  return ".git" === relativePath || relativePath.startsWith(".git/") || relativePath.endsWith("/.git");
@@ -44298,47 +44326,60 @@ var __webpack_exports__ = {};
44298
44326
  const parts = relativePath.split("/");
44299
44327
  return 2 === parts.length;
44300
44328
  },
44301
- handle: (repoPath, relativePath, changeType, editorYaml, stagedOnly)=>handleScriptsChange(repoPath, relativePath, editorYaml, changeType, stagedOnly)
44329
+ handle: handleScriptsChange
44302
44330
  },
44303
44331
  {
44304
44332
  matches: (relativePath)=>relativePath.startsWith("server_code/") && relativePath.endsWith(".py"),
44305
- handle: (repoPath, relativePath, changeType, editorYaml, stagedOnly)=>handleServerCodeChange(repoPath, relativePath, editorYaml, changeType, stagedOnly)
44333
+ handle: handleServerCodeChange
44306
44334
  },
44307
44335
  {
44308
44336
  matches: (relativePath)=>relativePath.startsWith("client_code/") && relativePath.endsWith(".py"),
44309
- handle: (repoPath, relativePath, changeType, editorYaml, stagedOnly)=>handleClientCodeChange(repoPath, relativePath, editorYaml, changeType, stagedOnly)
44337
+ handle: handleClientCodeChange
44310
44338
  },
44311
44339
  {
44312
44340
  matches: (relativePath)=>null !== detectFormTemplate(relativePath),
44313
- handle: (repoPath, relativePath, changeType, editorYaml, stagedOnly)=>handleFormTemplateChange(repoPath, relativePath, editorYaml, changeType, stagedOnly)
44341
+ handle: handleFormTemplateChange
44314
44342
  },
44315
44343
  {
44316
44344
  matches: (relativePath)=>"theme/parameters.yaml" === relativePath,
44317
- handle: (repoPath, relativePath, changeType, editorYaml, stagedOnly)=>handleThemeParametersChange(repoPath, relativePath, stagedOnly)
44345
+ handle: handleThemeParametersChange
44318
44346
  },
44319
44347
  {
44320
44348
  matches: (relativePath)=>relativePath.startsWith("theme/assets/"),
44321
- handle: (repoPath, relativePath, changeType, editorYaml, stagedOnly)=>handleAssetChange(repoPath, relativePath, changeType, editorYaml, stagedOnly)
44349
+ handle: handleAssetChange
44322
44350
  },
44323
44351
  {
44324
44352
  matches: ()=>true,
44325
- handle: (repoPath, relativePath, changeType, editorYaml, stagedOnly)=>handleExtraFileChange(repoPath, relativePath, stagedOnly)
44353
+ handle: handleExtraFileChange
44326
44354
  }
44327
44355
  ];
44328
- async function handleRename(repoPath, fromPath, toPath, editorYaml, stagedOnly) {
44329
- const validation = await validateRename(fromPath, toPath, repoPath, editorYaml);
44356
+ async function handleRename(rename, context) {
44357
+ const { fromPath, toPath } = rename;
44358
+ const validation = await validateRename(fromPath, toPath, context);
44330
44359
  if (!validation.valid) {
44331
44360
  logger_logger.verbose(chalk_source.yellow(`Rename invalid (${validation.reason}), falling back to unlink + add`));
44332
- const unlinkResult = await routeFileChange(repoPath, fromPath, "unlink", editorYaml, stagedOnly);
44333
- const addResult = await routeFileChange(repoPath, toPath, "add", editorYaml, stagedOnly);
44361
+ const unlinkResult = await routeFileChange({
44362
+ relativePath: fromPath,
44363
+ changeType: "unlink"
44364
+ }, context);
44365
+ const addResult = await routeFileChange({
44366
+ relativePath: toPath,
44367
+ changeType: "add"
44368
+ }, context);
44334
44369
  return [
44335
44370
  unlinkResult,
44336
44371
  addResult
44337
44372
  ].flat();
44338
44373
  }
44339
- return await handleRenameOperation(repoPath, fromPath, toPath, validation.entityType, editorYaml, stagedOnly);
44374
+ return await handleRenameOperation({
44375
+ fromPath,
44376
+ toPath,
44377
+ entityType: validation.entityType
44378
+ }, context);
44340
44379
  }
44341
- async function handleRenameOperation(repoPath, fromPath, toPath, entityType, editorYaml, stagedOnly) {
44380
+ async function handleRenameOperation(rename, context) {
44381
+ const { repoPath, editorYaml, stagedOnly = false } = context;
44382
+ const { fromPath, toPath, entityType } = rename;
44342
44383
  let oldName;
44343
44384
  let newName;
44344
44385
  let prefix = [];
@@ -44347,10 +44388,10 @@ var __webpack_exports__ = {};
44347
44388
  let isPackage = false;
44348
44389
  let actualToPath = toPath;
44349
44390
  if ("scripts" === entityType) {
44350
- const toRenameResult = await handlePathRenaming(repoPath, toPath, "scripts", stagedOnly);
44391
+ const toRenameResult = await handlePathRenaming(toPath, "scripts", context);
44351
44392
  if (toRenameResult.ignoreResult) return toRenameResult.ignoreResult;
44352
44393
  actualToPath = toRenameResult.newRelativePath;
44353
- const fromRenameResult = await handlePathRenaming(repoPath, fromPath, "scripts", stagedOnly);
44394
+ const fromRenameResult = await handlePathRenaming(fromPath, "scripts", context);
44354
44395
  oldName = fromRenameResult.pythonifiedName;
44355
44396
  newName = toRenameResult.pythonifiedName;
44356
44397
  prefix = [
@@ -44362,10 +44403,10 @@ var __webpack_exports__ = {};
44362
44403
  code
44363
44404
  });
44364
44405
  } else if ("server_modules" === entityType) {
44365
- const toRenameResult = await handlePathRenaming(repoPath, toPath, "server_code", stagedOnly);
44406
+ const toRenameResult = await handlePathRenaming(toPath, "server_code", context);
44366
44407
  if (toRenameResult.ignoreResult) return toRenameResult.ignoreResult;
44367
44408
  actualToPath = toRenameResult.newRelativePath;
44368
- const fromRenameResult = await handlePathRenaming(repoPath, fromPath, "server_code", stagedOnly);
44409
+ const fromRenameResult = await handlePathRenaming(fromPath, "server_code", context);
44369
44410
  oldName = fromRenameResult.pythonifiedName;
44370
44411
  newName = toRenameResult.pythonifiedName;
44371
44412
  prefix = [
@@ -44379,10 +44420,10 @@ var __webpack_exports__ = {};
44379
44420
  is_package: isPackage
44380
44421
  });
44381
44422
  } else if ("modules" === entityType) {
44382
- const toRenameResult = await handlePathRenaming(repoPath, toPath, "client_code", stagedOnly);
44423
+ const toRenameResult = await handlePathRenaming(toPath, "client_code", context);
44383
44424
  if (toRenameResult.ignoreResult) return toRenameResult.ignoreResult;
44384
44425
  actualToPath = toRenameResult.newRelativePath;
44385
- const fromRenameResult = await handlePathRenaming(repoPath, fromPath, "client_code", stagedOnly);
44426
+ const fromRenameResult = await handlePathRenaming(fromPath, "client_code", context);
44386
44427
  oldName = fromRenameResult.pythonifiedName;
44387
44428
  newName = toRenameResult.pythonifiedName;
44388
44429
  isPackage = actualToPath.endsWith("__init__.py");
@@ -44400,10 +44441,10 @@ var __webpack_exports__ = {};
44400
44441
  type: "ignore",
44401
44442
  reason: "Form template rename to .yaml file is only supported when entire form is renamed"
44402
44443
  };
44403
- const toRenameResult = await handlePathRenaming(repoPath, toPath, "client_code", stagedOnly);
44444
+ const toRenameResult = await handlePathRenaming(toPath, "client_code", context);
44404
44445
  if (toRenameResult.ignoreResult) return toRenameResult.ignoreResult;
44405
44446
  actualToPath = toRenameResult.newRelativePath;
44406
- const fromRenameResult = await handlePathRenaming(repoPath, fromPath, "client_code", stagedOnly);
44447
+ const fromRenameResult = await handlePathRenaming(fromPath, "client_code", context);
44407
44448
  oldName = fromRenameResult.pythonifiedName;
44408
44449
  const isPackageInit = actualToPath.endsWith("__init__.py");
44409
44450
  const kind = isPackageInit ? "package" : "module";
@@ -44412,7 +44453,10 @@ var __webpack_exports__ = {};
44412
44453
  type: "ignore",
44413
44454
  reason: "Form template not found for rename destination"
44414
44455
  };
44415
- const result = await buildFormTemplateData(repoPath, templateInfo.relativePath, stagedOnly, kind, templateInfo.format);
44456
+ const result = await buildFormTemplateData(templateInfo.relativePath, {
44457
+ kind,
44458
+ format: templateInfo.format
44459
+ }, context);
44416
44460
  if (result.ignoreResult) return result.ignoreResult;
44417
44461
  newName = result.className;
44418
44462
  prefix = [
@@ -44460,7 +44504,9 @@ var __webpack_exports__ = {};
44460
44504
  content: payload
44461
44505
  };
44462
44506
  }
44463
- async function routeSavableChange(repoPath, relativePath, changeType, editorYaml, stagedOnly = false) {
44507
+ async function routeSavableChange(change, context) {
44508
+ const { repoPath, editorYaml, stagedOnly = false } = context;
44509
+ const { relativePath, changeType } = change;
44464
44510
  if ("anvil.yaml" === relativePath) return {
44465
44511
  type: "ignore",
44466
44512
  reason: "anvil.yaml handled specially (multiple save paths)"
@@ -44504,13 +44550,15 @@ var __webpack_exports__ = {};
44504
44550
  };
44505
44551
  }
44506
44552
  if ("unlink" === changeType) return await handleFileDeletion(repoPath, relativePath, editorYaml);
44507
- for (const route of ROUTES)if (route.matches(relativePath)) return await route.handle(repoPath, relativePath, changeType, editorYaml, stagedOnly);
44553
+ for (const route of ROUTES)if (route.matches(relativePath)) return await route.handle(change, context);
44508
44554
  return {
44509
44555
  type: "ignore",
44510
44556
  reason: "Not a recognized Anvil file type"
44511
44557
  };
44512
44558
  }
44513
- async function handleThemeParametersChange(repoPath, relativePath, stagedOnly = false) {
44559
+ async function handleThemeParametersChange(change, context) {
44560
+ const { repoPath, stagedOnly = false } = context;
44561
+ const { relativePath } = change;
44514
44562
  const content = await readFileContent(repoPath, relativePath, stagedOnly);
44515
44563
  const parametersData = jsYaml.load(content);
44516
44564
  return {
@@ -44522,7 +44570,9 @@ var __webpack_exports__ = {};
44522
44570
  content: parametersData
44523
44571
  };
44524
44572
  }
44525
- async function handleExtraFileChange(repoPath, relativePath, stagedOnly = false) {
44573
+ async function handleExtraFileChange(change, context) {
44574
+ const { repoPath, stagedOnly = false } = context;
44575
+ const { relativePath } = change;
44526
44576
  const content = await readBinaryFileContent(repoPath, relativePath, stagedOnly);
44527
44577
  const base64Content = content.toString("base64");
44528
44578
  const pathParts = [
@@ -44535,7 +44585,9 @@ var __webpack_exports__ = {};
44535
44585
  content: base64Content
44536
44586
  };
44537
44587
  }
44538
- async function handleDirectoryRenaming(repoPath, originalParts, pythonifiedParts, baseDir) {
44588
+ async function handleDirectoryRenaming(rename, context) {
44589
+ const { repoPath } = context;
44590
+ const { originalParts, pythonifiedParts, baseDir } = rename;
44539
44591
  const needsRename = originalParts.some((part, idx)=>part !== pythonifiedParts[idx]);
44540
44592
  if (!needsRename) return null;
44541
44593
  const needsDirRename = originalParts.slice(0, -1).some((part, idx)=>part !== pythonifiedParts[idx]);
@@ -44553,7 +44605,9 @@ var __webpack_exports__ = {};
44553
44605
  }
44554
44606
  return null;
44555
44607
  }
44556
- async function renameIfNeeded(repoPath, relativePath, originalNameOrParts, baseDir) {
44608
+ async function renameIfNeeded(rename, context) {
44609
+ const { repoPath } = context;
44610
+ const { relativePath, originalNameOrParts, baseDir } = rename;
44557
44611
  let pythonifiedName;
44558
44612
  let pythonifiedParts;
44559
44613
  let needsRename;
@@ -44591,8 +44645,10 @@ var __webpack_exports__ = {};
44591
44645
  ignoreResult
44592
44646
  };
44593
44647
  }
44594
- async function handleScriptsChange(repoPath, relativePath, editorYaml, changeType, stagedOnly = false) {
44595
- const renameResult = await handlePathRenaming(repoPath, relativePath, "scripts", stagedOnly);
44648
+ async function handleScriptsChange(change, context) {
44649
+ const { repoPath, editorYaml, stagedOnly = false } = context;
44650
+ const { relativePath, changeType } = change;
44651
+ const renameResult = await handlePathRenaming(relativePath, "scripts", context);
44596
44652
  if (renameResult.ignoreResult) return renameResult.ignoreResult;
44597
44653
  const actualPath = renameResult.newRelativePath;
44598
44654
  const content = await readFileContent(repoPath, actualPath, stagedOnly);
@@ -44614,8 +44670,10 @@ var __webpack_exports__ = {};
44614
44670
  ]
44615
44671
  });
44616
44672
  }
44617
- async function handleServerCodeChange(repoPath, relativePath, editorYaml, changeType, stagedOnly = false) {
44618
- const renameResult = await handlePathRenaming(repoPath, relativePath, "server_code", stagedOnly);
44673
+ async function handleServerCodeChange(change, context) {
44674
+ const { repoPath, editorYaml, stagedOnly = false } = context;
44675
+ const { relativePath, changeType } = change;
44676
+ const renameResult = await handlePathRenaming(relativePath, "server_code", context);
44619
44677
  if (renameResult.ignoreResult) return renameResult.ignoreResult;
44620
44678
  const actualPath = renameResult.newRelativePath;
44621
44679
  const isPackage = actualPath.endsWith("__init__.py");
@@ -44640,8 +44698,10 @@ var __webpack_exports__ = {};
44640
44698
  ]
44641
44699
  });
44642
44700
  }
44643
- async function handleClientCodeFormChange(repoPath, relativePath, className, templatePath, format, kind, changeType, editorYaml, stagedOnly) {
44644
- const result = await buildFormTemplateData(repoPath, templatePath, stagedOnly, kind, format);
44701
+ async function handleClientCodeFormChange(options, context) {
44702
+ const { editorYaml } = context;
44703
+ const { templatePath, templateInfo, changeType } = options;
44704
+ const result = await buildFormTemplateData(templatePath, templateInfo, context);
44645
44705
  if (result.ignoreResult) return result.ignoreResult;
44646
44706
  const { formData, className: extractedClassName } = result;
44647
44707
  return handleIdBasedOperation({
@@ -44659,30 +44719,47 @@ var __webpack_exports__ = {};
44659
44719
  ]
44660
44720
  });
44661
44721
  }
44662
- async function handlePathRenaming(repoPath, relativePath, baseDir, stagedOnly) {
44722
+ async function handlePathRenaming(relativePath, baseDir, context) {
44663
44723
  const parts = relativePath.slice(0, -3).split("/");
44664
44724
  const originalParts = parts.slice(1);
44665
44725
  const pythonifiedParts = originalParts.map(pythonifyName);
44666
44726
  const pythonifiedName = extractPythonName(relativePath);
44667
- const dirRenameResult = await handleDirectoryRenaming(repoPath, originalParts, pythonifiedParts, baseDir);
44727
+ const dirRenameResult = await handleDirectoryRenaming({
44728
+ originalParts,
44729
+ pythonifiedParts,
44730
+ baseDir
44731
+ }, context);
44668
44732
  if (dirRenameResult) return {
44669
44733
  pythonifiedName,
44670
44734
  pythonifiedParts,
44671
44735
  newRelativePath: relativePath,
44672
44736
  ignoreResult: dirRenameResult
44673
44737
  };
44674
- const renameResult = await renameIfNeeded(repoPath, relativePath, originalParts, baseDir);
44738
+ const renameResult = await renameIfNeeded({
44739
+ relativePath,
44740
+ originalNameOrParts: originalParts,
44741
+ baseDir
44742
+ }, context);
44675
44743
  return renameResult;
44676
44744
  }
44677
- async function handleClientCodeChange(repoPath, relativePath, editorYaml, changeType, stagedOnly = false) {
44678
- const renameResult = await handlePathRenaming(repoPath, relativePath, "client_code", stagedOnly);
44745
+ async function handleClientCodeChange(change, context) {
44746
+ const { repoPath, editorYaml, stagedOnly = false } = context;
44747
+ const { relativePath, changeType } = change;
44748
+ const renameResult = await handlePathRenaming(relativePath, "client_code", context);
44679
44749
  if (renameResult.ignoreResult) return renameResult.ignoreResult;
44680
44750
  const actualPath = renameResult.newRelativePath;
44681
44751
  const isPackageInit = actualPath.endsWith("__init__.py");
44682
44752
  const kind = isPackageInit ? "package" : "module";
44683
44753
  const className = renameResult.pythonifiedName;
44684
44754
  const templateInfo = findFormTemplateForCodePath(repoPath, actualPath, kind);
44685
- if (templateInfo) return await handleClientCodeFormChange(repoPath, actualPath, className, templateInfo.relativePath, templateInfo.format, kind, changeType, editorYaml, stagedOnly);
44755
+ if (templateInfo) return await handleClientCodeFormChange({
44756
+ templatePath: templateInfo.relativePath,
44757
+ templateInfo: {
44758
+ format: templateInfo.format,
44759
+ kind
44760
+ },
44761
+ changeType
44762
+ }, context);
44686
44763
  const content = await readFileContent(repoPath, actualPath, stagedOnly);
44687
44764
  return handleIdBasedOperation({
44688
44765
  entityType: "modules",
@@ -44717,8 +44794,10 @@ var __webpack_exports__ = {};
44717
44794
  }
44718
44795
  return formData;
44719
44796
  }
44720
- async function buildFormTemplateData(repoPath, relativePath, stagedOnly, kind, format) {
44721
- const loadResult = await loadFormTemplateData(repoPath, relativePath, stagedOnly, kind, format);
44797
+ async function buildFormTemplateData(relativePath, templateInfo, context) {
44798
+ const { repoPath, stagedOnly = false } = context;
44799
+ const { kind } = templateInfo;
44800
+ const loadResult = await loadFormTemplateData(relativePath, templateInfo, context);
44722
44801
  if (false === loadResult.ok) return {
44723
44802
  formData: {},
44724
44803
  className: "",
@@ -44752,7 +44831,9 @@ var __webpack_exports__ = {};
44752
44831
  ignoreResult: null
44753
44832
  };
44754
44833
  }
44755
- async function handleFormTemplateChange(repoPath, relativePath, editorYaml, changeType, stagedOnly) {
44834
+ async function handleFormTemplateChange(change, context) {
44835
+ const { editorYaml } = context;
44836
+ const { relativePath, changeType } = change;
44756
44837
  const templateInfo = detectFormTemplate(relativePath);
44757
44838
  if (!templateInfo) return {
44758
44839
  type: "ignore",
@@ -44760,7 +44841,10 @@ var __webpack_exports__ = {};
44760
44841
  };
44761
44842
  const kind = templateInfo.kind;
44762
44843
  const format = templateInfo.format;
44763
- const result = await buildFormTemplateData(repoPath, relativePath, stagedOnly, kind, format);
44844
+ const result = await buildFormTemplateData(relativePath, {
44845
+ kind,
44846
+ format
44847
+ }, context);
44764
44848
  if (result.ignoreResult) return result.ignoreResult;
44765
44849
  const { formData, className } = result;
44766
44850
  return handleIdBasedOperation({
@@ -44776,7 +44860,9 @@ var __webpack_exports__ = {};
44776
44860
  subPathForCodeUpdate: null
44777
44861
  });
44778
44862
  }
44779
- async function handleAssetChange(repoPath, relativePath, changeType, editorYaml, stagedOnly = false) {
44863
+ async function handleAssetChange(change, context) {
44864
+ const { repoPath, editorYaml, stagedOnly = false } = context;
44865
+ const { relativePath, changeType } = change;
44780
44866
  const assetPath = relativePath.replace(/^theme[\/\\]assets[\/\\]/, "");
44781
44867
  const fileBuffer = await readBinaryFileContent(repoPath, relativePath, stagedOnly);
44782
44868
  const base64Content = fileBuffer.toString("base64");
@@ -45203,7 +45289,15 @@ var __webpack_exports__ = {};
45203
45289
  originalFilePaths.push(change.path);
45204
45290
  continue;
45205
45291
  }
45206
- const routeResult = await routeFileChange(this.config.repoPath, change.path, change.type, this.config.editorYaml, this.config.stagedOnly, change.from);
45292
+ const routeResult = await routeFileChange({
45293
+ relativePath: change.path,
45294
+ changeType: change.type,
45295
+ fromPath: change.from
45296
+ }, {
45297
+ repoPath: this.config.repoPath,
45298
+ editorYaml: this.config.editorYaml,
45299
+ stagedOnly: this.config.stagedOnly
45300
+ });
45207
45301
  const results = Array.isArray(routeResult) ? routeResult : [
45208
45302
  routeResult
45209
45303
  ];
@@ -45390,7 +45484,15 @@ var __webpack_exports__ = {};
45390
45484
  const newSaveArray = [];
45391
45485
  const newFilePaths = [];
45392
45486
  for (const change of changes){
45393
- const routeResult = await routeFileChange(this.config.repoPath, change.path, change.type, this.config.editorYaml, this.config.stagedOnly, change.from);
45487
+ const routeResult = await routeFileChange({
45488
+ relativePath: change.path,
45489
+ changeType: change.type,
45490
+ fromPath: change.from
45491
+ }, {
45492
+ repoPath: this.config.repoPath,
45493
+ editorYaml: this.config.editorYaml,
45494
+ stagedOnly: this.config.stagedOnly
45495
+ });
45394
45496
  const results = Array.isArray(routeResult) ? routeResult : [
45395
45497
  routeResult
45396
45498
  ];
@@ -45924,22 +46026,28 @@ var __webpack_exports__ = {};
45924
46026
  appName
45925
46027
  };
45926
46028
  }
45927
- async function validation_validateBranchSyncStatus(git, branchName, appId, anvilUrl, username) {
46029
+ async function validation_validateBranchSyncStatus(git, branchName, options) {
46030
+ const { appId, anvilUrl, username } = options;
45928
46031
  logger_logger.verbose(chalk_source.blue("Checking branch sync status..."));
45929
46032
  let authToken;
45930
46033
  try {
45931
46034
  authToken = await auth_getValidAuthToken(anvilUrl, username);
45932
46035
  } catch (e) {
45933
- return validateViaAnvilServer(git, branchName, appId, anvilUrl, username);
46036
+ return validateViaAnvilServer(git, branchName, options);
45934
46037
  }
45935
46038
  try {
45936
- return await validateViaGitFetch(git, branchName, appId, anvilUrl, authToken);
46039
+ return await validateViaGitFetch(git, branchName, {
46040
+ appId,
46041
+ anvilUrl,
46042
+ authToken
46043
+ });
45937
46044
  } catch (e) {
45938
46045
  logger_logger.verbose(chalk_source.yellow("Git fetch failed, trying server validation..."));
45939
- return validateViaAnvilServer(git, branchName, appId, anvilUrl, username);
46046
+ return validateViaAnvilServer(git, branchName, options);
45940
46047
  }
45941
46048
  }
45942
- async function validateViaGitFetch(git, branchName, appId, anvilUrl, authToken) {
46049
+ async function validateViaGitFetch(git, branchName, options) {
46050
+ const { appId, anvilUrl, authToken } = options;
45943
46051
  const baseUrl = new URL(anvilUrl);
45944
46052
  const encodedToken = encodeURIComponent(authToken);
45945
46053
  const gitPath = `/git/${appId}.git`;
@@ -46000,7 +46108,8 @@ var __webpack_exports__ = {};
46000
46108
  throw errors_createGitError.fetchFailed(e.message);
46001
46109
  }
46002
46110
  }
46003
- async function validateViaAnvilServer(git, branchName, appId, anvilUrl, username) {
46111
+ async function validateViaAnvilServer(git, branchName, options) {
46112
+ const { appId, anvilUrl, username } = options;
46004
46113
  logger_logger.verbose(chalk_source.blue("Validating sync status with Anvil server..."));
46005
46114
  const authToken = await auth_getValidAuthToken(anvilUrl, username);
46006
46115
  let commitId;
@@ -46045,676 +46154,13 @@ var __webpack_exports__ = {};
46045
46154
  throw createNetworkError.network(e.message);
46046
46155
  }
46047
46156
  }
46048
- var external_http_ = __webpack_require__("http");
46049
- const external_readline_namespaceObject = require("readline");
46050
- var external_readline_default = /*#__PURE__*/ __webpack_require__.n(external_readline_namespaceObject);
46051
- const external_node_url_namespaceObject = require("node:url");
46052
- const external_node_child_process_namespaceObject = require("node:child_process");
46053
- let isDockerCached;
46054
- function hasDockerEnv() {
46055
- try {
46056
- external_node_fs_.statSync('/.dockerenv');
46057
- return true;
46058
- } catch {
46059
- return false;
46060
- }
46061
- }
46062
- function hasDockerCGroup() {
46063
- try {
46064
- return external_node_fs_.readFileSync('/proc/self/cgroup', 'utf8').includes('docker');
46065
- } catch {
46066
- return false;
46067
- }
46068
- }
46069
- function isDocker() {
46070
- if (void 0 === isDockerCached) isDockerCached = hasDockerEnv() || hasDockerCGroup();
46071
- return isDockerCached;
46072
- }
46073
- let cachedResult;
46074
- const hasContainerEnv = ()=>{
46075
- try {
46076
- external_node_fs_.statSync('/run/.containerenv');
46077
- return true;
46078
- } catch {
46079
- return false;
46080
- }
46081
- };
46082
- function isInsideContainer() {
46083
- if (void 0 === cachedResult) cachedResult = hasContainerEnv() || isDocker();
46084
- return cachedResult;
46085
- }
46086
- const isWsl = ()=>{
46087
- if ('linux' !== external_node_process_namespaceObject.platform) return false;
46088
- if (external_node_os_namespaceObject.release().toLowerCase().includes('microsoft')) {
46089
- if (isInsideContainer()) return false;
46090
- return true;
46091
- }
46092
- try {
46093
- return external_node_fs_.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ? !isInsideContainer() : false;
46094
- } catch {
46095
- return false;
46096
- }
46097
- };
46098
- const is_wsl = external_node_process_namespaceObject.env.__IS_WSL_TEST__ ? isWsl : isWsl();
46099
- const wslDrivesMountPoint = (()=>{
46100
- const defaultMountPoint = '/mnt/';
46101
- let mountPoint;
46102
- return async function() {
46103
- if (mountPoint) return mountPoint;
46104
- const configFilePath = '/etc/wsl.conf';
46105
- let isConfigFileExists = false;
46106
- try {
46107
- await external_node_fs_promises_namespaceObject.access(configFilePath, external_node_fs_promises_namespaceObject.constants.F_OK);
46108
- isConfigFileExists = true;
46109
- } catch {}
46110
- if (!isConfigFileExists) return defaultMountPoint;
46111
- const configContent = await external_node_fs_promises_namespaceObject.readFile(configFilePath, {
46112
- encoding: 'utf8'
46113
- });
46114
- const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
46115
- if (!configMountPoint) return defaultMountPoint;
46116
- mountPoint = configMountPoint.groups.mountPoint.trim();
46117
- mountPoint = mountPoint.endsWith('/') ? mountPoint : `${mountPoint}/`;
46118
- return mountPoint;
46119
- };
46120
- })();
46121
- const powerShellPathFromWsl = async ()=>{
46122
- const mountPoint = await wslDrivesMountPoint();
46123
- return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
46124
- };
46125
- const powerShellPath = async ()=>{
46126
- if (is_wsl) return powerShellPathFromWsl();
46127
- return `${external_node_process_namespaceObject.env.SYSTEMROOT || external_node_process_namespaceObject.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
46128
- };
46129
- function defineLazyProperty(object, propertyName, valueGetter) {
46130
- const define = (value)=>Object.defineProperty(object, propertyName, {
46131
- value,
46132
- enumerable: true,
46133
- writable: true
46134
- });
46135
- Object.defineProperty(object, propertyName, {
46136
- configurable: true,
46137
- enumerable: true,
46138
- get () {
46139
- const result = valueGetter();
46140
- define(result);
46141
- return result;
46142
- },
46143
- set (value) {
46144
- define(value);
46145
- }
46146
- });
46147
- return object;
46148
- }
46149
- const execFileAsync = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_namespaceObject.execFile);
46150
- async function defaultBrowserId() {
46151
- if ('darwin' !== external_node_process_namespaceObject.platform) throw new Error('macOS only');
46152
- const { stdout } = await execFileAsync('defaults', [
46153
- 'read',
46154
- 'com.apple.LaunchServices/com.apple.launchservices.secure',
46155
- 'LSHandlers'
46156
- ]);
46157
- const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
46158
- const browserId = match?.groups.id ?? 'com.apple.Safari';
46159
- if ('com.apple.safari' === browserId) return 'com.apple.Safari';
46160
- return browserId;
46161
- }
46162
- const run_applescript_execFileAsync = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_namespaceObject.execFile);
46163
- async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
46164
- if ('darwin' !== external_node_process_namespaceObject.platform) throw new Error('macOS only');
46165
- const outputArguments = humanReadableOutput ? [] : [
46166
- '-ss'
46167
- ];
46168
- const execOptions = {};
46169
- if (signal) execOptions.signal = signal;
46170
- const { stdout } = await run_applescript_execFileAsync("osascript", [
46171
- '-e',
46172
- script,
46173
- outputArguments
46174
- ], execOptions);
46175
- return stdout.trim();
46176
- }
46177
- async function bundleName(bundleId) {
46178
- return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string\ntell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
46179
- }
46180
- const windows_execFileAsync = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_namespaceObject.execFile);
46181
- const windowsBrowserProgIds = {
46182
- MSEdgeHTM: {
46183
- name: 'Edge',
46184
- id: 'com.microsoft.edge'
46185
- },
46186
- MSEdgeBHTML: {
46187
- name: 'Edge Beta',
46188
- id: 'com.microsoft.edge.beta'
46189
- },
46190
- MSEdgeDHTML: {
46191
- name: 'Edge Dev',
46192
- id: 'com.microsoft.edge.dev'
46193
- },
46194
- AppXq0fevzme2pys62n3e0fbqa7peapykr8v: {
46195
- name: 'Edge',
46196
- id: 'com.microsoft.edge.old'
46197
- },
46198
- ChromeHTML: {
46199
- name: 'Chrome',
46200
- id: 'com.google.chrome'
46201
- },
46202
- ChromeBHTML: {
46203
- name: 'Chrome Beta',
46204
- id: 'com.google.chrome.beta'
46205
- },
46206
- ChromeDHTML: {
46207
- name: 'Chrome Dev',
46208
- id: 'com.google.chrome.dev'
46209
- },
46210
- ChromiumHTM: {
46211
- name: 'Chromium',
46212
- id: 'org.chromium.Chromium'
46213
- },
46214
- BraveHTML: {
46215
- name: 'Brave',
46216
- id: 'com.brave.Browser'
46217
- },
46218
- BraveBHTML: {
46219
- name: 'Brave Beta',
46220
- id: 'com.brave.Browser.beta'
46221
- },
46222
- BraveDHTML: {
46223
- name: 'Brave Dev',
46224
- id: 'com.brave.Browser.dev'
46225
- },
46226
- BraveSSHTM: {
46227
- name: 'Brave Nightly',
46228
- id: 'com.brave.Browser.nightly'
46229
- },
46230
- FirefoxURL: {
46231
- name: 'Firefox',
46232
- id: 'org.mozilla.firefox'
46233
- },
46234
- OperaStable: {
46235
- name: 'Opera',
46236
- id: 'com.operasoftware.Opera'
46237
- },
46238
- VivaldiHTM: {
46239
- name: 'Vivaldi',
46240
- id: 'com.vivaldi.Vivaldi'
46241
- },
46242
- 'IE.HTTP': {
46243
- name: 'Internet Explorer',
46244
- id: 'com.microsoft.ie'
46245
- }
46246
- };
46247
- new Map(Object.entries(windowsBrowserProgIds));
46248
- class UnknownBrowserError extends Error {
46249
- }
46250
- async function defaultBrowser(_execFileAsync = windows_execFileAsync) {
46251
- const { stdout } = await _execFileAsync('reg', [
46252
- 'QUERY',
46253
- ' HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice',
46254
- '/v',
46255
- 'ProgId'
46256
- ]);
46257
- const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
46258
- if (!match) throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
46259
- const { id } = match.groups;
46260
- const browser = windowsBrowserProgIds[id];
46261
- if (!browser) throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
46262
- return browser;
46263
- }
46264
- const default_browser_execFileAsync = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_namespaceObject.execFile);
46265
- const titleize = (string)=>string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x)=>x.toUpperCase());
46266
- async function default_browser_defaultBrowser() {
46267
- if ('darwin' === external_node_process_namespaceObject.platform) {
46268
- const id = await defaultBrowserId();
46269
- const name = await bundleName(id);
46270
- return {
46271
- name,
46272
- id
46273
- };
46274
- }
46275
- if ('linux' === external_node_process_namespaceObject.platform) {
46276
- const { stdout } = await default_browser_execFileAsync('xdg-mime', [
46277
- 'query',
46278
- 'default',
46279
- 'x-scheme-handler/http'
46280
- ]);
46281
- const id = stdout.trim();
46282
- const name = titleize(id.replace(/.desktop$/, '').replace('-', ' '));
46283
- return {
46284
- name,
46285
- id
46286
- };
46287
- }
46288
- if ('win32' === external_node_process_namespaceObject.platform) return defaultBrowser();
46289
- throw new Error('Only macOS, Linux, and Windows are supported');
46290
- }
46291
- const execFile = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_namespaceObject.execFile);
46292
- const open_dirname = external_node_path_.dirname((0, external_node_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__));
46293
- const localXdgOpenPath = external_node_path_.join(open_dirname, 'xdg-open');
46294
- const { platform: open_platform, arch } = external_node_process_namespaceObject;
46295
- async function getWindowsDefaultBrowserFromWsl() {
46296
- const powershellPath = await powerShellPath();
46297
- const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
46298
- const encodedCommand = external_node_buffer_namespaceObject.Buffer.from(rawCommand, 'utf16le').toString('base64');
46299
- const { stdout } = await execFile(powershellPath, [
46300
- '-NoProfile',
46301
- '-NonInteractive',
46302
- '-ExecutionPolicy',
46303
- 'Bypass',
46304
- '-EncodedCommand',
46305
- encodedCommand
46306
- ], {
46307
- encoding: 'utf8'
46308
- });
46309
- const progId = stdout.trim();
46310
- const browserMap = {
46311
- ChromeHTML: 'com.google.chrome',
46312
- BraveHTML: 'com.brave.Browser',
46313
- MSEdgeHTM: 'com.microsoft.edge',
46314
- FirefoxURL: 'org.mozilla.firefox'
46315
- };
46316
- return browserMap[progId] ? {
46317
- id: browserMap[progId]
46318
- } : {};
46319
- }
46320
- const pTryEach = async (array, mapper)=>{
46321
- let latestError;
46322
- for (const item of array)try {
46323
- return await mapper(item);
46324
- } catch (error) {
46325
- latestError = error;
46326
- }
46327
- throw latestError;
46328
- };
46329
- const baseOpen = async (options)=>{
46330
- options = {
46331
- wait: false,
46332
- background: false,
46333
- newInstance: false,
46334
- allowNonzeroExitCode: false,
46335
- ...options
46336
- };
46337
- if (Array.isArray(options.app)) return pTryEach(options.app, (singleApp)=>baseOpen({
46338
- ...options,
46339
- app: singleApp
46340
- }));
46341
- let { name: app, arguments: appArguments = [] } = options.app ?? {};
46342
- appArguments = [
46343
- ...appArguments
46344
- ];
46345
- if (Array.isArray(app)) return pTryEach(app, (appName)=>baseOpen({
46346
- ...options,
46347
- app: {
46348
- name: appName,
46349
- arguments: appArguments
46350
- }
46351
- }));
46352
- if ('browser' === app || 'browserPrivate' === app) {
46353
- const ids = {
46354
- 'com.google.chrome': 'chrome',
46355
- 'google-chrome.desktop': 'chrome',
46356
- 'com.brave.Browser': 'brave',
46357
- 'org.mozilla.firefox': 'firefox',
46358
- 'firefox.desktop': 'firefox',
46359
- 'com.microsoft.msedge': 'edge',
46360
- 'com.microsoft.edge': 'edge',
46361
- 'com.microsoft.edgemac': 'edge',
46362
- 'microsoft-edge.desktop': 'edge'
46363
- };
46364
- const flags = {
46365
- chrome: '--incognito',
46366
- brave: '--incognito',
46367
- firefox: '--private-window',
46368
- edge: '--inPrivate'
46369
- };
46370
- const browser = is_wsl ? await getWindowsDefaultBrowserFromWsl() : await default_browser_defaultBrowser();
46371
- if (browser.id in ids) {
46372
- const browserName = ids[browser.id];
46373
- if ('browserPrivate' === app) appArguments.push(flags[browserName]);
46374
- return baseOpen({
46375
- ...options,
46376
- app: {
46377
- name: open_apps[browserName],
46378
- arguments: appArguments
46379
- }
46380
- });
46381
- }
46382
- throw new Error(`${browser.name} is not supported as a default browser`);
46383
- }
46384
- let command;
46385
- const cliArguments = [];
46386
- const childProcessOptions = {};
46387
- if ('darwin' === open_platform) {
46388
- command = 'open';
46389
- if (options.wait) cliArguments.push('--wait-apps');
46390
- if (options.background) cliArguments.push('--background');
46391
- if (options.newInstance) cliArguments.push('--new');
46392
- if (app) cliArguments.push('-a', app);
46393
- } else if ('win32' !== open_platform && (!is_wsl || isInsideContainer() || app)) {
46394
- if (app) command = app;
46395
- else {
46396
- const isBundled = !open_dirname || '/' === open_dirname;
46397
- let exeLocalXdgOpen = false;
46398
- try {
46399
- await external_node_fs_promises_namespaceObject.access(localXdgOpenPath, external_node_fs_promises_namespaceObject.constants.X_OK);
46400
- exeLocalXdgOpen = true;
46401
- } catch {}
46402
- const useSystemXdgOpen = external_node_process_namespaceObject.versions.electron ?? ('android' === open_platform || isBundled || !exeLocalXdgOpen);
46403
- command = useSystemXdgOpen ? 'xdg-open' : localXdgOpenPath;
46404
- }
46405
- if (appArguments.length > 0) cliArguments.push(...appArguments);
46406
- if (!options.wait) {
46407
- childProcessOptions.stdio = 'ignore';
46408
- childProcessOptions.detached = true;
46409
- }
46410
- } else {
46411
- command = await powerShellPath();
46412
- cliArguments.push('-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand');
46413
- if (!is_wsl) childProcessOptions.windowsVerbatimArguments = true;
46414
- const encodedArguments = [
46415
- 'Start'
46416
- ];
46417
- if (options.wait) encodedArguments.push('-Wait');
46418
- if (app) {
46419
- encodedArguments.push(`"\`"${app}\`""`);
46420
- if (options.target) appArguments.push(options.target);
46421
- } else if (options.target) encodedArguments.push(`"${options.target}"`);
46422
- if (appArguments.length > 0) {
46423
- appArguments = appArguments.map((argument)=>`"\`"${argument}\`""`);
46424
- encodedArguments.push('-ArgumentList', appArguments.join(','));
46425
- }
46426
- options.target = external_node_buffer_namespaceObject.Buffer.from(encodedArguments.join(' '), 'utf16le').toString('base64');
46427
- }
46428
- if ('darwin' === open_platform && appArguments.length > 0) cliArguments.push('--args', ...appArguments);
46429
- if (options.target) cliArguments.push(options.target);
46430
- const subprocess = external_node_child_process_namespaceObject.spawn(command, cliArguments, childProcessOptions);
46431
- if (options.wait) return new Promise((resolve, reject)=>{
46432
- subprocess.once('error', reject);
46433
- subprocess.once('close', (exitCode)=>{
46434
- if (!options.allowNonzeroExitCode && exitCode > 0) return void reject(new Error(`Exited with code ${exitCode}`));
46435
- resolve(subprocess);
46436
- });
46437
- });
46438
- subprocess.unref();
46439
- return subprocess;
46440
- };
46441
- const open_open = (target, options)=>{
46442
- if ('string' != typeof target) throw new TypeError('Expected a `target`');
46443
- return baseOpen({
46444
- ...options,
46445
- target
46446
- });
46447
- };
46448
- function detectArchBinary(binary) {
46449
- if ('string' == typeof binary || Array.isArray(binary)) return binary;
46450
- const { [arch]: archBinary } = binary;
46451
- if (!archBinary) throw new Error(`${arch} is not supported`);
46452
- return archBinary;
46453
- }
46454
- function detectPlatformBinary({ [open_platform]: platformBinary }, { wsl }) {
46455
- if (wsl && is_wsl) return detectArchBinary(wsl);
46456
- if (!platformBinary) throw new Error(`${open_platform} is not supported`);
46457
- return detectArchBinary(platformBinary);
46458
- }
46459
- const open_apps = {};
46460
- defineLazyProperty(open_apps, 'chrome', ()=>detectPlatformBinary({
46461
- darwin: 'google chrome',
46462
- win32: 'chrome',
46463
- linux: [
46464
- 'google-chrome',
46465
- 'google-chrome-stable',
46466
- 'chromium'
46467
- ]
46468
- }, {
46469
- wsl: {
46470
- ia32: '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe',
46471
- x64: [
46472
- '/mnt/c/Program Files/Google/Chrome/Application/chrome.exe',
46473
- '/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe'
46474
- ]
46475
- }
46476
- }));
46477
- defineLazyProperty(open_apps, 'brave', ()=>detectPlatformBinary({
46478
- darwin: 'brave browser',
46479
- win32: 'brave',
46480
- linux: [
46481
- 'brave-browser',
46482
- 'brave'
46483
- ]
46484
- }, {
46485
- wsl: {
46486
- ia32: '/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe',
46487
- x64: [
46488
- '/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe',
46489
- '/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe'
46490
- ]
46491
- }
46492
- }));
46493
- defineLazyProperty(open_apps, 'firefox', ()=>detectPlatformBinary({
46494
- darwin: 'firefox',
46495
- win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
46496
- linux: 'firefox'
46497
- }, {
46498
- wsl: '/mnt/c/Program Files/Mozilla Firefox/firefox.exe'
46499
- }));
46500
- defineLazyProperty(open_apps, 'edge', ()=>detectPlatformBinary({
46501
- darwin: 'microsoft edge',
46502
- win32: 'msedge',
46503
- linux: [
46504
- 'microsoft-edge',
46505
- 'microsoft-edge-dev'
46506
- ]
46507
- }, {
46508
- wsl: '/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe'
46509
- }));
46510
- defineLazyProperty(open_apps, 'browser', ()=>'browser');
46511
- defineLazyProperty(open_apps, 'browserPrivate', ()=>'browserPrivate');
46512
- const node_modules_open = open_open;
46513
- const successPage = `<!DOCTYPE html>
46514
- <html lang="en">
46515
- <head>
46516
- <meta charset="utf-8" />
46517
- <meta name="viewport" content="width=device-width, initial-scale=1" />
46518
- <title>Anvil Sync • Login Complete</title>
46519
- <link rel="preconnect" href="https://fonts.googleapis.com">
46520
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
46521
- <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
46522
- <style>
46523
- * { box-sizing: border-box; }
46524
- html, body { height: 100%; margin: 0; }
46525
- body {
46526
- font-family: Poppins, -apple-system, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
46527
- color: #555555;
46528
- background: #f7fdff;
46529
- display: flex;
46530
- align-items: center;
46531
- justify-content: center;
46532
- padding: 20px;
46533
- }
46534
- .card {
46535
- width: min(480px, 100%);
46536
- background: #ffffff;
46537
- border-radius: 12px;
46538
- padding: 48px 40px;
46539
- text-align: center;
46540
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
46541
- }
46542
- .icon {
46543
- display: inline-flex;
46544
- align-items: center;
46545
- justify-content: center;
46546
- width: 56px;
46547
- height: 56px;
46548
- margin: 0 auto 24px;
46549
- border-radius: 50%;
46550
- background: #1bb0ee;
46551
- color: white;
46552
- }
46553
- .icon svg {
46554
- width: 28px;
46555
- height: 28px;
46556
- }
46557
- h1 {
46558
- font-size: 24px;
46559
- font-weight: 600;
46560
- line-height: 1.3;
46561
- margin: 0 0 12px;
46562
- color: #1a1a1a;
46563
- }
46564
- p {
46565
- color: #555555;
46566
- font-size: 15px;
46567
- line-height: 1.5;
46568
- margin: 0;
46569
- }
46570
- </style>
46571
- </head>
46572
- <body>
46573
- <main class="card" role="status" aria-live="polite">
46574
- <div class="icon" aria-hidden="true">
46575
- <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
46576
- <path d="M20 7L9 18l-5-5" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
46577
- </svg>
46578
- </div>
46579
- <h1>Anvil login complete</h1>
46580
- <p>Close this window and return to your terminal to continue.</p>
46581
- </main>
46582
- </body>
46583
- </html>`;
46584
- function errorPage(errorMsg) {
46585
- return `<!DOCTYPE html>
46586
- <html lang="en">
46587
- <head>
46588
- <meta charset="utf-8" />
46589
- <meta name="viewport" content="width=device-width, initial-scale=1" />
46590
- <title>Anvil Sync • Login Error</title>
46591
- <link rel="preconnect" href="https://fonts.googleapis.com">
46592
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
46593
- <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
46594
- <style>
46595
- * { box-sizing: border-box; }
46596
- html, body { height: 100%; margin: 0; }
46597
- body {
46598
- font-family: Poppins, -apple-system, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
46599
- color: #555555;
46600
- background: #f7fdff;
46601
- display: flex;
46602
- align-items: center;
46603
- justify-content: center;
46604
- padding: 20px;
46605
- }
46606
- .card {
46607
- width: min(480px, 100%);
46608
- background: #ffffff;
46609
- border-radius: 12px;
46610
- padding: 48px 40px;
46611
- text-align: center;
46612
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
46613
- }
46614
- .icon {
46615
- display: inline-flex;
46616
- align-items: center;
46617
- justify-content: center;
46618
- width: 56px;
46619
- height: 56px;
46620
- margin: 0 auto 24px;
46621
- border-radius: 50%;
46622
- background: #ef4444;
46623
- color: white;
46624
- }
46625
- .icon svg {
46626
- width: 28px;
46627
- height: 28px;
46628
- }
46629
- h1 {
46630
- font-size: 24px;
46631
- font-weight: 600;
46632
- line-height: 1.3;
46633
- margin: 0 0 16px;
46634
- color: #1a1a1a;
46635
- }
46636
- p {
46637
- color: #555555;
46638
- font-size: 15px;
46639
- line-height: 1.5;
46640
- margin: 16px 0 0;
46641
- }
46642
- .details {
46643
- color: #666666;
46644
- font-size: 13px;
46645
- word-break: break-word;
46646
- font-weight: 500;
46647
- font-family: ui-monospace, "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace;
46648
- margin: 16px 0 0;
46649
- padding: 12px;
46650
- background: #f8f9fa;
46651
- border-radius: 6px;
46652
- text-align: left;
46653
- }
46654
- </style>
46655
- </head>
46656
- <body>
46657
- <main class="card" role="status" aria-live="polite">
46658
- <div class="icon" aria-hidden="true">
46659
- <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
46660
- <path d="M15 9l-6 6M9 9l6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
46661
- </svg>
46662
- </div>
46663
- <h1>Anvil login failed</h1>
46664
- <div id="details" class="details">${errorMsg}</div>
46665
- <p>Close this window and return to your terminal to retry.</p>
46666
- </main>
46667
- </body>
46668
- </html>`;
46669
- }
46670
- const CLIENT_ID = "anvil-sync";
46157
+ __webpack_require__("http");
46158
+ require("readline");
46159
+ const CLIENT_ID = ANVIL_SYNC_CLIENT_ID;
46671
46160
  const SCOPES = "apps:read apps:write user:read";
46672
- function oauth_login_base64url(buf) {
46673
- return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
46674
- }
46675
46161
  function sleep(ms) {
46676
46162
  return new Promise((resolve)=>setTimeout(resolve, ms));
46677
46163
  }
46678
- function createBrowserLaunchPrompt(authUrl) {
46679
- if (!process.stdin.isTTY || !process.stdout.isTTY) return {
46680
- waitForOpen: Promise.resolve(false),
46681
- close: ()=>{}
46682
- };
46683
- const rl = external_readline_namespaceObject.createInterface({
46684
- input: process.stdin,
46685
- output: process.stdout
46686
- });
46687
- let closed = false;
46688
- let resolveWait = null;
46689
- const close = (opened = false)=>{
46690
- if (closed) return;
46691
- closed = true;
46692
- rl.close();
46693
- resolveWait?.(opened);
46694
- resolveWait = null;
46695
- };
46696
- const waitForOpen = new Promise((resolve)=>{
46697
- resolveWait = resolve;
46698
- rl.on("SIGINT", ()=>{
46699
- close();
46700
- process.kill(process.pid, "SIGINT");
46701
- });
46702
- rl.question("", async ()=>{
46703
- try {
46704
- await node_modules_open(authUrl);
46705
- logger_logger.info(chalk_source.dim("Opened your browser to continue login."));
46706
- close(true);
46707
- } catch {
46708
- logger_logger.warn("Could not open a browser automatically.");
46709
- close(false);
46710
- }
46711
- });
46712
- });
46713
- return {
46714
- waitForOpen,
46715
- close
46716
- };
46717
- }
46718
46164
  async function parseOAuthError(response) {
46719
46165
  const contentType = response.headers.get("content-type") || "";
46720
46166
  if (contentType.includes("application/json")) {
@@ -46730,23 +46176,6 @@ var __webpack_exports__ = {};
46730
46176
  return text;
46731
46177
  }
46732
46178
  }
46733
- async function exchangeAuthorizationCodeForTokens(anvilUrl, redirectUri, code, codeVerifier) {
46734
- const tokenResponse = await fetch(`${anvilUrl}/oauth/token`, {
46735
- method: "POST",
46736
- headers: {
46737
- "Content-Type": "application/x-www-form-urlencoded"
46738
- },
46739
- body: new URLSearchParams({
46740
- grant_type: "authorization_code",
46741
- code,
46742
- redirect_uri: redirectUri,
46743
- client_id: CLIENT_ID,
46744
- code_verifier: codeVerifier
46745
- })
46746
- });
46747
- if (!tokenResponse.ok) throw new Error(`Failed to exchange authorization code for token. ${await parseOAuthError(tokenResponse)}`);
46748
- return await tokenResponse.json();
46749
- }
46750
46179
  async function requestDeviceAuthorization(anvilUrl) {
46751
46180
  const response = await fetch(`${anvilUrl}/oauth/device_authorization`, {
46752
46181
  method: "POST",
@@ -46794,131 +46223,6 @@ var __webpack_exports__ = {};
46794
46223
  }
46795
46224
  throw new Error("Device login expired before it was approved.");
46796
46225
  }
46797
- async function createPkceLoginFlow(anvilUrl) {
46798
- const codeVerifier = external_crypto_.randomBytes(48).toString("hex");
46799
- const codeChallenge = oauth_login_base64url(external_crypto_.createHash("sha256").update(codeVerifier, "ascii").digest());
46800
- const state = external_crypto_.randomBytes(16).toString("hex");
46801
- const server = external_http_.createServer();
46802
- await new Promise((resolve)=>server.listen(0, "127.0.0.1", resolve));
46803
- const address = server.address();
46804
- if (!address || "string" == typeof address) throw new Error("No address");
46805
- const port = address.port;
46806
- const redirectUri = `http://127.0.0.1:${port}/oauth-callback`;
46807
- const authUrl = new URL(`${anvilUrl}/oauth/authorize`);
46808
- authUrl.searchParams.set("response_type", "code");
46809
- authUrl.searchParams.set("client_id", CLIENT_ID);
46810
- authUrl.searchParams.set("redirect_uri", redirectUri);
46811
- authUrl.searchParams.set("scope", SCOPES);
46812
- authUrl.searchParams.set("state", state);
46813
- authUrl.searchParams.set("code_challenge", codeChallenge);
46814
- authUrl.searchParams.set("code_challenge_method", "S256");
46815
- const codePromise = new Promise((resolve, reject)=>{
46816
- server.on("request", (req, res)=>{
46817
- if (!req.url) return;
46818
- const url = new URL(req.url, `http://127.0.0.1:${port}`);
46819
- if ("/oauth-callback" !== url.pathname) return;
46820
- const code = url.searchParams.get("code") || void 0;
46821
- const error = url.searchParams.get("error") || void 0;
46822
- const recvState = url.searchParams.get("state");
46823
- if (!recvState || !code && !error) {
46824
- res.statusCode = 400;
46825
- res.end("Missing code, error or state");
46826
- reject(new Error("Missing code/state/error"));
46827
- server.close();
46828
- return;
46829
- }
46830
- res.statusCode = 200;
46831
- res.setHeader("Content-Type", "text/html; charset=utf-8");
46832
- if (code) res.end(successPage);
46833
- else res.end(errorPage(error || "unknown"));
46834
- resolve({
46835
- code,
46836
- error,
46837
- recvState
46838
- });
46839
- server.closeAllConnections();
46840
- server.close();
46841
- });
46842
- });
46843
- let closed = false;
46844
- server.on("close", ()=>{
46845
- closed = true;
46846
- });
46847
- const close = async ()=>{
46848
- if (closed) return;
46849
- closed = true;
46850
- server.closeAllConnections();
46851
- if (!server.listening) return;
46852
- await new Promise((resolve)=>server.close(()=>resolve()));
46853
- };
46854
- return {
46855
- authUrl,
46856
- close,
46857
- waitForLogin: (async ()=>{
46858
- const { code, error, recvState } = await codePromise;
46859
- if (recvState !== state) throw new Error("Invalid state received from OAuth callback");
46860
- if (error) throw new Error(`Error received from OAuth callback: ${error}`);
46861
- const tokenData = await exchangeAuthorizationCodeForTokens(anvilUrl, redirectUri, code, codeVerifier);
46862
- return login(anvilUrl, {
46863
- access_token: tokenData.access_token,
46864
- refresh_token: tokenData.refresh_token,
46865
- expires_in: tokenData.expires_in,
46866
- scope: tokenData.scope
46867
- });
46868
- })()
46869
- };
46870
- }
46871
- function raceLoginAttempts(attempts) {
46872
- return new Promise((resolve, reject)=>{
46873
- let remaining = attempts.length;
46874
- let lastError = null;
46875
- for (const attempt of attempts)attempt.then(resolve).catch((error)=>{
46876
- if ("cancelled" === error.message) return;
46877
- remaining -= 1;
46878
- lastError = error;
46879
- if (0 === remaining && lastError) reject(lastError);
46880
- });
46881
- });
46882
- }
46883
- async function runInteractiveLoginFlow(anvilUrl) {
46884
- const pkceFlow = await createPkceLoginFlow(anvilUrl);
46885
- const deviceAuth = await requestDeviceAuthorization(anvilUrl);
46886
- const browserPrompt = createBrowserLaunchPrompt(pkceFlow.authUrl.toString());
46887
- let settled = false;
46888
- let spinnerStarted = false;
46889
- logger_logger.info(chalk_source.dim(`Logging in to ${anvilUrl}`));
46890
- console.log();
46891
- logger_logger.info(chalk_source.dim("Visit:"), `${deviceAuth.verification_uri_complete || deviceAuth.verification_uri}`);
46892
- logger_logger.info(chalk_source.dim("Device code:"), `${deviceAuth.user_code}`);
46893
- console.log();
46894
- logger_logger.info("OR Press ENTER to open a browser...");
46895
- browserPrompt.waitForOpen.then((opened)=>{
46896
- if (opened && !settled) {
46897
- spinnerStarted = true;
46898
- logger_logger.progress("login", "Waiting for login to complete...");
46899
- }
46900
- });
46901
- try {
46902
- const result = await raceLoginAttempts([
46903
- pkceFlow.waitForLogin,
46904
- pollDeviceAuthorization(anvilUrl, deviceAuth, {
46905
- isCancelled: ()=>settled
46906
- }).then(async (tokenData)=>login(anvilUrl, {
46907
- access_token: tokenData.access_token,
46908
- refresh_token: tokenData.refresh_token,
46909
- expires_in: tokenData.expires_in,
46910
- scope: tokenData.scope
46911
- }))
46912
- ]);
46913
- settled = true;
46914
- return result;
46915
- } finally{
46916
- settled = true;
46917
- browserPrompt.close();
46918
- if (spinnerStarted) logger_logger.progressEnd("login");
46919
- await pkceFlow.close();
46920
- }
46921
- }
46922
46226
  function getUrlConfigKey(appId) {
46923
46227
  return `anvil.auth.${appId}.url`;
46924
46228
  }
@@ -47032,539 +46336,6 @@ var __webpack_exports__ = {};
47032
46336
  cleanRemoteUrl
47033
46337
  };
47034
46338
  }
47035
- const defaultDeps = {
47036
- openSystem: async (pathToOpen)=>node_modules_open(pathToOpen),
47037
- isCommandAvailable: isCommandAvailable,
47038
- spawnShellCommand: async (commandLine)=>{
47039
- await new Promise((resolve, reject)=>{
47040
- const child = (0, external_child_process_.spawn)(commandLine, {
47041
- shell: true,
47042
- stdio: "inherit"
47043
- });
47044
- child.on("error", reject);
47045
- child.on("exit", (code)=>{
47046
- if (0 === code || null === code) resolve();
47047
- else reject(new Error(`Editor command exited with code ${code}`));
47048
- });
47049
- });
47050
- }
47051
- };
47052
- function parseCommandTokens(command) {
47053
- const input = command.trim();
47054
- if (!input) return [];
47055
- const tokens = [];
47056
- let current = "";
47057
- let quote = null;
47058
- let escaping = false;
47059
- for(let i = 0; i < input.length; i += 1){
47060
- const ch = input[i];
47061
- if (escaping) {
47062
- current += ch;
47063
- escaping = false;
47064
- continue;
47065
- }
47066
- if ("\\" === ch) {
47067
- escaping = true;
47068
- continue;
47069
- }
47070
- if (quote) {
47071
- if (ch === quote) quote = null;
47072
- else current += ch;
47073
- continue;
47074
- }
47075
- if ('"' === ch || "'" === ch) {
47076
- quote = ch;
47077
- continue;
47078
- }
47079
- if (/\s/.test(ch)) {
47080
- if (current) {
47081
- tokens.push(current);
47082
- current = "";
47083
- }
47084
- continue;
47085
- }
47086
- current += ch;
47087
- }
47088
- if (escaping) current += "\\";
47089
- if (quote) throw new Error(`Unterminated quote in command: ${command}`);
47090
- if (current) tokens.push(current);
47091
- return tokens;
47092
- }
47093
- function quoteForPosixShell(value) {
47094
- if ("" === value) return "''";
47095
- return `'${value.replace(/'/g, "'\"'\"'")}'`;
47096
- }
47097
- function quoteForCmdShell(value) {
47098
- const escaped = value.replace(/[%^&|<>()"!]/g, "^$&");
47099
- return `"${escaped}"`;
47100
- }
47101
- function buildShellCommandLine(tokens) {
47102
- if ("win32" === process.platform) return tokens.map(quoteForCmdShell).join(" ");
47103
- return tokens.map(quoteForPosixShell).join(" ");
47104
- }
47105
- function formatFallbackEditorLabel(preferredEditorCommand) {
47106
- const trimmed = preferredEditorCommand.trim();
47107
- if (!trimmed) return "your editor";
47108
- return trimmed;
47109
- }
47110
- async function path_open_openPathInEditorOrDefault(targetPath, preferredEditorCommand, deps = defaultDeps) {
47111
- if (preferredEditorCommand) if (deps.isCommandAvailable(preferredEditorCommand)) try {
47112
- const tokens = parseCommandTokens(preferredEditorCommand);
47113
- if (0 === tokens.length) throw new Error("empty command");
47114
- await deps.spawnShellCommand(buildShellCommandLine([
47115
- ...tokens,
47116
- targetPath
47117
- ]));
47118
- return;
47119
- } catch (error) {
47120
- logger_logger.warn(`Failed to open ${formatFallbackEditorLabel(preferredEditorCommand)} automatically: ${errors_getErrorMessage(error)}.`);
47121
- }
47122
- else logger_logger.info(`Open ${formatFallbackEditorLabel(preferredEditorCommand)} to edit your app.`);
47123
- await deps.openSystem(targetPath);
47124
- }
47125
- const CHECKOUT_ERROR_VALUE = "__ERROR__";
47126
- function isAbortLikeError(error) {
47127
- if (error instanceof Error && "AbortError" === error.name) return true;
47128
- if ("object" == typeof error && null !== error) {
47129
- const maybeType = error.type;
47130
- const maybeMessage = error.message;
47131
- if ("network_error" === maybeType && "string" == typeof maybeMessage && maybeMessage.toLowerCase().includes("abort")) return true;
47132
- }
47133
- const message = errors_getErrorMessage(error).toLowerCase();
47134
- return "aborted" === message || message.includes("aborted");
47135
- }
47136
- function normalizePickerQuery(term) {
47137
- return (term || "").trim();
47138
- }
47139
- function parseNonNegativeMs(raw) {
47140
- if (null == raw) return null;
47141
- const parsed = Number(raw);
47142
- if (!Number.isFinite(parsed) || parsed < 0) return null;
47143
- return parsed;
47144
- }
47145
- function getCheckoutPickerDelayMs() {
47146
- const fromEnv = parseNonNegativeMs(process.env.ANVIL_CHECKOUT_PICKER_DELAY_MS);
47147
- if (null != fromEnv) return fromEnv;
47148
- return 0;
47149
- }
47150
- function getCheckoutPickerPaginationDelayMs() {
47151
- return getCheckoutPickerDelayMs();
47152
- }
47153
- function getCheckoutPickerMaxRows() {
47154
- const raw = process.env.ANVIL_CHECKOUT_PICKER_MAX_ROWS;
47155
- const fromEnv = null == raw ? NaN : Number(raw);
47156
- if (null != raw && Number.isFinite(fromEnv) && fromEnv >= 4) return Math.floor(fromEnv);
47157
- return 12;
47158
- }
47159
- function formatLastEdited(lastEdited) {
47160
- if (!lastEdited) return;
47161
- return chalk_source.gray(`Last edited: ${lastEdited}`);
47162
- }
47163
- function formatAppPickerLabel(app) {
47164
- const appName = app.app_name || "Unnamed App";
47165
- return `${chalk_source.cyan(appName)} ${chalk_source.gray(`(${app.app_id})`)}`;
47166
- }
47167
- async function waitForDebounce(ms, signal) {
47168
- if (ms <= 0) return;
47169
- if (signal.aborted) throw new Error("aborted");
47170
- await new Promise((resolve, reject)=>{
47171
- const timer = setTimeout(()=>{
47172
- cleanup();
47173
- resolve();
47174
- }, ms);
47175
- const onAbort = ()=>{
47176
- cleanup();
47177
- reject(new Error("aborted"));
47178
- };
47179
- const cleanup = ()=>{
47180
- clearTimeout(timer);
47181
- signal.removeEventListener("abort", onAbort);
47182
- };
47183
- signal.addEventListener("abort", onAbort, {
47184
- once: true
47185
- });
47186
- });
47187
- }
47188
- function createCheckoutPickerSource(anvilUrl, username, deps, options = {}) {
47189
- const pageSize = options.pageSize ?? 20;
47190
- const debounceMs = options.debounceMs ?? 200;
47191
- const staleTimeMs = options.staleTimeMs ?? 30000;
47192
- const maxAutoPagesPerCall = options.maxAutoPagesPerCall ?? 8;
47193
- const initialQuery = normalizePickerQuery(options.initialQuery);
47194
- const simulatedDelayMs = getCheckoutPickerDelayMs();
47195
- const paginationDelayMs = getCheckoutPickerPaginationDelayMs();
47196
- const cache = new Map();
47197
- const getState = (query)=>{
47198
- const existing = cache.get(query);
47199
- if (existing) return existing;
47200
- const created = {
47201
- items: [],
47202
- nextCursor: null,
47203
- exhausted: false,
47204
- lastError: null,
47205
- updatedAt: 0,
47206
- inFlight: null
47207
- };
47208
- cache.set(query, created);
47209
- return created;
47210
- };
47211
- const fetchPage = async (query, signal, options = {})=>{
47212
- const state = getState(query);
47213
- if (state.inFlight) return void await state.inFlight;
47214
- state.inFlight = (async ()=>{
47215
- try {
47216
- if (simulatedDelayMs > 0) await new Promise((resolve)=>setTimeout(resolve, simulatedDelayMs));
47217
- if (options.cursor && paginationDelayMs > 0) await new Promise((resolve)=>setTimeout(resolve, paginationDelayMs));
47218
- const response = await deps.listAppsForCheckout({
47219
- anvilUrl,
47220
- username,
47221
- limit: pageSize,
47222
- cursor: options.cursor,
47223
- q: query || void 0,
47224
- signal
47225
- });
47226
- if (options.reset) state.items = [
47227
- ...response.apps
47228
- ];
47229
- else state.items.push(...response.apps);
47230
- state.nextCursor = response.next_cursor;
47231
- state.exhausted = !response.next_cursor;
47232
- state.lastError = null;
47233
- state.updatedAt = Date.now();
47234
- } catch (e) {
47235
- if (!signal.aborted && !isAbortLikeError(e)) {
47236
- const message = errors_getErrorMessage(e);
47237
- state.lastError = message;
47238
- state.updatedAt = Date.now();
47239
- }
47240
- } finally{
47241
- state.inFlight = null;
47242
- }
47243
- })();
47244
- await state.inFlight;
47245
- };
47246
- const ensureLoaded = async (query, signal)=>{
47247
- const state = getState(query);
47248
- const isStale = Date.now() - state.updatedAt > staleTimeMs;
47249
- if (0 === state.items.length) {
47250
- await waitForDebounce(debounceMs, signal);
47251
- await fetchPage(query, signal, {
47252
- cursor: void 0,
47253
- reset: false
47254
- });
47255
- } else if (state.lastError) {
47256
- await waitForDebounce(debounceMs, signal);
47257
- await fetchPage(query, signal, {
47258
- cursor: void 0,
47259
- reset: true
47260
- });
47261
- } else if (isStale) {
47262
- await waitForDebounce(debounceMs, signal);
47263
- await fetchPage(query, signal, {
47264
- cursor: void 0,
47265
- reset: true
47266
- });
47267
- }
47268
- let pagesLoaded = 0;
47269
- while(state.nextCursor && pagesLoaded < maxAutoPagesPerCall){
47270
- if (signal.aborted) throw new Error("aborted");
47271
- const cursor = state.nextCursor;
47272
- await fetchPage(query, signal, {
47273
- cursor,
47274
- reset: false
47275
- });
47276
- pagesLoaded += 1;
47277
- }
47278
- };
47279
- return {
47280
- source: async (term, { signal })=>{
47281
- const query = normalizePickerQuery(term) || initialQuery;
47282
- if (signal.aborted) return [];
47283
- await ensureLoaded(query, signal);
47284
- const state = getState(query);
47285
- if (state.lastError) return [
47286
- {
47287
- name: `${chalk_source.yellow("Fetch failed")} ${chalk_source.gray(`(${state.lastError})`)}`,
47288
- value: CHECKOUT_ERROR_VALUE,
47289
- disabled: true
47290
- }
47291
- ];
47292
- const summary = state.nextCursor ? chalk_source.gray(`Loaded ${state.items.length} apps • more available`) : chalk_source.gray(`Loaded ${state.items.length} apps`);
47293
- const choices = state.items.map((app)=>({
47294
- name: formatAppPickerLabel(app),
47295
- value: app.app_id,
47296
- description: formatLastEdited(app.last_edited)
47297
- }));
47298
- choices.unshift({
47299
- name: summary,
47300
- value: CHECKOUT_ERROR_VALUE,
47301
- disabled: true
47302
- });
47303
- return choices;
47304
- }
47305
- };
47306
- }
47307
- const INLINE_SPINNER_FRAMES = [
47308
- "⠋",
47309
- "⠙",
47310
- "⠹",
47311
- "⠸",
47312
- "⠼",
47313
- "⠴",
47314
- "⠦",
47315
- "⠧",
47316
- "⠇",
47317
- "⠏"
47318
- ];
47319
- async function runCustomCheckoutPicker(anvilUrl, username, deps, initialQuery) {
47320
- if (!process.stdin.isTTY || !process.stdout.isTTY) return null;
47321
- const pageSize = 20;
47322
- const staleTimeMs = 30000;
47323
- const debounceMs = 180;
47324
- const simulatedDelayMs = getCheckoutPickerDelayMs();
47325
- const paginationDelayMs = getCheckoutPickerPaginationDelayMs();
47326
- const maxVisibleRows = getCheckoutPickerMaxRows();
47327
- const cache = new Map();
47328
- let query = normalizePickerQuery(initialQuery);
47329
- let selectedIndex = 0;
47330
- let scrollOffset = 0;
47331
- let loading = false;
47332
- let loadingMore = false;
47333
- let done = false;
47334
- let pendingTimer = null;
47335
- let loadingRenderTimer = null;
47336
- let activeController = null;
47337
- let resolveResult = null;
47338
- const ensureState = (key)=>{
47339
- const existing = cache.get(key);
47340
- if (existing) return existing;
47341
- const created = {
47342
- items: [],
47343
- nextCursor: null,
47344
- lastError: null,
47345
- updatedAt: 0
47346
- };
47347
- cache.set(key, created);
47348
- return created;
47349
- };
47350
- const currentState = ()=>ensureState(query);
47351
- const clearScreen = ()=>{
47352
- process.stdout.write("\x1b[2J\x1b[H");
47353
- };
47354
- const visibleRows = ()=>{
47355
- const rows = process.stdout.rows || 24;
47356
- return Math.min(maxVisibleRows, Math.max(6, rows - 9));
47357
- };
47358
- const syncViewport = ()=>{
47359
- const items = currentState().items;
47360
- if (selectedIndex >= items.length) selectedIndex = Math.max(0, items.length - 1);
47361
- const height = visibleRows();
47362
- if (selectedIndex < scrollOffset) scrollOffset = selectedIndex;
47363
- else if (selectedIndex >= scrollOffset + height) scrollOffset = Math.max(0, selectedIndex - height + 1);
47364
- };
47365
- const render = ()=>{
47366
- clearScreen();
47367
- const state = currentState();
47368
- const items = state.items;
47369
- const activeQuery = query || chalk_source.gray("(all apps)");
47370
- const spinnerFrame = INLINE_SPINNER_FRAMES[Math.floor(Date.now() / 120) % INLINE_SPINNER_FRAMES.length];
47371
- const status = loading ? loadingMore ? chalk_source.yellow(`${spinnerFrame} Loading more apps... (${items.length} loaded)`) : chalk_source.yellow(`${spinnerFrame} Loading apps...`) : state.nextCursor ? chalk_source.gray(`Loaded ${items.length} apps • more available`) : chalk_source.gray(`Loaded ${items.length} apps`);
47372
- process.stdout.write(`${chalk_source.bold("Search apps by name or app ID")}\n`);
47373
- process.stdout.write(`${chalk_source.cyan("Query:")} ${activeQuery}\n`);
47374
- process.stdout.write(`${status}\n`);
47375
- if (state.lastError) process.stdout.write(`${chalk_source.red(`Fetch failed: ${state.lastError}`)}\n`);
47376
- const height = visibleRows();
47377
- const start = scrollOffset;
47378
- const end = Math.min(items.length, start + height);
47379
- if (0 !== items.length || loading || state.lastError) for(let i = start; i < end; i += 1){
47380
- const item = items[i];
47381
- const label = formatAppPickerLabel(item);
47382
- const line = i === selectedIndex ? `${chalk_source.green("❯")} ${label}` : ` ${label}`;
47383
- process.stdout.write(`${line}\n`);
47384
- }
47385
- else process.stdout.write(`${chalk_source.gray("No matches. Keep typing.")}\n`);
47386
- process.stdout.write(`\n${chalk_source.gray("↑/↓ navigate • type to search • enter select • esc/ctrl+c cancel")}\n`);
47387
- };
47388
- const fetchPage = async (key, cursor)=>{
47389
- const state = ensureState(key);
47390
- const controller = new AbortController();
47391
- if (!cursor && activeController) activeController.abort();
47392
- activeController = controller;
47393
- loading = true;
47394
- loadingMore = !!cursor;
47395
- startLoadingAnimation();
47396
- render();
47397
- try {
47398
- if (simulatedDelayMs > 0) await new Promise((resolve)=>setTimeout(resolve, simulatedDelayMs));
47399
- if (cursor && paginationDelayMs > 0) await new Promise((resolve)=>setTimeout(resolve, paginationDelayMs));
47400
- const response = await deps.listAppsForCheckout({
47401
- anvilUrl,
47402
- username,
47403
- limit: pageSize,
47404
- cursor,
47405
- q: key || void 0,
47406
- signal: controller.signal
47407
- });
47408
- const merged = cursor ? state.items.concat(response.apps) : response.apps;
47409
- cache.set(key, {
47410
- items: merged,
47411
- nextCursor: response.next_cursor,
47412
- lastError: null,
47413
- updatedAt: Date.now()
47414
- });
47415
- if (key === query) syncViewport();
47416
- } catch (e) {
47417
- if (!controller.signal.aborted && !isAbortLikeError(e)) {
47418
- const message = errors_getErrorMessage(e);
47419
- cache.set(key, {
47420
- ...state,
47421
- lastError: message,
47422
- updatedAt: Date.now()
47423
- });
47424
- }
47425
- } finally{
47426
- if (activeController === controller) activeController = null;
47427
- loading = false;
47428
- loadingMore = false;
47429
- stopLoadingAnimation();
47430
- render();
47431
- }
47432
- };
47433
- const ensureFresh = async (key)=>{
47434
- const state = ensureState(key);
47435
- const stale = Date.now() - state.updatedAt > staleTimeMs;
47436
- if (0 === state.items.length || stale || state.lastError) await fetchPage(key);
47437
- else render();
47438
- };
47439
- const maybeLoadMore = async ()=>{
47440
- const state = currentState();
47441
- if (!state.nextCursor || loading) return;
47442
- if (selectedIndex >= Math.max(0, state.items.length - 2)) await fetchPage(query, state.nextCursor || void 0);
47443
- };
47444
- const scheduleQueryFetch = ()=>{
47445
- if (pendingTimer) clearTimeout(pendingTimer);
47446
- pendingTimer = setTimeout(()=>{
47447
- pendingTimer = null;
47448
- ensureFresh(query);
47449
- }, debounceMs);
47450
- };
47451
- const startLoadingAnimation = ()=>{
47452
- if (loadingRenderTimer) return;
47453
- loadingRenderTimer = setInterval(()=>{
47454
- if (!done && loading) render();
47455
- }, 120);
47456
- };
47457
- const stopLoadingAnimation = ()=>{
47458
- if (!loadingRenderTimer) return;
47459
- clearInterval(loadingRenderTimer);
47460
- loadingRenderTimer = null;
47461
- };
47462
- const finish = (value)=>{
47463
- done = true;
47464
- if (pendingTimer) {
47465
- clearTimeout(pendingTimer);
47466
- pendingTimer = null;
47467
- }
47468
- if (activeController) {
47469
- activeController.abort();
47470
- activeController = null;
47471
- }
47472
- stopLoadingAnimation();
47473
- process.stdin.removeListener("keypress", onKeypress);
47474
- if (process.stdin.isTTY && process.stdin.setRawMode) process.stdin.setRawMode(false);
47475
- process.stdin.pause();
47476
- clearScreen();
47477
- if (resolveResult) resolveResult(value);
47478
- };
47479
- const onKeypress = (_str, key)=>{
47480
- if (done) return;
47481
- if (key.ctrl && "c" === key.name) return void finish(null);
47482
- if ("escape" === key.name) return void finish(null);
47483
- if ("return" === key.name) {
47484
- const state = currentState();
47485
- const selected = state.items[selectedIndex];
47486
- finish(selected ? selected.app_id : null);
47487
- return;
47488
- }
47489
- if ("up" === key.name) {
47490
- if (selectedIndex > 0) {
47491
- selectedIndex -= 1;
47492
- syncViewport();
47493
- render();
47494
- }
47495
- return;
47496
- }
47497
- if ("down" === key.name) {
47498
- const maxIndex = Math.max(0, currentState().items.length - 1);
47499
- if (selectedIndex < maxIndex) {
47500
- selectedIndex += 1;
47501
- syncViewport();
47502
- render();
47503
- maybeLoadMore();
47504
- }
47505
- return;
47506
- }
47507
- if ("backspace" === key.name || "delete" === key.name) {
47508
- if (query.length > 0) {
47509
- query = query.slice(0, -1);
47510
- selectedIndex = 0;
47511
- scrollOffset = 0;
47512
- render();
47513
- scheduleQueryFetch();
47514
- }
47515
- return;
47516
- }
47517
- if (!key.ctrl && !key.meta && key.sequence && 1 === key.sequence.length && key.sequence >= " ") {
47518
- query += key.sequence;
47519
- selectedIndex = 0;
47520
- scrollOffset = 0;
47521
- render();
47522
- scheduleQueryFetch();
47523
- }
47524
- };
47525
- logger_logger.pause();
47526
- try {
47527
- external_readline_default().emitKeypressEvents(process.stdin);
47528
- if (process.stdin.isTTY && process.stdin.setRawMode) process.stdin.setRawMode(true);
47529
- process.stdin.resume();
47530
- process.stdin.on("keypress", onKeypress);
47531
- await ensureFresh(query);
47532
- return await new Promise((resolve)=>{
47533
- resolveResult = resolve;
47534
- });
47535
- } finally{
47536
- logger_logger.resume();
47537
- }
47538
- }
47539
- async function selectAppForCheckout(anvilUrl, username, deps, initialQuery) {
47540
- if (!isTestMode() && "1" !== process.env.ANVIL_CHECKOUT_LEGACY_PICKER) return runCustomCheckoutPicker(anvilUrl, username, deps, initialQuery);
47541
- const picker = createCheckoutPickerSource(anvilUrl, username, deps, {
47542
- initialQuery
47543
- });
47544
- try {
47545
- const answer = await logger_logger.prompt([
47546
- {
47547
- type: "search",
47548
- name: "value",
47549
- message: "Search apps by name or app ID",
47550
- source: picker.source,
47551
- pageSize: 12,
47552
- loop: false,
47553
- instructions: {
47554
- navigation: "↑↓ navigate • type to filter",
47555
- pager: "enter select • ctrl+c cancel"
47556
- }
47557
- }
47558
- ]);
47559
- const selected = String(answer.value || "");
47560
- if (!selected || selected === CHECKOUT_ERROR_VALUE) return null;
47561
- return selected;
47562
- } catch (e) {
47563
- const err = e;
47564
- if ("ExitPromptError" === err.name || String(err.message || "").includes("User force closed")) return null;
47565
- throw e;
47566
- }
47567
- }
47568
46339
  const isUpKey = (key, keybindings = [])=>'up' === key.name || keybindings.includes('vim') && 'k' === key.name || keybindings.includes('emacs') && key.ctrl && 'p' === key.name;
47569
46340
  const isDownKey = (key, keybindings = [])=>'down' === key.name || keybindings.includes('vim') && 'j' === key.name || keybindings.includes('emacs') && key.ctrl && 'n' === key.name;
47570
46341
  const isSpaceKey = (key)=>'space' === key.name;
@@ -49974,7 +48745,7 @@ var __webpack_exports__ = {};
49974
48745
  }
49975
48746
  createPromptModule();
49976
48747
  resolveAnvilUrl();
49977
- function decideFallbackUrl(explicitUrl, availableUrls = getAvailableAnvilUrls()) {
48748
+ function watch_decideFallbackUrl(explicitUrl, availableUrls = getAvailableAnvilUrls()) {
49978
48749
  if (explicitUrl) return {
49979
48750
  source: "explicit",
49980
48751
  url: config_normalizeAnvilUrl(explicitUrl)
@@ -50001,7 +48772,6 @@ var __webpack_exports__ = {};
50001
48772
  getValidAuthToken: auth_getValidAuthToken,
50002
48773
  validateAppId: anvil_api_validateAppId,
50003
48774
  listAppsForCheckout: listAppsForCheckout,
50004
- runInteractiveLoginFlow: runInteractiveLoginFlow,
50005
48775
  clone: async (repoUrl, destinationPath, options)=>{
50006
48776
  const cloneArgs = [];
50007
48777
  if (options?.branch) cloneArgs.push("--branch", options.branch);
@@ -50014,9 +48784,6 @@ var __webpack_exports__ = {};
50014
48784
  },
50015
48785
  hardenCheckoutGitAuth: hardenCheckoutGitAuth
50016
48786
  };
50017
- function isInteractiveSession() {
50018
- return !!(process.stdin.isTTY && process.stdout.isTTY);
50019
- }
50020
48787
  function parseCheckoutInput(input) {
50021
48788
  const trimmed = input.trim();
50022
48789
  if (!trimmed) throw new Error("Input is required.");
@@ -50058,29 +48825,12 @@ var __webpack_exports__ = {};
50058
48825
  }
50059
48826
  return appId;
50060
48827
  }
50061
- async function resolveCheckoutUrl(explicitUrl, parsedUrl) {
50062
- if (explicitUrl) {
50063
- logger_logger.verbose(chalk_source.cyan("Using Anvil URL from --url: ") + chalk_source.bold(config_normalizeAnvilUrl(explicitUrl)));
50064
- return config_normalizeAnvilUrl(explicitUrl);
50065
- }
50066
- if (parsedUrl) {
50067
- logger_logger.verbose(chalk_source.cyan("Using Anvil URL from checkout input: ") + chalk_source.bold(config_normalizeAnvilUrl(parsedUrl)));
50068
- return config_normalizeAnvilUrl(parsedUrl);
50069
- }
50070
- const decision = decideFallbackUrl(void 0);
50071
- if ("available-multiple" !== decision.source) {
50072
- if (decision.url) logger_logger.verbose(chalk_source.cyan("Using configured Anvil URL: ") + chalk_source.bold(decision.url));
50073
- return decision.url;
50074
- }
50075
- const choices = decision.urls.map((url)=>({
50076
- name: url,
50077
- value: url
50078
- }));
50079
- choices.push({
50080
- name: "Cancel",
50081
- value: null
50082
- });
50083
- return logger_logger.select("Multiple logged-in Anvil URLs found. Which one would you like to use?", choices, decision.urls[0]);
48828
+ function resolveCheckoutUrlForApi(explicitUrl, parsedUrl) {
48829
+ if (explicitUrl) return config_normalizeAnvilUrl(explicitUrl);
48830
+ if (parsedUrl) return config_normalizeAnvilUrl(parsedUrl);
48831
+ const decision = watch_decideFallbackUrl(void 0);
48832
+ if ("available-multiple" === decision.source) throw new Error(`Multiple logged-in Anvil URLs found: ${decision.urls.join(", ")}. Use --url <ANVIL_URL> to choose one.`);
48833
+ return decision.url;
50084
48834
  }
50085
48835
  async function isPathInsideGitRepo(targetPath) {
50086
48836
  const resolved = external_path_default().resolve(targetPath);
@@ -50120,64 +48870,31 @@ var __webpack_exports__ = {};
50120
48870
  logger_logger.verbose(chalk_source.cyan("Checking auth token for: ") + chalk_source.bold(username ? `${username} @ ${anvilUrl}` : anvilUrl));
50121
48871
  return await deps.getValidAuthToken(anvilUrl, username);
50122
48872
  } catch (e) {
50123
- const interactive = process.stdin.isTTY && process.stdout.isTTY;
50124
- if (!interactive) throw createAuthError.required(`Not logged in to ${anvilUrl}. Run 'anvil login ${anvilUrl}' and retry.`);
50125
- const shouldLogin = await logger_logger.confirm(`Not logged in to ${anvilUrl}. Log in now?`, true);
50126
- if (!shouldLogin) throw createAuthError.required(`Not logged in to ${anvilUrl}. Run 'anvil login ${anvilUrl}' and retry.`);
50127
- await deps.runInteractiveLoginFlow(anvilUrl);
50128
- return deps.getValidAuthToken(anvilUrl, username);
48873
+ throw createAuthError.required(`Not logged in to ${anvilUrl}. Run 'anvil login ${anvilUrl}' and retry.`);
50129
48874
  }
50130
48875
  }
50131
- async function resolveCheckoutUsername(anvilUrl, explicitUsername, getAccounts = auth_getAccountsForUrl) {
48876
+ function resolveCheckoutUsernameForApi(anvilUrl, explicitUsername) {
50132
48877
  if (explicitUsername) return explicitUsername;
50133
- const accounts = getAccounts(anvilUrl);
48878
+ const accounts = auth_getAccountsForUrl(anvilUrl);
50134
48879
  if (0 === accounts.length) return;
50135
- if (1 === accounts.length) {
50136
- logger_logger.verbose(chalk_source.cyan("Auto-selected account: ") + chalk_source.bold(accounts[0]));
50137
- return accounts[0];
50138
- }
50139
- const interactive = process.stdin.isTTY && process.stdout.isTTY;
50140
- if (!interactive) throw new Error(`Multiple accounts found for ${anvilUrl}. Use --user <USERNAME> to choose one.`);
50141
- const choices = accounts.map((acct)=>({
50142
- name: acct,
50143
- value: acct
50144
- }));
50145
- choices.push({
50146
- name: "Cancel",
50147
- value: null
50148
- });
50149
- return logger_logger.select(`Multiple accounts found for ${anvilUrl}. Which account should be used for checkout?`, choices, accounts[0]);
48880
+ if (1 === accounts.length) return accounts[0];
48881
+ throw new Error(`Multiple accounts found for ${anvilUrl}: ${accounts.join(", ")}. Use --user <USERNAME> to choose one.`);
50150
48882
  }
50151
48883
  async function executeCheckout(options, deps = defaultCheckoutDeps) {
50152
48884
  let checkoutInput = options.input?.trim();
50153
- let preselectedAnvilUrl;
50154
- let preselectedUsername;
50155
- if (!checkoutInput) {
50156
- if (!isInteractiveSession()) throw new Error("`anvil checkout` without arguments requires an interactive TTY. Pass APP_ID or URL explicitly in non-interactive mode.");
50157
- const selectedUrl = await resolveCheckoutUrl(options.url);
50158
- if (!selectedUrl) return void logger_logger.info("Checkout cancelled.");
50159
- preselectedAnvilUrl = selectedUrl;
50160
- const selectedUsername = await resolveCheckoutUsername(selectedUrl, options.user);
50161
- if (null === selectedUsername) return void logger_logger.info("Checkout cancelled.");
50162
- preselectedUsername = selectedUsername || void 0;
50163
- const selectedInput = await selectAppForCheckout(selectedUrl, preselectedUsername, deps, options.query);
50164
- if (!selectedInput) return void logger_logger.info("Checkout cancelled.");
50165
- checkoutInput = selectedInput;
50166
- }
48885
+ if (!checkoutInput) throw new Error("Checkout input is required. Pass an app ID, editor URL, or /git URL explicitly.");
50167
48886
  logger_logger.verbose(chalk_source.cyan("Checkout input: ") + chalk_source.bold(checkoutInput));
50168
48887
  const parsed = parseCheckoutInput(checkoutInput);
50169
48888
  logger_logger.verbose(chalk_source.cyan("Resolved app ID: ") + chalk_source.bold(parsed.appId));
50170
- const anvilUrl = preselectedAnvilUrl || await resolveCheckoutUrl(options.url, parsed.detectedUrl);
50171
- if (!anvilUrl) return void logger_logger.info("Checkout cancelled.");
50172
- const resolvedUsername = preselectedUsername || await resolveCheckoutUsername(anvilUrl, options.user);
50173
- if (null === resolvedUsername) return void logger_logger.info("Checkout cancelled.");
48889
+ const anvilUrl = resolveCheckoutUrlForApi(options.url, parsed.detectedUrl);
48890
+ if (!anvilUrl) throw new Error("Anvil URL is required. Use --url <ANVIL_URL> or pass an input URL containing the host.");
48891
+ const resolvedUsername = resolveCheckoutUsernameForApi(anvilUrl, options.user);
50174
48892
  if (resolvedUsername) logger_logger.verbose(chalk_source.cyan("Using account: ") + chalk_source.bold(resolvedUsername));
50175
48893
  else logger_logger.verbose(chalk_source.cyan("No account preselected; resolving after auth token lookup."));
50176
48894
  const authToken = await ensureCheckoutAuthToken(anvilUrl, resolvedUsername, deps);
50177
48895
  let checkoutUsername = resolvedUsername;
50178
48896
  if (!checkoutUsername) {
50179
- const inferredUsername = await resolveCheckoutUsername(anvilUrl, void 0);
50180
- if (null === inferredUsername) return void logger_logger.info("Checkout cancelled.");
48897
+ const inferredUsername = resolveCheckoutUsernameForApi(anvilUrl, void 0);
50181
48898
  if (!inferredUsername) throw new Error(`Could not determine account for ${anvilUrl}. Use --user <USERNAME> so checkout can bind repository credentials.`);
50182
48899
  checkoutUsername = inferredUsername;
50183
48900
  }
@@ -50197,8 +48914,6 @@ var __webpack_exports__ = {};
50197
48914
  if (options.branch) logger_logger.verbose(chalk_source.cyan("Requested branch: ") + chalk_source.bold(options.branch));
50198
48915
  if ("number" == typeof options.depth) logger_logger.verbose(chalk_source.cyan("Clone depth: ") + chalk_source.bold(String(options.depth)));
50199
48916
  if (options.singleBranch) logger_logger.verbose(chalk_source.cyan("Single-branch clone enabled"));
50200
- logger_logger.progress("checkout", `Checking out app ${parsed.appId} from ${anvilUrl}`);
50201
- logger_logger.info(chalk_source.gray(` Destination directory: ${destinationDisplay}`));
50202
48917
  await deps.clone(cloneUrl, destinationPath, {
50203
48918
  branch: options.branch,
50204
48919
  depth: options.depth,
@@ -50220,18 +48935,15 @@ var __webpack_exports__ = {};
50220
48935
  } catch (e) {
50221
48936
  throw new Error(`Checkout clone succeeded, but failed to configure repository credentials: ${errors_getErrorMessage(e)}. The repository exists at ${destinationDisplay}, but Git auth bridge setup is incomplete.`);
50222
48937
  }
50223
- logger_logger.progressEnd("checkout", `Checked out ${parsed.appId} into ${destinationDisplay}`);
50224
- const preferredEditor = String(config_getConfig("preferredEditor") || "").trim();
50225
- const preferredEditorCommand = preferredEditor ? config_getPreferredEditorCommand(preferredEditor) : "";
50226
- if (options.open) {
50227
- await checkout_openPathInEditorOrDefault(destinationPath, preferredEditorCommand);
50228
- logger_logger.info(chalk_source.gray(`Opened ${destinationDisplay}`));
50229
- }
50230
- if (preferredEditorCommand && !options.open) if (isCommandAvailable(preferredEditorCommand)) logger_logger.info(chalk_source.cyan(`Next: ${preferredEditorCommand} ${destinationDisplay}`));
50231
- else logger_logger.warn(`Preferred editor command '${preferredEditorCommand}' was not found in PATH. Run 'anvil configure' to choose an installed editor.`);
50232
- }
50233
- async function checkout_openPathInEditorOrDefault(destinationPath, preferredEditorCommand, deps) {
50234
- await path_open_openPathInEditorOrDefault(destinationPath, preferredEditorCommand, deps);
48938
+ return {
48939
+ appId: parsed.appId,
48940
+ appName: validation.app_name,
48941
+ anvilUrl,
48942
+ destinationPath,
48943
+ destinationDisplay,
48944
+ username: checkoutUsername,
48945
+ remoteName
48946
+ };
50235
48947
  }
50236
48948
  const api_DEFAULT_ANVIL_URL = resolveAnvilUrl();
50237
48949
  async function api_checkUncommittedChanges(repoPath) {
@@ -50254,7 +48966,8 @@ var __webpack_exports__ = {};
50254
48966
  throw errors_createGitError.commandFailed("status", e.message);
50255
48967
  }
50256
48968
  }
50257
- async function src_api_syncToLatest(repoPath, appId, anvilUrl, authToken, currentBranch, username) {
48969
+ async function src_api_syncToLatest(repoPath, appId, options) {
48970
+ const { anvilUrl, authToken, currentBranch, username } = options;
50258
48971
  try {
50259
48972
  const git = esm_default(repoPath);
50260
48973
  const commitId = (await git.revparse([
@@ -50278,7 +48991,8 @@ var __webpack_exports__ = {};
50278
48991
  throw errors_createGitError.commandFailed("sync", e instanceof Error ? e.message : String(e));
50279
48992
  }
50280
48993
  }
50281
- async function src_api_watch(repoPath, appId, anvilUrl = api_DEFAULT_ANVIL_URL, stagedOnly = false, username) {
48994
+ async function src_api_watch(repoPath, appId, options = {}) {
48995
+ const { anvilUrl = api_DEFAULT_ANVIL_URL, stagedOnly = false, username } = options;
50282
48996
  repoPath = external_path_default().resolve(repoPath);
50283
48997
  const authToken = await auth_getValidAuthToken(anvilUrl, username);
50284
48998
  await auth_verifyAuth(authToken, anvilUrl);
@@ -50305,7 +49019,11 @@ var __webpack_exports__ = {};
50305
49019
  }
50306
49020
  logger_logger.verbose(chalk_source.cyan("Current branch: ") + chalk_source.bold(currentBranch));
50307
49021
  logger_logger.verbose(chalk_source.cyan("Current commit ID: ") + chalk_source.gray(commitId));
50308
- const syncStatus = await validation_validateBranchSyncStatus(git, currentBranch, appId, anvilUrl, username);
49022
+ const syncStatus = await validation_validateBranchSyncStatus(git, currentBranch, {
49023
+ appId,
49024
+ anvilUrl,
49025
+ username
49026
+ });
50309
49027
  let hasUncommittedChanges = false;
50310
49028
  try {
50311
49029
  const status = await git.status();
@@ -50350,6 +49068,7 @@ var __webpack_exports__ = {};
50350
49068
  return session;
50351
49069
  }
50352
49070
  })();
49071
+ exports.ANVIL_SYNC_CLIENT_ID = __webpack_exports__.ANVIL_SYNC_CLIENT_ID;
50353
49072
  exports.AnvilYamlValidationResult = __webpack_exports__.AnvilYamlValidationResult;
50354
49073
  exports.AppIdCandidate = __webpack_exports__.AppIdCandidate;
50355
49074
  exports.AppIdWithContext = __webpack_exports__.AppIdWithContext;
@@ -50358,6 +49077,7 @@ exports.CheckoutAppListItem = __webpack_exports__.CheckoutAppListItem;
50358
49077
  exports.CheckoutCloneOptions = __webpack_exports__.CheckoutCloneOptions;
50359
49078
  exports.CheckoutExecutionDeps = __webpack_exports__.CheckoutExecutionDeps;
50360
49079
  exports.CheckoutOptions = __webpack_exports__.CheckoutOptions;
49080
+ exports.CheckoutResult = __webpack_exports__.CheckoutResult;
50361
49081
  exports.DeviceAuthorizationResponse = __webpack_exports__.DeviceAuthorizationResponse;
50362
49082
  exports.FormTemplateValidationResult = __webpack_exports__.FormTemplateValidationResult;
50363
49083
  exports.LoginResult = __webpack_exports__.LoginResult;
@@ -50369,6 +49089,7 @@ exports.SettableConfigKey = __webpack_exports__.SettableConfigKey;
50369
49089
  exports.StoredTokens = __webpack_exports__.StoredTokens;
50370
49090
  exports.TokenData = __webpack_exports__.TokenData;
50371
49091
  exports.ValidateAppIdResponse = __webpack_exports__.ValidateAppIdResponse;
49092
+ exports.ValidateBranchSyncStatusOptions = __webpack_exports__.ValidateBranchSyncStatusOptions;
50372
49093
  exports.ValidatePathResult = __webpack_exports__.ValidatePathResult;
50373
49094
  exports.ValidationIssue = __webpack_exports__.ValidationIssue;
50374
49095
  exports.ValidationTarget = __webpack_exports__.ValidationTarget;
@@ -50376,7 +49097,6 @@ exports.checkUncommittedChanges = __webpack_exports__.checkUncommittedChanges;
50376
49097
  exports.deleteConfig = __webpack_exports__.deleteConfig;
50377
49098
  exports.detectAppIdsByCommitLookup = __webpack_exports__.detectAppIdsByCommitLookup;
50378
49099
  exports.detectAppIdsFromAllRemotes = __webpack_exports__.detectAppIdsFromAllRemotes;
50379
- exports.ensureCheckoutAuthToken = __webpack_exports__.ensureCheckoutAuthToken;
50380
49100
  exports.executeCheckout = __webpack_exports__.executeCheckout;
50381
49101
  exports.filterCandidates = __webpack_exports__.filterCandidates;
50382
49102
  exports.formatCandidateLabel = __webpack_exports__.formatCandidateLabel;
@@ -50405,7 +49125,6 @@ exports.logout = __webpack_exports__.logout;
50405
49125
  exports.lookupByCommit = __webpack_exports__.lookupByCommit;
50406
49126
  exports.lookupRemoteInfoForAppId = __webpack_exports__.lookupRemoteInfoForAppId;
50407
49127
  exports.normalizeAnvilUrl = __webpack_exports__.normalizeAnvilUrl;
50408
- exports.openPathInEditorOrDefault = __webpack_exports__.openPathInEditorOrDefault;
50409
49128
  exports.parseCheckoutInput = __webpack_exports__.parseCheckoutInput;
50410
49129
  exports.parseConfigSetValue = __webpack_exports__.parseConfigSetValue;
50411
49130
  exports.pollDeviceAuthorization = __webpack_exports__.pollDeviceAuthorization;
@@ -50413,11 +49132,9 @@ exports.preferredEditors = __webpack_exports__.preferredEditors;
50413
49132
  exports.requestDeviceAuthorization = __webpack_exports__.requestDeviceAuthorization;
50414
49133
  exports.resetConfig = __webpack_exports__.resetConfig;
50415
49134
  exports.resolveAnvilUrl = __webpack_exports__.resolveAnvilUrl;
50416
- exports.resolveCheckoutUrl = __webpack_exports__.resolveCheckoutUrl;
50417
- exports.resolveCheckoutUsername = __webpack_exports__.resolveCheckoutUsername;
50418
- exports.runInteractiveLoginFlow = __webpack_exports__.runInteractiveLoginFlow;
50419
49135
  exports.sanitizeDirectoryName = __webpack_exports__.sanitizeDirectoryName;
50420
49136
  exports.saveUpdates = __webpack_exports__.saveUpdates;
49137
+ exports.setAuthTokensForAccount = __webpack_exports__.setAuthTokensForAccount;
50421
49138
  exports.setConfig = __webpack_exports__.setConfig;
50422
49139
  exports.syncToLatest = __webpack_exports__.syncToLatest;
50423
49140
  exports.validateAnvilApp = __webpack_exports__.validateAnvilApp;
@@ -50430,6 +49147,7 @@ exports.validatePath = __webpack_exports__.validatePath;
50430
49147
  exports.verifyAuth = __webpack_exports__.verifyAuth;
50431
49148
  exports.watch = __webpack_exports__.watch;
50432
49149
  for(var __rspack_i in __webpack_exports__)if (-1 === [
49150
+ "ANVIL_SYNC_CLIENT_ID",
50433
49151
  "AnvilYamlValidationResult",
50434
49152
  "AppIdCandidate",
50435
49153
  "AppIdWithContext",
@@ -50438,6 +49156,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
50438
49156
  "CheckoutCloneOptions",
50439
49157
  "CheckoutExecutionDeps",
50440
49158
  "CheckoutOptions",
49159
+ "CheckoutResult",
50441
49160
  "DeviceAuthorizationResponse",
50442
49161
  "FormTemplateValidationResult",
50443
49162
  "LoginResult",
@@ -50449,6 +49168,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
50449
49168
  "StoredTokens",
50450
49169
  "TokenData",
50451
49170
  "ValidateAppIdResponse",
49171
+ "ValidateBranchSyncStatusOptions",
50452
49172
  "ValidatePathResult",
50453
49173
  "ValidationIssue",
50454
49174
  "ValidationTarget",
@@ -50456,7 +49176,6 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
50456
49176
  "deleteConfig",
50457
49177
  "detectAppIdsByCommitLookup",
50458
49178
  "detectAppIdsFromAllRemotes",
50459
- "ensureCheckoutAuthToken",
50460
49179
  "executeCheckout",
50461
49180
  "filterCandidates",
50462
49181
  "formatCandidateLabel",
@@ -50485,7 +49204,6 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
50485
49204
  "lookupByCommit",
50486
49205
  "lookupRemoteInfoForAppId",
50487
49206
  "normalizeAnvilUrl",
50488
- "openPathInEditorOrDefault",
50489
49207
  "parseCheckoutInput",
50490
49208
  "parseConfigSetValue",
50491
49209
  "pollDeviceAuthorization",
@@ -50493,11 +49211,9 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
50493
49211
  "requestDeviceAuthorization",
50494
49212
  "resetConfig",
50495
49213
  "resolveAnvilUrl",
50496
- "resolveCheckoutUrl",
50497
- "resolveCheckoutUsername",
50498
- "runInteractiveLoginFlow",
50499
49214
  "sanitizeDirectoryName",
50500
49215
  "saveUpdates",
49216
+ "setAuthTokensForAccount",
50501
49217
  "setConfig",
50502
49218
  "syncToLatest",
50503
49219
  "validateAnvilApp",