@salesforce/core 3.23.3 → 3.23.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [3.23.6](https://github.com/forcedotcom/sfdx-core/compare/v3.23.5...v3.23.6) (2022-07-06)
6
+
7
+ ### Bug Fixes
8
+
9
+ - workaround for jsforce update bug ([1776f50](https://github.com/forcedotcom/sfdx-core/commit/1776f505671a5a764c4e966736c2981df2b178a4))
10
+
11
+ ### [3.23.5](https://github.com/forcedotcom/sfdx-core/compare/v3.23.4...v3.23.5) (2022-07-06)
12
+
13
+ ### Bug Fixes
14
+
15
+ - add resolveAlias ([#605](https://github.com/forcedotcom/sfdx-core/issues/605)) ([ffa9ed6](https://github.com/forcedotcom/sfdx-core/commit/ffa9ed63ea583baa327071db4030ea5346d1128f))
16
+
17
+ ### [3.23.4](https://github.com/forcedotcom/sfdx-core/compare/v3.23.3...v3.23.4) (2022-07-05)
18
+
19
+ ### Bug Fixes
20
+
21
+ - force publish ([3eb660d](https://github.com/forcedotcom/sfdx-core/commit/3eb660dd23ee959e085a9ac3dbd65de92e511d74))
22
+
5
23
  ### [3.23.3](https://github.com/forcedotcom/sfdx-core/compare/v3.23.2...v3.23.3) (2022-06-30)
6
24
 
7
25
  ### Bug Fixes
@@ -392,12 +392,22 @@ const updateRevisionCounterToZero = async (scratchOrg) => {
392
392
  return;
393
393
  }
394
394
  try {
395
- await conn.tooling
396
- .sobject('SourceMember')
397
- .update(queryResult.map((record) => ({ Id: record.Id, RevisionCounter: 0 })));
395
+ // jsforce has a bug in its `update` code such that tooling#update doesn't work right
396
+ // https://github.com/jsforce/jsforce/blob/265eba5c734439dd7b77610c05b63bde7d4b1e83/src/connection.ts#L1082
397
+ // will result in `this._ensureVersion is not a function`
398
+ // so until that is resolved, we hit the API with singular records
399
+ // once that's fixed, you can use the following code for a single API call
400
+ // await conn.tooling
401
+ // .sobject('SourceMember')
402
+ // .update(queryResult.map((record) => ({ Id: record.Id, RevisionCounter: 0 })));
403
+ await Promise.all(queryResult.map((record) => conn.tooling.sobject('SourceMember').update({ Id: record.Id, RevisionCounter: 0 })));
398
404
  }
399
405
  catch (err) {
400
- await lifecycleEvents_1.Lifecycle.getInstance().emitWarning(messages.getMessage('SourceStatusResetFailureError', [scratchOrg.getOrgId(), scratchOrg.getUsername()]));
406
+ await lifecycleEvents_1.Lifecycle.getInstance().emitWarning(messages.getMessage('SourceStatusResetFailureError', [
407
+ scratchOrg.getOrgId(),
408
+ scratchOrg.getUsername(),
409
+ err instanceof Error ? err.message : '',
410
+ ]));
401
411
  }
402
412
  };
403
413
  exports.updateRevisionCounterToZero = updateRevisionCounterToZero;
@@ -10,16 +10,27 @@ export declare enum RequestStatus {
10
10
  Canceling = "Canceling",
11
11
  Canceled = "Canceled"
12
12
  }
13
- export interface BusinessProcessFileContent extends JsonMap {
14
- fullName: string;
15
- isActive: boolean;
16
- values: [
17
- {
18
- fullName: string;
19
- default?: boolean;
20
- }
21
- ];
13
+ export interface SettingType {
14
+ members: string[];
15
+ name: 'CustomObject' | 'RecordType' | 'BusinessProcess' | 'Settings';
22
16
  }
17
+ export interface PackageFile {
18
+ '@': {
19
+ xmlns: string;
20
+ };
21
+ types: SettingType[];
22
+ version: string;
23
+ }
24
+ export declare const createObjectFileContent: ({ allRecordTypes, allbusinessProcesses, apiVersion, settingData, objectSettingsData, }: {
25
+ allRecordTypes?: string[] | undefined;
26
+ allbusinessProcesses?: string[] | undefined;
27
+ apiVersion: string;
28
+ settingData?: Record<string, unknown> | undefined;
29
+ objectSettingsData?: {
30
+ [objectName: string]: ObjectSetting;
31
+ } | undefined;
32
+ }) => PackageFile;
33
+ export declare const createRecordTypeAndBusinessProcessFileContent: (objectName: string, json: Record<string, unknown>, allRecordTypes: string[], allbusinessProcesses: string[]) => JsonMap;
23
34
  /**
24
35
  * Helper class for dealing with the settings that are defined in a scratch definition file. This class knows how to extract the
25
36
  * settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
@@ -29,7 +40,10 @@ export default class SettingsGenerator {
29
40
  private objectSettingsData?;
30
41
  private logger;
31
42
  private writer;
43
+ private allRecordTypes;
44
+ private allbusinessProcesses;
32
45
  private shapeDirName;
46
+ private packageFilePath;
33
47
  constructor();
34
48
  /** extract the settings from the scratch def file, if they are present. */
35
49
  extract(scratchDef: ScratchOrgInfo): Promise<{
@@ -51,8 +65,4 @@ export default class SettingsGenerator {
51
65
  getShapeDirName(): string;
52
66
  private writeObjectSettingsIfNeeded;
53
67
  private writeSettingsIfNeeded;
54
- private createPackageXml;
55
- private createObjectFileContent;
56
- private createRecordTypeFileContent;
57
- private createBusinessProcessFileContent;
58
68
  }
@@ -6,14 +6,13 @@
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.RequestStatus = void 0;
9
+ exports.createRecordTypeAndBusinessProcessFileContent = exports.createObjectFileContent = exports.RequestStatus = void 0;
10
10
  const path = require("path");
11
11
  const kit_1 = require("@salesforce/kit");
12
12
  const ts_types_1 = require("@salesforce/ts-types");
13
13
  const js2xmlparser = require("js2xmlparser");
14
14
  const logger_1 = require("../logger");
15
15
  const sfError_1 = require("../sfError");
16
- const jsonXmlTools_1 = require("../util/jsonXmlTools");
17
16
  const zipWriter_1 = require("../util/zipWriter");
18
17
  const pollingClient_1 = require("../status/pollingClient");
19
18
  var RequestStatus;
@@ -27,13 +26,120 @@ var RequestStatus;
27
26
  RequestStatus["Canceled"] = "Canceled";
28
27
  })(RequestStatus = exports.RequestStatus || (exports.RequestStatus = {}));
29
28
  const breakPolling = ['Succeeded', 'SucceededPartial', 'Failed', 'Canceled'];
29
+ const createObjectFileContent = ({ allRecordTypes = [], allbusinessProcesses = [], apiVersion, settingData, objectSettingsData, }) => {
30
+ const output = {
31
+ '@': {
32
+ xmlns: 'http://soap.sforce.com/2006/04/metadata',
33
+ },
34
+ types: [],
35
+ };
36
+ if (settingData) {
37
+ const strings = Object.keys(settingData).map((item) => (0, kit_1.upperFirst)(item).replace('Settings', ''));
38
+ output.types.push({ members: strings, name: 'Settings' });
39
+ }
40
+ if (objectSettingsData) {
41
+ const strings = Object.keys(objectSettingsData).map((item) => (0, kit_1.upperFirst)(item));
42
+ output.types.push({ members: strings, name: 'CustomObject' });
43
+ if (allRecordTypes.length > 0) {
44
+ output.types.push({ members: allRecordTypes, name: 'RecordType' });
45
+ }
46
+ if (allbusinessProcesses.length > 0) {
47
+ output.types.push({ members: allbusinessProcesses, name: 'BusinessProcess' });
48
+ }
49
+ }
50
+ return { ...output, ...{ version: apiVersion } };
51
+ };
52
+ exports.createObjectFileContent = createObjectFileContent;
53
+ const calculateBusinessProcess = (objectName, defaultRecordType) => {
54
+ let businessProcessName = null;
55
+ let businessProcessPicklistVal = null;
56
+ // These four objects require any record type to specify a "business process"--
57
+ // a restricted set of items from a standard picklist on the object.
58
+ if (['Case', 'Lead', 'Opportunity', 'Solution'].includes(objectName)) {
59
+ businessProcessName = (0, kit_1.upperFirst)(defaultRecordType) + 'Process';
60
+ switch (objectName) {
61
+ case 'Case':
62
+ businessProcessPicklistVal = 'New';
63
+ break;
64
+ case 'Lead':
65
+ businessProcessPicklistVal = 'New - Not Contacted';
66
+ break;
67
+ case 'Opportunity':
68
+ businessProcessPicklistVal = 'Prospecting';
69
+ break;
70
+ case 'Solution':
71
+ businessProcessPicklistVal = 'Draft';
72
+ }
73
+ }
74
+ return [businessProcessName, businessProcessPicklistVal];
75
+ };
76
+ const createRecordTypeAndBusinessProcessFileContent = (objectName, json, allRecordTypes, allbusinessProcesses) => {
77
+ let output = {
78
+ '@': {
79
+ xmlns: 'http://soap.sforce.com/2006/04/metadata',
80
+ },
81
+ };
82
+ const name = (0, kit_1.upperFirst)(objectName);
83
+ const sharingModel = json.sharingModel;
84
+ if (sharingModel) {
85
+ output = {
86
+ ...output,
87
+ sharingModel: (0, kit_1.upperFirst)(sharingModel),
88
+ };
89
+ }
90
+ const defaultRecordType = json.defaultRecordType;
91
+ if (typeof defaultRecordType === 'string') {
92
+ // We need to keep track of these globally for when we generate the package XML.
93
+ allRecordTypes.push(`${name}.${(0, kit_1.upperFirst)(defaultRecordType)}`);
94
+ const [businessProcessName, businessProcessPicklistVal] = calculateBusinessProcess(name, defaultRecordType);
95
+ // Create the record type
96
+ const recordTypes = {
97
+ fullName: (0, kit_1.upperFirst)(defaultRecordType),
98
+ label: (0, kit_1.upperFirst)(defaultRecordType),
99
+ active: true,
100
+ };
101
+ output = {
102
+ ...output,
103
+ recordTypes: {
104
+ ...recordTypes,
105
+ },
106
+ };
107
+ if (businessProcessName) {
108
+ // We need to keep track of these globally for the package.xml
109
+ const values = {
110
+ fullName: businessProcessPicklistVal,
111
+ };
112
+ if (name !== 'Opportunity') {
113
+ values.default = true;
114
+ }
115
+ allbusinessProcesses.push(`${name}.${businessProcessName}`);
116
+ output = {
117
+ ...output,
118
+ recordTypes: {
119
+ ...recordTypes,
120
+ businessProcess: businessProcessName,
121
+ },
122
+ businessProcesses: {
123
+ fullName: businessProcessName,
124
+ isActive: true,
125
+ values,
126
+ },
127
+ };
128
+ }
129
+ }
130
+ return output;
131
+ };
132
+ exports.createRecordTypeAndBusinessProcessFileContent = createRecordTypeAndBusinessProcessFileContent;
30
133
  /**
31
134
  * Helper class for dealing with the settings that are defined in a scratch definition file. This class knows how to extract the
32
135
  * settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
33
136
  */
34
137
  class SettingsGenerator {
35
138
  constructor() {
139
+ this.allRecordTypes = [];
140
+ this.allbusinessProcesses = [];
36
141
  this.shapeDirName = `shape_${Date.now()}`;
142
+ this.packageFilePath = path.join(this.shapeDirName, 'package.xml');
37
143
  this.logger = logger_1.Logger.childFromRoot('SettingsGenerator');
38
144
  // If SFDX_MDAPI_TEMP_DIR is set, copy settings to that dir for people to inspect.
39
145
  const mdapiTmpDir = kit_1.env.getString('SFDX_MDAPI_TEMP_DIR');
@@ -57,7 +163,10 @@ class SettingsGenerator {
57
163
  async createDeploy() {
58
164
  const settingsDir = path.join(this.shapeDirName, 'settings');
59
165
  const objectsDir = path.join(this.shapeDirName, 'objects');
60
- await Promise.all([this.writeSettingsIfNeeded(settingsDir), this.writeObjectSettingsIfNeeded(objectsDir)]);
166
+ await Promise.all([
167
+ this.writeSettingsIfNeeded(settingsDir),
168
+ this.writeObjectSettingsIfNeeded(objectsDir, this.allRecordTypes, this.allbusinessProcesses),
169
+ ]);
61
170
  }
62
171
  /**
63
172
  * Deploys the settings to the org.
@@ -65,7 +174,15 @@ class SettingsGenerator {
65
174
  async deploySettingsViaFolder(scratchOrg, apiVersion) {
66
175
  const username = scratchOrg.getUsername();
67
176
  const logger = await logger_1.Logger.child('deploySettingsViaFolder');
68
- this.createPackageXml(apiVersion);
177
+ const packageObjectProps = (0, exports.createObjectFileContent)({
178
+ allRecordTypes: this.allRecordTypes,
179
+ allbusinessProcesses: this.allbusinessProcesses,
180
+ apiVersion,
181
+ settingData: this.settingData,
182
+ objectSettingsData: this.objectSettingsData,
183
+ });
184
+ const xml = js2xmlparser.parse('Package', packageObjectProps);
185
+ this.writer.addToZip(xml, this.packageFilePath);
69
186
  await this.writer.finalize();
70
187
  const connection = scratchOrg.getConnection();
71
188
  logger.debug(`deploying to apiVersion: ${apiVersion}`);
@@ -116,37 +233,12 @@ class SettingsGenerator {
116
233
  getShapeDirName() {
117
234
  return this.shapeDirName;
118
235
  }
119
- async writeObjectSettingsIfNeeded(objectsDir) {
120
- if (!this.objectSettingsData || !Object.keys(this.objectSettingsData).length) {
121
- return;
122
- }
123
- for (const objectName of Object.keys(this.objectSettingsData)) {
124
- const value = this.objectSettingsData[objectName];
125
- // writes the object file in source format
126
- const objectDir = path.join(objectsDir, (0, kit_1.upperFirst)(objectName));
127
- const customObjectDir = path.join(objectDir, `${(0, kit_1.upperFirst)(objectName)}.object`);
128
- const customObjectXml = (0, jsonXmlTools_1.JsonAsXml)({
129
- json: this.createObjectFileContent(value),
130
- type: 'RecordType',
131
- });
132
- this.writer.addToZip(customObjectXml, customObjectDir);
133
- if (value.defaultRecordType) {
134
- const recordTypesDir = path.join(objectDir, 'recordTypes', `${(0, kit_1.upperFirst)(value.defaultRecordType)}.recordType`);
135
- const recordTypesFileContent = this.createRecordTypeFileContent(objectName, value);
136
- const recordTypesXml = (0, jsonXmlTools_1.JsonAsXml)({
137
- json: recordTypesFileContent,
138
- type: 'RecordType',
139
- });
140
- this.writer.addToZip(recordTypesXml, recordTypesDir);
141
- // for things that required a businessProcess
142
- if (recordTypesFileContent.businessProcess) {
143
- const businessProcessesDir = path.join(objectDir, 'businessProcesses', `${recordTypesFileContent.businessProcess}.businessProcess`);
144
- const businessProcessesXml = (0, jsonXmlTools_1.JsonAsXml)({
145
- json: this.createBusinessProcessFileContent(objectName, recordTypesFileContent.businessProcess),
146
- type: 'BusinessProcess',
147
- });
148
- this.writer.addToZip(businessProcessesXml, businessProcessesDir);
149
- }
236
+ async writeObjectSettingsIfNeeded(objectsDir, allRecordTypes, allbusinessProcesses) {
237
+ if (this.objectSettingsData) {
238
+ for (const [item, value] of Object.entries(this.objectSettingsData)) {
239
+ const fileContent = (0, exports.createRecordTypeAndBusinessProcessFileContent)(item, value, allRecordTypes, allbusinessProcesses);
240
+ const xml = js2xmlparser.parse('CustomObject', fileContent);
241
+ this.writer.addToZip(xml, path.join(objectsDir, (0, kit_1.upperFirst)(item) + '.object'));
150
242
  }
151
243
  }
152
244
  }
@@ -161,54 +253,6 @@ class SettingsGenerator {
161
253
  }
162
254
  }
163
255
  }
164
- createPackageXml(apiVersion) {
165
- const pkg = `<?xml version="1.0" encoding="UTF-8"?>
166
- <Package xmlns="http://soap.sforce.com/2006/04/metadata">
167
- <types>
168
- <members>*</members>
169
- <name>Settings</name>
170
- </types>
171
- <types>
172
- <members>*</members>
173
- <name>CustomObject</name>
174
- </types>
175
- <version>${apiVersion}</version>
176
- </Package>`;
177
- this.writer.addToZip(pkg, path.join(this.shapeDirName, 'package.xml'));
178
- }
179
- createObjectFileContent(json) {
180
- const output = {};
181
- if (json.sharingModel) {
182
- output.sharingModel = (0, kit_1.upperFirst)(json.sharingModel);
183
- }
184
- return output;
185
- }
186
- createRecordTypeFileContent(objectName, setting) {
187
- const defaultRecordType = (0, kit_1.upperFirst)(setting.defaultRecordType);
188
- const output = {
189
- fullName: defaultRecordType,
190
- label: defaultRecordType,
191
- active: true,
192
- };
193
- // all the edge cases
194
- if (['Case', 'Lead', 'Opportunity', 'Solution'].includes((0, kit_1.upperFirst)(objectName))) {
195
- return { ...output, businessProcess: `${defaultRecordType}Process` };
196
- }
197
- return output;
198
- }
199
- createBusinessProcessFileContent(objectName, businessProcessName) {
200
- const objectToBusinessProcessPicklist = {
201
- Opportunity: { fullName: 'Prospecting' },
202
- Case: { fullName: 'New', default: true },
203
- Lead: { fullName: 'New - Not Contacted', default: true },
204
- Solution: { fullName: 'Draft', default: true },
205
- };
206
- return {
207
- fullName: businessProcessName,
208
- isActive: true,
209
- values: [objectToBusinessProcessPicklist[(0, kit_1.upperFirst)(objectName)]],
210
- };
211
- }
212
256
  }
213
257
  exports.default = SettingsGenerator;
214
258
  //# sourceMappingURL=scratchOrgSettingsGenerator.js.map
@@ -138,6 +138,16 @@ export declare class AliasAccessor extends AsyncOptionalCreatable {
138
138
  * @param usernameOrAlias a string that might be a username or might be an alias
139
139
  */
140
140
  resolveUsername(usernameOrAlias: string): string;
141
+ /**
142
+ * If the provided string is an alias, return it.
143
+ * If the provided string is not an alias, return the username of the provided alias
144
+ *
145
+ * This method is helpful when you don't know if the string you have is a username
146
+ * or an alias.
147
+ *
148
+ * @param usernameOrAlias a string that might be a username or might be an alias
149
+ */
150
+ resolveAlias(usernameOrAlias: string): Nullable<string>;
141
151
  /**
142
152
  * Set an alias for the given aliasable entity
143
153
  *
@@ -145,14 +155,24 @@ export declare class AliasAccessor extends AsyncOptionalCreatable {
145
155
  * @param entity the aliasable entity that's being aliased
146
156
  */
147
157
  set(alias: string, entity: Aliasable): void;
158
+ /**
159
+ * Unset the given alias.
160
+ *
161
+ */
148
162
  unset(alias: string): void;
149
163
  /**
150
- * This method unsets all the aliases for the given entity.
164
+ * Unsets all the aliases for the given entity.
151
165
  *
152
166
  * @param entity the aliasable entity for which you want to unset all aliases
153
167
  */
154
168
  unsetAll(entity: Aliasable): void;
155
169
  write(): Promise<ConfigContents>;
170
+ /**
171
+ * Returns true if the provided alias exists
172
+ *
173
+ * @param alias the alias you want to check
174
+ */
175
+ has(alias: string): boolean;
156
176
  protected init(): Promise<void>;
157
177
  /**
158
178
  * Returns the username of given aliasable entity
@@ -202,6 +202,21 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
202
202
  var _a;
203
203
  return (_a = this.getUsername(usernameOrAlias)) !== null && _a !== void 0 ? _a : usernameOrAlias;
204
204
  }
205
+ /**
206
+ * If the provided string is an alias, return it.
207
+ * If the provided string is not an alias, return the username of the provided alias
208
+ *
209
+ * This method is helpful when you don't know if the string you have is a username
210
+ * or an alias.
211
+ *
212
+ * @param usernameOrAlias a string that might be a username or might be an alias
213
+ */
214
+ resolveAlias(usernameOrAlias) {
215
+ var _a;
216
+ if (this.has(usernameOrAlias))
217
+ return usernameOrAlias;
218
+ return (_a = Object.entries(this.getAll()).find(([, username]) => username === usernameOrAlias)) === null || _a === void 0 ? void 0 : _a[0];
219
+ }
205
220
  /**
206
221
  * Set an alias for the given aliasable entity
207
222
  *
@@ -211,11 +226,15 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
211
226
  set(alias, entity) {
212
227
  this.config.set(alias, this.getNameOf(entity));
213
228
  }
229
+ /**
230
+ * Unset the given alias.
231
+ *
232
+ */
214
233
  unset(alias) {
215
234
  this.config.unset(alias);
216
235
  }
217
236
  /**
218
- * This method unsets all the aliases for the given entity.
237
+ * Unsets all the aliases for the given entity.
219
238
  *
220
239
  * @param entity the aliasable entity for which you want to unset all aliases
221
240
  */
@@ -226,6 +245,14 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
226
245
  async write() {
227
246
  return this.config.write();
228
247
  }
248
+ /**
249
+ * Returns true if the provided alias exists
250
+ *
251
+ * @param alias the alias you want to check
252
+ */
253
+ has(alias) {
254
+ return this.config.has(alias);
255
+ }
229
256
  async init() {
230
257
  this.config = await aliasesConfig_1.AliasesConfig.create(aliasesConfig_1.AliasesConfig.getDefaultOptions());
231
258
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/core",
3
- "version": "3.23.3",
3
+ "version": "3.23.6",
4
4
  "description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
5
5
  "main": "lib/exported",
6
6
  "types": "lib/exported.d.ts",