@anvil-works/anvil-cli 0.7.0-canary.16 → 0.7.0-canary.17
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/WatchSession.d.ts.map +1 -1
- package/dist/cli.js +78 -31
- package/dist/index.js +78 -31
- package/dist/services/auth.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WatchSession.d.ts","sourceRoot":"","sources":["../src/WatchSession.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EAOtB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"WatchSession.d.ts","sourceRoot":"","sources":["../src/WatchSession.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -13895,6 +13895,7 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
13895
13895
|
function setRepoContext(repoPath) {
|
|
13896
13896
|
repoContext = repoPath;
|
|
13897
13897
|
}
|
|
13898
|
+
const inFlightRefreshes = new Map();
|
|
13898
13899
|
async function verifyAuth(authToken, anvilUrl = getDefaultAnvilUrl()) {
|
|
13899
13900
|
try {
|
|
13900
13901
|
const resp = await fetch(`${anvilUrl}/ide/api/_/user`, {
|
|
@@ -13948,53 +13949,91 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
13948
13949
|
}
|
|
13949
13950
|
async function auth_getValidAuthToken(anvilUrl = getDefaultAnvilUrl(), username) {
|
|
13950
13951
|
const normalized = normalizeAnvilUrl(anvilUrl);
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
if (inMemoryAuth && authMatches(inMemoryAuth, normalized, username)) tokens = inMemoryAuth.tokens;
|
|
13954
|
-
else {
|
|
13955
|
-
repoAuth = repoContext ? await readAuthFromRepo(repoContext) : void 0;
|
|
13956
|
-
tokens = repoAuth && authMatches(repoAuth, normalized, username) ? repoAuth.tokens : getTokensAutoSelect(normalized, username);
|
|
13957
|
-
}
|
|
13952
|
+
const source = await resolveTokenSource(normalized, username);
|
|
13953
|
+
const tokens = getSourceTokens(source);
|
|
13958
13954
|
if (!tokens.authToken && !tokens.refreshToken) throw errors_createAuthError.required("Not logged in. Please log in first.");
|
|
13959
13955
|
const isExpired = null !== tokens.authTokenExpiresAt && tokens.authTokenExpiresAt <= Math.floor(Date.now() / 1000) + 60;
|
|
13960
|
-
if (tokens.refreshToken && isExpired)
|
|
13956
|
+
if (tokens.refreshToken && isExpired) {
|
|
13957
|
+
const refreshKey = getRefreshKey(normalized, username, source, tokens.refreshToken);
|
|
13958
|
+
const existingRefresh = inFlightRefreshes.get(refreshKey);
|
|
13959
|
+
if (existingRefresh) return existingRefresh;
|
|
13960
|
+
const refreshPromise = refreshAndStoreAccessToken(normalized, username, source, tokens.refreshToken).finally(()=>{
|
|
13961
|
+
inFlightRefreshes.delete(refreshKey);
|
|
13962
|
+
});
|
|
13963
|
+
inFlightRefreshes.set(refreshKey, refreshPromise);
|
|
13964
|
+
return refreshPromise;
|
|
13965
|
+
}
|
|
13966
|
+
if (tokens.authToken) return tokens.authToken;
|
|
13967
|
+
throw errors_createAuthError.required("No valid token available");
|
|
13968
|
+
}
|
|
13969
|
+
async function resolveTokenSource(normalizedUrl, username) {
|
|
13970
|
+
if (inMemoryAuth && authMatches(inMemoryAuth, normalizedUrl, username)) return {
|
|
13971
|
+
type: "memory",
|
|
13972
|
+
auth: inMemoryAuth
|
|
13973
|
+
};
|
|
13974
|
+
const repoAuth = repoContext ? await readAuthFromRepo(repoContext) : void 0;
|
|
13975
|
+
if (repoAuth && authMatches(repoAuth, normalizedUrl, username)) return {
|
|
13976
|
+
type: "repo",
|
|
13977
|
+
auth: repoAuth,
|
|
13978
|
+
repoPath: repoContext
|
|
13979
|
+
};
|
|
13980
|
+
const tokens = getTokensAutoSelect(normalizedUrl, username);
|
|
13981
|
+
return {
|
|
13982
|
+
type: "store",
|
|
13983
|
+
tokens,
|
|
13984
|
+
accountUsername: getStoreAccountUsername(normalizedUrl, username, tokens.refreshToken ?? void 0)
|
|
13985
|
+
};
|
|
13986
|
+
}
|
|
13987
|
+
function getSourceTokens(source) {
|
|
13988
|
+
return "store" === source.type ? source.tokens : source.auth.tokens;
|
|
13989
|
+
}
|
|
13990
|
+
function getStoreAccountUsername(normalizedUrl, username, refreshToken) {
|
|
13991
|
+
if (username) return username;
|
|
13992
|
+
const urlTokens = getUrlTokens(normalizedUrl);
|
|
13993
|
+
if (!urlTokens) return;
|
|
13994
|
+
const accounts = Object.keys(urlTokens);
|
|
13995
|
+
if (1 === accounts.length) return accounts[0];
|
|
13996
|
+
return refreshToken ? findAccountByRefreshToken(normalizedUrl, refreshToken) : void 0;
|
|
13997
|
+
}
|
|
13998
|
+
function getRefreshKey(normalizedUrl, username, source, refreshToken) {
|
|
13999
|
+
switch(source.type){
|
|
14000
|
+
case "memory":
|
|
14001
|
+
return `memory:${normalizedUrl}:${source.auth.username}`;
|
|
14002
|
+
case "repo":
|
|
14003
|
+
return `repo:${source.repoPath}:${normalizedUrl}:${source.auth.username}`;
|
|
14004
|
+
case "store":
|
|
14005
|
+
return `store:${normalizedUrl}:${source.accountUsername ?? username ?? refreshToken}`;
|
|
14006
|
+
}
|
|
14007
|
+
}
|
|
14008
|
+
async function refreshAndStoreAccessToken(normalizedUrl, username, source, refreshToken) {
|
|
14009
|
+
try {
|
|
14010
|
+
const tokens = getSourceTokens(source);
|
|
13961
14011
|
const clientId = tokens.clientId ?? ANVIL_SYNC_CLIENT_ID;
|
|
13962
|
-
const tokenData = await refreshAccessToken(
|
|
13963
|
-
const newExpiresAt = Math.floor(Date.now() / 1000) + tokenData.expires_in;
|
|
14012
|
+
const tokenData = await refreshAccessToken(refreshToken, normalizedUrl, clientId);
|
|
13964
14013
|
const newTokens = {
|
|
13965
14014
|
authToken: tokenData.access_token,
|
|
13966
14015
|
refreshToken: tokenData.refresh_token,
|
|
13967
|
-
authTokenExpiresAt:
|
|
14016
|
+
authTokenExpiresAt: Math.floor(Date.now() / 1000) + tokenData.expires_in,
|
|
13968
14017
|
clientId
|
|
13969
14018
|
};
|
|
13970
|
-
if (
|
|
13971
|
-
else if (
|
|
14019
|
+
if ("memory" === source.type) source.auth.tokens = newTokens;
|
|
14020
|
+
else if ("repo" === source.type) {
|
|
13972
14021
|
const encryptionKey = process.env["ANVIL_AUTH_FILE_ENCRYPTION_KEY"];
|
|
13973
14022
|
if (!encryptionKey) throw errors_createAuthError.required("Cannot refresh repo auth without ANVIL_AUTH_FILE_ENCRYPTION_KEY.");
|
|
13974
|
-
|
|
13975
|
-
await writeAuthToFile(
|
|
14023
|
+
source.auth.tokens = newTokens;
|
|
14024
|
+
await writeAuthToFile(source.repoPath, source.auth, encryptionKey);
|
|
13976
14025
|
} else {
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
const urlTokens = getUrlTokens(normalized);
|
|
13980
|
-
if (urlTokens) {
|
|
13981
|
-
const accounts = Object.keys(urlTokens);
|
|
13982
|
-
accountUsername = 1 === accounts.length ? accounts[0] : findAccountByRefreshToken(normalized, tokens.refreshToken);
|
|
13983
|
-
}
|
|
13984
|
-
}
|
|
13985
|
-
if (!accountUsername) {
|
|
13986
|
-
await clearTokensForAccount(normalized, username, tokens.refreshToken);
|
|
14026
|
+
if (!source.accountUsername) {
|
|
14027
|
+
await clearTokensForAccount(normalizedUrl, username, refreshToken);
|
|
13987
14028
|
throw errors_createAuthError.required("Cannot determine which account to refresh. Please log in again.");
|
|
13988
14029
|
}
|
|
13989
|
-
setAccountTokens(
|
|
14030
|
+
setAccountTokens(normalizedUrl, source.accountUsername, newTokens);
|
|
13990
14031
|
}
|
|
13991
14032
|
return tokenData.access_token;
|
|
13992
14033
|
} catch (e) {
|
|
13993
|
-
await clearTokensForAccount(
|
|
14034
|
+
await clearTokensForAccount(normalizedUrl, username, refreshToken);
|
|
13994
14035
|
throw e;
|
|
13995
14036
|
}
|
|
13996
|
-
if (tokens.authToken) return tokens.authToken;
|
|
13997
|
-
throw errors_createAuthError.required("No valid token available");
|
|
13998
14037
|
}
|
|
13999
14038
|
async function clearTokensForAccount(url, username, refreshToken) {
|
|
14000
14039
|
if (inMemoryAuth || repoContext && await readAuthFromRepo(repoContext)) return;
|
|
@@ -17845,6 +17884,12 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
17845
17884
|
}
|
|
17846
17885
|
}
|
|
17847
17886
|
function authDiagnostic(error) {
|
|
17887
|
+
if ("token_refresh_failed" === error.type && error.message?.includes("invalid_grant")) return {
|
|
17888
|
+
code: error.type,
|
|
17889
|
+
recoverability: "requires_user_action",
|
|
17890
|
+
requiresUserAction: true,
|
|
17891
|
+
suggestedAction: "Your Anvil session auth has expired or was invalidated. Run anvil login or restart the agent/watch session, then retry."
|
|
17892
|
+
};
|
|
17848
17893
|
return {
|
|
17849
17894
|
code: error.type,
|
|
17850
17895
|
recoverability: "requires_user_action",
|
|
@@ -18761,7 +18806,7 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
18761
18806
|
getAuthToken: ()=>this.authToken,
|
|
18762
18807
|
setAuthToken: (token)=>{
|
|
18763
18808
|
this.authToken = token;
|
|
18764
|
-
this.wsClient?.updateAuthToken(token);
|
|
18809
|
+
this.wsClient?.updateAuthToken?.(token);
|
|
18765
18810
|
},
|
|
18766
18811
|
getCurrentBranch: ()=>this.currentBranch,
|
|
18767
18812
|
getCommitId: ()=>this.commitId,
|
|
@@ -18781,7 +18826,7 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
18781
18826
|
getAuthToken: ()=>this.authToken,
|
|
18782
18827
|
setAuthToken: (token)=>{
|
|
18783
18828
|
this.authToken = token;
|
|
18784
|
-
this.wsClient?.updateAuthToken(token);
|
|
18829
|
+
this.wsClient?.updateAuthToken?.(token);
|
|
18785
18830
|
},
|
|
18786
18831
|
getCurrentBranch: ()=>this.currentBranch,
|
|
18787
18832
|
getCommitId: ()=>this.commitId,
|
|
@@ -18949,6 +18994,8 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
18949
18994
|
]);
|
|
18950
18995
|
}
|
|
18951
18996
|
logger_logger.verbose(external_chalk_default().cyan(`Environment branch ${"snapshot" === source ? "snapshot" : "update"}: `) + external_chalk_default().bold(`${this.currentBranch} -> ${targetBranch}`));
|
|
18997
|
+
this.authToken = await auth_getValidAuthToken(this.anvilUrl, this.username);
|
|
18998
|
+
this.wsClient?.updateAuthToken?.(this.authToken);
|
|
18952
18999
|
const fetchUrl = getGitFetchUrl(this.appId, this.authToken, this.anvilUrl);
|
|
18953
19000
|
const envRemoteRef = environmentRemoteRefForBranch(targetBranch);
|
|
18954
19001
|
await this.gitService.fetch(fetchUrl, environmentFetchRefSpecForBranch(targetBranch));
|
package/dist/index.js
CHANGED
|
@@ -13885,6 +13885,7 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
13885
13885
|
function auth_setRepoContext(repoPath) {
|
|
13886
13886
|
repoContext = repoPath;
|
|
13887
13887
|
}
|
|
13888
|
+
const inFlightRefreshes = new Map();
|
|
13888
13889
|
async function auth_verifyAuth(authToken, anvilUrl = getDefaultAnvilUrl()) {
|
|
13889
13890
|
try {
|
|
13890
13891
|
const resp = await fetch(`${anvilUrl}/ide/api/_/user`, {
|
|
@@ -13938,53 +13939,91 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
13938
13939
|
}
|
|
13939
13940
|
async function auth_getValidAuthToken(anvilUrl = getDefaultAnvilUrl(), username) {
|
|
13940
13941
|
const normalized = config_normalizeAnvilUrl(anvilUrl);
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
if (inMemoryAuth && authMatches(inMemoryAuth, normalized, username)) tokens = inMemoryAuth.tokens;
|
|
13944
|
-
else {
|
|
13945
|
-
repoAuth = repoContext ? await readAuthFromRepo(repoContext) : void 0;
|
|
13946
|
-
tokens = repoAuth && authMatches(repoAuth, normalized, username) ? repoAuth.tokens : getTokensAutoSelect(normalized, username);
|
|
13947
|
-
}
|
|
13942
|
+
const source = await resolveTokenSource(normalized, username);
|
|
13943
|
+
const tokens = getSourceTokens(source);
|
|
13948
13944
|
if (!tokens.authToken && !tokens.refreshToken) throw createAuthError.required("Not logged in. Please log in first.");
|
|
13949
13945
|
const isExpired = null !== tokens.authTokenExpiresAt && tokens.authTokenExpiresAt <= Math.floor(Date.now() / 1000) + 60;
|
|
13950
|
-
if (tokens.refreshToken && isExpired)
|
|
13946
|
+
if (tokens.refreshToken && isExpired) {
|
|
13947
|
+
const refreshKey = getRefreshKey(normalized, username, source, tokens.refreshToken);
|
|
13948
|
+
const existingRefresh = inFlightRefreshes.get(refreshKey);
|
|
13949
|
+
if (existingRefresh) return existingRefresh;
|
|
13950
|
+
const refreshPromise = refreshAndStoreAccessToken(normalized, username, source, tokens.refreshToken).finally(()=>{
|
|
13951
|
+
inFlightRefreshes.delete(refreshKey);
|
|
13952
|
+
});
|
|
13953
|
+
inFlightRefreshes.set(refreshKey, refreshPromise);
|
|
13954
|
+
return refreshPromise;
|
|
13955
|
+
}
|
|
13956
|
+
if (tokens.authToken) return tokens.authToken;
|
|
13957
|
+
throw createAuthError.required("No valid token available");
|
|
13958
|
+
}
|
|
13959
|
+
async function resolveTokenSource(normalizedUrl, username) {
|
|
13960
|
+
if (inMemoryAuth && authMatches(inMemoryAuth, normalizedUrl, username)) return {
|
|
13961
|
+
type: "memory",
|
|
13962
|
+
auth: inMemoryAuth
|
|
13963
|
+
};
|
|
13964
|
+
const repoAuth = repoContext ? await readAuthFromRepo(repoContext) : void 0;
|
|
13965
|
+
if (repoAuth && authMatches(repoAuth, normalizedUrl, username)) return {
|
|
13966
|
+
type: "repo",
|
|
13967
|
+
auth: repoAuth,
|
|
13968
|
+
repoPath: repoContext
|
|
13969
|
+
};
|
|
13970
|
+
const tokens = getTokensAutoSelect(normalizedUrl, username);
|
|
13971
|
+
return {
|
|
13972
|
+
type: "store",
|
|
13973
|
+
tokens,
|
|
13974
|
+
accountUsername: getStoreAccountUsername(normalizedUrl, username, tokens.refreshToken ?? void 0)
|
|
13975
|
+
};
|
|
13976
|
+
}
|
|
13977
|
+
function getSourceTokens(source) {
|
|
13978
|
+
return "store" === source.type ? source.tokens : source.auth.tokens;
|
|
13979
|
+
}
|
|
13980
|
+
function getStoreAccountUsername(normalizedUrl, username, refreshToken) {
|
|
13981
|
+
if (username) return username;
|
|
13982
|
+
const urlTokens = getUrlTokens(normalizedUrl);
|
|
13983
|
+
if (!urlTokens) return;
|
|
13984
|
+
const accounts = Object.keys(urlTokens);
|
|
13985
|
+
if (1 === accounts.length) return accounts[0];
|
|
13986
|
+
return refreshToken ? findAccountByRefreshToken(normalizedUrl, refreshToken) : void 0;
|
|
13987
|
+
}
|
|
13988
|
+
function getRefreshKey(normalizedUrl, username, source, refreshToken) {
|
|
13989
|
+
switch(source.type){
|
|
13990
|
+
case "memory":
|
|
13991
|
+
return `memory:${normalizedUrl}:${source.auth.username}`;
|
|
13992
|
+
case "repo":
|
|
13993
|
+
return `repo:${source.repoPath}:${normalizedUrl}:${source.auth.username}`;
|
|
13994
|
+
case "store":
|
|
13995
|
+
return `store:${normalizedUrl}:${source.accountUsername ?? username ?? refreshToken}`;
|
|
13996
|
+
}
|
|
13997
|
+
}
|
|
13998
|
+
async function refreshAndStoreAccessToken(normalizedUrl, username, source, refreshToken) {
|
|
13999
|
+
try {
|
|
14000
|
+
const tokens = getSourceTokens(source);
|
|
13951
14001
|
const clientId = tokens.clientId ?? ANVIL_SYNC_CLIENT_ID;
|
|
13952
|
-
const tokenData = await refreshAccessToken(
|
|
13953
|
-
const newExpiresAt = Math.floor(Date.now() / 1000) + tokenData.expires_in;
|
|
14002
|
+
const tokenData = await refreshAccessToken(refreshToken, normalizedUrl, clientId);
|
|
13954
14003
|
const newTokens = {
|
|
13955
14004
|
authToken: tokenData.access_token,
|
|
13956
14005
|
refreshToken: tokenData.refresh_token,
|
|
13957
|
-
authTokenExpiresAt:
|
|
14006
|
+
authTokenExpiresAt: Math.floor(Date.now() / 1000) + tokenData.expires_in,
|
|
13958
14007
|
clientId
|
|
13959
14008
|
};
|
|
13960
|
-
if (
|
|
13961
|
-
else if (
|
|
14009
|
+
if ("memory" === source.type) source.auth.tokens = newTokens;
|
|
14010
|
+
else if ("repo" === source.type) {
|
|
13962
14011
|
const encryptionKey = process.env["ANVIL_AUTH_FILE_ENCRYPTION_KEY"];
|
|
13963
14012
|
if (!encryptionKey) throw createAuthError.required("Cannot refresh repo auth without ANVIL_AUTH_FILE_ENCRYPTION_KEY.");
|
|
13964
|
-
|
|
13965
|
-
await writeAuthToFile(
|
|
14013
|
+
source.auth.tokens = newTokens;
|
|
14014
|
+
await writeAuthToFile(source.repoPath, source.auth, encryptionKey);
|
|
13966
14015
|
} else {
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
const urlTokens = getUrlTokens(normalized);
|
|
13970
|
-
if (urlTokens) {
|
|
13971
|
-
const accounts = Object.keys(urlTokens);
|
|
13972
|
-
accountUsername = 1 === accounts.length ? accounts[0] : findAccountByRefreshToken(normalized, tokens.refreshToken);
|
|
13973
|
-
}
|
|
13974
|
-
}
|
|
13975
|
-
if (!accountUsername) {
|
|
13976
|
-
await clearTokensForAccount(normalized, username, tokens.refreshToken);
|
|
14016
|
+
if (!source.accountUsername) {
|
|
14017
|
+
await clearTokensForAccount(normalizedUrl, username, refreshToken);
|
|
13977
14018
|
throw createAuthError.required("Cannot determine which account to refresh. Please log in again.");
|
|
13978
14019
|
}
|
|
13979
|
-
setAccountTokens(
|
|
14020
|
+
setAccountTokens(normalizedUrl, source.accountUsername, newTokens);
|
|
13980
14021
|
}
|
|
13981
14022
|
return tokenData.access_token;
|
|
13982
14023
|
} catch (e) {
|
|
13983
|
-
await clearTokensForAccount(
|
|
14024
|
+
await clearTokensForAccount(normalizedUrl, username, refreshToken);
|
|
13984
14025
|
throw e;
|
|
13985
14026
|
}
|
|
13986
|
-
if (tokens.authToken) return tokens.authToken;
|
|
13987
|
-
throw createAuthError.required("No valid token available");
|
|
13988
14027
|
}
|
|
13989
14028
|
async function clearTokensForAccount(url, username, refreshToken) {
|
|
13990
14029
|
if (inMemoryAuth || repoContext && await readAuthFromRepo(repoContext)) return;
|
|
@@ -17874,6 +17913,12 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
17874
17913
|
}
|
|
17875
17914
|
}
|
|
17876
17915
|
function authDiagnostic(error) {
|
|
17916
|
+
if ("token_refresh_failed" === error.type && error.message?.includes("invalid_grant")) return {
|
|
17917
|
+
code: error.type,
|
|
17918
|
+
recoverability: "requires_user_action",
|
|
17919
|
+
requiresUserAction: true,
|
|
17920
|
+
suggestedAction: "Your Anvil session auth has expired or was invalidated. Run anvil login or restart the agent/watch session, then retry."
|
|
17921
|
+
};
|
|
17877
17922
|
return {
|
|
17878
17923
|
code: error.type,
|
|
17879
17924
|
recoverability: "requires_user_action",
|
|
@@ -18790,7 +18835,7 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
18790
18835
|
getAuthToken: ()=>this.authToken,
|
|
18791
18836
|
setAuthToken: (token)=>{
|
|
18792
18837
|
this.authToken = token;
|
|
18793
|
-
this.wsClient?.updateAuthToken(token);
|
|
18838
|
+
this.wsClient?.updateAuthToken?.(token);
|
|
18794
18839
|
},
|
|
18795
18840
|
getCurrentBranch: ()=>this.currentBranch,
|
|
18796
18841
|
getCommitId: ()=>this.commitId,
|
|
@@ -18810,7 +18855,7 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
18810
18855
|
getAuthToken: ()=>this.authToken,
|
|
18811
18856
|
setAuthToken: (token)=>{
|
|
18812
18857
|
this.authToken = token;
|
|
18813
|
-
this.wsClient?.updateAuthToken(token);
|
|
18858
|
+
this.wsClient?.updateAuthToken?.(token);
|
|
18814
18859
|
},
|
|
18815
18860
|
getCurrentBranch: ()=>this.currentBranch,
|
|
18816
18861
|
getCommitId: ()=>this.commitId,
|
|
@@ -18978,6 +19023,8 @@ Promise.resolve(executeGitCredentialOperation(process.argv[2] || "get", {
|
|
|
18978
19023
|
]);
|
|
18979
19024
|
}
|
|
18980
19025
|
logger_logger.verbose(external_chalk_default().cyan(`Environment branch ${"snapshot" === source ? "snapshot" : "update"}: `) + external_chalk_default().bold(`${this.currentBranch} -> ${targetBranch}`));
|
|
19026
|
+
this.authToken = await auth_getValidAuthToken(this.anvilUrl, this.username);
|
|
19027
|
+
this.wsClient?.updateAuthToken?.(this.authToken);
|
|
18981
19028
|
const fetchUrl = anvil_api_getGitFetchUrl(this.appId, this.authToken, this.anvilUrl);
|
|
18982
19029
|
const envRemoteRef = environment_environmentRemoteRefForBranch(targetBranch);
|
|
18983
19030
|
await this.gitService.fetch(fetchUrl, environment_environmentFetchRefSpecForBranch(targetBranch));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAsC,MAAM,WAAW,CAAC;AAS9E,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAMjD,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,sBAAsB;AACtB,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,uBAAuB;AACvB,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/services/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAsC,MAAM,WAAW,CAAC;AAS9E,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAMjD,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,sBAAsB;AACtB,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,uBAAuB;AACvB,MAAM,WAAW,YAAY;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACzB;AAaD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAMjG;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAYD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAErD;AAQD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,SAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBpG;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACpC,YAAY,EAAE,MAAM,EACpB,QAAQ,SAAuB,EAC/B,QAAQ,SAAuB,GAChC,OAAO,CAAC,SAAS,CAAC,CA2BpB;AAMD;;GAEG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAY3F;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,SAAuB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC3G;AA8HD;;;GAGG;AACH,wBAAsB,oBAAoB,CACtC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/F,OAAO,CAAC,WAAW,CAAC,CAetB;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA0CxF;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYtE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAW/D"}
|