@salesforce/core 3.14.0 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [3.15.0](https://github.com/forcedotcom/sfdx-core/compare/v3.14.0...v3.15.0) (2022-04-26)
6
+
7
+ ### Features
8
+
9
+ - core changes to support create scratch and sandboxes ([#570](https://github.com/forcedotcom/sfdx-core/issues/570)) ([916eeb1](https://github.com/forcedotcom/sfdx-core/commit/916eeb1f96bebd5dce255f13c838ac0b10bf5b96))
10
+
5
11
  ## [3.14.0](https://github.com/forcedotcom/sfdx-core/compare/v3.13.1...v3.14.0) (2022-04-25)
6
12
 
7
13
  ### Features
@@ -0,0 +1,15 @@
1
+ import { SandboxProcessObject, SandboxRequest } from '../org';
2
+ import { TTLConfig } from './ttlConfig';
3
+ export declare type SandboxRequestCacheEntry = {
4
+ alias?: string;
5
+ setDefault: boolean;
6
+ prodOrgUsername: string;
7
+ sandboxProcessObject: Partial<SandboxProcessObject>;
8
+ sandboxRequest: Partial<SandboxRequest>;
9
+ };
10
+ export declare class SandboxRequestCache extends TTLConfig<TTLConfig.Options, SandboxRequestCacheEntry> {
11
+ static getDefaultOptions(): TTLConfig.Options;
12
+ static unset(key: string): Promise<void>;
13
+ static set(key: string, sandboxProcessObject: SandboxRequestCacheEntry): Promise<void>;
14
+ static getFileName(): string;
15
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SandboxRequestCache = void 0;
4
+ /*
5
+ * Copyright (c) 2020, salesforce.com, inc.
6
+ * All rights reserved.
7
+ * Licensed under the BSD 3-Clause license.
8
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
9
+ */
10
+ const kit_1 = require("@salesforce/kit");
11
+ const global_1 = require("../global");
12
+ const ttlConfig_1 = require("./ttlConfig");
13
+ class SandboxRequestCache extends ttlConfig_1.TTLConfig {
14
+ static getDefaultOptions() {
15
+ return {
16
+ isGlobal: true,
17
+ isState: true,
18
+ filename: SandboxRequestCache.getFileName(),
19
+ stateFolder: global_1.Global.SF_STATE_FOLDER,
20
+ ttl: kit_1.Duration.days(14),
21
+ };
22
+ }
23
+ static async unset(key) {
24
+ const cache = await SandboxRequestCache.create();
25
+ cache.unset(key);
26
+ await cache.write();
27
+ }
28
+ static async set(key, sandboxProcessObject) {
29
+ const cache = await SandboxRequestCache.create();
30
+ cache.set(key, sandboxProcessObject);
31
+ await cache.write();
32
+ }
33
+ static getFileName() {
34
+ return 'sandbox-create-cache.json';
35
+ }
36
+ }
37
+ exports.SandboxRequestCache = SandboxRequestCache;
38
+ //# sourceMappingURL=sandboxProcessCache.js.map
package/lib/exported.d.ts CHANGED
@@ -7,6 +7,7 @@ export { GlobalInfo, SfEntry, SfInfo, SfInfoKeys, SfOrg, SfOrgs, SfToken, SfToke
7
7
  export { DeviceOauthService, DeviceCodeResponse, DeviceCodePollingResponse } from './deviceOauthService';
8
8
  export { OrgUsersConfig } from './config/orgUsersConfig';
9
9
  export { ConfigPropertyMeta, ConfigPropertyMetaInput, Config, SfdxPropertyKeys, SfConfigProperties, SFDX_ALLOWED_PROPERTIES, SF_ALLOWED_PROPERTIES, } from './config/config';
10
+ export { SandboxRequestCacheEntry, SandboxRequestCache } from './config/sandboxProcessCache';
10
11
  export { ConfigInfo, ConfigAggregator, SfdxConfigAggregator } from './config/configAggregator';
11
12
  export { AuthFields, AuthInfo, AuthSideEffects, OrgAuthorization } from './org/authInfo';
12
13
  export { AuthRemover } from './org/authRemover';
@@ -18,7 +19,7 @@ export { SfdcUrl } from './util/sfdcUrl';
18
19
  export { getJwtAudienceUrl } from './util/getJwtAudienceUrl';
19
20
  export { Fields, FieldValue, LoggerLevel, LoggerLevelValue, LogLine, LoggerOptions, LoggerStream, Logger, } from './logger';
20
21
  export { Messages, StructuredMessage } from './messages';
21
- export { Org, SandboxProcessObject, StatusEvent, SandboxEvents, SandboxUserAuthResponse, SandboxUserAuthRequest, SandboxRequest, OrgTypes, ResultEvent, ScratchOrgRequest, } from './org';
22
+ export { Org, SandboxProcessObject, StatusEvent, SandboxEvents, SandboxUserAuthResponse, SandboxUserAuthRequest, SandboxRequest, ResumeSandboxRequest, OrgTypes, ResultEvent, ScratchOrgRequest, } from './org';
22
23
  export { OrgConfigProperties, ORG_CONFIG_ALLOWED_PROPERTIES } from './org/orgConfigProperties';
23
24
  export { PackageDir, NamedPackageDir, PackageDirDependency, SfProject, SfProjectJson, SfdxProject, SfdxProjectJson, } from './sfProject';
24
25
  export { SchemaPrinter } from './schema/printer';
@@ -29,8 +30,9 @@ export { CometClient, CometSubscription, StreamingClient, StatusResult } from '.
29
30
  export { MyDomainResolver } from './status/myDomainResolver';
30
31
  export { DefaultUserFields, REQUIRED_FIELDS, User, UserFields } from './org/user';
31
32
  export { PermissionSetAssignment, PermissionSetAssignmentFields } from './org/permissionSetAssignment';
32
- export { ScratchOrgCreateOptions, ScratchOrgCreateResult, scratchOrgCreate } from './org/scratchOrgCreate';
33
+ export { ScratchOrgCreateOptions, ScratchOrgCreateResult, scratchOrgCreate, scratchOrgResume, } from './org/scratchOrgCreate';
33
34
  export { ScratchOrgInfo } from './org/scratchOrgTypes';
34
35
  export { ScratchOrgLifecycleEvent, scratchOrgLifecycleEventName, scratchOrgLifecycleStages, } from './org/scratchOrgLifecycleEvents';
36
+ export { ScratchOrgCache } from './org/scratchOrgCache';
35
37
  export * from './util/sfdc';
36
38
  export * from './util/sfdcUrl';
package/lib/exported.js CHANGED
@@ -16,8 +16,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
17
17
  };
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.REQUIRED_FIELDS = exports.DefaultUserFields = exports.MyDomainResolver = exports.StreamingClient = exports.CometClient = exports.PollingClient = exports.SfdxError = exports.SfError = exports.SchemaValidator = exports.SchemaPrinter = exports.SfdxProjectJson = exports.SfdxProject = exports.SfProjectJson = exports.SfProject = exports.ORG_CONFIG_ALLOWED_PROPERTIES = exports.OrgConfigProperties = exports.OrgTypes = exports.SandboxEvents = exports.Org = exports.Messages = exports.Logger = exports.LoggerLevel = exports.getJwtAudienceUrl = exports.SfdcUrl = exports.WebOAuthServer = exports.Lifecycle = exports.Global = exports.Mode = exports.SFDX_HTTP_HEADERS = exports.Connection = exports.AuthRemover = exports.AuthInfo = exports.SfdxConfigAggregator = exports.ConfigAggregator = exports.SF_ALLOWED_PROPERTIES = exports.SFDX_ALLOWED_PROPERTIES = exports.SfConfigProperties = exports.SfdxPropertyKeys = exports.Config = exports.OrgUsersConfig = exports.DeviceOauthService = exports.SfInfoKeys = exports.GlobalInfo = exports.BaseConfigStore = exports.EnvVars = exports.SUPPORTED_ENV_VARS = exports.EnvironmentVariable = exports.envVars = exports.TTLConfig = exports.ConfigFile = void 0;
20
- exports.scratchOrgLifecycleStages = exports.scratchOrgLifecycleEventName = exports.scratchOrgCreate = exports.PermissionSetAssignment = exports.User = void 0;
19
+ exports.DefaultUserFields = exports.MyDomainResolver = exports.StreamingClient = exports.CometClient = exports.PollingClient = exports.SfdxError = exports.SfError = exports.SchemaValidator = exports.SchemaPrinter = exports.SfdxProjectJson = exports.SfdxProject = exports.SfProjectJson = exports.SfProject = exports.ORG_CONFIG_ALLOWED_PROPERTIES = exports.OrgConfigProperties = exports.OrgTypes = exports.SandboxEvents = exports.Org = exports.Messages = exports.Logger = exports.LoggerLevel = exports.getJwtAudienceUrl = exports.SfdcUrl = exports.WebOAuthServer = exports.Lifecycle = exports.Global = exports.Mode = exports.SFDX_HTTP_HEADERS = exports.Connection = exports.AuthRemover = exports.AuthInfo = exports.SfdxConfigAggregator = exports.ConfigAggregator = exports.SandboxRequestCache = exports.SF_ALLOWED_PROPERTIES = exports.SFDX_ALLOWED_PROPERTIES = exports.SfConfigProperties = exports.SfdxPropertyKeys = exports.Config = exports.OrgUsersConfig = exports.DeviceOauthService = exports.SfInfoKeys = exports.GlobalInfo = exports.BaseConfigStore = exports.EnvVars = exports.SUPPORTED_ENV_VARS = exports.EnvironmentVariable = exports.envVars = exports.TTLConfig = exports.ConfigFile = void 0;
20
+ exports.ScratchOrgCache = exports.scratchOrgLifecycleStages = exports.scratchOrgLifecycleEventName = exports.scratchOrgResume = exports.scratchOrgCreate = exports.PermissionSetAssignment = exports.User = exports.REQUIRED_FIELDS = void 0;
21
21
  const messages_1 = require("./messages");
22
22
  messages_1.Messages.importMessagesDirectory(__dirname);
23
23
  var configFile_1 = require("./config/configFile");
@@ -44,6 +44,8 @@ Object.defineProperty(exports, "SfdxPropertyKeys", { enumerable: true, get: func
44
44
  Object.defineProperty(exports, "SfConfigProperties", { enumerable: true, get: function () { return config_1.SfConfigProperties; } });
45
45
  Object.defineProperty(exports, "SFDX_ALLOWED_PROPERTIES", { enumerable: true, get: function () { return config_1.SFDX_ALLOWED_PROPERTIES; } });
46
46
  Object.defineProperty(exports, "SF_ALLOWED_PROPERTIES", { enumerable: true, get: function () { return config_1.SF_ALLOWED_PROPERTIES; } });
47
+ var sandboxProcessCache_1 = require("./config/sandboxProcessCache");
48
+ Object.defineProperty(exports, "SandboxRequestCache", { enumerable: true, get: function () { return sandboxProcessCache_1.SandboxRequestCache; } });
47
49
  var configAggregator_1 = require("./config/configAggregator");
48
50
  Object.defineProperty(exports, "ConfigAggregator", { enumerable: true, get: function () { return configAggregator_1.ConfigAggregator; } });
49
51
  Object.defineProperty(exports, "SfdxConfigAggregator", { enumerable: true, get: function () { return configAggregator_1.SfdxConfigAggregator; } });
@@ -104,9 +106,12 @@ var permissionSetAssignment_1 = require("./org/permissionSetAssignment");
104
106
  Object.defineProperty(exports, "PermissionSetAssignment", { enumerable: true, get: function () { return permissionSetAssignment_1.PermissionSetAssignment; } });
105
107
  var scratchOrgCreate_1 = require("./org/scratchOrgCreate");
106
108
  Object.defineProperty(exports, "scratchOrgCreate", { enumerable: true, get: function () { return scratchOrgCreate_1.scratchOrgCreate; } });
109
+ Object.defineProperty(exports, "scratchOrgResume", { enumerable: true, get: function () { return scratchOrgCreate_1.scratchOrgResume; } });
107
110
  var scratchOrgLifecycleEvents_1 = require("./org/scratchOrgLifecycleEvents");
108
111
  Object.defineProperty(exports, "scratchOrgLifecycleEventName", { enumerable: true, get: function () { return scratchOrgLifecycleEvents_1.scratchOrgLifecycleEventName; } });
109
112
  Object.defineProperty(exports, "scratchOrgLifecycleStages", { enumerable: true, get: function () { return scratchOrgLifecycleEvents_1.scratchOrgLifecycleStages; } });
113
+ var scratchOrgCache_1 = require("./org/scratchOrgCache");
114
+ Object.defineProperty(exports, "ScratchOrgCache", { enumerable: true, get: function () { return scratchOrgCache_1.ScratchOrgCache; } });
110
115
  // Utility sub-modules
111
116
  __exportStar(require("./util/sfdc"), exports);
112
117
  __exportStar(require("./util/sfdcUrl"), exports);
@@ -0,0 +1,36 @@
1
+ import { Nullable } from '@salesforce/ts-types';
2
+ import { GlobalInfo } from '../globalInfoConfig';
3
+ import { SfSandbox, SfSandboxes } from '../types';
4
+ export declare class SandboxAccessor {
5
+ private globalInfo;
6
+ constructor(globalInfo: GlobalInfo);
7
+ /**
8
+ * Returns all the sandboxes (or all the sandboxes for a given prod org)
9
+ *
10
+ * @param entity entity as a string should be a production org username
11
+ * and when entity is a SfSandbox, the prod org entity.prodOrgUsername will
12
+ * used in the filter.
13
+ */
14
+ getAll(entity?: string | SfSandbox): SfSandboxes;
15
+ /**
16
+ * Returns the SfSandbox config entry that corresponds to the given
17
+ * sandbox org id if it exists
18
+ *
19
+ * @param sandboxOrgId the sandboxOrgId that corresponds to a sandbox
20
+ */
21
+ get(sandboxOrgId?: string): Nullable<SfSandbox>;
22
+ /**
23
+ * Returns true if the given sandbox org id exists
24
+ *
25
+ * @param sandboxOrgId the sandboxOrgId that corresponds to a sandbox
26
+ */
27
+ has(sandboxOrgId?: string): boolean;
28
+ /**
29
+ * Set an sandboxOrgId for the given sandbox entity
30
+ *
31
+ * @param sandboxOrgId the sandboxOrgId you want to set
32
+ * @param entity the sandbox entity
33
+ */
34
+ set(sandboxOrgId: string, entity: SfSandbox): void;
35
+ unset(sandboxOrgId: string): void;
36
+ }
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2021, salesforce.com, inc.
4
+ * All rights reserved.
5
+ * Licensed under the BSD 3-Clause license.
6
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SandboxAccessor = void 0;
10
+ const types_1 = require("../types");
11
+ class SandboxAccessor {
12
+ constructor(globalInfo) {
13
+ this.globalInfo = globalInfo;
14
+ }
15
+ /**
16
+ * Returns all the sandboxes (or all the sandboxes for a given prod org)
17
+ *
18
+ * @param entity entity as a string should be a production org username
19
+ * and when entity is a SfSandbox, the prod org entity.prodOrgUsername will
20
+ * used in the filter.
21
+ */
22
+ getAll(entity) {
23
+ const all = this.globalInfo.get(types_1.SfInfoKeys.SANDBOXES) || {};
24
+ if (!entity) {
25
+ return all;
26
+ }
27
+ const prodOrgUsername = typeof entity === 'string' ? entity : entity.prodOrgUsername;
28
+ return Object.fromEntries(Object.entries(all).filter(([, value]) => value.prodOrgUsername === prodOrgUsername));
29
+ }
30
+ /**
31
+ * Returns the SfSandbox config entry that corresponds to the given
32
+ * sandbox org id if it exists
33
+ *
34
+ * @param sandboxOrgId the sandboxOrgId that corresponds to a sandbox
35
+ */
36
+ get(sandboxOrgId) {
37
+ var _a;
38
+ return sandboxOrgId ? (_a = this.getAll()[sandboxOrgId]) !== null && _a !== void 0 ? _a : null : null;
39
+ }
40
+ /**
41
+ * Returns true if the given sandbox org id exists
42
+ *
43
+ * @param sandboxOrgId the sandboxOrgId that corresponds to a sandbox
44
+ */
45
+ has(sandboxOrgId) {
46
+ var _a;
47
+ return !!(sandboxOrgId ? (_a = this.getAll()[sandboxOrgId]) !== null && _a !== void 0 ? _a : null : null);
48
+ }
49
+ /**
50
+ * Set an sandboxOrgId for the given sandbox entity
51
+ *
52
+ * @param sandboxOrgId the sandboxOrgId you want to set
53
+ * @param entity the sandbox entity
54
+ */
55
+ set(sandboxOrgId, entity) {
56
+ this.globalInfo.set(`${types_1.SfInfoKeys.SANDBOXES}["${sandboxOrgId}"]`, entity);
57
+ }
58
+ unset(sandboxOrgId) {
59
+ delete this.globalInfo.get(types_1.SfInfoKeys.SANDBOXES)[sandboxOrgId];
60
+ }
61
+ }
62
+ exports.SandboxAccessor = SandboxAccessor;
63
+ //# sourceMappingURL=sandboxAccessor.js.map
@@ -5,6 +5,7 @@ import { OrgAccessor } from './accessors/orgAccessor';
5
5
  import { TokenAccessor } from './accessors/tokenAccessor';
6
6
  import { AliasAccessor } from './accessors/aliasAccessor';
7
7
  import { SfInfo } from './types';
8
+ import { SandboxAccessor } from './accessors/sandboxAccessor';
8
9
  export declare function deepCopy<T extends AnyJson>(data: T): T;
9
10
  export declare class GlobalInfo extends ConfigFile<ConfigFile.Options, SfInfo> {
10
11
  protected static encryptedKeys: RegExp[];
@@ -27,6 +28,7 @@ export declare class GlobalInfo extends ConfigFile<ConfigFile.Options, SfInfo> {
27
28
  get orgs(): OrgAccessor;
28
29
  get tokens(): TokenAccessor;
29
30
  get aliases(): AliasAccessor;
31
+ get sandboxes(): SandboxAccessor;
30
32
  set(key: string, value: ConfigValue): void;
31
33
  write(newContents?: SfInfo): Promise<SfInfo>;
32
34
  protected init(): Promise<void>;
@@ -15,6 +15,7 @@ const orgAccessor_1 = require("./accessors/orgAccessor");
15
15
  const tokenAccessor_1 = require("./accessors/tokenAccessor");
16
16
  const aliasAccessor_1 = require("./accessors/aliasAccessor");
17
17
  const types_1 = require("./types");
18
+ const sandboxAccessor_1 = require("./accessors/sandboxAccessor");
18
19
  function deepCopy(data) {
19
20
  return JSON.parse(JSON.stringify(data));
20
21
  }
@@ -64,6 +65,9 @@ class GlobalInfo extends configFile_1.ConfigFile {
64
65
  get aliases() {
65
66
  return new aliasAccessor_1.AliasAccessor(this);
66
67
  }
68
+ get sandboxes() {
69
+ return new sandboxAccessor_1.SandboxAccessor(this);
70
+ }
67
71
  set(key, value) {
68
72
  if ((0, ts_types_1.isPlainObject)(value)) {
69
73
  value = this.timestamp(value);
@@ -101,5 +105,6 @@ GlobalInfo.EMPTY_DATA_MODEL = {
101
105
  [types_1.SfInfoKeys.ORGS]: {},
102
106
  [types_1.SfInfoKeys.TOKENS]: {},
103
107
  [types_1.SfInfoKeys.ALIASES]: {},
108
+ [types_1.SfInfoKeys.SANDBOXES]: {},
104
109
  };
105
110
  //# sourceMappingURL=globalInfoConfig.js.map
@@ -1,5 +1,5 @@
1
1
  import { ConfigFile } from '../config/configFile';
2
- import { SfInfo, SfInfoKeys, SfOrg, SfOrgs } from './types';
2
+ import { SfInfo, SfInfoKeys, SfOrg, SfOrgs, SfSandbox } from './types';
3
3
  interface Handler<T extends SfInfoKeys> {
4
4
  sfKey: T;
5
5
  merge: (sfData: SfInfo) => Promise<Partial<SfInfo>>;
@@ -11,7 +11,7 @@ interface Changes<T> {
11
11
  deleted: string[];
12
12
  }
13
13
  export declare class SfdxDataHandler {
14
- handlers: (AuthHandler | AliasesHandler)[];
14
+ handlers: (AuthHandler | AliasesHandler | SandboxesHandler)[];
15
15
  private original;
16
16
  write(latest?: SfInfo): Promise<void>;
17
17
  merge(sfData?: SfInfo): Promise<SfInfo>;
@@ -40,4 +40,14 @@ export declare class AliasesHandler extends BaseHandler<SfInfoKeys.ALIASES> {
40
40
  merge(sfData?: SfInfo): Promise<Partial<SfInfo>>;
41
41
  write(latest: SfInfo): Promise<void>;
42
42
  }
43
+ export declare class SandboxesHandler extends BaseHandler<SfInfoKeys.SANDBOXES> {
44
+ private static sandboxFilenameFilterRegEx;
45
+ sfKey: typeof SfInfoKeys.SANDBOXES;
46
+ merge(sfData?: SfInfo): Promise<Partial<SfInfo>>;
47
+ migrate(): Promise<Pick<SfInfo, SfInfoKeys.SANDBOXES>>;
48
+ write(latest: SfInfo, original: SfInfo): Promise<void>;
49
+ listAllSandboxFiles(): Promise<string[]>;
50
+ listAllSandboxes(): Promise<SfSandbox[]>;
51
+ private findChanges;
52
+ }
43
53
  export {};
@@ -6,13 +6,14 @@
6
6
  * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.AliasesHandler = exports.AuthHandler = exports.SfdxDataHandler = void 0;
9
+ exports.SandboxesHandler = exports.AliasesHandler = exports.AuthHandler = exports.SfdxDataHandler = void 0;
10
10
  const path_1 = require("path");
11
11
  const fs = require("fs");
12
12
  const kit_1 = require("@salesforce/kit");
13
13
  const ts_types_1 = require("@salesforce/ts-types");
14
14
  const global_1 = require("../global");
15
15
  const configFile_1 = require("../config/configFile");
16
+ const sandboxOrgConfig_1 = require("../config/sandboxOrgConfig");
16
17
  const globalInfoConfig_1 = require("./globalInfoConfig");
17
18
  const types_1 = require("./types");
18
19
  function isEqual(object1, object2) {
@@ -28,7 +29,7 @@ function isEqual(object1, object2) {
28
29
  }
29
30
  class SfdxDataHandler {
30
31
  constructor() {
31
- this.handlers = [new AuthHandler(), new AliasesHandler()];
32
+ this.handlers = [new AuthHandler(), new AliasesHandler(), new SandboxesHandler()];
32
33
  }
33
34
  async write(latest = globalInfoConfig_1.GlobalInfo.emptyDataModel) {
34
35
  await Promise.all(this.handlers.map((handler) => handler.write(latest, this.original)));
@@ -65,13 +66,13 @@ class BaseHandler {
65
66
  });
66
67
  (0, kit_1.set)(merged, `${key}["${k}"]`, Object.assign({}, older, newer));
67
68
  }
68
- // Keys that exist in .sfdx but not .sf are added becase we assume
69
+ // Keys that exist in .sfdx but not .sf are added because we assume
69
70
  // that this means the key was created using sfdx.
70
71
  // However, this is not always a valid assumption because it could
71
72
  // also mean that the key was deleted using sf, in which case we
72
73
  // do not want to migrate the sfdx key to sf.
73
74
  // Programmatically differentiating between a new key and a deleted key
74
- // would be nearly impossible. Instead we should ensure that whenever
75
+ // would be nearly impossible. Instead, we should ensure that whenever
75
76
  // sf deletes a key it also deletes it in sfdx. This way, we can safely
76
77
  // assume that we should migrate any keys that exist in in .sfdx
77
78
  const unhandledSfdxKeys = sfdxKeys.filter((k) => !sfKeys.includes(k));
@@ -211,4 +212,98 @@ class AliasesHandler extends BaseHandler {
211
212
  }
212
213
  exports.AliasesHandler = AliasesHandler;
213
214
  AliasesHandler.SFDX_ALIASES_FILENAME = 'alias.json';
215
+ class SandboxesHandler extends BaseHandler {
216
+ constructor() {
217
+ super(...arguments);
218
+ this.sfKey = types_1.SfInfoKeys.SANDBOXES;
219
+ }
220
+ async merge(sfData = globalInfoConfig_1.GlobalInfo.emptyDataModel) {
221
+ var _a, _b;
222
+ const sfdxData = await this.migrate();
223
+ const merged = (0, globalInfoConfig_1.deepCopy)(sfData);
224
+ // Only merge the key this handler is responsible for.
225
+ const key = this.sfKey;
226
+ const sfKeys = Object.keys((_a = sfData[key]) !== null && _a !== void 0 ? _a : {});
227
+ const sfdxKeys = Object.keys((_b = sfdxData[key]) !== null && _b !== void 0 ? _b : {});
228
+ // sandbox entries for .sf and .sfdx contain static data. Given there
229
+ // can be no mutation during the life of the sandbox, having to merge common keys
230
+ // is unnecessary.
231
+ // Keys that exist in .sfdx but not .sf are added because we assume
232
+ // that this means the key was created using sfdx.
233
+ // However, this is not always a valid assumption because it could
234
+ // also mean that the key was deleted using sf, in which case we
235
+ // do not want to migrate the sfdx key to sf.
236
+ // Programmatically differentiating between a new key and a deleted key
237
+ // would be nearly impossible. Instead, we should ensure that whenever
238
+ // sf deletes a key it also deletes it in sfdx. This way, we can safely
239
+ // assume that we should migrate any keys that exist in .sfdx
240
+ const unhandledSfdxKeys = sfdxKeys.filter((k) => !sfKeys.includes(k));
241
+ for (const k of unhandledSfdxKeys) {
242
+ (0, kit_1.set)(merged, `${key}["${k}"]`, sfdxData[key][k]);
243
+ }
244
+ // Keys that exist in .sf but not .sfdx are deleted because we assume
245
+ // that this means the key was deleted while using sfdx.
246
+ // We can make this assumption because keys that are created by sf will
247
+ // always be migrated back to sfdx
248
+ const unhandledSfKeys = sfKeys.filter((k) => !sfdxKeys.includes(k));
249
+ for (const k of unhandledSfKeys) {
250
+ delete merged[key][k];
251
+ }
252
+ return merged;
253
+ }
254
+ async migrate() {
255
+ const oldSandboxes = await this.listAllSandboxes();
256
+ const newSandboxes = Object.fromEntries(oldSandboxes.map((old) => [old.sandboxOrgId, old]));
257
+ return { [this.sfKey]: newSandboxes };
258
+ }
259
+ async write(latest, original) {
260
+ const { changed, deleted } = await this.findChanges(latest, original);
261
+ for (const sandboxData of Object.values(changed)) {
262
+ if (sandboxData) {
263
+ const orgId = sandboxData.sandboxOrgId;
264
+ const sandboxConfig = new sandboxOrgConfig_1.SandboxOrgConfig(sandboxOrgConfig_1.SandboxOrgConfig.getOptions(orgId));
265
+ sandboxConfig.set(sandboxOrgConfig_1.SandboxOrgConfig.Fields.PROD_ORG_USERNAME, sandboxData.prodOrgUsername);
266
+ await sandboxConfig.write();
267
+ }
268
+ }
269
+ for (const username of deleted) {
270
+ const originalSandbox = original.sandboxes[username];
271
+ const orgId = originalSandbox.sandboxOrgId;
272
+ const sandboxConfig = new sandboxOrgConfig_1.SandboxOrgConfig(sandboxOrgConfig_1.SandboxOrgConfig.getOptions(orgId));
273
+ await sandboxConfig.unlink();
274
+ }
275
+ }
276
+ async listAllSandboxFiles() {
277
+ const globalFiles = await fs.promises.readdir(global_1.Global.SFDX_DIR);
278
+ return globalFiles.filter((file) => file.match(SandboxesHandler.sandboxFilenameFilterRegEx));
279
+ }
280
+ async listAllSandboxes() {
281
+ return Promise.all((await this.listAllSandboxFiles()).map(async (filename) => {
282
+ const matches = filename.match(SandboxesHandler.sandboxFilenameFilterRegEx);
283
+ const orgId = matches ? matches[1] : '';
284
+ const sandboxConfig = new sandboxOrgConfig_1.SandboxOrgConfig(sandboxOrgConfig_1.SandboxOrgConfig.getOptions(orgId));
285
+ const stat = await sandboxConfig.stat();
286
+ const contents = { ...(await sandboxConfig.read(true)), sandboxOrgId: orgId };
287
+ const sandbox = Object.assign(contents, { timestamp: stat.mtime.toISOString() });
288
+ return sandbox;
289
+ }));
290
+ }
291
+ async findChanges(latest, original) {
292
+ var _a;
293
+ const latestSandboxes = latest.sandboxes;
294
+ const originalSandboxes = original.sandboxes;
295
+ const changed = {};
296
+ for (const [sandboxOrgId, sandbox] of Object.entries(latestSandboxes)) {
297
+ const originalSandbox = (_a = originalSandboxes[sandboxOrgId]) !== null && _a !== void 0 ? _a : {};
298
+ if (!isEqual(sandbox, originalSandbox)) {
299
+ changed[sandboxOrgId] = sandbox;
300
+ }
301
+ }
302
+ const deleted = Object.keys(originalSandboxes).filter((sandboxOrgId) => !latestSandboxes[sandboxOrgId]);
303
+ return { changed, deleted };
304
+ }
305
+ }
306
+ exports.SandboxesHandler = SandboxesHandler;
307
+ // The regular expression that filters files stored in $HOME/.sfdx
308
+ SandboxesHandler.sandboxFilenameFilterRegEx = /^(00D.*?)\.sandbox\.json$/;
214
309
  //# sourceMappingURL=sfdxDataHandler.js.map
@@ -2,7 +2,8 @@ import { JsonMap } from '@salesforce/ts-types';
2
2
  export declare enum SfInfoKeys {
3
3
  ORGS = "orgs",
4
4
  TOKENS = "tokens",
5
- ALIASES = "aliases"
5
+ ALIASES = "aliases",
6
+ SANDBOXES = "sandboxes"
6
7
  }
7
8
  export declare type Timestamp = {
8
9
  timestamp: string;
@@ -32,8 +33,25 @@ export interface SfTokens {
32
33
  export interface SfAliases {
33
34
  [alias: string]: string;
34
35
  }
36
+ export declare type SfSandbox = {
37
+ sandboxOrgId: string;
38
+ prodOrgUsername: string;
39
+ sandboxName?: string;
40
+ sandboxUsername?: string;
41
+ sandboxProcessId?: string;
42
+ sandboxInfoId?: string;
43
+ } & Timestamp & SfEntry;
44
+ /**
45
+ * The key will always be the sandbox username and the value will always be the
46
+ * production org username
47
+ * { "user@salesforce.com.mysandbox": "user@salesforce.com" }
48
+ */
49
+ export interface SfSandboxes {
50
+ [sandboxOrgId: string]: SfSandbox;
51
+ }
35
52
  export declare type SfInfo = {
36
53
  [SfInfoKeys.ORGS]: SfOrgs;
37
54
  [SfInfoKeys.TOKENS]: SfTokens;
38
55
  [SfInfoKeys.ALIASES]: SfAliases;
56
+ [SfInfoKeys.SANDBOXES]: SfSandboxes;
39
57
  };
@@ -6,5 +6,6 @@ var SfInfoKeys;
6
6
  SfInfoKeys["ORGS"] = "orgs";
7
7
  SfInfoKeys["TOKENS"] = "tokens";
8
8
  SfInfoKeys["ALIASES"] = "aliases";
9
+ SfInfoKeys["SANDBOXES"] = "sandboxes";
9
10
  })(SfInfoKeys = exports.SfInfoKeys || (exports.SfInfoKeys = {}));
10
11
  //# sourceMappingURL=types.js.map
@@ -46,6 +46,7 @@ export declare type OrgAuthorization = {
46
46
  configs: Nullable<string[]>;
47
47
  isScratchOrg?: boolean;
48
48
  isDevHub?: boolean;
49
+ isSandbox?: boolean;
49
50
  instanceUrl?: string;
50
51
  accessToken?: string;
51
52
  error?: string;
@@ -60,7 +61,7 @@ export interface AccessTokenOptions {
60
61
  instanceUrl?: string;
61
62
  }
62
63
  export declare type AuthSideEffects = {
63
- alias: string;
64
+ alias?: string;
64
65
  setDefault: boolean;
65
66
  setDefaultDevHub: boolean;
66
67
  };
@@ -166,6 +166,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
166
166
  instanceUrl,
167
167
  isScratchOrg: Boolean(devHubUsername),
168
168
  isDevHub: isDevHub || false,
169
+ isSandbox: globalInfo.sandboxes.has(orgId),
169
170
  orgId: orgId,
170
171
  accessToken: authInfo.getConnectionOptions().accessToken,
171
172
  oauthMethod: authInfo.isJwt() ? 'jwt' : authInfo.isOauth() ? 'web' : 'token',