sfdx-browserforce-plugin 6.0.0-next.7 → 6.0.0-next.8
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/README.md +3 -4
- package/lib/browserforce-command.d.ts +14 -3
- package/lib/browserforce-command.js +113 -16
- package/lib/browserforce-command.js.map +1 -1
- package/lib/browserforce.d.ts +13 -10
- package/lib/browserforce.js +33 -93
- package/lib/browserforce.js.map +1 -1
- package/lib/commands/browserforce/apply.js +17 -12
- package/lib/commands/browserforce/apply.js.map +1 -1
- package/lib/pages/login.d.ts +2 -2
- package/lib/pages/login.js +2 -9
- package/lib/pages/login.js.map +1 -1
- package/lib/plugin.d.ts +0 -2
- package/lib/plugin.js +0 -2
- package/lib/plugin.js.map +1 -1
- package/lib/plugins/activity-settings/index.e2e-spec.js +1 -1
- package/lib/plugins/activity-settings/index.e2e-spec.js.map +1 -1
- package/lib/plugins/company-information/index.e2e-spec.js +1 -1
- package/lib/plugins/company-information/index.e2e-spec.js.map +1 -1
- package/lib/plugins/company-information/index.js +4 -2
- package/lib/plugins/company-information/index.js.map +1 -1
- package/lib/plugins/customer-portal/available-custom-objects/index.js +1 -3
- package/lib/plugins/customer-portal/available-custom-objects/index.js.map +1 -1
- package/lib/plugins/customer-portal/available-custom-objects/index.test.js +1 -1
- package/lib/plugins/customer-portal/available-custom-objects/index.test.js.map +1 -1
- package/lib/plugins/customer-portal/enabled/index.js +1 -2
- package/lib/plugins/customer-portal/enabled/index.js.map +1 -1
- package/lib/plugins/customer-portal/enabled/index.test.js +1 -1
- package/lib/plugins/customer-portal/enabled/index.test.js.map +1 -1
- package/lib/plugins/customer-portal/index.e2e-spec.js +8 -10
- package/lib/plugins/customer-portal/index.e2e-spec.js.map +1 -1
- package/lib/plugins/customer-portal/index.test.js +1 -1
- package/lib/plugins/customer-portal/index.test.js.map +1 -1
- package/lib/plugins/customer-portal/portals/index.test.js +1 -1
- package/lib/plugins/customer-portal/portals/index.test.js.map +1 -1
- package/lib/plugins/density-settings/index.e2e-spec.js +1 -1
- package/lib/plugins/density-settings/index.e2e-spec.js.map +1 -1
- package/lib/plugins/email-deliverability/index.e2e-spec.js +1 -1
- package/lib/plugins/email-deliverability/index.e2e-spec.js.map +1 -1
- package/lib/plugins/high-velocity-sales-settings/index.d.ts +1 -1
- package/lib/plugins/high-velocity-sales-settings/index.e2e-spec.js +1 -1
- package/lib/plugins/high-velocity-sales-settings/index.e2e-spec.js.map +1 -1
- package/lib/plugins/high-velocity-sales-settings/index.js +4 -6
- package/lib/plugins/high-velocity-sales-settings/index.js.map +1 -1
- package/lib/plugins/history-tracking/index.e2e-spec.js +3 -4
- package/lib/plugins/history-tracking/index.e2e-spec.js.map +1 -1
- package/lib/plugins/history-tracking/index.js +3 -9
- package/lib/plugins/history-tracking/index.js.map +1 -1
- package/lib/plugins/home-page-layouts/index.e2e-spec.js +1 -1
- package/lib/plugins/home-page-layouts/index.e2e-spec.js.map +1 -1
- package/lib/plugins/home-page-layouts/index.js +2 -6
- package/lib/plugins/home-page-layouts/index.js.map +1 -1
- package/lib/plugins/home-page-layouts/index.test.js +1 -1
- package/lib/plugins/home-page-layouts/index.test.js.map +1 -1
- package/lib/plugins/lightning-experience-settings/index.e2e-spec.js +1 -1
- package/lib/plugins/lightning-experience-settings/index.e2e-spec.js.map +1 -1
- package/lib/plugins/linkedin-sales-navigator-settings/index.e2e-spec.js +1 -1
- package/lib/plugins/linkedin-sales-navigator-settings/index.e2e-spec.js.map +1 -1
- package/lib/plugins/omni-channel-settings/index.e2e-spec.js +1 -1
- package/lib/plugins/omni-channel-settings/index.e2e-spec.js.map +1 -1
- package/lib/plugins/opportunity-splits/index.e2e-spec.js +1 -1
- package/lib/plugins/opportunity-splits/index.e2e-spec.js.map +1 -1
- package/lib/plugins/permission-sets/index.e2e-spec.js +1 -1
- package/lib/plugins/permission-sets/index.e2e-spec.js.map +1 -1
- package/lib/plugins/permission-sets/service-presence-status/index.js +2 -6
- package/lib/plugins/permission-sets/service-presence-status/index.js.map +1 -1
- package/lib/plugins/picklists/field-dependencies/index.js +3 -6
- package/lib/plugins/picklists/field-dependencies/index.js.map +1 -1
- package/lib/plugins/picklists/field-dependencies/index.test.js +1 -1
- package/lib/plugins/picklists/field-dependencies/index.test.js.map +1 -1
- package/lib/plugins/picklists/index.e2e-spec.js +4 -5
- package/lib/plugins/picklists/index.e2e-spec.js.map +1 -1
- package/lib/plugins/picklists/index.js +7 -8
- package/lib/plugins/picklists/index.js.map +1 -1
- package/lib/plugins/record-types/index.e2e-spec.js +2 -3
- package/lib/plugins/record-types/index.e2e-spec.js.map +1 -1
- package/lib/plugins/record-types/index.js +8 -10
- package/lib/plugins/record-types/index.js.map +1 -1
- package/lib/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.js +1 -1
- package/lib/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.js.map +1 -1
- package/lib/plugins/relate-contact-to-multiple-accounts/index.js +2 -2
- package/lib/plugins/relate-contact-to-multiple-accounts/index.js.map +1 -1
- package/lib/plugins/salesforce-cpq-config/index.e2e-spec.js +1 -1
- package/lib/plugins/salesforce-cpq-config/index.e2e-spec.js.map +1 -1
- package/lib/plugins/salesforce-to-salesforce/index.e2e-spec.js +1 -1
- package/lib/plugins/salesforce-to-salesforce/index.e2e-spec.js.map +1 -1
- package/lib/plugins/salesforce-to-salesforce/index.js +1 -2
- package/lib/plugins/salesforce-to-salesforce/index.js.map +1 -1
- package/lib/plugins/security/authentication-configuration/index.e2e-spec.js +2 -3
- package/lib/plugins/security/authentication-configuration/index.e2e-spec.js.map +1 -1
- package/lib/plugins/security/certificate-and-key-management/index.e2e-spec.js +2 -5
- package/lib/plugins/security/certificate-and-key-management/index.e2e-spec.js.map +1 -1
- package/lib/plugins/security/certificate-and-key-management/index.js +2 -7
- package/lib/plugins/security/certificate-and-key-management/index.js.map +1 -1
- package/lib/plugins/security/certificate-and-key-management/index.test.js +1 -1
- package/lib/plugins/security/certificate-and-key-management/index.test.js.map +1 -1
- package/lib/plugins/service-channels/capacity/index.js +2 -5
- package/lib/plugins/service-channels/capacity/index.js.map +1 -1
- package/lib/plugins/service-channels/index.e2e-spec.js +5 -6
- package/lib/plugins/service-channels/index.e2e-spec.js.map +1 -1
- package/lib/plugins/slack/index.e2e-spec.js +1 -1
- package/lib/plugins/slack/index.e2e-spec.js.map +1 -1
- package/lib/plugins/user-access-policies/index.e2e-spec.js +1 -1
- package/lib/plugins/user-access-policies/index.e2e-spec.js.map +1 -1
- package/lib/plugins/user-access-policies/index.js +1 -1
- package/lib/plugins/user-access-policies/index.js.map +1 -1
- package/oclif.manifest.json +66 -70
- package/package.json +1 -1
- package/lib/commands/browserforce/plan.d.ts +0 -10
- package/lib/commands/browserforce/plan.js +0 -56
- package/lib/commands/browserforce/plan.js.map +0 -1
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ Apply the config:
|
|
|
47
47
|
```console
|
|
48
48
|
$ sf browserforce apply -f ./config/currency.json --target-org myOrg@example.com
|
|
49
49
|
logging in... done
|
|
50
|
-
Applying
|
|
50
|
+
Applying config file ./config/currency.json to org myOrg@example.com
|
|
51
51
|
[CompanyInformation] retrieving state... done
|
|
52
52
|
[CompanyInformation] changing 'defaultCurrencyIsoCode' to '"English (South Africa) - ZAR"'... done
|
|
53
53
|
logging out... done
|
|
@@ -124,8 +124,7 @@ USAGE
|
|
|
124
124
|
$ sf browserforce COMMAND
|
|
125
125
|
|
|
126
126
|
COMMANDS
|
|
127
|
-
browserforce apply apply a plan from a
|
|
128
|
-
browserforce plan retrieve state and generate plan file
|
|
127
|
+
browserforce apply apply a plan from a config file
|
|
129
128
|
browserforce playwright access the Playwright CLI
|
|
130
129
|
```
|
|
131
130
|
|
|
@@ -135,7 +134,7 @@ Both the `apply` and `plan` commands expect a config file and a target username
|
|
|
135
134
|
|
|
136
135
|
- `PLAYWRIGHT_BROWSER_CHANNEL`: let Playwright figure out the path to a browser (`chromium` or `chrome`)
|
|
137
136
|
- `PLAYWRIGHT_EXECUTABLE_PATH` or `CHROME_BIN`: point Playwright to a specific browser executable (e.g. `/usr/bin/google-chrome`)
|
|
138
|
-
- `
|
|
137
|
+
- `BROWSERFORCE_HEADLESS`: run in headless mode (default: `true`)
|
|
139
138
|
- `BROWSERFORCE_NAVIGATION_TIMEOUT_MS`: adjustable for slow internet connections (default: `90000`)
|
|
140
139
|
- `BROWSERFORCE_RETRY_MAX_RETRIES`: number of retries on failures opening a page (default: `4`)
|
|
141
140
|
- `BROWSERFORCE_RETRY_TIMEOUT_MS`: initial time between retries in exponential mode (default: `4000`)
|
|
@@ -4,12 +4,23 @@ export declare abstract class BrowserforceCommand<T> extends SfCommand<T> {
|
|
|
4
4
|
static baseFlags: {
|
|
5
5
|
'target-org': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
6
|
definitionfile: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
headless: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
'slow-mo': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
timeout: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
trace: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
exe: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
channel: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
'max-retries': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
'retry-timeout': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
16
|
'flags-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
17
|
};
|
|
11
|
-
protected
|
|
18
|
+
protected browserforce: Browserforce;
|
|
12
19
|
protected settings: any[];
|
|
20
|
+
protected retryConfig?: {
|
|
21
|
+
retries: number;
|
|
22
|
+
minTimeout: number;
|
|
23
|
+
};
|
|
13
24
|
init(): Promise<void>;
|
|
14
25
|
finally(err?: Error): Promise<void>;
|
|
15
26
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Flags, SfCommand, Ux } from '@salesforce/sf-plugins-core';
|
|
2
2
|
import { promises } from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
+
import { chromium } from 'playwright';
|
|
4
5
|
import { Browserforce } from './browserforce.js';
|
|
5
6
|
import { ConfigParser } from './config-parser.js';
|
|
6
7
|
import { handleDeprecations } from './plugins/deprecated.js';
|
|
@@ -11,21 +12,69 @@ export class BrowserforceCommand extends SfCommand {
|
|
|
11
12
|
'target-org': Flags.requiredOrg(),
|
|
12
13
|
definitionfile: Flags.string({
|
|
13
14
|
char: 'f',
|
|
14
|
-
description: 'path to a browserforce
|
|
15
|
+
description: 'path to a browserforce config file',
|
|
15
16
|
}),
|
|
16
|
-
|
|
17
|
-
char: '
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
'dry-run': Flags.boolean({
|
|
18
|
+
char: 'd',
|
|
19
|
+
description: 'dry run',
|
|
20
|
+
env: 'BROWSERFORCE_DRY_RUN',
|
|
20
21
|
}),
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// browser configuration
|
|
23
|
+
headless: Flags.boolean({
|
|
24
|
+
helpGroup: 'Browser Configuration',
|
|
25
|
+
summary: 'run in headless mode (default: true)',
|
|
26
|
+
allowNo: true,
|
|
27
|
+
env: 'BROWSERFORCE_HEADLESS',
|
|
28
|
+
default: !(process.env.BROWSER_DEBUG === 'true'), // for backwards-compatibility
|
|
29
|
+
}),
|
|
30
|
+
'slow-mo': Flags.integer({
|
|
31
|
+
helpGroup: 'Browser Configuration',
|
|
32
|
+
summary: 'slow motion in milliseconds (default: 0)',
|
|
33
|
+
env: 'BROWSERFORCE_SLOWMO',
|
|
34
|
+
default: Number(process.env.BROWSER_SLOWMO ?? '0'), // for backwards-compatibility
|
|
35
|
+
}),
|
|
36
|
+
timeout: Flags.integer({
|
|
37
|
+
helpGroup: 'Browser Configuration',
|
|
38
|
+
summary: 'the default navigation timeout in milliseconds',
|
|
39
|
+
env: 'BROWSERFORCE_NAVIGATION_TIMEOUT_MS',
|
|
40
|
+
default: 90_000,
|
|
41
|
+
}),
|
|
42
|
+
trace: Flags.boolean({
|
|
43
|
+
helpGroup: 'Browser Configuration',
|
|
44
|
+
summary: 'create a playwright trace',
|
|
45
|
+
description: 'The trace-date.zip file can be viewed with sf browserforce playwright show-trace trace-date.zip.',
|
|
46
|
+
env: 'PLAYWRIGHT_TRACE',
|
|
47
|
+
}),
|
|
48
|
+
exe: Flags.string({
|
|
49
|
+
helpGroup: 'Browser Configuration',
|
|
50
|
+
summary: 'the path to a browser executable',
|
|
51
|
+
description: 'on GitHub Actions with ubuntu-latest, this is set to /usr/bin/google-chrome',
|
|
52
|
+
env: 'PLAYWRIGHT_EXECUTABLE_PATH',
|
|
53
|
+
default: process.env.CHROME_BIN?.length ? process.env.CHROME_BIN : undefined,
|
|
54
|
+
}),
|
|
55
|
+
channel: Flags.string({
|
|
56
|
+
helpGroup: 'Browser Configuration',
|
|
57
|
+
summary: 'the channel (e.g. chromium or chrome) to use',
|
|
58
|
+
description: 'Playwright will try to figure out the path to the browser executable automatically.',
|
|
59
|
+
env: 'PLAYWRIGHT_BROWSER_CHANNEL',
|
|
60
|
+
}),
|
|
61
|
+
// retry config
|
|
62
|
+
'max-retries': Flags.integer({
|
|
63
|
+
helpGroup: 'Retry Configuration',
|
|
64
|
+
summary: 'the maximum number of retries for retryable actions',
|
|
65
|
+
env: 'BROWSERFORCE_RETRY_MAX_RETRIES',
|
|
66
|
+
default: 6,
|
|
67
|
+
}),
|
|
68
|
+
'retry-timeout': Flags.integer({
|
|
69
|
+
helpGroup: 'Retry Configuration',
|
|
70
|
+
summary: 'the inital timeout in milliseconds for retryable actions (exponentially increased)',
|
|
71
|
+
env: 'BROWSERFORCE_RETRY_TIMEOUT_MS',
|
|
72
|
+
default: 4_000,
|
|
25
73
|
}),
|
|
26
74
|
};
|
|
27
|
-
|
|
75
|
+
browserforce;
|
|
28
76
|
settings;
|
|
77
|
+
retryConfig;
|
|
29
78
|
async init() {
|
|
30
79
|
await super.init();
|
|
31
80
|
const { flags } = await this.parse({
|
|
@@ -38,27 +87,75 @@ export class BrowserforceCommand extends SfCommand {
|
|
|
38
87
|
definition = JSON.parse(definitionFileData);
|
|
39
88
|
}
|
|
40
89
|
catch (err) {
|
|
41
|
-
throw new Error('Failed parsing
|
|
90
|
+
throw new Error('Failed parsing config file');
|
|
42
91
|
}
|
|
43
92
|
}
|
|
44
93
|
handleDeprecations(definition);
|
|
45
|
-
// TODO: use require.resolve to dynamically load plugins from npm packages
|
|
46
94
|
this.settings = ConfigParser.parse(DRIVERS, definition);
|
|
47
|
-
|
|
95
|
+
const connection = flags['target-org'].getConnection();
|
|
96
|
+
const browserContext = await createBrowserContextFromFlags(flags);
|
|
97
|
+
const options = {
|
|
98
|
+
logger: new Ux({ jsonEnabled: this.jsonEnabled() }),
|
|
99
|
+
...createRetryOptionsFromFlags(flags),
|
|
100
|
+
};
|
|
101
|
+
this.browserforce = new Browserforce(connection, browserContext, options);
|
|
48
102
|
this.spinner.start('logging in');
|
|
49
|
-
await this.
|
|
103
|
+
await this.browserforce.browserContext.tracing.group('login');
|
|
104
|
+
await this.browserforce.login();
|
|
50
105
|
this.spinner.stop();
|
|
106
|
+
await this.browserforce.browserContext.tracing.groupEnd();
|
|
51
107
|
}
|
|
52
108
|
async finally(err) {
|
|
53
109
|
this.spinner.stop(err?.toString());
|
|
54
110
|
if (err?.cause instanceof Error) {
|
|
55
111
|
this.logToStderr(`Cause: ${err.cause.toString()}`);
|
|
56
112
|
}
|
|
57
|
-
if (this.
|
|
113
|
+
if (this.browserforce) {
|
|
58
114
|
this.spinner.start('logging out');
|
|
59
|
-
|
|
115
|
+
try {
|
|
116
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
117
|
+
const tracePath = `trace-${timestamp}.zip`;
|
|
118
|
+
await this.browserforce.browserContext.tracing.stop({ path: tracePath });
|
|
119
|
+
this.logToStderr(`Playwright trace saved to: ${tracePath}`);
|
|
120
|
+
}
|
|
121
|
+
catch (_) { }
|
|
122
|
+
await this.browserforce.browserContext.browser().close();
|
|
60
123
|
this.spinner.stop();
|
|
61
124
|
}
|
|
62
125
|
}
|
|
63
126
|
}
|
|
127
|
+
async function createBrowserContextFromFlags(flags) {
|
|
128
|
+
const browser = await chromium.launch({
|
|
129
|
+
...(flags.channel
|
|
130
|
+
? {
|
|
131
|
+
channel: flags.channel,
|
|
132
|
+
}
|
|
133
|
+
: {}),
|
|
134
|
+
...(flags.exe
|
|
135
|
+
? {
|
|
136
|
+
executablePath: flags.exe,
|
|
137
|
+
}
|
|
138
|
+
: {}),
|
|
139
|
+
headless: flags.headless,
|
|
140
|
+
slowMo: flags['slow-mo'],
|
|
141
|
+
});
|
|
142
|
+
const browserContext = await browser.newContext({
|
|
143
|
+
viewport: { width: 1280, height: 1536 },
|
|
144
|
+
});
|
|
145
|
+
browserContext.setDefaultNavigationTimeout(flags.timeout);
|
|
146
|
+
if (flags.trace) {
|
|
147
|
+
await browserContext.tracing.start({
|
|
148
|
+
screenshots: true,
|
|
149
|
+
snapshots: true,
|
|
150
|
+
sources: true,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return browserContext;
|
|
154
|
+
}
|
|
155
|
+
function createRetryOptionsFromFlags(flags) {
|
|
156
|
+
return {
|
|
157
|
+
retries: flags['max-retries'],
|
|
158
|
+
minTimeout: flags['retry-timeout'],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
64
161
|
//# sourceMappingURL=browserforce-command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserforce-command.js","sourceRoot":"","sources":["../src/browserforce-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAE9C,MAAM,OAAgB,mBAAuB,SAAQ,SAAY;IAC/D,MAAM,CAAC,SAAS,GAAG;QACjB,GAAG,SAAS,CAAC,SAAS;QACtB,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE;QACjC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC;YAC3B,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"browserforce-command.js","sourceRoot":"","sources":["../src/browserforce-command.ts"],"names":[],"mappings":"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"}
|
package/lib/browserforce.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type Connection } from '@salesforce/core';
|
|
2
2
|
import { type Ux } from '@salesforce/sf-plugins-core';
|
|
3
|
-
import {
|
|
3
|
+
import { Options as RetryOptions } from 'p-retry';
|
|
4
|
+
import { type BrowserContext, type FrameLocator, type Page } from 'playwright';
|
|
4
5
|
export type SalesforceUrlPath = `/${string}`;
|
|
6
|
+
export type BrowserforceOptions = {
|
|
7
|
+
logger?: Ux;
|
|
8
|
+
retry?: RetryOptions;
|
|
9
|
+
};
|
|
5
10
|
export declare class Browserforce {
|
|
6
|
-
|
|
11
|
+
connection: Connection;
|
|
12
|
+
browserContext: BrowserContext;
|
|
7
13
|
logger?: Ux;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
constructor(org: Org, logger?: Ux);
|
|
14
|
+
private lightningSetupUrl;
|
|
15
|
+
private retryConfig?;
|
|
16
|
+
constructor(connection: Connection, browserContext: BrowserContext, options?: BrowserforceOptions);
|
|
12
17
|
login(): Promise<Browserforce>;
|
|
13
|
-
logout(): Promise<Browserforce>;
|
|
14
|
-
getNewPage(): Promise<Page>;
|
|
15
18
|
openPage(urlPath: SalesforceUrlPath): Promise<Page>;
|
|
16
19
|
waitForSelectorInFrameOrPage(page: Page, selector: string): Promise<Page | FrameLocator>;
|
|
17
20
|
getMyDomain(): string | null;
|
|
@@ -20,6 +23,6 @@ export declare class Browserforce {
|
|
|
20
23
|
* @returns the setup url (e.g. https://[MyDomainName].my.salesforce-setup.com)
|
|
21
24
|
*/
|
|
22
25
|
getLightningSetupUrl(): Promise<string>;
|
|
26
|
+
retry<T>(input: (attemptCount: number) => PromiseLike<T> | T): Promise<T>;
|
|
23
27
|
}
|
|
24
28
|
export declare function waitForPageErrors(page: Page, timeout?: number): Promise<void>;
|
|
25
|
-
export declare function retry<T>(input: (attemptCount: number) => PromiseLike<T> | T): Promise<T>;
|
package/lib/browserforce.js
CHANGED
|
@@ -51,57 +51,34 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
53
|
import pRetry from 'p-retry';
|
|
54
|
-
import { chromium } from 'playwright';
|
|
55
54
|
import { LoginPage } from './pages/login.js';
|
|
56
55
|
const VF_IFRAME_SELECTOR = 'force-aloha-page iframe[name^=vfFrameId]';
|
|
57
56
|
export class Browserforce {
|
|
58
|
-
|
|
57
|
+
connection;
|
|
58
|
+
browserContext;
|
|
59
59
|
logger;
|
|
60
|
-
browser;
|
|
61
|
-
context;
|
|
62
60
|
lightningSetupUrl;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
61
|
+
retryConfig;
|
|
62
|
+
constructor(connection, browserContext, options) {
|
|
63
|
+
this.connection = connection;
|
|
64
|
+
this.browserContext = browserContext;
|
|
65
|
+
this.logger = options?.logger;
|
|
66
|
+
this.retryConfig = options?.retry ?? {
|
|
67
|
+
retries: 0,
|
|
68
|
+
};
|
|
66
69
|
}
|
|
67
70
|
async login() {
|
|
68
71
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
69
72
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
: {}),
|
|
77
|
-
...(process.env.CHROME_BIN
|
|
78
|
-
? {
|
|
79
|
-
// on GitHub Actions with ubuntu-latest, this is set to /usr/bin/google-chrome
|
|
80
|
-
executablePath: process.env.CHROME_BIN,
|
|
81
|
-
}
|
|
82
|
-
: {}),
|
|
83
|
-
...(process.env.PLAYWRIGHT_EXECUTABLE_PATH
|
|
84
|
-
? {
|
|
85
|
-
executablePath: process.env.PLAYWRIGHT_EXECUTABLE_PATH,
|
|
86
|
-
}
|
|
87
|
-
: {}),
|
|
88
|
-
headless: !(process.env.BROWSER_DEBUG === 'true'),
|
|
89
|
-
slowMo: parseInt(process.env.BROWSER_SLOWMO, 10) ?? 0,
|
|
90
|
-
});
|
|
91
|
-
this.context = await this.browser.newContext({
|
|
92
|
-
viewport: { width: 1280, height: 1536 },
|
|
93
|
-
});
|
|
94
|
-
// Start tracing if PLAYWRIGHT_TRACE is set
|
|
95
|
-
if (process.env.PLAYWRIGHT_TRACE === 'true') {
|
|
96
|
-
await this.context.tracing.start({
|
|
97
|
-
screenshots: true,
|
|
98
|
-
snapshots: true,
|
|
99
|
-
sources: true,
|
|
100
|
-
});
|
|
73
|
+
try {
|
|
74
|
+
await this.connection.refreshAuth();
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
throw new Error('login failed', { cause: e });
|
|
101
78
|
}
|
|
102
|
-
const page = __addDisposableResource(env_1, await this.
|
|
79
|
+
const page = __addDisposableResource(env_1, await this.browserContext.newPage(), true);
|
|
103
80
|
const loginPage = new LoginPage(page);
|
|
104
|
-
await loginPage.login(this.
|
|
81
|
+
await loginPage.login(this.connection);
|
|
105
82
|
return this;
|
|
106
83
|
}
|
|
107
84
|
catch (e_1) {
|
|
@@ -114,60 +91,24 @@ export class Browserforce {
|
|
|
114
91
|
await result_1;
|
|
115
92
|
}
|
|
116
93
|
}
|
|
117
|
-
async logout() {
|
|
118
|
-
if (this.browser) {
|
|
119
|
-
// Stop tracing and save if it was started
|
|
120
|
-
if (process.env.PLAYWRIGHT_TRACE === 'true') {
|
|
121
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
122
|
-
const tracePath = `trace-${timestamp}.zip`;
|
|
123
|
-
await this.context.tracing.stop({ path: tracePath });
|
|
124
|
-
if (this.logger) {
|
|
125
|
-
this.logger.log(`Playwright trace saved to: ${tracePath}`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
await this.browser.close();
|
|
129
|
-
}
|
|
130
|
-
return this;
|
|
131
|
-
}
|
|
132
|
-
async getNewPage() {
|
|
133
|
-
const page = await this.context.newPage();
|
|
134
|
-
page.setDefaultNavigationTimeout(parseInt(process.env.BROWSERFORCE_NAVIGATION_TIMEOUT_MS ?? '90000', 10));
|
|
135
|
-
return page;
|
|
136
|
-
}
|
|
137
94
|
// path instead of url
|
|
138
95
|
async openPage(urlPath) {
|
|
139
96
|
let page;
|
|
140
|
-
const result = await
|
|
141
|
-
page = await this.
|
|
97
|
+
const result = await this.retry(async () => {
|
|
98
|
+
page = await this.browserContext.newPage();
|
|
142
99
|
const setupUrl = urlPath.startsWith('/lightning') ? await this.getLightningSetupUrl() : this.getInstanceUrl();
|
|
143
100
|
const url = `${setupUrl}${urlPath}`;
|
|
144
101
|
const response = await page.goto(url);
|
|
145
102
|
if (response && !response.ok()) {
|
|
146
103
|
await Promise.race([
|
|
147
|
-
waitForPageErrors(page, 5_000),
|
|
148
104
|
(async () => {
|
|
149
|
-
await page.waitForTimeout(
|
|
150
|
-
throw new Error(`${response.status()}: ${response.
|
|
105
|
+
await page.waitForTimeout(5_000);
|
|
106
|
+
throw new Error(`${response.status()}: ${response.url()}`);
|
|
151
107
|
})(),
|
|
108
|
+
waitForPageErrors(page, 6_000),
|
|
152
109
|
]);
|
|
153
110
|
}
|
|
154
111
|
return page;
|
|
155
|
-
}, {
|
|
156
|
-
onFailedAttempt: async (context) => {
|
|
157
|
-
if (this.logger) {
|
|
158
|
-
this.logger.warn(`retrying ${context.retriesLeft} more time(s) because of "${context.error}"`);
|
|
159
|
-
}
|
|
160
|
-
if (page) {
|
|
161
|
-
try {
|
|
162
|
-
await page.close();
|
|
163
|
-
}
|
|
164
|
-
catch (e) {
|
|
165
|
-
// not handled
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
retries: parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES ?? '4', 10),
|
|
170
|
-
minTimeout: parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS ?? '4000', 10),
|
|
171
112
|
});
|
|
172
113
|
return result;
|
|
173
114
|
}
|
|
@@ -197,7 +138,7 @@ export class Browserforce {
|
|
|
197
138
|
}
|
|
198
139
|
getInstanceUrl() {
|
|
199
140
|
// sometimes the instanceUrl includes a trailing slash
|
|
200
|
-
return this.
|
|
141
|
+
return this.connection.instanceUrl?.replace(/\/$/, '');
|
|
201
142
|
}
|
|
202
143
|
/**
|
|
203
144
|
* @returns the setup url (e.g. https://[MyDomainName].my.salesforce-setup.com)
|
|
@@ -206,7 +147,7 @@ export class Browserforce {
|
|
|
206
147
|
if (!this.lightningSetupUrl) {
|
|
207
148
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
208
149
|
try {
|
|
209
|
-
const page = __addDisposableResource(env_2, await this.
|
|
150
|
+
const page = __addDisposableResource(env_2, await this.browserContext.newPage(), true);
|
|
210
151
|
const lightningResponse = await page.goto(`${this.getInstanceUrl()}/lightning/setup/SetupOneHome/home`);
|
|
211
152
|
this.lightningSetupUrl = new URL(lightningResponse.url()).origin;
|
|
212
153
|
}
|
|
@@ -222,6 +163,15 @@ export class Browserforce {
|
|
|
222
163
|
}
|
|
223
164
|
return this.lightningSetupUrl;
|
|
224
165
|
}
|
|
166
|
+
async retry(input) {
|
|
167
|
+
const res = await pRetry(input, {
|
|
168
|
+
...this.retryConfig,
|
|
169
|
+
onFailedAttempt: (context) => {
|
|
170
|
+
this.logger?.warn(`retrying ${context.retriesLeft} more time(s) because of "${context.error}"`);
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
return res;
|
|
174
|
+
}
|
|
225
175
|
}
|
|
226
176
|
export async function waitForPageErrors(page, timeout = 90_000) {
|
|
227
177
|
const anyErrorsLocator = page.locator(`#error, #errorTitle, #errorDesc, #validationError, div.errorMsg`);
|
|
@@ -234,14 +184,4 @@ export async function waitForPageErrors(page, timeout = 90_000) {
|
|
|
234
184
|
throw new Error(errorMessages.join('\n'));
|
|
235
185
|
}
|
|
236
186
|
}
|
|
237
|
-
export async function retry(input) {
|
|
238
|
-
const res = await pRetry(input, {
|
|
239
|
-
onFailedAttempt: (context) => {
|
|
240
|
-
console.warn(`retrying ${context.retriesLeft} more time(s) because of "${context.error}"`);
|
|
241
|
-
},
|
|
242
|
-
retries: parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES ?? '6', 10),
|
|
243
|
-
minTimeout: parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS ?? '4000', 10),
|
|
244
|
-
});
|
|
245
|
-
return res;
|
|
246
|
-
}
|
|
247
187
|
//# sourceMappingURL=browserforce.js.map
|
package/lib/browserforce.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserforce.js","sourceRoot":"","sources":["../src/browserforce.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"browserforce.js","sourceRoot":"","sources":["../src/browserforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BrowserforceCommand } from '../../browserforce-command.js';
|
|
2
2
|
export class BrowserforceApply extends BrowserforceCommand {
|
|
3
|
-
static description = 'apply a plan from a
|
|
3
|
+
static description = 'apply a plan from a config file';
|
|
4
4
|
static examples = [
|
|
5
5
|
`$ <%= config.bin %> <%= command.id %> -f ./config/currency.json --target-org myOrg@example.com
|
|
6
6
|
logging in... done
|
|
7
|
-
Applying
|
|
7
|
+
Applying config file ./config/currency.json to org myOrg@example.com
|
|
8
8
|
[CompanyInformation] retrieving state... done
|
|
9
9
|
[CompanyInformation] changing 'defaultCurrencyIsoCode' to '"English (South Africa) - ZAR"'... done
|
|
10
10
|
logging out... done
|
|
@@ -12,11 +12,12 @@ export class BrowserforceApply extends BrowserforceCommand {
|
|
|
12
12
|
];
|
|
13
13
|
async run() {
|
|
14
14
|
const { flags } = await this.parse(BrowserforceApply);
|
|
15
|
-
this.log(`Applying
|
|
15
|
+
this.log(`Applying config file ${flags.definitionfile} to org ${flags['target-org'].getUsername()}`);
|
|
16
16
|
for (const setting of this.settings) {
|
|
17
17
|
const driver = setting.Driver;
|
|
18
|
-
const instance = new driver(this.
|
|
18
|
+
const instance = new driver(this.browserforce);
|
|
19
19
|
this.spinner.start(`[${driver.name}] retrieving state`);
|
|
20
|
+
await this.browserforce.browserContext.tracing.group(driver.name);
|
|
20
21
|
let state;
|
|
21
22
|
try {
|
|
22
23
|
state = await instance.retrieve(setting.value);
|
|
@@ -27,20 +28,24 @@ export class BrowserforceApply extends BrowserforceCommand {
|
|
|
27
28
|
}
|
|
28
29
|
this.spinner.stop();
|
|
29
30
|
const diff = instance.diff(state, setting.value);
|
|
31
|
+
const action = flags['dry-run'] ? 'would change' : 'changing';
|
|
30
32
|
if (diff !== undefined) {
|
|
31
33
|
this.spinner.start(`[${driver.name}] ${Object.keys(diff)
|
|
32
34
|
.map((key) => {
|
|
33
|
-
return
|
|
35
|
+
return `${action} '${key}' to '${JSON.stringify(diff[key])}'`;
|
|
34
36
|
})
|
|
35
37
|
.join('\n')}`);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
if (!flags['dry-run']) {
|
|
39
|
+
try {
|
|
40
|
+
await instance.apply(diff);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
this.spinner.stop('failed');
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
this.spinner.stop();
|
|
38
47
|
}
|
|
39
|
-
|
|
40
|
-
this.spinner.stop('failed');
|
|
41
|
-
throw err;
|
|
42
|
-
}
|
|
43
|
-
this.spinner.stop();
|
|
48
|
+
await this.browserforce.browserContext.tracing.groupEnd();
|
|
44
49
|
}
|
|
45
50
|
else {
|
|
46
51
|
this.log(`[${driver.name}] no action necessary`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/commands/browserforce/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAMpE,MAAM,OAAO,iBAAkB,SAAQ,mBAA8C;IAC5E,MAAM,CAAC,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/commands/browserforce/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAMpE,MAAM,OAAO,iBAAkB,SAAQ,mBAA8C;IAC5E,MAAM,CAAC,WAAW,GAAG,iCAAiC,CAAC;IACvD,MAAM,CAAC,QAAQ,GAAG;QACvB;;;;;;GAMD;KACA,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,cAAc,WAAW,KAAK,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACrG,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,oBAAoB,CAAC,CAAC;YACxD,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAClE,IAAI,KAAK,CAAC;YACV,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;YAC9D,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,IAAI,CAAC,OAAO,CAAC,KAAK,CAChB,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;qBAClC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;oBACX,OAAO,GAAG,MAAM,KAAK,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;gBAChE,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;gBACF,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;oBACtB,IAAI,CAAC;wBACH,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC7B,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;wBAC5B,MAAM,GAAG,CAAC;oBACZ,CAAC;oBACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBACtB,CAAC;gBACD,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,uBAAuB,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QACD,OAAO;YACL,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC"}
|
package/lib/pages/login.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Connection } from '@salesforce/core';
|
|
2
2
|
import { type Page } from 'playwright';
|
|
3
3
|
export declare class LoginPage {
|
|
4
4
|
private page;
|
|
5
5
|
constructor(page: Page);
|
|
6
|
-
login(
|
|
6
|
+
login(connection: Connection): Promise<this>;
|
|
7
7
|
}
|
package/lib/pages/login.js
CHANGED
|
@@ -6,15 +6,8 @@ export class LoginPage {
|
|
|
6
6
|
constructor(page) {
|
|
7
7
|
this.page = page;
|
|
8
8
|
}
|
|
9
|
-
async login(
|
|
10
|
-
|
|
11
|
-
await org.refreshAuth();
|
|
12
|
-
}
|
|
13
|
-
catch (_) {
|
|
14
|
-
throw new Error('login failed');
|
|
15
|
-
}
|
|
16
|
-
const conn = org.getConnection();
|
|
17
|
-
await this.page.goto(`${conn.instanceUrl.replace(/\/$/, '')}${FRONT_DOOR_PATH}?sid=${conn.accessToken}&retURL=${encodeURIComponent(POST_LOGIN_PATH)}`);
|
|
9
|
+
async login(connection) {
|
|
10
|
+
await this.page.goto(`${connection.instanceUrl.replace(/\/$/, '')}${FRONT_DOOR_PATH}?sid=${connection.accessToken}&retURL=${encodeURIComponent(POST_LOGIN_PATH)}`);
|
|
18
11
|
await Promise.race([this.page.waitForURL((url) => url.pathname === POST_LOGIN_PATH), waitForPageErrors(this.page)]);
|
|
19
12
|
return this;
|
|
20
13
|
}
|
package/lib/pages/login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/pages/login.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAC/C,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAExD,MAAM,OAAO,SAAS;IACZ,IAAI,CAAO;IAEnB,YAAY,IAAU;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/pages/login.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAC/C,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAExD,MAAM,OAAO,SAAS;IACZ,IAAI,CAAO;IAEnB,YAAY,IAAU;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAsB;QAChC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAClB,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,eAAe,QAC5D,UAAU,CAAC,WACb,WAAW,kBAAkB,CAAC,eAAe,CAAC,EAAE,CACjD,CAAC;QACF,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,KAAK,eAAe,CAAC,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpH,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
package/lib/plugin.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { Org } from '@salesforce/core';
|
|
2
1
|
import { Browserforce } from './browserforce.js';
|
|
3
2
|
export declare abstract class BrowserforcePlugin {
|
|
4
3
|
protected browserforce: Browserforce;
|
|
5
|
-
protected org: Org;
|
|
6
4
|
constructor(browserforce: Browserforce);
|
|
7
5
|
abstract retrieve(definition?: unknown): Promise<unknown>;
|
|
8
6
|
/**
|