Skip to content

Commit cba673b

Browse files
committed
feat: lifecycle events for scratch org create
1 parent 38114a3 commit cba673b

11 files changed

+94
-54
lines changed

src/exported.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ export { PermissionSetAssignment, PermissionSetAssignmentFields } from './org/pe
104104

105105
export { ScratchOrgCreateOptions, ScratchOrgCreateResult, scratchOrgCreate } from './org/scratchOrgCreate';
106106

107-
export { ScratchOrgInfo } from './org/scratchOrgInfoApi';
107+
export { ScratchOrgInfo } from './org/scratchOrgTypes';
108+
export { ScratchOrgLifecycleEvent, scratchOrgLifecycleEventName } from './org/scratchOrgLifeCycleEvents';
108109

109110
// Utility sub-modules
110111
export * from './util/sfdc';

src/org/scratchOrgCreate.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@ import {
1717
requestScratchOrgCreation,
1818
pollForScratchOrgInfo,
1919
deploySettingsAndResolveUrl,
20-
ScratchOrgInfo,
2120
} from './scratchOrgInfoApi';
21+
import { ScratchOrgInfo } from './scratchOrgTypes';
2222
import SettingsGenerator from './scratchOrgSettingsGenerator';
2323
import { generateScratchOrgInfo, getScratchOrgInfoPayload } from './scratchOrgInfoGenerator';
2424
import { AuthFields, AuthInfo } from './authInfo';
2525
import { Connection } from './connection';
26+
import { emit } from './scratchOrgLifecycleEvents';
2627

2728
Messages.importMessagesDirectory(__dirname);
2829
const messages = Messages.load('@salesforce/core', 'scratchOrgCreate', [
@@ -106,8 +107,9 @@ const validateWait = (wait: Duration): void => {
106107

107108
export const scratchOrgCreate = async (options: ScratchOrgCreateOptions): Promise<ScratchOrgCreateResult> => {
108109
const logger = await Logger.child('scratchOrgCreate');
109-
logger.debug('scratchOrgCreate');
110110

111+
logger.debug('scratchOrgCreate');
112+
await emit({ stage: 'building request' });
111113
const {
112114
hubOrg,
113115
connectedAppConsumerKey,
@@ -151,7 +153,6 @@ export const scratchOrgCreate = async (options: ScratchOrgCreateOptions): Promis
151153

152154
// creates the scratch org info in the devhub
153155
const scratchOrgInfoRequestResult = await requestScratchOrgCreation(hubOrg, scratchOrgInfo, settingsGenerator);
154-
155156
const scratchOrgInfoId = ensureString(getString(scratchOrgInfoRequestResult, 'id'));
156157

157158
logger.debug(`scratch org has recordId ${scratchOrgInfoId}`);
@@ -177,6 +178,8 @@ export const scratchOrgCreate = async (options: ScratchOrgCreateOptions): Promis
177178
logger.debug(`scratch org username ${username}`);
178179

179180
const configAggregator = new ConfigAggregator();
181+
await emit({ stage: 'deploying', scratchOrgInfo: scratchOrgInfoResult });
182+
180183
const authInfo = await deploySettingsAndResolveUrl(
181184
scratchOrgAuthInfo,
182185
apiversion ??

src/org/scratchOrgErrorCodes.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Optional } from '@salesforce/ts-types';
99
import { Messages } from '../messages';
1010
import { SfError } from '../sfError';
1111
import { Logger } from '../logger';
12-
import { ScratchOrgInfo } from './scratchOrgInfoApi';
12+
import { ScratchOrgInfo } from './scratchOrgTypes';
1313

1414
const WORKSPACE_CONFIG_FILENAME = 'sfdx-project.json';
1515

src/org/scratchOrgInfoApi.ts

+9-39
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,9 @@ import { MyDomainResolver } from '../status/myDomainResolver';
2222
import { AuthInfo } from './authInfo';
2323
import { Org } from './org';
2424
import { checkScratchOrgInfoForErrors } from './scratchOrgErrorCodes';
25-
import SettingsGenerator, { ObjectSetting } from './scratchOrgSettingsGenerator';
26-
export interface ScratchOrgInfo {
27-
AdminEmail?: string;
28-
readonly CreatedDate?: string;
29-
ConnectedAppCallbackUrl?: string;
30-
ConnectedAppConsumerKey?: string;
31-
Country?: string;
32-
Description?: string;
33-
DurationDays?: string;
34-
Edition?: string;
35-
readonly ErrorCode?: string;
36-
readonly ExpirationDate?: string;
37-
Features?: string;
38-
HasSampleData?: boolean;
39-
readonly Id?: string;
40-
Language?: string;
41-
LoginUrl: string;
42-
readonly Name?: string;
43-
Namespace?: string;
44-
OrgName?: string;
45-
Release?: 'Current' | 'Previous' | 'Preview';
46-
readonly ScratchOrg?: string;
47-
SourceOrg?: string;
48-
readonly AuthCode: string;
49-
Snapshot: string;
50-
readonly Status: 'New' | 'Creating' | 'Active' | 'Error' | 'Deleted';
51-
readonly SignupEmail: string;
52-
readonly SignupUsername: string;
53-
readonly SignupInstance: string;
54-
Username: string;
55-
settings?: Record<string, unknown>;
56-
objectSettings?: { [objectName: string]: ObjectSetting };
57-
orgPreferences?: {
58-
enabled: string[];
59-
disabled: string[];
60-
};
61-
}
62-
25+
import SettingsGenerator from './scratchOrgSettingsGenerator';
26+
import { ScratchOrgInfo } from './scratchOrgTypes';
27+
import { emit } from './scratchOrgLifecycleEvents';
6328
export interface JsForceError extends Error {
6429
errorCode: string;
6530
fields: string[];
@@ -225,6 +190,7 @@ export const authorizeScratchOrg = async (options: {
225190
retry?: number;
226191
}): Promise<AuthInfo> => {
227192
const { scratchOrgInfoComplete, hubOrg, clientSecret, signupTargetLoginUrlConfig, retry: maxRetries } = options;
193+
await emit({ stage: 'authing', scratchOrgInfo: scratchOrgInfoComplete });
228194
const logger = await Logger.child('authorizeScratchOrg');
229195
logger.debug(`scratchOrgInfoComplete: ${JSON.stringify(scratchOrgInfoComplete, null, 4)}`);
230196

@@ -321,7 +287,8 @@ export const requestScratchOrgCreation = async (
321287

322288
await checkOrgDoesntExist(scratchOrgInfo); // throw if it does exist.
323289
try {
324-
return await hubOrg.getConnection().sobject('ScratchOrgInfo').create(scratchOrgInfo);
290+
await emit({ stage: 'requested' });
291+
return hubOrg.getConnection().sobject('ScratchOrgInfo').create(scratchOrgInfo);
325292
} catch (error) {
326293
// this is a jsforce error which contains the property "fields" which regular error don't
327294
const jsForceError = error as JsForceError;
@@ -356,11 +323,14 @@ export const pollForScratchOrgInfo = async (
356323
logger.debug(`polling client result: ${JSON.stringify(resultInProgress, null, 4)}`);
357324
// Once it's "done" we can return it
358325
if (resultInProgress.Status === 'Active' || resultInProgress.Status === 'Error') {
326+
await emit({ stage: 'ready', scratchOrgInfo: resultInProgress as unknown as ScratchOrgInfo });
359327
return {
360328
completed: true,
361329
payload: resultInProgress as unknown as AnyJson,
362330
};
363331
}
332+
await emit({ stage: 'pending', scratchOrgInfo: resultInProgress as unknown as ScratchOrgInfo });
333+
364334
logger.debug(`Scratch org status is ${resultInProgress.Status}`);
365335
return {
366336
completed: false,

src/org/scratchOrgInfoGenerator.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { WebOAuthServer } from '../webOAuthServer';
1313
import { Messages } from '../messages';
1414
import { SfError } from '../sfError';
1515
import { Org } from './org';
16-
import { ScratchOrgInfo } from './scratchOrgInfoApi';
16+
import { ScratchOrgInfo } from './scratchOrgTypes';
1717
import { ScratchOrgFeatureDeprecation } from './scratchOrgFeatureDeprecation';
1818

1919
const defaultConnectedAppInfo = {

src/org/scratchOrgLifecycleEvents.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2020, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
import { Lifecycle } from '../lifecycleEvents';
8+
import { ScratchOrgInfo } from './scratchOrgTypes';
9+
10+
const emitter = Lifecycle.getInstance();
11+
12+
export const scratchOrgLifecycleEventName = 'scratchOrgLifecycleEvent';
13+
14+
export interface ScratchOrgLifecycleEvent {
15+
stage: 'building request' | 'requested' | 'pending' | 'ready' | 'authing' | 'deploying';
16+
scratchOrgInfo?: ScratchOrgInfo;
17+
}
18+
19+
export const emit = async (event: ScratchOrgLifecycleEvent) => {
20+
emitter.emit(scratchOrgLifecycleEventName, event);
21+
};

src/org/scratchOrgSettingsGenerator.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { JsonAsXml } from '../util/jsonXmlTools';
1515
import { ZipWriter } from '../util/zipWriter';
1616
import { StatusResult } from '../status/types';
1717
import { PollingClient } from '../status/pollingClient';
18-
import { ScratchOrgInfo } from './scratchOrgInfoApi';
18+
import { ScratchOrgInfo, ObjectSetting } from './scratchOrgTypes';
1919
import { Org } from './org';
2020

2121
export enum RequestStatus {
@@ -30,11 +30,6 @@ export enum RequestStatus {
3030

3131
const breakPolling = ['Succeeded', 'SucceededPartial', 'Failed', 'Canceled'];
3232

33-
export interface ObjectSetting extends JsonMap {
34-
sharingModel?: string;
35-
defaultRecordType?: string;
36-
}
37-
3833
interface ObjectToBusinessProcessPicklist {
3934
[key: string]: {
4035
fullName: string;

src/org/scratchOrgTypes.ts

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2020, salesforce.com, inc.
3+
* All rights reserved.
4+
* Licensed under the BSD 3-Clause license.
5+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import { JsonMap } from '@salesforce/ts-types';
9+
10+
export interface ScratchOrgInfo {
11+
AdminEmail?: string;
12+
readonly CreatedDate?: string;
13+
ConnectedAppCallbackUrl?: string;
14+
ConnectedAppConsumerKey?: string;
15+
Country?: string;
16+
Description?: string;
17+
DurationDays?: string;
18+
Edition?: string;
19+
readonly ErrorCode?: string;
20+
readonly ExpirationDate?: string;
21+
Features?: string;
22+
HasSampleData?: boolean;
23+
readonly Id?: string;
24+
Language?: string;
25+
LoginUrl: string;
26+
readonly Name?: string;
27+
Namespace?: string;
28+
OrgName?: string;
29+
Release?: 'Current' | 'Previous' | 'Preview';
30+
readonly ScratchOrg?: string;
31+
SourceOrg?: string;
32+
readonly AuthCode: string;
33+
Snapshot: string;
34+
readonly Status: 'New' | 'Creating' | 'Active' | 'Error' | 'Deleted';
35+
readonly SignupEmail: string;
36+
readonly SignupUsername: string;
37+
readonly SignupInstance: string;
38+
Username: string;
39+
settings?: Record<string, unknown>;
40+
objectSettings?: { [objectName: string]: ObjectSetting };
41+
orgPreferences?: {
42+
enabled: string[];
43+
disabled: string[];
44+
};
45+
}
46+
47+
export interface ObjectSetting extends JsonMap {
48+
sharingModel?: string;
49+
defaultRecordType?: string;
50+
}

test/unit/org/scratchOrgErrorCodesTest.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { expect } from 'chai';
88
import { assert } from 'sinon';
99
import { Logger } from '../../../src/logger';
1010
import { SfError } from '../../../src/sfError';
11-
import { ScratchOrgInfo } from '../../../src/org/scratchOrgInfoApi';
11+
import { ScratchOrgInfo } from '../../../src/org/scratchOrgTypes';
1212
import { checkScratchOrgInfoForErrors } from '../../../src/org/scratchOrgErrorCodes';
1313

1414
const testUsername = 'foo';

test/unit/org/scratchOrgInfoApiTest.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ import { MyDomainResolver } from '../../../src/status/myDomainResolver';
1717
import SettingsGenerator from '../../../src/org/scratchOrgSettingsGenerator';
1818
import {
1919
requestScratchOrgCreation,
20-
ScratchOrgInfo,
2120
JsForceError,
2221
deploySettingsAndResolveUrl,
2322
pollForScratchOrgInfo,
2423
authorizeScratchOrg,
2524
} from '../../../src/org/scratchOrgInfoApi';
25+
import { ScratchOrgInfo } from '../../../src/org/scratchOrgTypes';
2626
import { Messages } from '../../../src/messages';
2727

2828
Messages.importMessagesDirectory(__dirname);

test/unit/org/scratchOrgSettingsGeneratorTest.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { assert, expect } from 'chai';
1111
import { Org, Connection } from '../../../src/org';
1212
import { sfdc } from '../../../src/util/sfdc';
1313
import { ZipWriter } from '../../../src/util/zipWriter';
14-
import { ScratchOrgInfo } from '../../../src/org/scratchOrgInfoApi';
14+
import { ScratchOrgInfo } from '../../../src/org/scratchOrgTypes';
1515
import SettingsGenerator from '../../../src/org/scratchOrgSettingsGenerator';
1616
import { MockTestOrgData } from '../../../src/testSetup';
1717

0 commit comments

Comments
 (0)