Skip to content

Commit cb49efc

Browse files
feat!: ga new tree commands (#975)
* feat!: ga the new data tree commands * test: fix relative path references * test: nuts for new commands use their permanent name * test: don't use the old weird files format for importing * test: works ok without existing save/resolve refs * fix: prevent undefined in template literal * docs: fix aliases, message from old command * chore: correct snapshots for alias fix * fix: update messages (#976) * fix: deprecation shows on legacy tree commands --------- Co-authored-by: Juliet Shackell <63259011+jshackell-sfdc@users.noreply.github.com>
1 parent c809b66 commit cb49efc

22 files changed

+358
-259
lines changed

NewTreeCommandsPlan.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
We're improving the `data export tree` and `data import tree` commands, but doing it in phases.
44

5-
## Phase 1: Beta the new commands. [Now]
5+
## Phase 1: Beta the new commands. [Completed]
66

77
Our plan:
88

@@ -29,7 +29,7 @@ Other differences:
2929
- `data import beta tree --files` (and not `--plan`) imports the files in parallel. Files can only reference each other if you specify `--plan`.
3030
- `data import tree` outputs deprecation warnings for both `--content-type` and `--config-help` flags.
3131

32-
## Phase 2: GA the new commands, put the old ones under the `legacy` sub-topic. [July 10, 2024]
32+
## Phase 2: GA the new commands, put the old ones under the `legacy` sub-topic. [Now]
3333

3434
Our plan:
3535

@@ -43,7 +43,7 @@ Our plan:
4343

4444
Our plan:
4545

46-
1. Update `data export tree --plan` to stop writing the unused `saveRefs` and `resolveRefs` properties on plan files, and stop returning them in JSON output.
46+
1. Update `data export tree --plan` to stop writing the unused `saveRefs` and `resolveRefs` properties on plan files, and stop returning them in JSON output, and remove the warning about that change.
4747
1. Tighten the schema to remove the `object` part of `files`, and remove `saveRefs` and `resolveRefs`.
4848
1. Check messages for any that aren't being used, then remove them.
4949
1. Remove the `beta` alias from `data import tree` and `data export tree`.

command-snapshot.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@
7474
},
7575
{
7676
"alias": [],
77-
"command": "data:export:beta:tree",
77+
"command": "data:export:legacy:tree",
7878
"flagAliases": ["apiversion", "outputdir", "targetusername", "u"],
7979
"flagChars": ["d", "o", "p", "q", "x"],
8080
"flags": ["api-version", "flags-dir", "json", "loglevel", "output-dir", "plan", "prefix", "query", "target-org"],
8181
"plugin": "@salesforce/plugin-data"
8282
},
8383
{
84-
"alias": ["force:data:tree:export"],
84+
"alias": ["force:data:tree:export", "data:export:beta:tree"],
8585
"command": "data:export:tree",
8686
"flagAliases": ["apiversion", "outputdir", "targetusername", "u"],
8787
"flagChars": ["d", "o", "p", "q", "x"],
@@ -109,15 +109,7 @@
109109
},
110110
{
111111
"alias": [],
112-
"command": "data:import:beta:tree",
113-
"flagAliases": ["apiversion", "sobjecttreefiles", "targetusername", "u"],
114-
"flagChars": ["f", "o", "p"],
115-
"flags": ["api-version", "files", "flags-dir", "json", "loglevel", "plan", "target-org"],
116-
"plugin": "@salesforce/plugin-data"
117-
},
118-
{
119-
"alias": ["force:data:tree:import"],
120-
"command": "data:import:tree",
112+
"command": "data:import:legacy:tree",
121113
"flagAliases": ["apiversion", "confighelp", "contenttype", "sobjecttreefiles", "targetusername", "u"],
122114
"flagChars": ["c", "f", "o", "p"],
123115
"flags": [
@@ -133,6 +125,14 @@
133125
],
134126
"plugin": "@salesforce/plugin-data"
135127
},
128+
{
129+
"alias": ["force:data:tree:import", "data:import:beta:tree"],
130+
"command": "data:import:tree",
131+
"flagAliases": ["apiversion", "sobjecttreefiles", "targetusername", "u"],
132+
"flagChars": ["f", "o", "p"],
133+
"flags": ["api-version", "files", "flags-dir", "json", "loglevel", "plan", "target-org"],
134+
"plugin": "@salesforce/plugin-data"
135+
},
136136
{
137137
"alias": ["force:data:soql:query"],
138138
"command": "data:query",

messages/tree.export.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Directory in which to generate the JSON files; default is current directory.
3030

3131
- Export records retrieved with the specified SOQL query into a single JSON file in the current directory; the command uses your default org:
3232

33-
<%= config.bin %> <%= command.id %> --query "SELECT Id, Name, (SELECT Name, Address__c FROM Properties__r) FROM Broker__c"
33+
<%= config.bin %> <%= command.id %> --query "SELECT Id, Name, (SELECT Name, Address**c FROM Properties**r) FROM Broker\_\_c"
3434

3535
- Export data using a SOQL query in the "query.txt" file and generate JSON files for each object and a plan that aggregates them:
3636

@@ -43,3 +43,11 @@ Directory in which to generate the JSON files; default is current directory.
4343
# PrefixSlashError
4444

4545
`--prefix` cannot contain a forward slash or backslash.
46+
47+
# PlanJsonWarning
48+
49+
Starting on Nov 10, 2024, the JSON output for `--plan` will no longer include the `saveRefs` and `resolveRefs` properties.
50+
51+
# LegacyDeprecation
52+
53+
Starting on Nov 10, 2024, this command will no longer be available. Use `data export tree` instead.

messages/tree.import.beta.md

Lines changed: 0 additions & 43 deletions
This file was deleted.

messages/tree.import.legacy.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# summary
2+
3+
Import data from one or more JSON files into an org.
4+
5+
# description
6+
7+
The JSON files that contain the data are in sObject tree format, which is a collection of nested, parent-child records with a single root record. Use the "<%= config.bin %> data export tree" command to generate these JSON files.
8+
9+
If you used the --plan flag when exporting the data to generate a plan definition file, use the --plan flag to reference the file when you import. If you're not using a plan, use the --files flag to list the files. If you specify multiple JSON files that depend on each other in a parent-child relationship, be sure you list them in the correct order.
10+
11+
The sObject Tree API supports requests that contain up to 200 records. For more information, see the REST API Developer Guide. (https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_sobject_tree.htm)
12+
13+
# flags.files.summary
14+
15+
Comma-separated and in-order JSON files that contain the records, in sObject tree format, that you want to insert.
16+
17+
# flags.plan.summary
18+
19+
Plan definition file to insert multiple data files.
20+
21+
# flags.content-type.summary
22+
23+
Content type of import files if their extention is not .json.
24+
25+
# flags.content-type.deprecation
26+
27+
The `config-type` flag is deprecated and will be moved to a `legacy` command after July 10, 2024. It will be completely removed after Nov 10, 2024. Use the new `data tree beta import` command.
28+
29+
# flags.config-help.summary
30+
31+
Display schema information for the --plan configuration file to stdout; if you specify this flag, all other flags except --json are ignored.
32+
33+
# flags.config-help.deprecation
34+
35+
The `config-help` flag is deprecated and will be moved to a `legacy` command after July 10, 2024. It will be completely removed after Nov 10, 2024. Use the new `data tree beta import` command.
36+
37+
# examples
38+
39+
- Import the records contained in two JSON files into the org with alias "my-scratch":
40+
41+
<%= config.bin %> <%= command.id %> --files Contact.json,Account.json --target-org my-scratch
42+
43+
- Import records using a plan definition file into your default org:
44+
45+
<%= config.bin %> <%= command.id %> --plan Account-Contact-plan.json
46+
47+
# schema-help
48+
49+
schema(array) - Data Import Plan: Schema for SFDX Toolbelt's data import plan JSON.
50+
51+
- items(object) - SObject Type: Definition of records to be insert per SObject Type
52+
- sobject(string) - Name of SObject: Child file references must have SObject roots of this type
53+
- saveRefs(boolean) - Save References: Post-save, save references (Name/ID) to be used for reference replacement in subsequent saves. Applies to all data files for this SObject type.
54+
- resolveRefs(boolean) - Resolve References: Pre-save, replace @<reference> with ID from previous save. Applies to all data files for this SObject type.
55+
- files(array) - Files: An array of files paths to load
56+
- items(string|object) - Filepath: Filepath string or object to point to a JSON or XML file having data defined in SObject Tree format.
57+
58+
# deprecation
59+
60+
After Nov 10, 2024, this command will no longer be available. Use `data export tree`.

messages/tree.import.md

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,29 @@ The JSON files that contain the data are in sObject tree format, which is a coll
88

99
If you used the --plan flag when exporting the data to generate a plan definition file, use the --plan flag to reference the file when you import. If you're not using a plan, use the --files flag to list the files. If you specify multiple JSON files that depend on each other in a parent-child relationship, be sure you list them in the correct order.
1010

11-
The sObject Tree API supports requests that contain up to 200 records. For more information, see the REST API Developer Guide. (https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_sobject_tree.htm)
12-
1311
# flags.files.summary
1412

1513
Comma-separated and in-order JSON files that contain the records, in sObject tree format, that you want to insert.
1614

17-
# flags.plan.summary
18-
19-
Plan definition file to insert multiple data files.
15+
# flag.files.description
2016

21-
# flags.content-type.summary
17+
Each file can contain up to 200 total records. For more information, see the REST API Developer Guide. (https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_composite_sobject_tree.htm)
2218

23-
Content type of import files if their extention is not .json.
19+
# flags.plan.summary
2420

25-
# flags.content-type.deprecation
21+
Plan definition file to insert multiple data files.
2622

27-
The `config-type` flag is deprecated and will be moved to a `legacy` command after July 10, 2024. It will be completely removed after Nov 10, 2024. Use the new `data tree beta import` command.
23+
# flags.plan.description
2824

29-
# flags.config-help.summary
25+
Unlike when you use the `--files` flag, the files listed in the plan definition file **can** contain more then 200 records. When the CLI executes the import, it automatically batches the records to comply with the 200 record limit set by the API.
3026

31-
Display schema information for the --plan configuration file to stdout; if you specify this flag, all other flags except --json are ignored.
27+
The order in which you list the files in the plan definition file matters. Specifically, records with lookups to records in another file should be listed AFTER that file. For example, let's say you're loading Account and Contact records, and the contacts have references to those accounts. Be sure you list the Accounts file before the Contacts file.
3228

33-
# flags.config-help.deprecation
29+
The plan definition file has the following schema:
3430

35-
The `config-help` flag is deprecated and will be moved to a `legacy` command after July 10, 2024. It will be completely removed after Nov 10, 2024. Use the new `data tree beta import` command.
31+
- items(object) - SObject Type: Definition of records to be insert per SObject Type
32+
- sobject(string) - Name of SObject: Child file references must have SObject roots of this type
33+
- files(array) - Files: An array of files paths to load
3634

3735
# examples
3836

@@ -43,14 +41,3 @@ The `config-help` flag is deprecated and will be moved to a `legacy` command aft
4341
- Import records using a plan definition file into your default org:
4442

4543
<%= config.bin %> <%= command.id %> --plan Account-Contact-plan.json
46-
47-
# schema-help
48-
49-
schema(array) - Data Import Plan: Schema for SFDX Toolbelt's data import plan JSON.
50-
51-
- items(object) - SObject Type: Definition of records to be insert per SObject Type
52-
- sobject(string) - Name of SObject: Child file references must have SObject roots of this type
53-
- saveRefs(boolean) - Save References: Post-save, save references (Name/ID) to be used for reference replacement in subsequent saves. Applies to all data files for this SObject type.
54-
- resolveRefs(boolean) - Resolve References: Pre-save, replace @<reference> with ID from previous save. Applies to all data files for this SObject type.
55-
- files(array) - Files: An array of files paths to load
56-
- items(string|object) - Filepath: Filepath string or object to point to a JSON or XML file having data defined in SObject Tree format.

src/commands/data/export/beta/tree.ts renamed to src/commands/data/export/legacy/tree.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
import { Messages } from '@salesforce/core';
99
import { SfCommand, Flags, Ux } from '@salesforce/sf-plugins-core';
10-
import { orgFlags, prefixValidation } from '../../../../flags.js';
11-
import { ExportConfig, runExport } from '../../../../export.js';
10+
import { orgFlags } from '../../../../flags.js';
11+
import { ExportApi, ExportConfig } from '../../../../api/data/tree/exportApi.js';
1212
import type { DataPlanPart, SObjectTreeFileContents } from '../../../../types.js';
1313

1414
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
@@ -18,9 +18,12 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
1818
public static readonly summary = messages.getMessage('summary');
1919
public static readonly description = messages.getMessage('description');
2020
public static readonly examples = messages.getMessages('examples');
21-
// TODO: when you remove the beta state, put the force: aliases back in
22-
public static readonly state = 'beta';
23-
21+
public static readonly hidden = true;
22+
public static readonly state = 'deprecated';
23+
public static readonly deprecationOptions = {
24+
to: 'data tree export',
25+
message: messages.getMessage('LegacyDeprecation'),
26+
};
2427
public static readonly flags = {
2528
...orgFlags,
2629
query: Flags.string({
@@ -35,7 +38,6 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
3538
prefix: Flags.string({
3639
char: 'x',
3740
summary: messages.getMessage('flags.prefix.summary'),
38-
parse: prefixValidation,
3941
}),
4042
'output-dir': Flags.directory({
4143
char: 'd',
@@ -47,14 +49,14 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
4749

4850
public async run(): Promise<DataPlanPart[] | SObjectTreeFileContents> {
4951
const { flags } = await this.parse(Export);
52+
const ux = new Ux({ jsonEnabled: this.jsonEnabled() });
53+
const exportApi = new ExportApi(flags['target-org'], ux);
5054
const exportConfig: ExportConfig = {
5155
outputDir: flags['output-dir'],
5256
plan: flags.plan,
5357
prefix: flags.prefix,
5458
query: flags.query,
55-
conn: flags['target-org'].getConnection(flags['api-version']),
56-
ux: new Ux({ jsonEnabled: this.jsonEnabled() }),
5759
};
58-
return runExport(exportConfig);
60+
return exportApi.export(exportConfig);
5961
}
6062
}

src/commands/data/export/tree.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
import { Messages } from '@salesforce/core';
99
import { SfCommand, Flags, Ux } from '@salesforce/sf-plugins-core';
10-
import { orgFlags } from '../../../flags.js';
11-
import { ExportApi, ExportConfig } from '../../../api/data/tree/exportApi.js';
10+
import { orgFlags, prefixValidation } from '../../../flags.js';
11+
import { ExportConfig, runExport } from '../../../export.js';
1212
import type { DataPlanPart, SObjectTreeFileContents } from '../../../types.js';
1313

1414
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
@@ -18,7 +18,7 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
1818
public static readonly summary = messages.getMessage('summary');
1919
public static readonly description = messages.getMessage('description');
2020
public static readonly examples = messages.getMessages('examples');
21-
public static readonly aliases = ['force:data:tree:export'];
21+
public static readonly aliases = ['force:data:tree:export', 'data:export:beta:tree'];
2222
public static readonly deprecateAliases = true;
2323

2424
public static readonly flags = {
@@ -35,6 +35,7 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
3535
prefix: Flags.string({
3636
char: 'x',
3737
summary: messages.getMessage('flags.prefix.summary'),
38+
parse: prefixValidation,
3839
}),
3940
'output-dir': Flags.directory({
4041
char: 'd',
@@ -45,19 +46,18 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
4546
};
4647

4748
public async run(): Promise<DataPlanPart[] | SObjectTreeFileContents> {
48-
this.info(
49-
'Try the the new "sf data export beta tree" command. It support SOQL queries with up to 5 levels of objects!'
50-
);
51-
5249
const { flags } = await this.parse(Export);
53-
const ux = new Ux({ jsonEnabled: this.jsonEnabled() });
54-
const exportApi = new ExportApi(flags['target-org'], ux);
50+
if (flags.plan) {
51+
this.warn(messages.getMessage('PlanJsonWarning'));
52+
}
5553
const exportConfig: ExportConfig = {
5654
outputDir: flags['output-dir'],
5755
plan: flags.plan,
5856
prefix: flags.prefix,
5957
query: flags.query,
58+
conn: flags['target-org'].getConnection(flags['api-version']),
59+
ux: new Ux({ jsonEnabled: this.jsonEnabled() }),
6060
};
61-
return exportApi.export(exportConfig);
61+
return runExport(exportConfig);
6262
}
6363
}

0 commit comments

Comments
 (0)