@salesforce/core 2.32.0 → 2.34.2

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,31 @@
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
+ ### [2.34.2](https://github.com/forcedotcom/sfdx-core/compare/v2.33.2...v2.34.2) (2022-01-25)
6
+
7
+ ### [2.33.2](https://github.com/forcedotcom/sfdx-core/compare/v2.33.1...v2.33.2) (2022-01-25)
8
+
9
+ ### Bug Fixes
10
+
11
+ - cant use require on json as module use readFileSync instead ([3085029](https://github.com/forcedotcom/sfdx-core/commit/3085029e70d7f88e2535bf0b80240855f13abf37))
12
+ - correct import declaration ([4c69d2d](https://github.com/forcedotcom/sfdx-core/commit/4c69d2dc3370c5f920becfe260ccb178279e4d92))
13
+ - exit deploy loop with error on status SucceededPartial ([492e891](https://github.com/forcedotcom/sfdx-core/commit/492e89184e4c865cc7fcf7df41b9c6af6a6f2237))
14
+ - remove unwanted dep ([12ccc3a](https://github.com/forcedotcom/sfdx-core/commit/12ccc3adc0efbe687059187ab4d849b1741c823d))
15
+ - save auth info ([226bbd2](https://github.com/forcedotcom/sfdx-core/commit/226bbd2dc09a7a8df5887c0ae7548c83ae19b748))
16
+ - use correct dir structure ([e947fec](https://github.com/forcedotcom/sfdx-core/commit/e947fecf33a1c19ff80b33f7515e39d4e524f77f))
17
+
18
+ ### [2.33.1](https://github.com/forcedotcom/sfdx-core/compare/v2.33.0...v2.33.1) (2021-12-15)
19
+
20
+ ### Bug Fixes
21
+
22
+ - faye doesn't use custom stuff passed it ([b1cefc7](https://github.com/forcedotcom/sfdx-core/commit/b1cefc76afde7f0dd56ed72b5539a47c118eef63))
23
+
24
+ ## [2.33.0](https://github.com/forcedotcom/sfdx-core/compare/v2.32.0...v2.33.0) (2021-12-14)
25
+
26
+ ### Features
27
+
28
+ - sandbox creation ([314dcf1](https://github.com/forcedotcom/sfdx-core/commit/314dcf164d93bd0e3a5f4763a4dfcdde7d0cb14a))
29
+
5
30
  ## [2.32.0](https://github.com/forcedotcom/sfdx-core/compare/v2.31.1...v2.32.0) (2021-12-14)
6
31
 
7
32
  ### Features
package/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2021, Salesforce.com, Inc.
1
+ Copyright (c) 2022, Salesforce.com, Inc.
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
package/lib/exported.d.ts CHANGED
@@ -18,7 +18,7 @@ export { SfdcUrl } from './util/sfdcUrl';
18
18
  export { getJwtAudienceUrl } from './util/getJwtAudienceUrl';
19
19
  export { Fields, FieldValue, LoggerLevel, LoggerLevelValue, LogLine, LoggerOptions, LoggerStream, Logger, } from './logger';
20
20
  export { Messages } from './messages';
21
- export { Org } from './org';
21
+ export { Org, SandboxProcessObject, StatusEvent, SandboxEvents, SandboxUserAuthResponse, SandboxUserAuthRequest, SandboxRequest, OrgTypes, ResultEvent, ScratchOrgRequest, } from './org';
22
22
  export { PackageDir, NamedPackageDir, PackageDirDependency, SfdxProject, SfdxProjectJson } from './sfdxProject';
23
23
  export { SchemaPrinter } from './schema/printer';
24
24
  export { SchemaValidator } from './schema/validator';
@@ -29,5 +29,7 @@ export { CometClient, CometSubscription, StreamingClient } from './status/stream
29
29
  export { MyDomainResolver } from './status/myDomainResolver';
30
30
  export { DefaultUserFields, REQUIRED_FIELDS, User, UserFields } from './user';
31
31
  export { PermissionSetAssignment, PermissionSetAssignmentFields } from './permissionSetAssignment';
32
+ export { ScratchOrgCreateOptions, ScratchOrgCreateResult, scratchOrgCreate } from './scratchOrgCreate';
33
+ export { ScratchOrgInfo } from './scratchOrgInfoApi';
32
34
  export * from './util/fs';
33
35
  export * from './util/sfdc';
package/lib/exported.js CHANGED
@@ -16,7 +16,7 @@ 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.PermissionSetAssignment = exports.User = exports.REQUIRED_FIELDS = exports.DefaultUserFields = exports.MyDomainResolver = exports.StreamingClient = exports.CometClient = exports.PollingClient = exports.SfdxErrorConfig = exports.SfdxError = exports.SchemaValidator = exports.SchemaPrinter = exports.SfdxProjectJson = exports.SfdxProject = 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.OAuth2WithVerifier = exports.AuthInfo = exports.ConfigAggregator = exports.Config = exports.OrgUsersConfig = exports.DeviceOauthService = exports.BaseConfigStore = exports.ConfigGroup = exports.ConfigFile = exports.AuthInfoConfig = exports.AliasGroup = exports.Aliases = void 0;
19
+ exports.scratchOrgCreate = exports.PermissionSetAssignment = exports.User = exports.REQUIRED_FIELDS = exports.DefaultUserFields = exports.MyDomainResolver = exports.StreamingClient = exports.CometClient = exports.PollingClient = exports.SfdxErrorConfig = exports.SfdxError = exports.SchemaValidator = exports.SchemaPrinter = exports.SfdxProjectJson = exports.SfdxProject = 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.OAuth2WithVerifier = exports.AuthInfo = exports.ConfigAggregator = exports.Config = exports.OrgUsersConfig = exports.DeviceOauthService = exports.BaseConfigStore = exports.ConfigGroup = exports.ConfigFile = exports.AuthInfoConfig = exports.AliasGroup = exports.Aliases = void 0;
20
20
  const messages_1 = require("./messages");
21
21
  messages_1.Messages.importMessagesDirectory(__dirname);
22
22
  var aliases_1 = require("./config/aliases");
@@ -64,6 +64,8 @@ var messages_2 = require("./messages");
64
64
  Object.defineProperty(exports, "Messages", { enumerable: true, get: function () { return messages_2.Messages; } });
65
65
  var org_1 = require("./org");
66
66
  Object.defineProperty(exports, "Org", { enumerable: true, get: function () { return org_1.Org; } });
67
+ Object.defineProperty(exports, "SandboxEvents", { enumerable: true, get: function () { return org_1.SandboxEvents; } });
68
+ Object.defineProperty(exports, "OrgTypes", { enumerable: true, get: function () { return org_1.OrgTypes; } });
67
69
  var sfdxProject_1 = require("./sfdxProject");
68
70
  Object.defineProperty(exports, "SfdxProject", { enumerable: true, get: function () { return sfdxProject_1.SfdxProject; } });
69
71
  Object.defineProperty(exports, "SfdxProjectJson", { enumerable: true, get: function () { return sfdxProject_1.SfdxProjectJson; } });
@@ -87,6 +89,8 @@ Object.defineProperty(exports, "REQUIRED_FIELDS", { enumerable: true, get: funct
87
89
  Object.defineProperty(exports, "User", { enumerable: true, get: function () { return user_1.User; } });
88
90
  var permissionSetAssignment_1 = require("./permissionSetAssignment");
89
91
  Object.defineProperty(exports, "PermissionSetAssignment", { enumerable: true, get: function () { return permissionSetAssignment_1.PermissionSetAssignment; } });
92
+ var scratchOrgCreate_1 = require("./scratchOrgCreate");
93
+ Object.defineProperty(exports, "scratchOrgCreate", { enumerable: true, get: function () { return scratchOrgCreate_1.scratchOrgCreate; } });
90
94
  // Utility sub-modules
91
95
  __exportStar(require("./util/fs"), exports);
92
96
  __exportStar(require("./util/sfdc"), exports);
package/lib/org.d.ts CHANGED
@@ -1,10 +1,63 @@
1
- import { AsyncCreatable } from '@salesforce/kit';
1
+ import { AsyncCreatable, Duration } from '@salesforce/kit';
2
2
  import { AnyJson, JsonMap, Optional } from '@salesforce/ts-types';
3
+ import { ScratchOrgCreateOptions, ScratchOrgCreateResult } from './scratchOrgCreate';
3
4
  import { AuthFields, AuthInfo } from './authInfo';
4
5
  import { ConfigAggregator } from './config/configAggregator';
5
6
  import { OrgUsersConfig } from './config/orgUsersConfig';
6
7
  import { SandboxOrgConfig } from './config/sandboxOrgConfig';
7
8
  import { Connection } from './connection';
9
+ export declare enum OrgTypes {
10
+ Scratch = "scratch",
11
+ Sandbox = "sandbox"
12
+ }
13
+ export interface StatusEvent {
14
+ sandboxProcessObj: SandboxProcessObject;
15
+ interval: number;
16
+ retries: number;
17
+ waitingOnAuth: boolean;
18
+ }
19
+ export interface ResultEvent {
20
+ sandboxProcessObj: SandboxProcessObject;
21
+ sandboxRes: SandboxUserAuthResponse;
22
+ }
23
+ export interface SandboxUserAuthRequest {
24
+ sandboxName: string;
25
+ clientId: string;
26
+ callbackUrl: string;
27
+ }
28
+ export declare enum SandboxEvents {
29
+ EVENT_STATUS = "status",
30
+ EVENT_ASYNC_RESULT = "asyncResult",
31
+ EVENT_RESULT = "result",
32
+ EVENT_AUTH = "auth"
33
+ }
34
+ export interface SandboxUserAuthResponse {
35
+ authUserName: string;
36
+ authCode: string;
37
+ instanceUrl: string;
38
+ loginUrl: string;
39
+ }
40
+ export interface SandboxProcessObject {
41
+ Id: string;
42
+ Status: string;
43
+ SandboxName: string;
44
+ SandboxInfoId: string;
45
+ LicenseType: string;
46
+ CreatedDate: string;
47
+ SandboxOrganization?: string;
48
+ CopyProgress?: number;
49
+ SourceId?: string;
50
+ Description?: string;
51
+ ApexClassId?: string;
52
+ EndDate?: string;
53
+ }
54
+ export declare type SandboxRequest = {
55
+ SandboxName: string;
56
+ LicenseType?: string;
57
+ SourceId?: string;
58
+ Description?: string;
59
+ };
60
+ export declare type ScratchOrgRequest = Pick<ScratchOrgCreateOptions, 'connectedAppConsumerKey' | 'durationDays' | 'nonamespace' | 'noancestors' | 'wait' | 'retry' | 'apiversion' | 'definitionjson' | 'definitionfile' | 'orgConfig' | 'clientSecret'>;
8
61
  /**
9
62
  * Provides a way to manage a locally authenticated Org.
10
63
  *
@@ -41,6 +94,25 @@ export declare class Org extends AsyncCreatable<Org.Options> {
41
94
  * @ignore
42
95
  */
43
96
  constructor(options: Org.Options);
97
+ /**
98
+ * create a sandbox from a production org
99
+ * 'this' needs to be a production org with sandbox licenses available
100
+ *
101
+ * @param sandboxReq SandboxRequest options to create the sandbox with
102
+ * @param options Wait: The amount of time to wait before timing out, Interval: The time interval between polling
103
+ */
104
+ createSandbox(sandboxReq: SandboxRequest, options: {
105
+ wait?: Duration;
106
+ interval?: Duration;
107
+ }): Promise<SandboxProcessObject>;
108
+ /**
109
+ * Creates a scratchOrg
110
+ * 'this' needs to be a valid dev-hub
111
+ *
112
+ * @param {options} ScratchOrgCreateOptions
113
+ * @returns {ScratchOrgCreateResult}
114
+ */
115
+ scratchOrgCreate(options: ScratchOrgRequest): Promise<ScratchOrgCreateResult>;
44
116
  /**
45
117
  * Clean all data files in the org's data path. Usually <workspace>/.sfdx/orgs/<username>.
46
118
  *
@@ -233,6 +305,32 @@ export declare class Org extends AsyncCreatable<Org.Options> {
233
305
  * @param throwWhenRemoveFails true if manageDelete should throw or not if the deleted fails.
234
306
  */
235
307
  private removeSandboxConfig;
308
+ private writeSandboxAuthFile;
309
+ /**
310
+ * Polls for the new sandbox to be created - and will write the associated auth files
311
+ *
312
+ * @private
313
+ * @param options
314
+ * sandboxProcessObj: The in-progress sandbox signup request
315
+ * retries: the number of retries to poll for every 30s
316
+ * shouldPoll: wait for polling, or just return
317
+ * pollInterval: Duration to sleep between poll events, default 30 seconds
318
+ */
319
+ private pollStatusAndAuth;
320
+ /**
321
+ * query SandboxProcess via SandboxInfoId
322
+ *
323
+ * @param id SandboxInfoId to query for
324
+ * @private
325
+ */
326
+ private querySandboxProcess;
327
+ /**
328
+ * determines if the sandbox has successfully been created
329
+ *
330
+ * @param sandboxProcessObj sandbox signup progeress
331
+ * @private
332
+ */
333
+ private sandboxSignupComplete;
236
334
  }
237
335
  export declare namespace Org {
238
336
  /**
package/lib/org.js CHANGED
@@ -6,10 +6,11 @@
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.Org = void 0;
9
+ exports.Org = exports.SandboxEvents = exports.OrgTypes = void 0;
10
10
  const path_1 = require("path");
11
11
  const kit_1 = require("@salesforce/kit");
12
12
  const ts_types_1 = require("@salesforce/ts-types");
13
+ const scratchOrgCreate_1 = require("./scratchOrgCreate");
13
14
  const authInfo_1 = require("./authInfo");
14
15
  const aliases_1 = require("./config/aliases");
15
16
  const authInfoConfig_1 = require("./config/authInfoConfig");
@@ -19,10 +20,24 @@ const orgUsersConfig_1 = require("./config/orgUsersConfig");
19
20
  const sandboxOrgConfig_1 = require("./config/sandboxOrgConfig");
20
21
  const connection_1 = require("./connection");
21
22
  const global_1 = require("./global");
23
+ const lifecycleEvents_1 = require("./lifecycleEvents");
22
24
  const logger_1 = require("./logger");
23
25
  const sfdxError_1 = require("./sfdxError");
24
26
  const fs_1 = require("./util/fs");
25
27
  const sfdc_1 = require("./util/sfdc");
28
+ const webOAuthServer_1 = require("./webOAuthServer");
29
+ var OrgTypes;
30
+ (function (OrgTypes) {
31
+ OrgTypes["Scratch"] = "scratch";
32
+ OrgTypes["Sandbox"] = "sandbox";
33
+ })(OrgTypes = exports.OrgTypes || (exports.OrgTypes = {}));
34
+ var SandboxEvents;
35
+ (function (SandboxEvents) {
36
+ SandboxEvents["EVENT_STATUS"] = "status";
37
+ SandboxEvents["EVENT_ASYNC_RESULT"] = "asyncResult";
38
+ SandboxEvents["EVENT_RESULT"] = "result";
39
+ SandboxEvents["EVENT_AUTH"] = "auth";
40
+ })(SandboxEvents = exports.SandboxEvents || (exports.SandboxEvents = {}));
26
41
  /**
27
42
  * Provides a way to manage a locally authenticated Org.
28
43
  *
@@ -58,6 +73,43 @@ class Org extends kit_1.AsyncCreatable {
58
73
  this.status = Org.Status.UNKNOWN;
59
74
  this.options = options;
60
75
  }
76
+ /**
77
+ * create a sandbox from a production org
78
+ * 'this' needs to be a production org with sandbox licenses available
79
+ *
80
+ * @param sandboxReq SandboxRequest options to create the sandbox with
81
+ * @param options Wait: The amount of time to wait before timing out, Interval: The time interval between polling
82
+ */
83
+ async createSandbox(sandboxReq, options) {
84
+ var _a;
85
+ this.logger.debug('CreateSandbox called with SandboxRequest: %s ', sandboxReq);
86
+ const createResult = await this.connection.tooling.create('SandboxInfo', sandboxReq);
87
+ this.logger.debug('Return from calling tooling.create: %s ', createResult);
88
+ if (Array.isArray(createResult) || !createResult.success) {
89
+ throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'SandboxInfoCreateFailed', [JSON.stringify(createResult)]);
90
+ }
91
+ const sandboxCreationProgress = await this.querySandboxProcess(createResult.id);
92
+ this.logger.debug('Return from calling singleRecordQuery with tooling: %s', sandboxCreationProgress);
93
+ const retries = options.wait ? options.wait.seconds / kit_1.Duration.seconds(30).seconds : 0;
94
+ this.logger.debug('pollStatusAndAuth sandboxProcessObj %s, maxPollingRetries %i', sandboxCreationProgress, retries);
95
+ const pollInterval = (_a = options.interval) !== null && _a !== void 0 ? _a : kit_1.Duration.seconds(30);
96
+ return this.pollStatusAndAuth({
97
+ sandboxProcessObj: sandboxCreationProgress,
98
+ retries,
99
+ shouldPoll: retries > 0,
100
+ pollInterval,
101
+ });
102
+ }
103
+ /**
104
+ * Creates a scratchOrg
105
+ * 'this' needs to be a valid dev-hub
106
+ *
107
+ * @param {options} ScratchOrgCreateOptions
108
+ * @returns {ScratchOrgCreateResult}
109
+ */
110
+ async scratchOrgCreate(options) {
111
+ return scratchOrgCreate_1.scratchOrgCreate({ ...options, hubOrg: this });
112
+ }
61
113
  /**
62
114
  * Clean all data files in the org's data path. Usually <workspace>/.sfdx/orgs/<username>.
63
115
  *
@@ -594,6 +646,7 @@ class Org extends kit_1.AsyncCreatable {
594
646
  *
595
647
  * @param throwWhenRemoveFails true if manageDelete should throw or not if the deleted fails.
596
648
  */
649
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
597
650
  async removeUsers(throwWhenRemoveFails) {
598
651
  this.logger.debug(`Removing users associate with org: ${this.getOrgId()}`);
599
652
  const config = await this.retrieveOrgUsersConfig();
@@ -637,6 +690,167 @@ class Org extends kit_1.AsyncCreatable {
637
690
  await this.manageDelete(async () => await sandboxOrgConfig.unlink(), sandboxOrgConfig.getPath(), throwWhenRemoveFails);
638
691
  }
639
692
  }
693
+ async writeSandboxAuthFile(sandboxProcessObj, sandboxRes) {
694
+ this.logger.debug('writeSandboxAuthFile sandboxProcessObj: %s, sandboxRes: %s', sandboxProcessObj, sandboxRes);
695
+ if (sandboxRes.authUserName) {
696
+ const productionAuthFields = this.connection.getAuthInfoFields();
697
+ this.logger.debug('Result from getAuthInfoFields: AuthFields %s', productionAuthFields);
698
+ // let's do headless auth via jwt (if we have privateKey) or web auth
699
+ const oauth2Options = {
700
+ loginUrl: sandboxRes.loginUrl,
701
+ instanceUrl: sandboxRes.instanceUrl,
702
+ username: sandboxRes.authUserName,
703
+ };
704
+ // If we don't have a privateKey then we assume it's web auth.
705
+ if (!productionAuthFields.privateKey) {
706
+ oauth2Options.redirectUri = `http://localhost:${await webOAuthServer_1.WebOAuthServer.determineOauthPort()}/OauthRedirect`;
707
+ oauth2Options.authCode = sandboxRes.authCode;
708
+ }
709
+ const authInfo = await authInfo_1.AuthInfo.create({
710
+ username: sandboxRes.authUserName,
711
+ oauth2Options,
712
+ parentUsername: productionAuthFields.username,
713
+ });
714
+ await authInfo.save();
715
+ const sandboxOrg = await Org.create({ aliasOrUsername: authInfo.getUsername() });
716
+ await sandboxOrg.setSandboxOrgConfigField(sandboxOrgConfig_1.SandboxOrgConfig.Fields.PROD_ORG_USERNAME,
717
+ // we couldn't get this far into the process without a production org so username will be there
718
+ productionAuthFields.username);
719
+ await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_RESULT, {
720
+ sandboxProcessObj,
721
+ sandboxRes,
722
+ });
723
+ }
724
+ else {
725
+ // no authed sandbox user, error
726
+ throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'MissingAuthUsername', [sandboxProcessObj.SandboxName]);
727
+ }
728
+ }
729
+ /**
730
+ * Polls for the new sandbox to be created - and will write the associated auth files
731
+ *
732
+ * @private
733
+ * @param options
734
+ * sandboxProcessObj: The in-progress sandbox signup request
735
+ * retries: the number of retries to poll for every 30s
736
+ * shouldPoll: wait for polling, or just return
737
+ * pollInterval: Duration to sleep between poll events, default 30 seconds
738
+ */
739
+ async pollStatusAndAuth(options) {
740
+ const { sandboxProcessObj, retries, shouldPoll, pollInterval } = options;
741
+ this.logger.debug('PollStatusAndAuth called with SandboxProcessObject%s, retries %s', sandboxProcessObj, retries);
742
+ const lifecycle = lifecycleEvents_1.Lifecycle.getInstance();
743
+ let pollFinished = false;
744
+ let waitingOnAuth = false;
745
+ const sandboxInfo = await this.sandboxSignupComplete(sandboxProcessObj);
746
+ if (sandboxInfo) {
747
+ await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_AUTH, sandboxInfo);
748
+ try {
749
+ this.logger.debug('sandbox signup complete with %s', sandboxInfo);
750
+ await this.writeSandboxAuthFile(sandboxProcessObj, sandboxInfo);
751
+ pollFinished = true;
752
+ }
753
+ catch (err) {
754
+ this.logger.debug('Exception while calling writeSandboxAuthFile %s', err);
755
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'JWTAuthError' && (err === null || err === void 0 ? void 0 : err.stack.includes("user hasn't approved"))) {
756
+ waitingOnAuth = true;
757
+ }
758
+ else {
759
+ throw sfdxError_1.SfdxError.wrap(err);
760
+ }
761
+ }
762
+ }
763
+ if (!pollFinished) {
764
+ if (retries > 0) {
765
+ // emit the signup progress of the sandbox and query the production org again after waiting the interval
766
+ await Promise.all([
767
+ await lifecycle.emit(SandboxEvents.EVENT_STATUS, {
768
+ sandboxProcessObj,
769
+ interval: pollInterval.seconds,
770
+ retries,
771
+ waitingOnAuth,
772
+ }),
773
+ await kit_1.sleep(pollInterval),
774
+ ]);
775
+ const polledSandboxProcessObj = await this.querySandboxProcess(sandboxProcessObj.SandboxInfoId);
776
+ return this.pollStatusAndAuth({
777
+ sandboxProcessObj: polledSandboxProcessObj,
778
+ retries: retries - 1,
779
+ shouldPoll,
780
+ pollInterval,
781
+ });
782
+ }
783
+ else {
784
+ if (shouldPoll) {
785
+ // timed out on retries
786
+ throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'OrgPollingTimeout', [sandboxProcessObj.Status]);
787
+ }
788
+ else {
789
+ // The user didn't want us to poll, so simply return the status
790
+ // simply report status and exit
791
+ await lifecycle.emit(SandboxEvents.EVENT_ASYNC_RESULT, sandboxProcessObj);
792
+ }
793
+ }
794
+ }
795
+ return sandboxProcessObj;
796
+ }
797
+ /**
798
+ * query SandboxProcess via SandboxInfoId
799
+ *
800
+ * @param id SandboxInfoId to query for
801
+ * @private
802
+ */
803
+ async querySandboxProcess(id) {
804
+ const queryStr = `SELECT Id, Status, SandboxName, SandboxInfoId, LicenseType, CreatedDate, CopyProgress, SandboxOrganization, SourceId, Description, EndDate FROM SandboxProcess WHERE SandboxInfoId='${id}' AND Status != 'D'`;
805
+ return await this.connection.singleRecordQuery(queryStr, {
806
+ tooling: true,
807
+ });
808
+ }
809
+ /**
810
+ * determines if the sandbox has successfully been created
811
+ *
812
+ * @param sandboxProcessObj sandbox signup progeress
813
+ * @private
814
+ */
815
+ async sandboxSignupComplete(sandboxProcessObj) {
816
+ this.logger.debug('sandboxSignupComplete called with SandboxProcessObject %s', sandboxProcessObj);
817
+ if (!sandboxProcessObj.EndDate) {
818
+ return;
819
+ }
820
+ try {
821
+ // call server side /sandboxAuth API to auth the sandbox org user with the connected app
822
+ const authFields = this.connection.getAuthInfoFields();
823
+ const callbackUrl = `http://localhost:${await webOAuthServer_1.WebOAuthServer.determineOauthPort()}/OauthRedirect`;
824
+ const sandboxReq = {
825
+ // the sandbox signup has been completed on production, we have production clientId by this point
826
+ clientId: authFields.clientId,
827
+ sandboxName: sandboxProcessObj.SandboxName,
828
+ callbackUrl,
829
+ };
830
+ this.logger.debug('Calling sandboxAuth with SandboxUserAuthRequest %s', sandboxReq);
831
+ const url = `${this.connection.tooling._baseUrl()}/sandboxAuth`;
832
+ const params = {
833
+ method: 'POST',
834
+ url,
835
+ headers: { 'Content-Type': 'application/json' },
836
+ body: JSON.stringify(sandboxReq),
837
+ };
838
+ const result = await this.connection.tooling.request(params);
839
+ this.logger.debug('Result of calling sandboxAuth %s', result);
840
+ return result;
841
+ }
842
+ catch (err) {
843
+ // There are cases where the endDate is set before the sandbox has actually completed.
844
+ // In that case, the sandboxAuth call will throw a specific exception.
845
+ if ((err === null || err === void 0 ? void 0 : err.name) === 'INVALID_STATUS') {
846
+ this.logger.debug('Error while authenticating the user %s', err === null || err === void 0 ? void 0 : err.toString());
847
+ }
848
+ else {
849
+ // If it fails for any unexpected reason, just pass that through
850
+ throw sfdxError_1.SfdxError.wrap(err);
851
+ }
852
+ }
853
+ }
640
854
  }
641
855
  exports.Org = Org;
642
856
  (function (Org) {
@@ -0,0 +1,43 @@
1
+ import { Duration } from '@salesforce/kit';
2
+ import { Org } from './org';
3
+ import { AuthInfo, AuthFields } from './authInfo';
4
+ import { ScratchOrgInfo } from './scratchOrgInfoApi';
5
+ export declare const DEFAULT_STREAM_TIMEOUT_MINUTES = 6;
6
+ export interface ScratchOrgCreateResult {
7
+ username?: string;
8
+ scratchOrgInfo?: ScratchOrgInfo;
9
+ authInfo?: AuthInfo;
10
+ authFields?: AuthFields;
11
+ warnings: string[];
12
+ }
13
+ /**
14
+ * interface ScratchOrgCreateOptions
15
+ *
16
+ * @param hubOrg the environment hub org
17
+ * @param connectedAppConsumerKey The connected app consumer key.
18
+ * @param durationDays duration of the scratch org (in days) (default:1, min:1, max:30)
19
+ * @param nonamespace create the scratch org with no namespace
20
+ * @param noancestors do not include second-generation package ancestors in the scratch org
21
+ * @param wait the streaming client socket timeout (in minutes) must be an instance of the Duration utility class (default:6, min:2)
22
+ * @param retry number of scratch org auth retries after scratch org is successfully signed up (default:0, min:0, max:10)
23
+ * @param apiversion target server instance API version
24
+ * @param definitionjson org definition in JSON format
25
+ * @param definitionfile path to an org definition file
26
+ * @param orgConfig overrides definitionjson
27
+ * @param clientSecret OAuth client secret of personal connected app
28
+ */
29
+ export interface ScratchOrgCreateOptions {
30
+ hubOrg: Org;
31
+ connectedAppConsumerKey?: string;
32
+ durationDays?: number;
33
+ nonamespace?: boolean;
34
+ noancestors?: boolean;
35
+ wait?: Duration;
36
+ retry?: number;
37
+ apiversion?: string;
38
+ definitionjson?: string;
39
+ definitionfile?: string;
40
+ orgConfig?: Record<string, unknown>;
41
+ clientSecret?: string;
42
+ }
43
+ export declare const scratchOrgCreate: (options: ScratchOrgCreateOptions) => Promise<ScratchOrgCreateResult>;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2020, 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.scratchOrgCreate = exports.DEFAULT_STREAM_TIMEOUT_MINUTES = void 0;
10
+ // third
11
+ const kit_1 = require("@salesforce/kit");
12
+ const ts_types_1 = require("@salesforce/ts-types");
13
+ // Local
14
+ const org_1 = require("./org");
15
+ const logger_1 = require("./logger");
16
+ const messages_1 = require("./messages");
17
+ const sfdxError_1 = require("./sfdxError");
18
+ const connection_1 = require("./connection");
19
+ const sfdxProject_1 = require("./sfdxProject");
20
+ const configAggregator_1 = require("./config/configAggregator");
21
+ const scratchOrgInfoApi_1 = require("./scratchOrgInfoApi");
22
+ const scratchOrgSettingsGenerator_1 = require("./scratchOrgSettingsGenerator");
23
+ const scratchOrgInfoGenerator_1 = require("./scratchOrgInfoGenerator");
24
+ messages_1.Messages.importMessagesDirectory(__dirname);
25
+ const messages = messages_1.Messages.loadMessages('@salesforce/core', 'scratchOrgCreate');
26
+ exports.DEFAULT_STREAM_TIMEOUT_MINUTES = 6;
27
+ const validateDuration = (durationDays) => {
28
+ const min = 1;
29
+ const max = 30;
30
+ if (Number.isInteger(durationDays)) {
31
+ if (durationDays < min) {
32
+ throw new sfdxError_1.SfdxError(`Expected 'durationDays' greater than or equal to ${min} but received ${durationDays}`, 'BoundsError');
33
+ }
34
+ if (durationDays > max) {
35
+ throw new sfdxError_1.SfdxError(`Expected 'durationDays' less than or equal to ${max} but received ${durationDays}`, 'BoundsError');
36
+ }
37
+ return;
38
+ }
39
+ throw new sfdxError_1.SfdxError("Expected 'durationDays' to be an integer number", 'TypeError');
40
+ };
41
+ const validateRetry = (retry) => {
42
+ if (Number.isInteger(retry)) {
43
+ return;
44
+ }
45
+ throw new sfdxError_1.SfdxError("Expected 'retry' to be an integer number", 'TypeError');
46
+ };
47
+ const validateWait = (wait) => {
48
+ const min = 2;
49
+ if (wait.minutes < min) {
50
+ throw new sfdxError_1.SfdxError(`Expected 'wait' greater than or equal to ${min} but received ${wait}`, 'BoundsError');
51
+ }
52
+ };
53
+ const scratchOrgCreate = async (options) => {
54
+ var _a;
55
+ const logger = await logger_1.Logger.child('scratchOrgCreate');
56
+ logger.debug('scratchOrgCreate');
57
+ const { hubOrg, connectedAppConsumerKey, durationDays = 1, nonamespace, noancestors, wait = kit_1.Duration.minutes(exports.DEFAULT_STREAM_TIMEOUT_MINUTES), retry = 0, apiversion, definitionjson, definitionfile, orgConfig, clientSecret = undefined, } = options;
58
+ validateDuration(durationDays);
59
+ validateRetry(retry);
60
+ validateWait(wait);
61
+ const { scratchOrgInfoPayload, ignoreAncestorIds, warnings } = await scratchOrgInfoGenerator_1.getScratchOrgInfoPayload({
62
+ definitionjson,
63
+ definitionfile,
64
+ connectedAppConsumerKey,
65
+ durationDays,
66
+ nonamespace,
67
+ noancestors,
68
+ orgConfig,
69
+ });
70
+ const scratchOrgInfo = await scratchOrgInfoGenerator_1.generateScratchOrgInfo({
71
+ hubOrg,
72
+ scratchOrgInfoPayload,
73
+ nonamespace,
74
+ ignoreAncestorIds,
75
+ });
76
+ // gets the scratch org settings (will use in both signup paths AND to deploy the settings)
77
+ const settingsGenerator = new scratchOrgSettingsGenerator_1.default();
78
+ await settingsGenerator.extract(scratchOrgInfo);
79
+ logger.debug(`the scratch org def file has settings: ${settingsGenerator.hasSettings()}`);
80
+ // creates the scratch org info in the devhub
81
+ const scratchOrgInfoRequestResult = await scratchOrgInfoApi_1.requestScratchOrgCreation(hubOrg, scratchOrgInfo, settingsGenerator);
82
+ const scratchOrgInfoId = ts_types_1.ensureString(ts_types_1.getString(scratchOrgInfoRequestResult, 'id'));
83
+ logger.debug(`scratch org has recordId ${scratchOrgInfoId}`);
84
+ const scratchOrgInfoResult = await scratchOrgInfoApi_1.pollForScratchOrgInfo(hubOrg, scratchOrgInfoId, wait);
85
+ const signupTargetLoginUrlConfig = await getSignupTargetLoginUrl();
86
+ const scratchOrgAuthInfo = await scratchOrgInfoApi_1.authorizeScratchOrg({
87
+ scratchOrgInfoComplete: scratchOrgInfoResult,
88
+ hubOrg,
89
+ clientSecret,
90
+ signupTargetLoginUrlConfig,
91
+ retry: retry || 0,
92
+ });
93
+ // we'll need this scratch org connection later;
94
+ const connection = await connection_1.Connection.create({ authInfo: scratchOrgAuthInfo });
95
+ const scratchOrg = await org_1.Org.create({ connection }); // scartchOrg should come from command
96
+ const username = scratchOrg.getUsername();
97
+ logger.debug(`scratch org username ${username}`);
98
+ const configAggregator = new configAggregator_1.ConfigAggregator();
99
+ const authInfo = await scratchOrgInfoApi_1.deploySettingsAndResolveUrl(scratchOrgAuthInfo, (_a = apiversion !== null && apiversion !== void 0 ? apiversion : configAggregator.getPropertyValue('apiVersion')) !== null && _a !== void 0 ? _a : (await scratchOrg.retrieveMaxApiVersion()), settingsGenerator, scratchOrg);
100
+ logger.trace('Settings deployed to org');
101
+ /** updating the revision num to zero during org:creation if source members are created during org:create.This only happens for some specific scratch org definition file.*/
102
+ await updateRevisionCounterToZero(scratchOrg);
103
+ return {
104
+ username,
105
+ scratchOrgInfo: scratchOrgInfoResult,
106
+ authInfo,
107
+ authFields: authInfo === null || authInfo === void 0 ? void 0 : authInfo.getFields(),
108
+ warnings,
109
+ };
110
+ };
111
+ exports.scratchOrgCreate = scratchOrgCreate;
112
+ const getSignupTargetLoginUrl = async () => {
113
+ try {
114
+ const project = await sfdxProject_1.SfdxProject.resolve();
115
+ const projectJson = await project.resolveProjectConfig();
116
+ return projectJson.signupTargetLoginUrl;
117
+ }
118
+ catch {
119
+ // a project isn't required for org:create
120
+ }
121
+ };
122
+ const updateRevisionCounterToZero = async (scratchOrg) => {
123
+ const conn = scratchOrg.getConnection();
124
+ const queryResult = await conn.tooling.sobject('SourceMember').find({ RevisionCounter: { $gt: 0 } }, ['Id']);
125
+ try {
126
+ await conn.tooling
127
+ .sobject('SourceMember')
128
+ .update(queryResult.map((record) => ({ Id: record.Id, RevisionCounter: 0 })));
129
+ }
130
+ catch (err) {
131
+ const message = messages.getMessage('SourceStatusResetFailure', [scratchOrg.getOrgId(), scratchOrg.getUsername()]);
132
+ throw new sfdxError_1.SfdxError(message, 'SourceStatusResetFailure');
133
+ }
134
+ };
135
+ //# sourceMappingURL=scratchOrgCreate.js.map
@@ -0,0 +1,4 @@
1
+ import { Optional } from '@salesforce/ts-types';
2
+ import { Logger } from './logger';
3
+ import { ScratchOrgInfo } from './scratchOrgInfoApi';
4
+ export declare const checkScratchOrgInfoForErrors: (orgInfo: ScratchOrgInfo, hubUsername: Optional<string>, logger: Logger) => ScratchOrgInfo;