@cerios/salesforce-sobjectly 1.1.0 → 1.2.0
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 +20 -12
- package/dist/cli.cjs +2 -2
- package/dist/cli.mjs +2 -2
- package/dist/{codegen-C6MEYiWo.mjs → codegen-0L2ebG9j.mjs} +202 -75
- package/dist/codegen-0L2ebG9j.mjs.map +1 -0
- package/dist/{codegen-Bylrt2Ju.cjs → codegen-Daud-Grz.cjs} +214 -71
- package/dist/codegen-Daud-Grz.cjs.map +1 -0
- package/dist/codegen.cjs +3 -1
- package/dist/codegen.d.cts +98 -31
- package/dist/codegen.d.mts +98 -31
- package/dist/codegen.mjs +3 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +15 -4
- package/dist/index.d.mts +15 -4
- package/dist/index.mjs +1 -1
- package/dist/{sf-cli-_Ua-M_Zi.mjs → sf-cli-D2PgjErx.mjs} +33 -13
- package/dist/sf-cli-D2PgjErx.mjs.map +1 -0
- package/dist/{sf-cli-R6LHwqoo.cjs → sf-cli-S2BrCbik.cjs} +33 -13
- package/dist/sf-cli-S2BrCbik.cjs.map +1 -0
- package/package.json +1 -1
- package/sobjectly.config.schema.json +92 -16
- package/dist/codegen-Bylrt2Ju.cjs.map +0 -1
- package/dist/codegen-C6MEYiWo.mjs.map +0 -1
- package/dist/sf-cli-R6LHwqoo.cjs.map +0 -1
- package/dist/sf-cli-_Ua-M_Zi.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -54,12 +54,19 @@ export default defineConfig({
|
|
|
54
54
|
apiVersion: "v66.0",
|
|
55
55
|
output: "src/generated/sobjects.ts",
|
|
56
56
|
sobjects: ["Account", "Contact", "Case", "User"],
|
|
57
|
-
//
|
|
58
|
-
auth: {
|
|
57
|
+
// Fill these in from process.env (any variable names), a secret store or elsewhere.
|
|
58
|
+
auth: {
|
|
59
|
+
type: "clientCredentials",
|
|
60
|
+
loginUrl: process.env.SF_LOGIN_URL,
|
|
61
|
+
clientId: process.env.SF_CLIENT_ID,
|
|
62
|
+
clientSecret: process.env.SF_CLIENT_SECRET,
|
|
63
|
+
},
|
|
59
64
|
picklists: "union",
|
|
60
65
|
});
|
|
61
66
|
```
|
|
62
67
|
|
|
68
|
+
The variable names are only suggestions; use whatever names your environment already has. A JSON config uses `"${NAME}"` placeholders instead. See [Auth](docs/codegen.md#auth) for every login method.
|
|
69
|
+
|
|
63
70
|
### 2. Generate types for your org
|
|
64
71
|
|
|
65
72
|
```bash
|
|
@@ -79,6 +86,7 @@ const sf = new SalesforceClient<SObjectRegistry>({
|
|
|
79
86
|
clientId: process.env.SF_CLIENT_ID!,
|
|
80
87
|
clientSecret: process.env.SF_CLIENT_SECRET!,
|
|
81
88
|
}),
|
|
89
|
+
// or reuse the config's auth: auth: await loadAuth() from "@cerios/salesforce-sobjectly/codegen"
|
|
82
90
|
});
|
|
83
91
|
|
|
84
92
|
// CRUD
|
|
@@ -107,16 +115,16 @@ for await (const contact of sf.iterate(sf.soql("Contact").select("Id", "Email"))
|
|
|
107
115
|
|
|
108
116
|
## 📖 Documentation
|
|
109
117
|
|
|
110
|
-
| Guide | What's in it
|
|
111
|
-
| ------------------------------------------------------------ |
|
|
112
|
-
| [Authentication](docs/authentication.md) | Salesforce CLI, access tokens, client credentials, JWT bearer, refresh tokens, custom providers
|
|
113
|
-
| [Code generation](docs/codegen.md) | Config reference, type mapping, required fields, picklists, CI usage
|
|
114
|
-
| [SOQL builder](docs/soql.md) | Selecting, relationships, filters, aggregates, pagination, escaping
|
|
115
|
-
| [Composite & collections](docs/composite-and-collections.md) | Composite with references, batch, tree, graph, sObject collections
|
|
116
|
-
| [Approvals, files, reports & more](docs/platform.md) | Record types, picklists, platform events, approvals, quick actions, UI API, files, reports, query plans
|
|
117
|
-
| [Bulk API 2.0](docs/bulk.md) | Ingest jobs, query jobs, CSV handling
|
|
118
|
-
| [Transports](docs/transports.md) | Custom HTTP clients (axios and Playwright examples), streaming, hooks, retries, timeouts
|
|
119
|
-
| [Endpoint coverage](docs/endpoints.md) | Which Salesforce REST resources have typed helpers
|
|
118
|
+
| Guide | What's in it |
|
|
119
|
+
| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
|
|
120
|
+
| [Authentication](docs/authentication.md) | Salesforce CLI, access tokens, client credentials, JWT bearer, refresh tokens, custom providers |
|
|
121
|
+
| [Code generation](docs/codegen.md) | Config reference, type mapping, required fields, picklists, CI usage |
|
|
122
|
+
| [SOQL builder](docs/soql.md) | Selecting, relationships, filters, aggregates, pagination, escaping |
|
|
123
|
+
| [Composite & collections](docs/composite-and-collections.md) | Composite with references, batch, tree, graph, sObject collections |
|
|
124
|
+
| [Approvals, files, reports & more](docs/platform.md) | Record types, picklists, platform events, approvals, quick actions, UI API, files, reports, query plans |
|
|
125
|
+
| [Bulk API 2.0](docs/bulk.md) | Ingest jobs, query jobs, CSV handling |
|
|
126
|
+
| [Transports](docs/transports.md) | Custom HTTP clients (axios and Playwright examples), streaming, hooks and request logging, retries, timeouts |
|
|
127
|
+
| [Endpoint coverage](docs/endpoints.md) | Which Salesforce REST resources have typed helpers |
|
|
120
128
|
|
|
121
129
|
## 🧭 API Overview
|
|
122
130
|
|
package/dist/cli.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_sf_cli = require("./sf-cli-
|
|
3
|
-
const require_codegen = require("./codegen-
|
|
2
|
+
const require_sf_cli = require("./sf-cli-S2BrCbik.cjs");
|
|
3
|
+
const require_codegen = require("./codegen-Daud-Grz.cjs");
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
let node_path = require("node:path");
|
|
6
6
|
let node_util = require("node:util");
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Lt as __commonJSMin, Mt as init_api_version, Pt as normalizeApiVersion } from "./sf-cli-
|
|
3
|
-
import {
|
|
2
|
+
import { Lt as __commonJSMin, Mt as init_api_version, Pt as normalizeApiVersion } from "./sf-cli-D2PgjErx.mjs";
|
|
3
|
+
import { T as init_validate_config, _ as findConfigFiles, f as runInit, l as init_init, n as generate, o as init_prompter, r as init_codegen, s as readlinePrompter, t as checkGenerated, u as parseSObjects, w as PICKLIST_MODES, y as loadConfig } from "./codegen-0L2ebG9j.mjs";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
6
|
import { parseArgs } from "node:util";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mt as init_api_version, Nt as isApiVersion, Pt as normalizeApiVersion, Rt as __esmMin, d as init_client, i as clientCredentials, n as sfCli, o as init_providers, r as accessToken, s as jwtBearer, t as init_sf_cli, u as SalesforceClient } from "./sf-cli-
|
|
1
|
+
import { Mt as init_api_version, Nt as isApiVersion, Pt as normalizeApiVersion, Rt as __esmMin, d as init_client, i as clientCredentials, n as sfCli, o as init_providers, r as accessToken, s as jwtBearer, t as init_sf_cli, u as SalesforceClient } from "./sf-cli-D2PgjErx.mjs";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
@@ -506,8 +506,17 @@ function validateAuth(value, { json, problem }) {
|
|
|
506
506
|
problem(`auth.type: must be one of ${Object.keys(AUTH_OPTIONS).join(", ")}, got ${show(type)}.`);
|
|
507
507
|
return;
|
|
508
508
|
}
|
|
509
|
-
for (const [key, option] of Object.entries(rest)) if (!allowed.includes(key))
|
|
510
|
-
|
|
509
|
+
for (const [key, option] of Object.entries(rest)) if (!allowed.includes(key)) {
|
|
510
|
+
const valid = allowed.filter((name) => !(name in DEPRECATED_AUTH_OPTIONS));
|
|
511
|
+
problem(`auth.${key}: not an option of "${String(type)}". Valid options: ${valid.join(", ")}.`);
|
|
512
|
+
} else validateAuthOption(key, option, rest, problem);
|
|
513
|
+
}
|
|
514
|
+
function validateAuthOption(key, option, setting, problem) {
|
|
515
|
+
const replacement = DEPRECATED_AUTH_OPTIONS[key];
|
|
516
|
+
if (replacement !== void 0 && replacement in setting) problem(`auth.${key}: use either ${replacement} or ${key}, not both.`);
|
|
517
|
+
else if (replacement !== void 0) {
|
|
518
|
+
if (typeof option !== "string" || option.length === 0) problem(`auth.${key}: must be a non-empty string, got ${show(option)}.`);
|
|
519
|
+
} else if (option !== void 0 && typeof option !== "string") problem(`auth.${key}: must be a string, got ${show(option)}.`);
|
|
511
520
|
}
|
|
512
521
|
function show(value) {
|
|
513
522
|
if (value === void 0) return "undefined";
|
|
@@ -518,7 +527,7 @@ function show(value) {
|
|
|
518
527
|
return typeof value;
|
|
519
528
|
}
|
|
520
529
|
}
|
|
521
|
-
var CodegenConfigError, AUTH_OPTIONS, PICKLIST_MODES, IDENTIFIER, VALIDATORS, CONFIG_OPTIONS;
|
|
530
|
+
var CodegenConfigError, AUTH_OPTIONS, DEPRECATED_AUTH_OPTIONS, PICKLIST_MODES, IDENTIFIER, VALIDATORS, CONFIG_OPTIONS;
|
|
522
531
|
var init_validate_config = __esmMin((() => {
|
|
523
532
|
init_api_version();
|
|
524
533
|
CodegenConfigError = class extends Error {
|
|
@@ -533,12 +542,25 @@ var init_validate_config = __esmMin((() => {
|
|
|
533
542
|
};
|
|
534
543
|
AUTH_OPTIONS = {
|
|
535
544
|
clientCredentials: [
|
|
545
|
+
"loginUrl",
|
|
546
|
+
"clientId",
|
|
547
|
+
"clientSecret",
|
|
536
548
|
"loginUrlEnv",
|
|
537
549
|
"clientIdEnv",
|
|
538
550
|
"clientSecretEnv"
|
|
539
551
|
],
|
|
540
|
-
accessToken: [
|
|
552
|
+
accessToken: [
|
|
553
|
+
"accessToken",
|
|
554
|
+
"instanceUrl",
|
|
555
|
+
"accessTokenEnv",
|
|
556
|
+
"instanceUrlEnv"
|
|
557
|
+
],
|
|
541
558
|
jwtBearer: [
|
|
559
|
+
"loginUrl",
|
|
560
|
+
"clientId",
|
|
561
|
+
"username",
|
|
562
|
+
"privateKey",
|
|
563
|
+
"privateKeyPath",
|
|
542
564
|
"loginUrlEnv",
|
|
543
565
|
"clientIdEnv",
|
|
544
566
|
"usernameEnv",
|
|
@@ -547,6 +569,16 @@ var init_validate_config = __esmMin((() => {
|
|
|
547
569
|
],
|
|
548
570
|
sfCli: ["targetOrg"]
|
|
549
571
|
};
|
|
572
|
+
DEPRECATED_AUTH_OPTIONS = {
|
|
573
|
+
loginUrlEnv: "loginUrl",
|
|
574
|
+
clientIdEnv: "clientId",
|
|
575
|
+
clientSecretEnv: "clientSecret",
|
|
576
|
+
accessTokenEnv: "accessToken",
|
|
577
|
+
instanceUrlEnv: "instanceUrl",
|
|
578
|
+
usernameEnv: "username",
|
|
579
|
+
privateKeyEnv: "privateKey",
|
|
580
|
+
privateKeyPathEnv: "privateKeyPath"
|
|
581
|
+
};
|
|
550
582
|
PICKLIST_MODES = [
|
|
551
583
|
"union",
|
|
552
584
|
"string",
|
|
@@ -598,25 +630,6 @@ var init_validate_config = __esmMin((() => {
|
|
|
598
630
|
CONFIG_OPTIONS = Object.keys(VALIDATORS).filter((key) => key !== "$schema");
|
|
599
631
|
}));
|
|
600
632
|
//#endregion
|
|
601
|
-
//#region src/codegen/config.ts
|
|
602
|
-
/**
|
|
603
|
-
* Type-checks a `sobjectly.config.ts`. The listed `sobjects` become a literal union, so a typo in
|
|
604
|
-
* a per-sObject option is a compile error:
|
|
605
|
-
*
|
|
606
|
-
* ```ts
|
|
607
|
-
* export default defineConfig({
|
|
608
|
-
* apiVersion: "v66.0",
|
|
609
|
-
* output: "src/generated/sobjects.ts",
|
|
610
|
-
* sobjects: ["Account", "Contact"],
|
|
611
|
-
* excludeCreateFields: { Acount: ["Name"] }, // ❌ "Acount" is not in sobjects
|
|
612
|
-
* });
|
|
613
|
-
* ```
|
|
614
|
-
*/
|
|
615
|
-
function defineConfig(config) {
|
|
616
|
-
return config;
|
|
617
|
-
}
|
|
618
|
-
var init_config = __esmMin((() => {}));
|
|
619
|
-
//#endregion
|
|
620
633
|
//#region src/codegen/load-config.ts
|
|
621
634
|
/** Looks for a `sobjectly.config.{ts,mts,cts,json}` file in `cwd`; the first match in lookup order wins. */
|
|
622
635
|
function findConfigFile(cwd = process.cwd()) {
|
|
@@ -671,6 +684,25 @@ var init_load_config = __esmMin((() => {
|
|
|
671
684
|
]);
|
|
672
685
|
}));
|
|
673
686
|
//#endregion
|
|
687
|
+
//#region src/codegen/config.ts
|
|
688
|
+
/**
|
|
689
|
+
* Type-checks a `sobjectly.config.ts`. The listed `sobjects` become a literal union, so a typo in
|
|
690
|
+
* a per-sObject option is a compile error:
|
|
691
|
+
*
|
|
692
|
+
* ```ts
|
|
693
|
+
* export default defineConfig({
|
|
694
|
+
* apiVersion: "v66.0",
|
|
695
|
+
* output: "src/generated/sobjects.ts",
|
|
696
|
+
* sobjects: ["Account", "Contact"],
|
|
697
|
+
* excludeCreateFields: { Acount: ["Name"] }, // ❌ "Acount" is not in sobjects
|
|
698
|
+
* });
|
|
699
|
+
* ```
|
|
700
|
+
*/
|
|
701
|
+
function defineConfig(config) {
|
|
702
|
+
return config;
|
|
703
|
+
}
|
|
704
|
+
var init_config = __esmMin((() => {}));
|
|
705
|
+
//#endregion
|
|
674
706
|
//#region src/codegen/init.ts
|
|
675
707
|
/**
|
|
676
708
|
* Creates a `sobjectly.config` file by asking for the API version, output path, sObjects, auth
|
|
@@ -785,7 +817,6 @@ function renderJsonConfig(answers) {
|
|
|
785
817
|
return `${JSON.stringify(config, null, " ")}\n`;
|
|
786
818
|
}
|
|
787
819
|
function renderTypeScriptConfig(answers) {
|
|
788
|
-
const envVars = AUTH_ENV_VARS[answers.auth];
|
|
789
820
|
const sobjects = answers.sobjects.map((name) => JSON.stringify(name)).join(", ");
|
|
790
821
|
return [
|
|
791
822
|
"import { defineConfig } from \"@cerios/salesforce-sobjectly/codegen\";",
|
|
@@ -797,26 +828,38 @@ function renderTypeScriptConfig(answers) {
|
|
|
797
828
|
`\toutput: ${JSON.stringify(answers.output)},`,
|
|
798
829
|
" // The sObjects to generate types for.",
|
|
799
830
|
`\tsobjects: [${sobjects}],`,
|
|
800
|
-
`\t// ${authComment(answers.auth
|
|
831
|
+
`\t// ${authComment(answers.auth)}`,
|
|
801
832
|
`\tauth: ${renderAuth(answers)},`,
|
|
802
833
|
`\tpicklists: ${JSON.stringify(answers.picklists)},`,
|
|
803
834
|
"});",
|
|
804
835
|
""
|
|
805
836
|
].join("\n");
|
|
806
837
|
}
|
|
838
|
+
/** The JSON auth setting: credentials are `"${NAME}"` placeholders, read from the environment. */
|
|
807
839
|
function authSetting(answers) {
|
|
808
|
-
|
|
840
|
+
if (answers.auth === "sfCli") return answers.targetOrg ? {
|
|
809
841
|
type: "sfCli",
|
|
810
842
|
targetOrg: answers.targetOrg
|
|
811
|
-
} : { type:
|
|
843
|
+
} : { type: "sfCli" };
|
|
844
|
+
const fields = AUTH_FIELDS[answers.auth].map(([key, envName]) => [key, `\${${envName}}`]);
|
|
845
|
+
return {
|
|
846
|
+
type: answers.auth,
|
|
847
|
+
...Object.fromEntries(fields)
|
|
848
|
+
};
|
|
812
849
|
}
|
|
850
|
+
/** The TypeScript auth setting: credentials are read with `process.env`. */
|
|
813
851
|
function renderAuth(answers) {
|
|
814
|
-
|
|
815
|
-
const
|
|
816
|
-
return
|
|
852
|
+
if (answers.auth === "sfCli") return `{ type: "sfCli"${answers.targetOrg ? `, targetOrg: ${JSON.stringify(answers.targetOrg)}` : ""} }`;
|
|
853
|
+
const fields = AUTH_FIELDS[answers.auth].map(([key, envName]) => `\t\t${key}: process.env.${envName},`);
|
|
854
|
+
return [
|
|
855
|
+
"{",
|
|
856
|
+
`\t\ttype: ${JSON.stringify(answers.auth)},`,
|
|
857
|
+
...fields,
|
|
858
|
+
" }"
|
|
859
|
+
].join("\n");
|
|
817
860
|
}
|
|
818
|
-
function authComment(auth
|
|
819
|
-
return auth === "sfCli" ? "Uses an org you are logged into with the Salesforce CLI (sf org login web)." :
|
|
861
|
+
function authComment(auth) {
|
|
862
|
+
return auth === "sfCli" ? "Uses an org you are logged into with the Salesforce CLI (sf org login web)." : "Fill these in from process.env (any variable names), a secret store or elsewhere. Keep secrets out of this file.";
|
|
820
863
|
}
|
|
821
864
|
async function maybeUpdateEnvExample(options, auth) {
|
|
822
865
|
const path = join(options.cwd, ".env.example");
|
|
@@ -866,36 +909,43 @@ function printNextSteps(log, answers, scriptAdded, cwd) {
|
|
|
866
909
|
"Next steps:",
|
|
867
910
|
cli ? ` 1. Log in with the Salesforce CLI: sf org login web${answers.targetOrg ? ` --alias ${answers.targetOrg}` : " --set-default"}` : ` 1. Put ${formatList(AUTH_ENV_VARS[answers.auth])} in a .env file${envIgnored ? "" : " (and add .env to .gitignore)"}.`,
|
|
868
911
|
` 2. Generate the types: ${command}`,
|
|
869
|
-
" 3. Use them:",
|
|
912
|
+
" 3. Use them, logging in with the config's auth:",
|
|
913
|
+
" import { loadAuth } from \"@cerios/salesforce-sobjectly/codegen\";",
|
|
870
914
|
` import { API_VERSION, type SObjectRegistry } from "./${answers.output.replace(/\.(ts|mts|cts)$/, "")}";`,
|
|
871
|
-
" const sf = new SalesforceClient<SObjectRegistry>({ apiVersion: API_VERSION, auth });"
|
|
915
|
+
" const sf = new SalesforceClient<SObjectRegistry>({ apiVersion: API_VERSION, auth: await loadAuth() });"
|
|
872
916
|
].join("\n"));
|
|
873
917
|
}
|
|
874
918
|
function formatList(items) {
|
|
875
919
|
if (items.length <= 1) return items.join("");
|
|
876
920
|
return `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
|
|
877
921
|
}
|
|
878
|
-
var SOBJECT_NAME, NPM_SCRIPT, AUTH_ENV_VARS, AUTH_CHOICES, PICKLIST_CHOICES, FORMAT_CHOICES, JSON_SCHEMA_REFERENCE;
|
|
922
|
+
var SOBJECT_NAME, NPM_SCRIPT, AUTH_FIELDS, AUTH_ENV_VARS, AUTH_CHOICES, PICKLIST_CHOICES, FORMAT_CHOICES, JSON_SCHEMA_REFERENCE;
|
|
879
923
|
var init_init = __esmMin((() => {
|
|
880
924
|
init_api_version();
|
|
881
925
|
init_load_config();
|
|
882
926
|
SOBJECT_NAME = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
883
927
|
NPM_SCRIPT = "sobjects:generate";
|
|
884
|
-
|
|
928
|
+
AUTH_FIELDS = {
|
|
885
929
|
clientCredentials: [
|
|
886
|
-
"SF_LOGIN_URL",
|
|
887
|
-
"SF_CLIENT_ID",
|
|
888
|
-
"SF_CLIENT_SECRET"
|
|
930
|
+
["loginUrl", "SF_LOGIN_URL"],
|
|
931
|
+
["clientId", "SF_CLIENT_ID"],
|
|
932
|
+
["clientSecret", "SF_CLIENT_SECRET"]
|
|
889
933
|
],
|
|
890
|
-
accessToken: ["SF_ACCESS_TOKEN", "SF_INSTANCE_URL"],
|
|
934
|
+
accessToken: [["accessToken", "SF_ACCESS_TOKEN"], ["instanceUrl", "SF_INSTANCE_URL"]],
|
|
891
935
|
jwtBearer: [
|
|
892
|
-
"SF_LOGIN_URL",
|
|
893
|
-
"SF_CLIENT_ID",
|
|
894
|
-
"SF_USERNAME",
|
|
895
|
-
"SF_PRIVATE_KEY_PATH"
|
|
936
|
+
["loginUrl", "SF_LOGIN_URL"],
|
|
937
|
+
["clientId", "SF_CLIENT_ID"],
|
|
938
|
+
["username", "SF_USERNAME"],
|
|
939
|
+
["privateKeyPath", "SF_PRIVATE_KEY_PATH"]
|
|
896
940
|
],
|
|
897
941
|
sfCli: []
|
|
898
942
|
};
|
|
943
|
+
AUTH_ENV_VARS = {
|
|
944
|
+
clientCredentials: AUTH_FIELDS.clientCredentials.map(([, envName]) => envName),
|
|
945
|
+
accessToken: AUTH_FIELDS.accessToken.map(([, envName]) => envName),
|
|
946
|
+
jwtBearer: AUTH_FIELDS.jwtBearer.map(([, envName]) => envName),
|
|
947
|
+
sfCli: []
|
|
948
|
+
};
|
|
899
949
|
AUTH_CHOICES = [
|
|
900
950
|
{
|
|
901
951
|
value: "clientCredentials",
|
|
@@ -1098,7 +1148,7 @@ async function buildSource(input, options) {
|
|
|
1098
1148
|
const env = options.env ?? process.env;
|
|
1099
1149
|
const outputPath = isAbsolute(config.output) ? config.output : resolve(options.cwd ?? process.cwd(), config.output);
|
|
1100
1150
|
const client = new SalesforceClient({
|
|
1101
|
-
auth: resolveAuth(config.auth, env),
|
|
1151
|
+
auth: resolveAuth(config.auth, env, { warn: (message) => logger.warn(message) }),
|
|
1102
1152
|
apiVersion,
|
|
1103
1153
|
transport: config.transport,
|
|
1104
1154
|
retry: true
|
|
@@ -1151,39 +1201,114 @@ function normalizeSource(source) {
|
|
|
1151
1201
|
}
|
|
1152
1202
|
return result;
|
|
1153
1203
|
}
|
|
1154
|
-
/**
|
|
1155
|
-
|
|
1204
|
+
/**
|
|
1205
|
+
* Turns the config's auth setting into an auth provider. Each credential comes from its key in
|
|
1206
|
+
* the setting (a `"${NAME}"` placeholder is read from `env`), else from the variable a deprecated
|
|
1207
|
+
* `*Env` key names, else from its default `SF_*` variable. Throws one error listing every
|
|
1208
|
+
* missing credential.
|
|
1209
|
+
*/
|
|
1210
|
+
function resolveAuth(auth, env, options = {}) {
|
|
1156
1211
|
const setting = auth ?? { type: "clientCredentials" };
|
|
1157
1212
|
if ("getToken" in setting) return setting;
|
|
1158
|
-
const
|
|
1159
|
-
|
|
1160
|
-
|
|
1213
|
+
const problems = [];
|
|
1214
|
+
const lookup = (key, defaultEnv) => readCredential(setting, key, defaultEnv, env, options.warn);
|
|
1215
|
+
const read = (key, defaultEnv) => {
|
|
1216
|
+
const { value, problem } = lookup(key, defaultEnv);
|
|
1217
|
+
if (problem) problems.push(problem);
|
|
1161
1218
|
return value;
|
|
1162
1219
|
};
|
|
1163
1220
|
switch (setting.type) {
|
|
1164
|
-
case "accessToken":
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1221
|
+
case "accessToken": {
|
|
1222
|
+
const token = {
|
|
1223
|
+
accessToken: read("accessToken", "SF_ACCESS_TOKEN"),
|
|
1224
|
+
instanceUrl: read("instanceUrl", "SF_INSTANCE_URL")
|
|
1225
|
+
};
|
|
1226
|
+
throwIfMissing(setting.type, problems);
|
|
1227
|
+
return accessToken(token);
|
|
1228
|
+
}
|
|
1229
|
+
case "jwtBearer": {
|
|
1230
|
+
const loginUrl = read("loginUrl", "SF_LOGIN_URL");
|
|
1231
|
+
const clientId = read("clientId", "SF_CLIENT_ID");
|
|
1232
|
+
const username = read("username", "SF_USERNAME");
|
|
1233
|
+
const configured = PRIVATE_KEY_SOURCES.filter(([key]) => key in setting);
|
|
1234
|
+
const found = (configured.length > 0 ? configured : PRIVATE_KEY_SOURCES).map(([key, defaultEnv]) => ({
|
|
1235
|
+
key,
|
|
1236
|
+
...lookup(key, defaultEnv)
|
|
1237
|
+
}));
|
|
1238
|
+
const source = found.find((item) => item.value);
|
|
1239
|
+
if (source === void 0) problems.push(`no private key: ${found.map((item) => item.problem).join(", and ")}`);
|
|
1240
|
+
throwIfMissing(setting.type, problems);
|
|
1241
|
+
const privateKey = source?.key === "privateKeyPath" ? readFileSync(source.value, "utf8") : source?.value ?? "";
|
|
1242
|
+
return jwtBearer({
|
|
1243
|
+
loginUrl,
|
|
1244
|
+
clientId,
|
|
1245
|
+
username,
|
|
1246
|
+
privateKey
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
case "sfCli": {
|
|
1250
|
+
const targetOrg = "targetOrg" in setting ? read("targetOrg", "") : void 0;
|
|
1251
|
+
throwIfMissing(setting.type, problems);
|
|
1252
|
+
return sfCli({ targetOrg });
|
|
1253
|
+
}
|
|
1254
|
+
case "clientCredentials": {
|
|
1255
|
+
const credentials = {
|
|
1256
|
+
loginUrl: read("loginUrl", "SF_LOGIN_URL"),
|
|
1257
|
+
clientId: read("clientId", "SF_CLIENT_ID"),
|
|
1258
|
+
clientSecret: read("clientSecret", "SF_CLIENT_SECRET")
|
|
1259
|
+
};
|
|
1260
|
+
throwIfMissing(setting.type, problems);
|
|
1261
|
+
return clientCredentials(credentials);
|
|
1262
|
+
}
|
|
1175
1263
|
default: throw new Error(`Unknown codegen auth type "${setting.type}".`);
|
|
1176
1264
|
}
|
|
1177
1265
|
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1266
|
+
/**
|
|
1267
|
+
* Loads the sobjectly config and returns an auth provider for its `auth` setting, so the client
|
|
1268
|
+
* logs in the same way as `sobjectly generate`:
|
|
1269
|
+
* `new SalesforceClient({ apiVersion: API_VERSION, auth: await loadAuth() })`.
|
|
1270
|
+
* Throws when no config file is found, or one error listing every missing credential.
|
|
1271
|
+
*/
|
|
1272
|
+
async function loadAuth(options = {}) {
|
|
1273
|
+
const cwd = options.cwd ?? process.cwd();
|
|
1274
|
+
let configPath = options.configPath === void 0 ? void 0 : resolve(cwd, options.configPath);
|
|
1275
|
+
if (configPath === void 0) {
|
|
1276
|
+
const found = findConfigFiles(cwd);
|
|
1277
|
+
if (found.length > 1) options.warn?.(`found ${found.join(" and ")}; using ${found[0]}. Remove the other one.`);
|
|
1278
|
+
configPath = found[0];
|
|
1279
|
+
}
|
|
1280
|
+
if (configPath === void 0) throw new Error(`No sobjectly config file found in ${cwd} (looked for ${CONFIG_FILE_NAMES.join(", ")}).\nPass { configPath } to loadAuth(), run "npx sobjectly init" to create a config, or pass an auth provider such as clientCredentials() to SalesforceClient directly.`);
|
|
1281
|
+
const { config } = await loadConfig(configPath);
|
|
1282
|
+
return resolveAuth(config.auth, options.env ?? process.env, { warn: options.warn });
|
|
1283
|
+
}
|
|
1284
|
+
function readCredential(setting, key, defaultEnv, env, warn) {
|
|
1285
|
+
const values = setting;
|
|
1286
|
+
if (key in values) {
|
|
1287
|
+
const configured = values[key];
|
|
1288
|
+
const name = typeof configured === "string" ? ENV_PLACEHOLDER.exec(configured)?.[1] : void 0;
|
|
1289
|
+
if (name !== void 0) return fromEnv(env, name, ` (from auth.${key} "${String(configured)}")`);
|
|
1290
|
+
return typeof configured === "string" && configured.length > 0 ? { value: configured } : {
|
|
1291
|
+
value: "",
|
|
1292
|
+
problem: `auth.${key} is empty or undefined (if it reads process.env, that variable is not set)`
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
const envKey = `${key}Env`;
|
|
1296
|
+
const legacy = values[envKey];
|
|
1297
|
+
if (typeof legacy === "string") {
|
|
1298
|
+
warn?.(`auth.${envKey} is deprecated and will be removed in 2.0. Use ${key}: process.env.${legacy} in a TypeScript config, or "${key}": "\${${legacy}}" in JSON.`);
|
|
1299
|
+
return fromEnv(env, legacy, "");
|
|
1300
|
+
}
|
|
1301
|
+
return fromEnv(env, defaultEnv, "");
|
|
1302
|
+
}
|
|
1303
|
+
function fromEnv(env, name, origin) {
|
|
1304
|
+
const value = env[name];
|
|
1305
|
+
return value ? { value } : {
|
|
1306
|
+
value: "",
|
|
1307
|
+
problem: `environment variable ${name}${origin} is not set`
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
function throwIfMissing(type, problems) {
|
|
1311
|
+
if (problems.length > 0) throw new Error(`Missing Salesforce credentials for auth "${type}":\n${problems.map((problem) => ` - ${problem}`).join("\n")}\nFill them in under auth in the config, or set the environment variables (e.g. with --env-file .env).`);
|
|
1187
1312
|
}
|
|
1188
1313
|
async function resolveSObjectNames(client, config, logger) {
|
|
1189
1314
|
const exclude = new Set((config.exclude ?? []).map((name) => name.toLowerCase()));
|
|
@@ -1253,24 +1378,26 @@ async function renameWithRetry(from, to) {
|
|
|
1253
1378
|
await new Promise((resolve) => setTimeout(resolve, 50 * attempt));
|
|
1254
1379
|
}
|
|
1255
1380
|
}
|
|
1256
|
-
var silentLogger;
|
|
1381
|
+
var silentLogger, PRIVATE_KEY_SOURCES, ENV_PLACEHOLDER;
|
|
1257
1382
|
var init_codegen = __esmMin((() => {
|
|
1258
1383
|
init_providers();
|
|
1259
1384
|
init_sf_cli();
|
|
1260
1385
|
init_client();
|
|
1261
1386
|
init_generator();
|
|
1387
|
+
init_load_config();
|
|
1262
1388
|
init_validate_config();
|
|
1263
1389
|
init_config();
|
|
1264
1390
|
init_type_mapper();
|
|
1265
|
-
init_load_config();
|
|
1266
1391
|
init_init();
|
|
1267
1392
|
init_prompter();
|
|
1268
1393
|
silentLogger = {
|
|
1269
1394
|
info: () => void 0,
|
|
1270
1395
|
warn: () => void 0
|
|
1271
1396
|
};
|
|
1397
|
+
PRIVATE_KEY_SOURCES = [["privateKey", "SF_PRIVATE_KEY"], ["privateKeyPath", "SF_PRIVATE_KEY_PATH"]];
|
|
1398
|
+
ENV_PLACEHOLDER = /^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/;
|
|
1272
1399
|
}));
|
|
1273
1400
|
//#endregion
|
|
1274
|
-
export {
|
|
1401
|
+
export { FIELD_TYPE_MAP as A, DEPRECATED_AUTH_OPTIONS as C, generateSource as D, validateConfig as E, mapFieldType as M, init_generator as O, CodegenConfigError as S, init_validate_config as T, findConfigFiles as _, resolveAuth as a, AUTH_OPTIONS as b, AUTH_ENV_VARS as c, renderConfig as d, runInit as f, findConfigFile as g, CONFIG_FILE_NAMES as h, loadAuth as i, init_type_mapper as j, readGeneratedHashes as k, init_init as l, init_config as m, generate as n, init_prompter as o, defineConfig as p, init_codegen as r, readlinePrompter as s, checkGenerated as t, parseSObjects as u, init_load_config as v, PICKLIST_MODES as w, CONFIG_OPTIONS as x, loadConfig as y };
|
|
1275
1402
|
|
|
1276
|
-
//# sourceMappingURL=codegen-
|
|
1403
|
+
//# sourceMappingURL=codegen-0L2ebG9j.mjs.map
|