@salesforce/core 3.7.3 → 3.7.6

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.
Files changed (70) hide show
  1. package/CHANGELOG.md +223 -0
  2. package/LICENSE.txt +1 -1
  3. package/lib/config/config.js +15 -15
  4. package/lib/config/configAggregator.js +4 -4
  5. package/lib/config/configFile.js +9 -9
  6. package/lib/config/configStore.js +14 -13
  7. package/lib/config/envVars.d.ts +20 -5
  8. package/lib/config/envVars.js +75 -10
  9. package/lib/config/keychainConfig.js +1 -1
  10. package/lib/crypto/crypto.js +6 -6
  11. package/lib/crypto/keyChainImpl.js +6 -6
  12. package/lib/crypto/secureBuffer.js +1 -1
  13. package/lib/deviceOauthService.js +5 -4
  14. package/lib/exported.d.ts +4 -2
  15. package/lib/exported.js +5 -1
  16. package/lib/globalInfo/globalInfoConfig.js +1 -1
  17. package/lib/globalInfo/sfdxDataHandler.js +11 -11
  18. package/lib/lifecycleEvents.js +2 -2
  19. package/lib/logger.js +12 -13
  20. package/lib/messages.js +10 -9
  21. package/lib/org/authInfo.js +45 -43
  22. package/lib/org/connection.d.ts +6 -1
  23. package/lib/org/connection.js +22 -8
  24. package/lib/org/org.d.ts +12 -2
  25. package/lib/org/org.js +62 -56
  26. package/lib/org/orgConfigProperties.js +1 -1
  27. package/lib/org/permissionSetAssignment.js +3 -3
  28. package/lib/org/scratchOrgCreate.d.ts +43 -0
  29. package/lib/org/scratchOrgCreate.js +142 -0
  30. package/lib/org/scratchOrgErrorCodes.d.ts +4 -0
  31. package/lib/org/scratchOrgErrorCodes.js +62 -0
  32. package/lib/org/scratchOrgFeatureDeprecation.d.ts +26 -0
  33. package/lib/org/scratchOrgFeatureDeprecation.js +110 -0
  34. package/lib/org/scratchOrgInfoApi.d.ts +94 -0
  35. package/lib/org/scratchOrgInfoApi.js +350 -0
  36. package/lib/org/scratchOrgInfoGenerator.d.ts +63 -0
  37. package/lib/org/scratchOrgInfoGenerator.js +223 -0
  38. package/lib/org/scratchOrgSettingsGenerator.d.ts +56 -0
  39. package/lib/org/scratchOrgSettingsGenerator.js +210 -0
  40. package/lib/org/user.js +24 -23
  41. package/lib/schema/printer.js +18 -18
  42. package/lib/schema/validator.js +8 -8
  43. package/lib/sfdxError.js +2 -2
  44. package/lib/sfdxProject.js +15 -13
  45. package/lib/status/myDomainResolver.js +3 -3
  46. package/lib/status/pollingClient.d.ts +2 -2
  47. package/lib/status/pollingClient.js +10 -4
  48. package/lib/status/streamingClient.d.ts +1 -1
  49. package/lib/status/streamingClient.js +6 -6
  50. package/lib/testSetup.js +21 -21
  51. package/lib/util/cache.js +3 -3
  52. package/lib/util/fs.js +12 -12
  53. package/lib/util/jsonXmlTools.d.ts +14 -0
  54. package/lib/util/jsonXmlTools.js +41 -0
  55. package/lib/util/mapKeys.d.ts +14 -0
  56. package/lib/util/mapKeys.js +48 -0
  57. package/lib/util/sfdc.js +3 -3
  58. package/lib/util/sfdcUrl.js +3 -3
  59. package/lib/util/zipWriter.d.ts +14 -0
  60. package/lib/util/zipWriter.js +68 -0
  61. package/lib/webOAuthServer.js +8 -8
  62. package/messages/envVars.md +53 -13
  63. package/messages/org.md +4 -0
  64. package/messages/scratchOrgCreate.md +27 -0
  65. package/messages/scratchOrgErrorCodes.md +99 -0
  66. package/messages/scratchOrgFeatureDeprecation.md +11 -0
  67. package/messages/scratchOrgInfoApi.md +11 -0
  68. package/messages/scratchOrgInfoGenerator.md +19 -0
  69. package/messages/user.md +4 -0
  70. package/package.json +33 -30
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getScratchOrgInfoPayload = exports.generateScratchOrgInfo = exports.getAncestorIds = void 0;
4
+ /*
5
+ * Copyright (c) 2021, 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 fs_1 = require("fs");
11
+ const kit_1 = require("@salesforce/kit");
12
+ const ts_types_1 = require("@salesforce/ts-types");
13
+ const sfdc_1 = require("../util/sfdc");
14
+ const sfdxProject_1 = require("../sfdxProject");
15
+ const webOAuthServer_1 = require("../webOAuthServer");
16
+ const messages_1 = require("../messages");
17
+ const sfdxError_1 = require("../sfdxError");
18
+ const scratchOrgFeatureDeprecation_1 = require("./scratchOrgFeatureDeprecation");
19
+ const defaultConnectedAppInfo = {
20
+ clientId: 'PlatformCLI',
21
+ legacyClientId: 'SalesforceDevelopmentExperience',
22
+ legacyClientSecret: '1384510088588713504',
23
+ };
24
+ messages_1.Messages.importMessagesDirectory(__dirname);
25
+ const messages = messages_1.Messages.loadMessages('@salesforce/core', 'scratchOrgInfoGenerator');
26
+ const SNAPSHOT_UNSUPPORTED_OPTIONS = [
27
+ 'features',
28
+ 'orgPreferences',
29
+ 'edition',
30
+ 'sourceOrg',
31
+ 'settingsPath',
32
+ 'releaseVersion',
33
+ 'language',
34
+ ];
35
+ // A validator function to ensure any options parameters entered by the user adhere
36
+ // to a allowlist of valid option settings. Because org:create allows options to be
37
+ // input either key=value pairs or within the definition file, this validator is
38
+ // executed within the ctor and also after parsing/normalization of the definition file.
39
+ const optionsValidator = (key, scratchOrgInfoPayload) => {
40
+ if (key.toLowerCase() === 'durationdays') {
41
+ throw new sfdxError_1.SfdxError('unrecognizedScratchOrgOption', 'durationDays');
42
+ }
43
+ if (key.toLowerCase() === 'snapshot') {
44
+ const foundInvalidFields = SNAPSHOT_UNSUPPORTED_OPTIONS.filter((invalidField) => invalidField in scratchOrgInfoPayload);
45
+ if (foundInvalidFields.length > 0) {
46
+ throw new sfdxError_1.SfdxError(messages.getMessage('unsupportedSnapshotOrgCreateOptions', [foundInvalidFields.join(', ')]), 'orgSnapshot');
47
+ }
48
+ }
49
+ };
50
+ /**
51
+ * Generates the package2AncestorIds scratch org property
52
+ *
53
+ * @param scratchOrgInfo - the scratchOrgInfo passed in by the user
54
+ * @param projectJson - sfdxProjectJson
55
+ * @param hubOrg - the hub org, in case we need to do queries
56
+ */
57
+ const getAncestorIds = async (scratchOrgInfo, projectJson, hubOrg) => {
58
+ if (Reflect.has(scratchOrgInfo, 'package2AncestorIds')) {
59
+ throw new sfdxError_1.SfdxError(messages.getMessage('Package2AncestorsIdsKeyNotSupportedError'), 'DeprecationError');
60
+ }
61
+ const packagesWithAncestors = (await projectJson.getPackageDirectories())
62
+ // check that the package has any ancestor types (id or version)
63
+ .filter((packageDir) => packageDir.ancestorId || packageDir.ancestorVersion);
64
+ if (packagesWithAncestors.length === 0) {
65
+ return '';
66
+ }
67
+ const ancestorIds = await Promise.all(packagesWithAncestors.map(async (packageDir) => {
68
+ var _a, _b, _c;
69
+ // ancestorID can be 05i, or 04t, alias; OR "ancestorVersion": "4.6.0.1"
70
+ // according to docs, 05i is not ok: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev2gp_config_file.htm
71
+ if (packageDir.ancestorVersion) {
72
+ if (!/^[0-9]+.[0-9]+.[0-9]+(.[0-9]+)?$/.test(packageDir.ancestorVersion)) {
73
+ throw messages.createError('InvalidAncestorVersionFormatError', [packageDir.ancestorVersion]);
74
+ }
75
+ // package can be an ID, but not according to docs
76
+ const packageAliases = projectJson.get('packageAliases');
77
+ const packageId = (_a = packageAliases[(0, ts_types_1.ensureString)(packageDir.package)]) !== null && _a !== void 0 ? _a : packageDir.package;
78
+ const [major, minor, patch] = packageDir.ancestorVersion.split('.');
79
+ let releasedAncestor;
80
+ try {
81
+ releasedAncestor = await hubOrg
82
+ .getConnection()
83
+ .singleRecordQuery(`SELECT Id, IsReleased FROM Package2Version WHERE Package2Id = '${packageId}' AND MajorVersion = ${major} AND MinorVersion = ${minor} AND PatchVersion = ${patch} and IsReleased = true`, { tooling: true });
84
+ }
85
+ catch (err) {
86
+ throw new sfdxError_1.SfdxError(messages.getMessage('NoMatchingAncestorError', [packageDir.ancestorVersion, packageDir.package]), 'NoMatchingAncestorError', [messages.getMessage('AncestorNotReleasedError', [packageDir.ancestorVersion])]);
87
+ }
88
+ if (packageDir.ancestorId && packageDir.ancestorId !== releasedAncestor.Id) {
89
+ throw messages.createError('AncestorIdVersionMismatchError', [
90
+ packageDir.ancestorVersion,
91
+ packageDir.ancestorId,
92
+ ]);
93
+ }
94
+ return releasedAncestor.Id;
95
+ }
96
+ if ((_b = packageDir === null || packageDir === void 0 ? void 0 : packageDir.ancestorId) === null || _b === void 0 ? void 0 : _b.startsWith('05i')) {
97
+ // if it's already a 05i return it, otherwise query for it
98
+ return packageDir.ancestorId;
99
+ }
100
+ if ((_c = packageDir === null || packageDir === void 0 ? void 0 : packageDir.ancestorId) === null || _c === void 0 ? void 0 : _c.startsWith('04t')) {
101
+ // query for the Id
102
+ return (await hubOrg
103
+ .getConnection()
104
+ .singleRecordQuery(`SELECT Id FROM Package2Version WHERE SubscriberPackageVersionId = '${packageDir.ancestorId}'`, { tooling: true })).Id;
105
+ }
106
+ // ancestorID can be an alias get it from projectJson
107
+ const packageAliases = projectJson.get('packageAliases');
108
+ if (packageDir.ancestorId && (packageAliases === null || packageAliases === void 0 ? void 0 : packageAliases[packageDir.ancestorId])) {
109
+ return packageAliases[packageDir.ancestorId];
110
+ }
111
+ throw new sfdxError_1.SfdxError(`Invalid ancestorId ${packageDir.ancestorId}`, 'InvalidAncestorId');
112
+ }));
113
+ return Array.from(new Set(ancestorIds)).join(';');
114
+ };
115
+ exports.getAncestorIds = getAncestorIds;
116
+ /**
117
+ * Takes in a scratchOrgInfo and fills in the missing fields
118
+ *
119
+ * @param hubOrg the environment hub org
120
+ * @param scratchOrgInfoPayload - the scratchOrgInfo passed in by the user
121
+ * @param nonamespace create the scratch org with no namespace
122
+ * @param ignoreAncestorIds true if the sfdx-project.json ancestorId keys should be ignored
123
+ */
124
+ const generateScratchOrgInfo = async ({ hubOrg, scratchOrgInfoPayload, nonamespace, ignoreAncestorIds, }) => {
125
+ var _a, _b;
126
+ let sfdxProject;
127
+ try {
128
+ sfdxProject = await sfdxProject_1.SfdxProjectJson.create({});
129
+ }
130
+ catch (e) {
131
+ // project is not required
132
+ }
133
+ scratchOrgInfoPayload.orgName = (_a = scratchOrgInfoPayload.orgName) !== null && _a !== void 0 ? _a : 'Company';
134
+ scratchOrgInfoPayload.package2AncestorIds =
135
+ !ignoreAncestorIds && (sfdxProject === null || sfdxProject === void 0 ? void 0 : sfdxProject.hasPackages())
136
+ ? await (0, exports.getAncestorIds)(scratchOrgInfoPayload, sfdxProject, hubOrg)
137
+ : '';
138
+ // Use the Hub org's client ID value, if one wasn't provided to us, or the default
139
+ if (!scratchOrgInfoPayload.connectedAppConsumerKey) {
140
+ scratchOrgInfoPayload.connectedAppConsumerKey =
141
+ (_b = hubOrg.getConnection().getAuthInfoFields().clientId) !== null && _b !== void 0 ? _b : defaultConnectedAppInfo.clientId;
142
+ }
143
+ if (!nonamespace && (sfdxProject === null || sfdxProject === void 0 ? void 0 : sfdxProject.get('namespace'))) {
144
+ scratchOrgInfoPayload.namespace = sfdxProject.get('namespace');
145
+ }
146
+ // we already have the info, and want to get rid of configApi, so this doesn't use that
147
+ scratchOrgInfoPayload.connectedAppCallbackUrl = `http://localhost:${await webOAuthServer_1.WebOAuthServer.determineOauthPort()}/OauthRedirect`;
148
+ return scratchOrgInfoPayload;
149
+ };
150
+ exports.generateScratchOrgInfo = generateScratchOrgInfo;
151
+ /**
152
+ * Returns a valid signup json
153
+ *
154
+ * definitionjson org definition in JSON format
155
+ * definitionfile path to an org definition file
156
+ * connectedAppConsumerKey The connected app consumer key. May be null for JWT OAuth flow.
157
+ * durationdays duration of the scratch org (in days) (default:1, min:1, max:30)
158
+ * nonamespace create the scratch org with no namespace
159
+ * noancestors do not include second-generation package ancestors in the scratch org
160
+ * orgConfig overrides definitionjson
161
+ *
162
+ * @returns scratchOrgInfoPayload: ScratchOrgInfoPayload;
163
+ ignoreAncestorIds: boolean;
164
+ warnings: string[];
165
+ */
166
+ const getScratchOrgInfoPayload = async (options) => {
167
+ var _a;
168
+ let warnings = [];
169
+ // orgConfig input overrides definitionjson (-j option; hidden/deprecated)
170
+ const definitionJson = options.definitionjson ? JSON.parse(options.definitionjson) : {};
171
+ const orgConfigInput = { ...definitionJson, ...((_a = options.orgConfig) !== null && _a !== void 0 ? _a : {}) };
172
+ let scratchOrgInfoPayload = orgConfigInput;
173
+ // the -f option
174
+ if (options.definitionfile) {
175
+ try {
176
+ const fileData = await fs_1.promises.readFile(options.definitionfile, 'utf8');
177
+ const defFileContents = (0, kit_1.parseJson)(fileData);
178
+ // definitionjson and orgConfig override file input
179
+ scratchOrgInfoPayload = { ...defFileContents, ...orgConfigInput };
180
+ }
181
+ catch (err) {
182
+ const error = err;
183
+ if (error.name === 'JsonParseError') {
184
+ throw new sfdxError_1.SfdxError(`An error occurred parsing ${options.definitionfile}`);
185
+ }
186
+ throw sfdxError_1.SfdxError.wrap(error);
187
+ }
188
+ }
189
+ // scratchOrgInfoPayload must be heads down camelcase.
190
+ const upperCaseKey = sfdc_1.sfdc.findUpperCaseKeys(scratchOrgInfoPayload);
191
+ if (upperCaseKey) {
192
+ throw new sfdxError_1.SfdxError('InvalidJsonCasing', upperCaseKey);
193
+ }
194
+ // Now run the fully resolved user input against the validator
195
+ Object.keys(scratchOrgInfoPayload).forEach((key) => {
196
+ optionsValidator(key, scratchOrgInfoPayload);
197
+ });
198
+ if (options.connectedAppConsumerKey) {
199
+ scratchOrgInfoPayload.connectedAppConsumerKey = options.connectedAppConsumerKey;
200
+ }
201
+ scratchOrgInfoPayload.durationDays = options.durationDays;
202
+ // Throw warnings for deprecated scratch org features.
203
+ const scratchOrgFeatureDeprecation = new scratchOrgFeatureDeprecation_1.ScratchOrgFeatureDeprecation();
204
+ // convert various supported array and string formats to a semi-colon-delimited string
205
+ if (scratchOrgInfoPayload.features) {
206
+ if (typeof scratchOrgInfoPayload.features === 'string') {
207
+ scratchOrgInfoPayload.features = scratchOrgInfoPayload.features.split(/[;,]/);
208
+ }
209
+ warnings = scratchOrgFeatureDeprecation.getFeatureWarnings(scratchOrgInfoPayload.features);
210
+ scratchOrgInfoPayload.features = scratchOrgInfoPayload.features.map((feature) => feature.trim());
211
+ scratchOrgInfoPayload.features = scratchOrgFeatureDeprecation
212
+ .filterDeprecatedFeatures(scratchOrgInfoPayload.features)
213
+ .join(';');
214
+ }
215
+ return {
216
+ scratchOrgInfoPayload,
217
+ // Ignore ancestor ids only when 'nonamespace' or 'noancestors' options are specified
218
+ ignoreAncestorIds: options.nonamespace || options.noancestors || false,
219
+ warnings,
220
+ };
221
+ };
222
+ exports.getScratchOrgInfoPayload = getScratchOrgInfoPayload;
223
+ //# sourceMappingURL=scratchOrgInfoGenerator.js.map
@@ -0,0 +1,56 @@
1
+ import { JsonMap } from '@salesforce/ts-types';
2
+ import { ScratchOrgInfo } from './scratchOrgInfoApi';
3
+ import { Org } from './org';
4
+ export declare enum RequestStatus {
5
+ Pending = "Pending",
6
+ InProgress = "InProgress",
7
+ Succeeded = "Succeeded",
8
+ SucceededPartial = "SucceededPartial",
9
+ Failed = "Failed",
10
+ Canceling = "Canceling",
11
+ Canceled = "Canceled"
12
+ }
13
+ export interface ObjectSetting extends JsonMap {
14
+ sharingModel?: string;
15
+ defaultRecordType?: string;
16
+ }
17
+ export interface BusinessProcessFileContent extends JsonMap {
18
+ fullName: string;
19
+ isActive: boolean;
20
+ values: [
21
+ {
22
+ fullName: string;
23
+ default?: boolean;
24
+ }
25
+ ];
26
+ }
27
+ /**
28
+ * Helper class for dealing with the settings that are defined in a scratch definition file. This class knows how to extract the
29
+ * settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
30
+ */
31
+ export default class SettingsGenerator {
32
+ private settingData?;
33
+ private objectSettingsData?;
34
+ private logger;
35
+ private writer;
36
+ private shapeDirName;
37
+ constructor();
38
+ /** extract the settings from the scratch def file, if they are present. */
39
+ extract(scratchDef: ScratchOrgInfo): Promise<void>;
40
+ /** True if we are currently tracking setting or object setting data. */
41
+ hasSettings(): boolean;
42
+ /** Create temporary deploy directory used to upload the scratch org shape.
43
+ * This will create the dir, all of the .setting files and minimal object files needed for objectSettings
44
+ */
45
+ createDeploy(): Promise<void>;
46
+ /**
47
+ * Deploys the settings to the org.
48
+ */
49
+ deploySettingsViaFolder(scratchOrg: Org, apiVersion: string): Promise<void>;
50
+ private writeObjectSettingsIfNeeded;
51
+ private writeSettingsIfNeeded;
52
+ private createPackageXml;
53
+ private createObjectFileContent;
54
+ private createRecordTypeFileContent;
55
+ private createBusinessProcessFileContent;
56
+ }
@@ -0,0 +1,210 @@
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.RequestStatus = void 0;
10
+ const path = require("path");
11
+ const kit_1 = require("@salesforce/kit");
12
+ const ts_types_1 = require("@salesforce/ts-types");
13
+ const js2xmlparser = require("js2xmlparser");
14
+ const logger_1 = require("../logger");
15
+ const sfdxError_1 = require("../sfdxError");
16
+ const jsonXmlTools_1 = require("../util/jsonXmlTools");
17
+ const zipWriter_1 = require("../util/zipWriter");
18
+ const pollingClient_1 = require("../status/pollingClient");
19
+ var RequestStatus;
20
+ (function (RequestStatus) {
21
+ RequestStatus["Pending"] = "Pending";
22
+ RequestStatus["InProgress"] = "InProgress";
23
+ RequestStatus["Succeeded"] = "Succeeded";
24
+ RequestStatus["SucceededPartial"] = "SucceededPartial";
25
+ RequestStatus["Failed"] = "Failed";
26
+ RequestStatus["Canceling"] = "Canceling";
27
+ RequestStatus["Canceled"] = "Canceled";
28
+ })(RequestStatus = exports.RequestStatus || (exports.RequestStatus = {}));
29
+ const breakPolling = ['Succeeded', 'SucceededPartial', 'Failed', 'Canceled'];
30
+ /**
31
+ * Helper class for dealing with the settings that are defined in a scratch definition file. This class knows how to extract the
32
+ * settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
33
+ */
34
+ class SettingsGenerator {
35
+ constructor() {
36
+ this.shapeDirName = `shape_${Date.now()}`;
37
+ this.logger = logger_1.Logger.childFromRoot('SettingsGenerator');
38
+ // If SFDX_MDAPI_TEMP_DIR is set, copy settings to that dir for people to inspect.
39
+ const mdapiTmpDir = kit_1.env.getString('SFDX_MDAPI_TEMP_DIR');
40
+ this.writer = new zipWriter_1.ZipWriter(mdapiTmpDir);
41
+ }
42
+ /** extract the settings from the scratch def file, if they are present. */
43
+ async extract(scratchDef) {
44
+ this.logger.debug('extracting settings from scratch definition file');
45
+ this.settingData = scratchDef.settings;
46
+ this.objectSettingsData = scratchDef.objectSettings;
47
+ this.logger.debug('settings are', this.settingData);
48
+ }
49
+ /** True if we are currently tracking setting or object setting data. */
50
+ hasSettings() {
51
+ return !(0, kit_1.isEmpty)(this.settingData) || !(0, kit_1.isEmpty)(this.objectSettingsData);
52
+ }
53
+ /** Create temporary deploy directory used to upload the scratch org shape.
54
+ * This will create the dir, all of the .setting files and minimal object files needed for objectSettings
55
+ */
56
+ async createDeploy() {
57
+ const settingsDir = path.join(this.shapeDirName, 'settings');
58
+ const objectsDir = path.join(this.shapeDirName, 'objects');
59
+ await Promise.all([this.writeSettingsIfNeeded(settingsDir), this.writeObjectSettingsIfNeeded(objectsDir)]);
60
+ }
61
+ /**
62
+ * Deploys the settings to the org.
63
+ */
64
+ async deploySettingsViaFolder(scratchOrg, apiVersion) {
65
+ const username = scratchOrg.getUsername();
66
+ const logger = await logger_1.Logger.child('deploySettingsViaFolder');
67
+ this.createPackageXml(apiVersion);
68
+ await this.writer.finalize();
69
+ const connection = scratchOrg.getConnection();
70
+ logger.debug(`deploying to apiVersion: ${apiVersion}`);
71
+ connection.setApiVersion(apiVersion);
72
+ const { id } = await connection.deploy(this.writer.buffer, {});
73
+ logger.debug(`deploying settings id ${id}`);
74
+ let result = await connection.metadata.checkDeployStatus(id);
75
+ const pollingOptions = {
76
+ async poll() {
77
+ try {
78
+ result = await connection.metadata.checkDeployStatus(id, true);
79
+ logger.debug(`Deploy id: ${id} status: ${result.status}`);
80
+ if (breakPolling.includes(result.status)) {
81
+ return {
82
+ completed: true,
83
+ payload: result.status,
84
+ };
85
+ }
86
+ return {
87
+ completed: false,
88
+ };
89
+ }
90
+ catch (error) {
91
+ logger.debug(`An error occurred trying to check deploy id: ${id}`);
92
+ logger.debug(`Error: ${error.message}`);
93
+ logger.debug('Re-trying deploy check again....');
94
+ return {
95
+ completed: false,
96
+ };
97
+ }
98
+ },
99
+ timeout: kit_1.Duration.minutes(10),
100
+ frequency: kit_1.Duration.seconds(1),
101
+ timeoutErrorName: 'DeployingSettingsTimeoutError',
102
+ };
103
+ const client = await pollingClient_1.PollingClient.create(pollingOptions);
104
+ const status = await client.subscribe();
105
+ if (status !== RequestStatus.Succeeded) {
106
+ const componentFailures = (0, ts_types_1.ensureObject)(result.details).componentFailures;
107
+ const failures = (Array.isArray(componentFailures) ? componentFailures : [componentFailures])
108
+ .map((failure) => failure.problem)
109
+ .join('\n');
110
+ const error = new sfdxError_1.SfdxError(`A scratch org was created with username ${username}, but the settings failed to deploy due to: \n${failures}`, 'ProblemDeployingSettings');
111
+ error.setData(result);
112
+ throw error;
113
+ }
114
+ }
115
+ async writeObjectSettingsIfNeeded(objectsDir) {
116
+ if (!this.objectSettingsData || !Object.keys(this.objectSettingsData).length) {
117
+ return;
118
+ }
119
+ for (const objectName of Object.keys(this.objectSettingsData)) {
120
+ const value = this.objectSettingsData[objectName];
121
+ // writes the object file in source format
122
+ const objectDir = path.join(objectsDir, (0, kit_1.upperFirst)(objectName));
123
+ const customObjectDir = path.join(objectDir, `${(0, kit_1.upperFirst)(objectName)}.object`);
124
+ const customObjectXml = (0, jsonXmlTools_1.JsonAsXml)({
125
+ json: this.createObjectFileContent(value),
126
+ type: 'RecordType',
127
+ });
128
+ this.writer.addToZip(customObjectXml, customObjectDir);
129
+ if (value.defaultRecordType) {
130
+ const recordTypesDir = path.join(objectDir, 'recordTypes', `${(0, kit_1.upperFirst)(value.defaultRecordType)}.recordType`);
131
+ const recordTypesFileContent = this.createRecordTypeFileContent(objectName, value);
132
+ const recordTypesXml = (0, jsonXmlTools_1.JsonAsXml)({
133
+ json: recordTypesFileContent,
134
+ type: 'RecordType',
135
+ });
136
+ this.writer.addToZip(recordTypesXml, recordTypesDir);
137
+ // for things that required a businessProcess
138
+ if (recordTypesFileContent.businessProcess) {
139
+ const businessProcessesDir = path.join(objectDir, 'businessProcesses', `${recordTypesFileContent.businessProcess}.businessProcess`);
140
+ const businessProcessesXml = (0, jsonXmlTools_1.JsonAsXml)({
141
+ json: this.createBusinessProcessFileContent(objectName, recordTypesFileContent.businessProcess),
142
+ type: 'BusinessProcess',
143
+ });
144
+ this.writer.addToZip(businessProcessesXml, businessProcessesDir);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ async writeSettingsIfNeeded(settingsDir) {
150
+ if (this.settingData) {
151
+ for (const item of Object.keys(this.settingData)) {
152
+ const value = (0, ts_types_1.getObject)(this.settingData, item);
153
+ const typeName = (0, kit_1.upperFirst)(item);
154
+ const fname = typeName.replace('Settings', '');
155
+ const fileContent = js2xmlparser.parse(typeName, value);
156
+ this.writer.addToZip(fileContent, path.join(settingsDir, fname + '.settings'));
157
+ }
158
+ }
159
+ }
160
+ createPackageXml(apiVersion) {
161
+ const pkg = `<?xml version="1.0" encoding="UTF-8"?>
162
+ <Package xmlns="http://soap.sforce.com/2006/04/metadata">
163
+ <types>
164
+ <members>*</members>
165
+ <name>Settings</name>
166
+ </types>
167
+ <types>
168
+ <members>*</members>
169
+ <name>CustomObject</name>
170
+ </types>
171
+ <version>${apiVersion}</version>
172
+ </Package>`;
173
+ this.writer.addToZip(pkg, path.join(this.shapeDirName, 'package.xml'));
174
+ }
175
+ createObjectFileContent(json) {
176
+ const output = {};
177
+ if (json.sharingModel) {
178
+ output.sharingModel = (0, kit_1.upperFirst)(json.sharingModel);
179
+ }
180
+ return output;
181
+ }
182
+ createRecordTypeFileContent(objectName, setting) {
183
+ const defaultRecordType = (0, kit_1.upperFirst)(setting.defaultRecordType);
184
+ const output = {
185
+ fullName: defaultRecordType,
186
+ label: defaultRecordType,
187
+ active: true,
188
+ };
189
+ // all the edge cases
190
+ if (['Case', 'Lead', 'Opportunity', 'Solution'].includes((0, kit_1.upperFirst)(objectName))) {
191
+ return { ...output, businessProcess: `${defaultRecordType}Process` };
192
+ }
193
+ return output;
194
+ }
195
+ createBusinessProcessFileContent(objectName, businessProcessName) {
196
+ const objectToBusinessProcessPicklist = {
197
+ Opportunity: { fullName: 'Prospecting' },
198
+ Case: { fullName: 'New', default: true },
199
+ Lead: { fullName: 'New - Not Contacted', default: true },
200
+ Solution: { fullName: 'Draft', default: true },
201
+ };
202
+ return {
203
+ fullName: businessProcessName,
204
+ isActive: true,
205
+ values: [objectToBusinessProcessPicklist[(0, kit_1.upperFirst)(objectName)]],
206
+ };
207
+ }
208
+ }
209
+ exports.default = SettingsGenerator;
210
+ //# sourceMappingURL=scratchOrgSettingsGenerator.js.map
package/lib/org/user.js CHANGED
@@ -11,12 +11,12 @@ const os_1 = require("os");
11
11
  const kit_1 = require("@salesforce/kit");
12
12
  const ts_types_1 = require("@salesforce/ts-types");
13
13
  const http_api_1 = require("jsforce/lib/http-api");
14
- const connection_1 = require("../org/connection");
15
14
  const logger_1 = require("../logger");
16
15
  const messages_1 = require("../messages");
17
16
  const secureBuffer_1 = require("../crypto/secureBuffer");
18
17
  const sfdxError_1 = require("../sfdxError");
19
18
  const sfdc_1 = require("../util/sfdc");
19
+ const connection_1 = require("./connection");
20
20
  const permissionSetAssignment_1 = require("./permissionSetAssignment");
21
21
  const authInfo_1 = require("./authInfo");
22
22
  const rand = (len) => Math.floor(Math.random() * len.length);
@@ -84,18 +84,18 @@ async function retrieveUserFields(logger, username) {
84
84
  const result = await connection.query(requiredFieldsFromAdminQuery);
85
85
  logger.debug('Successfully retrieved the admin user for this org.');
86
86
  if (result.totalSize === 1) {
87
- const results = kit_1.mapKeys(result.records[0], (value, key) => kit_1.lowerFirst(key));
87
+ const results = (0, kit_1.mapKeys)(result.records[0], (value, key) => (0, kit_1.lowerFirst)(key));
88
88
  const fields = {
89
- id: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.id)),
89
+ id: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.id)),
90
90
  username,
91
- alias: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.alias)),
92
- email: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.email)),
93
- emailEncodingKey: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.emailEncodingKey)),
94
- languageLocaleKey: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.languageLocaleKey)),
95
- localeSidKey: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.localeSidKey)),
96
- profileId: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.profileId)),
97
- lastName: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.lastName)),
98
- timeZoneSidKey: ts_types_1.ensure(ts_types_1.getString(results, exports.REQUIRED_FIELDS.timeZoneSidKey)),
91
+ alias: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.alias)),
92
+ email: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.email)),
93
+ emailEncodingKey: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.emailEncodingKey)),
94
+ languageLocaleKey: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.languageLocaleKey)),
95
+ localeSidKey: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.localeSidKey)),
96
+ profileId: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.profileId)),
97
+ lastName: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.lastName)),
98
+ timeZoneSidKey: (0, ts_types_1.ensure)((0, ts_types_1.getString)(results, exports.REQUIRED_FIELDS.timeZoneSidKey)),
99
99
  };
100
100
  return fields;
101
101
  }
@@ -228,10 +228,9 @@ class User extends kit_1.AsyncCreatable {
228
228
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
229
229
  password.value(async (buffer) => {
230
230
  try {
231
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
232
231
  // @ts-ignore TODO: expose `soap` on Connection however appropriate
233
232
  const soap = userConnection.soap;
234
- await soap.setPassword(ts_types_1.ensureString(info.getFields().userId), buffer.toString('utf8'));
233
+ await soap.setPassword((0, ts_types_1.ensureString)(info.getFields().userId), buffer.toString('utf8'));
235
234
  this.logger.debug(`Set password for userId: ${info.getFields().userId}`);
236
235
  resolve();
237
236
  }
@@ -294,6 +293,7 @@ class User extends kit_1.AsyncCreatable {
294
293
  * ```
295
294
  */
296
295
  async createUser(fields) {
296
+ var _a;
297
297
  // Create a user and get a refresh token
298
298
  const refreshTokenSecret = await this.createUserInternal(fields);
299
299
  // Create the initial auth info
@@ -301,7 +301,8 @@ class User extends kit_1.AsyncCreatable {
301
301
  const adminUserAuthFields = authInfo.getFields(true);
302
302
  // Setup oauth options for the new user
303
303
  const oauthOptions = {
304
- loginUrl: adminUserAuthFields.loginUrl,
304
+ // Communities users require the instance for auth
305
+ loginUrl: (_a = adminUserAuthFields.instanceUrl) !== null && _a !== void 0 ? _a : adminUserAuthFields.loginUrl,
305
306
  refreshToken: refreshTokenSecret.buffer.value((buffer) => buffer.toString('utf8')),
306
307
  clientId: adminUserAuthFields.clientId,
307
308
  clientSecret: adminUserAuthFields.clientSecret,
@@ -389,17 +390,17 @@ class User extends kit_1.AsyncCreatable {
389
390
  body,
390
391
  };
391
392
  const response = await this.rawRequest(conn, info);
392
- const responseBody = kit_1.parseJsonMap(ts_types_1.ensureString(response['body']));
393
- const statusCode = ts_types_1.asNumber(response.statusCode);
393
+ const responseBody = (0, kit_1.parseJsonMap)((0, ts_types_1.ensureString)(response['body']));
394
+ const statusCode = (0, ts_types_1.asNumber)(response.statusCode);
394
395
  this.logger.debug(`user create response.statusCode: ${response.statusCode}`);
395
396
  if (!(statusCode === 201 || statusCode === 200)) {
396
397
  let message = messages.getMessage('invalidHttpResponseCreatingUser', [statusCode]);
397
398
  if (responseBody) {
398
- const errors = ts_types_1.asJsonArray(responseBody.Errors);
399
+ const errors = (0, ts_types_1.asJsonArray)(responseBody.Errors);
399
400
  if (errors && errors.length > 0) {
400
401
  message = `${message} causes:${os_1.EOL}`;
401
402
  errors.forEach((singleMessage) => {
402
- if (!ts_types_1.isJsonMap(singleMessage))
403
+ if (!(0, ts_types_1.isJsonMap)(singleMessage))
403
404
  return;
404
405
  message = `${message}${os_1.EOL}${singleMessage.description}`;
405
406
  });
@@ -408,11 +409,11 @@ class User extends kit_1.AsyncCreatable {
408
409
  this.logger.debug(message);
409
410
  throw new sfdxError_1.SfdxError(message, 'UserCreateHttpError');
410
411
  }
411
- fields.id = ts_types_1.ensureString(responseBody.id);
412
+ fields.id = (0, ts_types_1.ensureString)(responseBody.id);
412
413
  await this.updateRequiredUserFields(fields);
413
414
  const buffer = new secureBuffer_1.SecureBuffer();
414
- const headers = ts_types_1.ensureJsonMap(response.headers);
415
- const autoApproveUser = ts_types_1.ensureString(headers['auto-approve-user']);
415
+ const headers = (0, ts_types_1.ensureJsonMap)(response.headers);
416
+ const autoApproveUser = (0, ts_types_1.ensureString)(headers['auto-approve-user']);
416
417
  buffer.consume(Buffer.from(autoApproveUser));
417
418
  return {
418
419
  buffer,
@@ -433,13 +434,13 @@ class User extends kit_1.AsyncCreatable {
433
434
  * @param fields The fields for the user.
434
435
  */
435
436
  async updateRequiredUserFields(fields) {
436
- const leftOverRequiredFields = kit_1.omit(fields, [
437
+ const leftOverRequiredFields = (0, kit_1.omit)(fields, [
437
438
  exports.REQUIRED_FIELDS.username,
438
439
  exports.REQUIRED_FIELDS.email,
439
440
  exports.REQUIRED_FIELDS.lastName,
440
441
  exports.REQUIRED_FIELDS.profileId,
441
442
  ]);
442
- const object = kit_1.mapKeys(leftOverRequiredFields, (value, key) => kit_1.upperFirst(key));
443
+ const object = (0, kit_1.mapKeys)(leftOverRequiredFields, (value, key) => (0, kit_1.upperFirst)(key));
443
444
  await this.org.getConnection().sobject('User').update(object);
444
445
  this.logger.debug(`Successfully Updated additional properties for user: ${fields.username}`);
445
446
  }