@salesforce/core 3.23.6 → 3.23.7

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,12 @@
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.7](https://github.com/forcedotcom/sfdx-core/compare/v3.23.6...v3.23.7) (2022-07-08)
6
+
7
+ ### Bug Fixes
8
+
9
+ - add structure writer interface and refactor ([daef19c](https://github.com/forcedotcom/sfdx-core/commit/daef19cb3a4d145ebb22c4f721a1bd47ffddce40))
10
+
5
11
  ### [3.23.6](https://github.com/forcedotcom/sfdx-core/compare/v3.23.5...v3.23.6) (2022-07-06)
6
12
 
7
13
  ### Bug Fixes
@@ -21,16 +21,16 @@ export interface PackageFile {
21
21
  types: SettingType[];
22
22
  version: string;
23
23
  }
24
- export declare const createObjectFileContent: ({ allRecordTypes, allbusinessProcesses, apiVersion, settingData, objectSettingsData, }: {
24
+ export declare const createObjectFileContent: ({ allRecordTypes, allBusinessProcesses, apiVersion, settingData, objectSettingsData, }: {
25
25
  allRecordTypes?: string[] | undefined;
26
- allbusinessProcesses?: string[] | undefined;
26
+ allBusinessProcesses?: string[] | undefined;
27
27
  apiVersion: string;
28
28
  settingData?: Record<string, unknown> | undefined;
29
29
  objectSettingsData?: {
30
30
  [objectName: string]: ObjectSetting;
31
31
  } | undefined;
32
32
  }) => PackageFile;
33
- export declare const createRecordTypeAndBusinessProcessFileContent: (objectName: string, json: Record<string, unknown>, allRecordTypes: string[], allbusinessProcesses: string[]) => JsonMap;
33
+ export declare const createRecordTypeAndBusinessProcessFileContent: (objectName: string, json: Record<string, unknown>, allRecordTypes: string[], allBusinessProcesses: string[]) => JsonMap;
34
34
  /**
35
35
  * Helper class for dealing with the settings that are defined in a scratch definition file. This class knows how to extract the
36
36
  * settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
@@ -41,10 +41,14 @@ export default class SettingsGenerator {
41
41
  private logger;
42
42
  private writer;
43
43
  private allRecordTypes;
44
- private allbusinessProcesses;
45
- private shapeDirName;
46
- private packageFilePath;
47
- constructor();
44
+ private allBusinessProcesses;
45
+ private readonly shapeDirName;
46
+ private readonly packageFilePath;
47
+ constructor(options?: {
48
+ mdApiTmpDir?: string;
49
+ shapeDirName?: string;
50
+ asDirectory?: boolean;
51
+ });
48
52
  /** extract the settings from the scratch def file, if they are present. */
49
53
  extract(scratchDef: ScratchOrgInfo): Promise<{
50
54
  settings: Record<string, unknown> | undefined;
@@ -62,7 +66,13 @@ export default class SettingsGenerator {
62
66
  * Deploys the settings to the org.
63
67
  */
64
68
  deploySettingsViaFolder(scratchOrg: Org, apiVersion: string): Promise<void>;
69
+ createDeployPackageContents(apiVersion: string): Promise<void>;
65
70
  getShapeDirName(): string;
71
+ /**
72
+ * Returns the destination where the writer placed the settings content.
73
+ *
74
+ */
75
+ getDestinationPath(): string | undefined;
66
76
  private writeObjectSettingsIfNeeded;
67
77
  private writeSettingsIfNeeded;
68
78
  }
@@ -13,8 +13,9 @@ 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 zipWriter_1 = require("../util/zipWriter");
17
16
  const pollingClient_1 = require("../status/pollingClient");
17
+ const zipWriter_1 = require("../util/zipWriter");
18
+ const directoryWriter_1 = require("../util/directoryWriter");
18
19
  var RequestStatus;
19
20
  (function (RequestStatus) {
20
21
  RequestStatus["Pending"] = "Pending";
@@ -26,7 +27,7 @@ var RequestStatus;
26
27
  RequestStatus["Canceled"] = "Canceled";
27
28
  })(RequestStatus = exports.RequestStatus || (exports.RequestStatus = {}));
28
29
  const breakPolling = ['Succeeded', 'SucceededPartial', 'Failed', 'Canceled'];
29
- const createObjectFileContent = ({ allRecordTypes = [], allbusinessProcesses = [], apiVersion, settingData, objectSettingsData, }) => {
30
+ const createObjectFileContent = ({ allRecordTypes = [], allBusinessProcesses = [], apiVersion, settingData, objectSettingsData, }) => {
30
31
  const output = {
31
32
  '@': {
32
33
  xmlns: 'http://soap.sforce.com/2006/04/metadata',
@@ -43,8 +44,8 @@ const createObjectFileContent = ({ allRecordTypes = [], allbusinessProcesses = [
43
44
  if (allRecordTypes.length > 0) {
44
45
  output.types.push({ members: allRecordTypes, name: 'RecordType' });
45
46
  }
46
- if (allbusinessProcesses.length > 0) {
47
- output.types.push({ members: allbusinessProcesses, name: 'BusinessProcess' });
47
+ if (allBusinessProcesses.length > 0) {
48
+ output.types.push({ members: allBusinessProcesses, name: 'BusinessProcess' });
48
49
  }
49
50
  }
50
51
  return { ...output, ...{ version: apiVersion } };
@@ -73,7 +74,7 @@ const calculateBusinessProcess = (objectName, defaultRecordType) => {
73
74
  }
74
75
  return [businessProcessName, businessProcessPicklistVal];
75
76
  };
76
- const createRecordTypeAndBusinessProcessFileContent = (objectName, json, allRecordTypes, allbusinessProcesses) => {
77
+ const createRecordTypeAndBusinessProcessFileContent = (objectName, json, allRecordTypes, allBusinessProcesses) => {
77
78
  let output = {
78
79
  '@': {
79
80
  xmlns: 'http://soap.sforce.com/2006/04/metadata',
@@ -112,7 +113,7 @@ const createRecordTypeAndBusinessProcessFileContent = (objectName, json, allReco
112
113
  if (name !== 'Opportunity') {
113
114
  values.default = true;
114
115
  }
115
- allbusinessProcesses.push(`${name}.${businessProcessName}`);
116
+ allBusinessProcesses.push(`${name}.${businessProcessName}`);
116
117
  output = {
117
118
  ...output,
118
119
  recordTypes: {
@@ -135,15 +136,23 @@ exports.createRecordTypeAndBusinessProcessFileContent = createRecordTypeAndBusin
135
136
  * settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
136
137
  */
137
138
  class SettingsGenerator {
138
- constructor() {
139
+ constructor(options) {
139
140
  this.allRecordTypes = [];
140
- this.allbusinessProcesses = [];
141
- this.shapeDirName = `shape_${Date.now()}`;
142
- this.packageFilePath = path.join(this.shapeDirName, 'package.xml');
141
+ this.allBusinessProcesses = [];
143
142
  this.logger = logger_1.Logger.childFromRoot('SettingsGenerator');
144
143
  // If SFDX_MDAPI_TEMP_DIR is set, copy settings to that dir for people to inspect.
145
- const mdapiTmpDir = kit_1.env.getString('SFDX_MDAPI_TEMP_DIR');
146
- this.writer = new zipWriter_1.ZipWriter(mdapiTmpDir);
144
+ const mdApiTmpDir = (options === null || options === void 0 ? void 0 : options.mdApiTmpDir) || kit_1.env.getString('SFDX_MDAPI_TEMP_DIR');
145
+ this.shapeDirName = (options === null || options === void 0 ? void 0 : options.shapeDirName) || `shape_${Date.now()}`;
146
+ this.packageFilePath = path.join(this.shapeDirName, 'package.xml');
147
+ let storePath;
148
+ if (!(options === null || options === void 0 ? void 0 : options.asDirectory)) {
149
+ storePath = mdApiTmpDir ? path.join(mdApiTmpDir, `${this.shapeDirName}.zip`) : undefined;
150
+ this.writer = new zipWriter_1.ZipWriter(storePath);
151
+ }
152
+ else {
153
+ storePath = mdApiTmpDir ? path.join(mdApiTmpDir, this.shapeDirName) : undefined;
154
+ this.writer = new directoryWriter_1.DirectoryWriter(storePath);
155
+ }
147
156
  }
148
157
  /** extract the settings from the scratch def file, if they are present. */
149
158
  async extract(scratchDef) {
@@ -165,7 +174,7 @@ class SettingsGenerator {
165
174
  const objectsDir = path.join(this.shapeDirName, 'objects');
166
175
  await Promise.all([
167
176
  this.writeSettingsIfNeeded(settingsDir),
168
- this.writeObjectSettingsIfNeeded(objectsDir, this.allRecordTypes, this.allbusinessProcesses),
177
+ this.writeObjectSettingsIfNeeded(objectsDir, this.allRecordTypes, this.allBusinessProcesses),
169
178
  ]);
170
179
  }
171
180
  /**
@@ -174,16 +183,7 @@ class SettingsGenerator {
174
183
  async deploySettingsViaFolder(scratchOrg, apiVersion) {
175
184
  const username = scratchOrg.getUsername();
176
185
  const logger = await logger_1.Logger.child('deploySettingsViaFolder');
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);
186
- await this.writer.finalize();
186
+ await this.createDeployPackageContents(apiVersion);
187
187
  const connection = scratchOrg.getConnection();
188
188
  logger.debug(`deploying to apiVersion: ${apiVersion}`);
189
189
  connection.setApiVersion(apiVersion);
@@ -230,15 +230,34 @@ class SettingsGenerator {
230
230
  throw error;
231
231
  }
232
232
  }
233
+ async createDeployPackageContents(apiVersion) {
234
+ const packageObjectProps = (0, exports.createObjectFileContent)({
235
+ allRecordTypes: this.allRecordTypes,
236
+ allBusinessProcesses: this.allBusinessProcesses,
237
+ apiVersion,
238
+ settingData: this.settingData,
239
+ objectSettingsData: this.objectSettingsData,
240
+ });
241
+ const xml = js2xmlparser.parse('Package', packageObjectProps);
242
+ await this.writer.addToStore(xml, this.packageFilePath);
243
+ await this.writer.finalize();
244
+ }
233
245
  getShapeDirName() {
234
246
  return this.shapeDirName;
235
247
  }
248
+ /**
249
+ * Returns the destination where the writer placed the settings content.
250
+ *
251
+ */
252
+ getDestinationPath() {
253
+ return this.writer.getDestinationPath();
254
+ }
236
255
  async writeObjectSettingsIfNeeded(objectsDir, allRecordTypes, allbusinessProcesses) {
237
256
  if (this.objectSettingsData) {
238
257
  for (const [item, value] of Object.entries(this.objectSettingsData)) {
239
258
  const fileContent = (0, exports.createRecordTypeAndBusinessProcessFileContent)(item, value, allRecordTypes, allbusinessProcesses);
240
259
  const xml = js2xmlparser.parse('CustomObject', fileContent);
241
- this.writer.addToZip(xml, path.join(objectsDir, (0, kit_1.upperFirst)(item) + '.object'));
260
+ await this.writer.addToStore(xml, path.join(objectsDir, (0, kit_1.upperFirst)(item) + '.object'));
242
261
  }
243
262
  }
244
263
  }
@@ -249,7 +268,7 @@ class SettingsGenerator {
249
268
  const typeName = (0, kit_1.upperFirst)(item);
250
269
  const fname = typeName.replace('Settings', '');
251
270
  const fileContent = js2xmlparser.parse(typeName, value);
252
- this.writer.addToZip(fileContent, path.join(settingsDir, fname + '.settings'));
271
+ await this.writer.addToStore(fileContent, path.join(settingsDir, fname + '.settings'));
253
272
  }
254
273
  }
255
274
  }
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import { Readable } from 'stream';
3
+ import { StructuredWriter } from './structuredWriter';
4
+ export declare class DirectoryWriter implements StructuredWriter {
5
+ private readonly rootDestination?;
6
+ constructor(rootDestination?: string | undefined);
7
+ addToStore(contents: string | Readable | Buffer, targetPath: string): Promise<void>;
8
+ finalize(): Promise<void>;
9
+ getDestinationPath(): string | undefined;
10
+ get buffer(): Buffer;
11
+ }
@@ -0,0 +1,52 @@
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.DirectoryWriter = void 0;
10
+ const stream_1 = require("stream");
11
+ const fs = require("fs");
12
+ const os = require("os");
13
+ const path = require("path");
14
+ const util_1 = require("util");
15
+ const pipeline = (0, util_1.promisify)(stream_1.pipeline);
16
+ class DirectoryWriter {
17
+ constructor(rootDestination) {
18
+ this.rootDestination = rootDestination;
19
+ if (!this.rootDestination) {
20
+ this.rootDestination = fs.mkdtempSync(`${os.tmpdir()}${path.sep}`);
21
+ }
22
+ else {
23
+ fs.mkdirSync(this.rootDestination, { recursive: true });
24
+ }
25
+ }
26
+ async addToStore(contents, targetPath) {
27
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
28
+ const destPath = path.join(this.rootDestination, targetPath);
29
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
30
+ if (contents instanceof stream_1.Readable) {
31
+ const writeStream = fs.createWriteStream(destPath);
32
+ await pipeline(contents, writeStream);
33
+ }
34
+ else if (typeof contents === 'string') {
35
+ fs.writeFileSync(destPath, contents);
36
+ }
37
+ else if (contents instanceof Buffer) {
38
+ fs.writeFileSync(destPath, contents);
39
+ }
40
+ }
41
+ finalize() {
42
+ return Promise.resolve(undefined);
43
+ }
44
+ getDestinationPath() {
45
+ return this.rootDestination;
46
+ }
47
+ get buffer() {
48
+ throw new Error('Not implemented');
49
+ }
50
+ }
51
+ exports.DirectoryWriter = DirectoryWriter;
52
+ //# sourceMappingURL=directoryWriter.js.map
@@ -0,0 +1,8 @@
1
+ /// <reference types="node" />
2
+ import { Readable } from 'stream';
3
+ export interface StructuredWriter {
4
+ addToStore(contents: string | Readable | Buffer, path: string): Promise<void>;
5
+ finalize(): Promise<void>;
6
+ getDestinationPath(): string | undefined;
7
+ get buffer(): Buffer;
8
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=structuredWriter.js.map
@@ -1,13 +1,14 @@
1
1
  /// <reference types="node" />
2
- import { pipeline as cbPipeline, Readable, Writable } from 'stream';
3
- export declare const pipeline: typeof cbPipeline.__promisify__;
4
- export declare class ZipWriter extends Writable {
5
- private rootDestination?;
2
+ import { Readable, Writable } from 'stream';
3
+ import { StructuredWriter } from './structuredWriter';
4
+ export declare class ZipWriter extends Writable implements StructuredWriter {
5
+ private readonly rootDestination?;
6
6
  private zip;
7
7
  private buffers;
8
8
  constructor(rootDestination?: string | undefined);
9
- addToZip(contents: string | Readable | Buffer, path: string): void;
9
+ addToStore(contents: string | Readable | Buffer, path: string): Promise<void>;
10
10
  finalize(): Promise<void>;
11
+ getDestinationPath(): string | undefined;
11
12
  private getOutputStream;
12
13
  private getInputBuffer;
13
14
  get buffer(): Buffer;
@@ -6,12 +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.ZipWriter = exports.pipeline = void 0;
9
+ exports.ZipWriter = void 0;
10
10
  const fs_1 = require("fs");
11
11
  const stream_1 = require("stream");
12
12
  const util_1 = require("util");
13
13
  const archiver_1 = require("archiver");
14
- exports.pipeline = (0, util_1.promisify)(stream_1.pipeline);
14
+ const pipeline = (0, util_1.promisify)(stream_1.pipeline);
15
15
  class ZipWriter extends stream_1.Writable {
16
16
  constructor(rootDestination) {
17
17
  super({ objectMode: true });
@@ -21,15 +21,19 @@ class ZipWriter extends stream_1.Writable {
21
21
  // higher values = diminishing returns on compression and made conversion slower
22
22
  this.zip = (0, archiver_1.create)('zip', { zlib: { level: 3 } });
23
23
  this.buffers = [];
24
- void (0, exports.pipeline)(this.zip, this.getOutputStream());
24
+ void pipeline(this.zip, this.getOutputStream());
25
25
  }
26
- addToZip(contents, path) {
26
+ async addToStore(contents, path) {
27
27
  this.zip.append(contents, { name: path });
28
+ return Promise.resolve();
28
29
  }
29
30
  async finalize() {
30
31
  await this.zip.finalize();
31
32
  await this.getInputBuffer();
32
33
  }
34
+ getDestinationPath() {
35
+ return this.rootDestination;
36
+ }
33
37
  getOutputStream() {
34
38
  if (this.rootDestination) {
35
39
  return (0, fs_1.createWriteStream)(this.rootDestination);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/core",
3
- "version": "3.23.6",
3
+ "version": "3.23.7",
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",
@@ -60,6 +60,7 @@
60
60
  "@salesforce/prettier-config": "^0.0.2",
61
61
  "@salesforce/ts-sinon": "^1.3.21",
62
62
  "@types/archiver": "^5.3.1",
63
+ "@types/chai-string": "^1.4.2",
63
64
  "@types/debug": "0.0.31",
64
65
  "@types/jsen": "0.0.21",
65
66
  "@types/jsonwebtoken": "8.5.7",
@@ -68,6 +69,7 @@
68
69
  "@typescript-eslint/eslint-plugin": "^4.33.0",
69
70
  "@typescript-eslint/parser": "4.33.0",
70
71
  "chai": "^4.3.4",
72
+ "chai-string": "^1.5.0",
71
73
  "commitizen": "^3.1.2",
72
74
  "eslint": "^7.27.0",
73
75
  "eslint-config-prettier": "^6.15.0",