@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.
@@ -10,34 +10,43 @@ export interface ScratchOrgCreateResult {
10
10
  authFields?: AuthFields;
11
11
  warnings: string[];
12
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
13
  export interface ScratchOrgCreateOptions {
14
+ /** the environment hub org */
30
15
  hubOrg: Org;
16
+ /** The connected app consumer key. */
31
17
  connectedAppConsumerKey?: string;
18
+ /** duration of the scratch org (in days) (default:1, min:1, max:30) */
32
19
  durationDays?: number;
20
+ /** create the scratch org with no namespace */
33
21
  nonamespace?: boolean;
22
+ /** create the scratch org with no second-generation package ancestors */
34
23
  noancestors?: boolean;
24
+ /** the streaming client socket timeout (in minutes) must be an instance of the Duration utility class (default:6) */
35
25
  wait?: Duration;
26
+ /** number of scratch org auth retries after scratch org is successfully signed up (default:0, min:0, max:10) */
36
27
  retry?: number;
28
+ /** target server instance API version */
37
29
  apiversion?: string;
30
+ /**
31
+ * org definition in JSON format, stringified
32
+ *
33
+ * @deprecated use orgConfig
34
+ */
38
35
  definitionjson?: string;
36
+ /**
37
+ * path to an org definition file
38
+ *
39
+ * @deprecated use orgConfig
40
+ * */
39
41
  definitionfile?: string;
42
+ /** overrides definitionjson */
40
43
  orgConfig?: Record<string, unknown>;
44
+ /** OAuth client secret of personal connected app */
41
45
  clientSecret?: string;
46
+ /** alias to set for the created org */
47
+ alias?: string;
48
+ /** after complete, set the org as the default */
49
+ setDefault?: boolean;
42
50
  }
51
+ export declare const scratchOrgResume: (jobId: string) => Promise<ScratchOrgCreateResult>;
43
52
  export declare const scratchOrgCreate: (options: ScratchOrgCreateOptions) => Promise<ScratchOrgCreateResult>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.scratchOrgCreate = exports.DEFAULT_STREAM_TIMEOUT_MINUTES = void 0;
3
+ exports.scratchOrgCreate = exports.scratchOrgResume = exports.DEFAULT_STREAM_TIMEOUT_MINUTES = void 0;
4
4
  /*
5
5
  * Copyright (c) 2020, salesforce.com, inc.
6
6
  * All rights reserved.
@@ -13,13 +13,15 @@ const messages_1 = require("../messages");
13
13
  const logger_1 = require("../logger");
14
14
  const configAggregator_1 = require("../config/configAggregator");
15
15
  const sfProject_1 = require("../sfProject");
16
- const lifecycleEvents_1 = require("../lifecycleEvents");
16
+ const globalInfo_1 = require("../globalInfo");
17
17
  const org_1 = require("./org");
18
18
  const scratchOrgInfoApi_1 = require("./scratchOrgInfoApi");
19
19
  const scratchOrgSettingsGenerator_1 = require("./scratchOrgSettingsGenerator");
20
20
  const scratchOrgInfoGenerator_1 = require("./scratchOrgInfoGenerator");
21
- const connection_1 = require("./connection");
21
+ const authInfo_1 = require("./authInfo");
22
22
  const scratchOrgLifecycleEvents_1 = require("./scratchOrgLifecycleEvents");
23
+ const scratchOrgCache_1 = require("./scratchOrgCache");
24
+ const scratchOrgErrorCodes_1 = require("./scratchOrgErrorCodes");
23
25
  messages_1.Messages.importMessagesDirectory(__dirname);
24
26
  const messages = messages_1.Messages.load('@salesforce/core', 'scratchOrgCreate', [
25
27
  'SourceStatusResetFailureError',
@@ -28,6 +30,11 @@ const messages = messages_1.Messages.load('@salesforce/core', 'scratchOrgCreate'
28
30
  'RetryNotIntError',
29
31
  'WaitValidationMaxError',
30
32
  'DurationDaysNotIntError',
33
+ 'NoScratchOrgInfoError',
34
+ 'ScratchOrgDeletedError',
35
+ 'StillInProgressError',
36
+ 'CacheMissError',
37
+ 'action.StillInProgress',
31
38
  ]);
32
39
  exports.DEFAULT_STREAM_TIMEOUT_MINUTES = 6;
33
40
  const validateDuration = (durationDays) => {
@@ -49,21 +56,70 @@ const validateRetry = (retry) => {
49
56
  throw messages.createError('RetryNotIntError');
50
57
  }
51
58
  };
52
- const validateWait = (wait) => {
53
- const min = 2;
54
- if (wait.minutes < min) {
55
- throw messages.createError('WaitValidationMaxError', [min, wait.minutes]);
59
+ const scratchOrgResume = async (jobId) => {
60
+ var _a, _b, _c;
61
+ const [logger, cache] = await Promise.all([
62
+ logger_1.Logger.child('scratchOrgResume'),
63
+ scratchOrgCache_1.ScratchOrgCache.create(),
64
+ (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'send request' }),
65
+ ]);
66
+ logger.debug(`resuming scratch org creation for jobId: ${jobId}`);
67
+ if (!cache.has(jobId)) {
68
+ throw messages.createError('CacheMissError', [jobId]);
56
69
  }
70
+ const { hubUsername, apiVersion, clientSecret, signupTargetLoginUrlConfig, definitionjson, alias, setDefault } = cache.get(jobId);
71
+ const hubOrg = await org_1.Org.create({ aliasOrUsername: hubUsername });
72
+ const soi = await (0, scratchOrgInfoApi_1.queryScratchOrgInfo)(hubOrg, jobId);
73
+ await (0, scratchOrgErrorCodes_1.validateScratchOrgInfoForResume)({ jobId, scratchOrgInfo: soi, cache, hubUsername });
74
+ // At this point, the scratch org is "good".
75
+ // Some hubs have all the usernames set to `null`
76
+ const username = (_a = soi.Username) !== null && _a !== void 0 ? _a : soi.SignupUsername;
77
+ // re-auth only if the org isn't in GlobalInfo
78
+ const globalInfo = await globalInfo_1.GlobalInfo.getInstance();
79
+ const scratchOrgAuthInfo = globalInfo.orgs.has(username)
80
+ ? await authInfo_1.AuthInfo.create({
81
+ username,
82
+ })
83
+ : await (0, scratchOrgInfoApi_1.authorizeScratchOrg)({
84
+ scratchOrgInfoComplete: soi,
85
+ hubOrg,
86
+ clientSecret,
87
+ signupTargetLoginUrlConfig,
88
+ retry: 0,
89
+ });
90
+ const scratchOrg = await org_1.Org.create({ aliasOrUsername: username });
91
+ await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'deploy settings', scratchOrgInfo: soi });
92
+ const settingsGenerator = new scratchOrgSettingsGenerator_1.default();
93
+ settingsGenerator.extract({ ...soi, ...definitionjson });
94
+ const [authInfo] = await Promise.all([
95
+ (0, scratchOrgInfoApi_1.resolveUrl)(scratchOrgAuthInfo),
96
+ (0, scratchOrgInfoApi_1.deploySettings)(scratchOrg, settingsGenerator, (_b = apiVersion !== null && apiVersion !== void 0 ? apiVersion : new configAggregator_1.ConfigAggregator().getPropertyValue('apiVersion')) !== null && _b !== void 0 ? _b : (await scratchOrg.retrieveMaxApiVersion())),
97
+ ]);
98
+ await scratchOrgAuthInfo.handleAliasAndDefaultSettings({
99
+ alias,
100
+ setDefault: setDefault !== null && setDefault !== void 0 ? setDefault : false,
101
+ setDefaultDevHub: false,
102
+ });
103
+ cache.unset((_c = soi.Id) !== null && _c !== void 0 ? _c : jobId);
104
+ const authFields = authInfo.getFields();
105
+ await Promise.all([(0, scratchOrgLifecycleEvents_1.emit)({ stage: 'done', scratchOrgInfo: soi }), cache.write(), (0, scratchOrgLifecycleEvents_1.emitPostOrgCreate)(authFields)]);
106
+ return {
107
+ username,
108
+ scratchOrgInfo: soi,
109
+ authInfo,
110
+ authFields,
111
+ warnings: [],
112
+ };
57
113
  };
114
+ exports.scratchOrgResume = scratchOrgResume;
58
115
  const scratchOrgCreate = async (options) => {
59
- var _a;
116
+ var _a, _b, _c;
60
117
  const logger = await logger_1.Logger.child('scratchOrgCreate');
61
118
  logger.debug('scratchOrgCreate');
62
119
  await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'prepare request' });
63
- 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;
120
+ 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, alias, setDefault = false, } = options;
64
121
  validateDuration(durationDays);
65
122
  validateRetry(retry);
66
- validateWait(wait);
67
123
  const { scratchOrgInfoPayload, ignoreAncestorIds, warnings } = await (0, scratchOrgInfoGenerator_1.getScratchOrgInfoPayload)({
68
124
  definitionjson,
69
125
  definitionfile,
@@ -81,36 +137,64 @@ const scratchOrgCreate = async (options) => {
81
137
  });
82
138
  // gets the scratch org settings (will use in both signup paths AND to deploy the settings)
83
139
  const settingsGenerator = new scratchOrgSettingsGenerator_1.default();
84
- await settingsGenerator.extract(scratchOrgInfo);
140
+ const settings = await settingsGenerator.extract(scratchOrgInfo);
85
141
  logger.debug(`the scratch org def file has settings: ${settingsGenerator.hasSettings()}`);
86
- // creates the scratch org info in the devhub
87
- const scratchOrgInfoRequestResult = await (0, scratchOrgInfoApi_1.requestScratchOrgCreation)(hubOrg, scratchOrgInfo, settingsGenerator);
142
+ const [scratchOrgInfoRequestResult, signupTargetLoginUrlConfig] = await Promise.all([
143
+ // creates the scratch org info in the devhub
144
+ (0, scratchOrgInfoApi_1.requestScratchOrgCreation)(hubOrg, scratchOrgInfo, settingsGenerator),
145
+ getSignupTargetLoginUrl(),
146
+ ]);
88
147
  const scratchOrgInfoId = (0, ts_types_1.ensureString)((0, ts_types_1.getString)(scratchOrgInfoRequestResult, 'id'));
148
+ const cache = await scratchOrgCache_1.ScratchOrgCache.create();
149
+ cache.set(scratchOrgInfoId, {
150
+ hubUsername: hubOrg.getUsername(),
151
+ hubBaseUrl: (_a = hubOrg.getField(org_1.Org.Fields.INSTANCE_URL)) === null || _a === void 0 ? void 0 : _a.toString(),
152
+ definitionjson: { ...(definitionjson ? JSON.parse(definitionjson) : {}), ...orgConfig, ...settings },
153
+ clientSecret,
154
+ alias,
155
+ setDefault,
156
+ });
157
+ await cache.write();
89
158
  logger.debug(`scratch org has recordId ${scratchOrgInfoId}`);
90
- const scratchOrgInfoResult = await (0, scratchOrgInfoApi_1.pollForScratchOrgInfo)(hubOrg, scratchOrgInfoId, wait);
91
- const signupTargetLoginUrlConfig = await getSignupTargetLoginUrl();
159
+ // this is where we stop--no polling
160
+ if (wait.minutes === 0) {
161
+ const soi = await (0, scratchOrgInfoApi_1.queryScratchOrgInfo)(hubOrg, scratchOrgInfoId);
162
+ return {
163
+ username: soi.SignupUsername,
164
+ warnings: [],
165
+ scratchOrgInfo: soi,
166
+ };
167
+ }
168
+ const soi = await (0, scratchOrgInfoApi_1.pollForScratchOrgInfo)(hubOrg, scratchOrgInfoId, wait);
92
169
  const scratchOrgAuthInfo = await (0, scratchOrgInfoApi_1.authorizeScratchOrg)({
93
- scratchOrgInfoComplete: scratchOrgInfoResult,
170
+ scratchOrgInfoComplete: soi,
94
171
  hubOrg,
95
172
  clientSecret,
96
173
  signupTargetLoginUrlConfig,
97
174
  retry: retry || 0,
98
175
  });
99
176
  // we'll need this scratch org connection later;
100
- const connection = await connection_1.Connection.create({ authInfo: scratchOrgAuthInfo });
101
- const scratchOrg = await org_1.Org.create({ connection }); // scartchOrg should come from command
177
+ const scratchOrg = await org_1.Org.create({
178
+ aliasOrUsername: (_b = soi.Username) !== null && _b !== void 0 ? _b : soi.SignupUsername,
179
+ });
102
180
  const username = scratchOrg.getUsername();
103
181
  logger.debug(`scratch org username ${username}`);
104
- const configAggregator = new configAggregator_1.ConfigAggregator();
105
- await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'deploy settings', scratchOrgInfo: scratchOrgInfoResult });
106
- const authInfo = await (0, scratchOrgInfoApi_1.deploySettingsAndResolveUrl)(scratchOrgAuthInfo, (_a = apiversion !== null && apiversion !== void 0 ? apiversion : configAggregator.getPropertyValue('org-api-version')) !== null && _a !== void 0 ? _a : (await scratchOrg.retrieveMaxApiVersion()), settingsGenerator, scratchOrg);
107
- logger.trace('Settings deployed to org');
108
- /** 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.*/
109
- await updateRevisionCounterToZero(scratchOrg);
110
- await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'done', scratchOrgInfo: scratchOrgInfoResult });
182
+ await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'deploy settings', scratchOrgInfo: soi });
183
+ const [authInfo] = await Promise.all([
184
+ (0, scratchOrgInfoApi_1.resolveUrl)(scratchOrgAuthInfo),
185
+ (0, scratchOrgInfoApi_1.deploySettings)(scratchOrg, settingsGenerator, (_c = apiversion !== null && apiversion !== void 0 ? apiversion : new configAggregator_1.ConfigAggregator().getPropertyValue('org-api-version')) !== null && _c !== void 0 ? _c : (await scratchOrg.retrieveMaxApiVersion())),
186
+ ]);
187
+ await scratchOrgAuthInfo.handleAliasAndDefaultSettings({
188
+ alias,
189
+ setDefault,
190
+ setDefaultDevHub: false,
191
+ });
192
+ cache.unset(scratchOrgInfoId);
193
+ const authFields = authInfo.getFields();
194
+ await Promise.all([(0, scratchOrgLifecycleEvents_1.emit)({ stage: 'done', scratchOrgInfo: soi }), cache.write(), (0, scratchOrgLifecycleEvents_1.emitPostOrgCreate)(authFields)]);
111
195
  return {
112
196
  username,
113
- scratchOrgInfo: scratchOrgInfoResult,
197
+ scratchOrgInfo: soi,
114
198
  authInfo,
115
199
  authFields: authInfo === null || authInfo === void 0 ? void 0 : authInfo.getFields(),
116
200
  warnings,
@@ -127,19 +211,4 @@ const getSignupTargetLoginUrl = async () => {
127
211
  // a project isn't required for org:create
128
212
  }
129
213
  };
130
- const updateRevisionCounterToZero = async (scratchOrg) => {
131
- const conn = scratchOrg.getConnection();
132
- const queryResult = await conn.tooling.sobject('SourceMember').find({ RevisionCounter: { $gt: 0 } }, ['Id']);
133
- if (queryResult.length === 0) {
134
- return;
135
- }
136
- try {
137
- await conn.tooling
138
- .sobject('SourceMember')
139
- .update(queryResult.map((record) => ({ Id: record.Id, RevisionCounter: 0 })));
140
- }
141
- catch (err) {
142
- await lifecycleEvents_1.Lifecycle.getInstance().emitWarning(messages.getMessage('SourceStatusResetFailureError', [scratchOrg.getOrgId(), scratchOrg.getUsername()]));
143
- }
144
- };
145
214
  //# sourceMappingURL=scratchOrgCreate.js.map
@@ -1,4 +1,10 @@
1
1
  import { Optional } from '@salesforce/ts-types';
2
- import { Logger } from '../logger';
3
2
  import { ScratchOrgInfo } from './scratchOrgTypes';
4
- export declare const checkScratchOrgInfoForErrors: (orgInfo: Optional<ScratchOrgInfo>, hubUsername: Optional<string>, logger: Logger) => ScratchOrgInfo;
3
+ import { ScratchOrgCache } from './scratchOrgCache';
4
+ export declare const validateScratchOrgInfoForResume: ({ jobId, scratchOrgInfo, cache, hubUsername, }: {
5
+ jobId: string;
6
+ scratchOrgInfo: ScratchOrgInfo;
7
+ cache: ScratchOrgCache;
8
+ hubUsername: string;
9
+ }) => Promise<ScratchOrgInfo>;
10
+ export declare const checkScratchOrgInfoForErrors: (orgInfo: Optional<ScratchOrgInfo>, hubUsername: Optional<string>) => Promise<ScratchOrgInfo>;
@@ -6,9 +6,12 @@
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.checkScratchOrgInfoForErrors = void 0;
9
+ exports.checkScratchOrgInfoForErrors = exports.validateScratchOrgInfoForResume = void 0;
10
10
  const messages_1 = require("../messages");
11
11
  const sfError_1 = require("../sfError");
12
+ const logger_1 = require("../logger");
13
+ const scratchOrgCache_1 = require("./scratchOrgCache");
14
+ const scratchOrgLifecycleEvents_1 = require("./scratchOrgLifecycleEvents");
12
15
  const WORKSPACE_CONFIG_FILENAME = 'sfdx-project.json';
13
16
  messages_1.Messages.importMessagesDirectory(__dirname);
14
17
  const messages = messages_1.Messages.loadMessages('@salesforce/core', 'scratchOrgErrorCodes');
@@ -34,14 +37,32 @@ const optionalErrorCodeMessage = (errorCode, args) => {
34
37
  return undefined;
35
38
  }
36
39
  };
37
- const checkScratchOrgInfoForErrors = (orgInfo, hubUsername, logger) => {
38
- if (!orgInfo) {
40
+ const validateScratchOrgInfoForResume = async ({ jobId, scratchOrgInfo, cache, hubUsername, }) => {
41
+ if (!scratchOrgInfo || !scratchOrgInfo.Id || scratchOrgInfo.Status === 'Deleted') {
42
+ // 1. scratch org info does not exist in that dev hub or has been deleted
43
+ cache.unset(jobId);
44
+ await cache.write();
45
+ throw scratchOrgInfo.Status === 'Deleted'
46
+ ? messages.createError('ScratchOrgDeletedError')
47
+ : messages.createError('NoScratchOrgInfoError');
48
+ }
49
+ if (['New', 'Creating'].includes(scratchOrgInfo.Status)) {
50
+ // 2. scratchOrgInfo exists, still isn't finished. Stays in cache for future attempts
51
+ throw messages.createError('StillInProgressError', [scratchOrgInfo.Status], ['action.StillInProgress']);
52
+ }
53
+ return (0, exports.checkScratchOrgInfoForErrors)(scratchOrgInfo, hubUsername);
54
+ };
55
+ exports.validateScratchOrgInfoForResume = validateScratchOrgInfoForResume;
56
+ const checkScratchOrgInfoForErrors = async (orgInfo, hubUsername) => {
57
+ if (!orgInfo || !orgInfo.Id) {
39
58
  throw new sfError_1.SfError('No scratch org info found.', 'ScratchOrgInfoNotFound');
40
59
  }
41
60
  if (orgInfo.Status === 'Active') {
61
+ await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'available', scratchOrgInfo: orgInfo });
42
62
  return orgInfo;
43
63
  }
44
64
  if (orgInfo.Status === 'Error' && orgInfo.ErrorCode) {
65
+ await scratchOrgCache_1.ScratchOrgCache.unset(orgInfo.Id);
45
66
  const message = optionalErrorCodeMessage(orgInfo.ErrorCode, [WORKSPACE_CONFIG_FILENAME]);
46
67
  if (message) {
47
68
  throw new sfError_1.SfError(message, 'RemoteOrgSignupFailed', [
@@ -51,6 +72,8 @@ const checkScratchOrgInfoForErrors = (orgInfo, hubUsername, logger) => {
51
72
  throw new sfError_1.SfError(namedMessages.getMessage('SignupFailedError', [orgInfo.ErrorCode]));
52
73
  }
53
74
  if (orgInfo.Status === 'Error') {
75
+ await scratchOrgCache_1.ScratchOrgCache.unset(orgInfo.Id);
76
+ const logger = await logger_1.Logger.child('ScratchOrgErrorCodes');
54
77
  // Maybe the request object can help the user somehow
55
78
  logger.error('No error code on signup error! Logging request.');
56
79
  logger.error(orgInfo);
@@ -1,4 +1,3 @@
1
- import { Optional } from '@salesforce/ts-types';
2
1
  import { Duration } from '@salesforce/kit';
3
2
  import { SaveResult } from 'jsforce';
4
3
  import { AuthInfo } from './authInfo';
@@ -9,6 +8,13 @@ export interface JsForceError extends Error {
9
8
  errorCode: string;
10
9
  fields: string[];
11
10
  }
11
+ /**
12
+ *
13
+ * @param hubOrg Org
14
+ * @param id Record ID for the ScratchOrgInfoObject
15
+ * @returns Promise<ScratchOrgInfo>
16
+ */
17
+ export declare const queryScratchOrgInfo: (hubOrg: Org, id: string) => Promise<ScratchOrgInfo>;
12
18
  /**
13
19
  * after we successfully signup an org we need to trade the auth token for access and refresh token.
14
20
  *
@@ -46,12 +52,17 @@ export declare const requestScratchOrgCreation: (hubOrg: Org, scratchOrgRequest:
46
52
  */
47
53
  export declare const pollForScratchOrgInfo: (hubOrg: Org, scratchOrgInfoId: string, timeout?: Duration) => Promise<ScratchOrgInfo>;
48
54
  /**
49
- * This authenticates into the newly created org and sets org preferences
55
+ * Deploy settings to the newly created scratch org
56
+ *
57
+ * @param scratchOrg an instance of the Org class
58
+ * @param orgSettings an instance of the SettingsGenerator class
59
+ * @param apiVersion the api version (used when created the package.xml)
60
+ */
61
+ export declare const deploySettings: (scratchOrg: Org, orgSettings: SettingsGenerator, apiVersion: string) => Promise<void>;
62
+ /**
50
63
  *
51
- * @param scratchOrgAuthInfo - an object containing the AuthInfo of the ScratchOrg
52
- * @param apiVersion - the target api version
53
- * @param orgSettings - The ScratchOrg settings
54
- * @param scratchOrg - The scratchOrg Org info
55
- * @returns {Promise<Optional<AuthInfo>>}
64
+ * @param scratchOrgAuthInfo an AuthInfo class from the scratch org
65
+ * @returns AuthInfo
56
66
  */
57
- export declare const deploySettingsAndResolveUrl: (scratchOrgAuthInfo: AuthInfo, apiVersion: string, orgSettings: SettingsGenerator, scratchOrg: Org) => Promise<Optional<AuthInfo>>;
67
+ export declare const resolveUrl: (scratchOrgAuthInfo: AuthInfo) => Promise<AuthInfo>;
68
+ export declare const updateRevisionCounterToZero: (scratchOrg: Org) => Promise<void>;
@@ -6,7 +6,7 @@
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.deploySettingsAndResolveUrl = exports.pollForScratchOrgInfo = exports.requestScratchOrgCreation = exports.authorizeScratchOrg = void 0;
9
+ exports.updateRevisionCounterToZero = exports.resolveUrl = exports.deploySettings = exports.pollForScratchOrgInfo = exports.requestScratchOrgCreation = exports.authorizeScratchOrg = exports.queryScratchOrgInfo = void 0;
10
10
  const kit_1 = require("@salesforce/kit");
11
11
  const ts_types_1 = require("@salesforce/ts-types");
12
12
  const ts_retry_promise_1 = require("ts-retry-promise");
@@ -17,6 +17,7 @@ const sfError_1 = require("../sfError");
17
17
  const sfdcUrl_1 = require("../util/sfdcUrl");
18
18
  const pollingClient_1 = require("../status/pollingClient");
19
19
  const myDomainResolver_1 = require("../status/myDomainResolver");
20
+ const lifecycleEvents_1 = require("../lifecycleEvents");
20
21
  const authInfo_1 = require("./authInfo");
21
22
  const org_1 = require("./org");
22
23
  const scratchOrgErrorCodes_1 = require("./scratchOrgErrorCodes");
@@ -131,6 +132,16 @@ const getAuthInfo = async (options) => {
131
132
  });
132
133
  }
133
134
  };
135
+ /**
136
+ *
137
+ * @param hubOrg Org
138
+ * @param id Record ID for the ScratchOrgInfoObject
139
+ * @returns Promise<ScratchOrgInfo>
140
+ */
141
+ const queryScratchOrgInfo = async (hubOrg, id) => {
142
+ return (await hubOrg.getConnection().sobject('ScratchOrgInfo').retrieve(id));
143
+ };
144
+ exports.queryScratchOrgInfo = queryScratchOrgInfo;
134
145
  /**
135
146
  * after we successfully signup an org we need to trade the auth token for access and refresh token.
136
147
  *
@@ -144,7 +155,7 @@ const getAuthInfo = async (options) => {
144
155
  */
145
156
  const authorizeScratchOrg = async (options) => {
146
157
  var _a;
147
- const { scratchOrgInfoComplete, hubOrg, clientSecret, signupTargetLoginUrlConfig, retry: maxRetries } = options;
158
+ const { scratchOrgInfoComplete, hubOrg, clientSecret, signupTargetLoginUrlConfig, retry } = options;
148
159
  await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'authenticate', scratchOrgInfo: scratchOrgInfoComplete });
149
160
  const logger = await logger_1.Logger.child('authorizeScratchOrg');
150
161
  logger.debug(`scratchOrgInfoComplete: ${JSON.stringify(scratchOrgInfoComplete, null, 4)}`);
@@ -156,7 +167,7 @@ const authorizeScratchOrg = async (options) => {
156
167
  hubOrg,
157
168
  clientSecret,
158
169
  scratchOrgInfoComplete,
159
- retry: maxRetries,
170
+ retry,
160
171
  signupTargetLoginUrlConfig,
161
172
  });
162
173
  const authInfo = await getAuthInfo({
@@ -257,11 +268,10 @@ timeout = kit_1.Duration.minutes(15)) => {
257
268
  const pollingOptions = {
258
269
  async poll() {
259
270
  try {
260
- const resultInProgress = await hubOrg.getConnection().sobject('ScratchOrgInfo').retrieve(scratchOrgInfoId);
271
+ const resultInProgress = await (0, exports.queryScratchOrgInfo)(hubOrg, scratchOrgInfoId);
261
272
  logger.debug(`polling client result: ${JSON.stringify(resultInProgress, null, 4)}`);
262
273
  // Once it's "done" we can return it
263
274
  if (resultInProgress.Status === 'Active' || resultInProgress.Status === 'Error') {
264
- await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'available', scratchOrgInfo: resultInProgress });
265
275
  return {
266
276
  completed: true,
267
277
  payload: resultInProgress,
@@ -289,12 +299,17 @@ timeout = kit_1.Duration.minutes(15)) => {
289
299
  const client = await pollingClient_1.PollingClient.create(pollingOptions);
290
300
  try {
291
301
  const resultInProgress = await client.subscribe();
292
- return (0, scratchOrgErrorCodes_1.checkScratchOrgInfoForErrors)(resultInProgress, hubOrg.getUsername(), logger);
302
+ return (0, scratchOrgErrorCodes_1.checkScratchOrgInfoForErrors)(resultInProgress, hubOrg.getUsername());
293
303
  }
294
304
  catch (error) {
295
- const err = error;
296
- if (err.message) {
297
- throw sfError_1.SfError.wrap(err);
305
+ if (error instanceof Error) {
306
+ const sfError = sfError_1.SfError.wrap(error);
307
+ sfError.setData({
308
+ username: hubOrg.getUsername(),
309
+ orgId: hubOrg.getOrgId(),
310
+ scratchOrgInfoId,
311
+ });
312
+ throw sfError;
298
313
  }
299
314
  throw new sfError_1.SfError(`The scratch org did not complete within ${timeout.minutes} minutes`, 'orgCreationTimeout', [
300
315
  'Try your force:org:create command again with a longer --wait value',
@@ -303,54 +318,88 @@ timeout = kit_1.Duration.minutes(15)) => {
303
318
  };
304
319
  exports.pollForScratchOrgInfo = pollForScratchOrgInfo;
305
320
  /**
306
- * This authenticates into the newly created org and sets org preferences
321
+ * Deploy settings to the newly created scratch org
307
322
  *
308
- * @param scratchOrgAuthInfo - an object containing the AuthInfo of the ScratchOrg
309
- * @param apiVersion - the target api version
310
- * @param orgSettings - The ScratchOrg settings
311
- * @param scratchOrg - The scratchOrg Org info
312
- * @returns {Promise<Optional<AuthInfo>>}
323
+ * @param scratchOrg an instance of the Org class
324
+ * @param orgSettings an instance of the SettingsGenerator class
325
+ * @param apiVersion the api version (used when created the package.xml)
313
326
  */
314
- const deploySettingsAndResolveUrl = async (scratchOrgAuthInfo, apiVersion, orgSettings, scratchOrg) => {
315
- const logger = await logger_1.Logger.child('scratchOrgInfoApi-deploySettingsAndResolveUrl');
327
+ const deploySettings = async (scratchOrg, orgSettings, apiVersion) => {
328
+ const logger = await logger_1.Logger.child('scratchOrgInfoApi-deploySettings');
316
329
  if (orgSettings.hasSettings()) {
317
330
  // deploy the settings to the newly created scratch org
318
331
  logger.debug(`deploying scratch org settings with apiVersion ${apiVersion}`);
319
332
  try {
320
333
  await orgSettings.createDeploy();
321
334
  await orgSettings.deploySettingsViaFolder(scratchOrg, apiVersion);
335
+ // updating the revision num to zero during org:creation if source members are created during org:create.
336
+ // This only happens for some specific scratch org definition file.
337
+ await (0, exports.updateRevisionCounterToZero)(scratchOrg);
338
+ logger.trace('Settings deployed to org');
322
339
  }
323
340
  catch (error) {
324
341
  throw sfError_1.SfError.wrap(error);
325
342
  }
326
343
  }
344
+ };
345
+ exports.deploySettings = deploySettings;
346
+ /**
347
+ *
348
+ * @param scratchOrgAuthInfo an AuthInfo class from the scratch org
349
+ * @returns AuthInfo
350
+ */
351
+ const resolveUrl = async (scratchOrgAuthInfo) => {
352
+ const logger = await logger_1.Logger.child('scratchOrgInfoApi-resolveUrl');
327
353
  const { instanceUrl } = scratchOrgAuthInfo.getFields();
328
- if (instanceUrl) {
329
- logger.debug(`processScratchOrgInfoResult - resultData.instanceUrl: ${instanceUrl}`);
330
- const options = {
331
- timeout: kit_1.Duration.minutes(3),
332
- frequency: kit_1.Duration.seconds(10),
333
- url: new sfdcUrl_1.SfdcUrl(instanceUrl),
334
- };
335
- try {
336
- const resolver = await myDomainResolver_1.MyDomainResolver.create(options);
337
- await resolver.resolve();
338
- }
339
- catch (error) {
340
- const sfError = sfError_1.SfError.wrap(error);
341
- logger.debug('processScratchOrgInfoResult - err: %s', error);
342
- if (sfError.name === 'MyDomainResolverTimeoutError') {
343
- sfError.setData({
344
- orgId: scratchOrgAuthInfo.getFields().orgId,
345
- username: scratchOrgAuthInfo.getFields().username,
346
- instanceUrl,
347
- });
348
- logger.debug('processScratchOrgInfoResult - err data: %s', sfError.data);
349
- }
350
- throw sfError;
351
- }
354
+ if (!instanceUrl) {
355
+ const sfError = new sfError_1.SfError('Org does not have instanceUrl');
356
+ sfError.setData({
357
+ orgId: scratchOrgAuthInfo.getFields().orgId,
358
+ username: scratchOrgAuthInfo.getFields().username,
359
+ instanceUrl,
360
+ });
361
+ throw sfError;
362
+ }
363
+ logger.debug(`processScratchOrgInfoResult - resultData.instanceUrl: ${instanceUrl}`);
364
+ const options = {
365
+ timeout: kit_1.Duration.minutes(3),
366
+ frequency: kit_1.Duration.seconds(10),
367
+ url: new sfdcUrl_1.SfdcUrl(instanceUrl),
368
+ };
369
+ try {
370
+ const resolver = await myDomainResolver_1.MyDomainResolver.create(options);
371
+ await resolver.resolve();
352
372
  return scratchOrgAuthInfo;
353
373
  }
374
+ catch (error) {
375
+ const sfError = sfError_1.SfError.wrap(error);
376
+ logger.debug('processScratchOrgInfoResult - err: %s', error);
377
+ if (sfError.name === 'MyDomainResolverTimeoutError') {
378
+ sfError.setData({
379
+ orgId: scratchOrgAuthInfo.getFields().orgId,
380
+ username: scratchOrgAuthInfo.getFields().username,
381
+ instanceUrl,
382
+ });
383
+ logger.debug('processScratchOrgInfoResult - err data: %s', sfError.data);
384
+ }
385
+ throw sfError;
386
+ }
387
+ };
388
+ exports.resolveUrl = resolveUrl;
389
+ const updateRevisionCounterToZero = async (scratchOrg) => {
390
+ const conn = scratchOrg.getConnection();
391
+ const queryResult = await conn.tooling.sobject('SourceMember').find({ RevisionCounter: { $gt: 0 } }, ['Id']);
392
+ if (queryResult.length === 0) {
393
+ return;
394
+ }
395
+ try {
396
+ await conn.tooling
397
+ .sobject('SourceMember')
398
+ .update(queryResult.map((record) => ({ Id: record.Id, RevisionCounter: 0 })));
399
+ }
400
+ catch (err) {
401
+ await lifecycleEvents_1.Lifecycle.getInstance().emitWarning(messages.getMessage('SourceStatusResetFailureError', [scratchOrg.getOrgId(), scratchOrg.getUsername()]));
402
+ }
354
403
  };
355
- exports.deploySettingsAndResolveUrl = deploySettingsAndResolveUrl;
404
+ exports.updateRevisionCounterToZero = updateRevisionCounterToZero;
356
405
  //# sourceMappingURL=scratchOrgInfoApi.js.map
@@ -1,3 +1,4 @@
1
+ import { AuthFields } from './authInfo';
1
2
  import { ScratchOrgInfo } from './scratchOrgTypes';
2
3
  export declare const scratchOrgLifecycleEventName = "scratchOrgLifecycleEvent";
3
4
  export declare const scratchOrgLifecycleStages: readonly ["prepare request", "send request", "wait for org", "available", "authenticate", "deploy settings", "done"];
@@ -6,3 +7,4 @@ export interface ScratchOrgLifecycleEvent {
6
7
  scratchOrgInfo?: ScratchOrgInfo;
7
8
  }
8
9
  export declare const emit: (event: ScratchOrgLifecycleEvent) => Promise<void>;
10
+ export declare const emitPostOrgCreate: (authFields: AuthFields) => Promise<void>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.emit = exports.scratchOrgLifecycleStages = exports.scratchOrgLifecycleEventName = void 0;
3
+ exports.emitPostOrgCreate = exports.emit = exports.scratchOrgLifecycleStages = exports.scratchOrgLifecycleEventName = void 0;
4
4
  /*
5
5
  * Copyright (c) 2020, salesforce.com, inc.
6
6
  * All rights reserved.
@@ -23,4 +23,23 @@ const emit = async (event) => {
23
23
  emitter.emit(exports.scratchOrgLifecycleEventName, event);
24
24
  };
25
25
  exports.emit = emit;
26
+ const postOrgCreateHookFields = [
27
+ 'accessToken',
28
+ 'clientId',
29
+ 'created',
30
+ 'createdOrgInstance',
31
+ 'devHubUsername',
32
+ 'expirationDate',
33
+ 'instanceUrl',
34
+ 'loginUrl',
35
+ 'orgId',
36
+ 'username',
37
+ ];
38
+ const isHookField = (key) => {
39
+ return postOrgCreateHookFields.includes(key);
40
+ };
41
+ const emitPostOrgCreate = async (authFields) => {
42
+ emitter.emit('postorgcreate', Object.fromEntries(Object.entries(authFields).filter(([key]) => isHookField(key))));
43
+ };
44
+ exports.emitPostOrgCreate = emitPostOrgCreate;
26
45
  //# sourceMappingURL=scratchOrgLifecycleEvents.js.map