Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: ga new tree commands #975

Merged
merged 10 commits into from
Jul 1, 2024
6 changes: 3 additions & 3 deletions NewTreeCommandsPlan.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

## Phase 1: Beta the new commands. [Now]
## Phase 1: Beta the new commands. [Completed]

Our plan:

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

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

Our plan:

Expand All @@ -43,7 +43,7 @@ Our plan:

Our plan:

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.
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.
1. Tighten the schema to remove the `object` part of `files`, and remove `saveRefs` and `resolveRefs`.
1. Check messages for any that aren't being used, then remove them.
1. Remove the `beta` alias from `data import tree` and `data export tree`.
Expand Down
22 changes: 11 additions & 11 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@
},
{
"alias": [],
"command": "data:export:beta:tree",
"command": "data:export:legacy:tree",
"flagAliases": ["apiversion", "outputdir", "targetusername", "u"],
"flagChars": ["d", "o", "p", "q", "x"],
"flags": ["api-version", "flags-dir", "json", "loglevel", "output-dir", "plan", "prefix", "query", "target-org"],
"plugin": "@salesforce/plugin-data"
},
{
"alias": ["force:data:tree:export"],
"alias": ["force:data:tree:export", "data:tree:beta:export"],
"command": "data:export:tree",
"flagAliases": ["apiversion", "outputdir", "targetusername", "u"],
"flagChars": ["d", "o", "p", "q", "x"],
Expand Down Expand Up @@ -109,15 +109,7 @@
},
{
"alias": [],
"command": "data:import:beta:tree",
"flagAliases": ["apiversion", "sobjecttreefiles", "targetusername", "u"],
"flagChars": ["f", "o", "p"],
"flags": ["api-version", "files", "flags-dir", "json", "loglevel", "plan", "target-org"],
"plugin": "@salesforce/plugin-data"
},
{
"alias": ["force:data:tree:import"],
"command": "data:import:tree",
"command": "data:import:legacy:tree",
"flagAliases": ["apiversion", "confighelp", "contenttype", "sobjecttreefiles", "targetusername", "u"],
"flagChars": ["c", "f", "o", "p"],
"flags": [
Expand All @@ -133,6 +125,14 @@
],
"plugin": "@salesforce/plugin-data"
},
{
"alias": ["force:data:tree:import", "data:tree:beta:import"],
"command": "data:import:tree",
"flagAliases": ["apiversion", "sobjecttreefiles", "targetusername", "u"],
"flagChars": ["f", "o", "p"],
"flags": ["api-version", "files", "flags-dir", "json", "loglevel", "plan", "target-org"],
"plugin": "@salesforce/plugin-data"
},
{
"alias": ["force:data:soql:query"],
"command": "data:query",
Expand Down
10 changes: 9 additions & 1 deletion messages/tree.export.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Directory in which to generate the JSON files; default is current directory.

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

<%= config.bin %> <%= command.id %> --query "SELECT Id, Name, (SELECT Name, Address__c FROM Properties__r) FROM Broker__c"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump dev-scripts to avoid linting the .md files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aww, it's on current dev-scripts. I don't know why that's still happening. Maybe something in vscode ext?

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

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

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

`--prefix` cannot contain a forward slash or backslash.

# PlanJsonWarning

After Nov 10, 2024, the JSON output for `--plan` will no longer include the `saveRefs` and `resolveRefs` properties.

# LegacyDeprecation

After Nov 10, 2024, this command will no longer be available. Use `data export tree`.
43 changes: 0 additions & 43 deletions messages/tree.import.beta.md

This file was deleted.

60 changes: 60 additions & 0 deletions messages/tree.import.legacy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# summary

Import data from one or more JSON files into an org.

# description

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.

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.

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)

# flags.files.summary

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

# flags.plan.summary

Plan definition file to insert multiple data files.

# flags.content-type.summary

Content type of import files if their extention is not .json.

# flags.content-type.deprecation

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.

# flags.config-help.summary

Display schema information for the --plan configuration file to stdout; if you specify this flag, all other flags except --json are ignored.

# flags.config-help.deprecation

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.

# examples

- Import the records contained in two JSON files into the org with alias "my-scratch":

<%= config.bin %> <%= command.id %> --files Contact.json,Account.json --target-org my-scratch

- Import records using a plan definition file into your default org:

<%= config.bin %> <%= command.id %> --plan Account-Contact-plan.json

# schema-help

schema(array) - Data Import Plan: Schema for SFDX Toolbelt's data import plan JSON.

- items(object) - SObject Type: Definition of records to be insert per SObject Type
- sobject(string) - Name of SObject: Child file references must have SObject roots of this type
- 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.
- resolveRefs(boolean) - Resolve References: Pre-save, replace @<reference> with ID from previous save. Applies to all data files for this SObject type.
- files(array) - Files: An array of files paths to load
- items(string|object) - Filepath: Filepath string or object to point to a JSON or XML file having data defined in SObject Tree format.

# deprecation

After Nov 10, 2024, this command will no longer be available. Use `data export tree`.
35 changes: 11 additions & 24 deletions messages/tree.import.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,29 @@ The JSON files that contain the data are in sObject tree format, which is a coll

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.

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)

# flags.files.summary

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

# flags.plan.summary

Plan definition file to insert multiple data files.
# flag.files.description

# flags.content-type.summary
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)

Content type of import files if their extention is not .json.
# flags.plan.summary

# flags.content-type.deprecation
Plan definition file to insert multiple data files.

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.
# flags.plan.description

# flags.config-help.summary
Unlike the `--files` flag, the files listed in the plan definition file **can** contain more then 200 records. These will be automatically batched to comply with that limit.

Display schema information for the --plan configuration file to stdout; if you specify this flag, all other flags except --json are ignored.
The file order matters--records with lookups to records in another file should be listed AFTER that file Example: you're loading Account and Contact records, and the contacts have references to those Accounts. The Accounts file should come before the Contacts file.

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

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.
- items(object) - SObject Type: Definition of records to be insert per SObject Type
- sobject(string) - Name of SObject: Child file references must have SObject roots of this type
- files(array) - Files: An array of files paths to load

# examples

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

<%= config.bin %> <%= command.id %> --plan Account-Contact-plan.json

# schema-help

schema(array) - Data Import Plan: Schema for SFDX Toolbelt's data import plan JSON.

- items(object) - SObject Type: Definition of records to be insert per SObject Type
- sobject(string) - Name of SObject: Child file references must have SObject roots of this type
- 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.
- resolveRefs(boolean) - Resolve References: Pre-save, replace @<reference> with ID from previous save. Applies to all data files for this SObject type.
- files(array) - Files: An array of files paths to load
- items(string|object) - Filepath: Filepath string or object to point to a JSON or XML file having data defined in SObject Tree format.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

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

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
Expand All @@ -18,9 +18,11 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessages('examples');
// TODO: when you remove the beta state, put the force: aliases back in
public static readonly state = 'beta';

public static readonly hidden = true;
public static readonly deprecationOptions = {
to: 'data tree export',
message: messages.getMessage('LegacyDeprecation'),
};
public static readonly flags = {
...orgFlags,
query: Flags.string({
Expand All @@ -35,7 +37,6 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
prefix: Flags.string({
char: 'x',
summary: messages.getMessage('flags.prefix.summary'),
parse: prefixValidation,
}),
'output-dir': Flags.directory({
char: 'd',
Expand All @@ -46,15 +47,19 @@ export default class Export extends SfCommand<DataPlanPart[] | SObjectTreeFileCo
};

public async run(): Promise<DataPlanPart[] | SObjectTreeFileContents> {
this.info(
'Try the the new "sf data export beta tree" command. It support SOQL queries with up to 5 levels of objects!'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if they run the legacy command, you'll get a suggestion for a beta command, it should just b e"data export tree" right

 ➜  ../../oss/plugin-data/bin/run.js data export legacy tree --query "SELECT ID FROM Account"
Try the the new "sf data export beta tree" command.  It support SOQL queries with up to 5 levels of objects!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even then,

 ➜  ../../oss/plugin-data/bin/run.js data export beta tree --query "SELECT ID FROM Account"   
 ›   Error: command data:export:beta:tree not found

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just going to remove that. at this point, you're intentionally choosing this old command to avoid the new one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, you found that I had the "beta" alias wrong on the new commands.

);

const { flags } = await this.parse(Export);
const ux = new Ux({ jsonEnabled: this.jsonEnabled() });
const exportApi = new ExportApi(flags['target-org'], ux);
const exportConfig: ExportConfig = {
outputDir: flags['output-dir'],
plan: flags.plan,
prefix: flags.prefix,
query: flags.query,
conn: flags['target-org'].getConnection(flags['api-version']),
ux: new Ux({ jsonEnabled: this.jsonEnabled() }),
};
return runExport(exportConfig);
return exportApi.export(exportConfig);
}
}
20 changes: 10 additions & 10 deletions src/commands/data/export/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

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

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

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

public async run(): Promise<DataPlanPart[] | SObjectTreeFileContents> {
this.info(
'Try the the new "sf data export beta tree" command. It support SOQL queries with up to 5 levels of objects!'
);

const { flags } = await this.parse(Export);
const ux = new Ux({ jsonEnabled: this.jsonEnabled() });
const exportApi = new ExportApi(flags['target-org'], ux);
if (flags.plan) {
this.warn(messages.getMessage('PlanJsonWarning'));
}
const exportConfig: ExportConfig = {
outputDir: flags['output-dir'],
plan: flags.plan,
prefix: flags.prefix,
query: flags.query,
conn: flags['target-org'].getConnection(flags['api-version']),
ux: new Ux({ jsonEnabled: this.jsonEnabled() }),
};
return exportApi.export(exportConfig);
return runExport(exportConfig);
}
}
Loading
Loading